智能体优先的仓库设计

创建时间: 2026-04-27 来源: [[sources/Harness engineering_ leveraging Codex in an agent-first world]] 相关: Harness-EngineeringGenerator-Evaluator-Architecture


核心哲学

在编码智能体系统中,从智能体的视角来看,任何无法在上下文中访问的东西都等同于不存在。Google Docs、聊天记录、人们头脑中的知识——智能体不可见。唯一可见的是仓库本地的、版本化的工件(代码、markdown、模式、可执行计划)。

因此,仓库的设计目标转变为:使智能体直接从仓库本身推理整个业务领域成为可能。人类工程师的目标是使环境对智能体既可读(legible)又可执行(enforceable)

给 Codex 一张地图,而不是一本 1000 页的使用手册。

为什么”一个大文件”方法会失败

许多团队尝试将所有智能体指引放入一个大 AGENTS.md 中。这会以可预测的方式失败:

失败模式原因
上下文是稀缺资源一个巨大的指引文件会挤占任务、代码和相关文档——智能体要么错过关键约束,要么为错误的约束进行优化
过多指引即无指引当一切都”重要”时,没有什么是真正重要的。智能体会做出局部模式匹配,而非有目的地导航
即时腐朽一本大型单体手册变成陈旧规则的坟墓。智能体无法辨别哪些仍然有效,人类停止维护,文件成为”有吸引力的陷阱”
难以验证一个单独的 blob 难以进行机械检查(覆盖率、新鲜度、所有权、交叉链接),漂移不可避免

仓库知识布局

AGENTS.md 视为目录(约 100 行),注入到每个智能体会话中。深度知识位于结构化的 docs/ 目录中:

AGENTS.md              ← 目录(约 100 行,始终在上下文中)
ARCHITECTURE.md        ← 顶层领域图与包层次结构
docs/
├── design-docs/       ← 核心信念、设计文档,含验证状态
│   ├── index.md
│   └── core-beliefs.md
├── exec-plans/        ← 执行计划
│   ├── active/        ← 活跃计划,含进展与决策日志
│   ├── completed/
│   └── tech-debt-tracker.md
├── generated/         ← 自动生成文档(如 db-schema.md)
├── product-specs/     ← 产品规范
│   └── index.md
├── references/        ← LLM 优化参考文件
│   ├── design-system-reference-llms.txt
│   └── uv-llms.txt
├── DESIGN.md          ← 设计方向与约束
├── FRONTEND.md        ← 前端框架与规范
├── PLANS.md           ← 计划约定
├── QUALITY_SCORE.md   ← 质量评分,追踪各领域差距
├── RELIABILITY.md     ← 可靠性标准
└── SECURITY.md        ← 安全规范

核心设计原则

  1. 渐进式信息披露:智能体从一个小而稳定的入口点开始,被教导接下来查找哪里——而非在开始时被淹没。
  2. 计划是一等工件:小型变更 = 轻量临时计划,复杂工作 = 完整的执行计划(进度与决策日志)。所有计划版本化并共同存储在仓库中
  3. 质量作为事实来源:质量文档对每个产品领域与架构层次进行评分,随时间追踪差距。
  4. 机械执行:专门的 linter 和 CI 作业验证知识库是最新的、交叉链接的且结构正确的。周期性的”文档园艺”智能体扫描过时文档并开启修复 PR。

架构约束作为倍增器

智能体在严格边界和可预测结构的环境中最为有效。

分层架构规则

每个业务领域(例如应用设置)内,代码只能按照固定层次向前依赖:

Types → Config → Repo → Service → Runtime → UI

跨领域关注点(认证、连接器、遥测、特性开关)通过单一显式接口进入:Providers。其他一切都被禁止,并通过机械方式强制执行。

自定义 Linter 与品味不变量

规则示例:

  • 静态强制结构化日志
  • 模式与类型的命名规范
  • 文件大小限制
  • 在边界处解析数据形状(解析,而非校验——parse, don’t validate)
  • 特定平台可靠性要求

因为 linter 是自定义的,错误消息直接包含针对智能体的修复指导。这些规则在人类优先的工作流程中可能显得迂腐,但在智能体环境中变成了倍增器:一旦编码,它们在每次生成中同时应用。

你深切关心边界、正确性和可重现性。在这些边界内,你允许智能体在如何表达解决方案方面拥有显著自由度。

智能体自主性循环

OpenAI 的仓库经过演进,使单个 Codex 智能体可以端到端完成一个新特性(无需人为干预):

提示词(例如"修复登录页面上的错误")
   ↓
验证代码库当前状态
   ↓
重现所报告的错误 → 录制错误演示视频
   ↓
实施修复 → 验证修复(驱动应用)→ 录制修复演示视频
   ↓
开启拉取请求
   ↓
响应智能体与人类反馈
   ↓
检测并修复构建失败
   ↓
仅在需要判断时升级给人类
   ↓
合并变更

将整个系统暴露给智能体

为了提高可读性,更多的基础设施被拉入智能体可访问的范围内:

  • 每个 git worktree 均可启动:每个变更均可启动一个独立的应用实例。
  • 浏览器自动化:Chrome DevTools Protocol 接入智能体运行时——DOM 快照、截图、导航。
  • 本地可观测性:每个 worktree 的临时可观测性栈(日志、指标、追踪)。智能体可直接查询 LogQL 和 PromQL。

这使得”确保服务启动完成时间在 800ms 以内”或”四个关键用户旅程中没有跨度超过两秒”这样的提示词变得可行。

技术选择偏好

智能体优先的仓库倾向于能够完全在仓库内被内化理解的依赖和抽象。通常被描述为”无聊”的技术往往更易于智能体建模——原因是组合性、API 稳定性以及在训练数据中的良好覆盖。

在某些情况下,让智能体重新实现子集功能比绕过公共库中不透明的上游行为更经济。例如:与其拉入一个通用的 p-limit 包,不如实现一个自有的 map-with-concurrency 辅助函数——它与 OpenTelemetry 仪表化紧密集成,具有 100% 测试覆盖率,且行为与运行时预期完全一致。

垃圾回收:对抗模式漂移

即使有良好的初始指引,智能体仍会复制仓库中已有的模式——包括不均匀或次优的模式。随时间推移,这会导致漂移。

解决方案:“黄金原则” + 定期清理智能体:

  • 将原则性、机械性的规则直接编码入仓库(例如”优先使用共享工具包而非手写辅助函数”、“不进行 YOLO 式数据探测”)。
  • 在定期节奏上,后台 Codex 任务扫描偏差,更新质量评分,并开启有针对性的重构 PR。
  • 大多数此类 PR 可在不到一分钟内审核并通过自动合并。

技术债务就像高利贷:几乎总是更好的做法是持续以小额增量偿还,而非任其累积后再以痛苦的爆发方式处理。

吞吐量改变合并哲学

在智能体吞吐量远超人类注意力的系统中:

  • 最小化阻塞合并门槛:拉取请求短生命周期。
  • 测试不稳定常通过后续运行处理,而非无休止地阻塞进展。
  • 纠错成本低廉,等待成本高昂

这在低吞吐量环境中是不负责任的。在这里,它往往是正确的权衡。

参考资料

  • 来源:OpenAI《Harness engineering: leveraging Codex in an agent-first world》——Ryan Lopopolo
  • 相关概念:ARCHITECTURE.md 模式——matklad,2021 年
  • 相关概念:解析,而非校验(Parse, don’t validate)——Alexis King,2019 年
  • 相关概念:AI 迫使我们编写良好代码——Logic Inc. 博客
  • 相关概念:Ralph Wiggum 循环——Geoff Huntley