AI 编程的真正瓶颈不是模型,是你没搞清楚自己不知道什么

📅 2026/7/10 7:49:37
AI 编程的真正瓶颈不是模型,是你没搞清楚自己不知道什么
AI 编程的真正瓶颈不是模型是你没搞清楚自己不知道什么图 1AI 编程时代的认知四象限与三阶段方法论摘要模型够强之后限制产出质量的是你能否识别自己的未知数。本文从 Anthropic 工程师的一线实践中提炼出可操作的认知框架。2026 年 7 月 6 日Anthropic 的 Claude Code 团队工程师 Thariq Shihipar 在 Claude 官方博客发了一篇 Field Guide。文章不长但里面一句话让我停下来想了很久“Claude Fable is the first model where I find the quality of the work is bottlenecked by my ability to clarify its unknowns.”意思很直白模型能力到位了限制产出质量的变量变成了人——你能不能把自己想要什么讲清楚。这话放两年前听着像推卸责任放今天看数据就知道不是。Fable 5 在 SWE-Bench Pro 上拿到 80.3%。Stripe 在 Anthropic 的公告中报告说这个模型一天完成了他们团队预计两个月的工作——一次跨 5000 万行 Ruby 代码的框架迁移。模型确实不是瓶颈了。那新瓶颈在哪在你脑子里那些你自己都不知道存在的假设、偏好和盲区。本文是对 Thariq 原文方法论的系统整理和延伸。所有方法来自原文内容和 Anthropic 官方公开资料不是我自己的发明——但分类框架和决策表是我基于原文重新组织的目的是让你读完能直接用。从一个老比喻说起地图不是领土Thariq 用了一个认识论里的经典比喻开篇地图与领土。这个说法来自 Alfred Korzybski 1933 年的著作Science and Sanity——“The map is not the territory”对现实的表征不等于现实本身。LessWrong 社区后来把这个概念发扬光大成了理性主义者的核心心智模型之一。映射到 AI 编程场景含义举例地图你给 AI 的全部输入Prompt、CLAUDE.md、skill 文件、上下文领土代码库的真实状态隐藏依赖、全局中间件、环境变量、CI 管线约束落差你的未知数地图没覆盖到的领土区域落差越大AI 需要猜的地方越多。任务越复杂猜错的概率越高返工成本越陡峭。图 2地图与领土的结构性落差——AI 必须用猜测填补鸿沟认知四象限先给自己的无知分个类Thariq 借用了 Donald Rumsfeld 2002 年 2 月 12 日在美国国防部新闻发布会上的 经典分类原始来源可追溯到 NASA 主任 William GrahamRumsfeld 在回忆录中有说明把开发者面对 AI agent 时的认知状态分成四格象限一句话解释AI 编程中的典型表现已知的已知你清楚、也告诉了 AI“TypeScriptRESTJSON 响应”已知的未知你知道自己没想好“数据库选型我还没决定”未知的已知你的直觉判断从不写出来“这个按钮不能放页面最底部”——你没说过但看到就知道错了未知的未知你完全没意识到的代码库有个全局中间件会拦截所有请求你根本不知道Thariq 举了两个人作为未知数很少的参考标杆Boris Cherny——Claude Code 的创建者和负责人同时也是 O’Reilly 出版的《Programming TypeScript》作者Jarred Sumner——Bun 运行时的创始人Bun 被 Anthropic 收购后加入了 Claude Code 团队此信息来自多家科技媒体报道及 Anthropic Fable 5 公告中对 Claude Code 团队的描述。需要注意这两位是 Claude Code 的内部开发者他们对模型行为的了解深度远超普通用户。但 Thariq 的重点不在于你要像他们一样了解模型内部而在于他们的共同习惯——即使了解这么深他们仍然假设自己有未知数并主动去发现它们。换句话说减少和管理未知数不是初学者的补救措施是高手的标准动作。图 3认知四象限的 AI 编程映射——每种未知数对应不同的发现策略实现前发现未知数的五种武器Thariq 在原文中给出了五种实现前的探索方法。下面我按什么时候该用哪个来重新组织而不是逐条平铺。先判断你的未知数在哪个象限如果你连问题空间都不熟悉Unknown Unknowns直接写 prompt 让 AI 开始干活就像蒙着眼睛投飞镖——不是不可能中但效率极低。这时候需要盲区扫描。如果你大概知道要什么但细节模糊Known Unknowns你自己去想可能想一下午也想不全。这时候需要访谈式追问——让 AI 来发现你思考的空白。如果你能认出好但说不清楚Unknown Knowns语言描述注定有歧义。这时候需要原型/参考代码——让你的直觉判断有东西可以反应。盲区扫描进入陌生领域的第一步Thariq 原文用的术语是 “Blind Spot Pass”。操作本身很简单我要在这个项目里加一个新的 auth provider 但我对 auth 模块一无所知。 帮我做一次 blind spot pass—— 找出我在这个任务上可能的 unknown unknowns 让我后续给你的指令更精准。关键在于两个细节第一给 AI 足够的背景让它知道你的起点在哪“我对 auth 模块一无所知”第二用 “unknown unknowns” 这个词明确告诉 AI 你要的不是教程而是问题空间的展开。原型与头脑风暴处理看到才知道对不对Unknown knowns 是最贵的未知数——因为它们只有在 AI 做错了、你看到结果时才会暴露。暴露得越晚返工成本越高。Thariq 的做法是提前逼自己的直觉表态我需要一个数据看板但说不清想要什么风格。 做一个 HTML 页面4 种完全不同的设计方向。 我看了告诉你哪个方向感觉对。这不是让 AI 猜对而是用原型作为触发器让你自己的隐含偏好浮出水面。另一个变体是在编程会话开始前做范围探索问题用户 onboarding 后流失率高。 搜一下代码库给我列 10 个可以干预的点 从改动最小到最激进排序。这样做的防御价值在于AI 经常能发现你没想到的方案好事但也可能把任务范围理解得跟你预期完全不同坏事。头脑风暴帮你在动手前对齐范围。访谈式追问让 AI 发现你的思考空白当头脑风暴做完、方向大致定了但仍有模糊地带时关于这个方案的架构歧义一次一个问题地采访我。 优先问那些我的回答会改变架构决策的问题。精妙之处你不需要知道自己哪里没想清楚——AI 基于它对任务的理解来提问它问的每一个问题都是一个你可能没想到的决策点。引用参考当语言不够用时有些东西你能认出来但描述不了——退避策略的精确语义、特定的动画曲线、某个框架的错误处理模式。与其花 500 字描述还可能有歧义不如直接指向参考实现vendor/rate-limiter 这个 Rust crate 实现了我要的退避语义。 读懂它在我们的 TypeScript API client 里复现。Thariq 特别强调源代码是最好的参考比截图好得多。即使是另一种语言写的代码提供的结构信息也远比自然语言描述精确。实现计划动手前的最后一道对齐当你觉得准备差不多了写一份 HTML 实现计划。 把我最可能要调的部分放最前面数据模型、类型接口、用户可见的东西。 纯机械重构放最后——那部分我信你。注意我最可能要调的这个措辞——这不是让 AI 写一份面面俱到的设计文档而是让它主动把需要人类判断的决策点暴露出来。你只审你该审的机械部分交给 AI。实现中别让 Agent 的决策变成黑箱计划写得再好实现中也会冒出新的 unknown unknowns。代码里的边缘情况、意料之外的依赖关系、性能约束——这些只有 agent 跑起来才会撞上。举一个日常场景你让 agent 给一个表单加字段验证。计划里说邮箱格式校验手机号长度检查agent 开始干的时候发现表单组件用的是团队自封装的FormField它的 validator prop 只接受同步函数——但你的邮箱校验要调后端查重是异步的。Agent 怎么办它必须做一个你没预料到的决策。如果你没给它遇到偏差怎么处理的指令它可能默默把异步校验改成了 onBlur 回调绕过了 validator 框架。等你发现的时候表单的错误状态管理已经全乱了。Thariq 的应对很简单——让 agent 维护一个偏差日志工作时维护一个 implementation-notes.md。 遇到边缘情况必须偏离计划时选保守方案 把偏差记在 Deviations 部分继续推进。偏差日志的实际格式大概长这样## Deviations ### D1: FormField validator 不支持 async - 原计划在 validator prop 中做邮箱去重校验 - 实际情况FormField validator 只接受同步函数 - 采取方案保守选择把异步校验移到 form submit 时做 - 代价用户填完邮箱不能立即看到重复提示 - 标记需要确认这个 UX 降级是否可接受这个文件的两重价值当次可追溯你看到 agent 做了什么判断、为什么偏离、代价是什么下次可预防这些偏差就是你下个类似任务需要提前明确的 known unknowns还有一个 Thariq 原文里隐含但重要的实践规划完成后开新 session 做实现。把 spec、原型等产出物传入新 session让 agent 在干净上下文里工作。规划阶段积累的几千 token 对话不但占上下文窗口还会让模型在做实现决策时过度参考早期那些已经被推翻的讨论。实现后你真的理解了刚才发生的事吗很多人用 AI 编程的流程是prompt → agent 干活 → 跑通了 → 合并。但跑通了和我理解了之间有巨大的鸿沟。想象一下agent 帮你重构了一个支付模块改了 12 个文件测试全绿。你 review 了 diff觉得看起来没问题。三周后这个模块出了个 bug你 debug 的时候发现 agent 当时引入了一个你根本没注意到的状态机变化——某个 flag 的重置时机从 “支付成功后” 变成了 “页面卸载时”。你从 diff 里根本看不出这个语义变化因为代码层面只是把resetState()从一个回调移到了另一个回调。这就是为什么 Thariq 提出了两个实现后的手段。推介文档Pitch把 agent 的工作打包给人看代码写完不等于任务完成。如果需要团队审批你需要一份 Pitch——简单说就是这东西是什么、为什么这么做的推介简报把原型、spec、implementation notes 打包成一份文档。 demo GIF 放最前面让审阅者 3 秒内知道这东西干什么。 我要能直接发 Slack 拿 buy-in。为什么这很重要因为你的审阅者一开始和你有相同的未知数。推介文档帮他们跳过你已经走过的探索路径直接看到结论和证据。而你的 implementation notes 恰好是他们关心的你考虑过边界情况吗的答案。自测问答Quiz合并前的最后一关长 session 结束后AI 做的事情可能远超你的理解范围。只看 diff 只能看到表面变化看不到这些变化与已有代码路径的交互。Thariq 的做法是让 Claude 生成一组关于本次变更的测验题自己做对了才允许合并关于这次变更生成一份 HTML 报告 上下文、设计意图、关键行为路径、可能的副作用。 底部加 quiz我过了才能合并。“只有通过自测才合并”——看着苛刻但逻辑很硬你不理解的代码不应该进生产环境。Agent 可以帮你写代码但代码出问题时负责 debug 的还是你。一个反面教训下面是一个常见的错误用法——把自测问答换成了 AI 自评# 错误做法让 agent 自己判断代码质量 检查一下你写的代码有没有问题确认没问题后直接提 PR。这样做 agent 几乎永远会说没问题。正确的做法是把评估权留在人手里——你来答题你来判断。Agent 是执行者不是审批者。图 4三阶段方法论全景——从发现未知到验证理解的迭代循环实战选择表遇到情况查这里你现在的状态未知数类型该用的方法核心 Prompt 模板进入完全陌生的代码库/领域Unknown Unknowns盲区扫描帮我做 blind spot pass找出我的 unknown unknowns不知道好长什么样Unknown Knowns原型 头脑风暴做 N 种不同方向我看了告诉你哪个对大方向有了细节模糊Known Unknowns访谈追问一次一个问题采访我优先问改变架构的问题能认出好的但说不出来Unknown Knowns引用参考这个 [语言] 实现是我要的语义在 [目标] 复现准备动手最后对齐混合实现计划把我最可能要调的决策放最前面Agent 在实现中需要判断运行时 Unknown Unknowns偏差日志维护 notes偏离计划时选保守方案并记录做完了需要别人审批审阅者的 Unknowns推介文档Pitch打包成文档demo 放前面直接能发 Slack做完了确认自己理解你的 Unknown Unknowns自测问答Quiz生成报告 测验题通过才合并避坑指南过度指定 vs 过度模糊的平衡Thariq 原文有一段精确的表述“If you are too specific, Claude will follow your instructions even when a pivot may be more appropriate. If you are too vague, Claude will often make choices and assumptions based on industry best practices that may not be a fit for your task.”正确姿势明确意图和约束“我要什么”“不能碰什么”但不锁死执行路径“怎么实现由你判断”。比如与其写用 Redis 做缓存key 格式是 user:{id}:profileTTL 300秒不如写给用户 profile 查询加缓存要求读多写少场景、可接受 5 分钟延迟、不引入新的基础设施依赖。前者锁死了执行路径后者给了约束但保留了 agent 的决策空间。长 session 的上下文退化上下文窗口越长模型越倾向于保守——因为它要照顾前面所有的讨论和决策。规划和实现用不同 session只传产出物不传对话。Diff 视角的盲区Diff 展示变化不展示变化在系统中的涟漪效应。一个看起来无害的 3 行改动可能通过 5 层调用链影响到你完全没看到的逻辑。自测问答是成本最低的兜底手段。一个更贴近日常的例子前面讲的 Stripe 和 Fable 视频都是大团队/高端场景。来看一个更普通的情况假设你是一个三人创业团队的全栈开发要给产品加一个邀请码注册功能。你打开 Claude Code写了一段 prompt“给注册流程加邀请码验证无效码显示错误提示。”Agent 开始干活。20 分钟后你拿到了一个能跑的实现。但过了两天你发现邀请码验证是在前端做的——有人直接调 API 绕过了前端批量注册了 500 个账号。复盘一下你的未知数你的已知的已知需要邀请码验证无效码要报错你的已知的未知没有你觉得需求很简单你的未知的已知安全校验应该在后端做——这是常识但你没说agent 也没问你的未知的未知有人会用脚本批量调注册 API如果用本文的方法论盲区扫描让 agent 先看一下现有注册流程的安全层——它会告诉你当前没有 rate limiting没有后端校验层访谈追问agent 应该问你邀请码验证放前端还是后端是否需要防刷实现计划计划里会暴露安全校验层这个决策点三步加起来多花 5 分钟省掉后面 500 个垃圾账号的清理工作。完整案例Fable 发布视频的制作过程Thariq 在原文里分享了一个真实案例——Fable 5 的发布视频完全用 Claude Code 编辑。值得注意的是这个流程不是线性的起点识别知道 Claude 能用代码剪视频和做转录但不确定精度是否够用盲区扫描让 Claude 解释 Whisper 转录原理搞清楚能否精确剪掉嗯和长停顿原型验证用 Remotion 转录结果做了个原型测试同步字幕 UI 是否可行新未知数浮现视频画面偏灰意识到需要调色但不知道什么算好的调色退回学习没有急着让 Claude 出几个版本选一个——而是先让 Claude 教自己调色的基础知识因为如果连好长什么样都不知道选择就没有依据关键洞察步骤 4 发现了一个新的 unknown known“我不知道好的调色长什么样”于是退回到头脑风暴/原型阶段重新处理。整个流程是循环的不是线性的。总结一棵决策树开始一个 AI 编程任务 │ ├── 这个领域/代码区域我熟吗 │ └── 不熟 → 盲区扫描展开问题空间 │ ├── 我能说清楚好的标准吗 │ └── 说不清 → 原型/参考逼直觉表态 │ ├── 剩余的模糊点我能列出来吗 │ └── 列不全 → 让 AI 访谈我它来发现空白 │ ├── 准备动手 │ ├── 写实现计划暴露决策点 │ ├── 开新 session干净上下文 │ └── Agent 维护偏差日志 │ └── 做完了 ├── 自测问答确认自己理解 ├── 推介文档帮审阅者理解 └── 发现新未知→ 退回对应步骤这棵树的根节点观点AI 编程不是写更好的 prompt而是持续缩小你的地图与真实领土之间的差距。模型能力越强这个差距的投资回报越高。参考Thariq Shihipar, A Field Guide to Claude Fable 5: Finding Your Unknowns, Claude Blog, 2026-07-06Anthropic, Claude Fable 5 and Claude Mythos 5, 2026-06-09Alfred Korzybski,Science and Sanity, 1933概念解释见 Wikipedia Map–territory relationDonald Rumsfeld, DoD News Briefing, 2002-02-12另见 Wikipedia There are unknown unknownsRumsfeld 本人在回忆录Known and Unknown: A Memoir中提到该框架最早来自 NASA 主任 William GrahamResearchGate, The Knowns and Unknowns Framework for Design ThinkingSourcegraph, Agentic Coding in 2026: A Practical Guide for Big CodeLessWrong, The Map is Not the Territory