资讯详情

Agent开发避坑指南:大模型判断逻辑分层与工具调用优化实践

📅 2026/10/26 21:32:45 | 华诺云谱 👁 阅读
Agent开发避坑指南:大模型判断逻辑分层与工具调用优化实践
1. 从一次线上事故说起为什么我把判断逻辑从大模型里搬了出来去年年底我负责的一个智能客服 Agent 上线第二周就出了状况。用户问“帮我查一下上个月的订单”Agent 回复了一段非常礼貌但完全无关的话大意是“我理解您想查询订单建议您登录官网查看”。问题是这个 Agent 明明接了订单查询工具它却选择不调用而是自己“编”了一个回答。排查日志发现大模型在那一轮推理中判断“用户意图不够明确”于是决定先追问而不是执行。但它的追问话术又跑偏了变成了一个泛泛的建议。这个案例让我意识到一个根本问题我把太多判断权交给了大模型。这不是个例。在 Agent 开发中很多人包括当时的我会习惯性地把“要不要调用工具”“调用哪个工具”“参数怎么填”“结果怎么处理”全部塞进 prompt 里让大模型一次性输出决策。这种做法在 demo 阶段看起来很优雅——一个 prompt 搞定所有逻辑。但一旦进入真实业务场景问题就会集中爆发。这篇文章想聊的就是这件事Agent 的判断逻辑到底该怎么分层。我会把自己踩过的三个坑完整还原出来包括当时的错误做法、排查过程、根因分析以及最终落地的分层方案。如果你正在做 Agent 开发或者准备从零搭建一个 AI Agent这些经验应该能帮你少走不少弯路。核心关键词Agent、大模型、Agent 架构、Agent 开发、工具调用、判断分层。2. 第一个坑把“意图识别”和“工具选择”混在一个 prompt 里2.1 当时的做法一个万能 prompt 包打天下最开始我的 Agent 架构非常简单用户输入 → 拼接一个系统 prompt → 大模型输出 JSON → 解析 JSON 执行工具。系统 prompt 大概长这样你是一个智能助手可以调用以下工具 - query_order: 查询订单参数 user_id, date_range - refund: 申请退款参数 order_id, reason - human_transfer: 转人工 请根据用户输入判断意图选择合适的工具并提取参数。 输出格式{tool: ..., params: {...}}这个方案在测试集上准确率大概 85%看起来还行。但上线后真实用户的输入千奇百怪准确率直接掉到 60% 左右。2.2 问题表现意图对了工具选错最典型的一类错误是用户说“我上周买的东西怎么还没到”大模型正确识别了意图是“查询物流”但它选择了query_order而不是query_logistics。因为 prompt 里没有query_logistics这个工具它只能从现有工具里挑一个最接近的。另一类错误更隐蔽用户说“算了帮我退了吧”大模型判断意图是“退款”但参数提取时把order_id填成了上一轮对话里提到的另一个订单号。这是因为大模型在长上下文里对指代消解做得不够稳定。2.3 根因分析大模型在做它不擅长的事这里涉及一个关键认知大模型擅长语义理解和生成但不擅长精确的枚举选择和状态跟踪。意图识别是语义理解大模型做得很好。但“从 N 个工具里选一个”本质上是一个分类问题而且工具数量越多、工具描述越相似大模型的准确率下降越明显。至于参数提取中的指代消解和状态跟踪这需要维护对话状态而大模型每次推理都是无状态的除非你把完整历史塞进去但那样又会引入噪声。我后来做了一个对比测试把工具选择从大模型里拿出来改成一个基于规则 轻量分类模型的独立模块准确率从 60% 提升到 92%。而意图识别仍然交给大模型准确率保持在 95% 以上。2.4 调整方案意图识别归大模型工具选择归规则引擎调整后的架构变成了两层第一层大模型只负责输出意图标签不负责选工具。比如用户说“我上周买的东西怎么还没到”大模型输出{intent: logistics_query}。第二层一个规则引擎根据意图标签映射到具体工具。映射关系是人工配置的比如logistics_query → query_logisticsorder_query → query_order。如果某个意图对应多个工具再根据槽位填充情况做二次判断。这样做的好处是大模型的输出空间从“所有工具的组合”缩小到了“有限的意图标签”准确率大幅提升。而且意图标签和工具的映射关系是显式的、可审计的出问题时能快速定位是意图识别错了还是映射配错了。提示意图标签的数量建议控制在 20 个以内。超过 20 个后大模型的意图分类准确率也会开始下降这时候需要考虑做意图的层级分类。3. 第二个坑让大模型自己决定“要不要调用工具”3.1 问题场景该调用的时候不调用不该调用的时候乱调用解决了工具选择的问题后我遇到了第二个坑大模型在“是否调用工具”这个判断上非常不稳定。有些问题明明需要查数据库才能回答大模型却直接用自己的知识编了一个答案。比如用户问“我的会员等级是什么”大模型回复“通常会员等级分为普通、白银、黄金……”完全没有调用query_member_level工具。反过来有些问题明明可以直接回答大模型却非要调用工具。用户说“你好”它调用query_user_info用户说“谢谢”它调用log_interaction。这些无效调用不仅浪费 token还增加了响应延迟。3.2 排查过程大模型的“自信”是问题根源我一开始以为是 prompt 写得不够清楚于是加了很多强调“如果问题涉及用户个人信息必须调用工具”“如果只是打招呼不要调用工具”。但效果有限大模型仍然会时不时地“自作主张”。后来我意识到这个问题的根源在于大模型对“自己知不知道答案”的判断是不可靠的。它不知道自己不知道什么。当它遇到一个需要实时数据的问题时它会倾向于用训练数据里的通用知识来回答而不是承认“我需要查一下”。这是一个认知层面的问题不是 prompt 能完全解决的。3.3 解决方案用前置规则做“工具调用触发器”我的做法是在大模型之前加一层轻量的规则判断我把它叫做“工具调用触发器”。这一层不依赖大模型而是基于关键词、正则、以及简单的分类模型来判断“这个问题是否必须调用工具”。具体来说触发器分三类第一类强制调用。如果用户输入命中了某些关键词如“我的订单”“我的余额”“查询”“帮我查”直接标记为必须调用工具跳过“是否调用”的判断。第二类强制不调用。如果用户输入是纯问候、纯感谢、纯闲聊通过一个轻量分类模型判断直接走通用回复不进入工具调用流程。第三类交给大模型判断。对于不确定的情况仍然让大模型决定但会在 prompt 里明确告诉它“如果你不确定请选择调用工具”。这个方案落地后无效调用减少了约 70%而该调用没调用的情况减少了约 85%。3.4 一个容易忽略的细节工具调用的“成本”也要考虑在调整过程中我还发现一个细节不同工具的调用成本差异很大。有些工具是查本地缓存毫秒级返回有些工具要调外部 API可能几百毫秒甚至超时。如果让大模型无差别地决定调用它不会考虑这些成本差异。所以我在触发器里加了一个优先级配置对于高成本工具触发条件更严格对于低成本工具可以适当放宽。这个配置是写在规则里的不交给大模型判断。4. 第三个坑把“结果处理”也交给大模型4.1 问题表现工具返回了正确结果大模型却处理错了这个坑是最隐蔽的。工具调用成功了返回了正确的数据但大模型在生成最终回复时把数据用错了。举个例子用户问“我最近一笔订单的金额是多少”工具返回{order_id: 12345, amount: 299.00, currency: CNY}。大模型生成的回复是“您最近一笔订单的金额是 299 元”。看起来没问题。但如果工具返回的是{order_id: 12345, amount: 29900, currency: CNY, unit: cent}大模型可能会忽略unit字段直接说“29900 元”。这就是典型的“结果处理错误”。另一类问题是工具返回了多个结果大模型在汇总时漏掉了部分信息或者把不同订单的信息混在一起。4.2 根因大模型对结构化数据的处理不可靠大模型对自然语言的理解很强但对结构化数据的处理并不稳定。它可能会忽略某些字段可能会把数字格式搞错可能会在多个结果之间混淆。而且这个问题很难通过 prompt 解决因为你不可能在 prompt 里穷举所有字段的处理规则。4.3 方案结果处理用模板 大模型只做“润色”我的做法是把结果处理分成两步第一步用代码做结构化处理。工具返回的 JSON 先经过一个格式化模块把关键字段提取出来按照预定义的模板填充。比如订单查询的模板是“您最近一笔订单订单号{order_id}的金额是 {amount} {currency}”。第二步大模型只负责润色。把填充好的文本交给大模型让它根据对话上下文调整语气和表达方式但不允许它修改任何数字和关键信息。为了确保大模型不“自由发挥”我在 prompt 里加了明确的约束“你只能调整语气和连接词不能修改任何数字、日期、订单号等关键信息。如果模板文本已经完整直接输出即可。”这个方案落地后结果处理的错误率从约 15% 降到了 2% 以下。4.4 补充什么时候可以让大模型多做一点当然并不是所有场景都适合用模板。如果工具返回的是非结构化文本比如一篇文章、一段日志那大模型的处理能力就很有价值。这时候可以让大模型做摘要、提取关键信息、生成自然语言回复。判断标准很简单如果结果是结构化的、字段明确的用代码处理如果结果是非结构化的、需要语义理解的交给大模型。5. 分层之后的 Agent 架构各司其职各尽其能5.1 整体架构图文字描述经过三次调整我的 Agent 架构最终变成了这样用户输入 → 前置触发器规则 轻量分类→ 意图识别大模型→ 工具选择规则引擎→ 工具执行代码→ 结果格式化代码→ 回复润色大模型→ 输出每一层只做自己擅长的事前置触发器判断是否需要调用工具用规则和轻量模型快且稳定。意图识别理解用户语义用大模型准确率高。工具选择意图到工具的映射用规则引擎可审计。工具执行实际调用用代码可靠。结果格式化结构化数据处理用代码精确。回复润色自然语言生成用大模型灵活。5.2 各层的职责边界与协作方式这里的关键是职责边界要清晰。大模型不负责枚举选择不负责状态跟踪不负责结构化数据处理。它只负责语义理解和自然语言生成。规则引擎不负责语义理解它只做确定性的映射和判断。代码不负责生成自然语言它只做结构化的数据处理。各层之间通过明确定义的接口通信。比如意图识别的输出必须是预定义的意图标签之一工具选择的输入必须是合法的意图标签输出必须是预定义的工具名之一。任何一层输出不符合预期都会被下一层拒绝并触发降级逻辑。5.3 降级逻辑当大模型不可用时怎么办分层架构还有一个好处降级更容易。如果大模型服务不可用我可以降级到纯规则方案。虽然准确率会下降但核心功能仍然可用。具体来说如果意图识别的大模型调用失败我会用一个基于关键词的兜底分类器。如果回复润色的大模型调用失败我会直接输出格式化后的模板文本。这些降级逻辑都是预先配置好的不需要临时写代码。6. 实操建议怎么判断哪些逻辑该交给大模型6.1 一个简单的判断框架经过这几个坑我总结了一个简单的判断框架。对于任何一个判断逻辑问自己三个问题第一这个判断是语义理解还是枚举选择语义理解交给大模型枚举选择交给规则。第二这个判断需要状态跟踪吗如果需要维护对话状态、用户状态、订单状态交给代码。第三这个判断的错误成本高吗如果错误成本高比如涉及金额、权限用规则 代码不用大模型。6.2 常见场景的分配建议场景建议方案理由意图识别大模型语义理解大模型擅长工具选择规则引擎枚举选择规则更稳定参数提取大模型 校验大模型提取代码校验是否调用工具前置规则 大模型兜底规则快且稳大模型处理边界情况结果格式化代码结构化数据处理代码精确回复生成大模型自然语言生成大模型擅长多轮对话状态代码状态跟踪代码可靠6.3 一个反直觉的经验大模型不是越多越好很多人做 Agent 时会倾向于“能交给大模型就交给大模型”觉得这样更智能。但我的经验恰恰相反大模型用的地方越少Agent 越稳定。当然这不是说大模型不好。大模型在语义理解和自然语言生成上的能力是无可替代的。但在其他环节规则和代码往往更可靠、更可预测、更便宜。我现在做 Agent 的原则是能用规则解决的不用大模型能用代码解决的不用大模型只有语义理解和自然语言生成才交给大模型。7. 踩坑之后的一些零散心得7.1 日志要记全不然排查全靠猜这三个坑能排查出来全靠日志记得全。我现在的日志会记录用户输入、前置触发器的判断结果、大模型的原始输出、规则引擎的映射结果、工具调用的入参和返回值、格式化后的文本、最终回复。每一层都有日志出问题时能快速定位是哪一层出了问题。7.2 测试集要覆盖边界情况我最初的测试集都是“正常”的用户输入比如“查一下我的订单”。但真实用户的输入千奇百怪有错别字、有省略、有指代、有情绪。后来我专门建了一个边界测试集覆盖了这些情况才发现了很多之前没注意到的问题。7.3 不要追求一次到位迭代才是常态我的 Agent 架构不是一开始就设计成这样的而是踩一个坑改一点慢慢演化出来的。所以如果你刚开始做 Agent不用追求一步到位。先跑起来遇到问题再调整迭代几次之后架构自然会清晰。7.4 大模型的上下文长度不是越长越好我试过把完整对话历史都塞进 prompt结果发现大模型反而更容易混淆。后来改成只保留最近几轮对话 关键状态摘要效果更好。上下文长度和准确率不是线性关系找到合适的长度比一味加长更重要。7.5 工具描述要写清楚但不要指望大模型能记住所有细节工具描述要写清楚参数含义、返回值格式、使用场景。但不要指望大模型能记住所有细节尤其是工具数量多的时候。关键信息还是要靠代码校验和规则兜底。8. 最后再说两句Agent 开发这件事说到底是在“智能”和“可控”之间找平衡。大模型带来了智能但也带来了不确定性。把判断逻辑分层让大模型只做它擅长的事其他交给规则和代码是我目前找到的最好的平衡点。这个方案不是完美的它需要更多的配置和维护成本。但相比线上事故带来的损失这些成本是值得的。而且随着 Agent 规模变大分层架构的优势会越来越明显。如果你也在做 Agent 开发欢迎交流。踩坑不可怕可怕的是踩了坑不知道为什么踩的。希望这篇文章能帮你少踩几个。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑