用例(User Case)
工具使用(ToolUse)
多工具(MultipleTools)

选择多个工具

在我们的 快速入门 中,我们介绍了如何构建一个调用单个 multiply 工具的链。现在让我们来看看如何扩展这个链,使其能够从多个工具中选择调用。我们将重点介绍链,因为默认情况下 代理 可以在多个工具之间路由。

设置

我们需要为本指南安装以下软件包:

%pip install --upgrade --quiet langchain-core

如果你想在 LangSmith 中追踪你的运行,请取消注释并设置以下环境变量:

import getpass
import os
 
# os.environ ["LANGCHAIN_TRACING_V2"] = "true"
# os.environ ["LANGCHAIN_API_KEY"] = getpass.getpass()

工具

回顾一下,我们已经有了一个 multiply 工具:

from langchain_core.tools import tool
 
 
@tool
def multiply(first_int: int, second_int: int) -> int:
    """Multiply two integers together."""
    return first_int * second_int

现在我们可以在它基础上添加一个 exponentiate 和一个 add 工具:

@tool
def add(first_int: int, second_int: int) -> int:
    "Add two integers."
    return first_int + second_int
 
 
@tool
def exponentiate(base: int, exponent: int) -> int:
    "Exponentiate the base to the exponent power."
    return base**exponent

使用一个工具和使用多个工具之间的主要区别在于,我们无法预先确定模型将调用哪个工具,因此我们不能像在 快速入门 中那样硬编码将特定工具放入我们的链中。相反,我们将添加 call_tools,一个 RunnableLambda,它接受带有工具调用的输出 AI 消息并路由到正确的工具。

from langchain_anthropic import ChatAnthropic
 
llm = ChatAnthropic(model="claude-3-sonnet-20240229", temperature=0)
from operator import itemgetter
from typing import Dict, List, Union
 
from langchain_core.messages import AIMessage
from langchain_core.runnables import (
    Runnable,
    RunnableLambda,
    RunnableMap,
    RunnablePassthrough,
)
 
tools = [multiply, exponentiate, add]
llm_with_tools = llm.bind_tools(tools)
tool_map = {tool.name: tool for tool in tools}
 
 
def call_tools(msg: AIMessage) -> Runnable:
    """Simple sequential tool calling helper."""
    tool_map = {tool.name: tool for tool in tools}
    tool_calls = msg.tool_calls.copy()
    for tool_call in tool_calls:
        tool_call["output"] = tool_map[tool_call["name"]].invoke(tool_call["args"])
    return tool_calls
 
 
chain = llm_with_tools | call_tools
chain.invoke("What's 23 times 7")
[{'name': 'multiply',
  'args': {'first_int': 23, 'second_int': 7},
  'id': 'toolu_01Wf8kUs36kxRKLDL8vs7G8q',
  'output': 161}]
chain.invoke("add a million plus a billion")
[{'name': 'add',
  'args': {'first_int': 1000000, 'second_int': 1000000000},
  'id': 'toolu_012aK4xZBQg2sXARsFZnqxHh',
  'output': 1001000000}]
chain.invoke("cube thirty-seven")
[{'name': 'exponentiate',
  'args': {'base': 37, 'exponent': 3},
  'id': 'toolu_01VDU6X3ugDb9cpnnmCZFPbC',
  'output': 50653}]