Harness Engineering 学习笔记

Harness Engineering 学习笔记
原文地址欢迎来到 Learn Harness Engineering | Learn Harness Engineering知识来源与初始之所以写这个是因为 Harness 自己好像明白但是讲出来好像总是很抽象。于是试着记录一下去理解再用自己的话说一下。核心机制模型变聪明❌ 模型外闭环 —— 工作系统 ✔关键名词名词含义Harness模型之外的一切——指令、工具、环境、状态管理、验证反馈诊断循环执行 → 观察失败 → 定位到 Harness 的哪一层出了问题 → 修补那一层 → 重新执行。Harness 工程的核心方法论完成定义一组可以用命令验证的条件——测试通过、lint 没报错、类型检查通过。没有的话 Agent 会自己编Harness 定义例子OpenAIHarness EngineeringHarness 核心原则仓库即规范。Codex 用 git worktree 隔离每个任务的运行环境 本地可观测性栈每个变更在独立的环境中验证。AnthropicLong-running agents 文档则更侧重状态持久化、显式恢复路径和结构化的进度跟踪。核心概念什么是 Harness模型权重之外的一切工程基础设施仓库是唯一事实来源约束非微操规则约束而不是逐条叮嘱Harness 五个子系统模型子系统说明指令AGENTS.mdCLAUDE.md工具权限环境—状态长任务进度跟踪PROGRESS.md 记录反馈AGENTS.md 显式列出验证命令。通常投入产出比最高——验证命令要写清楚要点Harness 要定期审计Harness 瓶颈定位需要失败记录和归因不能只靠拆除实验代码仓库 —— 唯一事实来源仓库当地图写与判断写什么写得好不好全新会话sysorgrunvalwhere怎么写好地图知识靠近代码每个模块目录下放一个简短的文档用标准化的入口文件CLAUDE.md最小但完备if delete → 不影响 → 删掉和代码一起更新知识更新跟代码变更绑定ACID 原则管理 Agent 状态原则说明原子性每次逻辑操作用一个 git commit 原子化。中途挂了就 git stash 回滚一致性定义一致状态的验证谓词所有测试通过、lint 无报错。Agent 每次操作后跑验证不一致的中间状态不要 commit隔离性多个 Agent 并发工作时状态文件要避免竞争条件。每个 Agent 用独立的进度文件或者用 git 分支隔离持久性关键的项目知识用 git 跟踪的文件持久化要点关键决策信息进仓库新会话测仓库好不好知识怎么写放在哪ACID 状态过期文档危险指令拆分 —— 不同文件Agent 的 In 三种系统提示任务描述仓库文件内容工具执行输出指令效果↓问题上下文预算中间迷失优先级冲突不同规则不知道重要性维护衰减只增不删矛盾累积前后矛盾拆分思路常用信息放手边偶尔用的收起来用不上的别带。入口文件 AGENTS.md50-200 行专题文档50-150 行每条指令都应该标明来源、适用条件、过期条件跨会话任务保持上下文连续上下文窗口有限 → 状态持久化文件 → 很快接上进度日志验证记录下一步行动状态持久化实践Agent —— 每次会话都会清空短期记忆的工程师写下关键信息交接进度文件PROGRESS.md—— 最基本的决策日志DECISIONS.md—— 什么决策、为什么、什么时候做的Git 提交作为检查点 —— commit 写清楚AGENTS.md 里写明每次开始和结束做什么要点上下文有限 → 更好的状态持久化 → 重建成本 → 短任务会话内结构化工件维持Agent 工作前先初始化第一个会话只初始化产出可运行的环境可验证的测试框架启动就绪清单文档任务分解Git 提交作为检查点热启动策略项目模板创建目录结构初始化的完成条件能启动、能测试、能看进度、能接手下一步要点初始化和实现分开初始化的产出四件验收初始化热 冷给 Agent 划清每次任务的边界注意力有限 → WIP1 工作流任何时刻只允许一个任务处于进行中状态每次只做一个功能点当前功能点端到端验证通过后才能开始下一个不要在实现功能 A 时顺便重构功能 B给每个任务定义显式的完成证据每个条目都要有验证命令把范围表面外部化记录所有任务的状态监控验证完成率Harness 应该持续跟踪VCRVerified Completion Rate 已通过验证的任务数 / 已启动的任务数。VCR 1.0 时阻止新任务启动。要点WIP1完成证据必须是可执行的任务完成状态外部化为文件过度延伸与不足完成共生功能清单约束 Agent 做什么三元组结构每个功能项包含三个要素(行为描述, 验证命令, 当前状态)功能清单服务四个 Harness 组件组件作用调度器读状态选下一个 not_started 的功能验证器执行验证命令判断是否允许状态转移交接报告器从功能清单自动生成会话交接摘要进度追踪器统计各状态分布提供项目健康度指标实施方法格式三元组Harness 控制状态转移提交验证请求Harness 执行验证命令根据结果决定是否允许状态转移在 CLAUDE.md 里写清楚规则粒度校准每个功能项应该是一次会话能完成的范围。太粗做不完太细管理开销大要点功能清单是 Harness 的基础结构不是给人看的备忘录。调度器、验证器、交接器都依赖它每个功能项必须有三元组行为描述 验证命令 当前状态。缺一项就不完整状态转移由 Harness 控制Agent 不能自己改状态。通过验证是唯一的升级路径功能清单是项目的单一权威来源任何关于该做什么的信息都从这里派生粒度控制在一次会话能完成的范围。太粗做不完太细管不过来防止 Agent 提前宣告完成Agent 倾向过早宣称任务完成滑坡效应没有强制要求全面执行验证跳过了实际运行或只跑了部分测试三层终止检查单元测试通过 ≠ 任务完成单元测试隔离被测单元跨组件问题不知道问题类型说明接口不匹配各自都用 mock 测试通过但端到端失败eg相对路径 vs 绝对路径状态传播错误数据库迁移表结构改变ORM 缓存还有旧结构条目环境依赖测试环境 ✔ 真实环境配置差异、网络延迟、服务不可用 ❌顺便重构核心功能没完成就开始重构代码优化性能改进风格 —— 已完成验证和未完成验证之间的边界改变了可能破坏了之前正确的东西自我评价的系统性偏差检查 ≠ 干活要分开防止过早完成的方法1. 外部化终止判定Harness 独立执行终止校验在 CLAUDE.md 中配置2. 构建三层终止校验层级内容语法与静态分析最低限度运行时行为验证测试执行、应用启动检查、关键路径验证。这是核心完成证据系统级确认端到端测试、集成验证、用户场景模拟3. 提供可操作的错误反馈明确指出哪里错了、应该怎么改4. 捕获运行时信号有效的运行时信号包括应用成功启动并达就绪状态关键功能路径在运行时是否执行成功数据库写入、文件操作等副作用是否正确临时资源是否被清理要点Agent 系统性地过度自信 —— 置信度校准偏差是客观存在的。代码写完了不代表做对了完成判定必须外部化 —— Harness 独立验证不信任 Agent 的感觉三层校验缺一不可 —— 语法通过、行为通过、系统通过层层递进错误消息要包含具体修复步骤 —— 让 Agent 能自我修正只说错了不够核心功能验证通过之前不许重构 —— 完成优先级约束是防止过早优化的关键跑通完整流程才算真正验证只有端到端测试能证明系统级缺陷不存在单元测试有盲区接口匹配状态传播错误资源生命周期问题环境依赖性端到端测试同时影响结果和行为Agent 知道工作要端到端测试编码行为会变考虑组件交互尊重架构边界处理错误路径实施方法0. 先定好架构边界再写端到端测试前提是系统有清晰的边界1. Harness 必须包含端到端层对于涉及跨组件修改的任务端到端测试通过是完成的前置条件2. 把架构规则变成可执行检查每条架构约束都应该有对应的测试或 lint 规则3. 设计面向 Agent 的错误消息失败信息要包含三要素什么出了问题、为什么、怎么修4. 建立审查反馈提升流程新类型的 Agent 错误就把它变成自动化检查要点单元测试对组件边界缺陷系统性盲视 —— 它们的隔离设计恰好使其无法检测交互问题端到端测试不仅检测缺陷还改变 Agent 的编码行为 —— 让它更关注集成和边界架构规则必须可执行 —— 每次提交自动检查不能只写在文档里等人来看错误消息要面向 Agent 设计 —— 包含怎么修的具体步骤形成自我修正闭环审查反馈提升让 Harness 自动变强 —— 每个被捕获的缺陷类别都变成永久防线让 Agent 的运行过程可观测可观测性缺失的影响无法区分正确和看似正确评估变成玄学重试变成盲猜会话交接信息断崖双层可观测性层级内容运行时可观测性系统层系统层的信号包括日志、追踪、进程事件、健康检查回答系统做了什么过程可观测性过程层Harness 决策工件的可见性包括计划、评分标准、验收条件回答为什么这个变更应该被接受自行处理可观测性局限不知道它不知道什么日志格式不统一过程可观测性不是日志能解决的搭建可观测性的方法1. 在 Harness 里内置运行时信号采集不要依赖 Agent 自己打日志。Harness 应该自动采集以下信号应用生命周期启动、就绪、运行、关闭各阶段状态功能路径执行关键路径的执行记录包括入口、检查点和出口数据流数据在组件间的流转记录资源利用异常的资源使用模式如内存持续增长错误和异常完整的错误上下文不只是错误消息2. 实施冲刺合同每个任务开始前生成者和评估者可能是同一个 Agent 的不同调用协商一份合同明确这次要做什么、怎么做算通过3. 建立评估评分标准4. 用 OpenTelemetry 标准化为每个 Harness 会话创建一个 trace每个任务创建一个 span每个验证步骤创建子 span。使用标准属性标注关键信息。这样可观测性数据可以和标准工具链Jaeger、Zipkin集成实例Planner规划者接收一段 1-4 句话的用户需求扩展成完整产品规格。被要求大胆设定范围并且专注于产品上下文和高层技术设计而不深入详细的技术实现原因是如果 Planner 过早指定了粒度技术细节且搞错了错误会级联到下游实现。更好的做法是约束交付物让 Agent 在执行中自己找到路径Generator生成者按 sprint 逐个功能实现。每个 sprint 前和 Evaluator 协商一份 sprint 合同约定这个功能块做完的标准。然后按合同实现自评后交给 QAEvaluator评估者用 Playwright MCP 像用户一样点击运行中的应用测试 UI 功能、API 端点和数据库状态。对每个 sprint 按四个维度评分产品深度、功能性、视觉设计和代码质量。每个维度有硬性阈值任一不达标则 sprint 失败Generator 收到详细反馈后修复要点可观测性是 Harness 的架构属性它是设计时必须考虑的核心能力不应只作为事后添加的功能双层可观测性缺一不可运行时信号解释发生了什么过程工件解释为什么这样做冲刺合同前置对齐工作防止生成者做了评估者因可预见原因立即拒绝的东西评分标准让评估可复现不同评估者对同一输出产生相似评分可观测性缺失导致 30-50% 的会话时间浪费在重复诊断上每次会话结束前都做好交接清洁状态不只是代码能编译构建和测试是底线还有三条容易被忽略的要求当前进度必须记录在机器可读的工件中已完成的子任务和它的通过标准正在做但还没做完的子任务和它当前卡在哪还没开始的子任务临时调试产物必须清理干净调试日志、临时文件、注释掉的代码、TODO 标记 —— 这些东西都会增加下一个会话的认知负担标准启动路径必须可用下一个会话能不能不靠人工干预就直接开始工作环境初始化、代码库加载、上下文获取、任务选择 —— 这些路径中的任何一个被破坏新会话就无法自行启动工作一个干净的会话退出需要满足五个条件构建通过、测试通过、进度已记录、临时工件已清理、启动路径可用怎么做1. 清洁状态是完成的必要条件会话完成的条件是两件事同时满足——任务通过验证且清洁状态检查通过2. 双模式清理策略即时清理每个会话结束时清理本次会话创建的临时文件更新功能清单状态确保构建和测试全部通过定期清理每周一次做一次全面的系统扫描处理累积的结构性问题更新质量文档跑基准测试检测整体质量有没有漂移3. 维护质量文档4. 定期简化 HarnessHarness 中每个组件的存在都源于模型在某个方面尚无法独立完成。推荐做法每月挑选一个 Harness 组件暂时禁用它跑一遍基准任务。如果结果没有退化就永久移除。如果退化则恢复该组件或换一个更轻量的替代方案。一个更深层的原则随着模型能力的提升Harness 中有趣的组合并没有减少它在位移。过去必须解决的问题被模型增长的能力覆盖了同时新的能力边界被打开暴露出过去触及不到的新问题。5. 清理操作必须幂等幂等的意思是一个操作无论执行一次还是执行一百次结果都一样。清理脚本必须具备这个特性因为清理失败时你会重跑一遍。如果重跑产生不同的结果就说明清理脚本存在 bug。6. 高吞吐量改变了合并策略要点清洁状态是会话完成的必要条件它是完成定义的一部分属于必要条件。代码写完了但状态是脏的那就不算做完五个维度缺一不可构建、测试、进度、工件、启动。每一条都要在退出时显式检查不能靠感觉应该没问题功能清单让 Agent 知道做完的标准没有清单Agent 用自己的标准判断完成那个标准几乎一定比你的标准低质量文档让代码库的健康状况可追踪知道哪里在退化才能主动修复。不知道问题在哪儿就只能等它爆发定期简化 Harness随着模型能力提升主动移除不再必要的组件。今天必须有的约束三个月后可能就是累赘以后再清理等于永远不清理熵增是默认方向只有主动的清洁操作才能对抗它。每次多花五分钟长期来看是回报最高的投资