Skip to content

Harness 设计思想

来自 idea-business 多模块实践的抽象经验。这里记录的是初始化新项目时可复用的思考方式,而不是某个项目的目录结构。

核心观点

Harness 不是一套文件夹,也不是一组 prompt。它是围绕 agent 工作方式设计的工程环境。

好的 harness 会持续回答五个问题:

  1. 谁拥有边界?
  2. 什么算完成?
  3. 下游凭什么相信上游?
  4. 失败后系统如何变聪明?
  5. 哪些信息应该进入 context,哪些应该留在文件系统?

只要这些问题没有被设计清楚,项目越自动化,问题传播越快。


1. 先设计所有权,再设计目录

目录结构只是所有权的投影。真正重要的是回答:

  • 哪些知识是全局的?
  • 哪些能力必须独立进化?
  • 哪些代码只是基础设施?
  • 哪些产物属于具体产品或任务?
  • 哪些状态只是 pipeline 过程记录?

idea-business 的重要经验不是“hub + 多 repo”这个形状本身,而是这个原则:

知识可以集中,业务闭环要独立,基础设施只共享确定性部分。

如果把业务逻辑过早共享,会切断每个场景自己的进化循环。如果完全不共享基础设施,日志、gate、schema、修复经验又会漂移。

初始化项目时先画“所有权地图”,再决定 monorepo、multi-repo、packages、modules、projects 怎么摆。


2. 把 Agent 输出当作声明,不当作事实

Agent 说“完成了”,只是一个声明。Harness 要求系统回答:

  • 产物在哪里?
  • 它是否非空?
  • 它是否符合下游契约?
  • 它是否真的改变了 workspace?
  • 它的质量判断来自谁?

这就是 phase success contract 的抽象形式:

phase 成功不是由执行者自报,而是由可验证证据证明。

这个思想适用于所有自动化边界,不限于 LLM:

  • CLI 成功返回不等于 artifact 可用。
  • judge 给分不等于 gate 通过,blocker 也必须被理解。
  • review-only agent 不等于没有改动,仍要检查 workspace。
  • markdown、HTML、图片、代码都可以是证据,但要有验证方式。

初始化新项目时,每个硬 handoff 都要写清楚“下游凭什么相信它”。


3. 把概率能力包在确定性壳里

LLM、外部 agent、生成式工具都是概率系统。不要把它们直接接到下游。

好的 harness 会在概率系统外面加确定性壳:

  • 输入边界明确:传什么文件、什么 prompt、什么上下文。
  • 调用方式明确:workspace、参数、权限、超时、输出路径。
  • 输出边界明确:必须写什么 artifact,怎么验证。
  • 失败语义明确:缺文件、空文件、schema 错、gate fail、工具不可用要能区分。

抽象原则:

让模型负责判断和生成,让代码负责边界、证据、状态和失败分类。

这条原则能防止 harness 变成“prompt 里祈祷模型守规矩”。规则越关键,越应该被确定性代码或结构化契约承载。


4. Context 是预算,不是仓库

很多 harness 问题不是信息不够,而是无关信息太多。

CLAUDE.mdAGENTS.md、skill、ADR、历史产物、产品档案都在争夺同一个稀缺资源:agent 的注意力。

实践经验:

  • always-on 文件只放每次都会影响行为的规则。
  • 场景知识按需加载,不要常驻。
  • 历史 raw JSON 容易造成 schema contagion。
  • 给 agent 精炼事实,比让它自己读一堆旧产物更稳定。
  • 负面清单经常激活错误模板,隔离输入更有效。

抽象原则:

不要问“这条信息有没有用”,要问“它是否值得每次都占用注意力”。

初始化新项目时,要设计 context 分层:哪些是 L1 always-on,哪些是 L2 入口,哪些是 L3 按任务读取。


5. 可观测性必须独立于业务流程

如果日志依赖每个模块自觉上报,迟早会漏。

好的 harness 会把运行事实作为独立系统:

  • event log 是 source of truth。
  • dashboard 只读,不参与修复。
  • run、phase、gate、tool、heartbeat 是观察维度,不是业务语义。
  • metrics 是长期趋势,不是一次报告。
  • failure reason 要稳定,方便聚合和复盘。

抽象原则:

业务 pipeline 可以变化,但观测模型要稳定。

当观测系统独立,项目才能回答更高级的问题:哪个阶段退化了,哪个 judge 漂了,哪个外部工具最常失败,哪个修复方案反复被用到。


6. 知识沉淀要按生命周期分层

不是所有经验都应该写进同一个文档。

有效的 harness 会区分:

知识类型回答的问题典型生命周期
Decision为什么这样设计长期,可被替代
Solution这个故障怎么修长期,随重复故障增强
Plan当前任务如何完成短期,完成后归档
Playbook重复流程怎么执行中期,随流程成熟更新
Reference外部世界有什么变化持续巡查,定期提炼

抽象原则:

经验不是越集中越好,而是要放到符合它生命周期的位置。

Bug fix 不应该伪装成 ADR。长期架构边界也不应该埋在一次 plan 里。外部调研不能只停留在 briefing,要能转化为 ADR、playbook 或 solution。


7. Gate 要保护边界,不要替代思考

Gate 的价值不是“打分”,而是阻止错误状态进入下游。

一个好的 gate 应该具备:

  • 明确的所有权:谁有资格判断这个边界?
  • 明确的输入:它读哪些 artifact?
  • 明确的输出:下游只看哪个 verdict、score 或 blocker?
  • 明确的失败动作:halt、retry、prototype、manual review 还是 force override?

实践里的关键教训:

Gate 不应该扩大自己的权力范围。

例如实现前的 evidence gate 可以检查“是否满足已声明的 stop/go 条件”,但不应该重新发明产品验证。边界越清晰,agent 越不容易在相邻职责之间漂移。


8. 抽象要等重复真实出现

Harness 很容易过早架构化。看到两个相似 phase,就想做通用 DSL;看到两个类似 skill,就想合并成库。

更稳的做法:

  1. 先让两个真实流程独立跑通。
  2. 观察重复发生在哪里:日志、gate、artifact、session、错误处理,还是业务判断。
  3. 只抽确定性边界,不抽业务语义。
  4. 抽完后做诚实度检查:代码更少了吗?上下文更少了吗?失败更清楚了吗?

抽象原则:

共享基础设施,保留进化闭环。

如果抽象让每个场景更难自我改进,它就是错误抽象。


9. 外部 Agent 是协作者,不是可信子程序

当 harness 调用另一个 agent、plugin 或 CLI 时,要把它视为外部协作者:

  • 它可能误解 cwd。
  • 它可能无法读需要的文件。
  • 它可能返回一段解释而不是写 artifact。
  • 它可能因权限、sandbox、quoting、上下文丢失而静默失败。
  • 它可能“看起来完成了”,但没有产生下游需要的证据。

抽象原则:

外部 agent 的自然语言响应不能直接成为 pipeline 状态。

自动化链路应该拥有调用、输出路径、artifact 验证和失败分类。plugin 或人工交互可以用于探索,但不能直接作为无人值守 pipeline 的成功依据。


初始化时的 12 个问题

新项目开始前,先回答这些问题,比先搭目录更重要:

  1. 这个项目有哪些独立进化闭环?
  2. 哪些规则每次都必须加载,哪些只在特定任务加载?
  3. 哪些知识是全局原则,哪些是产品或模块事实?
  4. 每个 phase 的下游是谁?
  5. 每个 hard handoff 的成功证据是什么?
  6. 哪些产物给机器读,哪些只给人看?
  7. 失败原因要如何分类,才能未来自动聚合?
  8. Judge 的权力边界在哪里?
  9. Fix 是否可能影响 Judge 的独立性?
  10. 外部工具或 agent 的输出如何被验证?
  11. 日志系统是否能在业务流程变化时保持稳定?
  12. 哪些重复已经真实出现,值得抽象成基础设施?

这些问题回答清楚后,再选择具体实现:单 repo 还是多 repo、目录怎么命名、是否需要 dashboard、是否需要 shared libs、是否需要 pipeline executor。


最小可复用理念

如果只能带走五句话:

  1. 先定所有权,再定结构。
  2. Agent 自报完成不算完成,证据才算。
  3. 概率能力负责生成,确定性壳负责边界。
  4. Context 是预算,文件系统才是仓库。
  5. 共享基础设施,保留业务闭环。