Dify 第4课:Agent 与工具编排


🎯 本课目标

  • 理解 Agent 的核心概念(ReAct / Function Calling)
  • 掌握 Dify Agent 的架构和工作原理
  • 能亲手搭建一个多工具 Agent 应用
  • 面试能聊透 Agent 选型、工具编排、异常处理

一、Agent 是什么——从概念讲起

AI Agent 的定义

Agent = LLM + 工具 + 自主决策能力

传统的大模型调用是:

用户问 → 模型答 (一次交互,完事)

Agent 模式是:

用户问 → 模型思考 → 决定调用工具 → 执行工具 → 模型分析结果 → 决定下一步
        ↓                                                     ↓
        可能需要多次循环                                   直到任务完成

为什么需要 Agent?

场景纯 LLMAgent
“查一下今天的天气”❌ LLM 不知道实时天气✅ 调用天气 API
“帮我翻译这个文件”⚠️ 只能翻短文本✅ 读文件 → 翻译 → 输出结果
“查订单然后退款”❌ 单步做不到✅ 查订单 → 验证 → 退款(多步)
“对比三家供应商价格”❌ 没数据✅ 多步搜索 → 整理对比表

LLM 的能力边界在没有外部信息源和行动能力的地方,Agent 就是来打破这个边界的。


二、Agent 的两大底层模式

2.1 ReAct(Reasoning + Acting)

Google 2023 年提出的框架,核心思路:边推理边行动,交替进行

Thought: 用户想知道北京的天气,我需要调用天气查询工具
Action: call weather_api(city="北京")
Observation: {"temp": 28, "condition": "晴", "humidity": 45%}
Thought: 查询到了,温度28度,晴天。总结回答
Answer: 北京今天28度,晴天,适合出门

ReAct 的关键:

  • LLM 每一步都要输出推理过程(Thought)
  • 然后决定执行什么 Action(工具调用)
  • 观察 Observation(工具返回的结果)
  • 再推理下一步,直到给出最终答案

2.2 Function Calling

OpenAI 提出的方式,比 ReAct 更结构化的工具调用协议:

LLM 收到用户问题
  ↓ 判断是否需要工具
输出:{"name": "get_weather", "arguments": {"city": "北京"}}
  ↓ 系统调用工具,返回结果
LLM 收到工具返回,生成最终回答

ReAct vs Function Calling 对比:

维度ReActFunction Calling
输出格式自然语言描述 Thought/ActionJSON 结构化 tools 调用
灵活性高(什么都能描述)中(必须按 schema 来)
可解析性低(需要解析 Thought 和 Action)高(JSON 直接解析)
适用复杂推理场景标准工具调用
Dify 支持✅(两者都有)

三、Dify Agent 架构

Dify Agent 的核心组件

用户输入
  ↓
┌────────────────────────────────────┐
│          Dify Agent Engine          │
│                                     │
│  ┌─────────┐    ┌───────────────┐  │
│  │ Prompt  │    │   模型调用     │  │
│  │ 模板    │ →  │ (LLM 推理)    │  │
│  └─────────┘    └───────┬───────┘  │
│                         │          │
│  ┌──────────────────────▼───────┐  │
│  │    工具调度器(Tool Router)   │  │
│  │  判断调哪个工具、调参数、解析结果 │  │
│  └──────────────────────┬───────┘  │
│                         │          │
│         ┌───────────────┼───────┐  │
│         ▼               ▼       ▼  │
│     内置工具       自定义工具   API  │
│  (搜索/计算/...)  (自定义代码)  (HTTP)│
│                                     │
│  ┌──────────────────────────────┐  │
│  │     循环控制器(Loop Control) │  │
│  │   检查是否结束/最大迭代次数   │  │
│  └──────────────────────────────┘  │
└────────────────────────────────────┘
  ↓
最终输出(或超时/错误终止)

Dify 支持的 Agent 类型

Dify 有两种 Agent 模式:

a) ReAct Agent(默认)
  • LLM 自主思考→行动→观察循环
  • 适合需要复杂推理的场景
b) Function Calling Agent
  • 基于 OpenAI/Fireworks/Azure 等支持 FC 的模型
  • 工具调用更稳定,参数解析更可靠

选型建议:

FC 模型(GPT-4o / Qwen 等)→ Function Calling Agent(更稳定)
非 FC 模型(部分开源模型)→ ReAct Agent(兼容性更好)
复杂多步场景 → ReAct(推理过程更透明)

四、Dify 的工具系统(核心)

4.1 内置工具

Dify 自带了开箱即用的工具:

工具用途
网页搜索调用搜索引擎获取实时信息
网页抓取抓取指定 URL 的内容
DALL-E 画图调用 DALL-E 生成图片
天气查询查实时天气
数学计算精确计算(LLM 算数不准时很有用)
时间日期当前时间
向量数据库知识库检索
获取当前时间时间相关
读取文件读取上传的文件

4.2 自定义工具(关键能力)

Dify 允许三种方式创建自定义工具:

a) 代码工具(最灵活)
# 写在 Dify 代码工具节点里的示例
def main(query: str, user_id: str) -> str:
    """
    根据用户ID查询订单信息。
    
    参数:
        query: 查询关键词或订单号
        user_id: 用户标识
    返回:
        订单信息的 JSON 字符串
    """
    # 这里可以写任意 Python 代码
    import json
    
    orders = db.query(f"SELECT * FROM orders WHERE user_id='{user_id}'")
    return json.dumps(orders, ensure_ascii=False)

特点:

  • 可以写任意 Python 代码
  • 可以请求外部 API、查数据库、处理文件
  • Dify 在沙箱中执行,有安全性保障
b) API 工具(HTTP Request)
通过 HTTP Request 节点调用外部 API:
  URL: https://api.openweathermap.org/data/2.5/weather
  Method: GET
  参数: {"q": "{city}", "appid": "{env.API_KEY}"}
  认证: API Key

特点:

  • 无需写代码,配置 URL + 参数即可
  • 支持 GET/POST/PUT/DELETE
  • 环境变量管理 API Key(安全)
c) OpenAPI/Swagger 导入
上传 OpenAPI 规范文件(swagger.json)
  → Dify 自动解析 API 定义
  → 生成对应的工具
  → Agent 直接可用

特点:

  • 零配置导入已有的 API 服务
  • 自动生成参数描述,LLM 理解得更准

4.3 工具描述的重要性(⚠️ 高频面试考点)

LLM 决定调用哪个工具的唯一依据是工具的描述文字。

# ❌ 差的描述
{
    "name": "get_weather",
    "description": "获取天气"  # 太模糊
}

# ✅ 好的描述
{
    "name": "get_weather",
    "description": "根据城市名称获取实时天气信息,包括温度、湿度、风力、天气状况等"
}

# 🏆 更好的描述(带参数说明)
{
    "name": "get_weather",
    "description": "查询指定城市的实时天气。用于回答用户关于天气、温度、是否适合出门等问题。",
    "parameters": {
        "city": {
            "type": "string",
            "description": "城市名称,中文,例如:北京、上海、广州"
        }
    }
}

面试题:「Agent 调错工具了,怎么办?」

90% 的情况是因为工具描述写得不够好。好的描述 = LLM 正确调用的前提,比代码逻辑本身还重要。参数说明要具体、示例值要有代表性。


五、Agent 策略配置

5.1 迭代次数(Iteration)

单轮(Single Round):
  LLM 只做一次工具调用,然后就回答
  适合:简单的搜索、查询场景

多轮(Multi Round):
  LLM 可以多次工具调用,逐步完成任务
  适合:复杂任务,如"帮我查张三的订单状态,如果已发货则催物流"

5.2 最大迭代次数

  • 默认:3-5 次
  • 建议:复杂任务 5-8 次,多了容易跑偏
  • 一定要设上限,防止 Agent 死循环

5.3 模型选择

Agent 对模型要求比普通对话高:

  • 必须选强推理模型(GPT-4o / Qwen-Plus / DeepSeek V4 Flash)
  • 弱模型在 Agent 模式下容易:tool 调用格式错误、选错工具、不理解 Observation

六、面试高频题(Agent 专场)

Q1:Agent 和 Workflow 有什么区别?什么场景用哪个?

Agent:
  由 LLM 自主决策调用路径
  适合:不确定的任务流程、需要推理的场景
  示例:客服机器人(用户问题不确定,需要 Agent 判断调什么工具)

Workflow:
  由开发者预定义执行路径
  适合:确定性的、重复性高的流程
  示例:退款流程(先查订单→验证身份→处理退款,步骤固定)

最佳实践:Workflow + Agent 混合
  工作流主体用 Workflow,某个节点用 Agent 做复杂判断

Q2:Agent 怎么处理工具调用失败?

1. Retry:自动重试(网络抖动)
2. 降级:工具不可用 → LLM 尝试其他方法完成目标
3. 报错:明确告知用户无法完成,而不是瞎编
4. 兜底:准备 fallback 工具

Q3:多个 Agent 如何协作?

单一 Agent 有上限—工具多了 LLM 会糊涂。

多 Agent 架构:
  用户 → 路由 Agent(判断走哪个子 Agent)
        ├→ 客服 Agent(工具:查订单、改地址)
        ├→ 技术支持 Agent(工具:查知识库、查日志)
        └→ 售后 Agent(工具:退款、退货)

每个子 Agent 只带 3-5 个工具,精度高很多。

Dify 自身不支持多 Agent 编排,但可以用 Workflow 节点层叠实现:一个 Agent 的输出作为下一个 Agent/Workflow 的输入。

Q4:对比一下 Dify Agent vs Coze Agent vs LangChain Agent?

Dify:
  开箱即用,可视化工具绑定,
  适合:产品化、中小规模生产

Coze(字节):
  插件生态丰富,人多,免费调用额度大
  适合:快速原型、个人使用
  缺点:数据在字节云上,企业级不适用

LangChain Agent:
  最灵活,底层控制力最强
  适合:需要深度定制的大规模场景
  缺点:代码量大,自己搭一套

💻 实操建议

今天建议你动手搭一个 Agent,可以选这个场景:

「智能客服 Agent」

  • 绑定知识库(查产品 FAQ)
  • 绑定天气工具(查发货地天气)
  • 绑定一个自定义的订单查询 API(模拟)
  • 用户问:帮我查一下订单 2024001 的发货状态,顺便看看最近发货地天气怎么样
  • Agent 需要:先查订单→拿到发货地→查天气→汇总回答

课后小测验

  1. ReAct 和 Function Calling 的核心区别是什么?Dify 里怎么选?
  2. Agent 的工具描述为什么这么重要?写一条好的例子看看。
  3. 一个 Agent 绑了 15 个工具,结果经常调错。你怎么解决?
  4. Agent 最大迭代次数设多少合适?设太大/太小各有什么问题?
  5. 多 Agent 架构和单 Agent 绑大量工具,你选哪个?为什么?

1. ReAct 和 Function Calling 的核心区别?Dify 里怎么选?

核心区别一句话:Function Calling 是模型主动说"我要调哪个",ReAct 是让模型自己写推理再决定调哪个。

维度Function CallingReAct
谁决定调工具模型原生能力,API 响应里直接带 tool_calls模型通过 “思考→行动→观察” 循环自己推理
实现机制模型训练时就有 tool schema 概念,原生输出结构化调用请求把工具描述塞进 prompt,让模型以文本形式"思考"再调用
推理过程可见黑盒——模型内部决策,用户看不到"为什么选这个工具"白盒——能看到模型的思考链路(Thought)
稳定性高——模型原生支持,解析确定中——依赖 prompt 质量,长 chain 可能走偏
多步推理弱——每次只调一个工具,复杂任务需要外部编排多轮强——天然支持"先查 A→根据结果调 B"的推理链

Dify 里怎么选:

  • 简单场景(单工具、翻译、摘要、天气查询)→ Function Calling,快、稳、省 tokens
  • 复杂场景(多步推理、需要根据上一步结果决定下一步)→ ReAct,推理过程可控
  • 模型支持:GPT-4、Claude 3.5+ 选 Function Calling 体验最好;小模型或开源模型优先 ReAct(很多小模型 FC 不准)

2. Agent 的工具描述为什么这么重要?写条好例子

重要性的根因:模型不认识你的工具函数名,只认识你的描述文字。描述就是模型的"操作说明书"。

写不好的后果:

  • 模型不知道该用哪个工具
  • 传的参数结构不对
  • 该调的时候不调,不该调的时候瞎调

好的例子 vs 差的例子:

# ❌ 差
name: get_weather
description: 获取天气
parameters: |
  city: string

# ✅ 好
name: get_weather
description: >
  根据城市名称查询实时天气和未来 3 天预报。
  当用户问"今天天气怎么样"、"明天会不会下雨"、"北京这周气温"时使用。
  注意:如果用户只说了"天气"没提城市,先反问用户具体城市再调用。
parameters: |
  city: string  # 城市名称,如"北京"、"上海"、"New York"。必填。

好描述的黄金法则:

  1. 什么场景触发 — “当用户问 XX 时使用”
  2. 参数说明清晰 — 格式、示例值、是否必填
  3. 边界情况处理 — 参数缺失怎么办
  4. 一句话定位 — 不要让模型在 15 个工具里猜

3. 一个 Agent 绑了 15 个工具,经常调错。怎么解决?

15 个工具对于大模型来说已经超载了,尤其是小模型。解法分层:

第一层:工具精简(最强效)

  • 先审计:这 15 个真的都需要吗?能不能合并?
  • 比如 5 个数据库查询工具 → 1 个通用查询工具 + 参数区分
  • 目标:控制在 8 个以内

第二层:工具分组

  • 按功能域分组(Gmail 类、Slack 类、数据库类…)
  • 用一个"路由器工具"先判断用户意图,再分派给具体子工具
  • Dify 里可以用 Workflow 先做意图分类,再进入不同的 Agent 节点

第三层:工具描述优化

  • 每个工具的描述要写清楚排他性条件,帮模型做决策
  • 比如:“此工具只用于查询用户信息。查询订单请使用另一个工具。”

第四层:多 Agent 拆分

  • 用户意图识别 Agent → 分派给 3 个专业 Agent,每个绑 5 个工具
  • 每个 Agent 的工具数量减少 2/3,准确率大幅提升

第五层:prompt 里加工具选择规则

工具选择规则:
1. 用户问"天气" → 只用 weather 工具
2. 用户问"发邮件" → 只用 email 工具
3. 一次只调用一个工具,不要同时调多个
4. 不确定时先问用户

4. Agent 最大迭代次数设多少合适?设太大/太小的问题?

推荐值:

场景推荐迭代次数
简单问答(单工具)3-5 次
多步推理(数据查询+计算+报告)8-15 次
复杂流程(审批链、多系统操作)15-25 次
代码生成/调试10-20 次

设太小的问题:

  • Agent 还没完成推理就被截断,返回半成品结果
  • 用户体验差——“它说到一半停了”
  • 解决方法:设置合理的超时 + 截断时返回"任务未完成,已执行到第 N 步"的友好提示

设太大的问题:

  • 循环死锁 — Agent 在某个步骤里打转,疯狂消耗 tokens 和 API 费用
  • 编造结果 — 迭代太多,模型可能开始胡编来"完成任务"
  • 响应时间暴涨 — 用户等几十秒才收到回复
  • 费用失控 — 一次请求可能花掉几万 tokens

最佳实践:

  • 设置软上限(比如 10 次)+ 硬上限(比如 20 次强停)
  • 配合超时时间(比如 60 秒)兜底
  • 监控迭代次数,超过软上限时记录日志排查
  • Dify 里可以设置 max_iterations 配合 timeout 双重保险

5. 多 Agent 架构 vs 单 Agent 绑大量工具,你选哪个?

选多 Agent。没有悬念。

理由:

维度单 Agent + N 工具多 Agent 架构
准确率工具多了模型决策准确率指数下降每个 Agent 专注 3-5 个工具,决策准确
维护性加一个工具要重新测试全部场景加一个新 Agent/工具影响隔离
扩展性超过 10 个工具后几乎不可用可以横向扩展到几十上百个 Agent
调试工具调错很难定位是哪个工具的问题Agent 职责明确,问题定位快
成本每次请求都带所有工具描述,tokens 浪费只带当前 Agent 的工具描述,省 tokens
错误隔离一个工具有 bug 影响整个 Agent一个 Agent 挂掉不影响其他

多 Agent 架构的成熟模式:

用户提问
  │
  ├─ 入口 Agent(意图识别 + 分类)
  │     │
  │     ├─ 客服 Agent ─── 查订单、退换货、开发票(5 个工具)
  │     ├─ 数据 Agent ─── 查报表、生成图表、导出数据(4 个工具)
  │     └─ 操作 Agent ─── 发邮件、建工单、更新状态(6 个工具)
  │
  └─ 汇总 Agent(统一回复格式,引用来源)

唯一选单 Agent 的场景:

  • 原型验证期,工具不超过 5 个
  • 非常简单的单步操作(查天气、翻译)
  • 模型资源受限,跑不了多 Agent 架构

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

blns_yxl

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值