大模型调用工具二:使用Function Calling
在 LangChain 中,Function Calling(函数调用) 是指让大语言模型(如 OpenAI、Claude 等)根据用户的问题,决定调用某个预定义的函数(或工具),并生成正确的函数调用参数,然后由系统实际执行该函数,并将结果返回给模型,形成闭环。
这是构建智能、可操作助手的核心技术之一,也是目前主流 LangChain 应用(如 Agent、问答助手、任务自动化等)的重要组成。
一、什么是 Function Calling?
简单来说:
函数调用(Function Calling)就是让 LLM “决定何时调用哪个函数,以及传入什么参数”,并由实际代码去执行该函数,再将结果反馈给 LLM,从而实现 LLM 与真实世界功能的交互。
它通常涉及以下几个步骤:
-
定义一组函数(或工具),包括函数名称、描述、参数结构。
-
让 LLM 分析用户输入,决定调用哪个函数,并生成函数调用的参数。
-
系统根据 LLM 的函数调用请求,实际执行对应的函数。
-
将函数执行结果返回给 LLM,让它继续生成最终回复。
二、LangChain 中的 Function Calling 支持
LangChain 提供了对 Function Calling 的原生支持,尤其是针对像 OpenAI 这类支持 Function Calling 的模型(如 gpt-3.5-turbo-0125、gpt-4-turbo等)。
LangChain 提供了:
-
langchain_core.utils.function_calling工具 -
langchain_core.messages中的FunctionMessage -
langchain的agents、tools、chat_models模块都深度集成了 Function Calling
三、Function Calling 使用示例(以 OpenAI 为例)
下面是一个完整的、可直接运行的示例,展示如何使用 LangChain 实现 Function Calling,让 LLM 帮助用户查询当前时间或获取用户信息。
🧩 场景设定
我们定义两个函数:
-
get_current_time()—— 返回当前时间 -
get_user_info(user_id: int)—— 模拟根据用户 ID 查询用户信息
然后让 LLM 根据用户问题,决定调用哪一个函数,并传递正确的参数。
✅ 1. 安装依赖(如未安装)
确保你安装了 LangChain 和 OpenAI 相关库:
pip install langchain langchain-openai
如果你用其他模型(如 Claude、Azure、Mistral 等),也支持 Function Calling,用法类似。
✅ 2. 完整代码示例:Function Calling
from langchain_core.messages import HumanMessage, FunctionMessage
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough
from langchain_openai import ChatOpenAI
from langchain_core.utils.function_calling import convert_to_openai_function
from typing import Dict, Any
import datetime
# -------------------------------
# Step 1: 定义你要调用的函数
# -------------------------------
# 函数1:获取当前时间
def get_current_time() -> str:
return f"当前时间是:{datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"
# 函数2:模拟获取用户信息
def get_user_info(user_id: int) -> str:
return f"用户ID为 {user_id} 的信息:这是一个模拟用户,姓名张三,注册于2023年。"
# -------------------------------
# Step 2: 将函数转换为 OpenAI Function 格式
# -------------------------------
functions = [
{
"name": "get_current_time",
"description": "获取当前系统时间",
"parameters": {}, # 无参数
},
{
"name": "get_user_info",
"description": "根据用户ID获取用户信息",
"parameters": {
"type": "object",
"properties": {
"user_id": {
"type": "integer",
"description": "要查询的用户ID",
}
},
"required": ["user_id"],
},
},
]
# 转换为 LangChain 可用的 Function 对象(兼容格式)
openai_functions = [convert_to_openai_function(f) for f in functions]
# -------------------------------
# Step 3: 定义 LLM 模型,并启用 function calling
# -------------------------------
model = ChatOpenAI(
model="gpt-3.5-turbo-0125", # 或 gpt-4-turbo,必须支持 function call
temperature=0,
)
# -------------------------------
# Step 4: 构建 Prompt,提示模型根据问题选择调用函数
# -------------------------------
prompt = ChatPromptTemplate.from_messages([
("system", "你是一个智能助手,可以根据用户问题调用以下函数:\n"
"1. get_current_time():获取当前时间\n"
"2. get_user_info(user_id):根据用户ID查询用户信息\n\n"
"请分析用户问题,决定调用哪个函数,并给出正确的参数。"),
("human", "{input}"),
])
# -------------------------------
# Step 5: 构建 Chain:Prompt -> LLM(带 function calling)-> 处理函数响应
# -------------------------------
def run_tools(function_call_result):
"""根据 LLM 的 function call 决定调用哪个实际函数"""
if not function_call_result.tool_calls:
return "抱歉,我无法处理该请求。"
for tool_call in function_call_result.tool_calls:
name = tool_call["name"]
args = tool_call["args"]
if name == "get_current_time":
result = get_current_time()
elif name == "get_user_info":
user_id = args.get("user_id")
if not isinstance(user_id, int):
return f"错误:user_id 必须是整数,但你传入的是 {user_id}"
result = get_user_info(user_id)
else:
return f"未知函数:{name}"
# 模拟返回函数执行结果给 LLM(用 FunctionMessage)
# 在真实 Agent 中,这一步会由 LangChain 自动管理
print(f"[函数调用结果] {name}({args}) => {result}")
return result # 简化:直接返回,不再进入多轮对话
# 组合 Chain
chain = (
RunnablePassthrough.assign(
chat_history=lambda x: [], # 可加入历史消息
)
| prompt
| model.bind(functions=openai_functions) # 关键:绑定 functions 参数,启用 function call
| RunnablePassthrough.assign(
final_response=lambda x: run_tools(x)
)
)
# -------------------------------
# Step 6: 测试调用
# -------------------------------
# 示例1:询问当前时间
print("=== 问题1:现在几点?===")
response1 = chain.invoke({"input": "现在几点?"})
print("回答:", response1["final_response"], "\n")
# 示例2:查询用户信息
print("=== 问题2:查一下用户ID为101的信息===")
response2 = chain.invoke({"input": "查一下用户ID为101的信息"})
print("回答:", response2["final_response"], "\n")
🧠 代码解析
|
步骤 |
说明 |
|---|---|
|
1️⃣ 定义函数 |
定义你希望 LLM 调用的实际功能,如 |
|
2️⃣ 转换函数为 OpenAI Function 格式 |
使用 |
|
3️⃣ 加载支持 Function Calling 的模型 |
比如 |
|
4️⃣ 构建 Prompt |
提示模型它可以使用哪些函数,引导它做出正确的函数调用决策 |
|
5️⃣ 处理函数调用结果 |
当 LLM 返回 |
|
6️⃣ 测试调用 |
模拟用户提问,观察 LLM 是否正确调用函数并返回结果 |
四、关键点总结
|
项目 |
说明 |
|---|---|
|
✅ Function Calling 作用 |
让 LLM 能够调用外部函数/工具,实现真正“能做事”的智能助手 |
|
✅ LangChain 支持情况 |
原生支持,特别是对 OpenAI 系列模型(gpt-3.5/4 + function call) |
|
✅ 必要步骤 |
定义函数 → 转换为 OpenAI Function 格式 → 绑定到模型 → 处理函数调用 |
|
✅ 工具/函数需有清晰描述和参数 |
LLM 依赖 description 和参数 schema 做出正确判断 |
|
✅ 推荐使用 Pydantic(高级) |
更规范地定义参数类型,提升 LLM 理解和生成准确性 |
|
✅ 可与 Agent 结合 |
实际项目中,通常用 Agent 管理多工具、多轮调用、记忆等 |
五、进阶:使用 LangChain Tools + Function Calling
在实际项目中,你可能不是手写 run_tools(),而是使用 LangChain 的标准 Tool类,配合 agent,让 LangChain 自动管理:
-
工具注册
-
工具描述
-
函数调用生成
-
工具执行
-
多轮交互
👉 推荐你进一步学习:
-
langchain.agents(如 Zero-shot Agent、ReAct Agent)
-
langchain.tools(标准 Tool 定义)
-
langchain_community.tools(现成工具,如搜索、API、数据库等)
六、总结
|
功能 |
是否支持 |
说明 |
|---|---|---|
|
✅ 让 LLM 调用自定义函数 |
✔️ |
通过 Function Calling 实现 |
|
✅ LangChain 原生支持 |
✔️ |
特别是对 OpenAI 模型 |
|
✅ 支持参数传递与校验 |
✔️ |
通过 JSON Schema / Pydantic |
|
✅ 可与 Agent 无缝集成 |
✔️ |
推荐用于生产级应用 |
|
✅ 支持多工具、多轮交互 |
✔️ |
构建真正智能的助手 |
更多推荐

所有评论(0)