跳到正文
LangChain Blog·· 2026-08-26精选AI 评分62

LangChain 推出结构化工具与 StructuredChatAgent

Structured Tools

AI 导读

LangChain 发布结构化工具抽象,工具输入不再限于单个字符串,可接受任意数量、任意类型的参数,并新增配套的 StructuredChatAgent。结构化工具由 name、description、args_schema 以及 _run/_arun 定义,args_schema 基于 Pydantic BaseModel 负责向智能体说明所需参数并在执行前校验输入。

推荐理由

LangChain 官方说明结构化工具与配套智能体类,读者可据此判断旧工具链的兼容边界与迁移成本。

正文 · AI 翻译

TL;DR:我们引入了一种新的抽象,允许使用更复杂的工具。以前的工具只接受单个字符串输入,而新工具可以接受任意数量、任意类型的输入。我们还引入了一个新的 agent 类,可以很好地与这些新型工具配合使用。

重要链接:

早在 2022 年 11 月我们首次推出 LangChain 时,agent 和工具的使用就在我们的设计中占据了核心地位。我们基于 ReAct 构建了最早的链之一,这是一篇开创性的论文,将工具使用推到了提示框架的前沿。

在早期,工具使用非常简单。模型会生成两个字符串:

  1. 一个工具名称
  2. 所选工具的一个输入字符串

这种方法将 agent 限制为每轮只能使用一个工具,而且该工具的输入被限制为单个字符串。这些限制主要源于模型的约束;模型连这些基本任务都难以熟练完成。可靠地执行更复杂的操作,例如选择多个工具或填充复杂的 schema,简直是天方夜谭。

然而,像 text-davinci-003、gpt-3.5-turbo 和 gpt-4 这样更先进的语言模型的快速发展,提高了现有模型能够可靠达到的下限。这促使我们重新评估 LangChain agent 框架中工具使用的限制。

今年早些时候,我们引入了一个“多动作”agent 框架,agent 可以在 agent executor 的每一步规划多个要执行的动作。在此基础上,我们现在摆脱了单字符串输入的限制,自豪地提供结构化工具支持!

结构化工具使语言模型与工具之间能够进行更复杂、多方面的交互,从而更容易构建创新、适应性强且强大的应用。

什么是“结构化工具”?

结构化工具代表 agent 可以采取的一个动作。它包装你提供的任何函数,让 agent 可以轻松地与之交互。一个结构化工具对象由其以下部分定义:

  1. name:一个标签,告诉 agent 该选择哪个工具。例如,一个名为 "GetCurrentWeather" 的工具告诉 agent 它是用来查找当前天气的。
  2. description:一份简短的说明手册,解释 agent 应在何时以及为何使用该工具。
  3. args_schema:向 agent 传达该工具的接口。它通常来自被包装函数的签名,并允许对工具输入进行额外的验证逻辑。
  4. _run 和 _arun 函数:这些定义了工具的内部运作方式。它可以是简单的事情,比如返回当前时间,也可以是更复杂的事情,比如发送消息或控制机器人。

工具的 name 是它的唯一标识符。一个好的名称能明确传达它的用途,因此一个名为 “GetCurrentWeather” 的工具比 “GCTW” 有用得多。如果一个工具的名称对你来说都不清楚,那它对 agent 来说很可能也不清楚。如果你让 agent 访问多个工具,名称还可以提供它们之间关系的信息。例如,如果你有 “AmazonSearch” 和 “AmazonCurrentBalance” 以及 “NikeShoppingCart” 工具,agent 可以推断出前两个是相关的,即使不阅读描述也是如此。

description 提供了关于如何使用该工具的更详细指令。好的描述应简洁,但能有效说明工具的功能。如果需要,这里也可以留出空间提供简短示例(或反例)。

args_schema 是一个 Pydantic BaseModel,用于定义要传递给工具的参数(及其类型信息)。它有两个主要职责:第一,说明需要从 agent 获取哪些信息。第二,在执行工具内部功能之前验证这些输入。

最后,_run 以及配套的异步 _arun 方法定义了工具的逻辑。你可以在这里放入任何内容,从算术运算、API 请求,到调用其他 LLM Chain。

新的结构化工具

除了这个新的基类之外,我们还发布了以下新工具,它们都继承自这个结构化工具类。

  • 文件管理 - 一个工具包,涵盖你可能需要的所有文件系统操作,包括 write、grep、move、copy、list_dir、find
  • Web 浏览器 - 虽然我们之前有用于文档加载器的浏览器,但现在我们发布了一个官方的有状态 PlayWright Browser 工具包,让 agent 可以访问网站、点击、提交表单并查询数据

有关所有工具(旧版和新版)的列表,请参阅文档 here。

实现你自己的结构化工具

最快的入门方式是调用 StructuredTool.from_function(your_callable) 构造函数。

例如,假设你想要一个通过 requests 库与 Hugging Face 模型交互的工具。

import requests
from langchain.tools.base import StructuredTool

API_KEY = "<MY-API-KEY>"

def get_huggingface_models(
   path: Optional[str] = None, query_params: Optional[dict] = None
) -> dict:
   """Tool that calls GET on <https://huggingface.co/models*> apis. Valid params include "search":"search", "author":"author", "filter":"filter" and "sort":"sort"."""
   base_url = "<https://huggingface.co/api/models>"
   headers = {"authorization": f"Bearer {API_KEY}"}
   result = requests.get(base_url + (path or ""), params=query_params, headers=headers)
   return result.json()

get_huggingface_models_tool = StructuredTool.from_function(get_huggingface_models)
models = get_huggingface_models_tool.run({"query_params": {"search": "gpt-j"}})
print(models)

在幕后,这会从函数签名推断出 args_schema。它用于告诉 agent,它可以提供 query 参数进行搜索,以及提供 path 参数来调用其他  子端点。

如果你想对工具定义有更多控制, 可以直接继承 BaseTool。例如,也许你希望 api key 从环境变量中自动加载。

from typing import Optional, Type

import aiohttp
import requests

from langchain.callbacks.manager import (
   AsyncCallbackManagerForToolRun,
   CallbackManagerForToolRun,
)
from langchain.tools import BaseTool
from pydantic import BaseModel, BaseSettings, Field

class GetHuggingFaceModelsToolSchema(BaseModel):
   path: str = Field(default="", description="the api path")
   query_params: Optional[dict] = Field(
       default=None, description="Optional search parameters"
   )

class GetHuggingFaceModelsTool(BaseTool, BaseSettings):
   """My custom tool."""

   name: str = "get_huggingface_models"
   description: str = """Tool that calls GET on <https://huggingface.co/models*> apis. Valid params include "search":"search", "author":"author", "filter":"filter" and "sort":"sort"."""
   args_schema: Type[GetHuggingFaceModelsToolSchema] = GetHuggingFaceModelsToolSchema
   base_url: str = "<https://huggingface.co/api/models>"
   api_key: str = Field(..., env="HUGGINGFACE_API_KEY")

   @property
   def _headers(self) -> dict:
       return {"authorization": f"Bearer {self.api_key}"}

   def _run(
       self,
       path: str = "",
       query_params: Optional[dict] = None,
       run_manager: Optional[CallbackManagerForToolRun] = None,
   ) -> dict:
       """Run the tool"""
       result = requests.get(
           self.base_url + path, params=query_params, headers=self._headers
       )
       return result.json()

   async def _arun(
       self,
       path: str = "",
       query_params: Optional[dict] = None,
       run_manager: Optional[AsyncCallbackManagerForToolRun] = None,
   ) -> dict:
       """Run the tool asynchronously."""

       async with aiohttp.ClientSession() as session:
           async with session.get(
               self.base_url + path, params=query_params, headers=self._headers
           ) as response:
               return await response.json()

get_models_tool = GetHuggingFaceModelsTool()
models = get_models_tool.run({"query_params": {"search": "gpt-j"}})
print(models)

我如何使用结构化工具?

我们新增了一个 StructuredChatAgent,它可以原生地配合这些结构化工具使用。请参阅this page了解演练。

由于之前 agent 的默认提示词和输出解析器存在限制,如果不进行额外定制,它们无法有效配合结构化工具使用。

要开始使用,你可以使用以下代码片段实例化结构化聊天 agent executor:

from langchain.agents import initialize_agent, AgentType
from langchain.chat_models import ChatAnthropic
tools = [] # Add any tools here
llm = ChatAnthropic(temperature=0) # or any other LLM
agent_chain = initialize_agent(tools, llm, agent=AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION)

这些工具也与来自 langchain.experimental 的 AutoGPT agent 兼容。

FAQ

Q: 我可以在现有 agents 中使用结构化工具吗?

A: 如果你的结构化工具接受一个字符串参数:可以,它仍然可以与现有 agents 一起使用。但是,接受多个参数的结构化工具如果不进一步定制,则无法直接与以下 agents 兼容:

  • zero-shot-react-description
  • react-docstore
  • self-ask-with-search
  • conversational-react-description
  • chat-zero-shot-react-description
  • chat-conversational-react-description

Q: 我还能创建字符串 Tools 吗?

A: 你仍然可以使用 Tool 构造函数和 @tool 装饰器来定义简单的字符串工具。继承自 BaseTool 类并接受单个字符串参数的工具仍会被视为字符串工具。

Q: 我可以将之前定义的字符串 BaseTool 与为 StructuredTool 构建的新 agents 一起使用吗

A:  可以!结构化工具不需要新的 agent executors,旧工具向前兼容。原始的 Tool 类与 StructuredTool 共享同一个基类,换句话说,你的工具应该开箱即用。

期望 JSON 序列化字符串输入的工具可能需要一些修改才能与较新智能体的输出解析器互操作,或者它们可以更新为新格式,新格式应能更好地支持更复杂的接口。

来源:LangChain Blog · langchain.com