news 2026/2/3 15:16:02

LangChain核心组件之Tools

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
LangChain核心组件之Tools

工具(Tools) 扩展了 智能体(Agents) 的能力,使其能够获取实时数据、执行代码、查询外部数据库,并在现实世界中执行操作。

在底层,工具本质上是具有明确定义输入和输出的可调用函数,这些函数会被传递给 聊天模型(Chat Model)。模型会根据对话上下文决定是否调用某个工具,并确定应传入哪些参数。

关于模型如何处理工具调用的详细说明,请参阅 工具调用(Tool Calling)。

创建工具

基础工具定义

创建工具最简单的方式是使用 @tool 装饰器。默认情况下,函数的文档字符串(docstring)会作为工具的描述,帮助模型理解何时应使用该工具:

fromlangchain.toolsimporttool@tooldefsearch_database(query:str,limit:int=10)->str:"""在客户数据库中搜索匹配指定查询条件的记录。 Args: query: 要搜索的关键词 limit: 返回结果的最大数量 """returnf"找到{limit}条关于 '{query}' 的结果"

类型提示(Type hints)是必需的,因为它们定义了工具的输入结构(input schema)。文档字符串应简洁且信息丰富,以帮助模型准确理解工具的用途。

服务端工具调用(Server-side tool use)
某些聊天模型(例如 OpenAI、Anthropic 和 Gemini)支持 内置工具(built-in tools),这些工具在服务端执行,例如网络搜索或代码解释器。请查阅 提供商概览(Provider Overview),了解如何在你使用的具体聊天模型中启用这些功能。

自定义工具属性
  1. 自定义工具名称
    默认情况下,工具名称取自函数名。如果需要更具描述性的名称,可以显式指定:
@tool("web_search")# 自定义名称defsearch(query:str)->str:"""在网络上搜索信息。"""returnf"搜索结果:{query}"print(search.name)# 输出: web_search
  1. 自定义工具描述
    你可以覆盖自动生成的工具描述,为模型提供更清晰的使用指引:
@tool("calculator",description="执行算术运算。遇到任何数学问题都应使用此工具。")defcalc(expression:str)->str:"""计算数学表达式。"""returnstr(eval(expression))
  1. 高级输入结构定义
    对于复杂输入,可以使用 Pydantic 模型或 JSON Schema 进行定义:
  • Pydantic 模型
frompydanticimportBaseModel,FieldfromtypingimportLiteralclassWeatherInput(BaseModel):"""Input for weather queries."""location:str=Field(description="City name or coordinates")units:Literal["celsius","fahrenheit"]=Field(default="celsius",description="Temperature unit preference")include_forecast:bool=Field(default=False,description="Include 5-day forecast")@tool(args_schema=WeatherInput)defget_weather(location:str,units:str="celsius",include_forecast:bool=False)->str:"""Get current weather and optional forecast."""temp=22ifunits=="celsius"else72result=f"Current weather in{location}:{temp}degrees{units[0].upper()}"ifinclude_forecast:result+="\nNext 5 days: Sunny"returnresult
  • JSON Schema
weather_schema={"type":"object","properties":{"location":{"type":"string"},"units":{"type":"string"},"include_forecast":{"type":"boolean"}},"required":["location","units","include_forecast"]}@tool(args_schema=weather_schema)defget_weather(location:str,units:str="celsius",include_forecast:bool=False)->str:"""Get current weather and optional forecast."""temp=22ifunits=="celsius"else72result=f"Current weather in{location}:{temp}degrees{units[0].upper()}"ifinclude_forecast:result+="\nNext 5 days: Sunny"returnresult
  1. 保留参数名
    以下参数名已被系统保留,不能用作工具参数,否则会导致运行时错误:
参数名用途说明
config保留用于内部向工具传递 RunnableConfig
runtime保留用于 ToolRuntime 参数(用于访问状态、上下文、存储等)

若需访问运行时信息,请使用 ToolRuntime 参数,而不是自行定义名为 config 或 runtime 的参数。

访问上下文(Accessing Context)

为什么这很重要?当工具能够访问智能体状态、运行时上下文和长期记忆时,其能力最为强大。这使得工具能做出上下文感知的决策、个性化响应,并在多轮对话中保持信息一致性。
运行时上下文(Runtime Context)允许你在运行时将依赖项(如数据库连接、用户 ID 或配置)注入工具,从而提升工具的可测试性和复用性。

通过 ToolRuntime 参数,工具可以访问以下运行时信息:

  • State(状态):在执行过程中流动的可变数据(如消息列表、计数器、自定义字段)
  • Context(上下文):不可变的配置信息,如用户 ID、会话详情或应用特定配置
  • Store(存储):跨会话的持久化长期记忆
  • Stream Writer(流写入器):在工具执行过程中流式输出自定义更新
  • Config(配置):当前执行的 RunnableConfig
  • Tool Call ID(工具调用 ID):当前工具调用的唯一标识符

ToolRuntime

使用 ToolRuntime 可以在一个参数中统一访问所有运行时信息。只需在工具函数签名中添加 runtime: ToolRuntime,系统会自动注入该参数,而不会暴露给大语言模型(LLM)。

ToolRuntime是一个统一参数,为工具提供对状态、上下文、存储、流写入、配置和工具调用 ID 的访问能力。它取代了旧版中分散使用的InjectedStateInjectedStoreget_runtimeInjectedToolCallId等注解。
运行时会自动为你提供这些能力,无需显式传递参数或依赖全局状态。

访问状态(State)

工具可通过 ToolRuntime 访问当前图(graph)的状态:

fromlangchain.toolsimporttool,ToolRuntime# 访问当前对话状态@tooldefsummarize_conversation(runtime:ToolRuntime)->str:"""总结当前对话内容。"""messages=runtime.state["messages"]human_msgs=sum(1forminmessagesifm.__class__.__name__=="HumanMessage")ai_msgs=sum(1forminmessagesifm.__class__.__name__=="AIMessage")tool_msgs=sum(1forminmessagesifm.__class__.__name__=="ToolMessage")returnf"对话包含{human_msgs}条用户消息、{ai_msgs}条 AI 回复和{tool_msgs}条工具结果"# 访问自定义状态字段@tooldefget_user_preference(pref_name:str,runtime:ToolRuntime# ToolRuntime 对模型不可见)->str:"""获取用户的某项偏好设置。"""preferences=runtime.state.get("user_preferences",{})returnpreferences.get(pref_name,"未设置")

runtime参数对模型是隐藏的。以上例中,模型在工具 Schema 中仅看到pref_name不会看到runtime

更新状态(Updating State)

使用 Command 可更新智能体状态或控制图的执行流程:

fromlanggraph.typesimportCommandfromlangchain.messagesimportRemoveMessagefromlanggraph.graph.messageimportREMOVE_ALL_MESSAGESfromlangchain.toolsimporttool,ToolRuntime# 清空对话历史@tooldefclear_conversation()->Command:"""清空对话历史。"""returnCommand(update={"messages":[RemoveMessage(id=REMOVE_ALL_MESSAGES)],})# 更新用户姓名@tooldefupdate_user_name(new_name:str,runtime:ToolRuntime)->Command:"""更新用户姓名。"""returnCommand(update={"user_name":new_name})
上下文(Context)

通过 runtime.context 可访问不可变的配置和上下文数据,如用户 ID、会话信息或应用配置:

fromdataclassesimportdataclassfromlangchain_openaiimportChatOpenAIfromlangchain.agentsimportcreate_agentfromlangchain.toolsimporttool,ToolRuntime USER_DATABASE={"user123":{"name":"Alice Johnson","account_type":"Premium","balance":5000,"email":"alice@example.com"},"user456":{"name":"Bob Smith","account_type":"Standard","balance":1200,"email":"bob@example.com"}}@dataclassclassUserContext:user_id:str@tooldefget_account_info(runtime:ToolRuntime[UserContext])->str:"""获取当前用户的账户信息。"""user_id=runtime.context.user_idifuser_idinUSER_DATABASE:user=USER_DATABASE[user_id]returnf"账户持有人:{user['name']}\n类型:{user['account_type']}\n余额:${user['balance']}"return"用户未找到"model=ChatOpenAI(model="gpt-4o")agent=create_agent(model,tools=[get_account_info],context_schema=UserContext,system_prompt="你是一名金融助手。")result=agent.invoke({"messages":[{"role":"user","content":"我的当前余额是多少?"}]},context=UserContext(user_id="user123"))
记忆(Memory / Store)

通过 runtime.store 可访问跨会话的持久化数据。存储(Store)允许你保存和检索用户或应用级别的长期信息:

fromtypingimportAnyfromlanggraph.store.memoryimportInMemoryStorefromlangchain.agentsimportcreate_agentfromlangchain.toolsimporttool,ToolRuntime# 读取用户信息@tooldefget_user_info(user_id:str,runtime:ToolRuntime)->str:"""查询用户信息。"""store=runtime.store user_info=store.get(("users",),user_id)returnstr(user_info.value)ifuser_infoelse"未知用户"# 保存用户信息@tooldefsave_user_info(user_id:str,user_info:dict[str,Any],runtime:ToolRuntime)->str:"""保存用户信息。"""store=runtime.store store.put(("users",),user_id,user_info)return"用户信息保存成功。"store=InMemoryStore()agent=create_agent(model,tools=[get_user_info,save_user_info],store=store)# 第一次会话:保存用户信息agent.invoke({"messages":[{"role":"user","content":"保存以下用户信息:userid: abc123, name: Foo, age: 25, email: foo@langchain.dev"}]})# 第二次会话:读取用户信息agent.invoke({"messages":[{"role":"user","content":"获取 ID 为 'abc123' 的用户信息"}]})# 输出示例:# - 姓名:Foo# - 年龄:25# - 邮箱:foo@langchain.dev
流写入器(Stream Writer)

通过 runtime.stream_writer,工具可在执行过程中流式输出自定义更新,适用于向用户提供实时反馈:

fromlangchain.toolsimporttool,ToolRuntime@tooldefget_weather(city:str,runtime:ToolRuntime)->str:"""获取指定城市的天气。"""writer=runtime.stream_writer# 在执行过程中流式输出进度writer(f"正在查询城市{city}的数据...")writer(f"已获取{city}的天气数据")returnf"{city}永远阳光明媚!"

若在工具中使用runtime.stream_writer,则必须在 LangGraph 的执行上下文中调用该工具。更多详情请参阅 流式处理(Streaming)。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/1/14 18:55:27

【毕业设计】机器学习基于python深度学习的会飞的昆虫识别

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

作者头像 李华
网站建设 2026/2/3 13:30:30

硬核!使用 eBPF kprobe 高性能解码 HTTP2 压缩头

摘要:本文介绍了 DeepFlow 新增的基于 eBPF kprobe 的 HTTP2/gRPC 压缩头部高性能解码能力。针对 HTTP2 协议使用 HPACK 算法压缩头部导致难以通过内核探针直接获取字段的问题,DeepFlow 通过自动学习通信双方的动态压缩字典,实现了无需依赖 u…

作者头像 李华
网站建设 2026/1/29 17:43:52

亚马逊卖家技术指南:符合平台规则的店铺评价优化策略

在亚马逊上,79%的消费者认为用户评论与亲友推荐同等重要,而自发留评率仅有1%-3%,一个小众却实用的运营方法正在成为卖家弥补这一巨大落差的关键。在亚马逊平台,产品评价直接影响商品的搜索排名和消费者购买决策。根据行业数据&…

作者头像 李华
网站建设 2026/1/31 12:42:42

基于微信小程序的小区物业管理系统(毕设源码+文档)

课题说明随着城市化进程的加快与小区管理精细化需求的提升,传统小区物业管理存在服务响应滞后、信息传递不及时、业主办事流程繁琐、缴费不便等问题,难以满足业主多元化的居住服务需求。本课题聚焦小区物业管理的实际痛点,设计并实现一款基于…

作者头像 李华
网站建设 2026/2/3 0:32:28

《实战代码揭秘:快速构建一个可对接多AI平台的GEO内容分发中间件》

内容定位: 实战、代码、接地气。符合CSDN开发者偏好具体技术实现、代码片段的阅读习惯。核心提纲与差异化亮点:引言:从一个具体开发任务开始开场白:“产品经理扔来需求:下周要让我们的课程内容同时被豆包和DeepSeek推荐…

作者头像 李华