模型: openai/gpt-5.4
生成日期: 2026-04-01
书名: Claude Code VS OpenCode:架构、设计与未来
章节: 第20章 — 上下文工程
Token用量: 约 6,500 input + 1,800 output
20.1 从提示工程到上下文工程
在 LLM 应用的早期阶段,“Prompt Engineering(提示工程)”几乎是最流行的关键词。那时大家觉得,只要把指令写得更清楚、更聪明、多给几个例子,模型表现就会明显提升。这种理解在早期是成立的,因为当时系统相对简单,很多应用确实就是“一段提示词 + 一个模型 + 一个输出”。
但 coding agent 的出现,把这种理解迅速推到了边界。因为一个真正工作的 agent,从来都不是只靠“一段 prompt”在运行。它实际看到的是一个不断变化的 token 状态:system prompt、tool schemas、用户输入、项目规则、会话历史、工具输出、记忆、摘要、检索片段、子任务结果、宿主注入信息……当这些东西叠在一起以后,问题就不再是“提示词怎么写得更漂亮”,而是“模型在这一刻到底看到了什么”。也正因此,行业开始从 Prompt Engineering 转向 Context Engineering(上下文工程)。
所谓提示工程,本质上是研究“如何写指令”;而上下文工程研究的是“如何策划模型在当前步骤看到的全部上下文状态”。这两个层次差别非常大。前者更像文案与交互技巧,后者更像信息系统设计。
在提示工程思维下,人们常问的问题是:系统提示词该怎么措辞?角色要怎么写?few-shot example(少样本示例)该给几个?什么语气会让模型更稳?这些问题依然有价值,但它们只是整体问题的一小部分。
在上下文工程思维下,问题会变成另一组:当前哪些信息必须在场?哪些信息不该在场?哪些内容应该摘要化?哪些内容应该按需检索?哪些是长期记忆,哪些只是瞬时工作状态?工具输出应如何整形?上下文窗口快满时该如何优雅恢复?如何避免上下文在长会话中逐渐腐坏?
可以看到,后者已经明显不是“写句子”的问题,而是系统工程问题。
为什么 coding agent 会强迫行业完成这个转变?因为这类系统的失败,往往并不是某句话写得不够好,而是模型处在错误的信息环境中。它可能看了错误文件,保留了过时假设,被无关工具输出淹没,漏掉了项目规则,又或者背着一段太长太脏的历史记录继续工作。也就是说,真正的失败点经常不是 instruction wording(指令措辞),而是 context state(上下文状态)。
所以,上下文工程可以被更准确地理解为 token-state curation(token 状态编排/策展)。这里的策展不是标准计算机术语,借用了策展人安排展品的比喻:不是把所有内容都堆出来,而是精心决定什么该被摆在当前视野里、什么该暂时移走、什么该作为背景、什么该作为重点。对模型而言,每一个 token 都在竞争注意力。好的 token 会帮助判断,坏的 token 会稀释判断。
OpenCode 已经在往这个方向走,因为它把 session、message、compaction、instruction layering 这些内容当成正式架构问题来处理,而不是“顺手拼 prompt”的细节。OMO 则进一步强化了这种思路:规则注入、continuation、hook 驱动上下文变换、task-scoped context,这些都说明它已经不把“提示词”当成唯一中心,而是把上下文视作动态拼装的运行时状态。Claude Code 则把这件事产品化:memory、auto-compact、持久规则与临时工作状态分层,让用户感受到的是“系统持续懂我”,而不是“我每次都要重复说”。
从实践角度看,这种转向会带来几个重要后果。
第一,system prompt 往往应该比人们想象得更小。真正稳定、长期有效的原则才应该留在这里;那些任务局部、时间敏感、可按需获取的细节,不应永久钉死在系统提示里。
第二,retrieval(检索)会成为中心机制。你不再试图把一切都提前塞进 prompt,而是在需要的时候拉入相关规则、文件片段、历史决策或文档说明。
第三,summary(摘要)不再只是聊天便利功能,而是正式工程产物。一个高质量的紧凑摘要,往往比十几轮原始对话回放更有价值,因为它保留了真正相关的状态。
第四,tool output 也属于上下文的一部分。如果工具输出又长又乱、没有结构,那它会直接污染上下文质量。因此,上下文工程不仅是“往里放什么”,也是“工具吐出来的东西长什么样”。
第五,memory 必须分层。用户长期偏好、项目恒定规则、仓库长期事实,适合进入 durable memory(持久记忆);某次实验结果、暂时假设、局部探索发现,则应该只停留在 working context(工作上下文)中。
这种转向还会改变评估方法。过去团队可能主要测试 prompt A 和 prompt B 哪个好;现在更值得测试的是 context policy(上下文策略)A 和 B 哪个好:少注入几个文件会不会更稳?工具输出先摘要再给模型会不会更好?把规则和任务状态拆开维护会不会降低冲突?更早做委派会不会减少主上下文污染?这些策略常常比几个句子换个说法更影响结果。
从更深层看,提示工程把模型想象成一个“阅读说明书的聪明读者”;上下文工程则把模型看成一个“运行在信息架构中的组件”。后者显然更接近 coding agent 的现实。因为模型的表现不仅取决于它听到了什么,也取决于周围有哪些信息、缺了哪些信息、这些信息之间的结构关系是什么,以及系统如何随着任务推进不断重排它的视野。
所以,未来 coding agent 的进步,当然仍然会受益于更强模型和更好提示词,但真正的大头越来越来自:让模型在正确的时间看到正确的信息,并且以正确的形式看到。 这就是上下文工程的本质。
一旦理解了这一点,很多看似分散的最佳实践就会自动串起来:最小 system prompt、JIT retrieval、compaction、structured notes、long-term memory、sub-agent 隔离、overflow recovery。这些都不是孤立技巧,而是同一门学问的不同侧面——像管理 CPU、内存、网络一样,管理模型的 token 状态。
提示工程教会行业如何“对模型说话”;上下文工程则教会行业如何“为模型布置思考环境”。对 coding agent 来说,后者显然是更高阶、也更关键的能力。
全景图:Prompt Engineering → Context Engineering → Harness Engineering
附录增补说明:本节由 openai/gpt-5.4 生成
本节 Token 消耗:约 3,800
如果说从 Prompt Engineering(提示工程)走到 Context Engineering(上下文工程),已经是一次重要的认知升级,那么在 2026 年的 coding agent 讨论中,行业实际上又往前迈了一步:开始进入 Harness Engineering。
这意味着,我们已经不能只问“提示词怎么写”,甚至也不能只问“模型当前看到了哪些信息”,而是要继续追问:什么样的运行环境,能够让某些错误天然更难发生,或者在发生后更容易被系统化纠正?
要理解这三者的关系,最好的方式不是把它们看成互相替代的流行语,而是看成一条逐层上升的演化阶梯。
| 范式 | 核心问题 | 时间尺度 | 确定性 |
|---|---|---|---|
| Prompt Engineering | “这句话该怎么写?” | 单次 prompt | 低 |
| Context Engineering | “模型此刻看到了什么信息?” | 单次 session | 中 |
| Harness Engineering | “什么环境能防止错误?” | 单个 project / runtime | 高 |
这个表格很重要,因为它说明三者关注的不是同一层问题。
Prompt Engineering 关注的是表达层。它研究措辞、语气、角色设定、few-shot examples、输出格式要求等,目标是让单次调用的行为尽可能符合预期。
Context Engineering 关注的是信息层。它研究模型每一步真正接触到的 token 状态:哪些文件被检索进来、哪些历史被压缩掉、哪些记忆是长期保留、哪些工具输出应该被摘要、哪些任务适合交给子 agent 以减少主上下文污染。
Harness Engineering 则关注运行时环境层。它把 system prompts、tools、MCPs、hooks、sub-agents、permissions、validators、memory policies、workflow orchestration 全都视为同一个系统设计问题。也就是说,模型并不是在“读一段话”,而是在“运行于一个被精心搭建的工程环境中”。
为什么说 Harness Engineering 包含了 Context Engineering
这里有一个容易被忽略但非常关键的判断:Harness Engineering 并不是要替代 Context Engineering,而是把它纳入一个更大的框架。
上下文当然仍然非常重要,但上下文只是 harness 的一个维度。就算你把信息喂得很精准,如果工具契约很差、权限控制很粗、编辑后没有验证、失败后没有回压、子任务没有上下文隔离,系统依然会经常出错。反过来,一个设计良好的 harness,常常可以弥补上下文的不完美,因为它会通过规则、校验、工作流和反馈机制,持续约束模型行为。
这也是行业不断“往上抽象”的原因。早期大家觉得 prompt 是核心;后来发现 context 更关键;再后来发现,context 仍然只是更大运行时设计中的一部分。于是,harness 这个概念自然出现了。
Harness 的四个维度,加上 Hooks
按照 Viv Trivedy 的提法,Harness 可以从四个维度来理解:
- System Prompt:包括 AGENTS.md、CLAUDE.md、skills、项目规则、运行时约束等。
- Tools / MCPs:包括内建工具、自定义 MCP servers、CLI wrappers、仓库专用命令、校验器等。
- Context:包括知识文档、检索片段、observability data(可观测性数据)、browser state(浏览器状态)、memory、summaries、compaction 结果等。
- Sub-agents:包括专业分工、上下文防火墙、并行执行、角色拆分、任务委派等。
在这四个维度之外,很多实践者——尤其是 HumanLayer ——还强调一个额外维度:Hooks。
这里的 hook 也需要稍作解释。它并不是 AI 教科书概念,而更像软件系统中的“事件挂钩点”:在某个事件发生时,系统自动执行一段确定性逻辑。比如 session 开始时注入规则、tool 调用前做检查、tool 调用后做摘要、sampling 后执行校验、文件变化时触发审计。这类 hooks 的价值在于:它们把原本概率性的模型流程,插入了可编程、可复现、可强制执行的控制点。HumanLayer 对 harness engineering 的重要补充,正是在这里:hooks 让 harness 从静态配置变成动态控制流。
graph TB
subgraph "Agent Harness"
SP["📋 系统提示<br/>AGENTS.md / CLAUDE.md / Skills"]
T["🔧 工具与MCP<br/>内建工具 + 自定义 MCP Servers"]
CTX["📚 上下文<br/>知识文档 / 可观测性 / 浏览器"]
SA["🤖 子智能体<br/>上下文防火墙 / 专业分工"]
HK["⚡ 钩子<br/>确定性控制流"]
end
LLM["🧠 LLM核心<br/>(非确定性)"]
SP --> LLM
T --> LLM
CTX --> LLM
LLM --> SA
HK -->|"拦截与校验"| LLM
style LLM fill:#ff6b6b,color:#fff
style SP fill:#4a9eff,color:#fff
style T fill:#51cf66,color:#fff
style CTX fill:#ffd43b,color:#000
style SA fill:#9775fa,color:#fff
style HK fill:#f06595,color:#fff
三句最能定义这个范式的话
要把 Harness Engineering 的精神说透,可以看三句具有代表性的公开表述。
第一句来自 Mitchell Hashimoto(2026 年 2 月 5 日):“anytime you find an agent makes a mistake, you take the time to engineer a solution such that the agent never makes that mistake again”。这句话几乎可以被看成 Harness Engineering 的工作准则。它强调的是:发现错误不是终点,而是把错误沉淀为系统约束的起点。
第二句来自 OpenAI(2026 年 2 月 11 日)的传播表述:团队借助 harness engineering,构建了一个million-line product with 0 hand-written code。不论把这句话理解为严格事实还是战略修辞,它都在强调同一个意思:只要 harness 足够成熟,模型生成的规模化软件生产,就不再只是“会不会写代码”的问题,而是“能不能在正确的工程环境中持续写对”。
第三句则来自 HumanLayer 对该领域的概括:hooks 提供了 event-driven deterministic control flow。这句话的重要性在于,它说明 agent 的可靠性不只是“知识够不够”,更是“环境什么时候、以什么方式、在什么节点强制介入”。
把四个维度映射到 OpenCode、OMO、Claude Code
如果把这套框架投射到 OpenCode、Oh-My-OpenCode(OMO)、Claude Code 三套系统上,可以得到一个非常清晰的对照表。
| Harness 维度 | OpenCode | OMO | Claude Code |
|---|---|---|---|
| System Prompt | config 中的 instructions、AGENTS.md | dynamic-agent-prompt-builder、41 hooks 注入上下文 | CLAUDE.md、4-type memory、managed settings |
| Tools | ~22 tools、Zod schema | 26 tools + skill-embedded MCPs | 61 tools、ML permission classifier |
| Context | session compaction、instruction management | preemptive compaction、wisdom accumulation、rules injection | 5-layer compaction、memory system |
| Sub-agents | 4 built-in agents、task tool | 11 agents、Atlas orchestrator、background spawner | AgentTool、TaskTools、DreamTask、Coordinator |
| Hooks | 5 plugin hook types | 41 hooks on 5 tiers | 5 hook types(session / compact / sampling / file) |
这个表如果展开看,会发现三者其实代表了三种很不同的 harness 策略。
1. System Prompt 维度
OpenCode 的 system prompt 层相对开放。instructions 可以来自配置,也可以来自 AGENTS.md 等项目文件。这种方式的优点是透明、可控、可自定义,但缺点是需要使用者自己具备较强的 prompt architecture 设计能力。
OMO 则把这一层工程化得更激进。dynamic-agent-prompt-builder 会根据 agent 类型动态组装提示,hooks 则可以在运行中进一步插入规则、提醒和上下文。于是 system prompt 不再只是一个静态文本,而成为 orchestration 的一部分。
Claude Code 的这层更偏“产品化管理”。通过 CLAUDE.md、memory 分层、managed settings,它形成了一套更垂直整合的指令系统。灵活性可能没有完全开放式系统那么高,但一致性和成熟度往往更强。
2. Tools / MCPs 维度
OpenCode 提供的是一个精简但严肃的工具面,大约二十多个工具,并通过 schema 做严格约束。这很符合其作为 open host 的定位。
OMO 的关键突破,在于它不仅增加工具数量,还引入了 skill-embedded MCPs。这意味着一个“能力包”不只是说明文档,而是“说明 + 工具接口 + 工作流”的组合体。这是非常典型的 harness engineering 思路,因为它把能力定义从静态知识推进到了可执行能力。
Claude Code 则看起来拥有三者中最丰富的直接工具库存,并通过 ML permission classifier 来减少人工确认成本。这也是 harness sophistication 的体现:不是单纯给模型更多手脚,而是给它一套判定“何时可以动手”的控制层。
3. Context 维度
OpenCode 已经把 session compaction、instruction management 等内容正式架构化,因此它天然站在 Context Engineering 这条线上。
OMO 则更进一步,做到了 preemptive compaction(预防式压缩)、wisdom accumulation(智慧积累) 和 rules injection(规则注入)。这说明它不仅管理上下文,还主动经营上下文,把 context 从存储问题升级为运行时调度问题。
Claude Code 的 context 层成熟度也非常高:memory system、multi-layer compaction、长期偏好保留与临时工作态分层,都体现出强烈的产品化 Context Engineering 思路。
4. Sub-agents 维度
sub-agent 是 Harness Engineering 最能体现“架构感”的一层。
OpenCode 已经具备 built-in agents 和 task tool,足以支持基本任务拆分。
OMO 则把 sub-agent 变成一整套 orchestration layer:11 个 agents、Atlas orchestrator、background spawner。这实际上把 “context firewall(上下文防火墙)” 原则落到了实处。不同 agent 处理不同问题,可以显著减少主上下文被无关探索污染。
Claude Code 虽然命名不同,如 AgentTool、TaskTools、DreamTask、Coordinator,但本质也体现了同一逻辑:通过角色与上下文边界来提升整体稳定性。
5. Hooks 维度
hooks 值得单独强调,因为它是最典型的“把概率系统嵌入确定性流程”的方式。
OpenCode 暴露了 5 类 plugin hooks,已经提供了重要的拦截面。
OMO 在此基础上发展出 41 hooks on 5 tiers。这几乎可以被看作 Harness Engineering 的实战教材:同一个宿主运行时,通过大量 hooks 被插入规则、上下文修正、验证逻辑、流程引导、状态管理。
Claude Code 的 hook 面更克制,但在 session、compaction、sampling、file 这些关键节点也提供了重要控制点。表面上接口较少,但依然体现出同样的设计哲学。
关键洞察:OMO 本质上是一个现成的 HaaS
如果要从三者里提炼出一个最关键的判断,那就是:OMO 本质上是一个把 OpenCode 转化为高工程化 agent runtime 的预制 harness。
也可以换一种更直接的说法:它是目前最接近 Harness as a Service 实践形态的系统之一。
为什么这个判断重要?因为很多团队其实并不是拿不到好模型,而是做不好 harness engineering。Harness Engineering 很难,它不是一个“大创意”,而是很多小控制点、很多默认值、很多工作流规则、很多验证机制、很多上下文策略长期积累的结果。OMO 的价值,就在于它把这些原本需要团队自己从零搭的能力,提前封装成了现成 runtime intelligence。
从这个角度看:
- Claude Code 是通过垂直整合,做出成熟闭环 harness;
- OpenCode 是提供一个开放的 harness 宿主,允许用户自己构建;
- OMO 则是在开放宿主之上,把 harness sophistication 打包出来。
从“优化一次对话”到“优化一个项目运行时”
Prompt、Context、Harness 这三层,其实还对应着一个时间尺度的升级:
- Prompt Engineering 优化的是一次请求;
- Context Engineering 优化的是一次会话;
- Harness Engineering 优化的是一个项目级运行时。
时间尺度一变,确定性就会逐渐增强。prompt 的影响通常是柔性的;context policy 稍强一些,但依然带有动态性;而 harness 中的 hooks、validators、permissions、sub-agent workflows、knowledge files 则是更持久的项目结构。它们不只是建议模型,而是在重塑模型可以采取的行为空间。
对构建者的真正启发
因此,当一个 agent 出错时,真正成熟的团队不应只停留在“改 prompt”这一层,而应学会判断修复应该落在哪一层:
- 如果是表达歧义,修 prompt;
- 如果是模型看错了信息,修 context policy;
- 如果这类错误本来就不该再发生,修 harness。
这就是今天 coding agent 设计正在发生的核心转向。Prompt Engineering 教会了行业如何更好地写指令;Context Engineering 教会了行业如何管理 token 状态;而 Harness Engineering 则在进一步教行业:如何设计一个让可靠性可以累积、让错误可以沉淀为机制、让模型能力真正转化为工程生产力的运行环境。