Anthropic 最近分享了一篇关于 Claude 5.0 Fable 的文章,里面提到的一个概念很适合用来理解 Coding Agent 的协作模式,那就是:unknowns。
unknowns 就是任务中那些没说清楚、没想明白,甚至一开始完全没有意识到的潜在问题。
我们平时在使用 Claude Code 时,会觉得自己的 Prompt 够清楚了。但一旦 Claude Code 开始修改代码,诸如历史设计、边界条件、依赖关系、项目风格之类的问题就会冒出来了。
所以,和 Claude Code 协作时,一个很重要的操作是先配合它把这些 unknowns 给找出来。
Prompt 是地图,代码库才是地形
如果说 Prompt、Skills 和上下文是一张地图的话,Claude Code 真正要完成工作的地方,代码库、真实业务和实际约束就是地形。

地图不是地形。Prompt 里的内容,只是对任务的描述。代码库里真实存在的历史设计、边界条件、依赖关系、项目风格,才是 Claude 真正要进入的环境。
地图和地形之间的差距,就是 unknowns。
任务越长,涉及的文件越多,Claude 遇到 unknowns 的概率就越高。而 Claude 遇到 unknowns 时,它就要根据自己对任务的理解做判断了。Fable 让 Anthropic 核心开发第一次感受到,工作质量的卡点在澄清 unknowns 的能力上。
有时候不能只靠“提前规划”,有些 unknowns 会反过来提醒我们:一开始选的方案,可能就需要调整。
unknowns 的分类

unknowns 可以拆分成了以下四种:
第一种:know knows。我们已经知道、并且已经写进 Prompt 里的内容。此类内容,包括不限于具体要开发什么功能、修改哪个模块、绝对不能动哪些文件,以及最终需要满足什么接口。
第二种:know unknowns。我们自己知道还没想明白、还没定下来的地方。此类内容,包括不限于数据模型是否需要调整、接口边界怎么定、某个功能到底要做到什么程度。这类问题适合在一开始就明确指出来,让 Claude 先帮我们分析不同方案的优劣,想清楚了再进入实际编码。
第三种:unknown knows。我们心里有明确的判断标准,但并没有在 Prompt 里写出来的内容。此类内容,包括不限于一个 UI 设计是不是顺眼、一个交互是不是自然、一个实现方式是不是符合项目的隐性习惯。很多时候,我们要在看到生成结果的那一瞬间才能做出判断,但在动手前很难用文字描述我们的需求。
第四种:unknown unknowns。我们完全没有意识到存在的问题。此类内容,包括不限于不知道该问什么、不知道代码库里有哪些历史遗留的坑,甚至不知道在这个技术领域里,“真正完美的实现”可以做到什么程度。
高水平的 Agentic Coder 开发项目中的 unknowns 一般会比较少。这不仅是因为他们很清楚自己想要什么、熟悉代码库和模型行为,更重要的是,他们会默认 unknowns 一定存在,并习惯于在动手前主动为这些不确定性做好准备。
实现前:让 Claude 先帮我暴露盲区
给 Claude 下指令容易走向两个极端。
给的指令太具体,Claude 会严格照做,哪怕中途发现换一个方案更合适,它也不一定会主动转向。给的指令太模糊,Claude 又可能直接按照通用的最佳实践来做判断,但这套判断往往并不契合当前项目的实际情况。
基于上面这些问题,我们可以当 Claude Code 是个前期协作的伙伴,先让它找出盲区,再进入正式的编码阶段。

做一次盲区排查
当我们要切到一个不熟悉的业务模块时,可以让 Claude 先做一次盲区排查。
举个例子,你准备给代码库加一个新的 auth provider,但对项目现有的 auth 模块几乎一无所知。这时可以让 Claude 先检索整个代码库,帮你找出相关的 unknown unknowns,并辅助你把后续的 Prompt 写得更清晰。
这里有个实用的示例 Prompt:
我正在给代码库添加一个新的 auth provider,但我不了解这里的 auth 模块。你能先做一次盲区排查,帮我找出相关的 unknown unknowns,并帮我更好地编写后续的 Prompt 吗?
这个方法特别适合用在任务开始前。它的价值不在于让 Claude 立刻去改写代码,而是先帮你弄清楚:这个任务里,有哪些是你目前还没意识到的潜在坑点。
先做脑暴与原型
有些任务在最开始是很难一步写到位的,尤其是涉及 UI 设计、交互、产品体验这类工作。毕竟我们有时候自己也说不清到底想要什么,但只要看到具体的方案,就能很快判断出哪一个最接近预期。
针对这种情况,可以先让 Claude 进行脑暴和原型开发。例如,先让它生成一个 HTML 页面,展示 4 种完全不同的 dashboard 设计方向;或是在真正对接后端接口前,先用假数据快速搓一个 editor toolbar 的单文件原型。
这样做的好处是能让许多 Unknown Knowns 尽早暴露出来。毕竟在正式实现后才发现方向跑偏,修改成本会呈指数级上升。尤其当代码结构、状态管理和数据流都对接完毕后,再去推翻重来,会比在原型阶段繁琐得多。
让 Claude 反问你
当我们对大方向有了初步判断后,还是会遗留一些细节上的歧义。这时候,可以直接让 Claude 反过来问你。
这里建议让 Claude 一次只问一个问题,并且优先询问那些会直接影响架构选择的关键点。你可以这样对它说:
请你一次只问我一个问题,围绕当前有歧义的地方来反问我。优先问那些我的回答会改变底层架构的问题。
给 Claude 提供具体的参考资料
如果你觉得用文字描述自己想要的东西太费劲,最直接的办法就是给 Claude 投喂具体的参考资料。它可以是设计图、产品文档或截图,当然最好的参考资料绝对是源代码。因为源代码能直接提供结构、语义和具体的实现细节,信息密度远比一张截图要高得多。
举个例子,你发现某个 Rust crate 已经完美实现了你想要的 backoff 机制,那就可以直接把这段 Rust 源码喂给 Claude,让它在当前正在写的 TypeScript API client 里复现出相同的运行语义。
生成实现计划
等上述的准备工作全部就绪、准备正式动手时,可以让 Claude 产出一份实现计划。
这份计划不需要事无巨细。只要让 Claude 把重点放在最需要人类进行主观调整和把关的地方,例如数据模型的设计、核心类型接口的定义、以及用户可见的交互流程。至于那些偏向机械性的重构或边角料代码细节,可以留到后面顺手处理。
实现中:计划要能记录变化
尽管在前期做足了准备——跑过了盲区排查、产出了原型、进行了针对性反问、提供了参考代码甚至写好了实现计划,在实际动手写代码时,依然无法完全挡住新的 unknowns 的出现。
真正进入编码阶段后,Claude 随时可能撞上未被预料的边界情况,或是发现原本设想的方案与项目底层的某些约束并不匹配。
针对这一问题,这里有个实用的工作流。在实现计划确认无误后,新开一个干净对话,只把前面讨论产出的 spec、原型等核心 artifacts 提交给 Claude,让它在一个完全干净、没有冗余历史对话干扰的上下文里开始写代码。
但更重要的是,在实际编码的过程中,要让 Claude 在本地实时维护一个像是 implementation-notes.md 或 .html之类的临时文件。这个文件专门用来记录它在编码过程中做了哪些技术决定、在哪里偏离了最初的计划,以及遇到棘手的边界情况时做出了什么保守的选择。
参考下面的 Prompt:
请保持并更新一个
implementation-notes.md文件。如果你遇到了迫使你偏离原定计划的边界情况,请直接选择最保守的安全方案,并将其记录在偏差说明栏目下,然后继续推进编码。
这个机制在工程实践中极其好用。
因为在长任务结束之后,如果人类只去审查 git diff,很容易丢失修改背后的逻辑上下文。而这份 implementation-notes 则提供了一份清晰的“改动日志”,不仅能让人一眼看懂 Claude 为什么要这样改代码,也为下一轮的协作和调整留下了极佳的上下文依据。
实现后:让 Claude 把变化讲清楚
代码写完后,还可以继续让 Claude 帮我们做两件事:解释和测验。
生成 项目说明书
在实际工程中,交付一个功能不仅要代码能够跑通,还要让团队里的其他人理解它、评审它并批准它。
在这个阶段,我们可以把之前产出的原型、spec 以及实现方案打包,提炼成一份可以直接发在飞书、钉钉等沟通工具上的说明文档。
这么做主要有两个好处:
让评审者更快地理解改动。特别是当他们一开始对这个任务也带着同样的 unknowns 时,这份说明能帮他们迅速对齐背景。
向资深专家证明改动的可靠性。让团队里更懂这块业务的专家一眼看到:他们所担心的那些潜在失败点和极端边界情况,已经在这次开发中被充分考虑并处理过了。
进行通关测验
Anthropic 团队提过一件事,在经过长时间的协作后,Claude 可能在底层默默实现了很多人类并没有完全意识到的细节。此时,只靠阅读 git diff,我们获得的理解往往非常浅层,因为许多运行时行为高度依赖项目现有的代码路径。
因此,作者会让 Claude 生成一份带有上下文的 HTML 格式技术报告,并在报告的底部附带一份针对本次改动的小测验。只有当开发者自己能够完全答对这些测试题时,才允许将这次修改合入主分支。
这个方法的目的很简单,就是确保作为代码第一责任人的你,真的彻底吃透了这次由 AI 协助完成的所有改动。