一次印象很深的调试经历。我让一个基于大模型写的智能体去批量整理项目文档,任务拆得不复杂:读取 PDF、提取关键信息、按模板输出。刚开始一切正常,跑到第 23 个文件时,它突然停住,反复调用同一个接口,每次都返回同一个错误。日志显示它根本没有读懂返回信息里的“参数缺失”,而是继续按自己的理解补了一个不存在的字段。那一刻我意识到:不是模型“笨”,而是它缺少一种能力——它不知道自己看到的返回结果意味着什么,也不知道自己已经陷入循环。
这就是生成式 AI 和智能体 AI 在真实项目中反复出现的问题。我们习惯把这类现象笼统称为“幻觉”“不稳定”“Token 浪费”,但如果只停留在这些模糊词上,很难真正改进系统。更值得做的,是给它们建立一套分类:认知能力缺口。简单说,就是模型在感知、记忆、推理、执行和自我监测这些认知环节上,出现了能力不足。它不一定需要你换一个更大的模型,它需要你准确判断缺口到底发生在哪一层。
1. 认知能力缺口:为什么现在必须认真对待
先看一个容易被忽略的变化。生成式 AI 擅长“一段话”。当任务是一个 Prompt 换一次输出,模型表现通常不错,因为你可以立刻检查结果,错了就重新生成。但智能体 AI 把任务拉长了:一次任务变成多条工具调用、多轮状态更新、长期目标跟踪。这时候,错误的传播方式完全不同。
一个不正确的中间判断,会被下一个步骤当作事实继续处理。模型在第一步读错了一个字段,第二步就会基于这个字段做计算,第三步可能会把错误结果写进报告。等到人工发现问题时,已经不可追溯了。所以在智能体场景里,“输出质量”不再是唯一指标,过程可靠性才是关键。
过去我们在评估模型时,更关注单轮输出质量,比如相关性和流畅度。但在智能体场景中,这些指标远远不够。我们更要关注过程中有没有出现认知能力缺口,因为它决定了系统的失控点在哪里。例如,如果 Agent 不知道自己的工具调用参数不对,它就会用错误路径继续执行。这种问题的危害远大于“生成语句不通顺”。
那为什么需要一个“分类法”?
因为不同缺口对应的干预手段完全不同。模型缺少某个领域的知识,你可能需要检索增强或者外部知识库;模型长期目标保持不住,你可能需要任务规划器和检查点;模型调用工具老是出错,你可能需要工具层的参数校验,而不是在提示词里反复强调。分类法不是为了给问题贴标签,而是为了降低团队沟通成本,让每次失败都可以用同一种语言描述。
没有分类的时候,团队容易陷入一种很常见的争论:一个人说“模型能力不行”,另一个人说“提示词没写好”,还有一个人说“框架不支持”。最后往往变成了换模型、换框架、写更长的提示词。三件事都做了一遍,问题还在。原因就是没有定位根因在哪一层。
所以我更建议把认知能力缺口拆成几类,每条故障先回答一个基础问题:问题出在模型没看见、不知道、想错、做错,还是不知道自己做错了?这样至少可以把排查方向收敛住。
2. 把缺口拆成五类:一套可操作的分类框架
下面这套框架是我在实践里常用的,也是比较贴近任务执行链路的一种拆法。任务进入系统后,先感知输入,再调用知识,再做规划,再执行工具,最后自我检测。这五个环节都会出现缺口,分类方式就按这条链路来。
2.1 感知与输入缺口
认知活动通常从感知开始,AI 也不例外。对模型来说,感知就是“它到底读到了什么”。这类缺口最隐蔽,因为错误往往不在生成结果里,而在输入状态。
典型场景有几种:上下文窗口把长文档截断了,模型不知道;用户给的 PDF 是扫描件,转文字后乱码,模型把乱码当成正文分析;多轮对话中,历史消息被压缩,关键约束丢掉了;工具返回的结果里包含编码问题,模型没有识别出来,继续做了加工。
判断线索也很直接:你把同样的问题换成完整、无噪声的输入,模型立刻能答对,那问题大概率出在感知层。
在工程上,这类缺口不能靠模型自己解决。模型不会主动问“你那段话里是不是少了个负数”,它只会顺着残缺的信息往下走。所以输入层需要做校验、结构化抽取、关键信息标记,甚至要在必要时主动告诉模型“这一段可信度低,不要作为推理依据”。
2.2 知识边界缺口
知识边界缺口是目前讨论最多的一类,因为它直接表现为幻觉。模型看似在输出一个事实,其实是在编造。这类缺口和记忆有关:模型知道训练数据里的知识,但不知道实时信息、私有领域知识,也不知道自己不知道。
举例来说,你问一个没有接入知识库的模型最新的系统版本号,它会一本正经地给出一个听起来合理的版本号,但那是编的。这就是模型没有实时知识,同时缺少“我不知道”的能力。
这是最容易被误判的一类问题。很多人以为是提示词不够强,就反复加“请基于事实回答”,但模型本身就没有这个事实,再强调也没有用。更合理的干预手段是引入外部知识:RAG、知识库、搜索引擎接口,或者限制模型在不确定时直接声明“无法确认”。
知识边界缺口还有一个特点:当模型被要求回答训练数据之外的内容时,它的信心和准确性不相关。也就是说,它可能很自信地说错。所以在应用中,只要任务依赖事实和私有数据,就应该默认开启检索增强或者引用机制,而不是默认模型全知。
2.3 推理与规划缺口
推理与规划缺口,指的是模型有足够的知识和输入,但步骤本身出了问题。
比如任务需要“把调研结果整理成报告并发送给指定邮箱”,模型可能前面做得不错,却在最后一步忘了指定邮箱,直接输出一个报告文件。另一种常见情况是任务分解不合理:让它做数据分析,它先花大量时间优化图表,却跳过了关键的数据校验。
很多智能体项目都有这个痛点:单步能力看起来很好,但一旦任务长起来,目标保持不住。模型会在某个中间步骤被局部的信息带走,忘记原始目标。
这类缺口的判断线索是:把任务拆成手动步骤,让模型每一步都输出当前子目标,再看它是否偏离。如果它能理解每一步但整体目标丢失,那基本就是规划缺口。
干预方式可以从流程入手:给任务加模板,规定第二步必须做什么,第三步必须做什么;或者引入规划器,让模型先生成计划,再按计划执行;还可以在关键节点设置人工确认,防止目标漂移滚雪球。
2.4 执行与工具调用缺口
智能体 AI 和外部环境打交道时,最容易出问题的地方就是工具调用。这类缺口不是模型不知道该调用哪个工具,而是调用参数不对、返回结果没处理、外部状态不同步、重试逻辑有问题。
一个很典型的场景:Agent 调用 API 时漏掉了必填字段,其实工具已经返回了“参数缺失”的明确报错,但模型没有解析这个结构化的错误信息,而是继续往输出里填猜测值。另一个场景是工具返回成功,但是结果是一个空值,模型没做判空,继续用空值计算。
判断执行缺口最好的方式是看日志:记录模型每次的工具参数、工具返回、模型的下一个动作。如果参数和返回都清晰,但模型还是错误理解,那问题就可能出现在描述方式上;如果参数本身就不对,那就需要在工具层加约束。
这里的核心原则是:不要在提示词层硬扛工具层的问题。模型看到工具描述时,本身就是模糊的。你更应该把工具描述写成严格的 schema,并在代码里做参数校验,返回结构也尽量类型化,让模型不需要“猜”。比如把返回结果统一成{status, data, message},会让很多解析错误直接消失。
2.5 自我监测与恢复缺口
最后一类缺口,也是我认为最值得关注的:模型无法判断自己的输出是否可靠,不会纠正错误,也不善于停止。
自我监测能力弱的表现很多。模型执行一段代码后报错,它没有检查报错原因,而是用同样的代码再执行一次,直到达到重试上限。更麻烦的是,它产生一个幻觉,然后基于这个幻觉继续做后续推理,每一步看起来都合理,结果却越走越偏。
这和前面的缺口有本质区别。前面是“做错了”,这一类是“做错了但不知道错了”,或者“知道报错了但不知道该怎么换方向”。
判断它也很容易:你在错误后给模型一个明确的反馈,问它“你知道哪里错了吗”,如果它不承认错,或者重复同样的行为,就说明自我监测能力不足。
这类缺口很难靠模型自身完全解决,因为模型对自身的评价通常不准确。工程上更可靠的思路是增加外部监督:独立的评估器、校验规则、最大值次数、降级策略、人工审批门。尤其是在关键操作前,设置“人工确认”或“外部校验”,哪怕这会增加一些延迟,也远远好过让 Agent 闷头跑到最后。
下表把这五类缺口的判断线索和典型干预整理在一起,方便在实际排查时对照。
| 缺口分类 | 典型现象 | 更直接的判断线索 | 典型干预手段 |
|---|---|---|---|
| 感知与输入缺口 | 关键信息漏掉、乱码、截断 | 换完整输入后能正常 | 输入校验、结构化抽取、可信度标记 |
| 知识边界缺口 | 幻觉、编造事实、信息过时 | 引入事实源后仍错误 | RAG、知识库、引用机制、允许不知道 |
| 推理与规划缺口 | 目标漂移、步骤顺序错误 | 单项都对但整体偏 | 计划模板、检查点、人工审批节点 |
| 执行与工具调用缺口 | 参数错误、不读返回结果 | 工具返回正常仍理解错 | 工具 schema、参数校验、类型化返回 |
| 自我监测与恢复缺口 | 不会纠正、重复失败 | 告知错误后仍不改变 | 评估器、最大重试、降级策略、人工门 |
3. 用分类法做 Agent 故障排查:从现象到根因
分类法不是用来写报告的,它要能指导排查。我在日常调试 Agent 时,基本会按下面这条路径走。
3.1 先记录现象,再动手改提示词
遇到 Agent 行为异常,最常见的错误做法是立刻改提示词,比如加一句“请仔细检查”。这是治标不治本。因为如果问题出在工具返回没有校验,提示词再怎么强调,模型也看不到真实的报错结构。
我建议先建立一个“故障现场”记录,至少包含五类信息:
- 任务描述和目标是什么
- 从第几步开始出错
- 模型在这一步收到的输入是什么
- 工具返回了什么内容
- 模型最终输出 / 后续动作是什么
这些记录是后续定位的分类依据。没有这些,讨论就变成猜谜。
3.2 按五类缺口打标签,而不是直接给结论
拿到现象后,可以先根据五类缺口给故障打标签。注意,一个故障可能同时有多个缺口,但你要先找最可能的那个。
比如 Agent 在处理文档时反复重试同一个读取接口。这个现象可能同时涉及执行缺口(接口调用参数不对)和自我监测缺口(没有换策略)。我会先检查执行层:看工具返回里是否有明确的报错结构,模型有没有正确解析。如果工具返回的是JSON错误,而模型还在尝试读取一个不存在的字段,那问题就非常清晰。
给故障打标签的目的,是让排查顺序变得可操作。我的经验是:
- 先看输入和工具返回,因为这两层有日志可查,最容易定位。
- 再看知识边界,确认模型是否依赖外部事实。
- 再看推理与规划,确认目标是否偏移。
- 最后看自我监测,确认在提示错误后模型是否能自我纠正。
系统性问题,比如网络波动、上游接口变更、权限配置错误,要排在这套认知分类之前,因为这类问题不是 AI 的认知缺口。
3.3 用具体手段验证,而不是猜
每个分类都有对应的验证手段,下面是我常用的一套方法:
- 输入缺口:复现问题时,把完整上下文打印出来,看有没有截断和乱码。可以把长文档换成短摘要,看结果是否恢复。
- 知识缺口:把同一个问题改成“带着外部资料”去问,如果结果立刻变好,说明模型本身没有这个知识。
- 推理规划缺口:让模型在正式执行前输出任务拆解过程,看它有没有遗漏关键步骤。
- 执行缺口:记录每一次工具调用的参数和返回值,对照 schema,检查模型是否填对了参数,是否正确判断返回结果。
- 自我监测缺口:在执行错误后给模型一个明确的错误反馈,观察它的下一步动作。如果它仍然用同一种方式重试,就需要外部干预。
这个方法能避免一个很常见的问题:把规划问题当成提示词问题。比如你给 Agent 加了很长的指令,它还是跑偏,这大概率不是指令不够长,而是缺少中期校验点。你需要在流程设计上设置检查点,而不是继续堆字。
3.4 一个排查示例
用一个常见案例来串一下。
假设一个文档批量处理 Agent 的任务是:读取所有 PDF 文件,提取“项目编号”,写入汇总表。故障现象是:前两个文件正常,第三个文件开始失败,而且 Agent 把“文件路径不存在”误判成“该项目未找到”。
排查路径:
- 查看日志,发现第三个文件传入的是相对路径,而当前工作目录并不是文件所在目录。
- 工具层返回了“路径不存在”的错误,但 Agent 没有读取错误码,而是继续把错误内容当作正常文本。
- 给模型更完善的提示词,能不能解决?也许能,但下次换个目录结构,它可能还会犯。
- 更合适的修复是:在工具执行前,先统一解析路径为绝对路径;工具返回错误时,直接中断流程,而不是让模型自由发挥。
这个案例里,问题既不来自知识缺口,也不来自规划缺口,而是典型的执行与工具调用缺口。如果一上来就调提示词,可能问题会暂时好转,但根因一直没有消掉。
4. 团队落地时,怎么把这个分类法真正用起来
分类法的价值,需要落到团队协作里才能体现出来。
4.1 建立一份“认知能力缺口日志”
与其每次出了问题口头描述,不如在项目里建立一份公共问题库。每条失败记录都写成类似这样的结构:
{ "task_id": "doc-batch-001", "symptom": "第三个文件开始失败,误判为项目未找到", "fault_class": "execution_tool_call", "evidence": "工具返回路径不存在,模型未读取错误码", "intervention": "工具层统一绝对路径,返回错误时中断", "validation": "重跑全部文件,路径错误不再出现" }这个日志有四个作用:让问题更容易统计;让不同角色的成员快速理解问题;帮你在模型更换时做回归对比;也让你在写周报或复盘时有据可依。
日志里的fault_class不要只填一个。如果现象里有明显多重因素,可以标两个,但不要标太多。标太多等于没标。
4.2 用分类法指导模型选型
选型不只看“模型在榜单上多少分”,也要看你的系统最常出现哪类缺口。
- 知识边界缺口多,优先选择方便接入外部知识库的模型,而不是追求更大的参数规模。
- 推理与规划缺口多,优先考虑支持结构化规划和工具调用的模型,或者搭配一个更可控的 Agent 框架。
- 执行与工具调用缺口多,要重点考察模型对工具 schema 的理解能力,以及框架对参数校验的支持。这类问题大概率不是换一个更强模型就能解决的,而是要在框架层把校验做扎实。
- 自我监测缺口多,就要搭配独立的评估器,不能依赖模型自我修正。
有一个常见误区:一发现 Agent 不够聪明就换模型。实际上,很多问题发生在系统边界上。换模型可能改善了 20%,但工具层校验缺失仍然会让另外 80% 的错误继续发生。
4.3 按缺口类型设计护栏
一个生产级智能体系统,不应该假设模型永不犯错,而应该在每一层都设计“兜底”。按五类缺口的思路,护栏也可以分成五层:
- 输入层护栏:对关键输入做 schema 校验,压缩上下文时保留必要字段,对不完整信息标记“低置信度”。
- 知识层护栏:关键答案要求引用来源,无法引用时直接返回“未知”,而不是编造。对时效性强的数据引入外部检索。
- 推理规划层护栏:复杂任务强制先生成计划;在关键节点设置检查点,让人工或规则确认子目标完成后再进入下一步。
- 执行层护栏:工具参数在代码层做强校验,返回结果统一结构化,对错误码设置明确分支,而不是让模型自行理解。
- 自我监测层护栏:设置最大重试次数;错误发生时提供备选策略;关键操作设置人工审批门。
这里我想特别提醒一点:不要把“让模型反思”当成唯一的自我监测机制。模型反思本身也可能继续幻觉。更可靠的方式是外部验证,比如代码执行后检查退出码,数据写入后检查行数,接口调用后检查响应状态。模型可以“反思”,但生产系统不能只靠反思。
4.4 把评估集按缺口拆分
传统的评估集通常只计算“任务成功率”。这个数字很直观,但如果任务失败,很难看出到底是哪一类缺口导致。
我建议把评估集拆成 5 个子集,分别对应五类缺口。例如:
- 输入异常集:包含截断、乱码、schema 错位、多轮状态丢失。
- 知识盲区集:包含训练数据之外的实时信息、私有资料、需要检索才能确认的问题。
- 长程规划集:包含多步骤任务、目标中途变化的场景、存在干扰信息的长流程。
- 工具调用集:包含必填参数遗漏、返回错误码、外部状态变化、工具返回不稳定。
- 自我纠正集:包含第一次执行失败后,模型能否根据提示正确调整策略。
有了这 5 个子集,你在评估新模型、新提示词、新框架时,就不只是看整体成功率,还能看到它到底改善的是哪一类缺口。比如一个模型整体成功率很高,但长程规划集得分低,那它就不一定适合做主流程 Agent;而另一个模型整体分不高,但工具调用集很强,如果再配合强校验层,可能更适合你的场景。
5. 边界与误区:分类不是终点,干预才是
这套分类法也有自己的边界,不要把它当成万能钥匙。
5.1 一个现象可能混合多个缺口
真实故障很少像教科书案例那样干净。同一个错误,可能先是输入不完整,导致模型推理出了问题,推理错误又导致工具调用失败。这时候不要死盯着最表面的标签,而是按排查顺序逐步拆。分类法最大的作用是让你避免在错误的楼层里找问题,而不是保证一次就能找到唯一根因。
5.2 不是所有失败都来自认知能力缺口
AI 运行在一个更大的系统里。网络抖动、上游接口变更、数据库锁死、权限配置错误、定时任务重叠,都有可能造成和“认知缺口”相似的现象。遇到问题,先排除系统和流程问题。分类法适用于 AI 行为相关的环节,不适用于所有故障。
5.3 缺口不可能完全消除,但可以被控制
我见过不少团队试图把 Agent 调到“不出错”,很快就会发现这是死路。模型本身是概率系统,再加上复杂外部环境,永远存在不确定性。更务实的目标是:让错误可以被发现、被纠正、不扩散。
这也是为什么前面反复提到“人工审批门”“最大重试次数”“外部评估器”。这些设计不是为了限制 Agent 能力,而是为了在它失控之前,给系统一个“踩刹车”的机会。
5.4 对智能体 AI,先建立“停下来”的能力
如果让我给一个新手团队提一条最优先的建议,我会说:先给 Agent 设计好停止条件,再让它跑起来。
什么是停止条件?比如最大完成次数、超时时间、错误重试上限、结果校验失败时的降级策略、需要人工审批的关键操作清单。很多 Agent 的问题不是“不够聪明”,而是“明知道不对还继续走”。所以自我监测与恢复缺口,往往是最后一道防线。
当 Agent 发现自己陷入循环、外部接口连续报错、上下文已经混乱时,最好的能力不是“再试一次”,而是“停下来、记录现场、请求帮助”。
这也是我对生成式 AI 和智能体 AI 最核心的一个判断:真正困难的,不是让模型生成更长的正确内容,而是让它在能力边界处做出正确反应。面对认知能力缺口,我们不需要追求一个永远正确的模型,我们需要的是一个知道自己会错、知道错在何处、知道何时该停下的系统。把这个想清楚,再回去看那些“幻觉”“不稳定”“无效重试”的问题,解决路径会清晰很多。