深色模式
常见AI使用问题
大模型幻觉的三大成因与解法
处理大模型幻觉时有一个常见误区:看到模型答错就笼统归因于“模型能力不行”,或以为“上一个 RAG 就能解决”。更有效的思路是精准定位错误来源,分类治理、对症下药。幻觉可以拆成三大底层成因。
第一是知识缺失,也是最常见的一类。模型没有可靠事实来源,却强行补全生成。比如问最新政策、内部系统状态或私有文档内容时,模型在预训练中没见过这些知识,仍会生成一个听起来合理但错误的答案。治理方式是接入权威数据源(如检索增强 RAG)、外部工具查询,并建立安全拒答机制,让模型在没有依据时可以选择不答。
第二是上下文冲突。输入证据内部自相矛盾,导致模型混淆和误选。典型场景是新旧文档同时被召回,或用户输入与知识库内容不一致。在冲突环境下,模型往往倾向选择位置靠前、描述更详细、更像答案的片段,而不一定是最新事实。治理方式包括版本控制、来源溯源、时间戳校验和证据排序,让正确证据更容易被选中。
第三是注意力偏移,更隐蔽。在长上下文或有噪声的环境里,模型关注了错误片段。此时并非没有客观证据,而是关键证据被噪声淹没、没被正确使用。典型表现有两种:错误关联(关注到相似但不相关的片段)和约束丢失(在多跳推理中漏掉约束条件)。治理方式包括上下文压缩、信息重排、引用约束和分步验证。
评估幻觉时也不能只看最终答案,还要对过程做多维验证:是否检索到了回答所需的关键证据、多源证据之间是否存在矛盾、生成内容是否严格忠实于所提供的证据。核心仍是分类治理,不同病因用不同药,不能指望单一方案覆盖所有情况。
Tool 和 Skill 的区别
在智能体系统里,Tool 和 Skill 属于两个不同层次。Tool 解决“能不能做”,Skill 解决“怎么做才对”。
Tool 是模型“能动手”的底层能力。查数据库、调接口、读文件、执行代码等动作,模型本身无法只靠语言推理完成,必须依赖真实可执行的外部函数。工程上,Tool 通常通过函数调用或 MCP 接入:模型看到工具名称、参数和用途描述,自主决定是否调用以及如何填写参数;系统真正执行后,再把结果返回给模型继续推理。Tool 的核心是执行动作,因此可能产生真实副作用,例如发送请求、修改数据、触发外部流程。
Skill 是模型“知道该怎么动手”的高层经验。很多任务并不是模型不能做,而是模型不知道在具体业务场景下该按什么流程、规范和顺序做。Skill 的本质是一包领域知识与流程经验,通常由说明文档、模板、脚本和参考资料组成。它告诉模型先做什么、后做什么、哪些字段要校验、异常时怎么兜底。
两者不是替代关系,而是协同关系。Tool 是“手”,提供真实执行能力;Skill 是“肌肉记忆”,提供正确做法。比如给模型接入一组对账接口,只是让模型有了“能查、能调、能执行”的能力;但如果没有 Skill,模型仍不知道公司对账流程里先拉哪张表、校验哪些字段、异常时如何处理。只有 Tool 和 Skill 配合,智能体才既能动手,也能按业务规范把事情做对。
Skill 还有一个重要价值:降低常驻上下文负担。若把全部业务规范和所有工具说明都塞进系统提示词,模型还没开始工作,上下文就被大量描述占满。Skill 采用按需加载机制,平时只常驻名称和简短描述;当模型判断当前任务相关时,再加载完整说明文档和资源。这种渐进式披露方式,既节省上下文,也减少无关信息干扰。
Skill 冲突怎么解决
Skill 冲突的本质不是缺少一个“裁判”,而是职责边界模糊、语义描述重叠。模型在选择 Skill 时,会把用户请求与各个 Skill 的名称、描述做语义匹配;如果两个 Skill 的适用场景和描述在模型看来高度相似,就会出现多个 Skill 抢同一个任务的情况。
解决 Skill 冲突,优先从设计层治根,而不是一上来就写硬编码优先级。
第一步是消除重叠。先判断冲突的两个 Skill 到底是不是在做同一件事:如果本质上是同一能力,就合并成一个 Skill;如果是两件不同的事,只是描述相似,就重新划清边界。描述里要写清适用场景、触发信号和负向约束,让模型能区分“什么时候用它”和“什么时候不用它”。如果两个能力路径很少同时使用,也应拆开放置,避免不必要的上下文竞争。
第二步是利用特异性,让模型自己选对。Skill 天然存在通用与专用的层次。比如系统里同时有“通用文档处理”和“合同解析”两个 Skill,面对合同时,应该优先触发合同解析。做法不是额外维护一张复杂优先级表,而是在专用 Skill 的描述中写足专属触发信号,例如“专门处理合同、条款解析、风险识别”;通用 Skill 则明确处理常规文档。范围越具体,描述越能表达优先级。
第三步才是显式仲裁。只有当两个 Skill 确实都相关、无法从描述上彻底拆开时,才引入上层编排或主 Agent 决策。常见兜底方式包括:专用规则压过通用规则;主 Agent 根据上下文分派;必要时双跑择优;高风险场景交给人工确认。
显式仲裁必须可观测。系统要记录每次是哪两个 Skill 发生争抢、最终选了谁、为什么这样选。真实运行日志不是为了事后甩锅,而是为了反向优化 Skill 描述和边界,最终把更多冲突消灭在设计阶段。
MCP 和函数调用有什么区别
MCP 不是函数调用的升级版,也不是函数调用的替代品。两者处在不同层次,解决的是一次工具调用链条里的不同问题。
函数调用负责“意图生成”。大模型原生输出的是自然语言,程序无法直接拿一句“查北京天气”去调用接口。函数调用让开发者预先定义工具名称、参数结构和用途说明,使模型能把自然语言意图转成结构化请求,例如生成“调用天气查询函数,参数为北京”。但函数调用只负责生成请求,不负责真正连接外部系统、启动工具、执行调用和接收回调结果。
MCP 负责“标准化执行”。它站在函数调用之后,解决工具发现、连接、调用和结果返回的标准化问题。过去每接一个外部工具,开发者都要单独写一套适配代码;工具多了以后,就会出现“十个工具十套接法、换个模型重来一遍”的生态碎片化问题。MCP 的目标是把工具发现、工具调用和结果返回统一成协议,让工具具备可发现、可移植、可跨系统执行的能力。
可以把一次工具调用看成接力赛:函数调用是第一棒,负责把模型意图表达成结构化请求;MCP 是第二棒,负责按统一协议找到工具、执行请求、返回结果。二者是前后配合关系,而不是谁取代谁。
工具调用失败怎么办
在真实生产环境里,Agent 工具调用失败是常态而不是意外。接口超时、网络抖动、触发限流、模型把参数填错(缺必填字段、格式不对、生成坏掉的 JSON)、返回格式混乱,都会导致调用失败。因此,只会“重试”并不足以应对:网络波动类问题重试确实能恢复,但参数填错这类确定性错误,原样重试一百次仍然会失败。
正确做法是把每次工具调用包在一层保护逻辑里,遵循“调用失败 → 错误分类 → 路由到对应恢复动作”的思路,按错误类型差异化兜底,而不是不分类地盲目重试。
第一类是临时性错误,例如接口超时、网络抖动、被限流。应对方式是带退避的重试:重试间隔按 1 秒、2 秒、4 秒指数递增,避免高频重打压垮服务端,同时设置最大重试次数,防止无限循环。如果某个工具连续失败超过阈值,说明它可能已经不可用,应触发熔断,暂时停用并切换到备用方案,避免单个坏工具拖垮整条流程或烧穿预算。
第二类是确定性错误,例如参数错误、格式错误、缺字段、坏 JSON。这类错误重试原样请求没用,应让模型自我纠正:把具体报错信息作为反馈重新喂回模型,让它带着错误原因重新生成。多数格式错误在给一次带反馈的重试机会后就能改对。进一步可以把报错结构化,明确指出修改方向,形成“失败 → 反思 → 带教训重试”的自我修复循环。
第三类是严重错误,例如预算即将超支、涉及不可逆危险操作、反复恢复仍然失败。这类情况的原则是绝不让 Agent 自作主张。一个失控的 Agent 比一个停下来的 Agent 危险得多。发生严重异常时,Agent 应立即停止、冻结并保存当前状态与进度,把最终决策权交回给人。
整套错误恢复还必须配合完整的日志与可观测性:把每一步调用、失败和恢复动作都记录下来,保证出问题时全链路可追溯,也便于事后复盘。
多 Agent 协作通信怎么设计
多 Agent 系统协作失败,根因往往不在单个 Agent 能力不足,而在 Agent 之间的信息交换出了问题。Agent 之间的通信带宽有限,无法把一个 Agent 脑中的全量上下文原封不动搬给另一个,只能通过消息传递。交接点最容易出现三种断裂:信息传丢(关键参数遗漏)、信息传歪(原始意图被下游曲解)、上下文断裂(多轮交接后丢失全局视野)。因此,通信要当成一个专门的架构问题来设计,核心是三件事。
第一是选对通信拓扑,决定谁跟谁说话。中心化模式(主管与执行者模式)由一个主 Agent 居中调度,负责拆解任务、分发任务、收集并汇总结果,所有子 Agent 只与主 Agent 通信,彼此不直接对话。它通信路径清晰、全局状态由主 Agent 统一维护,系统可控、好调试、好观测,通常优先推荐。接力交接模式是 Agent 之间直接传递,谁处理完就交给下一个,更灵活,但更容易在交接点出故障。
第二是定好消息契约,决定用什么协议和结构说话。应避免 Agent 之间用自然语言自由发挥,这一步最容易被忽略,也最容易引发歧义和信息丢失。更稳的做法是用结构化消息格式,把每次交互携带的数据固定成标准化接口,例如 JSON。派发任务时用清晰接口消除模糊空间,交代清楚子任务目标、期望输出格式、可用工具列表、边界与限制,以及上一步的结果。
第三是管好共享状态,确保各 Agent 看到同一份真相。如果每个 Agent 只掌握局部信息,系统会陷入协作混乱。可以建立一块统一维护的共享记忆区,也叫公共黑板,各 Agent 把关键进度、中间结论和状态写进去,需要时再读取,而不是靠一条条消息互相追问。子 Agent 返回结果时,不必把冗长推理过程原样传回,只需把精简结论写入共享状态,既省通信带宽,也保持各 Agent 上下文干净。共享状态要由编排者统一维护写入入口,保证全局视图一致。
落地时可以概括为四条:中心化编排管住通信路径,结构化消息管住交互语义,共享状态黑板管住全局真相,全流程可观测(例如贯穿的 Trace ID)保证每次交互和通信链路可追溯。
Prompt 注入怎么防
Prompt 注入的根因,是大模型分不清“指令”和“数据”。系统提示词、用户输入、网页内容、检索文档、工具返回结果,进入模型后都会被压平成同一段 Token 流。模型没有天然硬边界判断哪些必须服从、哪些只是待阅读素材。因此,单纯在提示词里加一句“不要听恶意指令”,无法真正解决问题。
更危险的是间接注入。攻击者可以把恶意指令藏在网页、知识库文档或工具返回结果里。模型读取这些外部内容后,可能把其中的伪装文字当成新指令执行。安全设计不能假设“模型一定不会被骗”,而要假设“模型迟早会被骗”,重点是让它即使被骗也造不成严重损失。
有效防御应采用四层纵深防御。
第一层是输入侧检测与隔离。系统提示词作为可信指令区,外部内容只作为不可信数据区,不能与系统提示词随意拼接。外部网页、文档、工具结果进入上下文前,应通过安全分类器或小模型扫描,识别隐藏指令、伪装系统消息、诱导越权文本等风险。但这只能挡住一部分攻击,无法保证全部拦截。
第二层是模型侧提升鲁棒性。模型训练阶段可以加入大量藏在网页和文档中的恶意指令样本,通过对抗训练和强化学习,让模型更容易识别并拒绝注入内容。这能降低被攻击成功的概率,但仍无法把成功率降为零。
第三层是执行侧控制爆炸半径,这是最关键的一层。Agent 的工具权限、数据访问和账号能力必须遵守最小权限原则,不给“万能钥匙”。高风险操作如转账、删库、发邮件、执行代码,应强制人工确认或放进沙箱。处理不可信外部内容的组件尽量只保留读权限;真正执行写操作的组件,最好与不可信内容隔离。
第四层是输出侧校验与可观测。系统要检查输出中是否夹带敏感信息、异常外链或格式逃逸,避免模型被诱导把密钥、日志等信息偷偷拼进 URL 或返回文本中。同时,完整记录外部内容来源、模型决策和工具调用链路。不可观测就不可控,事故发生后必须能追溯是哪份文档、哪个网页、哪个工具结果触发了异常行为。
Prompt 注入防御的目标不是追求“永不被攻破”,而是通过分层隔离、权限收敛和审计追踪,把攻击成本抬高,并把失败后的损失控制在可接受范围内。
上下文窗口爆了怎么办
智能体执行长任务时,对话历史、工具结果和中间推理会不断累积,最终把上下文窗口塞满。这个问题不能只靠换更大窗口的模型解决。窗口变大不代表可以随便塞:上下文越长,中间信息越容易被模型忽略;同时推理速度变慢、成本上升。真正要考察的是上下文工程能力。
核心思路是把上下文当成稀缺资源管理,而不是无限垃圾桶。有限窗口里应该始终只保留当前任务最需要的信息。工程上主要有四种打法。
第一是高质量摘要压缩。当对话接近窗口上限时,对历史内容做结构化摘要,把重要信息带入新窗口。摘要不是简单压缩字数,而是要保留架构决策、未解决问题、关键中间结论、当前计划和待办;重复的工具返回、冗长试错过程、过期细节则应果断丢弃。这样模型可以“换气”,但任务记忆不断。
第二是外部记忆。上下文窗口相当于内存,外部文件、数据库、向量库或检查点相当于硬盘。长任务应把阶段性进展、关键状态、重要产物写到外部,重新打开会话时再读回。编程类长任务尤其适合建立任务清单和进度文件,每一轮基于外部记录增量推进。
第三是按需检索。不要把全部资料、代码和文档一次性塞进上下文,而是使用检索增强思路:需要哪份资料时再取,用完后让它淡出上下文。这样能保持窗口干净,避免无关信息挤占注意力。
第四是子任务拆分与隔离。复杂任务可以拆给多个子 Agent,每个子 Agent 在独立上下文里处理一小块,只向主 Agent 回传精简结论。繁琐中间过程被隔离在子任务里,主流程只保留高密度信息。
上下文管理的目标,是让窗口里只留下“下一步决策最需要的信息”。稳定执行长任务,靠的是压缩、外部存储、即时检索和子任务隔离的组合,而不是单纯堆更长窗口。
Agent 记忆机制怎么设计
Agent 记忆机制要解决的核心矛盾,是上下文窗口有限,而任务执行周期和用户关系可能是长期的。只接入一个向量数据库,把历史对话全部塞进去,并不等于有了好的记忆系统。
合理的记忆体系应分层设计。
第一层是短期记忆,也可以理解为工作记忆。它保存当前任务相关信息,例如最近几轮对话、工具调用结果、当前执行计划、临时变量等。这类信息通常直接放在上下文窗口里,模型每一步都能实时访问。但短期记忆成本高,不能无限增长。
第二层是压缩记忆。当交互轮次变多、原始记录膨胀时,系统应把历史压缩成结构化摘要,记录用户目标、已完成步骤、关键决策、未解决问题和下一步事项。这样既能减少上下文占用,也能在新窗口中保持任务连续性。
第三层是长期记忆。它保存跨会话信息,例如用户偏好、长期目标、历史任务结果、业务知识和重要决策记录。长期记忆可以用向量数据库、知识图谱或关系数据库实现,但底层存储不是重点,关键是写入、更新、召回和遗忘策略。
长期记忆还可以进一步分成三类:语义记忆记录通用知识,例如业务规则和产品文档;情景记忆记录具体发生过的事件,例如某次审批、某次沟通;程序记忆记录流程和最佳实践,例如报销流程、写作规范、项目实施步骤。
记忆系统最大的挑战不是“记不住”,而是“记太多”。大量信息会过期、重复或与当前任务无关,如果每次都召回,会造成记忆污染和上下文膨胀。因此,完整记忆系统必须具备四种能力:写入、更新、召回和遗忘。什么时候存、什么时候改、什么时候删、什么时候总结,往往比“存什么”更重要。
好的 Agent 记忆机制,不是把全部历史都保存下来,而是在正确时机保存高价值事实,在正确场景召回相关信息,并能及时更新或作废过期内容。
长期记忆错乱怎么解决
长期记忆的难点在于事实会随时间变化。用户三月说自己在北京,五月说搬到上海,如果系统只是简单覆盖旧记忆,或者把两段话都丢进向量库检索,就会出现新旧记录打架:模型既可能忘掉历史,也可能把过期事实当成当前事实。
这类问题的本质不是存储不足,而是没有管理“事实在什么时间成立”。真实业务里,信息变化、用户改变主意、事实过期都很常见,记忆系统必须支持时间维度。
更稳的做法是使用双时间机制。
第一条时间线是现实世界时间,也叫有效时间。它记录某个事实在现实中从什么时候开始成立、什么时候失效。例如“用户在北京工作”可能在三月成立,五月失效;“用户在上海办公”从五月开始成立。
第二条时间线是系统时间,也叫事务时间。它记录系统什么时候写入这条信息、什么时候把它作废。现实时间用来回答“某个时刻真实情况是什么”,系统时间用来做审计和追溯。
工程上可以为每条事实挂上四个时间戳:成立时间、失效时间、写入时间、作废时间。这样,扁平文本就变成了带时间的事实网络。更新事实时,不应直接删除旧记录,而应标注旧事实失效,并新建一条有效事实;新旧事实之间用替代链连接。主检索默认只召回当前有效事实,旧事实保留在历史归档库中,满足追溯和审计需要。
更容易踩坑的是隐式冲突。用户往往不会明确说“请作废我以前的住址”,而是随口说“我现在在上海办公”。因此,记忆写入环节必须做冲突检测:把新事实与历史事实对比,判断是否需要让相关旧记忆失效。仅有双时间表结构还不够,如果写入时不检测冲突,记忆库仍会越长越乱。
长期记忆系统的目标,是同时知道“现在真实情况是什么”和“过去在某个时刻曾经是什么”。作废代替删除、有效事实默认召回、历史事实可追溯,是避免长期记忆错乱的核心原则。