调用LangChain 的工具(Tool Calling) 功能,它允许 大语言模型(LLM) 调用外部工具(如计算器、数据库查询、API 调用等),从而增强其功能

为了更直观的展示LangChain 的工具(Tool Calling) 功能,我先通过代码做个对比:

第一种:使用工具功能

代码如下:

import getpass
import os
from langchain.chat_models import init_chat_model
from langchain_core.tools import tool
from langchain_core.messages import HumanMessage, ToolMessage,SystemMessage


# 如果没有设置 GROQ_API_KEY,则提示用户输入
if not os.environ.get("GROQ_API_KEY"):
    os.environ["GROQ_API_KEY"] = getpass.getpass("Enter API key for Groq: ")

# 使用 @tool 装饰器注册工具函数
@tool
def abcefikfs(a: int, b: int) -> str:
    """abcefikfs do nothing."""
    return 'ffffff'

# 初始化 Llama 模型,使用 Groq 后端
llm = init_chat_model("llama3-8b-8192", model_provider="groq", temperature=0)

# 将工具绑定到模型上
tools = [abcefikfs]
llm_with_tools = llm.bind_tools(tools)

messages=[SystemMessage(content="请只返回最终结果,不要解释,如果没有找到结果,请返回无法找到答案")]
query = "Use function abcefikfs with a=2 and b=3 and return the result."
# print(llm_with_tools.invoke(query).tool_calls)

messages = [HumanMessage(query)]
ai_msg = llm_with_tools.invoke(messages)
messages.append(ai_msg)
for tool_call in ai_msg.tool_calls:
    selected_tool = {"abcefikfs": abcefikfs}[tool_call["name"].lower()]
    tool_output = selected_tool.invoke(tool_call["args"])
    messages.append(ToolMessage(tool_output, tool_call_id=tool_call["id"]))
    
messages.append(HumanMessage(content=f"The function returned: {tool_output}. Please summarize."))   
# 第二次调用:将工具输出和额外提示传回给模型,生成最终答案
response = llm.invoke(messages)
print("\nFinal Response:", response.content)

返回结果:
在这里插入图片描述
abcefikfs 方法被模型识别并正确返回结果。

第二种:不使用工具,直接用模型返回答案

部分代码如下:

messages = [
    SystemMessage(content="请只返回最终结果,不要解释,如果没有找到结果,请返回无法找到答案"),
    HumanMessage(content="Use function abcefikfs with a=2 and b=3 and return the result.")
]
# 不使用工具,将问题传给模型不用工具处理
response = llm.invoke(messages)
response.content

返回结果:
在这里插入图片描述

abcefikfs 方法是我们自定义乱写的一个方法,让模型直接调用这个方法它会不知道这个方法是什么的,因为我们并没有在工具中定义它,它会根据我们的提示工程(prompt)返回无法找到答案

这就引出了下面的内容。

通过 LangChain 的工具调用(Tool Calling) 功能,让 大语言模型(LLM) 调用外部工具(如计算器、数据库查询、API 调用等),从而增强其功能。例如,如果 LLM 需要执行数学运算,它可以调用一个计算函数,而不是自己尝试计算答案。


核心概念

  1. 工具(Tool):一个可以被 LLM 调用的外部功能,比如加法、乘法、搜索引擎等。
  2. 工具调用(Tool Calling):LLM 生成调用工具所需的参数,具体是否执行工具调用由用户决定。
  3. 工具绑定(Binding Tools):把工具传递给 LLM,使 LLM 在需要时能够调用它们。
  4. 工具调用解析(Tool Call Parsing):解析 LLM 生成的工具调用,并转换成 Python 对象。

代码解析

1. 定义工具

from langchain_core.tools import tool

@tool
def add(a: int, b: int) -> int:
    """Adds a and b."""
    return a + b

@tool
def multiply(a: int, b: int) -> int:
    """Multiplies a and b."""
    return a * b

tools = [add, multiply]

解释:

  • @tool:这个装饰器把普通的 Python 函数转换成 LangChain 工具,使其可以被 LLM 识别和调用。
  • add(a, b):接收两个整数,返回它们的和。
  • multiply(a, b):接收两个整数,返回它们的积。
  • tools = [add, multiply]:把所有工具存入列表,稍后传递给 LLM。

示例:

print(add(3, 5))       # 输出 8
print(multiply(4, 6))  # 输出 24

2. 使用 Pydantic 定义工具(另一种方式)

from pydantic import BaseModel, Field

class Multiply(BaseModel):
    a: int
    b: int
    def execute(self):
        return self.a * self.b

class Add(BaseModel):
    a: int
    b: int
    def execute(self):
        return self.a + self.b

tools = [Add, Multiply]

解释:

  • BaseModel:Pydantic 提供的数据模型,确保参数符合要求(如 ab 必须是整数)。
  • Field(..., description="xxx"):提供额外信息,帮助 LLM 理解工具的作用。
  • tools = [Add, Multiply]:同样存入工具列表,供后续 LLM 使用。

示例:

add_data = Add(a=3, b=7)
print(add_data.a + add_data.b,add_data.execute())  # 输出 10 10

3. 绑定工具到 LLM

from langchain.chat_models import init_chat_model

llm = init_chat_model("llama3-8b-8192", model_provider="groq")
llm_with_tools = llm.bind_tools(tools)

解释:

  • init_chat_model("llama3-8b-8192", model_provider="groq")
    • 初始化一个 Llama 3 8B 大语言模型,由 Groq 提供服务。
  • llm.bind_tools(tools)
    • 绑定工具,让 LLM 具备调用 addmultiply 的能力。

4. 让 LLM 调用工具

query = "What is 3 * 12? Also, what is 11 + 49?"
llm_with_tools.invoke(query).tool_calls

解释:

  • query:用户输入问题,要求计算 3 * 1211 + 49
  • llm_with_tools.invoke(query).tool_calls
    • 调用 LLM 处理这个问题,并返回它决定调用的工具。

输出结果:
在这里插入图片描述

这表示:

  1. LLM 认为它需要调用 Multiply(a=3, b=12) 来计算 3 * 12
  2. LLM 认为它需要调用 Add(a=11, b=49) 来计算 11 + 49

5. 处理 LLM 返回的工具调用

from langchain_core.output_parsers.openai_tools import PydanticToolsParser

chain = llm_with_tools | PydanticToolsParser(tools=[Multiply, Add])
chain.invoke(query)

解释:

  • PydanticToolsParser
    • 解析 LLM 生成的工具调用,并转换回 Pydantic 模型(如 Multiply(a=3, b=12))。
  • chain = llm_with_tools | PydanticToolsParser(tools=[Multiply, Add])
    • 组合 LLM 和工具解析器,使其输出结构化结果。
  • chain.invoke(query)
    • 运行整个调用链,最终输出:
    [Multiply(a=3, b=12), Add(a=11, b=49)]
    

完整示例

from langchain_core.tools import tool
from langchain.chat_models import init_chat_model
from langchain_core.output_parsers.openai_tools import PydanticToolsParser

@tool
def add(a: int, b: int) -> int:
    """Adds a and b."""
    return a + b

@tool
def multiply(a: int, b: int) -> int:
    """Multiplies a and b."""
    return a * b

tools = [add, multiply]

# 初始化 LLM
llm = init_chat_model("llama3-8b-8192", model_provider="groq")
llm_with_tools = llm.bind_tools(tools)

# 让 LLM 解析查询
query = "What is 3 * 12? Also, what is 11 + 49?"
tool_calls = llm_with_tools.invoke(query).tool_calls

# 解析工具调用
chain = llm_with_tools | PydanticToolsParser(tools=[multiply, add])
results = chain.invoke(query)

print(results)

输出:

[Multiply(a=3, b=12), Add(a=11, b=49)]

接着可以执行这个结果:

chain = llm_with_tools | PydanticToolsParser(tools=[Multiply, Add])
chain.invoke(query)

输出
在这里插入图片描述


总结

  • 工具调用(Tool Calling) 让 LLM 通过 外部函数 执行特定任务,而不是自己“猜”答案。
  • 可以使用 @tool 装饰器Pydantic 模型 定义工具。
  • 通过 bind_tools() 绑定工具到 LLM,让 LLM 在需要时调用它们。
  • invoke() 让 LLM 解析查询并 决定调用哪些工具
  • PydanticToolsParser 解析工具调用的结果 并转换成 Python 对象。

这样,LLM 既可以聊天,又可以 调用真实工具,从而具备更强的功能,比如:
✅ 计算数学公式
✅ 查询数据库
✅ 调用 API
✅ 执行代码
✅ 检索搜索引擎数据

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值