让大模型“动起来”:从理论到实践的LLM工具调用全解析
本文详细解析了如何通过工具调用(Tool Calling)赋予大语言模型(如DeepSeek)实时获取外部信息的能力,以“查询天气”为例,完整展示了从定义工具、调用API到多轮对话生成最终回答的全流程,揭示了LLM从被动应答向主动行动演进的技术路径与应用潜力。
引言
在人工智能飞速发展的今天,大语言模型(LLM)已经不再是单纯的文本生成器。它们正在进化为具备主动行动能力的智能体——能够理解任务、调用外部工具、获取实时信息,并基于这些信息做出更准确的决策。本文将结合一段完整的代码示例,深入剖析如何让LLM通过调用外部API来实现真正的“思考与行动”,从而构建一个能真正解决实际问题的AI系统。
一、背景知识铺垫:为什么需要让LLM“用工具”?
传统的LLM虽然拥有强大的语言理解和生成能力,但它存在一个根本性局限:
它只能基于训练数据中的信息进行推理和回答。
这意味着:
- 它无法知道最新的新闻事件;
- 它不知道今天的天气状况;
- 它不能查询实时股价或航班状态。
因此,为了让LLM具备实时感知世界的能力,我们需要让它能够“使用工具”——比如调用天气API、股票接口等。这正是我们今天要讲解的核心技术:LLM工具调用(Tool Calling)。
二、代码详解:一步步构建“会查天气的AI助手”
我们将逐行分析以下Jupyter Notebook中的代码,确保每一个细节都清晰明了。
print("LLM 调用 tools, 让 LLM '身外之物'")
第一步:环境准备 —— 安装依赖包
# npm install
# 先安装 requests
pip install requests
pip install openai
解释:
requests是Python中用于发送HTTP请求的库,用来与外部API通信。openai是OpenAI官方提供的SDK,支持与ChatGPT等模型交互。- 这里虽然使用的是DeepSeek模型,但其接口兼容OpenAI格式,所以可以使用相同的客户端。
第二步:定义工具函数 —— 获取天气信息
import requests
def get_weather(location: str) -> str:
url = "https://api.seniverse.com/v3/weather/now.json"
params = {
"key": "SaVS0t7eYbapka9iv",
"location": location,
"language": "zh-Hans"
}
try:
resp = requests.get(url, params=params, timeout=10)
data = resp.json()
print(data)
if "results" in data:
r = data["results"][0]
city = r["location"]["name"]
now = r["now"]
text = now["text"]
temp = now["temperature"]
return f"{city}当前天气: {text}, 气温 {temp}度"
else:
return "查询失败"
except Exception as e:
return f"异常: {e}"
详细解析:
函数签名:
get_weather(location: str) -> str
- 接收一个城市名称字符串作为输入;
- 返回一个描述天气情况的字符串。
API地址:
https://api.seniverse.com/v3/weather/now.json
- 使用的是心知天气的免费API。
- 需要提供API Key(已加密处理)。
参数说明:
"key":你的API密钥;"location":目标城市名(如"北京");"language":返回语言设置为简体中文。请求逻辑:
- 使用
requests.get()发起GET请求;- 设置超时时间为10秒,防止卡死;
- 将响应解析为JSON对象;
- 提取关键字段:城市名、天气描述、温度;
- 返回格式化后的结果。
异常处理:
- 如果网络出错或API无响应,捕获异常并返回错误提示。
测试调用:
print(get_weather("杭州"))输出示例:
{'results': [{'location': {'id': 'HSFXR95RZD21', 'name': '杭州', 'country': 'CN', 'path': '杭州,杭州,江西,中国', ...}, 'now': {'text': '晴', 'temperature': '12'}, ...}] 杭州当前天气: 晴, 气温 12度
第三步:初始化OpenAI客户端
from openai import OpenAI
client = OpenAI(
api_key="sk-f258376fcd7662418c578dd236dcbc64",
base_url="https://api.deepseek.com/v1"
)
详细解析:
- 使用
OpenAI类创建客户端实例;api_key:DeepSeek API的密钥(注意:此为示例密钥,请勿直接使用);base_url:指向DeepSeek的API地址,而非OpenAI官方地址;- 这表明我们正在使用兼容OpenAI协议的第三方模型服务,即DeepSeek。
第四步:定义工具(Tools) —— 告诉LLM我能做什么
# OpenAI 接口工具定义
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "获取指定城市的当前天气。",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "城市名称,如 北京"
}
},
"required": ["location"]
}
}
}
]
详细解析:
tools是一个列表,每个元素是一个工具定义;- 每个工具必须包含:
"type": "function":表示这是一个可调用的函数;"function":具体函数信息;
"name":函数名,必须与实际函数一致;"description":对这个工具功能的自然语言描述;"parameters":参数结构,以JSON Schema形式定义;
"properties":参数的具体属性;
"location":类型为字符串,描述为“城市名称”;"required":必填参数列表,这里只有location是必需的。⚠️ 注意:
- 这个
tools配置会被传给LLM,告诉它:“我有一个叫get_weather的功能,你可以用它来查天气。”- LLM会根据用户的问题判断是否需要调用该工具。
第五步:发起多轮对话 + 工具调用流程
import json
messages = [{"role": "user", "content": "北京天气怎么样?"}]
response = client.chat.completions.create(
model="deepseek-reasoner",
messages=messages,
tools=tools,
tool_choice="auto",
temperature=0.3
)
详细解析:
messages:对话历史,初始为用户提问;model="deepseek-reasoner":使用DeepSeek的推理模型(更强的逻辑能力);tools=tools:传递前面定义的工具列表;tool_choice="auto":让模型自动决定是否调用工具;temperature=0.3:控制输出随机性,较低值保证稳定性。
第六步:处理工具调用结果
response_message = response.choices[0].message
# 参考文档
print(response_message)
# tool_calls ChatCompletionMessageFunctionToolCall
messages.append(response_message)
if response_message.tool_calls:
for tool_call in response_message.tool_calls:
function_name = tool_call.function.name
# json 字符串变成json 对象
function_args = json.loads(tool_call.function.arguments)
if function_name == "get_weather":
function_response = get_weather(function_args["location"])
else:
function_response = "未知工具"
messages.append({
"tool_call_id": tool_call.id,
"role": "tool",
"name": function_name,
"content": function_response
})
else:
print(response_message.content)
详细解析:
获取回复消息:
response_message = response.choices[0].message- 得到LLM返回的消息对象。
检查是否有工具调用:
if response_message.tool_calls::如果模型决定调用工具,则进入分支;tool_call.function.name:获取被调用的函数名;tool_call.function.arguments:获取传入的参数(通常是JSON字符串);- 使用
json.loads()将其转换为字典;执行对应函数:
- 判断函数名为
get_weather,则调用之前定义的get_weather()函数;- 传入参数
location;- 执行后得到真实天气数据;
构造工具响应消息:
- 向
messages列表追加一条tool角色的消息;- 包含:
tool_call_id:工具调用ID;role: "tool";name: 函数名;content: 实际执行结果(如“北京当前天气: 晴, 气温 12度”);如果没有工具调用:
- 直接打印LLM的纯文本回复。
第七步:最终回复 —— 结合工具结果生成完整答案
final_response = client.chat.completions.create(
model="deepseek-reasoner",
messages=messages,
temperature=0.3
)
print(final_response.choices[0].message.content)
详细解析:
- 此时
messages中已经包含了:
- 用户提问;
- 模型要求调用工具;
- 工具返回的真实天气数据;
- 再次调用LLM,让它基于完整上下文生成最终回答;
- 最终输出可能是:
北京当前天气: 晴, 气温 12度 这是一个比较舒适的天气,适合户外活动。不过北京的天气变化较快,建议您: - 早晚温差可能较大,注意适时增减衣物 - 如果长时间在户外,可以适当防晒 - 关注最新天气预报,了解天气变化 需要我为您查询更详细的天气信息(如未来几天的预报)吗?
三、关键技术点总结
| 技术点 | 作用 |
|---|---|
| 工具定义(Tools) | 告诉LLM你能做什么,以及怎么用 |
| tool_choice="auto" | 让模型自主判断是否需要调用工具 |
| tool_calls | LLM返回的工具调用指令 |
| function arguments | 传给工具的参数,需正确解析 |
| multi-turn conversation | 多轮对话机制,先调用工具,再生成最终回复 |
四、背后的AI原理:LLM如何“学会使用工具”?
现代大模型之所以能调用工具,是因为它经过了专门的训练:
-
在训练数据中学习“工具使用模式”:
- 模型看到大量类似“我需要查询天气 → 调用get_weather(北京)”的样本;
- 学习到“当用户问天气时,应该调用某个函数”。
-
通过函数签名理解参数含义:
- 模型能理解
location是城市名,必须是字符串; - 知道哪些参数是必需的。
- 模型能理解
-
结合上下文推理决策:
- 即使没有明确说“请查天气”,只要语义相关,模型也能触发工具调用。
五、扩展应用方向
一旦掌握了工具调用,就可以构建更多智能场景:
| 场景 | 工具示例 |
|---|---|
| 智能客服 | 查询订单状态、退款进度 |
| 金融助手 | 获取股票行情、基金净值 |
| 旅游推荐 | 查景点开放时间、天气、交通 |
| 医疗咨询 | 查询药品说明书、医院挂号信息 |
只需添加新的工具函数和对应的API,就能不断扩展AI的能力边界。
六、结语:从“被动回答”到“主动行动”
我们今天所展示的代码,只是一个起点。它揭示了一个深刻的趋势:
未来的AI不再只是“会说话”的机器人,而是能“动手做事”的智能代理。
通过将LLM与外部工具结合,我们可以打造真正有用的AI助手——它不仅能理解你的话,还能为你去查天气、订机票、写报告……
正如你看到的,这一切并不复杂。只需要:
- 定义好工具;
- 给模型提供调用权限;
- 让它自己决定何时使用。
剩下的,就交给AI去完成吧!
附录:运行建议
- 使用自己的API Key替换示例中的密钥;
- 替换
get_weather为其他API(如天气、股票、翻译等); - 在本地或云上部署Jupyter Notebook运行;
- 推荐使用魔搭(ModelScope)平台快速部署和微调模型。
火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)