什么是 Harness:让 Agent 稳定干活的运行系统
一句话定位:Harness 是围绕模型搭起来的一层运行系统——管上下文、管工具、管状态、管执行边界、管验证,把 Agent 从「偶尔做对一次」变成「每次都做对」。前置:Agent 的基本循环——模型「思考 → 行动 → 观察」转着圈干活的那套机制。
先看一个翻车现场
想象你给 Agent 派了个固定活:每周五汇总团队周报。第一周它干得漂亮,格式清爽、数据齐全。
第二周你开了个新会话,它忘了格式偏好、漏了数据源,甚至编了一个不存在的数字。模型没换、提示词没变,输出却从九十分掉到不及格。
差别到底在哪?不在模型,在模型外面那圈没固定下来的东西——喂给它什么、允许它碰什么、状态存在哪、做完怎么验收、在什么边界里跑。把这五样焊成一个系统,它就有了名字:Harness。
Harness 全景:中央是 Agent 循环,①–④ 把它支撑起来,⑤ 守住出口——本篇全文沿用这套编号
渐进拆解
类比:模型和 Harness 的关系,就是芯片和整机。芯片决定性能上限,整机决定体验下限。没人因为跑分高就忍受一台天天死机的手机;同样,模型再强,没有 Harness,就只是「偶尔做对一次」。
那这台「整机」里都有什么?五个部件,每个都能在手机上找到影子:
图:隐喻映射——左边是手机上的影子,右边是 Harness 里的真身,编号全文沿用
- ①上下文:模型每一步「看到」什么由它决定——规则、记忆、上一步的观察都在这。
- ②工具:读写文件、跑命令这些本事,注册好、按权限发放。
- ③状态:auto memory 和会话压缩长在这儿,中断了能接上进度。
- ④执行环境:每一步圈在边界里跑,高危动作先问你。
- ⑤验证门:Agent 说「做完了」不算数,过了它才算。
一句话收拢:Harness 就是给 Agent 立规矩、发工具、留底账、验成色的那层壳。
你天天在用的 Claude Code 就是这么一台整机——它「越用越顺手」不是模型记性好,是这五样长在系统里,不随会话消失。
技术定义:业界通行的表述:Harness 是模型、工具、状态、上下文与执行环境的统一组织。它负责四件事:生命周期管理、配置与工具集装配、Checkpoint 与 Trace、高风险动作前的人工确认(human-in-the-loop)。
另一种按职责的拆法是四大子系统加双层操控循环。双层循环说的是控制回路怎么转:外层是人——定目标、验收结果,属于开环的意图输入;内层是 Agent 循环执行——它自己闭环,靠 PDCA(计划 → 执行 → 检查 → 改进)转起来。两层之间靠两条控制线衔接:前馈控制在开工前把目标、约束、可用工具喂足,让内层少走弯路;反馈控制拿执行结果的偏差修正下一轮——像开车,前馈是出发前看导航选路线,反馈是看到偏了再打方向。
四大子系统按职能分工:目标子系统管「要什么」(任务定义与验收标准),知识子系统管「靠什么」(上下文与记忆),工具子系统管「用什么」(能力接入),验证子系统管「对不对」(检查与裁决)。这套拆法与本篇五部件粒度不同——「状态」「执行环境」在它那里没有独立位置,分别落进知识与工具子系统的辖区——两套拆法不必强行一一对齐,选一套讲得清的用就好。
动手:一个最小 Harness
不到 15 行伪代码,五个部件各就各位(编号对应全景图):
def harness_loop(task, budget):
ctx = assemble(task) # ① 上下文:规则 / 记忆 / 技能装配
tools = registry.allow(task.role) # ② 工具:按角色发放
while not task.done and budget.ok(): # ③ 状态:预算与循环上限防失控
action = model.think(ctx) # 模型只是被调度的部件
result = sandbox.run(action, tools) # ④ 执行环境:在沙箱里落地
ctx = observe(ctx, result) # ① 上下文:观察结果回填
checkpoint(task, ctx) # ③ 状态:随时可中断可恢复
assert evidence(task.checks) # ⑤ 验证:要证据,不听自述
return report(evidence=trace(ctx)) # 带证据链交付
同一个概念,在不同文献里的叫法不同,对照如下(深挖去处指向本系列的对应专篇):
| 本篇用词 | 文献中的其他叫法 | 深挖去处 |
|---|---|---|
| ① 上下文 | Context Engineering · 知识子系统 · 提示词组装 / 会话管理 | 上下文压缩 |
| ② 工具 | Tool Registry · 工具子系统 | 工具执行 |
| ③ 状态 | 状态机 / Checkpoint · 记忆沉淀 / 状态外部化 | 状态机与 Checkpoint |
| ④ 执行环境 | Sandbox 边界 · Middleware / 沙箱 | 工具执行 |
| ⑤ 验证 | Eval / 回归 · 验证子系统 · Benchmark 科学度量 | Agent 评估 |
边界与取舍:什么时候不该上 Harness
Agent 应用不只有一种形态,选型要回答两个独立的问题:任务路径由谁决定,以及决定之后,控制流代码归谁。
形态:路径谁决定
第一个问题决定形态。按业界通行的分界(Anthropic《Building Effective Agents》):Workflow 是人预先写好路径,LLM 在固定路径上被编排——可预测、可靠;Agent 是模型在运行时自己决定下一步——灵活,但行为要跑了才知道。再往左退一档是纯脚本:没有模型参与决策,每一步写死。三者是一条「自主性」谱系上的三档。(有些分类还会列出 RAG 与 Chatbot——它们是检索能力与交互形态,挂在任何一档上都成立,不影响这个选型。)
图:形态谱系——三档只差一件事:路径由谁决定
| 形态 | 典型例子 | 适合 | 不适合 |
|---|---|---|---|
| 纯脚本 | 每天定时抓天气、拼一句话发到群里 | 步骤完全确定 | 需要理解与判断的环节 |
| Workflow | 客服工单:先自动分类,退货、投诉各走一条预先画好的流程 | 结构化任务、要可靠可预期 | 开放任务、路径没法预先画全 |
| Agent | Claude Code:自己决定读哪个文件、跑什么命令、怎么修 | 开放任务,路径无法预先画全 | 步骤其实固定的活——杀鸡用牛刀 |
Anthropic 的建议也顺着这条谱系:从最简单的起步——任务结构清晰就用 Workflow,只有模型需要灵活决策时才值得上 Agent。
载体:控制流归谁
决定做 Agent 之后,就到了第二个问题:控制流代码归谁。两条路:
- 用 Framework(LangGraph 这类)——主循环和工具调度封装在库里,你只填配置与回调。
- 建自有 Harness——主循环、工具、权限全部是你自己的代码,模型降级为可替换的插件。
两条路的取舍:
| 载体 | 适合 | 代价 |
|---|---|---|
| Framework(LangGraph 等) | 快速起步、标准场景 | 循环行为绑定库的抽象,升级随库走 |
| 自有 Harness | 开放任务 + 要稳定复现 + 长期演进 | 前期工程量大,一次性小活不划算 |
公开样本
这条路线已有几个公开样本:
| 项目 | 定位 | 架构要点 |
|---|---|---|
| OpenClaw(前身 Clawdbot) | 自托管的个人助理框架,「把开源框架的 Harness 当产品本体」的典型 | Gateway-Node 分层把消息入口与 Agent 核心分开,事件钩子做扩展点,数据落在本地 SQLite |
| DeerFlow(字节开源) | 自我定位是 super agent harness | 把子代理、记忆、沙箱编排成长任务的执行骨架 |
| DeepSeek Harness | 干脆连 Harness 一起开源,官方口号「Everything is a Plugin」 | 骨架基于 Cordis 微内核(其设计论文的标题就是「时空可组合性」的编程范式),模型只是插件之一 |
三个样本定位各异,共同点是:产品的核心资产是那套运行系统,模型是可替换的部件。
一句话决策:先选形态——路径固定就 Workflow,开放任务才上 Agent;再选载体——试错期用框架,认真做产品就把控制流收进自己手里。
坏味道预警
一个腐化的 Harness 通常有五种味道,各配一个可识别的信号:
- 需求模糊:同一句话每次执行出来的任务都不一样,目标从未被写死;
- 隐性约定:流程依赖「上一步记得要……」的默契,换个模型或隔一周就断;
- Agent 假装完成:报告说做完了,验收产物不存在或对不上;
- 指令文件腐化:指令文档越补越长、规则互相打架,没人敢删旧条目;
- 状态污染:上一次任务的残留数据悄悄影响下一次的判断。
识别靠把这些信号变成每次验收的检查项,重构手法在后续遇到具体坏味道时再展开(「假装完成」的防法本文自测段先给了一版)。
自测
合上文章先自己答,再展开对照:
用自己的话说 Harness 和 Framework 的本质区别?
控制流归属。Framework 拥有主循环,你的代码是被库调用的回调,行为上限由库作者决定;Harness 的主循环、上下文、工具、状态全部代码在你手里,模型降级为可替换的插件。前者交付「快」,后者交付「可控可复现」。
「Agent 假装完成」的信号有哪些?怎么设计反馈让它藏不住?
信号:声称测试通过但没有执行记录、引用不存在的文件或函数、总结与实际 diff 对不上、绕开验证步骤直接报完成。防法是⑤验证门——完成声明不采信自述,只采信证据:把「跑测试 / 跑构建」设为收尾的强制步骤,执行结果回填上下文,报告必须附 exit code 与输出摘要。
参考与延伸
- Anthropic《Building Effective Agents》(2024-12):Workflow 与 Agent 的形态分界出自此文 — anthropic.com/engineering/building-effective-agents
- DeepSeek Harness 开源仓库(2026-08):「Everything is a Plugin」官方口号与 Cordis 微内核的出处 — github.com/deepseek-ai/deepseek-harness
- Cordis 设计论文《A Programming Paradigm for Spatiotemporal Composability》:DeepSeek Harness 底座微内核的设计阐述 — arxiv.org/abs/2608.25512
- OpenClaw(开源个人助理框架):Gateway-Node 分层与本地 SQLite 的公开文档 — docs.openclaw.ai
- DeerFlow(字节开源):自我定位「super agent harness」的开源仓库 — github.com/bytedance/deer-flow
- Claude Code(产品页):文中「整机」例子的参照对象 — claude.com/product/claude-code
- Pi 会话设计的第一性论证(2026-10-24 汇总):Mario《Prompts are code, .json/.md files are state》(prompt=程序/状态必须落盘,PLAN.md 前身)+《Armin is wrong》(「local-first 只适用于你这一侧」「treat the provider as a black box that computes over your canonical log」)——Pi 的 JSONL 事件树与跨 provider 交接由此推导 — 见「读 Pi 学 harness 11/13/28」与 W43 扫荡报告 §3
本系列的后续学习路线(推荐顺序):模型调用与容错 → 上下文压缩 → 状态机与 Checkpoint → 工具执行 → 权限机制 → 记忆机制 · Skill 机制 → 多 Agent 编排。