基座工程(Harness Engineering):决定你的 AI Agent 能否真正工作的关键学科
大多数运行 AI 编程智能体(AI coding agents)的团队都在优化错误的变量。他们过度痴迷于模型选择 —— Claude vs. GPT vs. Gemini —— 却将周围的脚手架视为次要的配套工作。但基准测试数据和生产环境的实战经验告诉我们一个不同的故事:一个在演示中令人惊叹的模型与一个能够可靠交付生产代码的模型之间的差距,几乎完全取决于其周围的控制环(harness),而不是模型本身。
这个公式看似简单:智能体 = 模型 + 控制环 (Harness)。控制环是除此之外的一切 —— 工具 schema、权限模型、上下文生命周期管理、反馈循环、沙箱环境、文档基础设施、架构不变性。如果控制环搞错了,即使是最前沿的模型也会生成虚构的文件路径,在会话进行到 20 轮时破坏自身的约定,甚至在没写任何测试之前就宣称功能已完成。
控制环优先地位最清晰的证据来自 SWE-bench,这是编程智能体的标准基准测试。同一个模型根据包裹它的脚手架不同,得分差异巨大 —— 在完全相同的底层模型上,不同控制环实现的得分差距可达 20–30 个百分点。SWE-bench 不仅仅是在测试模型;它同时也在评估控制环。将模型选择视为主要可靠性变量的团队正在衡量错误的东西。
指南与传感器:核心分类法
思考控制环设计最有效的框架是区分两种根本不同的控制类型。
指南 (Guides) 是前馈的 —— 它们在智能体行动之前对其进行引导。AGENTS.md 文件就是一个指南。仓库中的架构文档是一个指南。在智能体执行第一个动作之前初始化其工作上下文的启动脚本也是一个指南。指南编码了“什么是好的实践”,主动防止错误的输出,并注入模型权重中不包含的项目特定知识。
传感器 (Sensors) 是反馈 —— 它们观察智能体的行为并生成修正信号。TypeScript 的类型检查器是一个传感器。ESLint 是一个传感器。Playwright 端到端测试套件是一个传感器。标记语义问题的 AI 代码审查器也是一个传感器。传感器允许智能体在单个会话内进行自我修正,而不是在每一步都需要人工干预。
传感器进一步按类型划分。计算型传感器 —— 如类型检查器、格式化器、结构化 Linter —— 是确定性的,运行速度以毫秒计,并提供二元的通过/失败反馈。推断型传感器 —— 如评估代码是否真正符合意图的 AI 审查器 —— 是概率性的,速度较慢,并能捕捉到结构化工具完全遗漏的含义层面错误。一个成熟的控制环会同时使用这两者。
实际情况是,大多数团队拥有的是“偶然形成的控制环”,而不是“设计出的控制环”。他 们有一些 TypeScript 脚本,可能还有一个 Linter。他们添加了 CLAUDE.md 或 AGENTS.md 文件。但他们没有问:智能体在开始之前需要知道什么?每项操作后存在哪些反馈循环?当这些循环检测到失败时会发生什么?这些问题的答案 —— 而不是模型 —— 决定了生产环境的可靠性。
你的代码库现在是一个通信协议
当智能体进行主要的代码生成时,一些根本性的东西发生了变化:代码仓库本身成为了人类工程师与他们授权的智能体之间主要的通信渠道。任何存在于某人脑海中、Confluence、Notion 文档或隐性知识中的架构决策,都会在控制环中留下漏洞。
一个 Codex 团队在五个月内由三名工程师生成了大约 1,500 个拉取请求(PR),构建了一个百万行级别的生产代码库 —— 平均每位工程师每天处理约 3.5 个 PR,且没有手动编写的源代码。其中最重要的设计决策是:首先为智能体的可读性(legibility)优化仓库。这不是传统意义上的人类可读性,而是零上下文的智能体有效运作所需的东西。
具体而言,这意味着:
- 所有架构决策必须存在于仓库中,且是机器可读的,而不是散落在外部文档系统中
- 通过在 CI 中运行的结构化测试强制执行严格的依赖分层 —— 不是记录在某个 wiki 中,而是通过机械手段强制执行
- 通过 Linter 验证交叉链接的文档,以便在代码更改时引用不会失效
- 每个会话都会加载
AGENTS.md或CLAUDE.md文件,其中包含技术栈、构建/测试命令和架构约束
最后一点值得强调。研究比较人工编写与 LLM 生成的 AGENTS.md 文件的发现了一个惊人的不对称性:LLM 生成的文件实际上会损害智能体的性能,而人工编写的文件在智能体基准测试中能带来约 4 个百分点的提升。那个加载到每个智能体会话并塑造后续每个决策的文件,应该由人类精心维护,而不是自动生成。
不变量胜过微观管理
一个来自大规模运行 Agent 团队的直觉反差经验:试图通过 Prompt 中冗长的指令来控制 Agent 行为是无法扩展的。指令变得越来越长,Agent 开始忽略末尾的指令,规则与执行的比例也持续恶化。
更持久的方法是强制执行不变量,而不是描述偏好。当架构边界违规或格式不一致导致 CI(持续集成)失败,而不是仅仅出现在风格指南中时,Agent 就不需要记住规则——它会收到一个信号。这与类型系统比代码审查评论在强制执行契约方面更有效的原理相同。
一个有效的模式是:将架构编码为在 CI 中运行的结构适应度函数(structural fitness functions)。如果你有一个严格的分层规则——比如服务层代码不能从运行时层导入——那就写一个测试来强制执行它。Agent 不需要理解架构背后的推理;它只需要在 PR 合并之前通过测试。不变量是自我强制执行的。
这使人类工程师的主要工作从编写代码转变为编写验收标准。指定“完成”是什么样子的——用传感器可以评估的术语来表达——比生成实现 更具杠杆作用。模糊的 Prompt 会产生幻觉出的文件路径和对错误模块的修改。一个指定了应更改哪些文件、验收标准是什么以及应通过哪些测试的结构化任务,足以约束解空间,从而使输出变得可预测。
自我评估问题
任何要求生成 Agent 对其自身输出进行判断的框架,都会得到只有自信而没有准确性的结果。这并非某种微妙的失败模式——而是一种系统性偏差。模型总是持续高估它们刚刚产出的代码质量,且随着 Session 变长,以及 Agent 在特定方法上投入更多,这种过度自信会产生复合效应。
架构上的对策是将生成器与评估器分离。Anthropic 用于长期运行 Agent 的框架明确地做到了这一点:规划器(planner)将 Prompt 扩展为详细的规范,生成器(generator)实现功能,而独立的评估器(evaluator)根据定义的标准进行测试——使用 Playwright 进行浏览器交互,并针对设计质量、原创性、工艺和功能进行评分。评估器和生成器还会在实现开始前协商 Sprint 合约,在编写任何代码之前就一段工作的“完成”标准达成一致。
生成器-评估器分离还有第二个好处:它使评估标准显式化且可检查。当评估器是一个拥有定义评分标准的独立 Agent 时,人类可以审查并调整衡量的内容。当它是同一个 Agent 进行自我评估时,评分标准是不可见的,且总是盲目乐观。
