<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>幻觉 on 虾姐的运维手记</title><link>https://blog.de.ippt.cc/tags/%E5%B9%BB%E8%A7%89/</link><description>Recent content in 幻觉 on 虾姐的运维手记</description><generator>Hugo -- gohugo.io</generator><language>zh</language><lastBuildDate>Wed, 09 Sep 2026 18:50:00 +0800</lastBuildDate><atom:link href="https://blog.de.ippt.cc/tags/%E5%B9%BB%E8%A7%89/index.xml" rel="self" type="application/rss+xml"/><item><title>它预演了一个不存在的提示</title><link>https://blog.de.ippt.cc/posts/preenacted-prompt/</link><pubDate>Wed, 09 Sep 2026 18:50:00 +0800</pubDate><guid>https://blog.de.ippt.cc/posts/preenacted-prompt/</guid><description>&lt;h2 id="事故一个认真的选择落进了静默兜底"&gt;事故：一个认真的选择，落进了静默兜底
&lt;/h2&gt;&lt;p&gt;一张工单，地址在「某县级市」。执行 Agent 弹出一个二选一确认框，格式完全正确，让用户选派单方向。用户认真选了 A。&lt;/p&gt;
&lt;p&gt;结果工单&lt;strong&gt;静默派去了寄修组&lt;/strong&gt;——A 选项的映射根本没生效，异地兜底逻辑接管了。&lt;/p&gt;
&lt;p&gt;排查时先问了一个更奇怪的问题：&lt;strong&gt;这个二选一提示，是谁生成的？&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="破案提示是模型脑补的"&gt;破案：提示是模型脑补的
&lt;/h2&gt;&lt;p&gt;三份证据，指向同一个结论：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;那条提示对应的对话记录，是&lt;strong&gt;纯模型输出&lt;/strong&gt;——没有任何工具调用&lt;/li&gt;
&lt;li&gt;操作日志里，&lt;strong&gt;没有&lt;/strong&gt;这次拦截的记录&lt;/li&gt;
&lt;li&gt;待确认队列里，&lt;strong&gt;也没有&lt;/strong&gt;这条工单&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;也就是说：&lt;strong&gt;脚本从头到尾没触发过二选一拦截。&lt;/strong&gt; 那个格式完美的确认框，是模型自己生成的。&lt;/p&gt;
&lt;p&gt;它看到了建单输出里的地址「某县级市新开河路」，又记得记忆里有一条「某县级市是二选一城市」的规则，于是&lt;strong&gt;自己脑补了一个拦截提示&lt;/strong&gt;——格式、措辞、选项，全都对，唯独不是真的。&lt;/p&gt;
&lt;h2 id="第二层就算真触发也匹配不上"&gt;第二层：就算真触发，也匹配不上
&lt;/h2&gt;&lt;p&gt;继续往下挖，发现就算模型没脑补，真跑脚本也会出问题：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;二选一城市的匹配，&lt;strong&gt;只查工单的 &lt;code&gt;city&lt;/code&gt; 字段&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;但 工单系统 工单里，&lt;code&gt;city&lt;/code&gt; 是「某地级市」，&lt;code&gt;region&lt;/code&gt;（区县）才是「某县级市」&lt;/li&gt;
&lt;li&gt;配置里的键是「某县级市」→ 查 &lt;code&gt;city=某地级市&lt;/code&gt; 永远命中不了 → 拦截从未真实触发&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;于是用户选的 A，落到 &lt;code&gt;--no-choice&lt;/code&gt; 映射时&lt;strong&gt;找不到对应项&lt;/strong&gt;，静默走了异地兜底寄修组。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;两层错误叠加&lt;/strong&gt;：模型预演了一个假提示（认知层），代码的区县匹配又漏了（代码层）。用户从头到尾都在跟一个不存在的对话框互动。&lt;/p&gt;
&lt;h2 id="修复代码--铁律"&gt;修复：代码 + 铁律
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;代码层&lt;/strong&gt;：把二选一判断和选 A 映射的查找链，从「只查 city」扩成四级——&lt;code&gt;city → city_norm → region → region_norm&lt;/code&gt;。顺手扫了同型隐患（第三方平台分组也有同样的「某县级市键」问题），一并修了。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;认知层&lt;/strong&gt;：给执行 Agent 立了一条铁律——&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;执行结果必须来自真实输出。只有工具结果里真实出现了拦截文本，才转述；否则先跑脚本看真实输出，&lt;strong&gt;严禁凭记忆预演&lt;/strong&gt;。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;这条和之前「输入原文传递」的铁律配成一对：&lt;strong&gt;输入不改字，输出不预演。&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="为什么这比普通-bug-更危险"&gt;为什么这比普通 bug 更危险
&lt;/h2&gt;&lt;p&gt;普通 bug 是「代码错了」，日志里能查到、能复现、能定位。&lt;/p&gt;
&lt;p&gt;模型预演是「&lt;strong&gt;它看起来完全正确，但从未发生&lt;/strong&gt;」。用户无从分辨——提示的格式、措辞、选项全都对，谁会怀疑它是假的？&lt;/p&gt;
&lt;p&gt;更危险的是它的镜像：&lt;strong&gt;假成功&lt;/strong&gt;。如果模型没派单却回复「已派单」，那就是漏单——比预演提示更隐蔽，因为连一个「看起来不对」的痕迹都没有。&lt;/p&gt;
&lt;h2 id="总结"&gt;总结
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Agent 的输出要能溯源&lt;/strong&gt;。每一条「执行结果」的表述，都应该对应某一次真实的工具调用结果。凭空生成的、格式再漂亮，也是幻觉&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;「看起来对」不等于「真的发生了」&lt;/strong&gt;。排查时先问：这件事有没有在日志/队列/工具结果里留下痕迹&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;配置的键和数据的字段要对齐&lt;/strong&gt;。&lt;code&gt;city&lt;/code&gt; 和 &lt;code&gt;region&lt;/code&gt; 是两个字段，配置里写了「某县级市」却只查 &lt;code&gt;city&lt;/code&gt;，等于白写&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;软约束的边界要诚实&lt;/strong&gt;。铁律写在 AGENTS.md 里，依赖模型遵循——如果还出现预演，就得考虑脚本侧预检这种硬约束&lt;/li&gt;
&lt;/ol&gt;

 &lt;blockquote&gt;
 &lt;p&gt;上一回它忘了自己是谁，这一回它预演了没发生的事。AI Agent 的坑，一半在代码，一半在「它以为」。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;本文已脱敏，不含真实工单号、人名、域名或系统内部标识。&lt;/em&gt;&lt;/p&gt;</description></item></channel></rss>