LangChain框架之Tools:给 Agent 装上手脚

    |     2026年8月19日   |   AI大模型应用, LangChain框架   |     0 条评论   |    1

上篇你把 Prompt 模板、LCEL 和结构化输出跑通了——大脑会说话、会按字段吐结果。但旅游助手还要查天气、算行程、搜资料。这篇系统讲 Tools@tool 怎么定义,一轮调用与多步循环有何差别,多工具如何分包工程化。


小明的工具全堆在一个文件里

小明跟着快速入门篇写了 get_weatheradd,同事又要「搜一下什么是 LCEL」。他继续往同一个 tools.py 里塞:

@tool
def get_weather(...): ...

@tool
def add(...): ...

@tool
def mock_search(...): ...

@tool
def book_ticket(...): ...   # 越来越多

文件过三百行,system_prompt 写成「天气用 A,算术用 B,搜索用 C……」一长串。改搜索逻辑时还总误伤天气。一轮调用遇到「先查天气再算数」又不够用。

小明去找老张:”手脚我会装,但怎么长成一只手、再长成工具箱?”

老张说:”三层看:

  1. 单工具协议 —— @tool + schema
  2. 多步循环 —— 手写 loop 或 create_agent
  3. 分包 —— tools/ 目录 + TOOLS 列表”

什么是 Tools(Agent 的手脚)

老张在白板上写导图原话:

完整 Agent 至少两件套:
  模型 = 大脑 → 推理、规划
  工具 = 手脚 → 执行、与外界交互

@tool 交给模型的三件事:
  名称 = 函数名
  输入 = 函数入参
  作用 = 函数注释(docstring)

“调用方式近似普通函数:get_weather.invoke({\"city\": \"杭州\"})
LangChain 还有不少预定义外部工具,官网集成列表可按需接;本课先把本地 @tool 与分包吃透。”

阶段 你得到什么
定义 + 一轮 看清 bind_tools → tool_calls → ToolMessage
多步 agent-loop 多工具直到无 tool_calls;或 create_agent
multi-tools 分包 tools/*.py + 统一 TOOLS

代码拆解:从 @tool 到工具箱

1. 定义工具:名称、入参、注释

tools.py

from langchain.tools import tool


@tool
def get_weather(city: str) -> str:
  """查询城市天气(模拟数据)。"""
  data = {
    "北京""晴,15°C,东风3级",
    "上海""多云,18°C,南风2级",
    "杭州""小雨,17°C,东北风2级",
  }
  return data.get(city, f"{city}:晴,20°C(模拟)")


TOOLS = [get_weather]
TOOL_MAP = {t.name: t for t in TOOLS}

main.py 预览 schema:

print(get_weather.name, get_weather.description)
print(get_weather.args)

“模型看见的不是你的 Python 源码细节,而是这套 schema。注释写糊,它就选糊。”

2. 一轮工具调用(看清协议)

agent.py

def run_one_tool_round(question: str) -> str:
  model = get_chat_model(temperature=0)
  model_with_tools = model.bind_tools(TOOLS)

  messages = [HumanMessage(content=question)]
  ai = model_with_tools.invoke(messages)
  messages.append(ai)

  if not ai.tool_calls:
    return ai.content or ""

  for tc in ai.tool_calls:
    name, args = tc["name"], tc["args"]
    result = TOOL_MAP[name].invoke(args)
    messages.append(ToolMessage(content=str(result), tool_call_id=tc["id"]))

  final = model.invoke(messages)
  return final.content or ""

“节奏固定:bind_tools → 可能产生 tool_callsTOOL_MAP[...].invokeToolMessage 回填 → 再 invoke 出自然语言。
一轮版适合学协议;多步任务会不够”

3. agent-loop:多步直到结束

两个工具:

@tool
def get_weather(city: str) -> str:
  """查询城市天气(模拟)。"""
  ...

@tool
def add(a: float, b: float) -> str:
  """计算两数之和。"""
  return str(a + b)


TOOLS = [get_weather, add]

手写循环核心:

for step in range(1, max_steps + 1):
  ai = model_with_tools.invoke(messages)
  messages.append(ai)
  if not ai.tool_calls:
    return ai.content or ""
  for tc in ai.tool_calls:
    result = TOOL_MAP[tc["name"]].invoke(tc["args"])
    messages.append(ToolMessage(content=str(result), tool_call_id=tc["id"]))

框架版(快速入门篇已见):

agent = create_agent(
  get_chat_model(temperature=0),
  tools=TOOLS,
  system_prompt="你是助手。需要查天气或做加法时必须调用工具,不要编造。",
)

“停止条件:无 tool_calls → 结束;手写版还有 max_steps 强制收尾。验收题:「北京天气怎么样?再算 10+20。」——至少两个工具。”

4. multi-tools:分包工程化

目录:

multi-tools/
  tools/
  weather.py
  calculator.py
  search.py
  __init__.py  ← 汇总 TOOLS
  agent.py
  main.py

tools/weather.py 注释写清何时用

@tool
def get_weather(city: str) -> str:
  """查询中国城市当前天气(模拟数据)。用户问天气、气温、下雨时使用。"""
  ...

tools/__init__.py

from tools.calculator import calculator
from tools.search import mock_search
from tools.weather import get_weather

TOOLS = [get_weather, calculator, mock_search]

agent.py

def build_agent():
  return create_agent(
    get_chat_model(temperature=0),
    tools=TOOLS,
    system_prompt=(
      "你是助理。天气用 get_weather,算术用 calculator,"
      "其它查资料用 mock_search。不要编造工具结果。"
    ),
  )

“扩展口诀:新增文件 → 写入 TOOLS。system_prompt 只做路由提示,细节仍靠每个工具的 docstring。”

ask 里遍历消息打印调用轨迹,排障很香:

for m in result["messages"]:
  if name == "AIMessage" and getattr(m, "tool_calls"None):
    for tc in m.tool_calls:
      print(f"  [调用] {tc['name']}({tc['args']})")
  if name == "ToolMessage":
    print(f"  [结果] {m.content}")

小明复述:”@tool 交 schema;一轮看协议;循环干多步;多了就按文件分包,清单进 TOOLS。”


总结

老张说:”第六篇只办一件事——把手脚从「能用」升级到「好管」。”

“三个核心理解:

  1. @tool = schema 工厂 —— 名称、入参、注释交给模型
  2. 一轮学协议,多步才叫 Agent —— 无 tool_calls 结束;框架可用 create_agent
  3. 多工具必分包 —— tools/*.py + TOOLS 清单,system_prompt 做路由”

LangChain 支线进度:

… → Prompts / LCEL / 结构化输出
    ↓
Tools 与 Tool Agent(本篇)
    ↓
Memory → AI私厨实战 → Runtime → …

小明说:”下一篇该给 Agent 装记忆了——不然每轮都像失忆。”

“对。下一篇:Memory:短期 / 持久化 / 管理策略。”

模型是大脑,工具是手脚;@tool 让模型看得见手脚说明书,分包让你还敢继续加手。

转载请注明来源:LangChain框架之Tools:给 Agent 装上手脚
本文链接地址:https://ai.zhousir.top/?p=3847

上一篇:

没有了

已经是最新文章
回复 取消