在 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)。
- 我们还添加了关于如何在 Python 和 JavaScript 中**将 LangGraph 状态传递给工具**的文档。我们还使得工具能够访问与运行关联的
RunnableConfig对象。这对于参数化工具行为、将全局参数传递给链以及访问诸如 Run ID 之类的元数据非常有用 — 这使得对工具管理拥有更大的控制权。阅读文档(Python、JS)。
丰富的工具输出
用额外数据丰富工具输出可以帮助您在后续操作或过程中使用这些输出,从而提高开发人员的效率。
- LangChain 中的工具现在可以**返回下游组件所需的结果**,但这些结果不应通过 ToolMessages 中的
artifact属性发送给模型。工具还可以返回 ToolMessages 来自行设置artifact,让开发人员更好地控制输出管理。在此处查看文档(Python、JS)。 - 我们还使工具能够**流式传输自定义事件**,提供实时反馈,从而提高工具的可用性。在此处查看文档(Python、JS)。
强大的工具调用错误处理
工具可能因各种原因失败 — 因此,实现回退机制并学习如何优雅地处理这些失败对于保持应用程序的稳定性很重要。为了支持这一点,我们添加了
下一步
在接下来的几周里,我们将继续添加关于定义工具和设计使用工具的架构的操作指南和最佳实践。我们还将更新许多工具和工具包集成的文档。这些努力旨在让用户在构建上下文感知推理应用程序时,充分发挥 LangChain 工具的潜力。
如果您还没有这样做,请查看我们的文档,了解更多关于 LangChain for Python 和 JavaScript 的信息。