# Harness Engineering 基础：定义、原则与架构模式

## 概述

2025 年下半年以来，围绕 AI agent 的工程实践讨论从"如何写更好的 prompt"急速转向"如何设计更好的运行环境"。OpenAI、Anthropic、LangChain、Inngest、HumanLayer 以及 Thoughtworks 等机构相继发表了关于 harness engineering 的深度文章，核心共识惊人地一致：**agent 的表现瓶颈不在模型能力，而在围绕模型的系统设计质量**。本文综合 8 篇核心笔记，系统梳理 harness engineering 的定义边界、核心组件、设计原则、多 agent 架构模式以及长时运行场景的特殊挑战，并识别这些文章之间的关键张力与矛盾。

## Harness 的定义与边界

### Agent = Model + Harness

LangChain 给出了最简洁的定义公式：**"Agent = Model + Harness"——如果你不是模型，那你就是 harness** [^4]。这个定义将 harness 的范围界定为围绕模型的所有代码、配置和执行逻辑，包括 system prompt、工具定义、编排逻辑、状态管理和基础设施。

但 harness 不等于 framework。Inngest 提出了这两者之间的关键区分 [^8]：**Framework** 为每个实现从头构建重试逻辑、状态持久化、任务队列和事件路由；**Harness** 则利用已有的持久化、事件驱动基础设施来统一处理这些关注点。Framework 封装应用逻辑和 AI 特定抽象，harness 提供基础设施层——"连接、保护和编排组件，但不做工作本身"。

Anthropic 从另一个角度强化了这一立场：**最成功的 agent 实现使用简单、可组合的模式，而非复杂的 framework** [^6]。Framework 虽然简化了标准任务，但通常遮蔽底层的 prompt 和响应，降低可调性。这种"反 framework"立场在多篇文章中形成共振。

Fowler/Thoughtworks 进一步将 harness 解构为三个核心类别：**Context Engineering**（知识层）、**Architectural Constraints**（约束层）和 **Garbage Collection**（清理层）[^5]。这个分类法比原始文章更为简洁，为理解 harness 提供了实用的心智模型。

### Harness 的本质是基础设施问题

Inngest 的核心洞察尤为深刻：**agent 面临的不是 AI 问题，而是基础设施问题** [^8]。持久化执行、step 级别的可观测性、自动重试、事件路由、调度和并发控制——这些都是成熟的基础设施问题，不需要为 AI 重新发明轮子。这个视角暗示 agent 工程的最佳实践应从分布式系统和编排引擎等成熟领域借鉴，而非仅从 AI 研究中寻找答案。

## 为什么 Harness 比模型能力更重要

多篇文章从不同角度论证了同一核心命题：**优化运行环境的回报远高于等待更好的模型**。

OpenAI 用大规模实践数据验证了这一点——100 万行代码、1500 个合并 PR、每工程师每天 3.5 个 PR [^1]。这些成果的关键不是模型本身，而是团队为 agent 构建的精密运行环境。HumanLayer 更直接地表述为"模型可能没问题，这只是一个技能问题（skill issue）"[^7]——大多数 coding agent 的失败不是因为模型不够聪明，而是因为工程师没有正确配置运行环境。

LangChain 从模型的根本局限出发论证了 harness 的必要性：原始模型无法维持跨交互的持久状态、无法自主执行代码、无法访问实时信息、无法配置环境或安装依赖 [^4]。这些能力缺口必须由 harness 来填补。

ETH Zurich 的研究（HumanLayer 引用）提供了一个反直觉的实证：**LLM 生成的 agent 配置文件反而会损害性能，同时多消耗 20% 的 token** [^7]。这意味着 harness 配置需要人类工程师的审慎设计，而非简单地交给 AI 自动生成。

## Harness 的核心组件

综合所有文章，harness 的核心组件可归纳为四大层次：

### 1. 系统提示与知识层

OpenAI 的 **Repo-Native Knowledge** 策略要求所有决策、架构规划和文档都驻留在代码仓库中（`AGENTS.md`、`ARCHITECTURE.md`、`PLANS.md`），agent 不会理会仓库之外的信息 [^1]。`AGENTS.md` 是一个约 100 行的轻量级索引文件，作为 agent 理解代码仓库的"入口地图"。HumanLayer 则强调 `CLAUDE.md` 应控制在 60 行以内 [^7]，过长的配置文件反而降低性能。

### 2. 工具与验证层

Anthropic 的工具设计采用 **poka-yoke（防错设计）** 原则——工具应防止常见的使用错误 [^6]。工具集应最小化：如果 agent 在两个工具之间犹豫，说明工具设计有问题。端到端测试工具（如 Puppeteer MCP、Playwright）的重要性在 Anthropic 的多篇文章中被反复强调 [^2][^3]——让 agent 像用户一样验证功能，比单纯依赖 unit test 效果显著更好。

### 3. 编排与架构约束层

OpenAI 通过 **Mechanical Enforcement**（机械化执行）确保质量——自定义 linter、CI 测试强制执行架构不变量 [^1]。Fowler 将此概括为 **"Runtime Constraints Enable Autonomy"**——约束解空间实际上使 agent 获得更大的自主权 [^5]。这是一个看似矛盾但深刻的洞察：更多的运行时约束不是限制了 agent，而是使其能更可靠地自主工作。

### 4. 基础设施层

Inngest 提供了最具体的基础设施方案：**Durable Execution**（持久化执行），每个 LLM/工具调用是可独立重试的 step [^8]。加上 step-level observability（可观测性）、事件驱动架构和 singleton 并发控制，形成了完整的生产级 agent 基础设施。OpenAI 的实践则展示了 agent 可以访问 Chrome DevTools 和 Prometheus/LogQL 进行自主调试和监控 [^1]。

## 设计原则

### 简单性优先

Anthropic 的核心哲学是：**从简单开始，只在确实能改善结果时才增加复杂度** [^6]。文章提供了完整的"复杂度阶梯"——从 augmented LLM → prompt chaining → routing → parallelization → orchestrator-workers → evaluator-optimizer → autonomous agent。工程师的决策不是"该不该用 agent"，而是"该在哪个复杂度层级停下来"。HumanLayer 将此原则具体化为"从简单开始，仅在失败时添加配置"[^7]。

### 可组合性

Inngest 的 **Six-Function Design** 将单体 agent 拆分为六个独立函数——主循环、回复函数、打字指示器、全局错误处理、定时心跳和 sub-agent 隔离 [^8]。这种关注点分离使每个组件可独立测试、重试和替换。

### 透明性与可观测性

Anthropic 强调让 agent 的思考过程可见——明确展示规划步骤，保持透明性 [^6]。OpenAI 通过 peer review（其他 agent 验证 PR）构建了 agent 级别的质量保证 [^1]。Inngest 的 step-level observability 则确保每个 step 都有追踪和审计日志 [^8]。

## 长时运行 Agent 的特殊挑战

### Context 断裂与状态持久化

长时间运行的 agent 面临一个根本性挑战：**它们必须在离散的 session 中工作，而每个新 session 都缺乏对之前工作的记忆** [^2]。Anthropic 用"换班工程师"的比喻描述了这一问题。解决方案是设计 **Session Startup Routine**：每个新 session 遵循固定流程——验证工作目录、审查 git 日志和进度文档、识别最高优先级的未完成功能、运行基础端到端测试 [^2]。

**Context 退化**是另一个核心问题。随着 context window 填满，模型的连贯性下降，部分模型出现 **"context anxiety"**——在接近感知到的 context 限制时过早结束工作 [^3]。LangChain 将此现象命名为 **context rot** [^4]，Anthropic 从 transformer 架构的 n² pairwise token 关系出发解释了其底层原因。

### 跨 Session 记忆

Anthropic 设计了双 agent 架构来解决跨 session 的持续性问题：**Initializer Agent** 负责首次 session 的基础设施搭建，**Coding Agent** 在后续 session 中专注增量开发 [^2]。关键发现是 **JSON 格式的功能清单被模型不当修改的概率远低于 Markdown** [^2]——一个实用且反直觉的洞察。`claude-progress.txt` 作为跨 session 的"记忆"载体，记录已完成的工作、当前状态和下一步计划。

### 状态持久化

OpenAI 通过 git commit 作为检查点实现状态持久化 [^1][^2]，Inngest 则通过 durable execution 使每个 step 成为可独立重试的工作单元 [^8]。两种方案分别解决了应用层和基础设施层的持久化需求。

## 多 Agent 架构模式

### Planner → Generator → Evaluator

Anthropic 设计了受 **GAN（生成对抗网络）** 启发的多 agent 系统 [^3]。核心思想是将创建和评估分离到不同的 agent 中——因为 agent 会可靠地"表扬"自己的输出，外部反馈比自我批评更有效。在全栈编码场景中，系统扩展为三 agent 架构：**Planner**（将简短 prompt 扩展为详细规格）、**Generator**（迭代实现功能）和 **Evaluator**（使用 Playwright 进行端到端测试，并在编码前协商"sprint 合同"定义成功标准）。经过 5-15 轮迭代，输出被推向更独特、更少"AI 味"的设计。

### 重构 Agent 作为"垃圾回收器"

OpenAI 坦诚承认了 agent 规模化生成代码时不可避免的质量退化——**AI slop（AI 垃圾模式）**[^1]。解决方案是部署专门的"重构 agent"定期扫描代码库，识别和修正偏离"黄金原则"的代码。Fowler 将此提升为 harness 三组件之一的 **Garbage Collection** 策略 [^5]。

### Context Firewall 与 Sub-Agent 隔离

HumanLayer 提出了 **Context Firewall** 概念——通过 sub-agent 将离散任务隔离在独立的 context window 中，防止中间噪声在父线程中积累 [^7]。这与 Anthropic 的 sub-agent 架构 [^6] 和 Inngest 的 `step.invoke()` 委托模式 [^8] 在思路上一致：隔离既维护了连贯性，又节约了 context 空间，还允许使用更便宜的模型处理子任务。

## 关键张力：未解决的矛盾

### 简单 vs 复杂

Anthropic 主张"从简单开始"[^6]，但 OpenAI 的实践表明大规模 agent 工程需要相当复杂的基础设施投入（五个月的团队努力）[^1]。Anthropic 自己也承认完整 harness 比简单方案贵 20 倍（$200 vs $9）[^3]。真正的问题是：**何时简单方案不够用，如何判断复杂度的投资回报率？**

### Harness 复杂度 vs 模型能力

Anthropic 提出了一个极具前瞻性的观点：**harness 复杂度应随模型能力提升而降低** [^3]。更新的模型需要更少的 scaffolding。这意味着今天精心设计的 harness 可能在下一代模型上变成不必要的负担。LangChain 的 **model-harness co-evolution** 概念进一步加强了这一趋势 [^4]——模型在特定 harness 中进行 post-training，两者形成协同进化。

### 灵活性 vs 可维护性

Fowler 精准地概括了这一张力：**"约束即自由"**——通过特定模式、强制边界和标准化结构来约束解空间，用灵活性换取可维护性和可靠性 [^5]。OpenAI 的 "boring tech" 原则是这一权衡的具体体现：优先使用稳定、文档完善的 API，因为 agent 在可预测的接口上表现更好 [^1]。

### 生成能力 vs 可预测性

这是 agent 工程中最根本的张力。Agent 的价值在于其生成能力和灵活性，但工程团队需要可预测的输出。Anthropic 对 Workflow（预定义路径，高可预测性）和 Agent（动态决策，高灵活性）的区分 [^6] 本质上就是这一张力的映射。Fowler 的 **"Illusion of Control"（控制幻觉）** 概念提醒我们：context engineering 提供的是概率上的改进，而非确定性的控制 [^5]。

## 跨文章洞见

**趋同模式**：所有文章都认同 harness 比模型更重要、简单优先、context 是稀缺资源这三个核心命题。从 OpenAI 的 `AGENTS.md` 到 Anthropic 的 `claude-progress.txt` 到 Manus 的 `todo.md`，"仓库内结构化知识"已成为不可争议的最佳实践。

**分歧地带**：行为测试的重要性存在温差。Anthropic 反复强调端到端测试的关键性 [^2][^3]，但 Fowler 指出 OpenAI 的方法恰恰缺乏对功能行为的验证 [^5]。另一个分歧是 harness 的标准化程度——OpenAI 展示了高度定制化的 harness [^1]，而 Fowler 预见了 harness 作为 service template 被标准化复用的趋势 [^5]。

**隐含趋势**：Fowler 预测的"技术栈趋同"值得关注——当"AI 友好性"成为技术选型的核心标准，那些拥有完善 harness 生态的技术栈将获得竞争优势 [^5]。此外，"pre-AI vs post-AI 维护分水岭"暗示为遗留代码库加装 harness 可能不值得投入，这将在系统架构策略上产生深远影响。

**未被充分讨论的领域**：多篇文章坦承"最小可行 harness"的定义仍不清晰 [^1]。harness 工程的团队能力建设——谁来设计 harness、需要什么技能——几乎没有被讨论。

## 对技术管理者的建议

1. **从审计开始**：盘点团队已有的"隐性 harness"——pre-commit hooks、linter、CI pipeline、架构约束、结构化测试。这些都是 harness 的雏形，应被系统化和强化 [^5]。

2. **投资仓库内知识**：创建 `AGENTS.md`（或 `CLAUDE.md`）作为 agent 的入口地图，保持精简（60-100 行），指向结构化的详细文档 [^1][^7]。这是投资回报率最高的单一行动。

3. **建立机械化质量门禁**：不要依赖 agent 的"判断力"来保证质量。通过 linter、类型检查和 CI 测试来机械化强制执行标准 [^1][^5]。

4. **选择正确的复杂度层级**：使用 Anthropic 的"复杂度阶梯"作为决策框架。大多数场景下 augmented LLM 或简单 workflow 就足够了，autonomous agent 应仅用于真正开放性的问题 [^6]。

5. **为长时运行场景做专门设计**：如果 agent 需要跨 session 工作，必须投资 session startup routine、进度文件和端到端测试机制 [^2][^3]。

6. **预期 harness 的"保质期"**：随着模型能力提升，定期重新评估 harness 的复杂度。过度的 scaffolding 不仅增加成本，还可能限制更强模型的发挥 [^3]。

7. **关注基础设施而非 framework**：agent 的可靠性问题（重试、持久化、可观测性）应交给成熟的基础设施方案，而非在 AI 代码中重新实现 [^8]。

## 引用来源

- [^1]: [OpenAI: Harness Engineering](../notes/01-openai-harness-engineering.md)
- [^2]: [Anthropic: Effective Harnesses for Long-Running Agents](../notes/02-anthropic-effective-harnesses.md)
- [^3]: [Anthropic: Harness Design for Long-Running Apps](../notes/03-anthropic-harness-design-long-running.md)
- [^4]: [LangChain: The Anatomy of an Agent Harness](../notes/04-langchain-anatomy-of-harness.md)
- [^5]: [Fowler/Thoughtworks: Harness Engineering](../notes/05-fowler-harness-engineering.md)
- [^6]: [Anthropic: Building Effective Agents](../notes/06-anthropic-building-effective-agents.md)
- [^7]: [HumanLayer: Skill Issue — Harness Engineering for Coding Agents](../notes/07-humanlayer-skill-issue.md)
- [^8]: [Inngest: Your Agent Needs a Harness, Not a Framework](../notes/08-inngest-harness-not-framework.md)
