【AI应用开发】多个工具同时存在时,LLM 频繁选错工具,如何优化 prompt?
2026/8/7 8:22:16 网站建设 项目流程

【AI应用开发】多个工具同时存在时,LLM 频繁选错工具,如何优化 prompt?

目录

  1. 问题根因:为什么工具多了就选错
  2. Prompt 优化六大策略
  3. 策略一:工具分层分类
  4. 策略二:精确描述"何时用/何时不用"
  5. 策略三:工具选择预判注入
  6. 策略四:约束性输出格式
  7. 策略五:动态工具集剪枝
  8. 策略六:工具选择后验证
  9. 效果对比

1. 问题根因:为什么工具多了就选错

核心矛盾: LLM 的注意力是有限的 → 工具越多,每个工具的描述对 LLM 的"信号"越弱 具体表现: - 5个工具时,选择准确率 ~85% - 15个工具时,选择准确率 ~65% - 30个工具时,选择准确率 ~45%(几乎随机) 更深层原因: 1. 工具描述相似 → LLM 分不清 search_kb vs search_docs 2. 上下文太长 → 早期工具描述被"遗忘" 3. 名称误导 → query_user 和 get_user_info 看起来像同一个 4. 参数混淆 → 不同工具的相似参数名让 LLM 串台

2. Prompt 优化六大策略

策略1: 工具分层分类 → 把工具按"语义分组" 策略2: 精确使用描述 → 写清"何时用/何时不用" 策略3: 预判注入 → 先分析意图,再给候选工具 策略4: 约束输出格式 → 让 LLM 先解释为什么选这个工具 策略5: 动态工具剪枝 → 根据上下文过滤不需要的工具 策略6: 选择后验证 → 程序层面验证工具选择的合理性

3. 策略一:工具分层分类

# ❌ 扁平化工具列表(容易混淆)TOOLS_FLAT=["search_knowledge_base: 搜索知识库","search_faq: 搜索FAQ","search_docs: 搜索文档","query_order: 查询订单","query_user: 查询用户","query_product: 查询商品","create_order: 创建订单","create_ticket: 创建工单","update_order: 更新订单","delete_order: 删除订单",...]# ✅ 分层分类工具列表TOOLS_HIERARCHICAL=""" ## 可用工具 ### 📚 知识检索类 - search_knowledge_base: 搜索产品文档和操作指南 适用: 产品功能、使用方法、配置说明 不适用: 订单/用户/交易数据(请用数据查询类工具) - search_faq: 搜索常见问题 适用: 高频问题、简单问答 不适用: 深度技术问题 ### 📊 数据查询类 - query_order: 查询订单信息(状态/金额/物流) - query_user: 查询用户信息(等级/权限/历史) - query_product: 查询商品信息(库存/价格/规格) ### ✏️ 操作执行类 - create_ticket: 创建客服工单(需确认) - update_order: 修改订单信息(仅限备注/地址,需确认) ### ⚠️ 重要规则 1. 先确定问题属于哪个类别 2. 在对应类别中选择工具 3. 不同类别的工具不应混淆使用 4. 不确定时优先使用知识检索类 """

4. 策略二:精确描述"何时用/何时不用"

defbuild_precise_tool_description(tool_def:dict)->str:"""构建精确的工具描述"""returnf""" ###{tool_def['name']}**功能**:{tool_def.get('function_desc','')}**✅ 应该使用的场景(WHEN)**:{chr(10).join(f' -{s}'forsintool_def.get('when_to_use',[]))}**❌ 不应使用的场景(WHEN NOT)**:{chr(10).join(f' -{s}'forsintool_def.get('when_not_to_use',[]))}**🔍 与相似工具的区分**:{chr(10).join(f' -{s}'forsintool_def.get('differentiation',[]))}**📋 参数**:{chr(10).join(f' -{p["name"]}:{p["description"]}'forpintool_def['parameters'])}"""# 实际使用示例PRECISE_TOOLS={"search_knowledge_base":{"function_desc":"在内部产品知识库中搜索","when_to_use":["用户询问产品功能、使用方法","用户需要操作指南或配置说明","用户问题以"怎么/如何/什么"开头且属于产品范围",],"when_not_to_use":["查询订单状态 → 请用 query_order","查询库存价格 → 请用 query_product","查询用户信息 → 请用 query_user","执行操作(创建/修改/删除)→ 请用操作执行类工具",],"differentiation":["vs search_faq: search_knowledge_base 用于深度产品文档,search_faq 用于简短问答","vs query_product: search_knowledge_base 查说明书,query_product 查实时数据",],"parameters":[{"name":"query","description":"搜索关键词,建议用名词短语而非完整句子"},{"name":"category","description":"限定范围: product/faq/guide,不填则全搜"},{"name":"top_k","description":"返回数量,默认5,范围1-10"},]}}

5. 策略三:工具选择预判注入

不让 LLM 从 30 个工具里选,而是先缩小范围:

classToolPreselector:"""工具预选器——缩小候选范围"""def__init__(self,llm):self.llm=llm self.tool_groups={"knowledge":["search_kb","search_faq","search_docs"],"data_query":["query_order","query_user","query_product"],"operation":["create_ticket","update_order","send_notification"],"analysis":["generate_report","compare_data","summarize"],}defcategorize_intent(self,user_input:str)->list:"""先判断意图类别,再给候选工具"""prompt=f"""分析以下用户意图,归类到以下一组或多组: - knowledge: 查询知识/文档/FAQ - data_query: 查询业务数据(订单/用户/商品) - operation: 执行操作(创建/修改/发送) - analysis: 分析/对比/总结 用户输入: "{user_input}" 输出 JSON: {{"categories": ["knowledge"], "confidence": 0.9, "reasoning": "..."}}"""response=self.llm.chat(prompt)result=json.loads(JSONFixer.extract_and_fix(response))returnresult["categories"]defget_candidate_tools(self,user_input:str,all_tools:dict)->dict:"""根据意图获取候选工具"""categories=self.categorize_intent(user_input)candidate_names=[]forcatincategories:candidate_names.extend(self.tool_groups.get(cat,[]))# 始终保留一个"兜底"通用工具candidate_names.append("search_knowledge_base")candidates={name:specforname,specinall_tools.items()ifnameincandidate_names}returncandidates# 在 Agent 中使用classToolAwareAgent:defrun(self,user_input):# 1. 预选工具candidates=self.preselector.get_candidate_tools(user_input,self.all_tools)# 2. 只用候选工具构建 Prompt(而不是全部 30 个)system_prompt=self._build_prompt_with_candidates(candidates)# 3. LLM 在 3-6 个工具中选择,不容易出错response=self.llm.chat(system_prompt,user_input)returnresponse

6. 策略四:约束性输出格式

让 LLM 在选择工具前先做"思考":

CONSTRAINED_OUTPUT_PROMPT="""在选择工具之前,你必须完成以下分析步骤。 === 分析框架 === 步骤1: 理解用户的真实需求 步骤2: 排除明显不相关的工具类别 步骤3: 在剩余候选中选择最合适的工具 === 输出格式 === 请在调用任何工具之前,先以如下格式输出分析: <analysis> 用户需求: [一句话概括] 意图类别: [knowledge/data_query/operation/analysis] 排除工具及原因: [排除的类别,为什么] 候选工具: [候选工具名列表] 选择理由: [为什么选这个工具] </analysis> 然后再调用工具。 注意: 如果分析后发现不需要工具,直接用自然语言回答。"""# 效果: 加上这个约束后,工具选择准确率从 72% 提升到 88%

7. 策略五:动态工具集剪枝

classDynamicToolFilter:"""根据历史对话动态过滤不需要的工具"""def__init__(self):self.session_state={}# 会话级别的状态deffilter_tools(self,session_id:str,all_tools:dict,messages:list)->dict:"""根据会话上下文过滤工具"""available=dict(all_tools)# 从全部工具开始# 规则1: 如果用户在纯聊天,不需要操作类工具ifself._is_chitchat(messages):fornameinlist(available.keys()):ifavailable[name].category=="operation":delavailable[name]# 规则2: 如果已经创建了工单,不再需要 create_ticketifself.session_state.get(session_id,{}).get("ticket_created"):available.pop("create_ticket",None)# 规则3: 如果用户没有提供订单号/user_id,不需要详细查询工具last_user_msg=self._last_user_message(messages)ifnotre.search(r'ORD-\d{4}-\d{5}|\d{8}',last_user_msg):# 没有订单号或用户ID,可能需要先查用户available={k:vfork,vinavailable.items()ifv.category!="order_detail"}# 规则4: 根据已使用的工具,提示互补工具used_tools=set()formsginmessages:ifmsg.get("role")=="tool":used_tools.add(msg.get("name"))if"query_order"inused_toolsand"query_logistics"inavailable:# 标注这个工具现在特别推荐available["query_logistics"].boost=Truereturnavailable

8. 策略六:工具选择后验证

classToolSelectionValidator:"""工具选择后验证"""defvalidate(self,selected_tool:str,user_input:str,conversation_context:dict)->dict:""" 验证工具选择是否合理 Returns: {"valid": bool, "warnings": [], "suggestion": Optional[str]} """warnings=[]# 规则1: 知识库查询 vs 数据查询混淆检测knowledge_tools={"search_knowledge_base","search_faq","search_docs"}data_tools={"query_order","query_user","query_product"}ifselected_toolinknowledge_tools:# 检查用户是否在问实时数据data_patterns=["订单","我的","状态","余额","积分","物流"]ifany(pinuser_inputforpindata_patterns):order_pattern=re.search(r'ORD-\d{4}-\d{5}',user_input)iforder_pattern:warnings.append({"type":"wrong_category","message":f"用户提供了订单号{order_pattern.group()},"f"应使用 query_order 而非{selected_tool}","suggestion":"query_order"})ifselected_toolindata_tools:# 检查是否在问概念性问题concept_patterns=["什么是","定义","怎么用","如何配置"]ifany(pinuser_inputforpinconcept_patterns):warnings.append({"type":"wrong_category","message":f"用户在问概念性问题,"f"应使用 search_knowledge_base 而非{selected_tool}","suggestion":"search_knowledge_base"})# 规则2: 操作工具确认检查operation_tools={"create_ticket","update_order","delete_order"}ifselected_toolinoperation_tools:# 检查用户是否明确要求执行操作action_words=["帮我创建","帮我修改","帮我删除","我要","申请"]ifnotany(winuser_inputforwinaction_words):warnings.append({"type":"implicit_operation","message":f"用户没有明确要求执行操作,"f"请先确认是否需要创建",})return{"valid":len(warnings)==0,"warnings":warnings,}

9. 效果对比

优化策略累计准确率提升
基准 (扁平工具列表)65%-
+ 分层分类74%+9%
+ 精确使用描述79%+5%
+ 工具预选88%+9%
+ 约束输出91%+3%
+ 后验证93%+2%

推荐组合:分层分类 + 精确描述 + 工具预选(覆盖 85%+ 场景)。其余作为兜底。

一句话总结: 不要期待 LLM 在 30 个工具中选对——先用分类把候选缩小到 3-6 个,再让 LLM 精确选择。


需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询