【免费下载链接】learn-harness-engineering
Harness engineering beginner tutorial, from 0 to 1
在长时运行的 Agent 任务里,最隐蔽的失败不是「代码写错」,而是「决策过程不可见」:Agent 跑了 20 分钟、改了一堆文件,最后告诉你"做完了但两个测试挂了",却说不出为什么。本教程以 learn-harness-engineering 仓库第十一讲的可观测性专题为骨架,聚焦其核心工件——冲刺合同(Sprint Contract),讲解如何用合同、评分标准与运行时日志把 Agent 的决策过程变成可检查、可复现、可引导下一轮迭代的证据链。读完你将掌握合同模板、验收条件写法、双层可观测性设计,以及它们在仓库 项目六(Capstone) 中的完整落地方式。
一、从 sprint-contract.md 开始:一个真实的冲刺合同长什么样
仓库中 docs/fr/lectures/lecture-11-why-observability-belongs-inside-the-harness/code/sprint-contract.md 给出了一个极简但完整的合同示例(原文为法文,译文如下):
# 冲刺合同示例(Exemple de Contrat de Sprint) 冲刺目标(Objectif du sprint): - 为有依据的 Q&A 结果添加可见的引用(citations) "完成"意味着("Terminé" signifie): - 用户提出一个问题 - 应用返回一个答案 - 至少显示一条引用 - 点击引用可在文档视图中打开源位置这个例子虽短,却包含了冲刺合同的两个关键组成部分,缺一不可:
- 冲刺目标(Scope 的浓缩):一句话说清"这次要交付什么"。这里明确为"给有依据的 Q&A 结果加可见引用",指向的是一个具体功能增量,而不是模糊的"改进问答体验"。
- "完成"的定义(验收条件,Definition of Done):把"做完"翻译成可逐条验证的行为链——提问 → 返回答案 → 至少一条引用可见 → 点击引用能跳转到源位置。四条全部满足才算完成,任何一条不满足都意味着任务未完成。
这份合同对应的功能,在仓库中恰好有真实实现:项目六的 src/services/qa-service.ts 中QaService.ask()返回的QAResponse携带citations数组(每个引用含documentId、chunkIndex、excerpt),而 ConversationHistory.tsx 负责渲染可展开的引用——这正是合同里"至少显示一条引用、点击可查看源位置"的落点。由此可见,合同不是纸面文档,而是与真实代码行为一一对应的验收清单。
二、为什么可观测性必须属于 harness:问题背景
冲刺合同是"过程可观测性"的核心工具,而它要解决的问题,来自第十一讲 index.md 开头描述的黑盒场景:Agent 执行任务时看不到运行时实际状态,只能凭猜测做决策。
没有可观测性,Agent 在不确定状态中做决策,评估变成主观判断,重试变成盲目摸索。OpenAI 与 Anthropic 都把可靠性定义为"证据问题":harness 必须以能指导下一步决策的形式,暴露运行时行为与评估信号。
当 harness 缺乏可观测性时,四类问题会系统性出现:
- 无法区分"正确"与"看似正确":代码审查通过(语法对、逻辑通)≠ 运行时正确。边界条件处理错误会在特定输入下产生错误结果,只有运行时追踪能揭示实际执行路径偏离了预期。代码审查看的是"写了什么",运行时追踪看的是"实际跑了什么"。
- 评估变成玄学:没有评分标准和验收条件时,评估者(人或 Agent)只能依赖隐式假设,同一个输出在不同评估者眼中可能截然不同,质量评估不可复现。
- 重试变成盲猜:Agent 不知道为什么失败时,重试方向是随机的,可能反复修复无关代码路径而忽略真正的故障根源。每次盲重试都消耗 token 和时间。
- 会话无法接续:把进度和验证结果记录在版本化文件中,才能让下一次会话检查项目状态;否则每次新会话都要重新摸索。
讲义中用一个教学示意量化了这个差距:执行"为应用添加暗色模式"任务时,无可观测性的 harness 会经历 3-4 轮盲重试、耗时约 45 分钟、勉强产出;而带完整可观测性的 harness 一次迭代、15 分钟产出高质量结果——效率差 3 倍,唯一的区别是可观测性(讲义明确注明这些数字是解释机制的教学假设,并非已发表实验的实测结果)。
三、双层可观测性:系统信号解释行为,过程工件解释意图
可观测性不是"多打点日志"那么简单。第十一讲将其拆成两层,缺一不可:
| 层次 | 回答的问题 | 包含内容 |
|---|---|---|
| 运行时可观测性(系统层) | "系统做了什么?" | 日志、追踪、进程事件、健康检查 |
| 过程可观测性(过程层) | "为什么这个变更应该被接受?" | 计划、冲刺合同、评分标准、验收条件 |
两者必须一起设计、相互增强,构成"双层可观测性":运行时信号解释行为,过程工件解释意图。讲义中的流程图清晰地展示了这一闭环:
闭环的关键在于:合同(Contract)先行,生成器按合同执行,运行时信号(Signals)持续收集,评估者(Review)拿着合同与信号逐项核对,最终给出"哪一项没过、该改哪里"的明确判决(Verdict),并反馈给下一轮生成。冲刺合同因此成为过程可观测性的核心工具:它让"评估者因为可预见原因立即拒绝生成者的产出"这件事在编码开始前就被消除。
四、编写冲刺合同:完整模板与三要素
讲义(index.md)给出了一个可实际套用的完整合同模板——"暗色模式支持":
# 冲刺合同: 暗色模式支持 ## 范围(Scope) - 修改主题切换组件 - 更新全局 CSS 变量 - 添加暗色模式测试 ## 验证标准(Verification Standards) - 每个组件的视觉回归测试通过 - 主流程端到端测试通过 - 无样式闪烁 (FOUC) ## 排除项(Exclusions) - 不处理打印样式 - 不处理第三方组件暗色模式三个组成部分各司其职:
- 范围(Scope):逐条列出要改动的组件、文件与测试,是生成器的施工清单。越具体,生成器越不容易"自由发挥"到计划者预期之外。
- 验证标准(Verification Standards):把"怎么做算通过"翻译成可执行的测试与检查,例如视觉回归测试、端到端测试、无 FOUC。它是评估者逐项打勾的依据,也是后面评分标准的素材。
- 排除项(Exclusions):明确"这次不做什么"。排除项的价值常被低估——它主动划出边界,防止生成器在打印样式、第三方组件等非目标领域上过度投入,也防止评估者拿合同外标准刁难结果。
写合同时有几个实践要点:
- 合同应在编码开始前由生成者与评估者(可能是同一个 Agent 的两次调用)协商确定;
- 验收条件必须可逐条验证(参考 sprint-contract.md 中"完成意味着"的写法),而不是形容词堆砌;
- 排除项要显式写出,把"不做的边界"从隐式假设变成显式约定。
五、配套机制:评分标准(Rubric)让评估可复现
合同解决"做什么、做到什么程度",评分标准则解决"怎么打分"。讲义给出了一张四档量化表:
# 评分标准 | 维度 | A | B | C | D | |------|---|---|---|---| | 代码正确性 | 所有测试通过 | 主流程通过 | 部分通过 | 编译失败 | | 架构合规 | 完全合规 | 轻微偏离 | 明显偏离 | 严重违反 | | 测试覆盖 | 主流程+边缘 | 仅主流程 | 仅有骨架 | 无测试 |同一目录下的 code/evaluator-rubric.md 则给出另一个维度的 1-5 分制示例,专门针对 Q&A 场景:
- 基础(Grounding):回答是否清晰关联到导入的源文档?
- 引用质量(Citation quality):对源文档的引用是否可见且具体?
- 功能可用性(Functionality):用户能否走通问答流程?
- 产品一致性(Product coherence):整体工作流是否浑然一体?
评分标准的本质是把"好不好"从主观判断变成基于证据的结构化评分,让不同评估者对同一输出产生相似结论。这一点在仓库项目六中有完整落地的样板:projects/project-06/solution/evaluator-rubric.md 以 15 个维度(构建编译、窗口启动、文档导入、文本索引、有依据 Q&A、会话历史、反馈收集、结构化日志、干净状态重置、持久化、状态栏、基准脚本、清理扫描器、harness 完整度等)逐项打分并附证据备注,最终给出 5.0/5 的总分——每个分数都有"证据"列支撑,而不是一句"感觉不错"。
六、运行时信号采集:结构化日志与 OpenTelemetry
过程层有合同与评分标准,系统层则需要自动采集信号。讲义强调:不要依赖 Agent 自己打印日志,harness 应自动采集以下五类信号:
- 应用生命周期:启动(startup)、就绪(ready)、运行(running)、关闭(shutdown)各阶段状态;
- 功能路径执行:关键路径的执行记录,含入口、检查点、出口;
- 数据流:数据在组件间的流转记录;
- 资源利用:异常模式(如内存持续增长);
- 错误和异常:完整错误上下文,而不只是错误消息。
仓库提供了配套演示代码 docs/fr/lectures/lecture-11-why-observability-belongs-inside-the-harness/code/runtime-logger.ts,用同一个"文档 Q&A 流水线"场景对比两种日志:
- 临时日志(console.log 风格):失败时只输出"
RetrievalEngine: something went wrong",没有组件维度、没有输入输出、没有关联 ID——从这类日志里无法定位根因; - 结构化 JSON 日志:每条记录包含
timestamp、level、component、action、durationMs、input、output、error、correlationId。该文件内置了一个种子故障(Vector dimension mismatch: query embedding dim=768, index embedding dim=1536),结构化日志能自动给出根因、下游影响与关联 ID,把调试从"手动猜测数分钟"变成"自动定位数秒"。
可运行方式(演示代码文件头部的注释):npx tsx docs/fr/lectures/lecture-11-why-observability-belongs-inside-the-harness/code/runtime-logger.ts。
项目六把这一理念变成了生产级实现:src/services/logger.ts 提供DEBUG/INFO/WARN/ERROR四级、timestamp + level + service + message + data的统一 JSON 结构,并通过logger.forService()为每个服务创建子日志器;所有服务(persistence、document、indexing、qa、ipc-handlers)都输出结构化条目,例如 qa-service.ts 在生成答案后记录confidence、citationCount、answerLength、durationMs。这一事实被 feature_list.json 中structured-logging功能项以"全部 5 个服务均使用logger.forService()输出结构化数据"的证据加以确认。
对于跨会话、跨任务的全链路追踪,讲义推荐用OpenTelemetry 标准化:为每个 harness 会话创建一个 trace,每个任务创建一个 span,每个验证步骤创建子 span(sub-span),并用标准属性标注关键信息,使可观测性数据能与 Jaeger、Zipkin 等标准工具链集成。
七、仓库中的完整落地:Project 06 如何把可观测性写进 harness
冲刺合同、评分标准与结构化日志并非孤立的示例,它们最终汇聚在项目六(projects/project-06/solution/)这套完整 harness 中,形成可运行、可验证的工程样板:
- AGENTS.md:开篇即要求"写任何代码前按顺序完成启动步骤"(读架构文档、读可靠性文档、运行
bash init.sh、读feature_list.json),并把"Definition of Done"写死为 7 条可检查条件(编译通过、窗口可见、功能出现在 feature_list 且状态为 pass、遵守分层边界、结构化日志覆盖、文档同步更新、clean-state 检查通过)——这正是冲刺合同思想在项目级 harness 中的制度化。 - feature_list.json:15 个功能项每条都带
status与evidence(证据),例如grounded-qa的 evidence 写明"QaService.ask()对问题分词、按关键词重叠打分、返回 top 2 引用;有引用时置信度 0.85,无引用时 0.30"——功能清单本身就是"评估信号"的载体。 - clean-state-checklist.md:把"干净状态"拆成构建、架构、运行时、日志、数据完整性、性能、仓库、脚本共 8 类可勾选检查项,例如"所有日志条目必须是可解析的合法 JSON""日志必须包含 timestamp/level/service/message"——这是评估者可逐项执行的验收清单。
- scripts/benchmark.sh:以导入、索引、查询、数据完整性 4 个任务组成的基准套件,用结构化输出记录每项耗时与通过/失败,为"下一轮迭代"提供量化证据。
从源码结构看,这套 harness 的设计意图是:把"合同 → 执行 → 信号 → 评估 → 判决"的闭环,沉淀为仓库中版本化的文件与脚本,使任何新会话都能通过读取这些工件快速恢复上下文并继续决策,而不是重新开始一轮盲猜。
八、来自 Anthropic 三 Agent 架构实验的佐证
讲义引用 Anthropic 的 harness 设计实验(对应更新后的 Opus 4.6 harness:一套架构中的三个 Agent——planner 制定规格、builder 实现、evaluator 测试运行中的应用并把反馈交给下一轮构建,该版本移除了 sprint 拆分),并给出完整成本数据(下表为讲义转述,非仓库实测):
| Agent 和阶段 | 时长 | 成本 |
|---|---|---|
| Planner(规划者) | 4.7 分钟 | $0.46 |
| Build 第 1 轮 | 2 小时 7 分钟 | $71.08 |
| QA 第 1 轮 | 8.8 分钟 | $3.24 |
| Build 第 2 轮 | 1 小时 2 分钟 | $36.89 |
| QA 第 2 轮 | 6.8 分钟 | $3.09 |
| Build 第 3 轮 | 10.9 分钟 | $5.88 |
| QA 第 3 轮 | 9.6 分钟 | $4.06 |
| 总计 | 3 小时 50 分钟 | $124.70 |
三个 Agent 各司其职,每个都有明确的可观测性角色。讲义强调了两点值得注意的细节:
- QA 反馈必须是具体且有证据的。示例反馈是"剪辑不能拖拽/移动、没有乐器 UI 面板、没有视觉效果编辑器"这类可核实的事实,而不是"感觉不对"。这正是冲刺合同 + 评分标准所要达成的效果。
- Evaluator 不是天生就强。早期版本会识别出合理问题后自我说服、最终批准工作;调校方法是"读 evaluator 的日志,找到它的判断与人类判断分叉的地方,更新 QA 的 prompt"——即把评估过程本身也变成可观测、可迭代的对象。
九、实践练习与核心要点
练习
- 可观测性差距分析:审查你当前的 harness,分别评估系统层与过程层的可观测性,找出"现有信号无法区分"的系统状态,提出补充方案。
- 冲刺合同实践:为一个真实任务写一份冲刺合同(范围 / 验证标准 / 排除项),让 Agent 按合同执行,对比有无合同时的效率与质量差异。
- 任务轨迹构建:记录一个完整编码任务中 Agent 的每一步操作,用 OpenTelemetry 语义约定标注,分析轨迹中的信息瓶颈——哪些步骤的决策缺乏足够的信号支持。
核心要点
- 可观测性是 harness 的架构属性,必须在设计时内置,而不是事后追加的功能。
- 双层可观测性缺一不可:运行时信号解释"发生了什么",过程工件(合同、评分标准)解释"为什么这样做"。
- 冲刺合同前置对齐工作,从源头防止"生成者做了评估者因可预见原因立即拒绝的东西"。
- 评分标准让评估可复现:不同评估者对同一输出产生相似评分,质量不再依赖个人主观。
- 把进度与验证结果记录在版本化文件中,让下一次会话能检查项目状态(引用原文介绍了这一机制,未报告启动耗时减少的百分比,本仓库同样不对此作量化承诺)。
围绕这些要点,可以从仓库的 第十一讲讲义、合同示例、评分标准示例、日志演示,以及 项目六完整实现 继续深入:先在讲义里理解机制,再跑一遍日志演示看到结构化与临时日志的差异,最后在项目六的 AGENTS.md、feature_list.json、clean-state-checklist.md 与 benchmark.sh 中看到整套机制如何被写成文件、可被任何新会话读取与验证。
【免费下载链接】learn-harness-engineering
Harness engineering beginner tutorial, from 0 to 1
相关推荐
Sprint Contract(冲刺契约):用「完成定义」把可观测性装进 Harness —— learn-harness-engineering 实战解析
Sprint Contract(冲刺契约):用「完成定义」把可观测性装进 Harness —— learn harness engineering 实战解析 导
Sprint 合约(Sprint Contract):把可观测性前置到任务开始前——learn-harness-engineering 过程可观测性实战指南
Sprint 合约(Sprint Contract):把可观测性前置到任务开始前——learn harness engineering 过程可观测性实战指南 本
冲刺合同与双层可观测性:learn-harness-engineering 中让 Agent 运行过程可被证据驱动的实战指南
冲刺合同与双层可观测性:learn harness engineering 中让 Agent 运行过程可被证据驱动的实战指南 本篇技术指南以 learn har
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考