1. Harness Engineering 核心概念解析
在AI系统开发领域,Harness Engineering(线束工程)正逐渐成为一个关键学科。这个术语最早由OpenAI工程团队在2026年正式提出,描述了一种全新的工程范式——工程师不再直接编写业务逻辑代码,而是设计让AI Agent能够可靠编写代码的系统基础设施。
1.1 定义与核心思想
Harness Engineering可以定义为:设计环境、约束、反馈循环和基础设施以使AI Agent在规模化场景下可靠运行的工程学科。其核心思想可以用一个简单类比来理解:
想象你要训练一匹野马。你不会直接骑上去——你会先搭建围栏、准备缰绳、铺好跑道。这些"基础设施"不是马本身,但没有它们,再好的马也只是一匹野马。AI Agent也是如此。模型(LLM)是那匹马——强大但未被驯化。Harness Engineering就是搭围栏、做缰绳、铺跑道的工程学科。
在技术实现上,Harness Engineering包含三大核心支柱:
- Context Engineering(上下文工程):管理信息的可访问性、结构和时机
- Architectural Constraints(架构约束):通过机械执行而非建议来建立边界
- Entropy Management(熵管理):定期清理Agent解决代码退化问题
1.2 三大支柱详解
1.2.1 Context Engineering
上下文工程是Harness Engineering中最重要的组成部分,通常占据工程师45%的工作时间。它包含三个关键方面:
- 静态上下文:仓库文档、设计规范文件(如CLAUDE.md/AGENTS.md)、架构图等
- 动态上下文:实时日志、性能指标、目录映射、CI/CD状态等
- 上下文压缩:多级信息精简管道,确保关键信息优先呈现
核心原则是:"Agent无法在上下文中访问的信息等于不存在"。这意味着工程师必须精心设计信息呈现的方式和时机。
1.2.2 Architectural Constraints
架构约束占工程时间的35%,它通过以下方式建立系统边界:
- 严格的依赖层级(Types → Config → Repo → Service → Runtime → UI)
- 确定性Linter执行自定义规则
- 基于LLM的审计员审查Agent合规性
- 结构性测试和pre-commit hooks
一个反直觉但重要的发现是:适当的约束实际上能让Agent更高效,因为它阻止了无用的探索,聚焦于解决方案空间。
1.2.3 Entropy Management
熵管理占剩余的20%工程时间,但对系统长期稳定性至关重要。它包括:
- 文档一致性验证
- 约束违规扫描
- 模式强制执行
- 依赖审计
这些措施共同防止系统随着时间推移而逐渐退化。
1.3 与传统工程学科的关系
Harness Engineering与几个相关学科有着密切联系但又有明显区别:
| 学科 | 与Harness Engineering的关系 |
|---|---|
| Prompt Engineering | Context Engineering的子集(单次交互vs系统级) |
| ML Engineering | 独立学科;假设模型已部署 |
| Agent Engineering | 互补;Harness工程师为Agent构建基础设施 |
| DevOps | 共享基础设施技能,但应用于AI上下文 |
1.4 为什么现在需要Harness Engineering?
三个关键趋势推动了Harness Engineering的兴起:
- 模型能力的提升:现代LLM已经足够强大,需要更完善的基础设施来发挥其潜力
- 系统复杂度的增加:AI系统规模扩大,需要更严格的约束和管理
- 投资回报率的考量:数据显示Harness优化的ROI远高于模型优化
LangChain的案例证明,仅改变Harness架构(不换模型)就能在Terminal Bench 2.0基准测试上从52.8%提升到66.5%,从Top 30跃升至Top 5。相比之下,模型微调通常只能带来3-5%的提升,却需要数周时间和大量计算资源。
2. Claude Code架构深度解析
Claude Code是Anthropic官方的AI编码助手CLI,拥有超过50万行TypeScript代码,是目前最完整的生产级Agent Harness参考实现。通过逆向工程它的架构,我们可以学习到教科书上找不到的实战智慧。
2.1 技术栈概览
Claude Code采用了现代化的技术栈:
| 类别 | 技术选择 |
|---|---|
| Runtime | Bun(TypeScript原生,高性能) |
| 语言 | TypeScript(严格模式) |
| UI框架 | React + Ink(终端组件) |
| CLI解析 | Commander.js |
| Schema验证 | Zod v4 |
| 搜索引擎 | ripgrep(通过BashTool调用) |
| API客户端 | @anthropic-ai/sdk |
| 协议 | MCP SDK, LSP |
| 状态管理 | 自定义Zustand-like Store + React Context |
| 遥测 | OpenTelemetry + gRPC |
| 功能开关 | GrowthBook + Bun bun:bundle |
| 认证 | OAuth 2.0, JWT, macOS Keychain |
2.2 系统规模与组成
Claude Code是一个相当庞大的系统:
- ~1,884个TypeScript/TSX文件
- 512,664行代码
- 43+工具
- 100+ Slash命令
- 80+ React Hooks
- 144+ UI组件
- 22+服务模块
- 26+ Hook事件
代码分布上,tools/和utils/是最大的两个目录,合计约占32%的代码量,反映出工具系统和基础设施工具是Harness的核心。
2.3 核心架构设计
2.3.1 目录结构
Claude Code的目录结构设计反映了其模块化架构:
code复制src/
├── main.tsx # 入口点,CLI引导
├── query.ts # 核心Agent循环
├── QueryEngine.ts # LLM查询引擎
├── Tool.ts # Tool基础接口
├── tools.ts # Tool注册表
├── Task.ts # 任务类型定义
├── commands.ts # 命令注册
├── tools/ # 43个工具目录
│ ├── BashTool/ # Shell命令执行
│ ├── FileReadTool/ # 文件读取
│ ├── FileWriteTool/ # 文件创建
│ ├── FileEditTool/ # 部分文件修改
│ └── ... # 更多工具
├── commands/ # ~101个命令目录
├── components/ # 144+ React/Ink终端组件
├── hooks/ # 80+自定义React Hooks
├── services/ # 22个服务子目录
├── utils/ # 33+子目录,100+文件
├── state/ # 应用状态管理
└── ... # 其他核心目录
2.3.2 入口点流程
Claude Code的启动流程设计精巧:
code复制main.tsx → 并行预取(MDM设置 + Keychain + API预连接)
↓
Commander.js CLI解析器初始化
↓
preAction Hook: init() → 遥测 → 插件 → 迁移 → 远程设置
↓
React/Ink渲染器启动
↓
交互式REPL/对话循环
设计哲学是采用延迟加载策略。重型模块(OpenTelemetry, gRPC, analytics)在需要时才加载,而关键路径(MDM设置、Keychain)则并行预取,确保启动速度。
2.3.3 核心数据流
Claude Code的数据流全景如下:
code复制用户输入 → UserPromptSubmit Hook → Slash Command解析
↓
QueryEngine.submitMessage()
├─→ 系统提示构建: base + tools + CLAUDE.md + MCP + memory
├─→ 消息规范化: normalizeMessagesForAPI()
│ ├─ 重排序attachment消息
│ ├─ 合并连续user/assistant消息
│ ├─ 剥离PDF/图片错误的重复内容
│ ├─ 规范化工具名称(别名→正式名)
│ └─ 工具搜索引用块处理
↓
queryLoop() [while(true)]
├─→ 压缩管道: snip → micro → collapse → auto
├─→ API调用: deps.sample() [流式]
├─→ 工具执行: StreamingToolExecutor (并发) / runTools (顺序)
│ ├─→ 工具分区: partitionToolCalls()
│ │ ├─ isConcurrencySafe=true → 并发执行
│ │ └─ isConcurrencySafe=false → 串行执行
│ └─→ 每个工具:
│ ├─ Zod schema验证
│ ├─ tool.validateInput()
│ ├─ PreToolUse Hook
│ ├─ 权限检查 (rules → mode → classifier)
│ ├─ Sandbox包装 (BashTool)
│ ├─ tool.call() [实际执行]
│ └─ PostToolUse Hook
├─→ 错误恢复: 7个continue站点
└─→ Stop Hook → 终止或继续
终止 → SessionEnd Hook → 转录保存 → 退出
2.3.4 消息类型系统
Claude Code定义了丰富的消息类型系统:
typescript复制type Message =
| UserMessage // 人类输入(或工具结果)
| AssistantMessage // 模型响应(文本 + 工具调用)
| AttachmentMessage // 记忆/资源附件
| SystemMessage // 系统消息
| SystemLocalCommandMessage // 本地工具结果(bash, read等)
| ToolUseSummaryMessage // 压缩后的工具历史
| TombstoneMessage // 已删除消息标记
| ProgressMessage // 流式进度更新
消息规范化(normalizeMessagesForAPI)是一个复杂的管道,处理包括连续用户消息合并、PDF/图片错误内容剥离、工具名称规范化等多种情况。
3. Agent Loop深度解析
Agent Loop是整个Harness系统的核心引擎。Claude Code的实现位于src/query.ts的queryLoop()函数,采用Async Generator设计模式。
3.1 基本架构
queryLoop函数签名和核心结构:
typescript复制async function* queryLoop(
params: QueryParams,
consumedCommandUuids: string[],
): AsyncGenerator<
| StreamEvent
| RequestStartEvent
| Message
| TombstoneMessage
| ToolUseSummaryMessage,
Terminal
> {
// 不可变参数
const {
systemPrompt, userContext, systemContext,
canUseTool, fallbackModel, querySource,
maxTurns, skipCacheWrite,
} = params
// 可变跨迭代状态
let state: State = {
messages: params.messages,
toolUseContext: params.toolUseContext,
maxOutputTokensOverride: params.maxOutputTokensOverride,
autoCompactTracking: undefined,
stopHookActive: undefined,
maxOutputTokensRecoveryCount: 0,
hasAttemptedReactiveCompact: false,
turnCount: 1,
pendingToolUseSummary: undefined,
transition: undefined,
}
while (true) {
// 循环体...
}
}
State类型定义了循环的核心状态:
typescript复制type State = {
messages: Message[]
toolUseContext: ToolUseContext
autoCompactTracking: AutoCompactTrackingState | undefined
maxOutputTokensRecoveryCount: number
hasAttemptedReactiveCompact: boolean
maxOutputTokensOverride: number | undefined
pendingToolUseSummary: Promise<ToolUseSummaryMessage | null> | undefined
stopHookActive: boolean | undefined
turnCount: number
transition: Continue | undefined
}
3.2 七个Continue站点
Claude Code的queryLoop设计了7个关键continue站点,每个对应不同的恢复场景:
- Proactive Compaction:token超过阈值时触发自动压缩
- Prompt Too Long:API返回prompt-too-long错误时触发上下文折叠
- Max Output Tokens:模型输出截断时升级8k→64k并重试
- Fallback Model:FallbackTriggeredError时切换模型重试
- Stop Hook Blocking:用户Hook要求额外轮次时注入消息继续
- Image/Media Errors:媒体错误时移除问题内容继续
- Tool Execution:正常工具执行完成后收集结果继续
3.3 压缩管道设计
Claude Code实现了四级压缩管道来处理上下文窗口限制:
-
Level 1: Snip Compact:
- 历史截断
- 成本极低,延迟~0ms
- 每轮迭代执行
-
Level 2: Microcompact:
- 老化工具结果缩减
- 成本低,延迟~1ms
- 每轮迭代执行
-
Level 3: Context-Collapse:
- 读时投射(不修改原始数组)
- 成本中等,延迟~5ms
- 渐进式执行
-
Level 4: Autocompact:
- LLM全对话摘要
- 成本高,延迟~2s
-
50k tokens时触发
执行顺序严格遵循:snip → micro → context-collapse → auto,各级可以组合运行。
3.4 工具执行编排
Claude Code有两种工具执行模式:
模式1: StreamingToolExecutor(默认)
边流式生成边执行工具。关键设计:
- 当识别到完整的
tool_useJSON块时,工具立即排队执行 - 模型还在生成第二个工具调用时,第一个已经在运行了
- 包含错误快速失败机制:一个工具出错会中止兄弟子进程
模式2: runTools()(回退模式)
分区后顺序执行。关键算法:
- 将工具调用分区为:
- 可并发组(isConcurrencySafe=true)
- 必须串行组(isConcurrencySafe=false)
- 并发执行可安全并发的工具组
- 串行执行必须顺序执行的工具组
- 收集并延迟应用上下文修改器,确保并发安全
工具分区算法示例:
code复制输入: [Read("a.ts"), Read("b.ts"), Write("c.ts"), Read("d.ts")]
分区结果:
批次1: { isConcurrencySafe: true, blocks: [Read("a.ts"), Read("b.ts")] }
批次2: { isConcurrencySafe: false, blocks: [Write("c.ts")] }
批次3: { isConcurrencySafe: true, blocks: [Read("d.ts")] }
执行顺序: 批次1并发 → 批次2串行 → 批次3并发
3.5 错误恢复策略
Claude Code实现了精细的错误恢复级联策略:
Prompt Too Long (413) 恢复流程
- 首先尝试排空context-collapse队列
- 如果仍失败,执行Reactive Compact(完整摘要)
- 最后手段:向用户报告错误并终止
Max Output Tokens 恢复流程
- 尝试升级输出token限制(8k→64k)
- 如果仍不足,采用多轮恢复(最多3次):
- 注入恢复消息要求模型从断点继续
- 明确指示不要道歉或重述
- 要求将剩余工作分解为更小部分
Stop Hook 恢复
- 检查Stop Hook是否阻止继续
- 处理任何阻塞性错误
- 关键设计:保留hasAttemptedReactiveCompact标志,防止无限循环
4. 实战经验与优化建议
基于对Claude Code的深入分析,以下是关键实战经验:
4.1 性能优化技巧
-
工具并发执行:
- 识别工具的安全属性(只读vs写入)
- 设计合理的分区算法
- 实测可提升"读取代码库"类操作从秒级到毫秒级
-
延迟加载策略:
- 区分关键路径和非关键路径
- 重型模块按需加载
- 预取关键资源(如认证信息)
-
渐进式压缩:
- 从轻量操作开始,逐步升级
- 记录各级压缩释放的token数
- 避免不必要的重量级操作
4.2 稳定性保障
-
错误恢复设计:
- 明确定义恢复站点和优先级
- 设置尝试次数限制
- 保留关键状态标志防止循环
-
状态管理:
- 使用单一State对象
- 明确区分可变和不可变部分
- 在continue站点整体重新赋值
-
Hook系统:
- 设计合理的Hook点(pre/post工具执行等)
- 确保Hook不会破坏核心流程
- 提供足够的上下文信息
4.3 可维护性建议
-
类型系统:
- 定义丰富的消息类型
- 使用Zod等工具进行运行时验证
- 保持类型定义与业务逻辑同步
-
目录结构:
- 按功能而非类型组织代码
- 保持工具/命令/服务的明确分离
- 统一工具接口规范
-
文档规范:
- 维护详细的CLAUDE.md/AGENTS.md
- 记录设计决策和取舍
- 使用代码注释解释微妙逻辑
5. 从理论到实践
理解Harness Engineering理论后,如何开始实践?以下是渐进式实施路径:
5.1 实施层级建议
| 层级 | 范围 | 投入 | 内容 |
|---|---|---|---|
| Level 1 | 个人 | 1-2小时 | CLAUDE.md + pre-commit hooks + 测试套件 |
| Level 2 | 小团队 | 1-2天 | AGENTS.md规范 + CI约束 + 共享模板 |
| Level 3 | 组织 | 1-2周 | 自定义中间件 + 可观测性 + 调度Agent |
5.2 入门练习
-
创建CLAUDE.md:
- 描述项目背景和目标
- 定义编码规范和约束
- 提供常见任务示例
-
实现基础工具:
- 文件读写工具
- 搜索工具
- 简单的Shell命令工具
-
设计Agent Loop:
- 基本循环结构
- 错误处理框架
- 简单的上下文管理
5.3 进阶路线
-
引入压缩管道:
- 实现snip和micro级别
- 添加context-collapse
- 最后引入autocompact
-
完善工具系统:
- 并发安全标记
- 输入验证
- 权限集成
-
构建可观测性:
- 遥测数据收集
- 性能监控
- 异常报警
Harness Engineering是一个需要理论与实践结合的学科。通过研究成熟系统如Claude Code,然后从小规模开始实践,逐步构建复杂的基础设施,开发者可以掌握这一AI时代的关键工程范式。
