如何在链中使用工具
在本指南中,我们将介绍创建调用工具的链和代理的基本方法。工具可以是任何东西——API、函数、数据库等。工具使我们能够扩展模型的能力,不仅仅是输出文本/消息。将模型与工具结合使用的关键在于正确提示模型并解析其响应,以便它选择正确的工具并为其提供正确的输入。
设置
我们需要安装以下软件包以进行本指南:
%pip install --upgrade --quiet langchain
如果您希望在 LangSmith 中跟踪您的运行,请取消注释并设置以下环境变量:
import getpass
import os
# os.environ["LANGCHAIN_TRACING_V2"] = "true"
# os.environ["LANGCHAIN_API_KEY"] = getpass.getpass()
创建一个工具
首先,我们需要创建一个可以调用的工具。对于这个例子,我们将从一个函数创建一个自定义工具。有关创建自定义工具的更多信息,请参见 本指南。
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
print(multiply.name)
print(multiply.description)
print(multiply.args)
multiply
multiply(first_int: int, second_int: int) -> int - Multiply two integers together.
{'first_int': {'title': 'First Int', 'type': 'integer'}, 'second_int': {'title': 'Second Int', 'type': 'integer'}}
multiply.invoke({"first_int": 4, "second_int": 5})
20
链
如果我们知道只需要固定次数地使用某个工具,我们可以为此创建一个链。让我们创建一个简单的链,仅仅是乘以用户指定的数字。
工具/函数调用
使用工具与 LLM 交互的最可靠方法之一是使用工具调用 APIs(有时也称为函数调用)。这仅适用于明确支持工具调用的模型。您可以在 这里 查看哪些模型支持工具调用,并在 本指南 中了解如何使用工具调用。
首先,我们将定义我们的模型和工具。我们将从一个工具 multiply
开始。
- OpenAI
- Anthropic
- Azure
- Cohere
- NVIDIA
- FireworksAI
- Groq
- MistralAI
- TogetherAI
pip install -qU langchain-openai
import getpass
import os
os.environ["OPENAI_API_KEY"] = getpass.getpass()
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-4o-mini")
pip install -qU langchain-anthropic
import getpass
import os
os.environ["ANTHROPIC_API_KEY"] = getpass.getpass()
from langchain_anthropic import ChatAnthropic
llm = ChatAnthropic(model="claude-3-5-sonnet-20240620")
pip install -qU langchain-openai
import getpass
import os
os.environ["AZURE_OPENAI_API_KEY"] = getpass.getpass()
from langchain_openai import AzureChatOpenAI
llm = AzureChatOpenAI(
azure_endpoint=os.environ["AZURE_OPENAI_ENDPOINT"],
azure_deployment=os.environ["AZURE_OPENAI_DEPLOYMENT_NAME"],
openai_api_version=os.environ["AZURE_OPENAI_API_VERSION"],
)
pip install -qU langchain-google-vertexai
import getpass
import os
os.environ["GOOGLE_API_KEY"] = getpass.getpass()
from langchain_google_vertexai import ChatVertexAI
llm = ChatVertexAI(model="gemini-1.5-flash")
pip install -qU langchain-cohere
import getpass
import os
os.environ["COHERE_API_KEY"] = getpass.getpass()
from langchain_cohere import ChatCohere
llm = ChatCohere(model="command-r-plus")
pip install -qU langchain-nvidia-ai-endpoints
import getpass
import os
os.environ["NVIDIA_API_KEY"] = getpass.getpass()
from langchain import ChatNVIDIA
llm = ChatNVIDIA(model="meta/llama3-70b-instruct")
pip install -qU langchain-fireworks
import getpass
import os
os.environ["FIREWORKS_API_KEY"] = getpass.getpass()
from langchain_fireworks import ChatFireworks
llm = ChatFireworks(model="accounts/fireworks/models/llama-v3p1-70b-instruct")
pip install -qU langchain-groq
import getpass
import os
os.environ["GROQ_API_KEY"] = getpass.getpass()
from langchain_groq import ChatGroq
llm = ChatGroq(model="llama3-8b-8192")
pip install -qU langchain-mistralai
import getpass
import os
os.environ["MISTRAL_API_KEY"] = getpass.getpass()
from langchain_mistralai import ChatMistralAI
llm = ChatMistralAI(model="mistral-large-latest")
pip install -qU langchain-openai
import getpass
import os
os.environ["TOGETHER_API_KEY"] = getpass.getpass()
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
base_url="https://api.together.xyz/v1",
api_key=os.environ["TOGETHER_API_KEY"],
model="mistralai/Mixtral-8x7B-Instruct-v0.1",
)
我们将使用 bind_tools
将工具的定义作为每次调用模型的一部分传递,以便模型在适当的时候可以调用该工具:
llm_with_tools = llm.bind_tools([multiply])
当模型调用该工具时,这将显示在输出的 AIMessage.tool_calls
属性中:
msg = llm_with_tools.invoke("whats 5 times forty two")
msg.tool_calls
[{'name': 'multiply',
'args': {'first_int': 5, 'second_int': 42},
'id': 'call_cCP9oA3tRz7HDrjFn1FdmDaG'}]
查看 LangSmith 跟踪信息。
调用工具
太好了!我们能够生成工具调用。但是如果我们想实际调用工具呢?为此,我们需要将生成的工具参数传递给我们的工具。作为一个简单的例子,我们将提取第一个 tool_call 的参数:
from operator import itemgetter
chain = llm_with_tools | (lambda x: x.tool_calls[0]["args"]) | multiply
chain.invoke("What's four times 23")
92
请查看 LangSmith 追踪这里。
代理
当我们知道任何用户输入所需的工具使用的特定顺序时,链非常适合。但对于某些用例,我们使用工具的次数取决于输入。在这些情况下,我们希望让模型自己决定使用工具的次数和顺序。代理可以让我们做到这一点。
LangChain 提供了许多内置代理,这些代理针对不同的用例进行了优化。可以在这里阅读所有代理类型。
我们将使用工具调用代理,这通常是最可靠的类型,也是大多数用例推荐的类型。
from langchain import hub
from langchain.agents import AgentExecutor, create_tool_calling_agent
# Get the prompt to use - can be replaced with any prompt that includes variables "agent_scratchpad" and "input"!
prompt = hub.pull("hwchase17/openai-tools-agent")
prompt.pretty_print()
================================[1m 系统消息 [0m================================
你是一个有帮助的助手
=============================[1m 消息占位符 [0m=============================
[33;1m[1;3m{chat_history}[0m
================================[1m 人类消息 [0m=================================
[33;1m[1;3m{input}[0m
=============================[1m 消息占位符 [0m=============================
[33;1m[1;3m{agent_scratchpad}[0m
代理也很棒,因为它们使使用多个工具变得简单。
@tool
def add(first_int: int, second_int: int) -> int:
"将两个整数相加。"
return first_int + second_int
@tool
def exponentiate(base: int, exponent: int) -> int:
"将底数提升到指数的幂。"
return base**exponent
tools = [multiply, add, exponentiate]
# 构建工具调用代理
agent = create_tool_calling_agent(llm, tools, prompt)
# 通过传入代理和工具创建代理执行器
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
使用代理,我们可以提出需要任意多次使用工具的问题:
agent_executor.invoke(
{
"input": "将 3 提升到五次方,并将其乘以 12 和 3 的和,然后平方整个结果"
}
)
[1m> 进入新的 AgentExecutor 链...[0m
[32;1m[1;3m
调用: `exponentiate`,参数为 `{'base': 3, 'exponent': 5}`
[0m[38;5;200m[1;3m243[0m[32;1m[1;3m
调用: `add`,参数为 `{'first_int': 12, 'second_int': 3}`
[0m[33;1m[1;3m15[0m[32;1m[1;3m
调用: `multiply`,参数为 `{'first_int': 243, 'second_int': 15}`
[0m[36;1m[1;3m3645[0m[32;1m[1;3m
调用: `exponentiate`,参数为 `{'base': 405, 'exponent': 2}`
[0m[38;5;200m[1;3m13286025[0m[32;1m[1;3m将 3 提升到五次方的结果是 243。
12 和 3 的和是 15。
将 243 乘以 15 得到 3645。
最后,3645 的平方是 13286025。[0m
[1m> 完成链。[0m
{'input': '将 3 提升到五次方,并将其乘以 12 和 3 的和,然后平方整个结果',
'output': '将 3 提升到五次方的结果是 243。 \n\n12 和 3 的和是 15。 \n\n将 243 乘以 15 得到 3645。 \n\n最后,3645 的平方是 13286025。'}
查看 LangSmith 跟踪。