模型判断是否调用工具,核心在于其意图识别与**函数调用(Function Calling)**能力。这个过程通常由模型根据用户查询、可用工具描述以及系统指令,自主决定是直接回答还是生成一个结构化的工具调用请求。
一、核心判断逻辑与流程
一个典型的工具调用决策流程如下:
graph TD A用户输入 --> B构造包含工具描述的Prompt B --> C大模型推理 C --> D{模型输出解析} D -- 包含结构化工具调用 --> E提取工具名与参数 D -- 纯自然语言 --> F直接返回答案 E --> G执行对应工具函数 G --> H将工具执行结果返回给模型 H --> I模型整合结果生成最终回复 F --> I
二、关键技术实现方式
- 基于提示工程(Prompt Engineering)的自主判断这是最基础的方式,通过精心设计的系统提示词(System Prompt)引导模型做出判断。
python
# 示例:通过Prompt引导模型判断def build_tool_decision_prompt(user_query: str, tools_list: list) -> str:
"""
构建引导模型判断是否调用工具的Prompt """
tools_description = "
".join([f"- {t['name']}: {t['description']}" for t in tools_list])
prompt = f"""你是一个AI助手,可以调用工具来解决问题。请根据用户问题决定是否需要调用工具。
你可以使用的工具:
{tools_description}
**决策规则:**
1. 如果用户问题涉及实时数据(如天气、股价)、需要执行具体操作(如计算、文件读写)或查询外部信息,请调用工具。
2. 如果是一般性知识问答、聊天或无需外部工具即可回答的问题,请直接回答。
**输出格式:**
- 如果需要调用工具,请严格按此JSON格式回复:
{{"action": "call_tool", "tool": "工具名", "parameters": {{"参数1": "值1"}}}}
- 如果直接回答,请按此格式回复:
{{"action": "direct_answer", "content": "你的回答内容"}}
用户问题:{user_query}
"""
return prompt
# 使用示例
available_tools = [
{"name": "get_weather", "description": "获取指定城市的当前天气"},
{"name": "calculate", "description": "执行数学计算"},
{"name": "search_web", "description": "在互联网上搜索信息"}
]
user_question = "北京今天天气怎么样?"
prompt = build_tool_decision_prompt(user_question, available_tools)
# 将prompt发送给大模型并获取响应
- 使用原生函数调用(Function Calling)API
主流大模型API(如OpenAI、DeepSeek)提供了专用的函数调用接口,模型会输出结构化的函数调用请求。
python
import openai
import json
# 定义可供调用的工具(函数)
tools = [
{
"type": "function",
"function": {
"name": "get_current_weather",
"description": "获取指定城市的当前天气",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "城市名称,例如:北京、上海"
}
},
"required": ["location"]
}
}
}
]
def chat_with_function_calling(user_input: str):
"""
使用OpenAI格式的Function Calling API """
client = openai.OpenAI(api_key="your-api-key")
# 第一次调用:模型判断是否需要调用函数 response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=[{"role": "user", "content": user_input}],
tools=tools, # 关键:提供工具定义 tool_choice="auto", # 让模型自主决定是否调用
)
message = response.choices[0].message
# 判断模型是否决定调用工具 if message.tool_calls: # 如果tool_calls不为空,表示需要调用工具
print("模型决定调用工具")
# 提取工具调用信息
tool_call = message.tool_calls[0]
tool_name = tool_call.function.name
tool_args = json.loads(tool_call.function.arguments)
print(f"工具名: {tool_name}")
print(f"参数: {tool_args}")
# 执行对应的工具函数 if tool_name == "get_current_weather":
weather_result = get_weather_from_api(tool_args["location"])
# 将工具执行结果返回给模型进行总结 second_response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=[
{"role": "user", "content": user_input},
message, # 包含工具调用的消息
{
"role": "tool",
"content": weather_result,
"tool_call_id": tool_call.id
}
]
)
final_answer = second_response.choices[0].message.content
return final_answer else:
# 模型直接回答 print("模型选择直接回答")
return message.content
# 测试不同场景
print("场景1 - 需要工具调用:")
result1 = chat_with_function_calling("北京今天气温多少度?")
print(f"回答: {result1}
")
print("场景2 - 直接回答:")
result2 = chat_with_function_calling("请介绍一下人工智能的历史")
print(f"回答: {result2}")
- 基于ReAct(Reasoning + Acting)框架的链式思考
让模型通过"思考-行动-观察"的循环来决策,更适合复杂任务。
python
def react_style_decision(user_query: str, max_steps: int = 5):
"""
基于ReAct框架的工具调用决策 """
history = []
for step in range(max_steps):
# 构建包含思考过程的Prompt
prompt = f"""你正在解决一个问题。这是你的思考历史:
{format_history(history)}
当前问题:{user_query}
请按以下格式回应:
Thought: [你的思考,分析当前是否需要工具以及需要什么工具]
Action: [如果需要工具,格式为"工具名(参数)";如果不需要,格式为"Answer:你的回答"]
"""
# 获取模型响应
response = get_llm_response(prompt)
thought, action = parse_react_response(response)
history.append(f"Step {step}: Thought: {thought}")
if action.startswith("Answer:"):
# 模型决定直接回答
return action.replace("Answer:", "").strip()
else:
# 模型决定调用工具
tool_name, params = parse_action_string(action)
result = execute_tool(tool_name, params)
history.append(f"Step {step}: Observation: {result}")
return "达到最大步骤数,任务未完成。"
三、模型判断的依据与策略
| 判断依据 | 倾向于调用工具 | 倾向于直接回答 |
|---|---|---|
| 信息时效性 | 需要实时/最新数据(天气、股价、新闻) | 通用知识、历史信息、概念解释 |
| 操作类型 | 需要执行计算、读写文件、调用API | 纯文本生成、分析、总结 |
| 信息范围 | 超出模型训练数据或知识截止日期 | 在模型知识范围内 |
| 任务复杂度 | 需要多步骤处理或外部验证 | 简单的一步回答 |
| 用户意图 | 明确要求执行操作("打开文件"、"搜索") | 聊天、咨询、创意写作 |
四、实际应用中的关键考虑
- 置信度阈值:模型可能对是否调用工具存在不确定性,可以设置置信度阈值,低于阈值时要求用户澄清。
- 工具描述质量:工具的名称、描述和参数定义必须清晰准确,直接影响模型判断的准确性。
- 多工具选择 :当多个工具都相关时,模型需要选择最合适的一个。可以通过在Prompt中提供工具选择逻辑或使用专用API参数(如
tool_choice)来引导。 - 错误处理:模型可能生成无效的工具调用(如参数类型错误),需要在执行前进行验证,并提供错误反馈机制让模型重新决策。
python
def safe_tool_execution(tool_call, available_tools):
"""
安全的工具执行与错误处理
"""
try:
# 验证工具是否存在
if tool_call["tool"] not in available_tools:
return f"错误:工具 '{tool_call['tool']}' 不存在"
# 验证参数是否符合schema tool_schema = available_tools[tool_call["tool"]]["parameters"]
if not validate_parameters(tool_call["parameters"], tool_schema):
return "错误:参数格式不正确"
# 执行工具
result = execute_tool_safely(tool_call["tool"], tool_call["parameters"])
return result
except Exception as e:
return f"工具执行出错:{str(e)}"
五、在LangChain/LangGraph中的实现
使用AI框架可以简化工具调用判断的逻辑:
python
from langchain.agents import initialize_agent, Tool
from langchain_openai import ChatOpenAI
# 定义工具
tools = [
Tool(
name="Weather",
func=get_weather,
description="获取城市天气,输入应为城市名称"
),
Tool(
name="Calculator",
func=calculate,
description="执行数学计算,输入应为数学表达式"
)
]
# 初始化Agent,模型会自动判断是否及如何调用工具
llm = ChatOpenAI(model="gpt-3.5-turbo")
agent = initialize_agent(
tools,
llm, agent="zero-shot-react-description", #使用ReAct策略 verbose=True
)
# 运行模型会自动判断
result = agent.run("北京的温度比上海高5度,上海现在25度,北京多少度?")
# 模型会:1) 识别需要计算 2) 调用Calculator工具 3) 返回结果
总结 :模型通过分析用户查询的意图、对比自身能力与可用工具的功能,并遵循系统指令中定义的决策规则,来判断是否需要调用工具。现代大模型通过函数调用API 、结构化输出 和智能体框架的支持,能够相当准确地做出这一判断,这是构建实用AI代理(Agent)系统的关键技术基础。