在 LangChain 中,​Function Calling(函数调用)​​ 是指让大语言模型(如 OpenAI、Claude 等)根据用户的问题,​决定调用某个预定义的函数(或工具),并生成正确的函数调用参数,然后由系统实际执行该函数,并将结果返回给模型,形成闭环。

这是构建智能、可操作助手的核心技术之一,也是目前主流 LangChain 应用(如 Agent、问答助手、任务自动化等)的重要组成。


一、什么是 Function Calling?

简单来说:

函数调用(Function Calling)就是让 LLM “决定何时调用哪个函数,以及传入什么参数”,并由实际代码去执行该函数,再将结果反馈给 LLM,从而实现 LLM 与真实世界功能的交互。

它通常涉及以下几个步骤:

  1. 定义一组函数(或工具)​,包括函数名称、描述、参数结构。

  2. 让 LLM 分析用户输入,决定调用哪个函数,并生成函数调用的参数。​

  3. 系统根据 LLM 的函数调用请求,实际执行对应的函数。​

  4. 将函数执行结果返回给 LLM,让它继续生成最终回复。​


二、LangChain 中的 Function Calling 支持

LangChain 提供了对 Function Calling 的原生支持,尤其是针对像 ​OpenAI​ 这类支持 Function Calling 的模型(如 gpt-3.5-turbo-0125gpt-4-turbo等)。

LangChain 提供了:

  • langchain_core.utils.function_calling工具

  • langchain_core.messages中的 FunctionMessage

  • langchainagentstoolschat_models模块都深度集成了 Function Calling


三、Function Calling 使用示例(以 OpenAI 为例)

下面是一个完整的、可直接运行的示例,展示如何使用 LangChain 实现 Function Calling,让 LLM 帮助用户查询当前时间或获取用户信息。


🧩 场景设定

我们定义两个函数:

  1. get_current_time()—— 返回当前时间

  2. 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 调用的实际功能,如 get_current_time()get_user_info()

2️⃣ 转换函数为 OpenAI Function 格式

使用 convert_to_openai_function(),生成模型理解的 JSON Schema

3️⃣ 加载支持 Function Calling 的模型

比如 gpt-3.5-turbo-0125,并在调用时通过 .bind(functions=...)启用

4️⃣ 构建 Prompt

提示模型它可以使用哪些函数,引导它做出正确的函数调用决策

5️⃣ 处理函数调用结果

当 LLM 返回 tool_calls时,根据函数名和参数去真正执行函数

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 自动管理:

  • 工具注册

  • 工具描述

  • 函数调用生成

  • 工具执行

  • 多轮交互

👉 推荐你进一步学习:


六、总结

功能

是否支持

说明

✅ 让 LLM 调用自定义函数

✔️

通过 Function Calling 实现

✅ LangChain 原生支持

✔️

特别是对 OpenAI 模型

✅ 支持参数传递与校验

✔️

通过 JSON Schema / Pydantic

✅ 可与 Agent 无缝集成

✔️

推荐用于生产级应用

✅ 支持多工具、多轮交互

✔️

构建真正智能的助手


Logo

欢迎加入 MCP 技术社区!与志同道合者携手前行,一同解锁 MCP 技术的无限可能!

更多推荐