LangChain 函数调用(Function Calling)学习总结
一、这是什么?(概念解释)
函数调用(Function Calling) 是一种让大语言模型(LLM)能够与外部工具交互的能力。
简单来说:
- 普通的 LLM 只能"说"(输出文字)
- 有了函数调用,LLM 可以"做"(调用外部 API、查询数据库、执行工具等)
在 LangChain 中,通过 bind_tools() 方法将自定义工具绑定到 ChatModel 上,让模型可以根据用户问题自动选择合适的工具来执行。
二、有什么用?(应用场景)
| 场景 | 说明 |
|---|---|
| 实时信息查询 | 查询天气、股票、新闻等实时数据 |
| 网络搜索 | 调用 Google 搜索获取最新资讯 |
| 数据库操作 | 查询/更新数据库中的数据 |
| 复杂计算 | 调用计算器、数学库进行精确计算 |
| 系统操作 | 读取文件、发送邮件、控制 IoT 设备 |
| 多步骤任务 | 组合多个工具完成复杂任务 |
三、完整示例代码
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import json
import os
from typing import Type, Any
import requests
from langchain_core.messages import ToolMessage
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough
from langchain_core.tools import BaseTool
from langchain_openai import ChatOpenAI
from pydantic import Field, BaseModel
import dotenv
dotenv.load_dotenv()
# ============ 第一步:定义工具 ============
# 1. 定义工具的参数 Schema(用 Pydantic 描述)
class WeatherArgsSchema(BaseModel):
city: str = Field(description="需要查询天气的目标城市,例如:北京")
# 2. 创建自定义工具类(继承 BaseTool)
class WeatherTool(BaseTool):
"""查询指定城市的天气预报"""
name: str = "weather_query"
description: str = "当你需要查询天气信息时使用此工具"
args_schema: Type[BaseModel] = WeatherArgsSchema
def _run(self, city: str) -> str:
# 这里调用实际的天气 API
return f"{city}今天晴天,温度 25°C"
# ============ 第二步:创建模型并绑定工具 ============
# 初始化工具
weather_tool = WeatherTool()
tools = [weather_tool]
# 创建 ChatModel
llm = ChatOpenAI(model="gpt-4o-mini")
# 将工具绑定到模型上(关键步骤!)
llm_with_tools = llm.bind_tools(tools=tools)
# ============ 第三步:创建执行链 ============
prompt = ChatPromptTemplate.from_messages([
("system", "你是一个智能助手,可以调用工具帮助用户"),
("human", "{query}")
])
chain = {"query": RunnablePassthrough()} | prompt | llm_with_tools
# ============ 第四步:调用并处理工具结果 ============
query = "北京今天天气怎么样?"
response = chain.invoke(query)
# 检查模型是否想要调用工具
if response.tool_calls:
# 模型决定调用工具
print(f"模型想调用工具: {response.tool_calls}")
# 手动执行工具
for tool_call in response.tool_calls:
tool_result = weather_tool.invoke(tool_call['args'])
print(f"工具返回: {tool_result}")
# 将工具结果反馈给模型,生成最终回答
final_response = llm.invoke([
*prompt.invoke(query).to_messages(),
response,
ToolMessage(content=tool_result, tool_call_id=tool_call['id'])
])
print(f"最终回答: {final_response.content}")
else:
# 模型直接回答
print(f"直接回答: {response.content}")
四、函数调用流程图
┌─────────────────────────────────────────────────────────────────────────┐
│ 函数调用完整流程 │
└─────────────────────────────────────────────────────────────────────────┘
用户提问 LLM 处理 工具执行
│ │ │
▼ │ │
"北京天气怎么样?" ────────────────▶│ 分析问题 │
│ │ │
│ │ 需要天气信息 ─────────────▶│
│ │ │
│ │ 返回 tool_calls: │
│ │ [{name: "weather_query", │
│ │ args: {city: "北京"}}] │
│ │◀──────────────────────────│
│ │ │
│ │ 解析 tool_calls │
│ │ │
│ │ 调用工具 ──────────────────▶│
│ │ │ 执行天气API
│ │◀──────────────────────────│
│ │ │
│ │ 获取工具结果 │
│ │ "北京:晴天,25°C" │
│ │ │
│ │ 再次调用 LLM │
│ │ (上下文 + 工具结果) │
│ │ │
│◀─────────────────────────────│ 生成最终回答 │
│ │ │
"根据查询结果, │ │
北京今天是晴天, │ │
温度25度。" │ │
│ │ │
┌─────────────────────────────────────────────────────────────────────────┐
│ 核心要点 │
└─────────────────────────────────────────────────────────────────────────┘
1. bind_tools() - 让 LLM 知道有哪些工具可用
2. tool_calls - LLM 返回的工具调用指令
3. 工具执行 - 手动执行工具获取实际结果
4. 结果反馈 - 将工具结果返回给 LLM 生成最终回答