“工具”在 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 指南中了解更多关于从函数创建工具的信息,请参阅 Python 和 JavaScript。
- 此外,任何 LangChain runnable 现在都可以转换为工具,从而更容易重用现有的 LangChain runnable,包括 chains 和 agents。重用现有的 runnable 减少了冗余,并允许您更快地部署新功能。例如,下面我们将一个 LangGraph agent 配置了另一个“用户信息 agent”作为工具,使其能够将相关问题委托给辅助 agent。
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 文档中查看如何将 runnables 用作工具。
灵活的工具输入
工具必须处理来自不同数据源和用户交互的多样化输入。验证这些输入可能很麻烦,尤其是在确定哪些输入应该由模型生成,哪些应该由其他来源提供时。
- 在 LangChain 中,您现在可以将模型生成的 ToolCalls 直接传递给工具(请参阅 Python, JS 文档)。虽然这简化了执行由模型调用的工具,但在某些情况下,我们不希望工具的所有输入都由模型生成。例如,如果我们的工具需要某种类型的用户 ID,则此输入很可能来自我们代码的其他位置,而不是来自模型。对于这些情况,我们添加了注释 ,以指定哪些工具输入不应由模型生成。请在此处查看文档 (Python, JS)。
- 我们还添加了关于如何在 Python 和 JavaScript 中将 LangGraph 状态传递给工具的文档。我们还使工具可以访问与运行相关的
RunnableConfig
对象。这对于参数化工具行为、通过链传递全局参数以及访问 Run IDs 等元数据非常有用—— Run IDs 提供了对工具管理的更多控制。阅读文档 (Python, JS)。
丰富的工具输出
使用附加数据丰富您的工具输出可以帮助您在后续操作或流程中使用这些输出,从而提高开发人员的效率。
- LangChain 中的工具现在可以返回下游组件中需要的结果,但这些结果不应作为通过 ToolMessages 中的
artifact
属性发送给模型的内容的一部分。工具还可以返回 ToolMessages 以自行设置artifact
,从而使开发人员可以更好地控制输出管理。请在此处查看文档 (Python, JS)。 - 我们还使工具能够流式传输 自定义事件,提供实时反馈,从而提高工具的可用性。请在此处查看文档 (Python, JS)。
稳健地处理工具调用错误
工具可能会因各种原因而失败——因此,实施回退机制并学习如何优雅地处理这些故障对于维护应用程序的稳定性非常重要。为了支持这一点,我们添加了:
- 关于如何使用 prompt engineering 和回退来处理工具调用错误的文档 (Python, JS)。
- 关于如何在您的 LangGraph 图中使用 flow engineering 来处理工具调用错误的文档 (Python, JS)。
接下来是什么
在接下来的几周里,我们将继续添加关于定义工具和设计使用工具的架构的指南和最佳实践。我们还将更新我们众多工具和工具包集成的文档。这些努力旨在帮助用户在构建上下文感知推理应用程序时最大限度地发挥 LangChain 工具的潜力。
如果您还没有这样做,请查看我们的文档以了解更多关于 LangChain for Python 和 JavaScript 的信息。