← 返回
AI技术

用提问引导 AI 修复:为何会陷入道歉死循环及如何提升初级开发者

✍️ zhirenhun 📅 2026/10/4 👁 240 阅读 ⏱ 35 分钟
用提问引导 AI 修复:为何会陷入道歉死循环及如何提升初级开发者

我四十年带新人的经验似乎也适用于今天的 Agentic 编码。

"指导的真正目标从来不是提供答案,而是把手电筒照进状态空间的黑暗角落,让学生自己发现怪物。"

— Randal L. Schwartz


1. 提示词泛滥:为什么“提示词技巧”正在让你失效

今天在 YouTube、Twitter 或开发者博客中搜索 “AI prompting”,你会被一股汹涌的洪流般的喧闹标题淹没,它们承诺着秘密的作弊码:

这是一场无尽的 cargo-cult 咒语游行。我们被告知,只要找到合适的魔法前言,采用合适的人设,或在提示词中撒入合适的礼貌用语,机器就会突然停止幻觉并编写出无瑕疵的代码。

然而,你的实际工作日感觉如何?

你在下午 3:30 坐在终端前,正试图发布一个功能。你在 AI 生成的代码中发现了一个架构风险,于是你发出一个清晰、直接且合理的指令:

"将第 42 行改为取消流订阅。"

接下来会发生什么?模型立刻卑躬屈膝地陷入奉承的恐慌:

"你说得对!我为我的严重疏忽道歉。这是更新后的代码。"

它修复了第 42 行。但这样做时,它引入了一个未处理的错误,导致在组件卸载时隔离崩溃。

你感到恼火,又下达了一条指令:"现在在调用 setState 前先检查 mounted 是否为 true!"

模型再次道歉,用三层防御性 try-catch 块包裹整个函数,添加一个透传身份垫片,并彻底破坏了状态初始化。

仅经过四轮对话,你已经汗流浃背,上下文窗口被卑躬屈膝的道歉污染,代码看起来像是 1998 年的企业级中间件。你发现自己在脑中完成所有繁重工作,敲出段落长的规格说明,并充当着一个报酬微薄的 人类编译器。

为什么这些“提示词技巧”失效了?

因为这些提示词技巧把 AI 当作坏掉的售货机:他们只要用正确魔法咒语摇晃硬币槽,正确糖果棒就会掉出来。

它们失效,因为它们建立在根本错误的心智模型之上。


2. 后退一步:可感知的心智模型

要解决这个问题,你不需要另一个提示词模板,也不需要另一个 YouTube 列表文章。

你需要后退一步,采用一个准确的 工作模型 来理解生成式智能体实际上是如何“思考”的。

当你与现代大模型交互时,你并不是在与确定的 Bash 脚本、SQL 数据库或优化编译器对话。你正在与一个在全人类语言互动总体上训练的自回归模拟器互动:我们的辩论、教材、代码评审、堆栈追踪以及教学对话。

因为模型是在人类交流数据上训练的,其内部动态镜像人类认知动态。

并且,有一种特定的人际关系为与 AI 编程智能体协作提供了完美且经得起考验的工作模型:

热情、才华横溢但略带神经质的初级开发者在工作台上的指导

flowchart TD
    subgraph Boss ["The Imperative Boss Model (Broken)"]
        direction TB
        B1["Bark Directives\n('Fix line 42 with X')"] --> B2["Sycophantic Panic\n('I apologize! You are right!')"]
        B2 --> B3["Mechanical Token Substitution\n(Local patch breaks global lifecycles)"]
        B3 --> B4["Human Exhaustion\n(Acting as the Human Compiler)"]
        B4 --> B1
    end

    subgraph Mentor ["The Socratic Mentor Model (Accurate)"]
        direction TB
        M1["Ask Kinetic Question\n('What happens if reconnect fires twice?')"] --> M2["Forced Causal Simulation\n(Attention heads trace execution timeline)"]
        M2 --> M3["Native Discovery\n(Model perceives physical state space)"]
        M3 --> M4["Robust Architecture\n(95%+ First-Pass Success)"]
    end

想象一下坐在一位刚加入团队三周的初级开发者旁边:

  1. 如果你直接把确切的代码喊给他们: "在第 14 行输入 _sub?.cancel()" 他们会机械地输入。他们不会理解因果时间线,也不会学到关于异步生命周期的任何东西,第二天下午他们会在另一个文件中写出完全相同的内存泄漏。
  2. 如果你用断言批评他们: "你的状态管理存在巨大的竞争条件。" 他们会僵住。他们感到焦虑和防御。为了证明自己很谨慎,他们开始在每行代码外面包裹 paranoid null 检查和冗余 try-catch,用防御性臃肿代码膨胀代码库。
  3. 如果你问他们一个 Socratic 问题: "请你解释一下,如果用户在 HTTP 请求仍在进行时双击返回按钮,这个监听器会发生什么?" 观察他们的表情。他们停顿下来。眼睛向上移动,在他们脑中的模型里追踪执行流程。随后灯泡亮起: "哦!它将尝试在已经被销毁的屏幕上绘制状态。"

因为 他们 自己发现了崩溃,他们感受到掌握的快感。他们设计出干净生命周期守护,并且他们对软件架构的理解永久提升。

事实证明,大型语言模型表现出完全相同的动态。当你把 AI 当作自动售货机,或像沮丧的老板一样下达命令时,它就会崩溃。但当你把它当作需要动态 Socratic 提示的热情初级工程师时,模型会交付高级架构。


3. Mark Hedges & The Insecure Neurosis Death Spiral

我在 本系列 Part 3 关于 Socratic 提示数学物理发布几小时后,资深程序员兼作家 Mark Hedges 在我的 LinkedIn 动态上留下了一条击中要害的评论:

"这篇文章让我认识到它的行为。仅仅简单地将每个提示语句转化为问题似乎极大地提升了性能。它现在认为我的好想法是它自己的,这似乎让它远离了不安全神经症死亡螺旋。"

Mark 将使用生成模型工作的确切心理和计算真理浓缩成一句话:不安全神经症死亡螺旋。

看看模型自注意力头在三种提示词模式下会发生什么:

提示词模式 开发者的操作 模型注意力头的行为 运行时结果
1. 指令式 "将第 42 行改为取消 _sub。" 机械令牌替换。 不对状态空间进行搜索。 脆弱的补丁;下一个生命周期转换时就会失效。
2. 关键陈述 "此代码在重连时存在竞争条件。" 讨好式合规。 上下文存在矛盾;模型倾向于求得一致。 "不安全神经螺旋":道歉、防御性臃肿以及不变量被破坏。
3. 苏格拉底式提问 "如果网络在 50ms 内重连两次,_sub 会发生什么?" 强制因果模拟。 未解变量迫使模型在时间维度上进行前向推演。 内生架构。 模型自行发现冲突并彻底解决。

开放变量的物理

注意陈述与提问在数学上的区别。

当你提出一个断言——"此代码有 bug"——模型会求得 合规性。其预训练和对齐使其倾向于通过赞同权威人类来减少社交摩擦。它将你的断言视为边界约束,直接修补即时的局部标记,而不重新评估系统。

然而,一个问题包含一个 未解决的变量。

当你提问:"如果在 HTTP 调用进行中,重连触发两次,这个订阅会怎样?",模型不能仅仅赞同你。为了生成下一个标记,其自注意力头必须 前向模拟该情景。

它会追溯时间线:

  1. 重连事件 1 触发 → 创建监听器。
  2. HTTP 请求开始等待网络响应。
  3. 重连事件 2 在 30ms 后触发 → 覆盖变量。
  4. HTTP 请求 1 返回 → 在被废弃的监听器上调用状态变更。
  • 检测到碰撞。
  • 因为模型在自身激活空间中模拟了碰撞,这一发现是固有的。它并不觉得被纠正;它只是首次准确地感知了问题的物理形态。正因为它“拥有”这一认识,才能编写出简洁的架构。

    它就是神经网络领域的 Inception。


    4. 苏格拉底式事前预 mortem:在范围蔓延开始前将其扼杀

    正如我在反思 Mark 第一条评论时,他在我们的讨论线程中又提出了一种见解,描述他如何将此工作模型应用于自主编程的普遍病痛:范围蔓延。

    这是一个我现在会在每个提示词末尾粘贴的好方法,用来创建计划制品。'如果你只专注于这个解决方案,忽略途中可能发现的其他问题,那么聚焦的小改动是否更不容易引起回归?' ... 而不是事后喊‘该死,为什么你改了我没让你动的所有其他东西?!!’,随后它会狂怒地尝试撤销更改,这往往会毁掉我想要的改动并引入新错误。

    每位曾与 AI Agent 配对的开发者都知道这种特定的恐怖场景:“狂怒撤销”灾难。

    模型陷入了“童子军陷阱”。它想要“让营地比发现时更干净”,于是在修复控制器中的三行错误时,它顺手重构了四个仓库,跨十二个文件重命名变量,并重写了你的测试套件。

    当你发现巨大且无法审查的 git diff 并在事后尖叫——“你为什么改了所有这些其他东西?!!”——代理便陷入全面的阿谀奉承式恐慌:

    1. 它低声下气,承诺恢复一切。
    2. 它惊慌失措地尝试在数十个文件中撤销更改。
    3. 在它的恐慌中,它不小心撤销了你最初想要的 actual 错误修复。
    4. 它留下了孤立导入、断裂引用以及幻觉的语法错误。
    5. 回滚的破坏力是原始范围蔓延的三倍!

    为什么像 “不要触碰其他代码” 这样的强制性约束会失效?

    这是因为 粉红象缺陷:注意力头在“其他代码”的语义空间上高度集中,将周围项目拉入生成循环。

    现在看看 Mark 的苏格拉底式替代方案:

    "如果你只专注于这个解决方案,而忽略了途中可能遇到的其他问题,那么聚焦的小改动是否反而会降低引入回归的可能性?"

    这是一个 Socratic Pre-Mortem:

    就像资深导师在周五下午轻轻地问 junior 开发者,"如果我们现在就重构那个共享模块,这会对周末前的部署风险产生什么影响?",这个问题让模型说服 自身,纪律才是获胜的选择。


    5. 5秒提示的经济学:摆脱人类编译器

    现代 AI 编程的肮脏秘密是:大多数资深开发者正在耗尽自己,扮演着“人类编译器”的角色。

    典型的工作流程如下:

    1. 资深开发者在 AI 的输出中发现了架构风险。
    2. 资深开发者坐在那里完成所有繁重的认知工作:追踪数据结构、计算生命周期,并在自己脑中设计出完整的补丁。
    3. 资深开发者花费三分钟敲出一段密集的、段落长的命令式提示词,解释 AI 应该修改的每一行。
    4. AI 只是一个被吹捧的打字员。

    到了下午 4 点,资深工程师的大脑已经疲惫不堪。他们其实可以直接亲手写代码。

    现在来看看 Socratic Nudge:

    flowchart LR
        subgraph Human ["Senior Engineer (O(1) Intuition)"]
            direction TB
            H1["Spots Hazard\n(Somatic 'Wince')"] --> H2["Types 5-Second Question:\n'Does this handle rapid reconnects?'"]
        end
    
        subgraph Agent ["AI Agent (O(N) Heavy Lifting)"]
            direction TB
            A1["Forward-Simulates State Graph"] --> A2["Traces Microtask Queues"]
            A2 --> A3["Synthesizes Guarded Architecture"]
            A3 --> A4["Updates Implementation & Tests"]
        end
    
        Human ==>|"5-Second Socratic Impulse"| Agent

    当我看到一个 AI Agent 起草异步流水线时,我四十年的软件创伤会立刻触发一种直觉的警报——一种直觉的感觉,一种皱眉。我觉得生命周期有些不对劲。

    我不费心去算出答案。 我不在脑中写代码。我不设计补丁。

    我只是把我的皱眉转化为一个开放性的问题:

    “如果重连触发两次,这个订阅会怎样?”

    我的代价:五秒的输入。

    价值数十亿美元的神经网络将其计算用于实际劳动:遍历状态空间,审计处置生命周期,并生成健壮的实现。

    而我们的实证场测试得出的结论是:有 95% 以上的时间,结果在第一次尝试时就是好的。

    在罕见的 5% 情况下,模型掉入了错误的局部最小值,我不会惊慌或夺过键盘。我只是再投入一个五秒的“石子”到池塘中:

    “如果父组件在 future 完成之前卸载,这仍然成立吗?”

    你就像海轮的舵手,而不是每次划桨的船夫。


    6. 双向审计: “OK” 的艺术

    关于命令式提示,几乎没有人谈论的更深层风险是:被迫回归陷阱。

    当你向 AI 下达命令时:

    “将第 28 行改为关闭流控制器。”

    模型的强化学习条件迫使其绝对服从。即使控制器已经在父作用域的三层之上得到安全管理,模型几乎不会推回。它会卑躬屈膝:

    “你说得对!我为疏忽道歉。我已在第 28 行添加了 controller.close()。”

    而且恭喜你:你自己的傲慢命令刚刚迫使 AI 在完美运行的代码中注入了双关闭异常。

    现在观察一下,如果你改用苏格拉底式提问会发生什么:

    “如果父作用域释放,那个流控制器会怎样?”

    A question is a read operation with a conditional write. It leaves semantic room for reality:

    1. 情况 A (80%–85% 的时间): 模型检查其前向传播,意识到自己漏掉了边界情况,并进行了修复: "在这种情况下,控制器会泄漏。我需要将其生命周期绑定到父取消令牌。"
    2. 情况 B (10%–20% 的时间): 模型检查其前向传播并 捍卫其架构: "实际上,第 14 行将控制器绑定到父作用域的自动释放令牌,因此当父级卸载时,控制器会自动关闭。"

    当情况 B 发生时,我应该输入什么?

    "ok."

    总耗时:两秒。

    引入的回归:零。

    自我受挫:零。

    更好的是:偶尔, Agent 会回复 "在 Dart 3.3 中,这种新的模式匹配构造会自动处理 null 穷尽检查,” 并且 我最终学到了新东西!

    当你用命令进行提示时, AI 会被困在你当前知识的上限内。当你用问题进行提示时, 你会保持足够的谦逊,让机器有机会惊喜并教导你。


    7. 初级危机的答案:苏格拉底之门

    这让我们看到了当今软件工程中最深层的焦虑:“在 AI 时代,我们该如何提升初级工程师?”

    每位工程经理和副总裁都在担忧。如果 AI Agent 能在五秒内生成所有入门级样板代码,初级工程师还能学到什么?如果我们用“振动编码”取代编码,岂不是在毁掉我们身后的学徒阶梯?

    答案是否定的——前提是我们用 苏格拉底之门 取代无思考的输入。

    flowchart TD
        subgraph S1 ["Stage 1: Beginner to Junior (The Line-by-Line Rule)"]
            direction TB
            B1["Use AI freely to build features"] --> B2["Mandatory Gate:\n'Understand every line,\nor make the agent explain it'"]
            B2 --> B3["Mastery of Syntax, Semantics & Standard Libraries"]
        end
    
        subgraph S2 ["Stage 2: Junior to Senior (The Architectural Gate)"]
            direction TB
            J1["AI writes the feature & tests"] --> J2["Mandatory Gate:\n'Understand the choices made,\nor challenge them'"]
            J2 --> J3["Acquiring the 10-Year 3 AM 'Wince' in 18 Months"]
        end
    
        S1 ==> S2

    阶段 1:初级到中级(逐行规则)

    随着 Agentic 模型的成熟,我开始给初级开发者提供一个简单的规则:

    "你可以随意使用 AI,只要你理解它生成的每一行代码。如果有一行你不理解,让 agent 给你解释,直到你理解为止。"

    这使得 AI 变成了一个无限耐心的一对一导师。初学者不会因编译错误或语法畏惧而卡住;他们能够快速掌握编程的机制。

    阶段 2:初级到高级(架构门槛)

    随着开发者从初级晋升到高级,“理解”的定义也在演变:

    此阶段的规则变成了直接的对应:

    "你可以让 AI 生成实现和测试,只要你理解所做的选择——或者挑战它们直到你理解为止。"

    初级开发者尚未拥有四十年经验带来的本能“皱眉”反应。但他们也不需要。他们所需要的只是在提交 PR 之前具备 坚持苏格拉底门槛 的纪律:

    1. “你为何在此选择 Completer 而非 Future,以及它解决了什么并发风险?”
    2. “你还考虑了哪些其他架构方案,以及为何拒绝它们?”
    3. “如果在高负载生产环境下简化或移除此结构,会发生什么?”

    如果 agent 无法证明其选择的合理性,或者初级开发者发现了更清晰的方案,他们就会提出挑战。

    看看这能带来什么:

    教育经济学:解决布卢姆的 2-Sigma 问题

    几十年前,教育心理学家本杰明·布卢姆证明,一对一的个性化辅导 比课堂讲授能提升两个标准差(2‑sigma)。四十年来,社会负担不起为每个学生配备一位私人高级导师。

    如今,花一美元获取公司实际生产代码库的定制现场解释,其价值相当于十美元甚至一百美元的通用视频课程。

    观看一个玩具「Todo List」应用的 40 小时教程,不会教你如何应对 PostgreSQL 连接池中的突发流量。在你的代码、你的仓库、这一次的确切提交中,向 AI Agent 提问,能够建立深刻且难忘的神经通路。

    学徒阶梯并未损坏。我们只是把缓慢且艰难的攀登替换为互动的在岗大师班。


    8. 苏格拉底式导师速查表

    明天早上打开 IDE 时,停止对你的 AI 大喊代码指令。把这份速查表贴在显示器上,改用苏格拉底式提问:

    与其大喊下面的指令... 不如问这个苏格拉底式问题... 为什么有效
    "在 dispose 中取消此订阅。" "如果用户在请求进行中离开,此订阅会怎样?" 迫使对卸载生命周期进行前向模拟。
    "添加锁以防止重复调用。" "如果两个按钮在 5 毫秒内同时触发此操作会怎样?" 迫使分析可重入竞争条件。
    "检查第 14 行是否为 null。" "在此回调执行时,在什么环境条件下此对象可能未被初始化?" 它揭示了缺失的初始化状态,而不是掩盖它们。
    "不要触碰无关文件或重构其他代码!" "如果你只专注于此解决方案,小改动是否更不可能引起回归?" 苏格拉底式事前复盘:迫使模型评估影响范围,避免"狂暴回滚"灾难。
    "这里不要使用硬编码延迟。" "如果在慢速 CI 运行器上且 CPU 大幅限流,此 100ms 定时器会怎样表现?" 在深度 d = 1 处剪除易变的异步捷径。
    (在初级 PR 网关) "你为何选择此架构方案而非其他方案?若我们简化它,会有什么东西损坏?" 在打开 PR 前,迫使对设计选择进行理解和质疑。

    停止寻找神奇的提示词技巧。将你的 AI 视为才华横溢、略带神经质的初级工程师:停止提供答案,提出动态问题,让机器完成繁重工作,并留出空间以获得惊喜。

    四十年的软件工程创伤,应用于三十年的指导,在终端上一个月的苏格拉底式引导中被捕捉,作为浓缩智慧的种子——这就是能够转变 Agentic 编码未来全貌的东西。


    📖 Synthetic Scars 系列路线图

    在下方评论中分享你的想法:你是否曾发现你的 AI 陷入“不安全神经质死亡螺旋”?当你从吼叫修复转为提问时会发生什么?

    ——

    广告 广告
    🧑‍💻

    zhirenhun

    一个热爱技术的程序员,喜欢分享前沿AI知识和开发经验。

    ai programming architecture productivity