共计 2871 个字符,预计需要花费 8 分钟才能阅读完成。
背景痛点
初次接触大模型 Agent 工具调用时,开发者常会遇到几个典型问题:

- 工具描述模糊 :不知道如何用结构化语言准确描述工具功能,导致大模型无法正确理解和使用工具
- 响应解析困难 :大模型返回的工具体调用请求格式复杂,提取参数时容易出错
- 逻辑耦合严重 :工具执行代码与大模型交互代码混在一起,难以维护和扩展
- 错误处理缺失 :没有考虑大模型可能产生错误调用或工具执行失败的情况
技术方案
我们采用 OpenAI Function Calling 作为基础架构,它的核心优势在于:
- 标准化接口 :通过 JSON Schema 明确定义工具
- 灵活调用 :大模型自主决定何时以及如何调用工具
- 清晰响应 :返回结构化的工具调用请求
工具定义规范
一个完整的工具定义包括:
{
"name": "get_current_weather",
"description": "Get the current weather in a given location",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "The city and state, e.g. San Francisco, CA"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"]
}
},
"required": ["location"]
}
}
响应解析流程
当大模型决定调用工具时,会返回如下结构的响应:
{
"role": "assistant",
"content": null,
"function_call": {
"name": "get_current_weather",
"arguments": "{\"location\":\"Beijing\",\"unit\":\"celsius\"}"
}
}
完整代码实现
以下是基于 Python 和 OpenAI API 的完整示例(需要安装 openai 库):
import openai
import json
from typing import Dict, Any
# 模拟天气 API
def get_current_weather(location: str, unit: str = "celsius") -> str:
"""模拟天气查询工具"""
return f"{location} 当前天气: 22 度 {unit}, 晴"
# 工具定义
tools = [
{
"name": "get_current_weather",
"description": "获取指定位置的当前天气",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "城市名称,如: 北京"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"]
}
},
"required": ["location"]
}
}
]
# 处理工具调用
def handle_tool_call(function_name: str, arguments: Dict[str, Any]) -> str:
if function_name == "get_current_weather":
return get_current_weather(**arguments)
raise ValueError(f"未知工具: {function_name}")
# 主对话循环
def chat_loop():
messages = [{"role": "system", "content": "你是一个有帮助的助手"}]
while True:
user_input = input("你:")
if user_input.lower() == "exit":
break
messages.append({"role": "user", "content": user_input})
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=messages,
tools=tools,
tool_choice="auto"
)
assistant_message = response.choices[0].message
messages.append(assistant_message)
# 检查是否调用了工具
if assistant_message.get("function_call"):
function_call = assistant_message["function_call"]
try:
arguments = json.loads(function_call["arguments"])
tool_response = handle_tool_call(function_call["name"],
arguments
)
messages.append({
"role": "function",
"name": function_call["name"],
"content": tool_response
})
except Exception as e:
print(f"工具调用错误: {e}")
continue
print(f"助手: {assistant_message.get('content','')}")
if __name__ == "__main__":
chat_loop()
避坑指南
工具描述精确性
- 避免模糊描述:” 获取天气数据 ” → “ 获取指定城市当前温度、天气状况和体感温度 ”
- 参数说明要具体:” 位置信息 ” → “ 城市名称,支持中英文,如 ’ 北京 ’ 或 ’Beijing'”
处理大模型幻觉
- 验证必填参数是否存在
- 检查参数值是否合法(如枚举值)
- 添加默认参数值(如单位默认为摄氏度)
异步超时控制
import asyncio
from functools import partial
async def run_with_timeout(func, timeout=5, *args, **kwargs):
try:
return await asyncio.wait_for(asyncio.get_event_loop().run_in_executor(None, partial(func, *args, **kwargs)
),
timeout
)
except asyncio.TimeoutError:
raise TimeoutError(f"工具执行超时: {timeout} 秒")
进阶建议
工具版本兼容
- 在工具名称中包含版本号:”get_weather_v2″
- 维护旧版本工具一段时间
- 通过 API 网关实现版本路由
工具组合调用
- 设计工具依赖关系图
- 实现工具执行结果缓存
- 处理循环依赖检测
延伸学习
- OpenAI 官方文档:Function Calling 指南
- LangChain 框架:Tool 和 Agent 的实现
- 开源项目:AutoGPT 的工具体系
实战挑战
- 扩展当前示例,增加股票查询工具
- 实现工具调用历史记录功能
- 添加用户权限验证机制
正文完
