LLM 越强越不靠谱给 Agent 套一层不信任架构摘要模型越强Agent 反而越容易翻车——因为越聪明的模型你越容易信任、越不设防。旗舰模型照样会幻觉、算错、调错工具。与其逐个打补丁研究幻觉怎么治不如换视角假设 LLM 每一步都可能出错从架构层面设计让系统在不信任下依然运转。本质上只需要三个设计决策——输出当草稿、记忆做外面、外部信号做风险分级。本文用报销审批 Agent 的真实代码把这套架构摊开看。预计阅读时间5 分钟目录决策一把 LLM 的输出当草稿不当答案决策二不依赖 LLM记住而是把记忆做在它外面决策三不信任 LLM 的自评用外部信号做风险分级模型越强翻车往往越离谱。一个 7B 的小模型你会老老实实给它加校验、加护栏换成旗舰模型你下意识就觉得它应该不会错吧——结果幻觉、算错、调错工具照样来。问题不在模型不够强在于你太信任它。与其研究幻觉怎么治“遗忘怎么补”不如换一个视角从架构层面假设 LLM 在每一步都可能出错然后设计让系统在不信任下依然运转的结构。这不需要五个章节。本质上只需要三个设计决策。决策一把 LLM 的输出当草稿不当答案LLM 是概率生成器这意味着它输出的每一个字——无论是事实陈述、计算结果还是工具调用决策——都应该被当作未经证实的草稿必须经过验证才能对外交付。这不是对某个具体局限幻觉、算错的应对而是对 LLM 本质特性的统一回应。打个比方LLM 的输出就像流水线上的半成品必须过质检才能出厂。你不能因为包装看起来精美就直接上架。验证的方式取决于输出类型。事实性陈述用 RAG 检索结果做来源比对数值结果用代码重新计算做交叉校验工具调用决策用原生 function calling 的参数 schema 做约束而不是让模型自由输出 JSON 再手动解析。以一个报销审批 Agent 为例用户提交差旅费 3200 元Agent 需要核对公司制度中的住宿和交通标准。错误做法是让 LLM 直接判断是否符合标准——它会基于训练语料里的通用差旅常识给出一个看起来合理的判断但你公司的标准它根本不知道。正确做法是 LLM 只负责理解意图和提取结构化字段制度比对用规则引擎做。# LLM 只做这一步把自然语言变成结构化数据extractedllm_extract(差旅费3200元北京出差3天,schema{amount:float,city:str,days:int})# 制度比对用代码LLM 不参与compliancecheck_policy(extracted[amount],extracted[city],extracted[days])# LLM 再做最后一步把冷冰冰的规则结果翻译成用户能看懂的话replyllm_explain(compliance)这个模式——LLM 理解输入 → 代码做判断 → LLM 表达输出——是一个可以套到绝大多数 Agent 场景的通用骨架。它把 LLM 锁定在它擅长的语言理解和生成两端中间的事实判断和计算留给代码。原文里幻觉“计算错误”工具调用混乱三个独立章节的问题在这个骨架下被一次性消解。决策二不依赖 LLM记住而是把记忆做在它外面LLM 没有记忆只有注意力。每次生成时它对当前上下文中所有 token 重新分配注意力权重。所谓遗忘本质是关键信息在注意力竞争中被淹没或上下文超限后被截断。调大窗口不解决问题——研究已经证明即使 128k 窗口中间位置的信息召回率也会显著下降。所以不要指望把完整历史塞进上下文。应该把记忆做成 LLM 外部的独立组件每轮对话只注入精炼后的关键信息。比喻成给 LLM 配一个随身秘书它脑子记不住的所有事秘书都归档好需要时递到手边。具体三层结构结构化状态用户身份、偏好、当前任务进度用固定 schema 存储每轮以系统提示注入。滑动窗口原始对话历史只保留最近 3-4 轮保证即时连贯性。按需检索更早的信息向量化存储用户提及时检索召回而非常驻上下文。原文用手动提取地址和预算存字典来演示记忆但那只能处理可枚举的简单字段。真正的工程记忆要处理的是开放域信息——用户三周前提过的某个技术偏好、上次对话中遇到的某个坑——这些靠字典存不下必须靠向量检索。关键是记忆的可靠性不取决于 LLM取决于你在外部维护了什么。LLM 只负责读注入的信息不负责记。决策三不信任 LLM 的自评用外部信号做风险分级LLM 不知道自己不知道什么。它对确定知道和在猜的输出在文本语气上没有区别——都是一样自信。这是幻觉和工具误调用的共同根源也是最难工程化解决的一点。你无法让模型获得元认知但可以给它装一个外置仪表盘——司机不用知道自己有多困仪表盘超阈值就强制进服务区。最实用的信号有两个一是模型是否调用了它应该调用的工具。如果用户问今天汇率多少而模型直接回答了一个数字、没有触发汇率查询接口这本身就是一个强风险信号——意味着模型可能在用训练数据里的旧汇率。在 function calling 架构下这个检测很简单涉及实时数据的任务tool_calls为空就标记风险。二是 logprob对数概率。虽然不完美但生成 token 的平均 logprob 低于阈值时说明模型对这轮输出心里没底。把 logprob 和是否该调工具却没调组合成一个简单的风险评分超过阈值就触发人工复核或降级兜底而不是直接输出给用户。不需要复杂——两个信号做一个小规则就够了risk0ifinvolves_realtime_data(task)andnotresponse.tool_calls:risk2# 该查实时数据却没查高风险ifavg_logprob(response)-1.0:risk1# 模型自身不确定ifrisk2:route_to_human()# 转人工不输出这个思路的核心是你不需要让 LLM 变聪明你只需要在它犯大错之前拦住它。一个简单的该调用工具没调用 logprob 偏低的规则能拦截掉相当比例的高危输出。三个决策叠加起来就是给 Agent 套的那层不信任架构把 LLM 锁在它擅长的两端用代码和外部组件兜底中间的不确定性再用风险分级在它犯大错前拦住。这套架构不追求让 LLM 变聪明只追求让系统在 LLM 犯错时依然可靠——毕竟模型越强你越需要这层壳。