11714 字
59 分钟
从地图到真实地形:Agentic Coding 时代的未知项工程

从地图到真实地形:Agentic Coding 时代的未知项工程#

基于 Anthropic 技术成员 Thariq Shihipar 的文章
《A field guide to Claude Fable 5: Finding your unknowns》
所做的深度整理、扩展解读与工程化重构。

摘要#

随着 Claude Code、Codex 等 Coding Agent 的能力持续增强,软件开发中的主要瓶颈正在发生变化。

过去,我们经常把失败归因于模型能力不足:模型不够聪明、上下文不够长、代码生成不够准确。但在越来越多的长周期任务中,真正限制结果质量的,往往不再是 Agent 是否会写代码,而是人类是否能够提前识别、表达并持续管理任务中的未知项

提示词、需求文档、Skills、规则文件和实现计划只是对任务的描述,是一张“地图”;真实代码库、历史架构、隐含约束、用户偏好和运行环境才是“真实地形”。地图与地形之间的差距,就是 Agent 必须自行猜测的空间。

本文在完整保留原文精髓的基础上,将“发现未知项”扩展为一套可工程化落地的方法论:

  • 在实施前,通过盲区扫描、头脑风暴、原型、访谈、参考实现和决策优先的计划,主动暴露未知项;
  • 在实施中,通过新会话、结构化上下文和 implementation-notes.md,记录偏离、假设与新发现;
  • 在实施后,通过解释材料、测验、评审和评测,将“代码已经完成”升级为“人类真正理解且系统可以验证”;
  • 在跨任务层面,通过 Context Engineering、Harness Engineering、规格资产和持续评测,把一次性经验沉淀为下一次 Agent 执行的基础设施。

最终目标不是消灭所有未知项,而是建立一种能力:

让高影响的未知项更早暴露,让执行中的未知项可见,让已经付过代价的未知项不再重复出现。


1. 模型越来越强,为什么长周期任务仍然会失败?#

Anthropic 原文以“地图与真实地形”的区别开篇。1

对于 Coding Agent 而言:

  • 地图是我们交给模型的提示词、需求、上下文、Skills、规则文件、实现计划和参考材料;
  • 真实地形是代码库本身、实际业务约束、历史兼容逻辑、运行环境、组织习惯、用户审美以及实现过程中不断暴露的边界条件。

地图永远不可能天然等于地形。

地图与真实地形:Prompt、Spec 与真实系统之间的偏差

当 Agent 遇到地图没有覆盖的地形时,它必须做决定。

它可能:

  • 根据行业通用实践补齐缺失信息;
  • 根据代码库中的局部模式推断整体设计;
  • 选择它认为最保守或最常见的方案;
  • 继续执行原计划,即使实现中已经出现了转向信号;
  • 在没有显式授权的情况下做出数据模型、接口或架构决策。

这些决策不一定低质量,甚至常常看起来“很合理”。问题在于,合理不等于符合当前任务的真实意图

任务越长,Agent 接触的模块越多,累积决策越多,地图与地形之间的偏差就越可能被放大。

可以使用一个非严格的启发式公式理解这种风险:

任务风险未知项数量×决策影响范围×自主执行跨度反馈密度×可验证性\text{任务风险} \approx \frac{ \text{未知项数量} \times \text{决策影响范围} \times \text{自主执行跨度} }{ \text{反馈密度} \times \text{可验证性} }

这不是一个统计模型,而是一种工程直觉:

  • 未知项越多,猜测越多;
  • 一个未知项越靠近数据模型、权限边界或公共接口,影响越大;
  • Agent 连续自主执行越久,偏差越可能累积;
  • 原型、测试、评审和可观测性越充分,偏差越容易被及时发现。

因此,强模型并没有消除工程方法的重要性。相反,模型越强、能够承担的任务越长,人类越需要把精力从“逐行写代码”转向:

  • 定义问题;
  • 识别未知;
  • 暴露关键决策;
  • 构造反馈回路;
  • 验证结果;
  • 沉淀经验。

这正是 Agentic Coding 与传统代码补全的根本区别。


2. 四种未知项:先知道自己处于哪一种状态#

原文将任务信息分成四类。这一分类看似简单,却是整篇方法论的认知基础。

类型定义典型表现主要风险最有效的处理方式
已知的已知已经明确知道并能表达功能目标、指定文件、禁止事项、验收条件信息遗漏或表达不精确Prompt、Spec、验收标准
已知的未知知道自己还没弄清楚不确定数据库、接口语义、部署方式过早拍板、未经验证就实现调研、对比、实验、提问
未知的已知实际有判断标准,但未显式表达“看到后才知道喜不喜欢”Agent 交付后才发现不符合偏好多方案、原型、示例、对照
未知的未知根本没意识到该考虑什么不知道正确问题、失败模式或优秀标准架构方向错误、隐蔽风险、系统性返工盲区扫描、专家视角、代码考古、预演

2.1 已知的已知:Prompt 中最容易表达的部分#

这部分通常包括:

  • 要新增什么功能;
  • 需要修复什么问题;
  • 哪些模块允许修改;
  • 要遵循什么架构规范;
  • 需要通过哪些测试;
  • 最终交付什么文件。

OpenAI 的 Codex 最佳实践将一个良好的任务输入概括为四类信息:目标、上下文、约束和完成条件。2 这四类内容,本质上就是把“已知的已知”尽量结构化。

但仅仅写清楚已知内容还不够。很多失败并不是 Prompt 写错,而是 Prompt 中根本没有覆盖真正决定结果的因素。

2.2 已知的未知:至少知道自己应该停下来调查#

例如:

  • 不确定当前认证模块是否允许新增 Provider;
  • 不知道某个 API 是否保证幂等;
  • 不清楚数据库中的状态字段是否允许回退;
  • 不确定前端交互应该使用弹窗还是独立页面;
  • 不知道采用事件驱动是否值得增加复杂度。

这是相对“友好”的未知项,因为你至少知道问题存在。

对这类未知,最危险的行为是为了让 Agent 尽快开始而强行给出一个未经验证的答案。正确做法是把它显式标记为待决策项,让 Agent:

  1. 阅读代码和文档;
  2. 列出候选方案;
  3. 展示证据;
  4. 说明取舍;
  5. 通过原型或实验缩小不确定性。

2.3 未知的已知:人类的“品味”与隐性知识#

这类未知在 UI、产品流程和架构设计中尤其常见。

你可能无法提前准确描述:

  • 什么样的页面“看起来专业”;
  • 怎样的代码结构“符合团队习惯”;
  • 多复杂的抽象才算合适;
  • 哪种错误提示“对用户足够友好”;
  • 哪种 API 命名“就是不对劲”。

但当你看到结果时,又能迅速做出判断。

这些判断来自经验、审美、业务直觉和组织惯例。它们并不是不存在,只是尚未被语言化。

原文强调:原型的价值不只是验证技术可行性,更重要的是帮助人类把隐性标准变成显性标准。

一旦你能够说出:

  • “我不喜欢这个方向,因为信息层级太平均”;
  • “这个流程的问题不是步骤多,而是用户失去了回退能力”;
  • “这个抽象看起来通用,但破坏了领域语义”;

未知的已知就开始转化为已知的已知。

2.4 未知的未知:真正昂贵的盲区#

这是最难处理的一类:

  • 你不知道应该问什么;
  • 你不知道优秀结果可以达到什么水平;
  • 你不知道代码库中曾经发生过什么;
  • 你不知道某个默认选择会触发安全或兼容问题;
  • 你甚至不知道当前解决的并不是真正的问题。

未知的未知无法依靠“再把需求写详细一点”解决,因为你缺少的不是表达,而是认知。

因此需要改变任务入口:

不是直接问:

帮我实现这个功能。

而是先问:

在开始实现前,请从架构、业务、数据、权限、兼容性、测试和运维角度做一次盲区扫描,指出我可能尚未意识到、但会改变方案的重要问题。

这不是让 Agent 替代决策,而是让 Agent 帮助人类获得提出正确问题的能力


3. Agentic Coding 的核心技能:管理未知,而不只是编写 Prompt#

优秀的 Agent 使用者看起来往往“更会写 Prompt”,但更深层的差异是:

  1. 他们对代码库更加熟悉;
  2. 他们知道模型擅长和不擅长什么;
  3. 他们能预测哪些决策容易出错;
  4. 他们会为未知项设计暴露机制;
  5. 他们不会把一次成功完全归因于模型;
  6. 他们会把错误转化为规则、测试、工具或文档。

因此,Agentic Coding 并不是把自然语言写得越来越长,而是建立一个围绕 Agent 的工程环境。

Martin Fowler 网站上的 Harness Engineering 文章把这种环境分为两类控制:3

  • 前馈控制(Feedforward):在 Agent 行动前,通过规则、文档、示例、架构约束和工具说明提高首次做对的概率;
  • 反馈控制(Feedback):在 Agent 行动后,通过测试、静态分析、日志、浏览器验证、代码评审和评测帮助其自我纠正。

Harness 前馈控制与反馈控制闭环

原文中的每一种方法,都可以放入这一框架:

原文方法工程角色
Blind Spot Pass在执行前发现缺失上下文
Brainstorm / Prototype低成本验证方向与隐性偏好
Interview将模糊认知转化为明确决策
References提供高信息密度的行为示例
Implementation Plan提前暴露高影响决策
Implementation Notes记录执行中出现的新未知
Pitches / Explainers让结果可理解、可评审
Quizzes验证人类是否真正掌握变更

因此,“发现未知项”不是一个单独的 Prompt 技巧,而是 Harness Engineering 的核心目标之一。


4. 帮助 Agent 帮助你:在过度具体与过度模糊之间#

原文指出,向 Agent 下达任务存在一个微妙的平衡。

4.1 过度具体:把错误方案写成不可违背的命令#

例如:

  • 必须新建一个微服务;
  • 必须引入消息队列;
  • 必须使用某个设计模式;
  • 必须按照指定类结构实现;
  • 不允许偏离预设步骤。

如果这些要求来自充分调研,它们是约束;如果它们只是未经验证的猜测,就可能把 Agent 锁死在错误方向。

强 Agent 往往能够在代码库中发现更优路径,但若指令没有授权它指出冲突,它可能仍会机械执行。

4.2 过度模糊:把所有设计责任都交给模型默认值#

例如:

帮我把登录功能做好。

Agent 必须自行决定:

  • 使用 Session 还是 JWT;
  • 是否需要刷新令牌;
  • 如何处理撤销;
  • 是否允许多设备登录;
  • 权限模型如何组织;
  • 错误如何返回;
  • 安全边界是什么;
  • 如何兼容现有用户。

模型可能采用常见实践,但“常见”不等于“适合”。

4.3 更好的任务输入:同时描述意图与认知边界#

一个成熟的任务输入应至少包括:

目标:我希望改变什么结果?
上下文:哪些代码、文档、错误、历史决策与任务相关?
约束:哪些边界不能违反?
完成条件:如何判断任务真正结束?
已知未知:哪些问题我知道尚未确定?
经验起点:我对当前领域和代码库了解多少?
决策权限:哪些决策 Agent 可以自主做,哪些必须暴露给我?
偏离策略:遇到计划外情况时,是停止、保守处理,还是记录后继续?

这比单纯增加 Prompt 字数更重要。

Anthropic 将“Context Engineering”定义为:持续选择和维护在当前推理时刻最有价值的信息,而不只是优化一句系统提示词。4 对长周期 Agent 而言,真正的问题已经从:

我应该怎样措辞?

转变为:

在这个阶段,Agent 需要看到哪些信息,哪些信息应该被压缩,哪些决策必须保持显著,哪些历史内容反而会造成干扰?


第一部分:实施前——在错误变贵之前发现未知#

5. Blind Spot Pass:先扫描盲区,再开始解决问题#

当任务位于陌生代码模块、陌生技术领域或陌生业务流程中时,第一步不应是让 Agent 写代码,而应是让它帮助你建立问题空间。

5.1 盲区扫描应该覆盖什么?#

一份高质量的 Blind Spot Pass 通常应检查:

  • 业务目标:当前需求是否只是表象?真正需要优化的指标是什么?
  • 代码结构:相关入口、核心调用链、状态流转和依赖边界在哪里?
  • 历史决策:为什么现有代码会这样设计?是否存在兼容负担?
  • 数据模型:哪些字段、约束和迁移可能被影响?
  • 权限安全:新增能力会扩大哪些访问面?
  • 失败模式:超时、重试、重复提交、部分成功如何处理?
  • 用户体验:用户如何理解状态、撤销操作和失败结果?
  • 测试验证:当前有哪些测试?最容易遗漏哪些边界?
  • 部署运维:配置、灰度、回滚和可观测性如何处理?
  • 替代方案:是否存在更简单的问题解决方式?

5.2 推荐 Prompt#

我准备在当前项目中实现【任务】。
我的当前认知:
- 我对该业务的了解:
- 我对相关代码模块的了解:
- 我已经确定的约束:
- 我目前知道但尚未解决的问题:
在开始设计或编码前,请做一次 Blind Spot Pass。
请扫描相关代码、文档、测试和配置,从以下角度识别我可能尚未意识到的未知项:
1. 真实业务目标;
2. 调用链与状态流转;
3. 数据模型;
4. 权限与安全;
5. 历史兼容;
6. 并发、一致性和失败恢复;
7. 测试与验收;
8. 部署、监控和回滚;
9. 是否存在更简单或方向不同的方案。
请按“未知项—为什么重要—需要什么证据—可能改变什么决策”的格式输出。
暂时不要修改代码。

5.3 为什么这一阶段不能被“Plan”完全替代?#

计划是在当前认知基础上组织行动,而盲区扫描是在检查当前认知本身是否成立。

如果一开始解决的是错误问题,再精细的计划只会提高错误执行的效率。


6. Brainstorm 与 Prototype:把隐性判断变成可观察对象#

原文尤其强调在存在大量“未知的已知”时,不要直接进入正式实现。

6.1 头脑风暴的目标不是生成更多想法#

无约束地让 Agent 生成二十个方案,通常只会制造信息噪声。

更有效的头脑风暴应该让方案之间形成明显差异,例如:

  • 最低成本方案;
  • 最低风险方案;
  • 最佳用户体验方案;
  • 最易维护方案;
  • 最具扩展性方案;
  • 完全不同的问题重构方案。

然后让人类对差异做反应。

不要给我十个相似方案。
请给出四个原则明显不同的方向:
A. 最小改动;
B. 体验优先;
C. 架构长期演进优先;
D. 重新定义问题的替代方案。
每个方向说明:
- 核心假设;
- 最适合的场景;
- 最大风险;
- 需要验证的未知项;
- 最小可行原型。

6.2 Prototype 的价值:降低“认知采样”成本#

原型不是低质量正式版本,而是一种认知工具。

它可以验证:

  • 技术是否可行;
  • 交互是否自然;
  • 性能是否达到下限;
  • 用户是否理解状态;
  • 数据是否足以支持功能;
  • 两个组件能否真实集成;
  • 你以为喜欢的方案是否真的合适。

Simon Willison 强调,Coding Agent 大幅降低了探索性原型的成本,使工程师能够在正式承诺之前验证更多技术路线。5

6.3 原型必须与正式实现隔离#

推荐约束:

本轮只制作一次性原型,目标是验证【假设】。
限制:
- 不修改正式业务代码;
- 不连接生产数据;
- 使用假数据或独立目录;
- 不提前建设通用抽象;
- 输出验证结论和未解决问题;
- 原型默认不可直接合并。

这样可以避免 Agent 将“探索代码”误当成“生产基础设施”。


7. Interviews:让 Agent 采访你,而不是一次抛出问题清单#

完成初步探索后,通常仍有模糊项。

原文建议让 Agent 一次只问一个问题,并优先询问那些答案会改变架构的问题。

7.1 为什么“一次一个问题”更有效?#

如果 Agent 一次列出十五个问题,人类往往会:

  • 对简单问题回答很多;
  • 对困难问题快速带过;
  • 忽略问题之间的依赖;
  • 在没有理解后果时仓促决定;
  • 给出互相矛盾的答案。

一次一个问题可以让 Agent 根据每次回答动态更新后续问题。

这更接近真正的需求分析,而不是静态问卷。

7.2 问题优先级#

Agent 应优先问:

  1. 会改变数据模型的问题;
  2. 会改变权限边界的问题;
  3. 会改变公共接口的问题;
  4. 会改变用户主流程的问题;
  5. 会改变一致性与失败恢复的问题;
  6. 会显著改变工期和复杂度的问题;
  7. 最后才是局部命名和样式问题。

7.3 推荐 Prompt#

请采访我以消除任务中的模糊项。
规则:
- 每次只问一个问题;
- 优先询问答案会改变数据模型、接口、权限、状态机或用户主流程的问题;
- 每个问题先简短说明“为什么这个答案会改变方案”;
- 根据我的回答更新你的任务理解;
- 如果我的回答与已有代码约束冲突,请指出,不要自动迎合;
- 当高影响未知项已经收敛后,输出决策摘要和仍未解决的问题。

8. References:当语言不够时,用工作示例传递语义#

有些需求很难通过描述完整传达:

  • 一套交互的节奏;
  • 一个退避算法的真实语义;
  • 某种组件组织方式;
  • 团队惯用的错误处理;
  • 一个复杂工作流的边界行为。

这时,参考实现往往比更多形容词更有效。

8.1 为什么源代码是高密度参考?#

截图只能展示最终外观,源代码还包含:

  • 状态如何变化;
  • 边界如何处理;
  • 数据如何流动;
  • 失败如何恢复;
  • 组件如何拆分;
  • 类型如何约束;
  • 测试如何表达意图。

原文认为,即使参考实现使用不同语言,它仍然能够有效传递行为语义。

Simon Willison 也提出“积攒自己会做的东西”:保存可运行示例、原型和小工具,未来让 Agent 组合已有成功资产,而不是每次从零生成。6

8.2 不要说“照抄”,要说清楚复用什么#

请阅读 `vendor/rate-limiter` 中的参考实现。
我希望复用的是:
- 指数退避的行为语义;
- 抖动策略;
- 最大等待上限;
- 可取消行为;
- 测试覆盖的边界。
我不希望复用的是:
- Rust 的具体类型组织;
- 该项目的日志框架;
- 与当前代码库冲突的命名。
请先输出语义对照表,再在当前 TypeScript 客户端中实现等价行为。

参考的目的不是复制形式,而是减少“我以为你知道我说的是什么”的空间。


9. Implementation Plan:计划应优先暴露决策,而不是堆砌步骤#

很多 Agent 生成的计划看起来很详细:

  1. 创建文件;
  2. 新增类;
  3. 修改 Controller;
  4. 增加 Service;
  5. 编写测试。

但这些往往是最不需要人类审查的机械动作。

真正需要提前暴露的是:

  • 为什么改变数据模型;
  • 新接口如何定义;
  • 状态机如何变化;
  • 哪些行为对用户可见;
  • 如何保持兼容;
  • 哪些失败需要补偿;
  • 哪些地方仍依赖假设。

9.1 决策优先的计划结构#

# Implementation Plan
## 1. 目标与非目标
## 2. 已确认事实
## 3. 仍存在的未知项
## 4. 需要人类审查的关键决策
### 4.1 数据模型
### 4.2 公共接口与类型
### 4.3 权限与安全
### 4.4 状态流转
### 4.5 用户可见行为
### 4.6 兼容与迁移
## 5. 验收与验证策略
## 6. 回滚方案
## 7. 机械性实现步骤
## 8. 暂不处理事项

9.2 计划不是一次性契约#

原文明确提醒:计划不能消灭实施中的未知项。

一个成熟计划应声明:

  • 哪些是确定决策;
  • 哪些是假设;
  • 哪些地方允许 Agent 自主选择;
  • 哪些情况必须停下来;
  • 哪些情况可采用保守方案继续;
  • 如何记录偏离。

这让计划从“理想路径描述”变成“可适应的执行协议”。


第二部分:实施中——让偏离可见,而不是假装计划没有变化#

10. 使用新的实现会话,但传递结构化成果#

原文建议:规划完成后,开启一个新的 Claude Code 会话,并把规格、原型、计划和参考材料传入。

这样做的价值在于:

  • 减少探索过程中的噪声;
  • 避免过长对话造成注意力稀释;
  • 将已收敛结论作为新的任务起点;
  • 迫使团队把关键认知沉淀为可复用文件;
  • 让实现 Agent 不必重新经历全部讨论。

Anthropic 的 Context Engineering 文章指出,上下文是有限资源,更多 Token 并不必然带来更好结果;随着内容增长,信息检索与注意力会逐渐退化。4

因此,理想做法不是把全部聊天历史塞给 Agent,而是提供一组结构化资产:

/spec.md
/prototype/
/implementation-plan.md
/architecture-decisions.md
/references.md
/acceptance-tests.md

11. Implementation Notes:为执行中的未知项建立日志#

无论规划多充分,Agent 都会在真实代码中遇到:

  • 文档与实现不一致;
  • 隐藏的兼容逻辑;
  • 缺失的测试基础;
  • 无法复用的抽象;
  • 计划没有覆盖的边界;
  • 外部依赖的真实限制;
  • 原方案在当前架构中不可行。

原文建议维护一个临时 implementation-notes.md

11.1 推荐模板#

# Implementation Notes
## Progress
- [ ] ...
## New Findings
### F-001
- 发现:
- 证据:
- 影响:
## Decisions Made
### D-001
- 决策:
- 候选方案:
- 选择理由:
- 影响范围:
- 是否需要人类复核:
## Deviations
### DEV-001
- 原计划:
- 实际发现:
- 偏离方案:
- 为什么选择保守处理:
- 风险:
- 后续动作:
## Assumptions
### A-001
- 假设:
- 当前证据:
- 如果假设错误会发生什么:
- 如何验证:
## Deferred Issues
- ...

11.2 给 Agent 明确偏离策略#

实施期间维护 `implementation-notes.md`。
遇到计划外情况时:
1. 如果会改变公共接口、数据模型、权限、安全边界或不可逆迁移,停止并明确报告;
2. 如果只是局部实现差异,选择影响最小、最容易回滚的方案继续;
3. 所有偏离必须记录原计划、发现、决策、证据和影响;
4. 不得为了“完成任务”静默删除验收条件;
5. 不得将临时绕过方案描述为正式解决方案。

这相当于为 Agent 定义了“自治边界”。


12. 从逐动作审批转向可观测的监督#

随着用户对 Agent 更熟悉,他们通常不会继续逐条批准每一个命令,而是允许 Agent 执行更长时间,并在发现偏离时中断。

Anthropic 对 Agent 自主性的研究发现,经验更丰富的 Claude Code 用户更常开启自动批准,但同时也更频繁地进行主动中断。7

这意味着有效监督并不等于:

每一步都点确认。

更成熟的监督是:

  • 能看到 Agent 正在做什么;
  • 能看到它依据了什么;
  • 能看到计划与实际的差异;
  • 能在关键节点介入;
  • 能够快速回滚;
  • 能在事后重建完整过程。

因此,Agent 系统应该提供:

  • 进度文件;
  • 结构化日志;
  • 可读的命令输出;
  • 测试状态;
  • Diff 摘要;
  • 风险告警;
  • 明确的停止条件;
  • 简单的干预入口。

第三部分:实施后——“代码写完”不是任务完成#

13. Pitches 与 Explainers:让变更能够被理解和批准#

一个功能能否交付,不只取决于代码是否运行,还取决于其他人是否能够理解:

  • 为什么要做;
  • 做了什么;
  • 为什么这样做;
  • 哪些风险已经处理;
  • 哪些风险仍然存在;
  • 如何验证;
  • 如何回滚;
  • 需要谁批准。

原文建议把原型、规格、计划和实现记录打包成一份解释材料。

13.1 推荐结构#

# Change Explainer
## 1. 一分钟摘要
## 2. 问题与影响
## 3. 演示
## 4. 方案概览
## 5. 关键决策及理由
## 6. 与原计划的偏离
## 7. 风险与缓解措施
## 8. 测试与验证结果
## 9. 部署与回滚
## 10. 需要评审者确认的事项

这种材料可以同时服务两类评审者:

  • 不了解背景的人:帮助其快速获得你最初缺少的认知;
  • 领域专家:证明常见失败模式和边界问题已被考虑。

14. Quizzes:确认人类真正理解了 Agent 完成的工作#

长时间 Agent 执行后,人类可能只知道:

  • 测试通过了;
  • Diff 很大;
  • Agent 说任务完成了。

但并不知道:

  • 真实调用链如何变化;
  • 哪些旧行为被保留;
  • 哪些假设被写进代码;
  • 失败时如何恢复;
  • 数据迁移是否可逆;
  • 哪些测试只是表面覆盖;
  • 后续维护需要注意什么。

原文作者会要求 Claude 在解释变更后对自己进行测验,并表示只有完全通过后才合并。

这个做法的本质不是考试,而是恢复认知所有权

14.1 推荐 Prompt#

请生成一份本次变更的完整技术解释,覆盖:
- 背景与目标;
- 关键调用链;
- 数据和状态如何流动;
- 主要设计决策;
- 与原计划的偏离;
- 边界与失败模式;
- 测试覆盖;
- 部署和回滚;
- 后续维护风险。
然后设计一组测验题:
- 不要只问文件名和代码细节;
- 重点验证我是否理解系统行为、约束和失败恢复;
- 包含场景题;
- 我回答后逐题评价;
- 在我无法解释关键路径前,不要将评审视为完成。

14.2 Quiz 不能替代代码评审#

测验验证的是人类理解,而不是代码正确性。

完整验证仍应包括:

  • 单元测试;
  • 集成测试;
  • 类型检查;
  • 静态分析;
  • 安全检查;
  • 架构边界检查;
  • 实际 UI 或 API 验证;
  • 独立 Review Agent;
  • 人类抽样评审。

15. 原文案例:Claude Code 如何完成 Fable 发布视频#

原文使用 Fable 发布视频说明整套方法如何串联。

作者并不是视频编辑专家,但希望使用 Claude Code 端到端完成视频制作。

15.1 从已知内容出发#

他知道:

  • Claude 可以通过代码处理视频;
  • 可以进行语音转录;
  • 可以结合 FFmpeg 做时间轴剪辑。

但他不知道:

  • 转录是否足够准确;
  • 是否能可靠识别语气词和停顿;
  • 是否能按照时间戳精确剪掉这些内容。

因此,第一步不是直接让 Agent 完整剪辑,而是让它解释 Whisper 类转录和 FFmpeg 剪辑如何配合。

15.2 用原型验证“不知道是否可行”的效果#

作者希望界面元素能与说话内容按词同步,但不知道这种效果能否实现。

于是他让 Claude 使用 Remotion 和转录时间信息制作原型视频。

原型将“技术上是否可行”从抽象讨论变成了可观察结果。

15.3 发现自己不知道“什么叫好”#

视频完成后,作者觉得画面有些沉闷,意识到这可能与调色有关。

他最初让 Claude 生成几个版本供选择,但很快发现:

  • 他不知道应该调整哪些参数;
  • 不知道优秀调色的判断标准;
  • 甚至不知道自己的偏好如何命名。

于是他不再盲目要求更多版本,而是先让 Claude 教他理解调色。

这正是从“未知的未知”向“已知的未知”,再向“已知的已知”的转化过程:

从未知项到可执行要求的认知转化

这个案例说明,Agent 不仅是执行工具,也可以是认知脚手架。


第四部分:从原文进一步扩展——未知项工程的四个支柱#

16. Context Engineering:未知项首先是上下文缺口#

Prompt 只是上下文的一部分。

Agent 在执行中真正依赖的还包括:

  • 代码;
  • 测试;
  • 目录结构;
  • 构建命令;
  • 规则文件;
  • Skills;
  • 工具描述;
  • 历史决策;
  • 当前进度;
  • 环境状态;
  • 外部资料;
  • 执行反馈。

Anthropic 将 Context Engineering 描述为:在有限的注意力预算中,持续选择最可能带来正确行为的信息。4

从未知项视角看,Context Engineering 需要解决三个问题:

16.1 缺什么?#

  • Agent 是否知道真实完成条件?
  • 是否知道历史约束?
  • 是否看到了相关测试?
  • 是否了解非目标?
  • 是否知道团队偏好的设计方式?

16.2 多了什么?#

  • 是否塞入了大量过期讨论?
  • 是否存在互相冲突的旧计划?
  • 是否包含与当前任务无关的大段文档?
  • 是否让关键约束淹没在上下文中?

16.3 如何动态更新?#

  • 新发现是否进入实现记录?
  • 已确认决策是否回写规格?
  • 重复错误是否进入规则文件?
  • 关键测试是否成为验收门禁?
  • 会话切换时如何压缩和交接?

因此,高质量上下文不是“尽可能多”,而是:

足够、相关、可验证、无冲突,并随着任务阶段变化。


17. Harness Engineering:未知项需要前馈与反馈双重控制#

Anthropic 在构建有效 Agent 的工程总结中建议,先寻找能够解决问题的最简单方案,只有在确有必要时再增加 Agent 复杂度。8

OpenAI 在介绍 Agent-first 工程实践时提到,早期进展不理想往往不是 Codex 缺乏能力,而是环境没有提供足够清晰、可执行和可强制的结构。9

当 Agent 失败时,正确问题通常不是:

如何让模型再努力一点?

而是:

它缺少什么能力、工具、规则、反馈或可观察信号?

17.1 前馈控制:减少 Agent 第一次走错的概率#

包括:

  • AGENTS.md / CLAUDE.md
  • 架构规则;
  • 代码示例;
  • Spec;
  • Skills;
  • 参考实现;
  • 脚手架;
  • 任务模板;
  • 禁止事项;
  • 验收标准。

17.2 反馈控制:让错误能够自动暴露#

包括:

  • 编译器;
  • 类型系统;
  • 单元测试;
  • 集成测试;
  • Lint;
  • 静态分析;
  • 架构测试;
  • 浏览器自动化;
  • 日志与 Trace;
  • Review Agent;
  • Evals;
  • 人类评审。

只有前馈没有反馈,团队无法知道规则是否有效;只有反馈没有前馈,Agent 会不断重复已经发生过的错误。

成熟 Harness 的目标不是控制 Agent 的每个 Token,而是让系统趋向期望状态。


18. Spec-Driven Development:把意图变成一等工程资产#

Spec-Driven Development 的核心是:先以结构化、面向行为的形式表达意图,再由 Agent 根据 Spec 实现代码。Thoughtworks 对这一实践的梳理指出,Spec 可以从一次性 Spec-first,进一步演进为长期维护的 Spec-anchored,甚至成为主要源资产。10

“未知项工程”与 SDD 的结合点在于:

  • Blind Spot Pass 发现规格缺口;
  • Interview 消除规格歧义;
  • Prototype 验证规格方向;
  • Implementation Plan 将规格映射为技术决策;
  • Implementation Notes 记录真实地形对规格的修正;
  • Explainer 和 Quiz 验证规格、实现与人类理解是否一致。

Spec 驱动的认知闭环

关键不是“写一份很长的需求”,而是让规格具有:

  • 行为导向;
  • 明确边界;
  • 可验证条件;
  • 决策记录;
  • 与代码同步演进的机制。

19. Evals 与 Compound Engineering:让同一个未知项只付一次学费#

如果每次任务都重新遇到同样的问题,说明团队只有“聊天经验”,没有工程记忆。

OpenAI 的 Agent Improvement Loop 将 Trace、人工反馈、模型反馈、Evals 和 Harness 修改连接成闭环:运行记录告诉我们发生了什么,反馈解释什么重要,Evals 将标准变成可重复检查,最终再修改 Agent 的 Harness。11

Simon Willison 将类似思想概括为 Compound Engineering:每次项目结束后做复盘,把有效经验记录下来,让后续 Agent 运行站在更高起点。5

19.1 未知项的沉淀路径#

本次发现应沉淀为
Agent 不知道构建命令AGENTS.md / CLAUDE.md
总是违反模块边界架构测试或静态规则
经常遗漏某类边界条件回归测试 / Eval Case
某个复杂操作步骤固定Skill / Script
某种设计模式反复使用参考实现 / 模板
某项业务决策长期有效Architecture Decision Record
某类错误需要人工判断Review Checklist
某工具返回信息不适合模型优化 Tool Schema 与错误消息

19.2 从记录问题到改造系统#

Agent 改进闭环:Trace、反馈、Eval 与 Harness 更新

这使“未知项管理”从一次性技巧升级为持续改进机制。


第五部分:一套完整的 Unknown Lifecycle Management 流程#

20. 未知项生命周期#

可以将原文方法进一步抽象为六个阶段。

未知项生命周期管理流程

阶段一:发现#

目标:找到尚未进入任务描述、但可能影响结果的因素。

输出:

  • 盲区清单;
  • 相关代码与文档地图;
  • 风险假设;
  • 待验证问题。

阶段二:分类#

目标:判断未知项属于哪一类,以及影响有多大。

建议标记:

  • 类型:KK / KU / UK / UU;
  • 影响:低 / 中 / 高;
  • 可逆性:可轻易回滚 / 迁移成本高 / 不可逆;
  • 决策人:Agent / 开发者 / 架构师 / 产品 / 安全;
  • 证据要求:代码 / 文档 / 原型 / 实验 / 业务确认。

阶段三:降低#

目标:通过调研、访谈、原型和参考,将未知项转化为明确决策。

不是所有未知都必须消灭。需要优先处理:

  • 高影响;
  • 低可逆;
  • 跨模块;
  • 用户可见;
  • 安全相关;
  • 数据迁移相关。

阶段四:约束#

目标:为仍然存在的未知设定执行策略。

例如:

  • 遇到权限与数据模型变化必须停止;
  • 局部实现差异可选择保守方案;
  • 所有假设必须记录;
  • 不允许静默改变验收条件;
  • 所有不可逆操作必须有回滚方案。

阶段五:验证#

目标:确认系统结果、代码质量和人类理解。

三层验证:

  1. 计算验证:测试、类型、Lint、静态分析;
  2. 语义验证:Review Agent、场景评测、规格对照;
  3. 认知验证:Explainer、Quiz、人类复述。

阶段六:沉淀#

目标:把本次发现变成下一次的前馈或反馈能力。

最终不应只留下代码,还应留下:

  • 规则;
  • 测试;
  • Spec;
  • ADR;
  • 示例;
  • Skill;
  • 工具;
  • 复盘结论。

21. 建议的项目文档结构#

project/
├── AGENTS.md
├── CLAUDE.md
├── docs/
│ ├── architecture.md
│ ├── domain-model.md
│ ├── decisions/
│ │ ├── ADR-001-xxx.md
│ │ └── ADR-002-xxx.md
│ └── agent-workflows/
│ ├── blind-spot-pass.md
│ ├── implementation-plan-template.md
│ ├── code-review-checklist.md
│ └── retrospective-template.md
├── specs/
│ └── feature-x/
│ ├── requirements.md
│ ├── unknowns.md
│ ├── prototype-notes.md
│ ├── implementation-plan.md
│ ├── implementation-notes.md
│ ├── acceptance-tests.md
│ └── explainer.md
├── evals/
│ ├── regression/
│ └── agent-behavior/
└── scripts/
├── verify.sh
└── architecture-check.sh

这里需要区分:

  • 长期上下文:项目级规则、架构、构建方式;
  • 任务上下文:某个 Feature 的需求、计划和实现记录;
  • 验证资产:测试、评测、检查脚本;
  • 决策资产:ADR、偏离和复盘。

第六部分:可直接复用的 Prompt 模板#

22. 任务启动模板#

任务目标:
【描述希望改变的业务或系统结果】
当前上下文:
- 相关代码:
- 相关文档:
- 已知历史:
- 当前错误或限制:
约束:
- 不允许改变:
- 必须保持兼容:
- 安全与合规:
- 技术限制:
完成条件:
- 行为验收:
- 测试验收:
- 文档验收:
- 部署与回滚:
我的认知起点:
- 我熟悉:
- 我不熟悉:
- 我知道尚未确定:
- 我可能存在的假设:
在编码前:
1. 做 Blind Spot Pass;
2. 标记高影响未知项;
3. 必要时逐题采访我;
4. 给出差异明显的候选方向;
5. 输出决策优先的实施计划;
6. 暂时不要修改代码。

23. 未知项登记模板#

# Unknowns Register
| ID | 未知项 | 类型 | 影响 | 可逆性 | 当前证据 | 处理方式 | 决策人 | 状态 |
|---|---|---|---|---|---|---|---|---|
| U-001 | | UU | 高 | 低 | | 原型 | | Open |

类型:

  • KK:Known Known;
  • KU:Known Unknown;
  • UK:Unknown Known;
  • UU:Unknown Unknown。

24. Agent 自治边界模板#

你可以自主决定:
- 局部变量和私有函数命名;
- 不改变行为的机械重构;
- 已有模式下的测试补充;
- 可轻易回滚的局部实现选择。
你必须停止并报告:
- 公共 API 变化;
- 数据模型或迁移变化;
- 权限与安全边界变化;
- 删除兼容逻辑;
- 新增外部依赖;
- 无法满足验收条件;
- 需要不可逆操作;
- 原计划核心假设被证明错误。
遇到其他计划外情况:
- 选择最保守、影响最小、最易回滚的方案;
- 记录到 `implementation-notes.md`;
- 在最终报告中集中说明。

25. 实施完成后的审查模板#

请不要只告诉我“任务已完成”。
请执行以下审查:
1. 对照原始目标和完成条件逐项验收;
2. 输出文件级和行为级变更摘要;
3. 说明关键调用链;
4. 列出所有新假设、偏离和保守处理;
5. 运行测试、类型检查、Lint 和可用的静态分析;
6. 检查边界条件、失败恢复、权限和并发;
7. 使用独立视角重新 Review Diff;
8. 说明未覆盖风险;
9. 生成部署和回滚步骤;
10. 生成一组场景测验,验证我是否理解本次变更。
如果存在未满足项,不得用“基本完成”掩盖。

第七部分:常见反模式#

26. 反模式一:一上来就让 Agent 全量实现#

问题:

  • 尚未验证问题;
  • 未发现高影响未知项;
  • 隐性偏好直到最后才出现;
  • Agent 在错误方向上快速积累代码。

改进:

  • 先扫描、原型、访谈和计划;
  • 将高风险决策提前。

27. 反模式二:把超长 Prompt 当成完整上下文#

问题:

  • 信息过期;
  • 规则冲突;
  • 关键约束不显著;
  • Agent 无法区分事实、猜测和历史讨论。

改进:

  • 分离长期上下文和任务上下文;
  • 标记已确认事实、假设和待决策项;
  • 使用新的实现会话传入压缩后的资产。

28. 反模式三:计划写得很细,却不允许偏离#

问题:

  • 真实地形一定会出现新情况;
  • Agent 为了服从计划掩盖冲突;
  • 计划错误被放大为系统错误。

改进:

  • 为不同类型偏离定义策略;
  • 对高影响变化停止;
  • 对局部变化保守处理并记录。

29. 反模式四:让 Agent 自己说“测试通过,所以正确”#

问题:

  • 测试可能不充分;
  • 测试可能由同一个错误假设生成;
  • 用户体验和业务语义难以完全计算验证;
  • Diff 中可能存在未覆盖路径。

改进:

  • 规格对照;
  • 独立 Review;
  • 场景测试;
  • 人类理解测验;
  • 持续 Eval。

30. 反模式五:每次都重新提醒同样的规则#

问题:

  • 经验只存在于聊天记录;
  • 团队无法复用;
  • Agent 在新会话重复犯错。

改进:

  • 两次出现的问题进入规则;
  • 可计算的问题进入测试;
  • 稳定流程进入 Skill;
  • 架构选择进入 ADR;
  • 失败案例进入 Eval 集。

31. 反模式六:把所有决策都交给 Agent,或所有决策都由人类批准#

两个极端都低效。

全部交给 Agent#

会导致:

  • 隐性架构决策无人治理;
  • 业务偏好被通用实践替代;
  • 高风险变化静默发生。

每一步都人工批准#

会导致:

  • 人类陷入命令级监督;
  • 无法扩大 Agent 自主执行跨度;
  • 审批产生疲劳,却未必提高安全。

正确方式是按影响与可逆性分层:

决策类型推荐权限
私有局部实现Agent 自主
可回滚的模块内设计Agent 决策并记录
公共接口与跨模块设计人类审查
数据、安全、权限、不可逆迁移必须显式批准

第八部分:团队成熟度模型#

32. Level 0:Prompt 驱动#

特征:

  • 每次临时输入;
  • 没有结构化上下文;
  • 完成标准模糊;
  • 主要依赖人工看 Diff。

结果:

  • 成功不可复制;
  • 错误重复发生;
  • Agent 质量波动大。

33. Level 1:计划驱动#

特征:

  • 复杂任务先计划;
  • 有基本验收条件;
  • 会要求 Agent 调研代码。

不足:

  • 计划仍是一次性的;
  • 实施偏离缺乏记录;
  • 经验没有沉淀。

34. Level 2:未知项驱动#

特征:

  • 启动前做 Blind Spot Pass;
  • 区分四类未知;
  • 使用原型和访谈;
  • 计划优先展示关键决策;
  • 实施中维护 Notes。

结果:

  • 返工更早发生;
  • 高影响决策更可见;
  • 人类和 Agent 形成真正协作。

35. Level 3:Harness 驱动#

特征:

  • 项目有规则、Skills、脚本、测试和 Review;
  • 前馈与反馈控制完备;
  • Agent 自治边界清晰;
  • 人类主要监控和干预。

结果:

  • 长周期任务可靠性提升;
  • 人工 Review 成本下降;
  • 结果更容易复现。

36. Level 4:持续改进驱动#

特征:

  • Trace、反馈和失败案例进入 Evals;
  • 重复问题自动转化为规则或检查;
  • Spec、代码和验证资产同步演进;
  • 每次项目结束都有 Compound Step。

结果:

  • 每次 Agent 运行都在改善下一次运行;
  • 团队逐渐形成可复用的 Agent 工程能力;
  • 模型升级时也能验证哪些 Harness 仍然必要。

Anthropic 对长周期 Harness 的实践还提醒:Harness 本身也会过时。每一个额外组件都隐含了“模型无法自行完成某件事”的假设,随着模型能力提升,这些假设需要通过逐项删减和对照实验重新验证。12


结语:真正稀缺的不是生成能力,而是判断与反馈能力#

当模型越来越强时,一个危险错觉是:

只要把任务完整交给 Agent,它最终总能自己解决。

但长周期任务的现实是:

  • Agent 不知道你没有表达的偏好;
  • 不知道代码库中未文档化的历史;
  • 不知道哪些行业惯例在你的组织中不成立;
  • 不知道你对问题的理解是否本身有误;
  • 也不一定知道什么时候应该停止执行并重新定义问题。

因此,Agentic Coding 的核心能力不是放弃控制,也不是逐行监督,而是建立一套未知项管理机制。

在实施前:

  • 找出盲区;
  • 通过原型和参考让隐性标准显性化;
  • 让 Agent 采访你;
  • 把高影响决策放到计划最前面。

在实施中:

  • 使用干净、结构化的上下文;
  • 定义 Agent 自治边界;
  • 记录发现、假设和偏离;
  • 让真实地形持续修正地图。

在实施后:

  • 不只看代码是否生成;
  • 还要验证系统行为、人类理解和风险边界;
  • 将经验写回规则、测试、Skills、Spec 和 Evals。

每一份 Explainer、每一次 Brainstorm、每一个 Prototype、每一轮 Interview、每一个 Reference、每一条 Test,本质上都在做同一件事:

在修复成本还低的时候,发现自己原本不知道的事情。

下一次启动复杂任务时,与其直接说“开始实现”,不如先说:

请先帮助我发现这个任务中,我尚未意识到的未知项。

这句话不是拖慢开发。

它是在强模型时代,重新把工程判断、系统理解和结果责任带回开发过程。


参考资料#

Footnotes#

  1. Thariq Shihipar, Anthropic, A field guide to Claude Fable 5: Finding your unknowns, 2026-07-06.

  2. OpenAI, Codex Best Practices.

  3. Martin Fowler, Birgitta Böckeler 等, Harness engineering for coding agent users.

  4. Anthropic, Effective context engineering for AI agents, 2025-09-29. 2 3

  5. Simon Willison, AI should help us produce better code, 2026-03-10. 2

  6. Simon Willison, Hoard things you know how to do, 2026-02-26.

  7. Anthropic, Measuring AI agent autonomy in practice, 2026-02-18.

  8. Anthropic, Building Effective AI Agents, 2024-12-19.

  9. OpenAI, Harness engineering: leveraging Codex in an agent-first world, 2026-02-11.

  10. Birgitta Böckeler, Martin Fowler, Understanding Spec-Driven-Development: Kiro, spec-kit, and Tessl, 2025-10-15.

  11. OpenAI Cookbook, Build an Agent Improvement Loop with Traces, Evals, and Codex, 2026-05-12.

  12. Anthropic, Harness design for long-running application development, 2026-03-24.

从地图到真实地形:Agentic Coding 时代的未知项工程
https://jupiter-ws.cn/posts/ai-coding/agentic-coding-unknown-engineering/
作者
Jupiter
发布于
2026-07-08
许可协议
CC BY-NC-SA 4.0