content/07-faq/why-ai-first-answer-not-optimal.md

为什么 AI 第一次给的常常不是最佳方案,追问一句才给出更好的?

你让 AI 给个方案,它给了,看着也合理;你随口追一句「这是最佳方案吗,还有没有更可靠的?」——它立刻掏出一个明显更好的。

于是你困惑:既然它想得出更好的,为什么第一次不直接给?是不是在偷懒? 这不是偷懒,是大模型的一个结构性特性。本文把它讲透:① 一个真实例子 → ② 这在 AI 领域叫什么 → ③ 通用解法 → ④ 你那句追问其实是什么 → ⑤ 怎么更省力。


一、先看一个真实例子(已脱敏)

某个 Spring AI 项目里出了个 bug:AI Chat 的 5 个文件工具(读文件 / 写文件 / 列目录 / 改文件 …)突然全部报「工具执行失败」,但普通业务工具(比如建工单)一切正常。

排查链路一路挖到底,根因是这样的:

  • 文件工具不是直接在主进程里跑,而是丢进一个 Docker 沙箱容器里执行,容器名固定为 agent-sandbox-<租户>
  • 上一次服务进程退出时,留下了一个半死容器(建出来了但从没正常起来),一直占着 agent-sandbox-<租户> 这个名字。
  • 新进程每次 docker run --name agent-sandbox-<租户> 都和这个残骸撞名(Docker 报 exit 125: name already in use)→ 容器起不来 → 5 个文件工具全军覆没。
  • 而沙箱管理器没有自愈逻辑(代码注释里作者自己都写了「死容器清理、野容器扫描还没做」),于是这个残骸永久占名,怎么重试都失败,直到人工 docker rm -f

根因坐实后,问「怎么修」。AI 第一次给的方案是 A + B

  • A. 启动时全量清场:服务一启动,扫一遍所有带标签的沙箱容器,docker rm -f 全删掉再对外服务。
  • B. 撞名就重试docker run 收到 exit 125(名字被占)时,先 docker rm -f 掉那个名字,再重跑一次。

看着挺合理,也确实能解决问题。但追问一句「review 下,是不是最佳方案,还有没有更可靠的?」之后,AI 给出了明显更好的 **reconcile(状态对账)**方案:

建容器之前,先 docker inspect 看一眼这个名字的现状,再分支处理:

  • 不存在 → 正常 docker run
  • 活着、且镜像匹配 → 直接复用(连重启后还在跑的「暖容器」都能接管,省冷启动)
  • 死的 / 退出的 / 镜像不符 → 删掉再重建

配套:docker run 失败时顺手自清残骸;启动时只扫「非运行」的孤儿容器(不碰还活着的);撞名重试只当最后兜底。

对比一下就知道第二个为什么更好:

第一次的 A+Breconcile
处理方式撞了墙再补救(反应式)建之前先对账(主动式)
会不会误杀活容器B 的 rm -f 分不清死活,可能把另一个进程正在用的容器干掉只清死的,永不杀活的
靠不靠字符串匹配要 grep exit 125 的错误文案,脆按状态分支,不依赖报错文案
顺带好处无;A 还会在重启时把暖容器一起删 → 必冷启能复用暖容器,重启后第一个请求不冷启

注意 reconcile 不是什么高深东西——它就是 Kubernetes「对账到期望状态」的同一个思路。AI 完全想得到,只是第一次没去想。


二、这在 AI 领域叫什么问题

核心是一个词:满足即止(Satisficing)——只找「够好、能用」就停手,不去找「最优」。这是 Herbert Simon 的「有限理性」,放到大模型上格外贴切,因为模型本质是一路顺着概率最高的下一个词往下写,天然倾向于给「最典型、最顺手」的答案,而不是「最好」的。

它是几个更具体的毛病叠加出来的:

学名通俗说在上面例子里的体现
System 1 vs System 2(Kahneman)直觉快答 vs 慢想细比用了快答(直接补报错),没切到慢想(重设计生命周期)
锚定偏置 Anchoring被现成的框框带着走照着代码注释里作者列的「待办」去补,没跳出原作者的思路
生成 ≠ 选择,却挤在一起自己出题、自己拍板,一气呵成同一口气「列出 A/B/C 并选了 A+B」,没单独做一轮筛选
推理算力没花够(test-time compute)没多「想」几步就交卷第一个能跑的方案出现就停了

一句话归因:AI 交付的是「眼前这个报错,第一个能摁灭它的补丁」,而不是「退一步重新设计、让这类问题压根不发生」的方案。退这一步很便宜、它也做得到,但不会自动发生——得有人推一把。


三、通用解法是什么

学术界对付「满足即止」的招,几乎都是同一个思路:别信第一稿,强行多走一步「审查 + 重搜」。常见的有:

  • Self-Refine / Reflexion:生成 → 自己挑刺 → 改。即「写完先自我批判一遍再交」。
  • Self-Consistency / Best-of-N:对同一问题采样多个答案,再投票或挑最好的那个。
  • Tree of Thoughts:把多个候选当树枝铺开搜索,而不是一条道走到黑。
  • Generator–Critic / Debate(多智能体辩论):一个负责出方案,另一个专门唱反调,逼出更优解。
  • LLM-as-Judge:用一个「裁判」按固定标尺给候选打分再选。

把它们串起来就一句话:把「生成」和「审查」拆成两个角色,让审查去逼问生成。


四、你那句追问,其实是什么

回到例子——让方案从 A+B 升级到 reconcile 的,就是那句:

「review 下,是不是最佳方案,是否还有更可靠的?」

这在术语上正好是 Reflexion / Generator–Critic 循环里的那个 Critic(批判者)。你从外部手动触发了「自我批判 + 重新搜索」这一步,相当于亲自当了裁判,把 AI 从 System 1 逼到了 System 2。你做的事,本质和「Best-of-N + 验证器」是同构的,只是验证器是你这个人。

这招很有效,但代价是:得靠你每次都记得追问。 你其实是在用人肉补一个本该自动化的流程步骤。


五、有没有更省力的方式

有,按「省力程度」三档,从轻到重:

① 一个固定触发词(最轻,按需用) 不用每次写长句,约定一个口令——比如以后只要打 「最优解」「列否决项」,AI 就自动跑「跨范式发 3 个候选 + 自我挑刺 + 打分 + 说明为什么否决其它」。零长期负担,但要你记得打。

② 写进 CLAUDE.md / 长期记忆,让它自动做(最省力,长期推荐) 存一条常驻规则:

核心 / 难回退的设计决策,交付前强制发散 ≥3 个跨范式候选并自我批判,再给推荐。

关键是配一个闸门——只对「重要 + 难改」的事触发,琐事不触发,免得啥都开方案评审会。这样你一个字都不用打,AI 自己就走这一步。

③ 交给专门的审查代理 / 子智能体(团队/框架级) 很多 Agent 框架都内置「Critic / Reviewer 子代理」或「共识规划」流程,干的就是「让第二个人挑刺」。重要决策出完初稿甩给它,等于把你那句「review 下」固化进流水线,不靠人记。

什么时候才值得这么较真? 一个判据:事情越核心、越难回退,越要走这一步。 影响一整套系统的生命周期设计、选型、架构——必须走;改个错别字、写个一次性脚本——不必,否则反而磨叽。把这个「度」拿捏好,本身就是手艺。


一句话结论

AI 第一次给的常常是「够用解」而非「最优解」,因为它默认走 System 1 的快答、容易被现成框架锚定、还把「生成」和「筛选」挤进了同一口气。通用解法是 Self-Refine / Generator–Critic——让「审查」作为独立一步去逼问「生成」。你那句「是不是最佳方案」就是人肉版的 Critic;想更省力,就把它写成一条「重要决策才触发」的常驻规则,让 AI 自己多走那一步,而不是每次等你追问。


相关内容

评论