🌟 LangChain 30 天保姆级教程 · Day 23|Agent 进阶实战!Function Calling + 自动 Tool 注册,打造会“动

系列目标 :30 天从 LangChain 入门到企业级部署
今日任务:理解 ReAct Agent 原理 → 实现自定义 Tool → 构建"查订单 + 发通知"自动化工作流!


🤖 一、为什么需要 Function Calling?

普通聊天机器人只能"说",但企业需要 AI 能"做":

  • "帮我查订单 1001 的状态"
  • "如果已发货,发邮件通知客户"
  • "顺便查下今天北京天气"

传统 Chain 的局限

  • ❌ 固定流程,无法动态决策
  • ❌ 不能组合多个外部服务

解决方案

Agent + Tools ------ 让 LLM 自主规划调用工具整合结果
💡 今天,我们就用 LangChain 的 ReAct Agent + 自定义 Tool,打造一个会"思考+行动"的 AI 助手!


🧠 二、Agent 核心原理:ReAct 框架

ReAct = Reasoning(推理) + Acting(行动)

工作流程:

  1. 用户提问 → Agent 分析是否需要工具
  2. 若需要 → 选择合适 Tool + 生成参数
  3. 调用 Tool → 获取结果
  4. 基于结果生成最终回答(可多轮)

🔑 关键:LLM 必须支持 Function Calling(结构化输出)
Qwen 通过 Ollama 支持 Function Calling (需 ollama>=0.1.34


🛠️ 三、动手实践 1:定义自定义 Tool

假设我们有两个内部服务:

Tool 1:查询订单状态(模拟)

python 复制代码
# day23_agent_tools.py
from langchain_core.tools import tool

@tool
def get_order_status(order_id: str) -> str:
    """根据订单ID查询物流状态。输入必须是纯数字字符串,如 '1001'"""
    # 模拟数据库查询
    mock_db = {
        "1001": "已发货,快递单号 SF123456789CN",
        "1002": "处理中",
        "1003": "已签收"
    }
    return mock_db.get(order_id, "订单不存在")

Tool 2:发送邮件通知(模拟)

python 复制代码
@tool
def send_email(to: str, subject: str, body: str) -> str:
    """发送邮件给指定收件人"""
    # 模拟发送
    return f"✅ 邮件已发送至 {to},主题:{subject}"

✅ 使用 @tool 装饰器 → 自动提取函数名、描述、参数 schema!


🧩 四、动手实践 2:创建 ReAct Agent

步骤 1:初始化支持 Function Calling 的 LLM

ini 复制代码
# day23_react_agent.py
from langchain_ollama import ChatOllama

# 关键:启用 function calling(Ollama 会自动处理)
llm = ChatOllama(
    model="qwen:7b",
    temperature=0,
    format="json"  # 强制 JSON 输出(部分版本需要)
)

⚠️ 确保 Ollama 版本 ≥ 0.1.34,并已拉取最新 Qwen 模型:

复制代码
ollama pull qwen:7b

步骤 2:绑定 Tools 到 Agent

ini 复制代码
from langchain.agents import create_react_agent, AgentExecutor
from langchain import hub

# 加载 ReAct Prompt(官方模板)
prompt = hub.pull("hwchase17/react")

# 创建 Agent
agent = create_react_agent(
    llm=llm,
    tools=[get_order_status, send_email],  # 自动注册!
    prompt=prompt
)

# 创建执行器
agent_executor = AgentExecutor(
    agent=agent,
    tools=[get_order_status, send_email],
    verbose=True,
    handle_parsing_errors=True  # 容错
)

hub.pull("hwchase17/react") 是 LangChain 官方维护的 ReAct Prompt!


步骤 3:测试多步任务

ini 复制代码
# 场景:用户要求"查订单并通知"
query = "订单 1001 如果已发货,请发邮件通知 customer@example.com"

result = agent_executor.invoke({"input": query})
print("\n🤖 最终回答:", result["output"])

▶️ 执行过程(verbose=True 输出):

makefile 复制代码
Thought: 我需要先查询订单状态
Action: get_order_status
Action Input: {"order_id": "1001"}
Observation: 已发货,快递单号 SF123456789CN
Thought: 订单已发货,需要发送邮件
Action: send_email
Action Input: {"to": "customer@example.com", "subject": "您的订单已发货", "body": "订单 1001 已发货..."}
Observation: ✅ 邮件已发送至 customer@example.com...
Thought: 任务完成
Final Answer: 已为您查询订单 1001,状态为"已发货",并已发送邮件通知客户。

完美实现

  • 自主决策调用顺序
  • 正确解析参数
  • 整合多工具结果

🌐 五、进阶:自动注册目录下所有 Tool

避免手动导入每个函数:

python 复制代码
import inspect
from pathlib import Path

def auto_register_tools(tool_module_path: str):
    """自动注册指定模块下的所有 @tool 函数"""
    spec = importlib.util.spec_from_file_location("tools", tool_module_path)
    module = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(module)
    
    tools = []
    for name, obj in inspect.getmembers(module):
        if hasattr(obj, "_tool_name"):  # langchain tool 标记
            tools.append(obj)
    return tools

# 使用
tools = auto_register_tools("./my_company_tools.py")
agent_executor = AgentExecutor(agent=agent, tools=tools, ...)

💡 适用于微服务架构:每个业务域提供自己的 tools.py


⚠️ 六、注意事项 & 最佳实践

表格

问题 建议
LLM 不调用 Tool 在 Prompt 中强调"必须使用工具";检查函数描述是否清晰
参数解析错误 使用明确的类型注解(str, int);避免复杂嵌套
工具副作用(如真发邮件) 开发阶段用 Mock;生产加审批开关
循环调用 设置 max_iterations=5 防死循环
中文工具描述失效 确保 Ollama/Qwen 支持中文 Function Calling(Qwen 表现良好)

💡 安全建议

  • 所有 Tool 输入做校验(如 order_id.isdigit()
  • 敏感操作(如删数据)需人工确认
  • 记录完整 Action 日志用于审计

📦 七、配套代码结构

bash 复制代码
langchain-30-days/
└── day23/
    ├── my_company_tools.py   # 自定义 Tool 定义
    └── react_agent_main.py   # Agent 创建与执行

📝 八、今日小结

  • ✅ 理解了 ReAct Agent 的"推理+行动"机制
  • ✅ 学会了用 @tool 装饰器定义自定义工具
  • ✅ 实现了多步任务自动化(查订单 → 发邮件)
  • ✅ 掌握了自动注册 Tool 的工程技巧
  • ✅ 知道了安全与容错的最佳实践

🎯 明日预告:Day 24 ------ Plan-and-Execute Agent!让 AI 先制定计划再执行,解决复杂任务!

相关推荐
Csvn1 小时前
🌟 LangChain 30 天保姆级教程 · Day 22|长文档处理三剑客!MapReduce、Refine、Map-Rerank,让 AI 消化整本手册
python·langchain
John.Lewis2 小时前
Python小课(1)认识Python
开发语言·python
Polar__Star2 小时前
SQL中如何实现特定顺序的查询:CASE WHEN自定义排序
jvm·数据库·python
u0109147602 小时前
mysql如何配置监听IP_mysql bind-address多地址设置
jvm·数据库·python
a9511416422 小时前
如何配置RMAN使用第三方备份软件接口_NetBackup或Commvault的MML层整合
jvm·数据库·python
踏着七彩祥云的小丑2 小时前
Python——requests——响应码
python
Ulyanov2 小时前
Apache Kafka在雷达仿真数据流处理中的应用
分布式·python·kafka·apache·雷达电子战
u0109147602 小时前
CSS如何处理超长文本换行问题_结合word-wrap属性
jvm·数据库·python
电化学仪器白超2 小时前
小乌龟Git全程图形化操作指南:嵌入式本地版本管理与Gitee私有云备份实战
git·python·单片机·嵌入式硬件·物联网·gitee·自动化