人工智能实战Agent 工具调用总是乱选从意图识别到 Tool Router 的可靠调用架构设计一、问题场景Agent 看起来聪明但一用工具就翻车很多团队在大模型能力稳定后会继续做 Agent。典型需求包括1. 查询订单 2. 调用数据库 3. 读取知识库 4. 发送邮件 5. 创建工单 6. 调用搜索接口初版 Agent 通常是用户输入 ↓ 大模型判断要不要调用工具 ↓ 执行工具 ↓ 返回结果Demo 阶段效果很好。但一上线就会出现1. 用户只是普通咨询Agent 却调用了数据库 2. 应该查订单却调用了知识库 3. 工具参数缺字段 4. 工具调用顺序错误 5. 同一个问题有时调用工具有时不调用 6. 工具失败后模型继续编答案这类问题非常危险。因为工具调用不同于聊天。聊天答错只是内容问题。工具调用错了可能变成查错数据 发错消息 创建错误工单 触发错误业务动作这篇文章解决的问题是如何让 Agent 工具调用从“模型自由发挥”变成“可控的工程流程”。二、错误架构让模型直接决定一切很多初版 Agent 会把所有工具描述塞进 Prompt你可以使用以下工具 1. search_docs 2. query_order 3. send_email 4. create_ticket然后让模型自己决定。问题是模型不是调度系统。它可能因为语义相似选错工具。例如用户问我的订单怎么退款这可能是知识库问题查询退款规则也可能是订单问题查询具体订单状态如果没有明确路由策略模型会不稳定。三、正确思路Tool Router 独立出来生产级 Agent 不建议让模型直接随意调用工具。推荐架构用户输入 ↓ 意图识别 Intent Classifier ↓ Tool Router ↓ 参数抽取 ↓ 参数校验 ↓ 工具执行 ↓ 结果总结核心变化工具调用不再是自由生成而是受控流程。四、定义工具 SchemaTOOLS{search_docs:{description:查询知识库文档适合规则、流程、说明类问题,required_params:[query]},query_order:{description:查询用户订单状态适合具体订单相关问题,required_params:[order_id]},create_ticket:{description:创建人工工单适合系统无法解决或用户明确要求人工处理,required_params:[user_id,description]}}五、意图分类设计先定义意图而不是直接定义工具。INTENTS{knowledge_query:规则、政策、流程、说明类问题,order_query:具体订单状态、物流、退款进度,human_support:需要人工处理的问题,general_chat:普通聊天不需要工具}意图和工具映射INTENT_TO_TOOL{knowledge_query:search_docs,order_query:query_order,human_support:create_ticket,general_chat:None}六、可复现意图识别为了方便复现先用规则版本。defclassify_intent(user_input:str):if订单inuser_inputor物流inuser_inputor退款进度inuser_input:returnorder_queryif人工inuser_inputor客服inuser_inputor投诉inuser_input:returnhuman_supportif规则inuser_inputor流程inuser_inputor怎么inuser_input:returnknowledge_queryreturngeneral_chat生产环境可以换成LLM 分类 小模型分类 规则 模型混合分类但无论哪种方式都建议输出intent confidence七、参数抽取importredefextract_params(intent:str,user_input:str,user_id:strNone):ifintentorder_query:matchre.search(r\d{6,},user_input)return{order_id:match.group(0)ifmatchelseNone}ifintentknowledge_query:return{query:user_input}ifintenthuman_support:return{user_id:user_id,description:user_input}return{}八、参数校验defvalidate_params(tool_name:str,params:dict):requiredTOOLS[tool_name][required_params]missing[]forkeyinrequired:ifnotparams.get(key):missing.append(key)ifmissing:returnFalse,missingreturnTrue,[]如果缺参数不能硬调工具。应该反问用户ifnotvalid:return{action:ask_followup,message:f缺少必要信息{missing}}九、工具实现defsearch_docs(query:str):return{type:doc_result,content:f知识库中关于【{query}】的结果}defquery_order(order_id:str):return{type:order_result,order_id:order_id,status:退款处理中}defcreate_ticket(user_id:str,description:str):return{type:ticket_result,ticket_id:T202605010001,status:created}十、Tool Router 完整实现defexecute_tool(tool_name:str,params:dict):iftool_namesearch_docs:returnsearch_docs(params[query])iftool_namequery_order:returnquery_order(params[order_id])iftool_namecreate_ticket:returncreate_ticket(params[user_id],params[description])raiseValueError(funknown tool:{tool_name})defagent_router(user_input:str,user_id:strNone):intentclassify_intent(user_input)tool_nameINTENT_TO_TOOL[intent]iftool_nameisNone:return{action:direct_answer,message:这是普通对话不需要调用工具。}paramsextract_params(intent,user_input,user_id)valid,missingvalidate_params(tool_name,params)ifnotvalid:return{action:ask_followup,intent:intent,tool:tool_name,missing:missing,message:f为了继续处理请补充{missing}}tool_resultexecute_tool(tool_name,params)return{action:tool_result,intent:intent,tool:tool_name,params:params,result:tool_result}十一、测试cases[退款规则是什么,帮我查一下订单123456789的退款进度,我要投诉转人工客服,你好今天天气不错]forcaseincases:print(case)print(agent_router(case,user_idu001))print(-*50)预期退款规则是什么 → search_docs 订单123456789 → query_order 投诉转人工 → create_ticket 普通聊天 → 不调用工具十二、为什么要记录决策过程工具调用必须记录1. 原始用户输入 2. 识别意图 3. 选择工具 4. 抽取参数 5. 校验结果 6. 工具返回日志示例{user_input:帮我查一下订单123456789的退款进度,intent:order_query,tool:query_order,params:{order_id:123456789},status:success}如果用户投诉“查错了”你可以回溯。十三、踩坑记录坑 1让模型直接调用高风险工具例如发送邮件 删除数据 退款操作这类工具必须有人审或二次确认。坑 2缺参数也调用工具参数不完整时必须反问。不要让模型猜。坑 3没有工具白名单工具必须注册不允许模型生成任意函数名。坑 4工具失败后模型编结果工具失败时必须明确告诉用户失败不允许模型伪造结果。坑 5不记录调用日志Agent 系统一定要可审计。十四、适合收藏的 Agent 工具调用 Checklist工具定义 [ ] 是否有工具白名单 [ ] 是否定义 required_params [ ] 是否区分高风险工具 [ ] 是否有工具描述 路由 [ ] 是否先识别 intent [ ] 是否有 intent 到 tool 的映射 [ ] 是否有 confidence [ ] 低置信度是否反问 参数 [ ] 是否抽取参数 [ ] 是否校验缺失参数 [ ] 是否禁止模型猜参数 执行 [ ] 是否捕获工具异常 [ ] 是否有超时控制 [ ] 是否有重试限制 [ ] 是否记录工具日志 安全 [ ] 高风险操作是否二次确认 [ ] 是否支持人工介入 [ ] 是否禁止任意工具调用十五、经验总结Agent 的核心不是让模型“想干什么就干什么”。真正可上线的 Agent 必须是模型理解意图 工程控制动作 工具提供结果 系统负责审计一句话总结Agent 不是聊天机器人加几个函数而是一个受控的任务执行系统。十六、优化建议后续可以继续做1. 使用 LLM 做 intent 分类 2. 加入置信度机制 3. 高风险工具二次确认 4. 工具调用超时和熔断 5. 工具结果二次总结 6. 构建工具调用评测集 7. 增加多工具编排能力 8. 接入审计日志最后一句经验Agent 能不能上线不取决于它多聪明而取决于它是否可控。