当前位置: 首页 > news >正文

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)。

http://www.cnnetsun.cn/news/464986.html

相关文章:

  • 环境仿真软件:SWAT_(8).SWAT软件的安装与配置
  • R MySQL 连接
  • 导师严选2026 AI论文工具TOP10:继续教育必备测评与推荐
  • 【2026亲测】彻底禁止Windows 10/11自动更新,一键禁止windows更新工具
  • 【例4-6】香甜的黄油(信息学奥赛一本通- P1345)
  • 鸿蒙开发者12月社区声望值月度榜单揭晓!
  • 深度学习毕设项目:基于python深度学习的会飞的昆虫识别机器学习
  • 明天就要发言?4个「演说急救技巧」,小白也能从容开口不翻车
  • 基于微信小程序的甜品外卖平台系统(毕设源码+文档)
  • 基于微信小程序的洗车服务平台系统(毕设源码+文档)
  • 基于微信小程序的乡镇中学教学管理系统的设计与实现(毕设源码+文档)
  • volatile的可见性、安全发布的秘密与ThreadLocal原理
  • 2025年大模型版本更新全景图:从入门到精通
  • AI + CATIA V5:一个完全由大模型设计的齿轮
  • ASTM D4169-16与ASTM D4169-2023e1中DC-13 核心差异对比(精简版)
  • AI产品经理转型指南:35-50万年薪不是梦,附4阶段学习路径_AI产品经理转型正确方法
  • python基于django的高等数学课程教辅资源系统的设计与实现_h27e4uy9
  • Vibe Kanban:Rust构建的AI编程代理编排平台
  • 基于 ANFIS 的非线性回归附Matlab代码
  • 【Rokid AR录屏功能逆向分析:通过蓝牙HCI抓包实现CXR SDK未提供的AR录屏功能】
  • 【毕业设计】python基于pytorch训练蔬菜识别基于人工智能训练蔬菜识别
  • 密歇根大学让AI视觉推理更靠谱:从“瞎猜“到“真看懂“的技术革命
  • lvgl之显示gif测试代码
  • 【程序员必藏】2025最新RL×LLM技术全景扫描:从全生命周期到推理增强,附60+开源模型与30+训练框架
  • 救命神器2026研究生必看TOP8 AI论文平台测评与推荐
  • 长城杯 WEB安全 AI WAF
  • “休眠当关机”,实现不动硬件的一键开关机
  • 学霸同款2026最新!9款AI论文写作软件测评:毕业论文高效写作指南
  • 微信小程序开发中,模拟器启动失败问题
  • AI写作助手测评:谁是最强创作大脑