【免费下载链接】learn-harness-engineering
Harness engineering beginner tutorial, from 0 to 1
本文是 learn-harness-engineering 课程中 Frontier Harness Design Breakdowns(前沿 Harness 设计拆解) 部分的完整导览与深度解读。它以课程提出的指令(Instructions)、工具(Tools)、环境(Environment)、状态(State)、反馈(Feedback)五子系统框架为分析透镜,逐一拆解 Pi、Claude Code、Codex、DeepSeek Harness 四款真实产品的 harness 架构,回答同一个核心问题:围绕模型之外的工程基础设施(harness)到底是怎么设计的? 读完本文,你将掌握用五子系统框架分析任何 agent 产品的方法论,理解四款产品在上下文连续性、初始化、验证、可观测性、交接与循环等核心机制上的不同取舍,并能把这些设计直接迁移到自己的项目里。
为什么要逐产品拆解 Harness
课程第一讲就指出:强大的模型能力并不能保证可靠的执行结果。同一个模型,放在不同的 harness 里,表现可能相差一个数量级。而本部分的价值在于——课程讲的是"应该怎么做",这些产品展示的是"顶尖团队实际怎么做"。
拆解时有一个明确的纪律:不讨论模型推理能力有多强、在某个 benchmark 上得分多高、也不泛泛介绍"这个 agent 能做什么",那些是模型层与产品层的问题。这里只考察 harness——即模型权重之外的一切(参见 Lecture 2 · What a Harness Actually Is 中对 harness 的定义:模型权重之外的工程基础设施总和)。
每个产品都代表一套独立的设计决策组合。并排对比它们,就能看到不同团队如何用完全不同的方式实现同一套核心机制:
- Pi 把 harness 建成"最小核心 + 可编程扩展",用"最小系统提示词 + 按需加载"做上下文工程;
- Claude Code 把 harness 建成完整的运行时环境:分层记忆、五层压缩、权限系统、hooks、子代理一应俱全;
- Codex 把 harness 哲学推到逻辑极致:仓库即系统记录(system of record),AGENTS.md 只是一页目录,用 git worktree 隔离环境;
- DeepSeek Harness 把 harness 本身定义为与模型无关的独立运行时:Everything is a Plugin(一切皆插件)。
分析框架:五子系统与核心机制
要对产品做系统化拆解,先要有一把尺子。本部分的统一分析框架来自课程 Lecture 2:一个 harness 由五个子系统构成,每个子系统有明确职责与评价标准:
| 子系统 | 职责 | 评价要点 |
|---|---|---|
| 指令(Instructions) | 通过 AGENTS.md / CLAUDE.md 等项目规则文件表达项目意图 | 层级是否清晰、规则是否可机械检查 |
| 工具(Tools) | 提供 shell、文件、测试等可执行能力 | 是否遵循最小权限原则、扩展面是否开放 |
| 环境(Environment) | 用依赖锁文件、运行时版本、容器描述自描述环境状态 | 是否可复现、是否可隔离 |
| 状态(State) | 用 PROGRESS.md、git 提交等记录进度 | 跨会话是否连续、是否可恢复 |
| 反馈(Feedback) | 显式列出验证命令(测试、lint、构建) | 是否能把"完成判定"变成可执行路径 |
除此之外,拆解还关注上下文连续性、初始化、验证、可观测性、交接(handoffs)、循环(loops)等核心机制。仓库中 Lecture 2 的代码示例 给出了一个本地编码 agent 的 harness 组件清单:system prompt、AGENTS.md、bash 工具、文件读写工具、git 访问、本地文件系统、启动脚本、测试命令、stop hooks、lint 检查、evaluator loop——其中任何一个组件被替换,实际生效的 agent 就变了。配套的 harness-vs-no-harness.ts 用同一组任务对比"无 harness"与"有 harness"两种运行方式:无 harness 时每个任务都"静默通过",即使它缺少认证测试、越出了任务范围;有 harness 时同样的规则被显式执行并阻断。这正是"拆解产品 harness"要观察的核心:产品把哪些规则硬化成了运行时机制。
四款产品的核心哲学:一页速览
拆解之前,先用一句话概括每款产品的设计哲学,这是理解后续细节的锚点:
- Pi = 最小核心 + 可编程扩展。它的官方定位刻意保持核心小巧,把控制权交还给你:"Ask Pi to build what you want, or install a package that does it your way." 它把 harness 分成四个可定制层:Extensions(挂在生命周期事件上的 TypeScript hooks)、Skills(按需加载的能力包,采用渐进式披露)、Prompt templates(输入
/name时展开的 Markdown 提示词模板)、Themes(TUI 外观)。这种分层本身就是一种 harness 设计:规则和扩展完全决定模型能看到什么、何时看到,而不是把这些决策硬编码进核心。 - Claude Code = 完整的运行时环境。Anthropic 明确把它归类为 agentic harness。它的核心是一个简单的 while 循环(调模型 → 执行工具 → 观察结果 → 再调模型),但绝大部分代码不在循环里,而在循环周围的系统里:权限系统、上下文压缩管线、扩展机制、子代理编排、会话存储。循环是骨架,骨架之外的一切决定可靠性。
- Codex = 仓库即系统记录,AGENTS.md 只是目录页。工程价值在于设计环境、表达意图、构建反馈回路。它用"减法"保持核心克制,把更多责任交给仓库约定与上下文工程。
- DeepSeek Harness = 模型无关的独立运行时。传统编码 agent 的结构是"LLM + 固定 agent 循环 + 固定工具集",它则是"模型 + 一个插件化核心(Cordis)"。核心只负责插件的加载、卸载、依赖与事件,自身不拥有任何具体的 agent 能力——没有"特权的核心"需要打补丁。
Pi:把上下文工程从系统提示词中解放出来
Pi(npm 包 @earendil-works/pi-coding-agent)自我定位为"minimal agent harness",它不叫自己"最强的编码 agent",而是把身份锚定在 harness 这个词上。详细拆解见 Breaking Down Pi's Harness Design。
指令子系统:AGENTS.md 与 SYSTEM.md
Pi 在指令处理上保持克制,但层级清晰:
- AGENTS.md:加载顺序为全局
~/.pi/agent/AGENTS.md→ 逐级向上遍历父目录 → 当前目录./AGENTS.md(同时兼容 CLAUDE.md)。这把"仓库即系统记录"落到了实处——指令是文件,不是聊天框里敲的提醒。 - SYSTEM.md:默认系统提示词可按项目替换或追加。这是 Pi 唯一官方提供的"系统提示词"修改入口,同时也承担了"环境自描述"层的职责。
Pi 官方强调其系统提示词是最小化的:核心不塞进一长串"如果……那么……"规则,而是暴露扩展点,让规则以 skill 和 extension 的形式按需出现。这直接呼应课程 Lecture 4 · Why One Giant Instruction File Fails 的结论——Pi 通过"最小核心 + 拆分文件 + 按需加载"天然规避了巨型指令文件问题。
状态与上下文:Pi 最精细的地方
Pi 的上下文工程把课程的"上下文连续性""防止上下文污染"变成了具体机制:
- 可编程压缩(Programmable compaction):当上下文接近上限时,旧消息被自动摘要。压缩策略本身是可定制的——可以用扩展实现基于主题的压缩、代码感知摘要,甚至用另一个模型做摘要。默认机制细节:自动压缩在两种情况下触发(上下文溢出恢复 / 超过保留阈值),分割点保留最近约 20,000 tokens,更早的消息被摘要成 "context handoff" 并增量链式压缩。换句话说,Pi 把"如何压缩"当作 harness 的一部分,而不是固定常量。
- 动态上下文(Dynamic context):扩展可以在每次推理前注入消息、过滤消息历史、实现 RAG、构建长期记忆。这比"上下文满了再压缩"更进一步:它在消息进入上下文窗口之前就决定什么该进去。
- 会话树(Session tree):Pi 明确声明 "sessions are stored as trees"——
/tree可以回到任意历史节点并从此继续,所有分支存储在同一个文件里。这解决的是课程反复强调的跨会话上下文断裂问题:不是靠强制摘要搭桥,而是靠结构化历史回放。分支可导出为 HTML 或上传为 gist 分享,这本身也提供了可观测性。
工具子系统:Skills 与 Extensions 双层结构
- Skills:被明确定义为"agent 按需加载的自包含能力包",包含指令与工具,遵循 Agent Skills 标准。渐进式披露保证 skill 细节只在被触发时才进入上下文,不会撑爆 prompt 缓存——这是从成本视角做的 harness 设计:上下文里每多一个 token,每次推理都要付费。
- Extensions:挂在内置生命周期事件上的 TypeScript hooks。官方示例包括:拦截危险命令(权限闸门)、切换任务时对代码状态做 checkpoint、保护路径(如禁止写入
.env)、在把工具输出交给模型前修改它、从外部源(文件监听器/Webhooks/CI)注入消息唤醒 agent。这些 hook API 也从@mariozechner/pi-coding-agent/hooks导出。社区 harness pi-agent-harness 进一步把这些 hook 面打包成现成扩展:skill-router、session-summary、extract-patterns、telemetry。
Extensions 是 Pi 最重要的设计决策:它不是给你几个开关,而是把运行时内部的整个事件面暴露出来。想要加记忆?在 agent/pre-step 注入。想记录行为?订阅会话事件。想修改模型请求?挂到 agent/request。让 agent 能修改自己的 harness——这比任何配置项集合都更接近"可编程 harness"的定义。
反馈与验证:让"学习"成为 harness 的一部分
Pi 本身不内置强制测试闸门(验证命令需用户在 AGENTS.md 中指定),但社区 harness pi-agent-harness 用扩展把"反馈回路"结构化了:
- session-summary:维护滚动更新的
PROGRESS.md——对应课程的状态子系统,用于长任务进度跟踪; - extract-patterns:从会话中收集候选经验并记入
LESSONS.md——把"每次会话结束前留下良好的交接"从约定变成机制; - telemetry:记录 token 用量、成本等指标——可观测性。
同一社区仓库还演示了 VISION.md(目标)、PROGRESS.md(进度)、LESSONS.md(经验)、STANDARDS.md(标准)这套跨会话持久化的 Markdown 文件体系,正是课程推荐的"仓库即系统记录 + 进度文件 + 交接机制"模式。
映射到课程框架
| 子系统 | Pi 的实现 | 评估 |
|---|---|---|
| 指令 | 层级化 AGENTS.md 加载 + SYSTEM.md | 层级清晰,但规则需用户自己写 |
| 工具 | 按需 skills + 全生命周期扩展 hooks | 极强;把工具系统变成可编程面 |
| 环境 | SYSTEM.md 环境自描述;用户在 AGENTS.md 声明运行时环境 | 机制开放,可复现性依赖用户描述质量 |
| 状态 | 会话树 + 可定制压缩 + PROGRESS.md | 极强;跨会话连续性与可恢复性是核心 |
| 反馈 | 用户自定义验证命令;session-summary / extract-patterns 结构化机制 | 机制已提供,内容由用户供给 |
Pi 的取舍与 Claude Code、Codex 形成鲜明对比:Claude Code 把"记忆、权限、子代理"放进核心提供开箱即用体验;Codex 把"仓库约定与环境隔离"设为默认;Pi 则选择什么都不替你决定——它把决策变成扩展点。代价是你要么自己写扩展,要么安装别人写的包。
Claude Code:把课程核心机制全部产品化
Claude Code 可能是目前被研究得最透彻的公开 harness:源码开放、社区分析报告详尽,它把课程中几乎每一条核心机制——分层记忆、上下文压缩、权限、hooks、子代理、会话持久化——都变成了完整的产品实现。详细拆解见 Breaking Down Claude Code's Harness Design。
指令子系统:分层记忆系统
Claude Code 的记忆系统是对 harness 理论最直接的贡献。官方文档明确:每个会话都以全新的上下文窗口开始,跨会话的知识通过两种机制携带——CLAUDE.md 文件(你写的指令)与 auto memory(Claude 自己写的笔记)。按作用范围从宽到窄,CLAUDE.md 分四类:
- 组织策略级:由 IT/DevOps 集中管理(如
/etc/claude-code/CLAUDE.md),承载公司级标准; - 用户级
~/.claude/CLAUDE.md:跨项目的个人偏好与规则; - 项目级
./CLAUDE.md或./.claude/CLAUDE.md:架构、技术栈、验证命令等项目的系统记录,随仓库共享; - 本地级
./CLAUDE.local.md:项目内的个人偏好,通常加入.gitignore而非提交。
另有两种补充机制:子目录级按需加载(子目录里的 CLAUDE.md 启动时不加载,只有 Claude 读取该目录文件时才进入上下文);auto memory(Claude 根据你的纠正和偏好主动写笔记,按仓库共享、跨 worktree 生效,每个会话最多加载前 200 行或 25KB)。
这四个层级构成一条指令层级:官方文档说"更具体的指令出现在上下文中更靠后的位置"(项目指令出现在用户指令之后)。价值在于:模型不必在每次对话开头消化整个巨型指令文件,指令按作用域加载到离适用处最近的地方。这正是 Lecture 4 "巨型指令文件为何失败"的产品化答案。
上下文子系统:五层压缩管线
Claude Code 不是简单地"满了就摘要",而是用一条五层压缩管线管理上下文。其架构细节来自 VILA Lab 的源码级分析:先做无损剪枝(移除冗余的工具结果),再做结构化蒸馏,最后才用有损的 LLM 摘要,并配有熔断器防止过度压缩。Lecture 5 讲长任务为何丢失连续性,Claude Code 的答案是多级漏斗。
与之配套的是追加式(append-oriented)会话存储:所有历史都追加写入 history.jsonl,支持 /resume 恢复与 fork 分支。这保证了"每个会话结束前留下良好交接"——不是因为系统记忆力好,而是因为存储层是追加式、可回放的。
工具子系统:四种扩展机制
Claude Code 把扩展面分成四类,每类解决不同问题,这是其设计中最值得借鉴的部分:
- Skills:由
SKILL.md描述的程序性知识,通过渐进式披露按触发自动加载,适合"如何做某事"的领域知识; - MCP:连接外部系统的 JSON-RPC 协议,提供"模型触达外部世界"的标准接口;
- Hooks:挂在
PreToolUse、PostToolUse、Stop等生命周期事件上的确定性脚本; - Plugins / Subagents:把复杂任务委派给专门的 agent。
关键设计是职责分离:CLAUDE.md 管"做什么"(what),Skills 管"怎么做"(how),MCP 管"连哪里"(where),hooks 管"何时强制"(when)。如果团队把这几层混在一起——比如把本该放 MCP 的事写进 CLAUDE.md——就会造成课程所说的上下文泄漏。
反馈与验证:确定性约束 + 人机分工
Lecture 10 强调"只有完整流程跑通,验证才算数"。Claude Code 通过两条轨道实现:
- 权限系统(确定性约束):权限不是简单"什么都问"。它把七种模式与一个基于 ML 的分类器结合:低风险操作放行,高风险操作按策略确认或拒绝。这把"给 agent 设定清晰任务边界"(Lecture 7)变成运行时强制,而不是提示词里的恳求。
- Hooks(防止过早宣布完成):
PostToolUsehooks 可以在工具执行后强制运行检查并把结果写回上下文;Stophooks 在 agent 宣布完成时介入。这实现了"干活的人"与"检查的人"分离——Anthropic 在 harness 文章里观察到 agent 会"自信地表扬自己的工作",因此用 hooks 注入确定性检查,而不是信任模型的自评。 - 子代理(上下文隔离):每个子代理的对话历史存放在独立的 sidechain 文件中,不膨胀父 agent 的上下文。拆分任务的同时拆分上下文:切分任务也隔离了上下文污染。
可观测性与会话持久化
Claude Code 的日志是完整的追加式记录(history.jsonl),配合 /compact、/clear、/init 等显式命令,让你主动管理上下文状态而不是被动等它填满。/init 甚至把"每次任务开始前先初始化"(Lecture 6)变成一条命令:它会自动分析代码库并生成包含构建命令、测试指令、工程约定的初始 CLAUDE.md。
映射到课程框架
| 子系统 | Claude Code 的实现 | 评估 |
|---|---|---|
| 指令 | 分层作用域(组织/用户/项目/本地)+ auto memory | 分层记忆是标杆实现 |
| 工具 | 四种扩展类型:Skills + MCP + hooks + 子代理 | 职责清晰分离是核心强项 |
| 环境 | 项目内设置 + settings.json | 依赖用户在 CLAUDE.md 中描述环境 |
| 状态 | 追加式会话存储 + 五层压缩 + resume/fork | 极强;长任务连续性的参考实现 |
| 反馈 | 权限分类器 + PostToolUse hooks 强制检查 | 把"防止过早宣布完成"变成确定性机制 |
Codex:仓库即系统记录,AGENTS.md 是目录页
OpenAI 的 Codex 可能是四款产品中与"harness 基本原理"绑定最深的:命名整个领域的文章 Harness Engineering 本身就是 OpenAI 团队用 Codex 构建产品的经验总结。Codex 的哲学一句话概括:仓库是系统记录,AGENTS.md 只是目录页,工程价值在于设计环境、表达意图、构建反馈回路。详细拆解见 Breaking Down Codex's Harness Design。
指令子系统:目录页,而非百科全书
这是 Codex 对 harness 理论最具影响力的贡献。原文章的核心主张是:
单个巨型指令文件难以机械地检查覆盖度、新鲜度、归属与交叉链接,漂移不可避免。因此我们不再把 AGENTS.md 当作百科全书,而是当作目录页:代码库知识存放在结构化文档中,AGENTS.md 指向它们。
实践指导:把 AGENTS.md 保持在约 100 行(原文推荐约 100 行,接近上限就把内容移入 docs/);放不下就拆进 docs/ 目录让 agent 按需读文件。这就是"给地图,别给手册"(give the map, not the manual)的权威出处。配套原则是强制不变量,而非微管理实现(enforce invariants, don't micromanage the implementation)——AGENTS.md 只放不可违反的约束与验证命令,实现细节交给模型。
上下文子系统:Write-Select-Compress-Isolate
Codex 的上下文工程可概括为四种策略(该框架由社区在"上下文工程"成为独立学科后归纳并映射回 Codex):
- Write(写入):把上下文持久化到窗口之外——结论写进文档、状态写进文件,而不是留在对话里。对应"仓库即系统记录"。
- Select(选择):只把必要的 token 拉进窗口——让 AGENTS.md 指路、按需读文件,而不是加载整个仓库。
- Compress(压缩):保留真正重要的内容——支持自动压缩与手动
/compact,compact_prompt可定制。 - Isolate(隔离):按不同边界切分上下文——用子代理隔离不同任务的上下文,前端子代理永远不会看到后端数据库 schema。
Codex 还有细粒度的环境上下文设计:社区源码分析显示,build_environment_update_item 在环境变化时只输出变更的字段(CWD、git 分支、文件系统),而不是把完整系统上下文逐轮粘贴。这个工程细节避免了上下文中的重复 token 占用。
工具与边界:Worktree 隔离 + 子代理
Codex 有两个核心 harness 机制:
- git worktree 环境隔离:每个任务运行在独立的 git worktree 中,配本地可观测性栈(日志、指标、trace),让每个变更都在隔离环境中得到验证。这是 Lecture 7"为每个 agent 任务设定清晰边界"的物理实现——边界靠环境隔离强制,而不是靠指令请求。环境子系统在这里变成硬隔离。
- 核心级子代理:
spawn_agent/wait_agent是核心工具:模型显式创建子代理,给它独立的会话历史与工具集,然后等待结果。子代理继承父代 AGENTS.md 指令,但运行在自己的上下文中。配置存放在.codex/agents/*.toml,可指定不同模型与指令。这是"上下文隔离"的直接实现,也体现了 Lecture 12 交接精神:每个子代理都是一个边界清晰的工作单元。
反馈子系统:把验证命令写进规范
OpenAI 实践中最强调的一点:把验证命令显式写进 AGENTS.md,让"如何确认工作正确"成为仓库的一部分。在 Codex 的工程工作流里,测试、CI、文档、可观测性配置全部由 Codex 生成,而每一个都提供一条"可执行验证路径"。对"能力强但不可靠的模型",答案不是指望模型自觉负责,而是让验证路径成为 harness 的默认组件。
审批策略(approval policies)与计划模式(plan mode)提供反向反馈:高风险操作执行前,系统先生成计划并请求批准,把"任务边界"与"人类决策权"变成运行时控制。
映射到课程框架
| 子系统 | Codex 的实现 | 评估 |
|---|---|---|
| 指令 | AGENTS.md 目录页 + 拆分 docs/ + 强制不变量 | 教科书级;定义了"给地图,别给手册" |
| 工具 | Worktree 隔离 + spawn_agent 子代理 | 通过环境隔离实现强边界 |
| 环境 | 独立 worktrees + 可观测性栈 | Worktree 隔离是标志性特性 |
| 状态 | Write 策略(状态写入文件/文档) | 依赖约定而非内置记忆 |
| 反馈 | 规范中的验证命令 + 审批策略 + 计划模式 | 让反馈路径成为默认;值得采纳 |
Codex 与 Claude Code 的对比很能说明问题:Claude Code 用"加法",把记忆、权限、子代理放进核心;Codex 用"减法",保持核心克制,把更多责任交给仓库约定与上下文工程。
DeepSeek Harness:把 harness 变成与模型无关的操作系统
DeepSeek Harness(命令名 dsh)的官方定义直截了当:Agent = Model + Environment + Tools + State——模型、环境、工具、状态的四元组合。如果前三款产品问"harness 应该怎么设计",它问的是更激进的问题:harness 能不能成为独立于特定模型的运行时? 答案是肯定的,而且它把这件事做到了极致:产品的每一部分都是插件,包括模型适配器、工具注册表、会话日志,乃至 agent 循环本身。详细拆解见 Breaking Down DeepSeek Harness's Design。
这是课程"模型权重之外一切都是 harness"的最彻底实现:如果 harness 是独立的,那就让它成为自己的操作系统。
架构核心一:能力接缝(Capability Seam)
DeepSeek Harness 把"能力"表示为 Services,并几乎把每个能力分成三层:
Service Definition(服务定义:声明接口)
↓
Service Provider(服务提供者:实现接口)
↓
Consumer(消费者:通常是模型面对的工具)
以文件系统为例:在 FS Service 之下有多个 Provider——Local FS、E2B FS、Remote FS——全部通过一组一致的文件工具向上暴露。Shell、Subprocess、Sandbox、Web、LLM、SubAgent 都遵循同一结构。这回答了 harness 工程里一个老问题:agent 应该依赖"具体工具"还是"能力接口"? 它选择后者——工具子系统被标准化为接口,替换 Provider 不会改变模型看到的工具面,却彻底替换了底层环境。
架构核心二:事件管线(Event Pipeline)
DeepSeek Harness 内部不是简单的"LLM → tool → LLM"流,而是一条事件管线,每个阶段都是插件可以观察的事件点:
turn/start → claim input → assemble(system prompt / context / tools)
→ agent/pre-step → step/start → LLM request(agent/request)→ llm/stream
→ assistant/message → tool/call
→ tools/pre-execute(permission / guard / policy / hook)
→ tools/execute → tools/post-execute → tool/result → step/end → next turn
(turn/*、step/*、user/message、assistant/*、tool/* 是持久化会话事件;agent/pre-step、agent/request、llm/stream、tools/* 是插件可观察的扩展点。)
这个设计最大的好处是:很多功能根本不需要修改 agent 循环本身。想在工具执行前跑安全检查?监听 tools/pre-execute。想加记忆?在 agent/pre-step 注入。想记录行为?订阅会话事件。想修改模型请求?挂到 agent/request。想决定是否继续推理?监听 agent/turn-stopping。相比 Lecture 11"让 agent 执行可观测",它更进一步:不是"加日志",而是把循环的每一步变成事件点,让可观测性、权限、记忆、策略以监听者身份挂到循环上,而不是硬编码进循环。
架构核心三:会话事件日志与"模型可见即记录"
DeepSeek Harness 有一条只追加(append-only)的会话事件日志,并确立了一条强大的工程约束:
Model-visible means logged. 任何进入模型请求的内容都必须能从日志中重建,并由运行时不变量(runtime invariant)强制保证。
换句话说,可观测性不是事后补加的日志,而是 harness 的第一性原理约束:任何进入模型上下文的内容默认都要被记录。这直接呼应课程末讲"可观测性属于 harness 内部",并把只追加存储设计变成一条原则:日志只追加、从不覆盖,会话状态可回放。
映射到课程框架
| 子系统 | DeepSeek Harness 的实现 | 评估 |
|---|---|---|
| 指令 | 插件化;规则/skills 以插件注入 | 极灵活,但缺乏 CLAUDE.md 式内置约定 |
| 工具 | Service Definition → Provider → Consumer 能力接缝 | 工具子系统标准化到极致 |
| 环境 | Sandbox/FS/Shell Provider 全部可替换(含远端 E2B) | 环境完全可插拔 |
| 状态 | 只追加会话事件日志 + Model-visible means logged | 可观测性成为第一性原理约束 |
| 反馈 | tools/pre-execute 处的 permission / guard / policy / hook | 反馈机制事件化 |
根本区别在于:Pi、Claude Code、Codex 都在"某个特定 agent 内部"优化 harness,而 DeepSeek Harness 把 harness 定义为独立于模型的操作系统,agent 本身只是跑在这个 OS 上、可替换的应用。代价同样清晰:灵活性越高,配置成本越高——这是"harness 即 OS"设计固有的代价。
横向对比:加法、减法与独立运行时
把四款产品放在同一张表里,它们的设计取向一目了然:
| 产品 | 核心取向 | 上下文工程策略 | 边界机制 | 关键可借鉴点 |
|---|---|---|---|---|
| Pi | 最小核心 + 可编程扩展 | 可编程压缩 + 动态上下文 + 会话树 | 扩展 hooks(权限/保护路径) | 让 agent 修改自己的 harness |
| Claude Code | 完整运行时(加法) | 五层压缩管线 + 追加式会话存储 | 权限分类器 + PostToolUse hooks | 分层记忆、职责分离的扩展面 |
| Codex | 仓库约定(减法) | Write-Select-Compress-Isolate | worktree 环境隔离 + 子代理 | AGENTS.md 目录页、不变量优先 |
| DeepSeek Harness | 独立运行时(操作系统化) | 事件管线 + 只追加会话日志 | 能力接缝 + tools/pre-execute 事件 | 循环每一步都是事件点、模型可见即记录 |
一个值得注意的共性:四款产品都认同"指令文件必须拆分、按需加载"。Pi 用"最小核心 + 按需 skills",Claude Code 用"分层作用域 + 子目录按需加载",Codex 用"100 行目录页 + docs/ 拆分",DeepSeek Harness 用"插件注入"——它们以不同方式共同验证了 Lecture 4 的结论:巨型指令文件必然失败,关键在于把指令放在离适用处最近的地方。
另一个共性是"验证必须是确定性机制而非提示词恳求":Claude Code 用权限分类器 + hooks,Codex 把验证命令写进规范并用 worktree 隔离验证,DeepSeek Harness 在 tools/pre-execute 挂 permission/guard/policy,Pi 通过扩展面让社区实现 session-summary 等反馈机制。这对应课程 Lecture 9 · Why Agents Declare Victory Too Early 与 Lecture 10 · Why End-to-End Testing Changes Results 的核心论点。
如何阅读本部分并落地到自己的项目
本部分的推荐阅读路径是:先读前几讲课程建立五子系统框架——尤其是 Lecture 2 · What a Harness Actually Is——再回到这里看真实产品如何实现这些机制。每篇文章结尾都包含 "Mapping to the Course Framework"(映射到课程框架) 与 "Designs Worth Adopting"(值得采纳的设计) 两节,帮助你快速把产品设计选择翻译回课程概念。
四篇文章给出的"值得采纳"清单汇总起来,就是一份可以直接动手的检查表:
- 让压缩策略可插拔:harness 里"上下文如何压缩"不应该是硬编码参数,而应是可替换的策略接口(Pi 的做法)。
- 用会话树或追加式存储替代强制摘要:跨会话恢复不一定要依赖"上一轮的摘要",结构化历史回放往往是更可靠的状态子系统(Pi 的会话树、Claude Code 的 history.jsonl、DeepSeek 的只追加日志)。
- 指令按作用域分层:不要堆进单个文件;目录级指令文件是"加载到离指令适用处最近的地方"的优雅实现(Claude Code)。
- 把 AGENTS.md 写成目录页:约 100 行,指向 docs/ 中的细节,使其可机械检查;只写不变量与验证命令,不微管理实现(Codex)。
- 用 hooks/事件点做确定性检查:防止过早宣布完成需要运行时强制,而不是提示词恳求(Claude Code、DeepSeek Harness)。
- 按任务拆分上下文:切分任务的同时切分上下文,让子任务结果不污染主循环(Claude Code 子代理、Codex spawn_agent)。
- 让循环的每一步都成为事件点:把权限、记忆、策略、日志作为监听者挂到循环上,而不是硬编码进循环(DeepSeek Harness)。
- 模型可见即记录:任何进入模型上下文的内容都必须可记录、可重建,把可观测性变成第一性原理约束(DeepSeek Harness)。
- 只发送环境上下文增量:环境变化时只输出变更字段,避免逐轮重复粘贴完整系统上下文(Codex)。
- 对 prompt 缓存友好:skill 按需加载而非把所有规则一次性塞进系统提示词——这既是上下文工程,也是成本工程(Pi)。
延伸阅读路线
- 四篇产品拆解原文:Breaking Down Pi's Harness Design | Breaking Down Claude Code's Harness Design | Breaking Down Codex's Harness Design | Breaking Down DeepSeek Harness's Design
- 建立分析框架:Lecture 2 · What a Harness Actually Is,配套代码示例 harness-components.md 与 harness-vs-no-harness.ts
- 理解"仓库即系统记录":Lecture 3 · Why the Repository Must Become the System of Record
- 理解"巨型指令文件为何失败":Lecture 4 · Why One Giant Instruction File Fails
- 理解"长任务为何丢失连续性":Lecture 5 · Why Long-Running Tasks Lose Continuity
- 理解"验证与可观测性":Lecture 9 · Why Agents Declare Victory Too Early | Lecture 10 · Why End-to-End Testing Changes Results | Lecture 11 · Why Observability Belongs Inside the Harness | Lecture 12 · Why Every Session Must Leave a Clean State
【免费下载链接】learn-harness-engineering
Harness engineering beginner tutorial, from 0 to 1
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



