Function Calling 原理与实战:从零构建智能工具调用系统
摘要:Function Calling 是大语言模型(LLM)与外部世界交互的核心机制。本文深入解析 Function Calling 的工作原理、实现细节和最佳实践,通过完整的实战案例演示如何构建可靠的工具调用系统,帮助开发者掌握这一关键技术。
一、Function Calling 核心概念
1.1 什么是 Function Calling?
Function Calling 允许 LLM 在对话过程中调用预定义的函数,获取实时信息或执行操作:
┌─────────────────────────────────────────────────────────┐
│ Function Calling 工作流程 │
├─────────────────────────────────────────────────────────┤
│ │
│ 用户: "北京今天天气怎么样?" │
│ │ │
│ ▼ │
│ ┌─────────┐ │
│ │ LLM │ 分析用户意图,决定调用哪个函数 │
│ └────┬────┘ │
│ │ │
│ │ function_call: { │
│ │ name: "get_weather", │
│ │ arguments: {"city": "北京"} │
│ │ } │
│ ▼ │
│ ┌─────────┐ │
│ │ 函数 │ 执行天气 API 调用 │
│ └────┬────┘ │
│ │ │
│ │ result: "北京今天晴,25°C" │
│ ▼ │
│ ┌─────────┐ │
│ │ LLM │ 整合结果,生成自然语言回复 │
│ └────┬────┘ │
│ │ │
│ ▼ │
│ AI: "北京今天天气晴朗,气温25°C,很适合出行~" │
│ │
└─────────────────────────────────────────────────────────┘

1.2 Function Calling vs 传统 API 调用
# 传统方式:硬编码逻辑判断
def traditional_chat(user_input):
if "天气" in user_input:
# 提取城市名
city = extract_city(user_input)
# 调用天气 API
weather = get_weather(city)
# 格式化回复
return f"{
city}天气:{
weather}"
elif "翻译" in user_input:
# 另一套逻辑...
pass
# 需要为每种意图编写判断逻辑,难以扩展
# Function Calling 方式:LLM 自动决策
async def function_calling_chat(user_input, tools):
# LLM 根据工具描述自动选择合适的函数
response = await llm.chat(
messages=[{
"role": "user", "content": user_input}],
tools=tools # 工具定义列表
)
if response.tool_calls:
# LLM 决定调用某个工具
tool_call = response.tool_calls[0]
result = await execute_tool(tool_call)
# 将结果返回给 LLM 生成最终回复
return await generate_response_with_result(result)
return response.content
二、主流平台 Function Calling 实现
2.1 OpenAI Function Calling
# OpenAI Function Calling 实现
from openai import OpenAI
import json
client = OpenAI()
# 定义工具
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"]
}
}
}
]
# 工具实现
def get_weather(city: str, unit: str = "celsius") -> str:
# 实际实现中调用天气 API
return json.dumps({
"city": city,
"temperature": 25,
"unit": unit,
"condition": "晴"
})
# 发起对话
def chat_with_tools(user_message):
messages = [{
"role": "user", "content": user_message}]
response = client.chat.completions.create(
model="gpt-4",
messages=messages,
tools=tools,
tool_choice="auto" # 自动决定是否调用工具
)
assistant_message = response.choices[0].message
# 检查是否有工具调用
if assistant_message.tool_calls:
# 执行工具调用
for tool_call in assistant_message.tool_calls:
function_name = tool_call.function.name
arguments = json.loads(tool_call.function.arguments)
if function_name == "get_weather":
result = get_weather(**arguments)
# 将工具结果添加到消息历史
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"content": result
})
# 再次调用 LLM 生成最终回复
final_response = client.chat.completions.create(
model="gpt-4",
messages=messages
)
return final_response.choices[0].message.content
return assistant_message.content
2.2 Anthropic Claude Tool Use
# Anthropic Claude Tool Use 实现
import anthropic
client = anthropic.Anthropic()
# 定义工具
tools = [
{
"name": "get_weather",
"description": "获取指定城市的当前天气信息",
"input_schema": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名称"
}
},
"required": ["city"]
}
}
]
def chat_with_claude(user_message):
messages = [{
"role": "user", "content": user_message}]
response = client.messages.create(
model="claude-3-opus-20240229",
max_tokens=1024,
tools=tools,
messages=messages
)
# 检查是否有工具使用
if response.stop_reason == "tool_use":
# 提取工具调用
tool_use = next(
block for block in response.content
if block.type == "tool_use"
)
# 执行工具
result = get_weather(**tool_use.input)
# 发送工具结果
messages.append({
"role": "assistant", "content": response.content})
messages.append({
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": tool_use.id,
"content": result
}
]
})
# 获取最终回复
final_response = client.messages.create(
model="claude-3-opus-20240229",
max_tokens=1024,
tools=tools,
messages=messages
)
return final_response.content[0].text
return response.content[0].text
2.3 Google Gemini Function Calling
# Google Gemini Function Calling 实现
import google.generativeai as genai
genai.configure(api_key="your-api-key")
# 定义函数
def get_weather(city: str) -> dict:
"""获取天气信息"""
return {
"city": city,
"temperature": 25,
"condition": "晴"
}
# 创建模型
model = genai.GenerativeModel(
model_name="gemini-pro",
tools=[get_weather] # 直接传递函数
)
def chat_with_gemini(user_message):
chat = model.start_chat()
response = chat.send_message(user_message)
# 检查是否有函数调用
if response.candidates[0].content.parts:
for part in response.candidates[0].content.parts:



被折叠的 条评论
为什么被折叠?



