核心定义
Function Calling(函数调用)是大模型与外部工具/函数交互的核心能力,能够让模型根据用户需求自主判断是否需要调用指定函数,通过结构化参数传递调用指令并获取执行结果,最终结合结果生成精准响应,以此解决大模型自身无法完成的复杂计算、实时数据查询等任务。
两种工具添加方案
方案一:直接通过 Tool.from_function 定义工具
该方案适用于函数逻辑简单的场景,可直接通过字典指定参数规范,无需额外定义专门的参数模型,实现快速封装。
步骤1:基础依赖与初始化
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.tools import Tool
from pydantic import BaseModel, Field
# 大模型初始化
llm = ChatOpenAI(
model_name="qwen-plus",
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
api_key="[你的API Key]",
)
# 提示模板定义
chat_prompt_template = ChatPromptTemplate.from_messages(
[
# 系统角色定义
("system", "你是一个{role}专家,可以帮助用户解决问题"),
# 用户输入占位符
("human", "{input}"),
]
)
步骤2:封装为工具
通过 Tool.from_function 方法将自定义函数封装为工具,需明确指定工具名称、功能描述及参数校验模型:
# 定义参数模型
class SunArgs(BaseModel):
num1: int = Field(description="第一个数")
num2: int = Field(description="第二个数")
# 定义求和函数
def sum(a, b):
return a + b
sum_tool = Tool.from_function(
# 关联核心函数
func=sum,
# 工具名称(模型调用时识别的名称)
name="sum",
# 工具功能描述(帮助模型判断是否调用)
description="计算两个数的和",
# 参数规范,指定参数类型与描述
args_schema=SunArgs,
)
步骤3:绑定工具并执行调用
# 为大模型绑定工具(可绑定多个,传入列表)
llm = llm.bind_tools([sum_tool])
# 组合提示模板与大模型,形成调用链
llm = chat_prompt_template | llm
# 调用模型,传入角色与用户需求
response = llm.invoke(input={"role": "数学", "input": "计算10和20的和"})
# 解析工具调用结果并执行函数
tool_calls = response.tool_calls
for tool_call in tool_calls:
# 匹配工具名称
if tool_call["name"] == "sum":
# 获取模型传递的参数
args = tool_call["args"]
# 执行函数
result = sum(**args)
# 输出结果:30
print(result)
方案二:通过 @tool 装饰器定义工具(推荐)
步骤1:基础依赖与初始化
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.tools import Tool
from pydantic import BaseModel, Field
# 大模型初始化
llm = ChatOpenAI(
model_name="qwen-plus",
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
api_key="[你的API Key]",
)
# 提示模板定义
chat_prompt_template = ChatPromptTemplate.from_messages(
[
# 系统角色定义
("system", "你是一个{role}专家,可以帮助用户解决问题"),
# 用户输入占位符
("human", "{input}"),
]
)
步骤2:用装饰器定义工具函数
通过 @tool 装饰器可直接将自定义函数封装为工具,无需额外调用 Tool.from_function 方法,只需关联对应的参数模型即可完成配置:
# 定义参数模型
class SunArgs(BaseModel):
num1: int = Field(description="第一个数")
num2: int = Field(description="第二个数")
@tool(
# 工具功能描述
description="计算两个数的和",
# 关联参数模型
args_schema=SunArgs,
)
def sum(num1, num2):
return num1 + num2
步骤3:绑定工具并执行调用
# 绑定工具(直接传入函数,无需额外封装)
llm = llm.bind_tools([sum])
# 组合提示模板与大模型
llm = chat_prompt_template | llm
# 调用模型
response = llm.invoke(input={"role": "数学", "input": "计算10和20的和"})
# 解析并执行工具调用
for tool_call in response.tool_calls:
if tool_call["name"] == "sum":
args = tool_call["args"]
# 通过 invoke 方法执行函数
result = sum.invoke(args)
# 输出结果:30
print(result)
使用 LangChain 内置工具
LangChain 提供了丰富的内置工具集,无需自行编写底层逻辑即可直接调用,能快速实现文件操作、代码运行、数据查询等常见功能,大幅提升开发效率。
1. 安装内置工具依赖
首先安装包含各类内置工具的扩展包,执行以下命令:
uv add langchain_experimental
2. 内置工具使用示例(PythonREPLTool)
以 PythonREPLTool 为例,该工具支持直接执行 Python 代码,可实现文件创建、数据计算、脚本运行等功能,完整使用代码如下:
from langchain_experimental.tools.python.tool import PythonREPLTool
from langchain_openai import ChatOpenAI
# 大模型初始化
model = ChatOpenAI(
model_name="qwen-plus",
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
api_key="[你的API Key]",
)
# 为大模型绑定内置 PythonREPLTool 工具
model = model.bind_tools([PythonREPLTool()])
# 调用模型,传入用户需求
response = model.invoke(
"帮我在当前目录下创建一个html文件,文件内容是李白的《静夜思》",
)
# 解析工具调用指令并执行对应操作
tool_calls = response.tool_calls
for tool_call in tool_calls:
# 匹配内置工具名称 Python_REPL
if tool_call["name"] == "Python_REPL":
# 获取模型传递的工具调用参数
args = tool_call["args"]
# 打印参数内容(查看模型生成的 Python 代码)
print(args)
# 初始化工具并执行对应操作
python_tool = PythonREPLTool()
# 运行工具并获取执行结果
result = python_tool.run(args)
核心关键要点
- 工具调用位置:工具函数必须部署在服务端执行,大模型仅负责输出工具调用指令,不具备直接执行工具函数的能力,需由后端服务解析指令后触发函数运行。
- 工具描述精准性:工具的
description字段需简洁且精准(例如“计算两个整数的和”),清晰告知模型工具的核心功能,其表述质量直接决定模型能否准确识别需求并触发正确调用。 - 参数定义规范性:两种方案均需明确参数的类型与功能描述;推荐使用
Pydantic的BaseModel定义参数模型,该方式可实现参数自动校验,能显著降低模型调用时的参数错误率。 - 调用结果解析:需通过
response.tool_calls获取模型返回的工具调用指令,遍历解析出工具名称与输入参数后,执行对应的工具函数,最终获取执行结果并用于后续响应生成。