欢迎光临
我们一直在努力

Harness 到底指什么:Coding Agent 时代的运行时边界、工程纪律与业务分层

目录

一、为什么今天必须重新理解 Harness

二、几个定义:Harness 的宽口径与窄口径

(一)不同作者使用 harness 的范围并不完全一致

(二)收敛Harness 窄口径

三、Harness 不是 SDD,Spec 也不是 Harness

四、Coding Agent 的平台层:harness 应该提供什么

(一)上下文管理:决定模型此刻应该知道什么

(二)记忆管理:决定跨 run 应该继承什么

(三)工具调用:让模型通过受控接口改变世界

(四)权限与 sandbox:让 agent 有能力,但不能越界

(五)Subagent 编排:隔离复杂任务,降低上下文污染

(六)Skill 机制:把可复用行为封装成可装载能力

(七)Hook 机制:在生命周期关键点注入业务约束

(八)运行闭环:让 agent 不会半路消失

五、业务工程是什么:建在 harness 之上的一组 spec

(一)工作流主干:任务从哪里开始,到哪里结束

(二)阶段契约:每个阶段产出什么,如何放行

(三)原子工具:阶段做事时调用哪些能力

(四)领域知识:判断好坏所依赖的背景

六、为什么不该轻易改 harness

(一)harness 本身一直在高速迭代

(二)harness 的复杂度远超直觉

(三)绕开 harness 会破坏 SDD 的工程纪律

(四)业务团队最稀缺的不是平台能力,而是清晰 spec

七、一个典型反例:全量注入 memory/ 目录

(一)典型的乱改 harness的经典问题

(二)分层治理的正确做法

八、业务侧应该怎么用 harness

(一)把 AGENTS.md 写成地图,而不是百科全书

(二)把 docs/ 当作记录系统

(三)把 workflow 写成状态机

(四)把 skill 写小、写专、写可验证

(五)把工具输出设计成 agent 可读

(六)把验证前移,而不是事后人工兜底

九、什么时候可以做 harness engineering

十、一个更准确的分层模型

第一层:模型层

第二层:Harness 层

第三层:Spec 层

第四层:Evidence 层

第五层:Governance 层

十一、写给业务团队的实践原则

原则一:不要把 harness 当业务代码改

原则二:把 spec 当一等产物

原则三:上下文要导航,不要堆砌

原则四:阶段要有 gate

原则五:工具要可读、可控、可审计

原则六:skill 要小而专

原则七:记忆要可删除

原则八:不要用 hook 绕过平台

原则九:证据比总结重要

原则十:平台问题平台化,业务问题 spec 化

十二、结语:克制是 Coding Agent 时代的工程纪律

参考文章列表


干货分享,感谢您的阅读!

过去一年,AI 编程领域有一个词开始频繁出现:harness

它不是一个新词。传统软件工程里,test harness 指测试夹具;硬件工程里,wire harness 指线束;安全工程里,harness 常常表示把一个不稳定对象包起来,让它在可控边界内运行。但到了 Coding Agent 语境里,这个词开始有了新的重量。

它不再只是“包一层工具调用”的小组件,而是指向一个更大的工程事实:

当模型开始从“回答问题”变成“持续执行任务”,真正决定 agent 能不能可靠工作的,不只是模型能力,而是模型外部那一整套运行时环境。

这套环境包括上下文怎么进来、工具怎么调用、权限怎么限制、任务怎么拆分、状态怎么保存、失败怎么恢复、长任务怎么交接、结果怎么验证。它像汽车的底盘、方向盘、刹车、传动系统和仪表盘。模型是发动机,但没有 harness,发动机只会空转、乱冲,或者在第一个复杂路口熄火。

所以,讨论 harness,其实不是在讨论一个术语,而是在讨论 Coding Agent 时代的软件工程边界:什么应该由平台负责,什么应该由业务负责;什么是 agent runtime 的问题,什么是业务 spec 的问题;什么可以配置,什么不该魔改。

我写这篇文章本质上想回答四个问题:

  • Harness 到底是什么?

  • 为什么 harness 不是 spec,也不是 SDD?

  • 业务工程应该建在 harness 之上,而不是改 harness 本身。

  • 一个成熟团队应该如何围绕 harness 组织自己的 agent 工程实践?

  • 一、为什么今天必须重新理解 Harness

    早期使用 LLM 写代码时,人和模型之间的关系很简单:人提出问题,模型给出代码片段,人复制、修改、运行、调试。这个阶段真正的工作流还掌握在人手里,模型只是一个高级补全器。

    后来出现了 Copilot、Cursor、Claude Code、Codex CLI 这类 Coding Agent,关系变了。模型不再只是给出建议,而是可以读仓库、改文件、跑测试、看日志、提交 patch,甚至在一个任务上连续工作数小时。

    这时,问题就不再是“模型会不会写代码”,而是:

    • 它知道现在该看哪些上下文吗?

    • 它知道哪些文件不能改吗?

    • 它知道什么时候应该停下来问人吗?

    • 它知道测试失败后该怎么归因吗?

    • 它知道长任务中间状态怎么保存吗?

    • 它知道上下文窗口不够时应该压缩什么、丢弃什么、保留什么吗?

    • 它知道多个 agent 并行工作时如何隔离、交接和收敛吗?

    这些问题不是单次 prompt 能解决的。它们属于运行时工程。

    也就是说,Coding Agent 的可靠性并不只来自模型参数,而来自三层东西的共同作用:

    • 第一层是 Model,也就是基础模型能力。
    • 第二层是 Harness,也就是围绕模型构建的 agent runtime:上下文、工具、权限、状态、循环、反馈、隔离、验证。
    • 第三层是 Spec,也就是业务侧写给 agent 执行的任务契约、工作流、领域规则和验收标准。

    很多团队刚开始做 AI 工程时,会把这三层混在一起。模型答错了,就改 prompt;prompt 不够,就写一堆规则;规则爆炸了,就用 hook 全量注入;上下文炸了,就自己做 memory;memory 又失控,就继续补丁。最后形成一个脆弱、不可升级、不可审计的“土法 agent runtime”。

    这就是为什么需要认真讨论 harness。

    Harness 的价值不是“让模型多几个工具”,而是把一个不稳定的语言模型,放进一个可控、可恢复、可验证、可演化的工程系统里。

    二、几个定义:Harness 的宽口径与窄口径

    (一)不同作者使用 harness 的范围并不完全一致

    OpenAI 在 “Harness engineering: leveraging Codex in an agent-first world” 中,把工程师的新职责描述为设计环境、明确意图、构建反馈回路,让 Codex agents 能可靠工作。这里的 harness engineering 不是写业务代码,而是围绕 agent 构建可执行环境、工具、约束和反馈系统。

    Anthropic 在 Claude Agent SDK 文章里提到,驱动 Claude Code 的 agent harness,也可以用来驱动其他类型的 agent。这个说法把 Claude Code 背后的 agent runtime 抽象成一个可复用的 SDK 层。

    Simon Willison 在 “How coding agents work” 里用得更宽。他说 coding agent 是一个 LLM 的 harness,通过隐藏 prompt 和 callable tools 扩展模型能力。在这个口径下,Claude Code、Cursor、Codex CLI 这类完整产品都可以被称作 harness。

    LangChain 那类文章常用一句更抽象的公式:

    Agent = Model + Harness.

    这个公式很有用。它告诉我们:agent 不是模型本身,而是模型被某套运行机制包裹之后形成的系统。

    (二)收敛Harness 窄口径

    但在工程讨论中,harness 的范围必须收敛,否则边界会失真。

    如果把整个产品都叫 harness,那么 CLI、IDE 插件、Web UI、权限弹窗、命令面板、协作界面都算 harness。这个口径适合做产品分析,但不适合讨论工程分层。因为业务工程的边界会被推到 UI 之外,很多真正需要治理的问题反而说不清楚。

    如果把 harness 只理解成“模型调用接口 + tools schema”,范围又太窄。上下文压缩、长期记忆、subagent 隔离、任务状态、hook、权限、sandbox、tool result trimming 这些关键机制都会被下放给业务团队。结果是每个业务仓库都要自己写一套半吊子的 agent runtime。

    因此,本文采用一个偏窄但仍然完整的定义:

    Harness 是 Coding Agent 的平台运行时层:它负责把模型包进一个可控执行环境,使模型能够在上下文、工具、权限、状态、反馈和验证机制的约束下持续完成任务。

    更具体地说,harness 包括:

    • agent loop:模型如何观察、计划、调用工具、接收结果、继续行动;

    • context management:哪些信息进入窗口,哪些信息被压缩、索引、延迟加载;

    • memory management:跨会话状态、项目规则、偏好、历史证据如何保存和注入;

    • tool runtime:工具如何注册、授权、调用、超时、截断、回传;

    • sandbox / permission:文件系统、网络、shell、凭据、危险命令如何被限制;

    • subagent orchestration:多个 agent 如何拆分任务、隔离上下文、交接结果;

    • hooks / lifecycle:会话开始、压缩前后、结束前、工具调用前后如何切入;

    • feedback loop:测试、审查、日志、指标、评估、人工反馈如何回流;

    • state and handoff:长任务如何保存进度、恢复现场、避免重复劳动;

    • observability:agent 的行为、证据、决策路径如何被记录和审计。

    三、Harness 不是 SDD,Spec 也不是 Harness

    在 Coding Agent 语境里,另一个常被混用的词是 SDD,也就是 Spec-Driven Development。

    SDD 讨论的是业务交付方式:人不再主要通过手写代码和 AI 协作,而是通过写 spec 来定义需求、设计、约束、验收和演进路径。代码变成 spec 的派生产物。

    Harness engineering 讨论的是 agent 平台运行方式:如何让 agent 在长期任务中稳定执行、正确使用工具、保留必要上下文、避免越权、形成反馈闭环。

    两者不是同一层。

    SDD 关心的是:

    我们要构建什么?它应该满足什么需求?阶段怎么切?验收标准是什么?领域规则是什么?

    Harness engineering 关心的是:

    Agent 如何运行?上下文如何管理?工具如何调用?权限如何限制?失败如何恢复?状态如何交接?

    因此可以这样分层:

    Model 负责生成能力。 Harness 负责运行能力。 Spec 负责业务意图。

    SDD 是上层工程范式,Harness Engineering 是下层运行时范式。没有 spec,harness 只是在空转;没有 harness,spec 只是文档,无法稳定执行。

    Spec 和 harness 也不是包含关系。

    Spec 是业务侧产物,通常包括需求说明、设计文档、阶段契约、任务分解、验收标准、领域知识、参考实现、禁止事项。它们可以被 agent 读取、引用、执行,但它们本身不是 agent runtime。

    Harness 是平台侧能力,通常由 Claude Code、Codex、Cursor、Devin、LangGraph、内部 agent framework 或其他 SDK 提供。它负责让 spec 被正确加载、执行、验证和收敛。

    一个简单判断标准是:

    如果一个东西描述“要做什么、做到什么程度、按什么业务规则判断好坏”,它通常是 spec。 如果一个东西决定“agent 如何看到信息、如何行动、如何受限、如何恢复、如何验证”,它通常是 harness。

    比如:

    • “支付链路必须支持幂等重试”是 spec。

    • “agent 修改支付代码前必须先读取 payments/README.md”是 spec,也可能是项目规则。

    • “AGENTS.md 只作为索引,不全量塞入所有背景资料”是 harness 使用策略。

    • “上下文窗口满了时如何压缩历史消息”是 harness。

    • “测试失败后 agent 必须附上失败日志和修复证据”是 spec 中的验收约束。

    • “shell 输出超过一定长度如何截断并保留 tail”是 harness。

    • “实现阶段完成后进入 review 阶段,review 不通过不得 merge”是业务工作流 spec。

    • “subagent 如何创建独立上下文并回传摘要”是 harness。

    这层边界一旦混淆,团队就会陷入两个极端。

    第一个极端是“平台万能论”:以为只要 harness 足够强,业务不需要写清楚 spec。结果 agent 很会跑,但不知道往哪跑。

    第二个极端是“业务全包论”:以为业务仓库可以用 prompt、hook、脚本把所有 agent 行为都管住。结果业务团队开始重写上下文管理、memory、权限系统、任务调度,最后得到一个不可维护的影子 harness。

    正确的姿势是:业务写 spec,平台供 harness。业务组合 harness 原语,但不重写 harness 机制。

    四、Coding Agent 的平台层:harness 应该提供什么

    以 Claude Code、Claude Agent SDK、Codex CLI、Cursor Agent 这类系统为参照,一个成熟的 Coding Agent harness 至少应该提供以下能力。

    (一)上下文管理:决定模型此刻应该知道什么

    模型看到的不是“整个世界”,而是当前上下文窗口。这个窗口是稀缺资源。上下文管理的本质,是在有限窗口里做信息预算。

    它要回答:

    • 当前任务需要哪些文件、规则、历史事实?

    • 哪些内容应该直接放入窗口?

    • 哪些内容应该作为索引或引用存在?

    • 哪些内容可以通过工具按需读取?

    • 哪些历史应该压缩?

    • 哪些证据不能在压缩中丢失?

    • 哪些陈旧规则应该被淘汰?

    很多团队犯的第一个错误,就是把上下文管理理解成“多塞资料”。比如把所有文档、所有 memory、所有历史决策在会话开始时一次性注入。短期看 agent 好像“知道得更多”,长期看只会造成三件事:

    • 第一,窗口被垃圾信息占满,真正任务上下文被挤出去。
    • 第二,陈旧规则和新规则并存,agent 无法判断哪个更可信。
    • 第三,信息没有层级,模型只能局部模式匹配,而不能有意识地导航。

    更好的做法是把上下文分层:

    • 短小稳定的入口索引进入默认上下文;

    • 任务相关的阶段契约按需加载;

    • 大型背景材料放在 docs/、knowledge base 或工具索引中;

    • 历史运行证据通过结构化 state 或 handoff 摘要保留;

    • 低价值中间过程不进入长期记忆。

    OpenAI 那篇 Codex 实践文章里,一个非常重要的经验就是:不要把 AGENTS.md 当百科全书,而要把它当地图。地图不承载所有知识,只告诉 agent 去哪里找权威信息。

    这其实是上下文工程的核心原则:

    上下文不是越多越好,而是越可导航、越新鲜、越可验证越好。

    (二)记忆管理:决定跨 run 应该继承什么

    上下文管理处理的是当前窗口,记忆管理处理的是跨会话、跨任务、跨阶段的持久信息。

    它包括:

    • 项目级规则;

    • 用户偏好;

    • 已确认的架构决策;

    • 已踩过的坑;

    • 当前任务进度;

    • 未完成事项;

    • 关键证据;

    • 需要下次恢复的状态。

    记忆不是“把所有过去都保存下来”。记忆的本质是选择性遗忘。

    如果一个团队用 memory/ 目录保存所有经验,然后每次会话启动用 hook 全量注入,这不是记忆管理,而是上下文污染。真正的记忆系统必须有压缩、索引、优先级、新鲜度、所有权和删除机制。

    好的记忆应该满足四个条件:

    • 第一,它是结构化的。agent 能分辨这是项目规则、阶段状态、设计决策还是临时笔记。
    • 第二,它是可定位的。agent 能通过索引找到来源,而不是在一大坨文本里猜。
    • 第三,它是可淘汰的。过期规则能被删除或降权。
    • 第四,它是可审计的。关键结论背后有证据,不是凭空留下的一句话。

    (三)工具调用:让模型通过受控接口改变世界

    Coding Agent 真正产生副作用,不是因为它会说话,而是因为它能调用工具。它能读文件、写文件、执行 shell、跑测试、访问 GitHub、启动浏览器、查询日志、打开 PR、调用 MCP server、连接 SaaS。

    工具调用是 agent 从“文本生成器”变成“工程执行者”的分界线。因此,harness 必须管理工具调用的协议和边界:

    • 工具如何注册?

    • 输入输出 schema 是什么?

    • 哪些工具需要用户确认?

    • 哪些命令禁止执行?

    • 超时如何处理?

    • 大输出如何截断?

    • 失败如何回传?

    • 工具结果如何进入上下文?

    • 凭据如何隔离?

    • 副作用如何记录?

    业务侧可以决定“这个项目需要哪些工具”,但不应该自己绕开 harness 去执行危险操作。否则权限、审计、回滚和上下文归因都会失效。

    一个成熟团队应该把工具分成三类:

    • 第一类是只读工具,比如扫描仓库、搜索代码、读取日志、查询指标。它们风险低,适合频繁调用。
    • 第二类是可逆写工具,比如修改文件、生成 patch、创建临时 worktree。它们需要保留 diff 和证据。
    • 第三类是高风险副作用工具,比如部署、删除、发邮件、改数据库、合并 PR。它们必须经过更严格的 gate、人类确认或自动化策略限制。

    (四)权限与 sandbox:让 agent 有能力,但不能越界

    没有 sandbox 的 agent,本质上是一个带 shell 的不稳定自动化脚本。它可能读到不该读的凭据,删掉不该删的文件,执行不该执行的命令,或者把内部信息发到外部服务。Harness 必须提供权限边界:

    • 文件系统读写范围;

    • 网络访问范围;

    • shell 命令白名单或黑名单;

    • secret 管理;

    • 外部 API 调用权限;

    • 用户确认机制;

    • workspace / worktree 隔离;

    • 临时环境销毁;

    • 审计日志。

    业务工程不应该绕开这些边界。你可以在 spec 里声明某个阶段需要部署权限,也可以在工具配置里注册特定命令,但不应该让 agent 通过一个自写脚本绕过平台权限系统。

    因为权限不是“麻烦的弹窗”,而是 agent 工程纪律的一部分。

    (五)Subagent 编排:隔离复杂任务,降低上下文污染

    复杂任务不能总让一个 agent 从头干到尾。单一上下文会膨胀,注意力会漂移,历史错误会污染后续判断。Subagent 的价值在于:

    • 任务隔离;

    • 上下文隔离;

    • 专业角色隔离;

    • 并行探索;

    • 证据收敛;

    • 降低主 agent 负担。

    入口 agent 不一定亲自做所有事。它可以派出:

    • repo-scanner:只负责扫描仓库结构;

    • requirement-analyst:只负责提炼需求;

    • design-reviewer:只负责评审设计;

    • test-runner:只负责跑测试和归因;

    • security-reviewer:只负责找安全风险;

    • release-checker:只负责发布前检查。

    但 subagent 不是业务方随手拼出来的“多开几个模型”。真正的 subagent 机制需要 harness 支持:独立上下文、工具权限、结果摘要、状态回传、失败处理、并行调度和收敛策略。

    业务侧可以定义“派什么角色、产出什么证据、如何验收”,但不应该重写 subagent runtime。

    (六)Skill 机制:把可复用行为封装成可装载能力

    Skill 是 agent 工程里非常关键的一层。它介于工具和 spec 之间。

    工具通常是原子能力,比如运行命令、读文件、查 API。Spec 通常是业务契约,比如“实现这个需求必须满足哪些约束”。Skill 则是可复用的行为单元,比如:

    • 如何做视觉回归测试;

    • 如何审查数据库 migration;

    • 如何分析线上日志;

    • 如何处理某类前端 bug;

    • 如何生成 release note;

    • 如何跑某个项目的 E2E;

    • 如何根据 design doc 实现接口。

    一个好的 skill 通常包含:

    • 触发条件;

    • 输入要求;

    • 使用步骤;

    • 可调用工具;

    • 输出格式;

    • 验收标准;

    • 风险提醒;

    • 常见失败处理。

    Harness 负责 skill 如何被发现、加载、组合、授权和执行;业务工程负责 skill 里面写什么。

    这也是业务团队最应该投入的地方之一。因为 skill 是业务经验的沉淀方式。它比一次性 prompt 更稳定,比大段文档更可执行,比工具脚本更贴近 agent 的决策过程。

    (七)Hook 机制:在生命周期关键点注入业务约束

    Hook 是 harness 给业务留下的扩展点。

    常见 hook 包括:

    • SessionStart:会话开始时加载项目入口规则;

    • PreToolUse:工具调用前检查权限或参数;

    • PostToolUse:工具调用后记录结果或提取证据;

    • PreCompact:上下文压缩前保存关键状态;

    • PostCompact:压缩后恢复必要索引;

    • Stop:会话结束前检查是否完成闭环。

    Hook 的危险在于,它看起来像万能胶水。很多团队一遇到问题就写 hook,最后 hook 变成绕过 harness 的后门。

    好的 hook 应该是轻量、声明式、可审计的。它应该做生命周期补充,而不是接管 agent runtime。

    比如:

    • 在 SessionStart 注入一个短索引,可以。

    • 在 SessionStart 全量注入 memory/ 下所有文件,不可以。

    • 在 Stop 阶段检查任务状态是否同步,可以。

    • 在 Stop 阶段自动执行部署,不可以,除非有明确 gate 和权限设计。

    • 在 PreCompact 保存关键 handoff 摘要,可以。

    • 在 PreCompact 把所有历史原样复制到另一个文件等待下次全量注入,不可以。

    Hook 的原则是:只在 harness 允许的生命周期点补充业务信息,不用 hook 发明另一套 harness。

    (八)运行闭环:让 agent 不会半路消失

    一个真正可用的 Coding Agent,不是能改代码就行,而是必须形成闭环。

    闭环包括:

  • 读取任务和当前状态;

  • 判断所处阶段;

  • 收集必要上下文;

  • 制定局部计划;

  • 调用工具执行;

  • 运行测试或检查;

  • 收敛证据;

  • 更新状态;

  • 判断完成、继续或阻塞;

  • 给出可审查交付物。

  • 很多 agent 失败,不是失败在代码能力,而是失败在闭环缺失:

    • 做了实现,没跑测试;

    • 跑了测试,没解释失败;

    • 改了代码,没同步状态;

    • 发现阻塞,没明确阻塞条件;

    • 做了一半,上下文压缩后忘了进度;

    • 产出了结果,没有证据;

    • 任务结束时没有交接下一步。

    Harness 的核心使命,就是让这个闭环尽可能稳定。业务 spec 的使命,是把每个阶段的放行条件写清楚。

    五、业务工程是什么:建在 harness 之上的一组 spec

    如果 harness 是运行时底座,那么业务工程的产物是什么?答案是:一组可执行的 spec。

    这里的 spec 不是单一文档,而是一个分层系统。它至少包括四类东西。

    (一)工作流主干:任务从哪里开始,到哪里结束

    工作流主干定义整个交付过程的阶段顺序和状态机。它回答:

    • 当前任务有哪些阶段?

    • 每个阶段的入口条件是什么?

    • 每个阶段完成后进入哪里?

    • 哪些情况需要阻塞?

    • 哪些情况需要人工确认?

    • 最终完成标准是什么?

    比如一个常见软件交付流程可以是:

  • intake:理解需求;

  • discovery:扫描仓库和相关背景;

  • design:形成设计方案;

  • implementation:实现;

  • review:自审和 subagent 审查;

  • verification:测试、日志、指标、E2E;

  • handoff:总结证据和后续事项。

  • 这个主干不是 agent runtime。它只是告诉 harness:任务应该按什么业务阶段推进。

    (二)阶段契约:每个阶段产出什么,如何放行

    阶段契约是 SDD 的核心。它把“做完了”变成可判断的条件。

    一个阶段契约应该写清楚:

    • 输入是什么;

    • 允许读取哪些资料;

    • 允许调用哪些工具;

    • 必须产出什么;

    • 验收标准是什么;

    • 失败如何处理;

    • 什么时候必须停下来问人;

    • 产物如何交给下一阶段。

    比如 design 阶段的契约可以要求:

    • 必须列出涉及模块;

    • 必须说明数据流变化;

    • 必须列出兼容性风险;

    • 必须引用至少一个现有实现;

    • 不得修改代码;

    • 不确定关键需求时必须阻塞。

    Implementation 阶段的契约可以要求:

    • 只实现已通过 design gate 的方案;

    • 每次修改必须有 diff;

    • 必须运行相关测试;

    • 不得顺手重构无关代码;

    • 测试失败必须归因;

    • 不能通过删除测试来让 CI 通过。

    阶段契约越清楚,agent 越容易稳定工作。

    (三)原子工具:阶段做事时调用哪些能力

    业务 spec 还需要定义可复用的原子能力,比如:

    • repo scan;

    • dependency graph;

    • API schema check;

    • database migration check;

    • visual diff;

    • E2E runner;

    • observability query;

    • PR review checklist;

    • release note generator;

    • ticket sync;

    • feature flag check。

    这些原子能力不应该知道自己属于哪个阶段。它们只负责输入、输出和失败模式。这样才能被多个阶段复用。

    好的原子工具应该有明确边界:

    • 输入格式稳定;

    • 输出结构化;

    • 副作用可控;

    • 失败信息可诊断;

    • 可被 harness 记录和审计。

    (四)领域知识:判断好坏所依赖的背景

    领域知识不一定被直接 invoke,但它影响 agent 的判断。

    它包括:

    • 系统架构;

    • 业务术语;

    • 关键流程;

    • 设计原则;

    • 禁止事项;

    • 参考实现;

    • 历史事故;

    • 性能边界;

    • 安全要求;

    • 合规规则。

    领域知识最容易腐烂,所以不能写成一个巨大的“宝典”。更好的方式是结构化:

    • 用短 AGENTS.md 做索引;

    • 用 docs/ 作为记录系统;

    • 每篇文档有 owner、更新时间、适用范围;

    • 重要规则能被机械检查;

    • 过期知识可以被删除;

    • agent 只按需读取相关文档。

    业务工程的差异化,不是看谁的 harness 改得深,而是看谁的 spec 写得好。

    六、为什么不该轻易改 harness

    很多团队在使用 Coding Agent 时,会自然产生一个冲动:平台默认行为不够贴合业务,那我能不能自己改一下?

    比如:

    • 自己接管上下文压缩;

    • 自己做一套 memory 注入;

    • 自己实现 subagent 调度;

    • 绕过工具权限系统;

    • 用 hook 偷偷塞入大量资料;

    • 写脚本自动执行高风险操作;

    • 用 prompt 模拟平台本该提供的状态机。

    这些做法短期看很爽,长期看几乎都会变成债务。原因有四个。

    (一)harness 本身一直在高速迭代

    Claude Code、Codex、Cursor 这些工具的底层机制都在快速变化。上下文压缩、skill 加载、工具调用、权限模型、sandbox、长任务 handoff、review loop,这些能力会持续升级。

    如果你没有魔改 harness,就能直接享受平台升级。

    如果你绕过了 harness,每次升级都要重新验证自己的补丁是否仍然正确。平台本来替你吸收的复杂度,又回到了业务团队身上。

    (二)harness 的复杂度远超直觉

    上下文管理看起来很简单:不就是把需要的信息塞给模型吗?实际不是。

    它涉及:

    • token budget;

    • cache 命中;

    • 信息优先级;

    • 长短期记忆分层;

    • 历史摘要;

    • 证据保真;

    • 冲突规则;

    • 新鲜度;

    • 引用导航;

    • 压缩时机;

    • 恢复策略;

    • 多 agent 交接。

    你以为自己写了 200 行脚本替代 memory,实际只是把平台团队已经处理过的几百个边界情况重新拉回来了。

    工具调用也一样。一个 shell wrapper 很容易写,但权限、超时、截断、审计、回滚、secret 隔离、并发冲突、失败重试,都会慢慢找上门。

    (三)绕开 harness 会破坏 SDD 的工程纪律

    SDD 的价值,不是“把需求写成文档”这么简单,而是把业务交付变成可阶段化、可验收、可审计的过程。

    这个过程依赖 harness 提供的硬边界:

    • subagent 上下文隔离;

    • 阶段 gate;

    • 工具权限;

    • 状态同步;

    • 测试证据;

    • handoff 摘要;

    • 人工确认点。

    你一旦绕开 harness,这些约束就可能一起塌掉。

    比如,业务为了方便,让 agent 在 hook 里自动加载所有历史文档。看起来只是优化记忆,实际破坏了上下文预算、信息新鲜度、压缩策略和阶段隔离。

    再比如,业务为了提速,让 agent 直接执行部署脚本。看起来只是减少确认,实际绕开了权限、审计和发布 gate。

    (四)业务团队最稀缺的不是平台能力,而是清晰 spec

    大多数 agent 失败,并不是因为平台少一个高级机制,而是因为业务没有写清楚:

    • 需求到底是什么;

    • 什么算完成;

    • 哪些文件是权威来源;

    • 哪些约束不能破;

    • 哪些测试必须跑;

    • 哪些风险必须暴露;

    • 不确定时该问谁;

    • 阶段之间如何交接。

    很多“我要改 harness”的冲动,本质上是 spec 没写清楚之后的补偿行为。

    正确做法不是先改 harness,而是先问:

    这个问题能不能通过更清楚的 spec、更好的阶段契约、更小的 skill、更明确的工具边界解决?

    如果能,就不要动 harness。

    七、一个典型反例:全量注入 memory/ 目录

    (一)典型的乱改 harness的经典问题

    假设一个团队在仓库里建了一个 memory/ 目录,里面放所有项目经验:

    • 架构笔记;

    • 历史事故;

    • 用户偏好;

    • 旧需求;

    • 设计争论;

    • bug 复盘;

    • prompt 片段;

    • 临时 TODO;

    • 上次 agent 的总结。

    然后他们写了一个 SessionStart hook:每次 agent 会话启动,把 memory/ 下所有文件全部注入上下文。

    这看起来像“增强记忆”,实际是典型的乱改 harness。问题至少有五个。

    • 第一,窗口会爆。上下文窗口是稀缺资源,全量注入会挤掉当前任务真正相关的代码、日志和测试结果。
    • 第二,信息没有优先级。模型无法区分项目硬约束、历史参考、临时想法和过期 TODO。
    • 第三,陈旧知识会污染判断。旧规则一旦没有淘汰机制,就会和新规则一起进入窗口。
    • 第四,压缩策略失效。平台本来会根据上下文价值做压缩和保留,你全量注入等于把所有内容强行设为“重要”。
    • 第五,维护责任转移。原本 harness 负责的记忆分层、上下文预算、信息恢复,现在都变成业务团队的隐性债务。

    (二)分层治理的正确做法

    正确做法不是全量注入,而是分层治理:

    • AGENTS.md 只做短索引;

    • docs/ 作为权威知识库;

    • run state 保存当前任务进度;

    • .inbox 或类似机制保存待处理输入;

    • hook 只注入当前阶段必要的轻量信息;

    • 大文档通过工具按需检索;

    • 过期记忆定期删除或降权;

    • 关键结论必须链接到证据来源。

    换句话说:记忆不是堆资料,而是设计可恢复的注意力。

    八、业务侧应该怎么用 harness

    不改 harness,不等于什么都不能做。相反,业务团队应该非常主动地组合 harness 暴露的原语。

    可以从六个方向入手。

    (一)把 AGENTS.md 写成地图,而不是百科全书

    AGENTS.md 应该短、稳、可导航。

    它适合放:

    • 项目一句话说明;

    • 仓库结构索引;

    • 关键文档入口;

    • 常用命令;

    • 必须遵守的少量硬规则;

    • 当前工作流入口;

    • 不确定时应该读取哪里。

    它不适合放:

    • 大段架构历史;

    • 所有业务知识;

    • 所有 API 说明;

    • 所有设计争论;

    • 大量 prompt 技巧;

    • 已过期的临时规则。

    AGENTS.md 的最佳形态不是“知识本体”,而是“知识路由”。

    (二)把 docs/ 当作记录系统

    业务知识应该进入结构化 docs/,而不是堆进 prompt。

    好的 docs/ 应该有:

    • index;

    • 设计文档;

    • 架构文档;

    • 决策记录;

    • 参考实现;

    • 操作手册;

    • 测试策略;

    • 发布流程;

    • 常见故障;

    • 文档 owner 和更新时间。

    这样 agent 可以通过 AGENTS.md 找到入口,再按任务读取相关文档,而不是一开始就被所有知识淹没。

    (三)把 workflow 写成状态机

    不要只写“请完成这个需求”。要写清楚 agent 应该如何推进:

    • intake 完成后进入 discovery;

    • discovery 必须产出影响范围;

    • design 未通过不得 implementation;

    • implementation 后必须 self-review;

    • verification 必须有测试证据;

    • release 前必须通过 checklist;

    • 阻塞时必须说明原因和缺口。

    状态机的价值是减少漂移。Agent 不再凭感觉推进,而是按阶段契约推进。

    (四)把 skill 写小、写专、写可验证

    不要写一个“万能开发 skill”。那只是另一个大 prompt。

    好的 skill 应该像一个小型 SOP:

    • 什么时候用;

    • 做哪几步;

    • 调哪些工具;

    • 看哪些文件;

    • 产出什么格式;

    • 如何判断成功;

    • 常见失败怎么办。

    例如:

    • “React 视觉回归检查 skill”;

    • “数据库 migration review skill”;

    • “API breaking change 检查 skill”;

    • “日志归因 skill”;

    • “PR 自审 skill”。

    Skill 是业务经验沉淀的最佳颗粒度之一。

    (五)把工具输出设计成 agent 可读

    很多工具是给人看的,不是给 agent 看的。比如超长日志、彩色终端输出、复杂 HTML、噪声巨大的测试报告。Agent 需要结构化、可摘要、可定位的输出。

    工具应该尽量提供:

    • JSON 输出;

    • 错误分类;

    • 关键日志 tail;

    • 失败用例列表;

    • 相关文件路径;

    • 可复现命令;

    • 建议下一步;

    • 证据引用。

    这不是“让工具更漂亮”,而是提升 agent 的可操作性。

    (六)把验证前移,而不是事后人工兜底

    Agent 交付必须有证据。证据越早进入闭环,越能减少后期人工审查负担。

    可以要求每个阶段产出:

    • 读取过哪些文件;

    • 修改了哪些文件;

    • 跑了哪些命令;

    • 测试结果是什么;

    • 失败如何归因;

    • 哪些风险未解决;

    • 哪些假设需要人工确认。

    没有证据的 agent 输出,只是自然语言自信。

    九、什么时候可以做 harness engineering

    前面一直强调业务不要乱改 harness,但这不等于 harness engineering 不重要。

    恰恰相反,harness engineering 会越来越重要。只是它应该由平台团队、基础设施团队、AI 工程平台团队,或者具备平台视角的人来做,而不是每个业务项目各自魔改。

    适合做 harness engineering 的场景包括:

    • 公司要建设统一 Coding Agent 平台;

    • 多个业务团队需要共享 agent runtime;

    • 需要统一权限、安全、审计和合规;

    • 需要支持长任务、多 agent、批量任务;

    • 需要接入内部工具、CI、日志、指标、工单系统;

    • 需要建立统一的评估和回放机制;

    • 需要对 agent 行为做可观测性和治理;

    • 需要在模型升级时保持业务兼容。

    这类工作应该沉淀为平台能力,而不是散落在各个业务仓库里。

    业务团队可以提出需求,比如:

    • 需要更好的上下文检索;

    • 需要更细的工具权限;

    • 需要某类 hook;

    • 需要 subagent 结果结构化;

    • 需要测试报告自动摘要;

    • 需要 PR review loop;

    • 需要日志和 tracing 对 agent 可读。

    但实现这些需求时,最好通过平台 harness 扩展,而不是在业务层写绕路脚本。

    判断一项改动属于业务 spec 还是 harness engineering,可以问三个问题:

    • 第一,这个机制是否跨项目复用?
    • 第二,它是否影响 agent 如何运行,而不只是影响 agent 做什么?
    • 第三,它是否涉及上下文、权限、工具、状态、循环、sandbox、调度、压缩、审计?

    如果答案多半是“是”,那它大概率属于 harness,不该在单个业务项目里随便实现。

    十、一个更准确的分层模型

    可以用五层来理解 Coding Agent 工程。

    第一层:模型层

    模型层提供语言理解、代码生成、推理、工具调用决策等基础能力。

    它回答:模型能不能理解和生成?

    第二层:Harness 层

    Harness 层提供运行时:上下文、工具、权限、状态、sandbox、agent loop、subagent、memory、hook、反馈闭环。

    它回答:模型如何在工程环境中可靠行动?

    第三层:Spec 层

    Spec 层提供业务意图:需求、设计、阶段契约、验收标准、领域规则、工作流。

    它回答:agent 应该做什么,做到什么标准?

    第四层:Evidence 层

    Evidence 层提供可验证结果:测试、日志、diff、review、指标、截图、trace、PR、部署结果。

    它回答:我们凭什么相信已经做好?

    第五层:Governance 层

    Governance 层提供组织约束:权限、责任、审计、成本、模型选择、升级策略、风险治理。

    它回答:谁可以让 agent 做什么,出了问题如何追责和改进?

    很多讨论只停留在前三层:model、harness、spec。但在真实组织里,evidence 和 governance 同样重要。没有 evidence,agent 输出不可验证;没有 governance,agent 能力越强,风险越大。

    这五层加起来,才是完整的 agentic software engineering。

    十一、写给业务团队的实践原则

    最后,把本文压缩成几条实践原则。

    原则一:不要把 harness 当业务代码改

    业务仓库里不要重写 agent loop、上下文压缩、memory 注入、subagent runtime、权限系统。能配置就配置,能扩展就扩展,不能扩展就向平台提需求。

    原则二:把 spec 当一等产物

    需求 spec、设计 spec、阶段契约、验收标准、领域知识、工具说明,都应该像代码一样被 review、版本化、维护和淘汰。

    原则三:上下文要导航,不要堆砌

    AGENTS.md 做地图,docs/ 做知识库,state 做当前进度,工具按需读取。不要把所有资料塞进窗口。

    原则四:阶段要有 gate

    没有 gate,agent 会滑行;有 gate,agent 才能收敛。每个阶段都要有明确输入、输出、验收和阻塞条件。

    原则五:工具要可读、可控、可审计

    Agent 使用工具不是为了模仿人敲命令,而是为了得到结构化证据。工具输出应该帮助 agent 判断下一步,而不是制造噪声。

    原则六:skill 要小而专

    Skill 是业务经验的封装,不是大杂烩 prompt。一个 skill 只解决一类稳定问题。

    原则七:记忆要可删除

    不能删除的记忆最终会变成污染。每条长期记忆都应该有适用范围、新鲜度和证据来源。

    原则八:不要用 hook 绕过平台

    Hook 是生命周期扩展点,不是后门。用 hook 补充上下文、保存状态、做闭环检查可以;用 hook 接管 runtime 不可以。

    原则九:证据比总结重要

    Agent 说“我完成了”没有意义。它必须给出 diff、测试、日志、截图、review 结果、风险列表和未决事项。

    原则十:平台问题平台化,业务问题 spec 化

    如果问题跨项目、涉及 runtime、权限、状态、工具、上下文,它应该平台化。 如果问题只涉及某个业务流程、阶段、规则、验收,它应该 spec 化。

    十二、结语:克制是 Coding Agent 时代的工程纪律

    Harness 这个词之所以重要,是因为它标志着软件工程重心的迁移。

    过去,工程师主要写代码。 后来,工程师开始写 prompt。 现在,工程师越来越多地在写 spec、设计工具、组织上下文、构建反馈闭环。

    但越是在这个阶段,越要克制。

    不要因为 agent 某次失败,就急着给 harness 打补丁。 不要因为上下文不够,就把所有资料塞进去。 不要因为平台默认行为不完美,就重写一套 memory。 不要因为工具权限麻烦,就绕开 sandbox。 不要因为业务规则复杂,就把它们混进 agent runtime。

    业务工程真正该做的,是把 spec 写清楚,把阶段切干净,把工具设计成 agent 可读,把证据闭环做扎实。

    Harness 是平台层。 Spec 是业务层。 Model 是能力源。 Evidence 是信任基础。 Governance 是组织边界。

    一句话总结:

    业务工程的工作,不是改 harness,而是写好 spec,组合 harness 暴露的原语,让 agent 在正确的边界内稳定完成任务。

    这不是保守,而是专业。

    在 Coding Agent 时代,真正高水平的工程师,不是最会魔改平台的人,而是最清楚什么不该改、什么该沉淀、什么该交给 spec、什么该交给 harness 的人。

    克制不是少做事。 克制是把力气用在真正该做的地方。

    参考文章列表

  • OpenAI:Harness engineering: leveraging Codex in an agent-first world https://openai.com/index/harness-engineering/ 支撑 “harness engineering” 的 OpenAI 口径:设计环境、明确意图、构建反馈回路,让 Codex agents 可靠工作。
  • Anthropic:Building agents with the Claude Agent SDK https://claude.com/blog/building-agents-with-the-claude-agent-sdk 明确提到 “the agent harness that powers Claude Code”,适合支撑 Claude Code SDK / Claude Agent SDK 作为 agent harness 的说法。
  • Anthropic Engineering:Effective harnesses for long-running agents https://www.anthropic.com/engineering/effective-harnesses-for-long-running-agents 适合支撑 long-running agent 场景下的 harness 设计:跨上下文窗口、长期任务、handoff、进度追踪等。
  • Simon Willison:How coding agents work https://simonwillison.net/guides/agentic-engineering-patterns/how-coding-agents-work/ 采用更宽泛的 harness 定义:coding agent 是 LLM 的 harness,通过隐藏 prompt 和 callable tools 扩展模型能力。
  • LangChain:The Anatomy of an Agent Harness The Anatomy of an Agent Harness 可用于支撑 “Agent = Model + Harness” 这类抽象分层。
  • The New Code — Sean Grove / OpenAI 相关访谈或文章整理 Darek M101 可用于支撑 SDD / spec-driven development 的上层范式讨论。 注意这不是 OpenAI 官方原文,更适合作为二手参考。
  • 赞(0)
    未经允许不得转载:171主机测评 » Harness 到底指什么:Coding Agent 时代的运行时边界、工程纪律与业务分层
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址