在 LLM 的语境下,“工具” 是旨在被模型调用的实用程序。它们具有明确定义的模式,可以输入到模型中,并生成可以反馈给模型的输出。每当您希望模型控制部分代码或调用外部 API 时,都需要工具,这使得它们成为 LLM 应用程序的基本构建块。
在过去几周中,我们一直专注于改进我们的核心工具接口和文档。这些更新使以下操作变得更加容易:
- 将任何代码转换为工具
- 将不同类型的输入传递给工具
- 从工具返回复杂的输出
- 使用架构创建更可靠的工具
让我们深入探讨以下在 LangChain 中集成、使用和管理工具的改进。
简化的工具定义
工具集成可能很复杂,通常需要手动操作,例如编写自定义包装器或接口。在 LangChain 中,我们从工具定义开始减少了复杂性。
- 您现在可以将任何 Python 函数传递到
ChatModel.bind_tools()
中,这允许直接使用普通 Python 函数作为工具。这简化了您定义工具的方式,因为 LangChain 只会解析类型注释和文档字符串以推断所需的模式。以下是一个模型必须从输入中提取地址列表并将其传递到工具中的示例
from typing import List
from typing_extensions import TypedDict
from langchain_anthropic import ChatAnthropic
class Address(TypedDict):
street: str
city: str
state: str
def validate_user(user_id: int, addresses: List[Address]) -> bool:
"""Validate user using historical addresses.
Args:
user_id: (int) the user ID.
addresses: Previous addresses.
"""
return True
llm = ChatAnthropic(
model="claude-3-sonnet-20240229"
).bind_tools([validate_user])
result = llm.invoke(
"Could you validate user 123? They previously lived at "
"123 Fake St in Boston MA and 234 Pretend Boulevard in "
"Houston TX."
)
result.tool_calls
[{'name': 'validate_user',
'args': {'user_id': 123,
'addresses': [{'street': '123 Fake St', 'city': 'Boston', 'state': 'MA'},
{'street': '234 Pretend Boulevard', 'city': 'Houston', 'state': 'TX'}]},
'id': 'toolu_011KnPwWqKuyQ3kMy6McdcYJ',
'type': 'tool_call'}]
相关的 LangSmith 跟踪 显示了工具模式如何在幕后被填充,包括将函数文档字符串解析为顶级和参数级描述。
在我们的针对 Python 和 JavaScript 的操作指南中,了解有关从函数创建工具的更多信息。
- 此外,任何 LangChain 可运行的 现在都可以转换为工具,这使得更容易重用现有的 LangChain 可运行的,包括链和代理。重用现有可运行的可以减少冗余,并允许您更快地部署新功能。例如,下面我们将一个 LangGraph 代理与另一个“用户信息代理”作为工具一起使用,使其能够将相关问题委托给辅助代理。
from typing import List, Literal
from typing_extensions import TypedDict
from langchain_openai import ChatOpenAI
from langgraph.prebuilt import create_react_agent
llm = ChatOpenAI(temperature=0)
user_info_agent = create_react_agent(llm, [validate_user])
class Message(TypedDict):
role: Literal["human"]
content: str
agent_tool = user_info_agent.as_tool(
arg_types={"messages": List[Message]},
name="user_info_agent",
description="Ask questions about users.",
)
agent = create_react_agent(llm, [agent_tool])
在我们的 Python 和 JavaScript 文档中,了解如何使用可运行的作为工具。
灵活的工具输入
工具必须处理来自不同数据源和用户交互的多种输入。验证这些输入可能很麻烦,尤其是确定哪些输入应该由模型生成,而哪些应该由其他来源提供。
- 在 LangChain 中,您现在可以将模型生成的 ToolCalls 直接传递给工具(见 Python、JS 文档)。虽然这简化了由模型调用的工具的执行,但也有一些情况是我们不希望所有工具输入都由模型生成。例如,如果我们的工具需要某种类型的用户 ID,则此输入可能来自我们代码中的其他地方,而不是来自模型。对于这些情况,我们添加了注释,这些注释指定哪些工具输入不应由模型生成。在下面的文档中查看这些注释 (Python、JS)。
- 我们还添加了有关如何将LangGraph 状态传递给工具的文档,见 Python 和 JavaScript。我们还使工具能够访问与运行关联的
RunnableConfig
对象。这对于参数化工具行为、通过链传递全局参数以及访问元数据(例如运行 ID)很有用,这些元数据提供了对工具管理的更多控制。阅读文档 (Python、JS)。
丰富的工具输出
使用更多数据丰富您的工具输出可以帮助您在后续操作或流程中使用这些输出,从而提高开发效率。
- LangChain 中的工具现在可以返回下游组件中需要的结果,但这些结果不应作为内容的一部分通过 ToolMessages 发送到模型。工具还可以返回 ToolMessages 来设置
artifact
本身,从而使开发人员能够更好地控制输出管理。在下面的文档中查看这些注释 (Python、JS)。 - 我们还使工具能够流式传输自定义事件,提供实时反馈,从而提高工具的可用性。在下面的文档中查看这些注释 (Python、JS)。
对工具调用错误的稳健处理
工具可能由于各种原因而失败,因此,实现回退机制以及学习如何优雅地处理这些失败对于维护应用程序稳定性至关重要。为了支持这一点,我们添加了
接下来是什么
在接下来的几周中,我们将继续添加有关定义工具和设计使用工具的架构的最佳实践和操作指南。我们还将更新对我们众多工具和工具包集成的文档。这些努力旨在让用户能够在构建上下文感知推理应用程序时最大限度地发挥 LangChain 工具的潜力。
如果您尚未查看,请查看我们的文档,详细了解针对 Python 和 JavaScript 的 LangChain。