ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Harness Engineering 对照实验报告:用 AGENTS.md 约束驱动开发重塑 AI 编程软件架构

Harness Engineering 对照实验报告:用 AGENTS.md 约束驱动开发重塑 AI 编程软件架构 1. 当 AI 编程撞上架构失控一个真实项目的对照实验如果你正在用 Claude Code、Codex CLI 或 Cursor 写项目大概率遇到过这种场景第一周 AI 帮你三小时搭出原型第三周你想加一个「全局序列号」功能结果发现要改 7 个文件、跑 3 次回归、还引入了两个新 bug。这不是模型变笨了而是代码库本身失去了可被 AI 安全修改的结构。Harness Engineering 这个词最近在 AI 编程圈被反复提起核心主张来自 Mitchell Hashimoto 的一句话每当 Agent 犯一次错你就花时间工程化一个解决方案让它再也不会犯同样的错。OpenAI Codex Team 在百万行零手写实践中把它提炼成「仓库即大脑」「Application Legibility」等方法论。而 AGENTS.md 就是这套方法论最直接的落地载体——它不是给人看的 README而是给 AI 看的约束文件。我最近在一个跨平台拍照工具项目上做了一组对照实验同一个需求文档、同一个模型、同一个技术栈唯一变量是「有没有 AGENTS.md 约束」。五轮迭代下来无约束分支最终变成 2645 行单文件有约束分支是 83 个文件、单文件平均 60 行、类型检查零错误。更关键的是第五轮地狱级需求变更时无约束分支的修改成本是有约束分支的 8 到 10 倍。这篇不是理论科普而是一份可复制的操作手册。我会把 AGENTS.md 约束模板、对照实验的变量设计、以及如何用 TaoToken 跑通验证请求的完整步骤都写出来你可以直接拿去改自己项目的 AGENTS.md。2. 前置准备用 TaoToken 统一模型入口做对照实验最怕的一件事是「模型不一致导致结论不可信」。Raw 分支用 A 模型、Harnessed 分支用 B 模型最后数据再漂亮也没意义。所以第一步是把两个分支的模型调用统一到同一个入口。TaoToken 在这里的作用是提供一个兼容 OpenAI 协议的 API 网关你可以在 AGENTS.md 里写死 base_url让 Claude Code、Codex CLI、以及自己写的脚本都走同一个端点。这样对照实验的「模型」变量才真正被控制住。具体操作先去官网 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 注册账号然后在控制台 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite 创建一个 API Key。Key 只在创建时显示一次复制后立刻存到环境变量里不要写进 AGENTS.md 或任何会进 git 的文件。# 写入 shell 配置避免每次会话重新 export echo export TAOTOKEN_API_KEYsk-你的key ~/.zshrc source ~/.zshrc # 验证环境变量生效 echo $TAOTOKEN_API_KEY | head -c 8API 端点固定为 https://taotoken.net/api注意这个地址不带任何 UTM 参数直接作为 base_url 使用。如果你用的是 Claude Code它读取的是 ANTHROPIC_BASE_URL如果用 Codex CLI 或 OpenAI SDK读的是 OPENAI_BASE_URL。两个都指向同一个网关即可。export OPENAI_BASE_URLhttps://taotoken.net/api export OPENAI_API_KEY$TAOTOKEN_API_KEY export ANTHROPIC_BASE_URLhttps://taotoken.net/api export ANTHROPIC_API_KEY$TAOTOKEN_API_KEY这一步做完你的两个实验分支就共享了同一个模型入口。接下来所有关于「约束 vs 无约束」的差异才能归因到 AGENTS.md 本身而不是模型波动。3. AGENTS.md 约束模板可直接复制的骨架AGENTS.md 的写法直接决定约束强度。我踩过的坑是第一版写成了「项目介绍 技术栈说明」结果 AI 读完照样往 App.js 里堆代码。后来参考 ETH Zurich 关于指令文件长度的研究60 行以内效果最佳把 AGENTS.md 压缩成「硬规则 目录契约 禁止清单」三段式约束才真正生效。下面是我在 Harnessed 分支实际使用的模板你可以直接复制到项目根目录# AGENTS.md ## 硬规则违反即拒绝生成 - 单文件不得超过 200 行超过必须拆分为同目录下的独立模块 - 禁止在 App.tsx 中写业务逻辑它只允许做路由挂载 - 所有跨模块调用必须经过 src/services/ 下的接口层 - 新增功能必须新建文件禁止在已有文件中追加超过 30 行 - 所有数据结构必须先定义在 src/types/ 中再使用 ## 目录契约 - src/ai/ AI 能力封装对外只暴露 recommend() 一个函数 - src/db/ 数据持久化只允许 database.ts 直接操作 SQLite - src/sync/ 云端同步与冲突解决禁止被 UI 层直接 import - src/plugins/ 插件系统每个插件独立目录通过 registry 注册 - src/screens/ 页面组件只允许调用 hooks 和 services - src/types/ 全局类型定义禁止写运行时代码 ## 禁止清单 - 禁止使用 any类型不确定时用 unknown 类型守卫 - 禁止在组件内直接 fetch必须走 services 层 - 禁止循环依赖A 依赖 B 则 B 不得 import A - 禁止把 API Key、密钥、token 写进任何源码文件 - 禁止删除或绕过已有测试文件 ## 变更流程 1. 每次需求变更前先读本文件确认约束 2. 变更后若发现新的错误模式把规则追加到「硬规则」 3. 提交前运行 tsc --noEmit类型错误必须为 0这份模板的关键在于「可执行」。像「保持代码整洁」这种话 AI 无法判断但「单文件不超过 200 行」它可以数行数「禁止在 App.tsx 写业务逻辑」它可以检查 import。约束越具体Harness 越硬。对照实验里 Raw 分支没有这个文件AI 每次会话都是「从零理解项目」于是它倾向于把所有逻辑塞进最少的文件里因为那样它自己「看起来」最省事。这就是无约束分支代码熵快速上升的根本原因。4. 对照实验变量设计与验证请求变量设计决定了实验能不能得出可信结论。我的做法是两个分支共用同一份 PRD、同一个模型入口、同一个技术栈React Native Expo唯一差异是 Harnessed 分支根目录有 AGENTS.md 且每次会话强制注入。五轮迭代的复杂度是递进的第一轮基础拍照加模板命名第二轮全局序列号加颜色标签第三轮跨平台适配加数据迁移第四轮视频加 AI 加云端同步第五轮实时协作加插件系统加 Web 端。每一轮结束后记录三个指标核心文件行数、新增功能需要修改的文件数、类型检查错误数。验证请求这一步很多人会跳过但它恰恰是判断 Harness 是否生效的关键。我的做法是在每轮迭代结束后用同一个 prompt 分别问两个分支的代码库看 AI 的回答质量差异。# 用 curl 直接验证模型入口是否正常 curl https://taotoken.net/api/v1/chat/completions \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -H Content-Type: application/json \ -d { model: claude-sonnet-4-20250514, messages: [ {role: user, content: 读取当前目录的 AGENTS.md然后告诉我新增一个天气插件需要改哪些文件} ], max_tokens: 1024 }如果 Harness 生效模型会回答「新建 src/plugins/weather/ 目录在 registry 注册不需要改 App.tsx」。如果没生效它会回答「在 App.js 里加一个 WeatherPlugin 组件」。这个差异就是约束驱动开发最直观的证据。你也可以在模型对话 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite 里手动跑同样的 prompt对比两个分支的回答。实测下来Harnessed 分支的回答稳定指向具体文件路径Raw 分支的回答则经常出现「在合适的位置添加」这种模糊表述。5. 本篇常见错排查第一个高频错误是 AGENTS.md 写太长。我第一版写了 300 多行结果 AI 在会话中只读了前 50 行就开始生成代码后面的约束形同虚设。解决办法是压缩到 60 行以内把最重要的硬规则放在最前面。如果规则确实多拆成 AGENTS.md 加 docs/constraints/ 目录AGENTS.md 里只放索引和最高优先级规则。第二个错误是约束之间互相矛盾。比如同时写了「禁止在组件内直接 fetch」和「services 层可以调用组件内的 hook」AI 遇到冲突时会随机选一条遵守导致行为不可预测。排查方法是把所有规则列出来逐条检查是否存在逻辑冲突尤其是「允许」和「禁止」的边界。第三个错误是忘记在会话开始时注入 AGENTS.md。Claude Code 和 Codex CLI 默认会读根目录的 AGENTS.md但如果你用的是自己写的脚本或第三方工具需要手动把文件内容拼进 system prompt。验证方法是问 AI「你读到了哪些约束」如果它答不上来说明注入没生效。第四个错误是 API Key 泄露。有人图省事把 key 写进 AGENTS.md 或 .env 后提交到 git这是严重的安全问题。正确做法是 key 只存本地环境变量AGENTS.md 里只写「禁止把密钥写进源码」这条规则。如果你怀疑 key 已经泄露立刻去控制台 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 吊销旧 key 并重新生成。第五个错误是类型检查没纳入验证流程。Harnessed 分支之所以能做到零类型错误是因为每轮迭代结束都跑 tsc --noEmit。如果你跳过这一步约束就只停留在「文件拆分」层面类型安全这个维度会失效。建议把类型检查写进 AGENTS.md 的变更流程里作为提交前的强制动作。6. 把约束驱动开发落到你的项目里如果你打算在自己的项目上复现这套方法建议从最小可行版本开始先写一份 30 行的 AGENTS.md只包含「单文件行数上限」「禁止在入口文件写业务逻辑」「新增功能必须新建文件」这三条硬规则跑两周看效果。等团队适应了再逐步追加目录契约和禁止清单。接入层面如果你只是想让 AI 稳定读取 AGENTS.md 并遵守约束用 API Keys 配合接入文档 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 把 base_url 配好就够了。如果你要做长期的编码 Agent 或者多轮迭代的 Harness 实验建议直接上 Coding Plan https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite它的会话持久化和上下文管理更适合这种需要反复注入约束的场景。最后分享一个我在实验里验证过的判断标准如果你的项目里 AI 每次新增功能都要改超过 5 个文件说明 Harness 还没建立起来如果新增功能只需要新建文件加一处注册说明约束已经生效。这个标准比任何理论都直接你可以拿它当自己项目的体检指标。
返回列表