--- title: "再看 Harness Engineering:真正要设计的不是约束,而是可删的工作现场" source_url: "https://mp.weixin.qq.com/s/y1pIKtBFr5BrN3f7VOypWw" author: 若飞 feed: 架构师(JiaGouX) publish_time: "2026-06-09 22:46" ingested: "2026-06-10" sha256: a74e46b5e2a54794b26e913be19ef8bca17fc145 type: raw tags: [agent, harness, skill, sub-agent, model, guides, sensors, deletable-constraint, worksite] sources: [long-running-agent-ralph-loop-handover-harness-ruofei] --- ## 再看 Harness Engineering:真正要设计的不是约束,而是可删的工作现场 架构师(JiaGouX)| 若飞 | 2026-06-09 这两天又看到几篇讲 Harness Engineering 的文章。 只看标题,它很容易被当成又一个新概念:Prompt Engineering 之后是 Context Engineering,Context Engineering 之后又来了 Harness Engineering。 放回工程现场看,这件事没那么玄。 它回答的,其实是一个很日常的问题: **当大模型不再只是回答问题,而是开始读文件、调用工具、改代码、跑测试、接着上一轮继续做事时,模型外面那一整套工作现场该怎么搭?** Model、Tool、Skill、Sub-agent、Harness 这几个词,表面上是在讲 Agent 架构,往里看,其实是在讲一件事:一个能做事的 Agent,外面到底需要什么样的工作台。 这张工作台上,有规则,有工具,有状态,有测试,有权限,也有将来要删掉的旧约束。 前面几篇我们分别聊过状态边界、任务级 Harness、验证工作台和 Skills。这几条线放在一起看,更像在补同一个现场里的不同位置。 图 1:Agent 五层关系图 ### 先拆五层 先把主语挪出来: ``` Agent 不是一个模型,而是一个能围绕目标持续行动的系统。 ``` 普通聊天模型更像"你问一句,它答一句"。 Agent 更像"你给它一个目标,它先判断下一步该做什么;做完一步,再看环境反馈,然后继续往下走"。 比如: - 读一个代码仓库,定位一个 bug; - 根据 issue 改几处文件,再跑测试; - 打开浏览器复现页面问题; - 查日志、看 trace、改配置,再验证结果; - 把一篇技术稿里的事实断言逐条核对来源。 这些事情都不是一次回答能结束的。 它们需要模型、工具、上下文、状态、验证和权限一起工作。 所以聊 Agent 时,只盯着模型,会少看一半。 只堆工具,也会少看另一半。 ### 模型管推理 Model,也就是模型,是 Agent 的推理核心。 它负责理解目标、读上下文、生成下一步动作,或者判断某个结果是否合理。 但模型本身通常不直接执行外部动作。 它可以说"我想读取这个文件""我想调用这个 API""我想运行这条测试命令",但真正把文件读出来、把命令跑起来、把 API 调出去、把结果塞回上下文的,是模型外面的系统。 这里最容易混淆。 Claude Code、Codex、Cursor、Hermes Agent 这类产品,当然都依赖模型能力。但你实际感受到的"它能不能干活",很大一部分来自模型外面的那套东西: - 它能不能看见你的文件; - 它能不能安全地调用工具; - 它能不能知道项目怎么启动; - 它能不能跑测试并读懂失败; - 它能不能把做过的事留下来; - 它能不能在危险操作前停下来。 模型像发动机。 但一辆车能不能上路,不只看发动机。 ### 手和手艺 Tool 是最容易被看见的一层。 它就是 Agent 伸向外部世界的手。 文件系统、Shell、浏览器、数据库、搜索、代码解释器、内部 API,都可以是工具。 模型通常只表达调用意图,真正的工具调用由外部运行系统完成。这个边界很重要,因为工具一旦接上,就可能有副作用。 读文件风险小一点。 删数据、发请求、改配置、提交代码,风险就不一样了。 Tool 不只是"能力扩展",也是权限边界。 Skill 另一层。 Skill 不是某一次动作,而是一套可以复用的做事方法。 比如: - 怎么排查一个前端页面问题; - 怎么做一次技术稿事实核验; - 怎么处理一个数据库迁移; - 怎么审一段安全敏感代码; - 怎么把一个长任务拆成计划、执行和验收。 这些事情不靠一个工具就能完成。它们需要步骤、经验、检查点和输出格式。 我更愿意把 Tool 看成"手",把 Skill 看成"手艺"。 工具告诉 Agent 能做什么。 Skill 告诉 Agent 这类事通常怎么做。 这也是我们最近一直在写 Skills 的原因。它的价值不在于多存几段提示词,而在于把团队经验沉淀成 Agent 可以反复调用的过程资产。 ### 分工不是魔法 Sub-agent 这几年也很热。 一听多 Agent,很容易想到并行:一个查资料,一个写代码,一个跑测试,一个做 review。 这个方向确实有价值,但它不是魔法。 Sub-agent 本质上是把一个任务拆给另一个能独立处理子问题的 Agent。它可以有自己的上下文、工具、目标和输出。 问题在于,分工会带来新的管理成本。 多个 Agent 同时跑,谁来分任务?谁来合并结果?谁来判断哪个结论可信?谁来处理冲突?谁来决定什么时候停? 如果这些没有设计好,多 Agent 只是把单个 Agent 的混乱放大。 现在看 Sub-agent,我会先看三个点: - 子任务是否足够独立; - 输出是否能被验证; - 主 Agent 或人类是否能合并和裁剪结果。 能做到这三点,多 Agent 才像工程分工。 做不到,就只是多开了几个窗口。 ### Harness 管运行 讲到这里,再看 Harness 就清楚一些了。 如果说 Model 是推理核心,Tool 是外部动作,Skill 是做事方法,Sub-agent 是任务分工,那么 Harness 管的是整个 Agent 怎么跑起来。 它包括: - 每一步给模型看什么上下文; - 哪些工具能用,哪些要确认; - 任务状态放在哪里; - 什么时候启动测试; - 失败结果怎么回到模型; - 哪些动作只能 dry-run; - 日志、截图、trace、commit 怎么留下; - 做到什么程度可以停; - 下一轮 Agent 怎么接手。 一个好理解的区分是:Scaffolding 更像管"怎么想",Harness 更像管"怎么跑"。 这句话好记,但工程里还要多看一层: 能落地的 Harness,不只是让 Agent 跑起来,还要让它跑完以后能被检查、被接手、被修正。 这就是它和普通"工具调用框架"的差别。 只会调用工具,还不够。 工具调用前后发生了什么,错误有没有挡在提交之前,失败经验能不能回到下一轮,这些才是工程现场里更要命的部分。 ### 先看现场 OpenAI 有一个 Harness Engineering 文章,讲的是"一个内部产品,所有代码都由 Codex 写,人类不直接手写代码"。 这个点很抓眼,但真正能借鉴的地方更朴素。 他们为了让 Codex 能长期工作,把仓库变成了 Agent 能读懂的现场。 他们一开始也试过一个很大的 AGENTS.md。后来发现不行。 一个巨大的规则文件,很快会变成负担。上下文窗口被占满,规则过期也没人维护,Agent 还分不清哪些约束是真正关键的。 于是他们把 AGENTS.md 改成入口地图。更细的知识放到仓库里的结构化文档、执行计划、质量记录、产品规格和设计文档里。 这个变化很像新人入职。 新人入职时,我们也不会把公司所有制度、历史决策、产品细节都塞进一页纸里。更合理的方式是给一张地图,让他知道不同问题该去哪里查。 Agent 也是一样。 它运行时看不到的东西,就等于不存在。 Slack 里的共识、会议里的取舍、某个老工程师脑子里的经验,如果没有进入仓库、文档、脚本、测试、日志或可查询工具,就很难稳定影响下一次执行。 这件事给我的提醒是: Agent-first 的代码库,第一步往往是让系统更可读。 可读,不只是给人读。 也要给 Agent 读。 ### 前后咬合 ThoughtWorks / Martin Fowler 把 Harness 拆成 Guides 和 Sensors,我觉得这个拆法很实用。 Guides 是行动前的引导。 比如 AGENTS.md、Skills、架构文档、接口说明、类型信息、任务模板、验收标准。 它们的作用,是让 Agent 动手前少猜一点。 Sensors 是行动后的反馈。 比如测试、类型检查、linter、结构规则、日志、浏览器截图、trace、code review agent。 它们的作用,是让 Agent 做完后能回到真实世界里校验。 只写 Guides,容易变成"规矩很多,但不知道有没有用"。 只靠 Sensors,Agent 会不断撞墙,再根据报错修回来。 Harness 不是单点组件。 它更像一组前后咬合的控制。 图 2:Guides 和 Sensors 的反馈闭环 更细一点,可以把它们分成两类。 一类是确定性的:类型检查、单元测试、依赖边界、格式化、静态分析。这些便宜、快、可靠,适合每次都跑。 另一类是语义性的:LLM review、架构审查、需求理解、行为判断。这些更贵,也没那么稳定,但能处理测试不好表达的问题。 从团队实践看,刚开始搭 Harness,没必要急着把所有东西都交给另一个 LLM 来评。 机械能检查的,就先机械检查。 模型最适合放在那些确实需要语义判断的位置:有没有误解需求,方案是不是绕开了现有抽象,测试是不是只是在迎合实现,代码是不是在制造新的复杂度。 人更适合留在更少、更关键的位置。 人不必回到逐行盯代码的状态,更适合看目标、边界、风险和取舍。 ### 状态接班 Anthropic 的长任务 Harness 文章,讲的是另一个很熟悉的问题:Agent 做长项目时会断档。 第一轮做了一半,上下文快满了。 下一轮进来,不知道前面到底做过什么。 项目稍微像样一点,又可能提前宣布完成。 这不只是模型能力问题,更像交接班问题。 Anthropic 的做法很朴素:第一轮 initializer agent 先搭环境,生成 feature list、progress file、git repo 和启动脚本。后续 coding agent 每次开始时,先读当前目录、git log、进度文件和功能列表,启动服务,跑基础端到端检查,再挑一个还没通过的功能继续做。 这里有意思的不是 JSON 文件这个形式。 而是它把长任务变成了可接手状态。 一个后续 Agent 进入现场时,不再只靠上一轮聊天摘要猜,而是能看到: - 哪些功能还没通过; - 哪些测试步骤定义了"通过"; - 最近提交了什么; - 当前应用能不能启动; - 上一轮留下了什么进度; - 这次只推进哪一个小目标。 长上下文当然有帮助。 但长上下文不等于长期状态管理。 能接手的项目,往往不是文档最多,而是状态最清楚。 ### 太厚会慢 Vercel 那篇删除 80% 工具的文章很有意思。 他们做的是一个内部 text-to-SQL agent。旧版本有很多专门工具:查 schema、找 join、检索 catalog、生成分析计划、校验 SQL、格式化结果。 后来他们把大部分工具删掉,保留一个能执行 bash 的文件系统 agent,让 Claude 直接读 Cube DSL 文件,用 grep、cat、ls 自己探索。 结果反而更好:成功率从 80% 到 100%,平均耗时、步骤数和 token 都下降。 这个案例不宜简单理解成"工具越少越好"。 更准确地说,是他们发现旧 Harness 在替模型做太多选择。 语义层本来就是一组结构清楚、命名稳定、内容可读的文件。Claude 直接读原始文件,比通过一堆中间工具拿摘要更自然。 这个案例补了一个边界: 好的 Harness 不一定更厚。 图 3:厚 Harness 和薄 Harness 的取舍 有时要加约束,有时要删约束。 有时要把工具拆细,有时要把工具收回到一个更通用、更透明的接口。 我会看它能不能让 Agent 更快接近真实上下文,少误解中间抽象,也更容易从失败里恢复。 这点放到团队里尤其明显。 很多团队搭 Agent 时,会自然走向平台化:多接几个 MCP,多包几个工具,多写几层路由,多拆几个角色。 短期看像能力变强,长期看可能只是把模型困在过时抽象里。 一个 Harness 组件,至少要能说清楚:它解决哪类失败,最近有没有触发,关掉以后质量和成本会不会变差。 如果说不清,它就可能已经变成技术债。 ### 小流程起步 如果一个团队明天想试 Harness Engineering,我会从一个小流程开始,先不急着做"大而全的 Agent 平台"。 风险低、输入稳定、验证明确,连续跑几轮,能看出很多问题。 比如: - 技术稿事实核验; - 小型 bug 修复; - 文档与代码一致性检查; - 配置漂移扫描; - 测试失败归因; - PR 风险初筛。 这些流程有个共同点:结果能看见,失败能复盘,权限也容易收住。 它们不一定显得高级,但很适合判断一套 Harness 到底有没有用。 我通常会给每个流程留一张很小的任务卡: - 目标:这次要解决什么 - 边界:哪些明确不做 - 输入:代码、文档、日志、issue、截图 - 可用工具:只读还是可写,哪些工具需要确认 - 验证:要跑哪些命令,留下什么证据 - 状态:候选、已验证、已提交怎么区分 - 停止:做到什么可以停,遇到什么需要停 - 回写:失败经验写回哪里 这张卡不复杂,它只是把几个关键问题摆在桌面上: 任务怎么开始。 怎么验证。 谁能改外部状态。 什么叫完成。 错了怎么留痕。 下一轮怎么接手。 如果这几项说不清,Agent 也许能跑起来,但后面的 review、合并、回滚和接手都会很费劲。 跑完几轮以后,哪些东西值得固化,通常会很清楚。 总是忘记读某份文档,那份文档多半要变成入口地图。 总是改错层级,可以补依赖边界检查。 总是测试不完整,可以补验证模板。 总是误解业务规则,可以把规则搬进仓库。 总是人工重复同一类 review,再考虑 review skill 或 linter。 某个约束一个月都没触发,就可以关掉试试。 ### 最后 Model、Tool、Skill、Sub-agent、Harness 这些词,分开看都不难。 难的是放到真实工程里,它们很快会缠在一起。 模型会提出动作,工具会产生副作用,Skill 会沉淀团队经验,Sub-agent 会带来分工和合并问题,Harness 则要把上下文、状态、反馈和权限串起来。 所以我现在看 Harness Engineering,不太把它当成一个新名词。 它更像是软件工程在 Agent 时代重新露出来的一组老问题: - 上下文怎么组织。 - 状态怎么提交。 - 反馈怎么进入下一轮。 - 权限怎么收口。 - 质量怎么持续清理。 - 人的判断放在哪里。 - 旧约束什么时候该删。 模型越来越强以后,工程不会消失。 它只是从"我亲手写每一行代码",更多转向"我设计一个能让 Agent 稳定工作的现场"。 这个现场不需要一开始就很大。 但要清楚、可查、可验、可回滚。 还要留一个出口: 当模型已经不再需要某个约束时,我们要舍得把它删掉。