在 LangGraph 中定义“工具”(Tool)
·
在 LangGraph 中定义“工具”(Tool),本质上是将普通的 Python 函数或外部能力(如API)封装起来,供图中的大模型(LLM)节点调用。
🔧 定义工具的基本方法
完整的工具定义与集成流程可以概括为以下几步,你可以通过这个代码结构图快速了解:
对图中的关键环节进行说明:
1. 创建工具函数
最简单的方法是使用 @tool 装饰器。你需要为函数提供清晰的名称和描述,因为LLM主要依赖这些来决定何时以及如何使用它。
from langchain.tools import tool
@tool
def search_web(query: str) -> str:
"""根据用户的问题执行网页搜索。"""
# 调用搜索引擎API
return f"关于 '{query}' 的搜索结果..."
也可以使用 args_schema 参数来定义更严谨的输入模型(使用Pydantic),或通过 return_direct=True 让代理在调用此工具后直接结束
2. 将工具绑定到模型
创建工具列表后,需要将它们绑定到LLM,使其知道这些工具的存在和调用方式
tools = [search_web, calculator]
model = ChatOpenAI(model="gpt-4")
model_with_tools = model.bind_tools(tools) # 或使用 bind_functions
3. 在图中集成工具
通常,你会创建一个专门的工具执行节点。LangGraph 提供了预置的 ToolNode 来简化这一步,它支持并行执行、错误处理等。
from langgraph.prebuilt import ToolNode, ToolExecutor
# 使用预置节点
tool_node = ToolNode(tools)
# 或者,自定义一个工具节点
tool_executor = ToolExecutor(tools)
def execute_tools(state):
# 处理LLM的工具调用请求
action = state['messages'][-1].tool_calls[0]
result = tool_executor.invoke(action)
return {"messages": [ToolMessage(content=result, name=action.tool)]}
-
然后将这个节点添加到图中,并通过条件边将其与LLM推理节点连接起来,形成一个“思考-行动”的循环。
⚠️ 核心注意事项与最佳实践
为了让工具在图中稳定可靠地工作,需要注意以下几点:
| 注意事项 | 说明与建议 |
|---|---|
| 1. 工具描述 | 清晰、准确的描述至关重要,直接决定LLM能否正确调用它。避免模糊,说明输入格式和用途。 |
| 2. 状态读写 | 工具可以直接读取和更新图的状态。通过 InjectedState 访问,或通过返回值更新状态,这能用于传递中间结果。 |
| 3. 错误处理 | 工具调用可能失败。使用 ToolNode 时,可利用其内置的 handle_tool_errors 参数来捕获异常并返回友好信息给LLM,避免图运行中断。 |
| 4. 隐藏参数 | 如果工具需要API密钥、用户ID等不应由LLM控制的参数,应将其放在图的 config 或 state 中,在工具函数内部读取,而非暴露给模型。 |
| 5. 工具数量 | 工具过多会增加LLM的认知负担和token消耗。可考虑根据任务动态筛选工具(如通过语义检索),而非一次性全部提供。 |
| 6. 控制流 | 必须通过条件边清晰定义何时调用工具、何时结束,否则容易产生无限循环。 |
| 7. 长期记忆 | 若需跨对话保存用户偏好等数据,可以使用LangGraph的长期记忆(存储)功能,工具和节点都能读写。 |
更多推荐


所有评论(0)