LLM 自动选择多工具底层完整原理
LLM 自动选择多工具底层完整原理一、核心前提工具元数据全部传给 LLM执行llm.bind_tools([calculator, search, weather])时LangChain 会自动做两件事读取每个工具tool函数的文档字符串、参数名、参数类型、参数描述把所有工具转换成标准 JSON Schema 工具列表塞进发给 LLM 的系统提示附加字段发给大模型的工具列表简化示例json[ { name: calculator_tool, description: 计算数学四则表达式支持abs、round求和等数值运算, parameters: { type: object, properties: { expression: {type: string, description: 纯数学表达式如 1020*5} }, required: [expression] } }, { name: get_weather, description: 查询指定城市实时天气, parameters: {city: {type: string, description: 城市名称}} }, { name: web_search, description: 联网搜索最新实时资讯、百科、事件静态知识不知道时调用 } ]LLM 会同时看到所有工具名称、功能描述、入参要求依靠自身语义理解做匹配判断。二、LLM 选择工具的 4 层判断逻辑从上到下执行1. 语义意图匹配第一层核心判断模型对比用户提问和每个工具description的用途描述做相似度匹配用户问123乘以45等于多少→ 和 calculator 描述「数学计算」高度匹配优先选计算器用户问北京今天多少度→ 和 weather「查询城市天气」匹配选天气工具用户问2026最新GDP数据→ 静态知识库过时匹配 search「联网查实时信息」2. 关键词特征辅助筛选工具描述里的专属关键词会强化模型判断calculatorcalculate、sum、math、expression、加减乘除weatherweather、temperature、气温、下雨、城市search最新、实时、新闻、查询、百科、现在3. 参数校验能否提取对应入参过滤不匹配工具模型不仅看用途还会判断能不能从用户问题里提取出工具需要的参数提问上海天气weather 需要city参数能提取上海→ 可用 calculator 需要expression提取不出数学式子 → 排除提问50除以2calculator 可提取表达式50 / 2weather 需要城市问题无城市 → 直接放弃天气工具4. 优先级与多工具同时调用单一意图只选 1 个工具深圳明天天气→ 仅调用 get_weather复合意图同时调用多个工具模型可输出多条 tool_call 示例提问深圳今天气温多少再算一下250*8LLM 会生成两个 tool_call调用 get_weather (city深圳)调用 calculator_tool (expression250 * 8)不需要任何工具问题纯常识、主观问答、无需计算 / 联网猫喜欢吃什么模型直接输出文本tool_calls []三、完整执行链路LangGraph ReAct 循环用户输入问题agent节点调用绑定全部工具的llm_with_toolsLLM 读取全部工具 Schema语义匹配生成 AIMessage包含tool_calls数组工具名 提取好的参数路由函数should_continue判断存在 tool_calls → 进入ToolNodeToolNode 自动分发执行对应工具根据tool_call[name]匹配函数列表里的工具传入参数执行多个 tool_call 会循环依次执行全部生成 ToolMessage工具结果放回 messages 列表回到 agent 节点LLM 结合工具返回数据整理自然语言最终回答无新 tool_call 则结束四、人为控制 LLM 工具选择的优化技巧1. 写清晰、差异化的工具 docstring最重要避免描述模糊每个工具写明适用场景、不适用场景减少模型选错python运行# 优秀示例 tool def calculator_tool(expression: str) - str: 仅用于数学数值计算。不查天气、不查新闻。 处理加减乘除、绝对值、求和等数字运算。 参数纯数字运算表达式例如 100 - 20 * 3 2. 工具命名语义化工具名带上业务标识模型更容易识别calculator_tool/weather_query/general_web_search不建议命名func1tool_a无意义名称。3. 区分工具适用边界减少混淆比如搜索和计算器功能完全隔离描述不要重叠 如果两个工具用途相近比如本地知识库检索 联网搜索在描述里明确区分local_rag查内部文档、历史资料web_search查互联网实时新鲜信息4. system prompt 补充工具选择规则给 LLM 额外约束强制选择逻辑python运行system_prompt 你拥有3个工具使用规则 1. 所有数字计算、求和、四则运算必须使用 calculator_tool禁止自己口算 2. 查询任意城市温度、降雨使用 get_weather 3. 超过2025年的实时数据、网络新闻使用 web_search 4. 普通常识问题不需要调用任何工具直接回答。 llm_with_tools llm.bind_tools(tools).with_messages([SystemMessage(contentsystem_prompt)])五、常见选错工具的原因工具文档描述太简短、模糊模型分不清用途多个工具功能高度重叠无明确边界说明temperature 0随机性导致模型乱选工具用户提问语义模糊同时包含多个领域关键词缺少系统提示词约束工具使用规则六、多工具完整可运行示例python运行from langchain.tools import tool from langgraph.prebuilt import ToolNode, MessagesState from langgraph.graph import StateGraph, START, END from langchain_openai import ChatOpenAI # 工具1计算器 tool def calculator_tool(expression: str) - str: 仅处理数学四则运算、数值计算不处理天气/网络查询 allowed {abs:abs, round:round} try: res eval(expression, {__builtins__:{}}, allowed) return str(res) except Exception as e: return str(e) # 工具2天气 tool def get_weather(city: str) - str: 查询指定城市实时天气仅接收城市名称 return f{city} 今日 27℃ 多云 # 工具3联网搜索 tool def web_search(query: str) - str: 查询互联网实时资讯、最新数据模型静态知识不足时使用 return f搜索结果{query} 的相关实时信息 # 注册全部工具 tools [calculator_tool, get_weather, web_search] tool_node ToolNode(tools) llm ChatOpenAI(modelgpt-4o-mini, temperature0) llm_with_tools llm.bind_tools(tools) def agent(state: MessagesState): return {messages: [llm_with_tools.invoke(state[messages])]} def route(state): last_msg state[messages][-1] if last_msg.tool_calls: return tools return END builder StateGraph(MessagesState) builder.add_node(agent, agent) builder.add_node(tools, tool_node) builder.add_edge(START, agent) builder.add_conditional_edges(agent, route) builder.add_edge(tools, agent) graph builder.compile() # 测试复合提问自动调用两个工具 res graph.invoke({messages: [(human, 武汉今天天气怎么样再计算 36 * 15)]}) print(res[messages][-1].content)运行后模型会自动识别同时需要天气 计算器并行生成两条工具调用指令。