通义千问2.5工具调用全攻略:Function Calling实战演示
本文介绍了基于星图GPU平台自动化部署通义千问2.5-7B-Instruct镜像的实践方法,重点演示了其在Function Calling场景下的应用。通过该平台可快速搭建智能助手系统,实现天气查询、订单状态检索等任务的模型微调与AI应用开发,充分发挥其在轻量级Agent构建中的高效性与稳定性。
通义千问2.5工具调用全攻略:Function Calling实战演示
引言
在构建智能代理(Agent)系统时,大语言模型(LLM)不仅需要理解用户意图,还需具备与外部世界交互的能力。Function Calling(函数调用)正是实现这一能力的核心机制——它允许模型根据上下文判断是否需要调用预定义的工具,并以结构化方式输出调用参数。
通义千问2.5-7B-Instruct 模型原生支持 Function Calling 和 JSON 格式强制输出,这使其成为轻量级 Agent 构建的理想选择。本文将围绕该模型,深入讲解 Function Calling 的工作原理、配置方法和工程实践,通过完整代码示例展示如何实现天气查询、数据库检索、代码执行等典型场景的工具集成。
1. Function Calling 技术背景与核心价值
1.1 为何需要 Function Calling?
尽管大模型具备强大的语言理解和生成能力,但其知识受限于训练数据,且无法直接访问实时信息或执行操作。例如:
- “今天北京天气怎么样?” → 需要调用天气 API
- “帮我查一下订单 ID 为 10086 的状态” → 需要连接数据库
- “画一个正弦波图像” → 需要运行 Python 代码
传统做法是让模型自由生成文本描述请求,再由后端解析,这种方式存在格式不稳定、易出错、难以自动化等问题。
Function Calling 提供了一种标准化解决方案:模型不再“描述”动作,而是“声明”要调用的函数及其参数,输出为结构化的 JSON 对象,便于程序自动解析和执行。
1.2 通义千问2.5的Function Calling优势
相比其他7B级别模型,通义千问2.5-7B-Instruct 在工具调用方面具有以下显著优势:
- 原生支持 JSON 输出模式:可通过提示词控制模型输出严格符合 Schema 的 JSON 结构。
- 高精度参数提取:在 HumanEval 和 ToolBench 基准测试中表现优异,能准确识别多参数函数调用。
- 长上下文支持(128K):可在复杂对话历史中保持对工具调用状态的记忆。
- 商用许可开放:可安全用于企业级应用开发。
这些特性使得 Qwen2.5-7B 成为目前最适合部署本地化 Agent 系统的中等规模模型之一。
2. Function Calling 工作机制详解
2.1 调用流程总览
Function Calling 的典型执行流程如下:
- 定义工具集:预先注册一组可用函数及其 JSON Schema 描述
- 构造提示词:将工具描述注入 prompt,引导模型理解何时调用
- 模型推理:模型分析用户输入,决定是否调用函数并生成 JSON 参数
- 解析与执行:系统解析 JSON 并调用对应函数
- 结果反馈:将函数返回结果重新输入模型,生成最终回复
整个过程形成一个“感知→决策→行动→反馈”的闭环。
2.2 函数描述的JSON Schema设计
为了让模型正确理解函数用途和参数要求,必须使用标准 JSON Schema 进行描述。以下是一个天气查询函数的定义示例:
{
"name": "get_weather",
"description": "获取指定城市的当前天气信息",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名称,如'北京'、'上海'"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "温度单位,默认为celsius"
}
},
"required": ["city"]
}
}
关键字段说明: - name:函数名,需与实际代码一致 - description:功能描述,影响模型调用判断 - parameters:参数结构定义,支持嵌套对象 - required:必填参数列表
模型会基于此描述自动生成类似以下的调用请求:
{
"function": "get_weather",
"arguments": {
"city": "杭州",
"unit": "celsius"
}
}
3. 实战项目:基于Qwen2.5-7B的智能助手
本节将演示如何使用 vLLM + FastAPI 搭建一个支持 Function Calling 的智能助手服务。
3.1 环境准备
确保已安装以下依赖库:
pip install vllm fastapi uvicorn pydantic requests
启动 vLLM 推理服务器(假设模型已下载至本地路径):
python -m vllm.entrypoints.api_server \
--host 0.0.0.0 \
--port 8000 \
--model /models/Qwen2.5-7B-Instruct \
--tensor-parallel-size 1 \
--dtype half \
--enable-auto-tool-call
注意:
--enable-auto-tool-call是启用函数调用的关键参数
3.2 定义可用工具集
创建 tools.py 文件,定义三个常用工具:
import requests
import subprocess
import sqlite3
from typing import Dict, Any
def get_weather(city: str, unit: str = "celsius") -> Dict[str, Any]:
"""获取城市天气"""
try:
url = f"https://wttr.in/{city}?format=j1"
response = requests.get(url, timeout=5)
data = response.json()
temp_c = data['current_condition'][0]['temp_C']
desc = data['current_condition'][0]['weatherDesc'][0]['value']
return {
"city": city,
"temperature": float(temp_c),
"unit": "°C",
"description": desc,
"success": True
}
except Exception as e:
return {"error": str(e), "success": False}
def execute_python_code(code: str) -> Dict[str, Any]:
"""执行Python代码并返回结果"""
try:
result = subprocess.run(
['python', '-c', code],
capture_output=True,
text=True,
timeout=10
)
return {
"stdout": result.stdout,
"stderr": result.stderr,
"returncode": result.returncode,
"success": result.returncode == 0
}
except Exception as e:
return {"error": str(e), "success": False}
def query_order_status(order_id: int) -> Dict[str, Any]:
"""模拟查询订单状态"""
# 模拟数据库
orders = {
10086: {"status": "已发货", "tracking_number": "SF123456789CN"},
10010: {"status": "待付款", "expires_in_hours": 24}
}
order = orders.get(order_id)
if order:
return {"order_id": order_id, "info": order, "found": True}
else:
return {"order_id": order_id, "error": "订单不存在", "found": False}
3.3 构造函数调用提示词
向模型发送请求时,需在 prompt 中包含工具描述。以下是构造请求体的 Python 示例:
import requests
def build_tool_call_request(user_input: str):
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "获取指定城市的当前天气信息",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "城市名称"},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "温度单位"
}
},
"required": ["city"]
}
}
},
{
"type": "function",
"function": {
"name": "execute_python_code",
"description": "执行提供的Python代码片段",
"parameters": {
"type": "object",
"properties": {
"code": {"type": "string", "description": "要执行的Python代码"}
},
"required": ["code"]
}
}
},
{
"type": "function",
"function": {
"name": "query_order_status",
"description": "查询订单状态",
"parameters": {
"type": "object",
"properties": {
"order_id": {"type": "integer", "description": "订单ID"}
},
"required": ["order_id"]
}
}
}
]
messages = [
{"role": "user", "content": user_input}
]
return {
"messages": messages,
"tools": tools,
"tool_choice": "auto", # 自动选择是否调用工具
"max_tokens": 512,
"temperature": 0.3
}
# 发送请求到vLLM API
response = requests.post(
"http://localhost:8000/v1/chat/completions",
json=build_tool_call_request("杭州现在气温多少?")
)
print(response.json())
3.4 解析模型输出并执行调用
模型响应示例(成功触发调用):
{
"id": "chat-xxx",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": null,
"tool_calls": [
{
"id": "call-abc123",
"type": "function",
"function": {
"name": "get_weather",
"arguments": {"city": "杭州"}
}
}
]
}
}
]
}
解析逻辑如下:
import json
def handle_model_response(response_json, user_input):
choice = response_json["choices"][0]
message = choice["message"]
if hasattr(message, "tool_calls") and message.tool_calls:
# 执行第一个工具调用
tool_call = message.tool_calls[0]
func_name = tool_call["function"]["name"]
args = json.loads(tool_call["function"]["arguments"])
# 映射函数名到实际函数
available_functions = {
"get_weather": get_weather,
"execute_python_code": execute_python_code,
"query_order_status": query_order_status
}
if func_name in available_functions:
result = available_functions[func_name](**args)
return {
"requires_action": True,
"function": func_name,
"arguments": args,
"result": result
}
# 否则直接返回文本回复
return {
"requires_action": False,
"reply": message.content
}
3.5 完整对话循环实现
结合以上组件,构建完整的 Agent 循环:
def run_conversation(user_input: str):
# 第一步:调用模型判断是否需要工具
initial_request = build_tool_call_request(user_input)
response = requests.post(
"http://localhost:8000/v1/chat/completions",
json=initial_request
).json()
action_result = handle_model_response(response, user_input)
if not action_result["requires_action"]:
return action_result["reply"]
# 第二步:执行函数并获取结果
func_result = action_result["result"]
# 第三步:将结果返回给模型生成自然语言回复
final_messages = [
{"role": "user", "content": user_input},
{
"role": "assistant",
"tool_calls": [
{
"id": "call-123",
"type": "function",
"function": {
"name": action_result["function"],
"arguments": json.dumps(action_result["arguments"])
}
}
]
},
{
"role": "tool",
"content": json.dumps(func_result),
"tool_call_id": "call-123"
}
]
# 最终请求(不带tools,仅生成回复)
final_response = requests.post(
"http://localhost:8000/v1/chat/completions",
json={
"messages": final_messages,
"max_tokens": 256,
"temperature": 0.2
}
).json()
return final_response["choices"][0]["message"]["content"]
# 测试
print(run_conversation("订单号10086现在什么状态?"))
# 输出:"您的订单号10086当前状态为‘已发货’,快递单号是SF123456789CN。"
4. 最佳实践与常见问题
4.1 提升调用准确率的技巧
- 清晰的功能描述:避免模糊表述,如“处理数据”应改为“计算两个数的加法”
- 合理设置必填参数:使用
required字段明确约束 - 限制枚举值:对固定选项使用
enum,减少拼写错误 - 添加示例说明(可选):部分框架支持提供调用示例
4.2 错误处理与降级策略
- 网络异常:工具调用失败时应返回结构化错误信息
- 无效参数:模型可能生成不符合 schema 的参数,需做校验
- 无匹配工具:当
tool_choice=auto时,模型可能选择不调用,需准备兜底回复
4.3 安全注意事项
- 代码执行隔离:
execute_python_code类功能应在沙箱环境中运行 - 敏感接口保护:避免暴露数据库写入、文件删除等高危操作
- 输入验证:对所有传入参数进行类型和范围检查
5. 总结
Function Calling 是连接大模型与真实世界的桥梁。本文以通义千问2.5-7B-Instruct 为例,系统性地展示了从环境搭建、工具定义、请求构造到结果处理的全流程实现。
通过本次实践,我们验证了该模型在以下方面的突出表现: - ✅ 能准确识别多场景下的工具调用需求 - ✅ 支持复杂参数结构的 JSON 输出 - ✅ 在 128K 上下文中保持稳定的调用一致性 - ✅ 可在消费级 GPU(如 RTX 3060)上高效运行
对于希望构建轻量级、可商用 Agent 系统的开发者而言,Qwen2.5-7B-Instruct 提供了一个性能与成本兼顾的理想选择。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。
更多推荐



所有评论(0)