--- title: 'Harness 之后:Agent 可靠性的关键,是状态边界和失败闭环' source_url: 'https://mp.weixin.qq.com/s/zxNl9EUO2KErWp4K8M7D0Q' tags: [wechat, article, claude, openai, gpt, agent, harness, long-running-agent, state-boundary, failure-closed-loop, runtime-contract, commit-gate, trace-feedback] feed_name: '架构师' date: 2026-06-02 author: '若飞' sha256: d7cc5759f9970625d04bafd16b96a4c8170e6249cb5c7a1fce4486a790c4a8ac review_value: 8 review_confidence: 7 review_recommendation: strong ingested: 2026-06-03 review_stars: 4 --- # Harness 之后:Agent 可靠性的关键,是状态边界和失败闭环 ## 太长不看 - Harness Engineering 这轮讨论的价值,是把模型外面的执行环境、工具、上下文、生命周期、可观测、验证和治理,明确看成一个独立系统层(ETCLOVG 七层:Execution / Tooling / Context / Lifecycle / Observability / Verification / Governance)。 - 但 Harness 不能只写成组件清单。Agent 真进入工程流程以后,可靠性取决于这些组件能不能形成一套**状态清楚、证据可查、失败可恢复**的运行时闭环。 - 长上下文不等于长期状态管理,memory 也不等于治理。很多失败不是模型不会想,而是系统没有区分候选动作、已验证动作和已提交状态。 - Trace 也不只是日志。它有用,是因为失败轨迹能回写到规则、Skill、Hook、Workflow 和测试里。 - 下一步拆成三件事:**运行时契约 / 状态提交闸门 / 失败回写闭环**。 - 团队要试,不要一上来做"大而全的 Agent 平台"。先找一个输入稳定、输出可审、失败可见、权限低风险的小流程,连续跑几轮。 ## 一、综述的价值:把模型外的工程层压成一张地图 过去几年 Agent 工程的变化被压成三段: 1. **Prompt Engineering**——指令、few-shot、推理模板,核心围绕一次模型调用。 2. **Context Engineering**——每一步到底该让模型看见什么,检索、压缩、工具结果排序、上下文窗口管理开始变得重要。 3. **Harness Engineering**——执行环境、工具接口、上下文、生命周期、可观测、验证、治理一起进来。 ETCLOVG 七层分类: - **Execution**:Agent 在哪里运行,沙箱和权限怎么控制。 - **Tooling**:工具怎么描述、发现、调用。 - **Context**:短期上下文、session 记忆、长期记忆怎么管理。 - **Lifecycle**:单 Agent 循环、多 Agent 编排、任务生命周期怎么组织。 - **Observability**:trace、成本、失败、可靠性信号怎么收集。 - **Verification**:任务和轨迹怎么评估,失败怎么归因。 - **Governance**:权限、安全、审计、组件加固怎么做。 架构师视角下这张图的实际价值在于:把容易混在一起的东西拆开。 > 别急着把所有模型外的问题都塞进"上下文"这个筐里。 > 工具不是权限。 > 记忆不是状态。 > 日志不是证据。 > 编排不是治理。 > 长上下文也不是长期运行。 这些东西一旦混在一起,Agent 越强,系统越容易乱。 ## 二、组件要咬合:分类 ≠ 闭环 分类能告诉我们有哪些部件,但不能保证这些部件真的能一起工作。这和平时做系统很像:服务、缓存、队列、网关、日志、监控、CI、权限、回滚——清单都对,但实际出问题常常出在部件之间。 Agent Harness 也一样。一个系统可以有 memory、tools、sandbox、trace、eval、policy,但它仍然可能不可靠。比如: - 长任务跑到一半,上一轮 Agent 留下半个实现,下一轮 Agent 不知道发生过什么,只能靠猜。 - 模型提出一个动作,验证器没挡住,工具已经改了数据库。 - trace 里记录了很多 token、调用和中间结果,但没人能从里面判断哪一步开始偏。 - memory 越积越多,旧项目里的临时经验变成了新项目里的默认偏好。 这些问题不是"再加一个组件"就能解决的。它们指向的,是**状态和责任边界**——七层组件摆齐只是开始,到了真实任务里,更难的是让这些组件互相咬合,形成一条**能恢复、能复查**的闭环。 ## 三、长任务怕断档:可接手状态 vs 长上下文 Anthropic 的长任务 Harness 文章给了一个朴素的例子:让一个 Agent 连续开发一个复杂应用,问题不是单个 session 写不出代码,而是它会一上来想把所有东西一次性做完,做到一半上下文耗尽,留下半个实现;下一轮 session 进来时不知道前面到底发生过什么,只能重新摸索;到了后期,另一个 Agent 看到项目里已经有不少东西,又可能提前宣布"差不多完成了"。 这个失败模式挺熟悉。这不只是智力问题,更像**交接问题**。 Anthropic 的做法:让第一轮 initializer agent 先搭环境、列 feature、写进度文件;后面的 coding agent 每次只做增量进展;session 结束前留下清晰记录,让下一个 Agent 能接。这和人类工程师交接班很像。 复杂项目里更值钱的不只是"我今天写了多少代码",而是: - 当前目标是什么。 - 哪些功能还失败。 - 哪些改动已经提交。 - 哪些只是临时尝试。 - 测试结果是什么。 - 下一步该从哪里继续。 > 长期 Agent 需要的不只是更长的聊天记录,更是**可接手、可验证、可回滚**的运行时状态。 > 上下文可以让模型多看一段历史,但它不能自动判断哪些历史可信、哪些已经过期、哪些只是一次失败尝试。 ## 四、状态要分层:候选 / 已验证 / 已执行 / 已提交 模型输出一个想法,和系统真的提交一个状态,不是一回事。如果这个边界不清,Agent 的很多失败会从"语言层面的幻觉",变成**外部世界里的损坏**。 Google DeepMind 的 AutoHarness 论文用游戏环境讲了一个类似问题:模型在某些游戏里会走非法动作。非法动作本身不稀奇,关键在于系统有没有一个外部机制,能判断当前状态下哪些动作合法,把不合法的动作挡在提交之前。 放到企业系统里更直接: - Agent 说"应该删除这些过期记录"——这只是候选判断。 - 它生成一条 SQL——仍然只是候选动作。 - 权限检查通过、dry-run 通过、影响范围可见——才进入可执行阶段。 - 正式写入数据库以后——才是已提交状态。 - 提交以后,还要有审计、回滚点和人工可读证据。 **一次动作的状态提交链路**: | 状态 | 含义 | 需要的机制 | |------|------|-----------| | 候选输出 | 模型提出一个想法或动作 | prompt、上下文、任务目标 | | 已验证动作 | 外部规则确认它能做 | validator、权限、测试、dry-run | | 已执行动作 | 工具已经产生副作用 | sandbox、审计、日志、成本记录 | | 已提交状态 | 外部系统状态被正式改变 | checkpoint、回滚、人工确认、证据归档 | 很多 Agent 事故出在中间两层: - 模型本来只是"猜了一下",系统却把它当成"已经确认的事实"。 - 模型本来只是"试了一次",工具却已经把外部状态改掉。 - 模型本来只是"当前 session 的临时结论",memory 却把它写成长期偏好。 > 长期来看,Agent Runtime 的核心问题清单是:哪些输出只是候选、哪些动作要先验证、哪些工具会产生副作用、哪些副作用可以回滚、哪些状态需要人确认、哪些错误不能写进长期记忆。 > 这些问题看起来土,但比"模型会不会多想几步"更接近生产系统。 ## 五、Trace 要回写:前馈 + 反馈 + 确定性 vs 语义性 LangChain 的案例值得留意:固定模型只改 deepagents-cli 外面的 Harness,在 Terminal Bench 2.0 上做改进。具体分数可以当案例看,不适合直接外推成普遍承诺——但更值得看的是怎么改: - 用 trace 去看 Agent 到底在哪里失败(没按任务说明做、没验证、跑超时、测试没读完整、停得太早)。 - 把这些失败分析变成可重复的 Trace Analyzer Skill。 - 再回过头调整系统提示、工具和 middleware。 **Trace 的价值不只是"我有日志"**——日志如果只是存着,最多是事后查账。Trace 能进入 Harness,是因为它能回答几个问题: - 失败从哪一步开始。 - 当时模型看到了什么。 - 工具返回了什么。 - 哪个验证没有触发。 - 哪条规则写得太虚。 - 下次应该把反馈放在更早的位置,还是更晚的位置。 Martin Fowler 把 Harness 里的控制分成两类: - **前馈(feedforward)**——Agent 行动前给它方向,比如 `AGENTS.md`、规则、技能、架构说明、项目约定。 - **反馈(feedback)**——Agent 行动后让它自我修正,比如测试、lint、静态分析、日志、浏览器检查、review agent。 再往下还可以分: - **Computational controls(确定性)**:测试、类型检查、脚本、lint。 - **Inferential controls(语义性)**:reviewer agent、LLM judge、人工 review。 工程里更稳的分配是:便宜、稳定、快速的检查尽量前移;昂贵、不确定、需要取舍的检查留给关键节点。区别只是:现在被约束的对象不只是人写的代码,也包括 Agent 的行为。 ## 六、三条分歧 **第一条:模型会不会把 Harness 吃掉?** - "Big Model" 派(Boris Cherny、Cat Wu、Noam Brown):尽量让模型发挥能力,外层包装保持很薄;过去很多 scaffold 可能会被更强的推理模型吸收掉。 - "Big Harness" 派(Jerry Liu、LangChain、AutoHarness):模型能力上去以后,任务也会变大,任务一变大,新的约束又会出现。 折中:模型会吃掉一部分 Harness,但不会吃掉**外部状态和责任边界**。只要 Agent 还要进入文件系统、浏览器、数据库、生产环境、审批链和人类团队,外部状态、权限、证据和回滚就不会消失。模型可以更聪明,但它不能替系统承担所有责任。 **第二条:同一个模型在不同 Harness 里到底差多少?** Ry Walker 的说法挺贴近企业实践:同一个模型,经过不同 CLI、framework、runtime,表现会有明显差别。架构师的提醒是:运行时约定最好别绑死在某一个工具形态上——模型会换、CLI 会换、供应商会换、团队偏好也会换。 更稳的做法是把运行时契约尽量沉到项目层和流程层:项目怎么启动、哪些命令能跑、哪些文件不能动、什么算完成、证据放在哪里、失败怎么记录、哪些动作要人确认。不同 Harness 可以读取这些约定,但约定本身最好别完全依赖某个 Harness。 **第三条:Harness 能不能解决欠规格?** Hamidreza Saghir 在《Your coding agent is under-specified》里讲得很直接:很多 coding agent 的问题不是模型坏,而是任务本身没写清楚。代码要精确到分支、状态、错误路径和副作用,但自然语言任务常常只写 happy path。 Harness 能做的是把缺失规格放到 Agent 能看到、能执行、能被检查的位置(`AGENTS.md`、测试、类型、review checklist、权限、结构化日志、工作流脚本)。但 Harness 不能替我们想清楚所有规格——如果团队自己都没有说清楚"这个项目到底怎么做事",Agent 只会用训练数据里的平均习惯补空。 > Harness 更像一个放大器——它能放大清晰的规则,也会放大模糊的流程;它能让清晰流程跑得更快,也能让模糊流程更快地产生半成品。 > 这个边界需要留住:Harness 有价值,前提是流程本身值得被放大。 ## 七、先做三件事:运行时契约 / 状态提交闸门 / 失败回写 ### 7.1 运行时契约 Agent 开工前,运行边界要清楚。至少包括: - 目标是什么。 - 做到哪里停。 - 输入从哪里来。 - 输出交给谁看。 - 哪些系统能读。 - 哪些动作能写。 - 哪些动作要人确认。 - 上一轮留下了什么证据。 和 Cowork 模板里的 `TERMINATION` 是一条线。Prompt 如果只写"帮我做竞品分析",它会自然扩散;运行时契约会写清读哪些站点、看哪些字段、输出几段、哪些地方不预测、什么时候停止、哪些链接打不开要标出来。Agent 任务越长,这份契约越重要——它不是要压住创造力,只是先把任务边界说清楚。 ### 7.2 状态提交闸门 候选判断被直接写成已提交状态是 Agent 过程中最容易出问题的一环。可以先把状态分成几类: - **草稿**:可以随时重写。 - **候选结论**:需要来源和验证。 - **工具动作**:可能有副作用。 - **提交状态**:会改变外部系统。 - **长期记忆**:会影响未来任务。 每一类都要有不同闸门:草稿可以宽松;候选结论要来源;工具动作要权限;提交状态要**审计和回滚**;长期记忆要更克制。 > 记忆更像预算,不像仓库——不是所有发生过的事情都值得记住。尤其是那些临时绕路、失败猜测、一次性偏好,如果被写进长期记忆,会变成未来判断里的噪声。 ### 7.3 失败回写 Agent 做错了,光让它道歉没太大意义——更有用的是看这个错误应该回写到哪里: | 错误类型 | 写到哪里 | |----------|---------| | 项目约定没读到 | `AGENTS.md` 或项目入口说明 | | 同类任务步骤不稳定 | 沉淀成 Skill 或 Runbook | | 每次都忘记跑测试 | Hook 或 Stop check | | 危险命令差点执行 | 权限和 PreToolUse | | 评估标准不清 | 补测试、lint、review checklist | | 流程本身太松散 | 先别自动化,回到人工流程把输入输出跑清楚 | 每个反复出现的 Agent 错误都值得追问一次:它是提示词问题、状态问题、权限问题、验证问题,还是流程问题。这个问题问清楚,补丁才知道落在哪里。 ## 八、先稳再自动化 长期 Agent、cron、subagents、orchestrator——这些能力很诱人,看起来只要接上就能让一个人拥有一支后台团队。但流程还没跑明白时,自动化很容易放大混乱。 - 一个竞品扫描流程,如果输入列表每周都临时变、输出格式没人看、失败链接不记录、引用来源不归档,那么接上 Agent 以后,只会定时生成更多看起来像成果的半成品。 - 一个代码 review 流程,如果风险分类不清、测试口径不清、谁来裁决不清,多 Agent 并行以后,也只是把 review 压力往后推。 更稳的做法:从很小的地方开始。 - 选一个低风险、可审阅、输入稳定的流程:每周固定站点的竞品扫描、PR 第一轮只读审查、文档来源归档、发布前 smoke checklist、公众号素材来源台账。 - 先连续跑几轮,只让 Agent 读和整理,不让它写外部系统。 - 每轮都要求它留下失败记录和证据。 - 人类 review 后,再把重复问题写回规则、Skill 或检查脚本。 - 等输入、输出、失败和权限都稳定,再考虑定时任务和更高自动化。 这条路看起来慢一点,但对 Agent 系统来说,慢一点反而更真实——因为要验证的不只是"它能不能偶尔做对一次",还有"它出错以后,状态还能不能被看懂"。 ## 九、收束 Harness Engineering 这轮讨论,把一个事实说得更清楚了:Agent 的可靠性不能继续只押在模型能力上——模型之外那层执行环境、上下文、工具、验证、观测和治理,正在变成独立的工程对象。 > 模型可以不断给出可能性。Harness 提供约束环境。状态边界和失败闭环,负责把错误挡在提交之前,把正确结果沉淀成证据。 这件事没有那么炫,但真要让 Agent 进入日常研发、运维、内容、数据和业务流程,最后拼的往往就是这些不太炫的东西: - 状态能不能被看懂。 - 错误能不能被拦住。 - 证据能不能被复核。 - 状态能不能被回滚。 - 下一轮能不能接着做,而不是重新猜。 Harness 之后,Agent 可靠性的下一步,会先从这两件事看:**状态边界,失败闭环**。 ## 参考来源 - 论文主页地址:https://picrew.github.io/LLM-Harness/