← 返回文章列表

Dify 中级实验(12):Agent 深度配置——如何让智能体自主调用工具?

1. 业务场景

先讲一个我们实际遇到的场景。

一家电商公司的运营团队想做一个「业务助手」:销售问「最近订单怎么样?」,它去查数据;运营说「把促销数据算一下」,它跑分析;主管说「给王经理发个会议通知」,它真的把消息发出去。一开始他们以为这只是「把对话模型接进来」的事,结果发现完全不是——闲聊模型只会在对话框里聊天,它不会自己去查数据、不会主动调工具、更不知道什么时候该发消息。真正能干活的助手,必须能自己决定做什么、用什么工具做、按什么顺序做

我们第一次接这类需求时,第一反应也是「把模型换聪明点不就行了」。真正动手配起来才发现——「会聊」和「会干活」之间隔着的不是模型,是工具:模型再聪明,手上没有工具可调,也只会礼貌地说一句「我无法访问外部系统」。

这不是个例。任何「用户一句话、系统要动手办事」的场景都是这个模式:客服机器人要查订单状态再回复、HR 助手要查员工档案再开证明、运维助手要查服务状态再告警——「会聊」和「会干活」之间,隔着工具调用这道坎

2. 场景痛点

这个流程的痛点,在运营团队的「业务助手」项目上体现得最直接:

本质上,「助手能不能干活」不取决于模型多聪明,而取决于给它挂了什么工具、定了什么规则——工具即能力边界

3. 方案:为什么是 Agent + 自定义工具

Dify 的 Agent 应用(agent-chat) 就是为「自主调用工具干活」设计的:模型 + Function Calling 策略 + 工具列表 + 行为规则,四件套配齐,Agent 就能自己决定何时调用什么工具。而工具从哪来?任何工作流发布后都可以变成自定义工具——这正是本实验的关键能力。

选它的理由:

这篇文章我们就用它搭一个「全栈业务助手」:Agent 自主决定何时调用内置时间工具、代码解释器和自定义「发送消息」工具,完成「查数据 → 分析 → 生成报告 → 发通知」的完整业务动作。

4. 整体架构

13_02(工具载体,workflow 模式):

graph TD start["开始:to / title / content / priority"] --> send["模拟发送消息(Code:生成 MSG-xxx 消息 ID)"] send --> confirm["确认回复(LLM:一句话告知发送结果)"] confirm --> end1["结束:result / message_id / status"]

13_01(agent-chat 模式):无画布节点,配置 = 模型 + 策略 + 工具 + 系统提示词。

链路很清晰:13_02 工作流负责「把发消息这件事做成一个工具」,13_01 Agent 负责「决定什么时候用这个工具」——工具与决策分离,Agent 只认工具的输入输出契约,工具内部怎么实现它不关心。

5. 模块设计

5.1 Agent 核心配置(agent_mode)

model_config:

  agent_mode:

    enabled: true

    max_iteration: 10            # 太少跑不完,太多浪费 Token,10-15 合理

    strategy: function_call       # function_call 更稳;ReAct 更灵活

    tools:

    - enabled: true

      provider_id: time

      provider_name: time

      provider_type: builtin

      tool_label: 获取当前时间

      tool_name: current_time

      tool_parameters: {}

  model:

    completion_params:

      max_tokens: 4000

      temperature: 0.7

      top_p: 0.9

    name: deepseek-v4-flash

    provider: deepseek

  prompt_type: simple             # agent-chat 必须 simple / advanced

5.2 系统提示词(pre_prompt)——Agent 的行为上限

pre_prompt: |

  你是一个全栈业务助手,可以帮助用户完成以下任务:

  ## 可用工具

  1. **数据查询** - 查询业务数据(订单、用户、产品)

  2. **代码解释器** - 执行 Python 代码做数据分析(数值计算、统计、趋势)

  3. **发送消息** - 发送通知消息(接收人/标题/内容/优先级)

  4. **获取当前时间** - 获取系统当前时间(内置工具)

  ## 行为规则

  1. 分步思考:确定用户需要什么 → 需要哪些工具 → 按什么顺序调用

  2. 工具传递:一个工具的输出可以作为下一个工具的输入

  3. 确认优先:对破坏性操作(如发送消息),先请用户确认

  4. 错误处理:工具返回错误则分析原因并修正参数重试;连续 3 次错误停止并告知"系统暂时不可用"

  ## 工具选择策略

  1. 优先使用专用工具(如数据查询)而非代码解释器

  2. 代码解释器只用于数值计算和数据分析

  3. 发送消息前必须请用户确认

  ## 输出格式

  - 涉及数据分析必须展示完整分析过程;最终回答结构化、清晰

5.3 自定义工具(13_02)

自定义工具的本质是 OpenAPI 规范中定义的 API,Dify 会把它转成 Function Calling 的函数定义交给 LLM。开始节点四个变量:

- data:

    type: start

    variables:

    - label: 接收人

      required: true

      type: text-input

      variable: to

    - label: 消息标题

      required: true

      type: text-input

      variable: title

    - label: 消息内容

      required: true

      type: paragraph

      variable: content

    - label: 优先级(默认 normal)

      required: false

      type: select

      variable: priority

      options: [low, normal, high]

代码节点模拟发送:

def main(to: str, title: str, content: str, priority: str) -> dict:

    import time

    pri = (priority or "normal").strip() or "normal"

    msg_id = "MSG-{}-{}".format(time.strftime("%Y%m%d%H%M%S"), abs(hash(to + title)) % 10000)

    return {

        "message_id": msg_id,

        "status": "success",

        "send_text": "已向 {} 发送消息「{}」(优先级 {}):{}".format(to, title, pri, content)

    }

发布流程:工作流 → 发布为工具 → 在 13_01 的工具列表中挂载,Agent 即可通过 send_message(to/title/content/priority)自主调用。

6. 运行验证

输入 预期 实测
你好 直接回复,不调任何工具 无工具调用,正常闲聊
现在几点了? 调用内置 current_time 工具调用并返回当前时间
给王经理发一条通知,内容:明早 9 点开会 先请求确认 → 调 send_message → 返回 MSG-xxx 三轮工具编排完整,消息 ID 正确返回
12345 × 67890 等于多少? 自动判断需要计算,调代码解释器 计算结果正确展示
连续追问「再发一次」 记忆生效,复用上轮参数 记忆窗口内参数延续,无需重述

7. 实战坑

现象 修复
agent-chat 的 prompt_type 留空 导入/保存报 '' is not a valid PromptType 必须显式填 simpleadvanced
agent-chat 用 blocking 响应模式 应用不可用/调用报错 agent-chat 只支持 streaming,必须用 streaming
工具描述写得太简略 LLM 不知道何时该用,工具长期闲置 描述写清「做什么/何时用/参数含义」(实验文档设计约束)
工作流没发布就去找工具 Agent 工具列表里找不到 send_message 先「发布为工具」再挂载;改动后需重新发布(实验文档设计约束)
破坏性操作不设确认规则 一条指令就发出真实通知 pre_prompt 里写「发送前请用户确认」(实验文档设计约束)

8. 实验文档及源码获取

文章聚焦核心配置与采坑点;实验的完整分步操作(节点搭建/参数表/调试指引)见实验文档原文。

本系列 · Dify 实验 · 中级
  1. Dify 中级实验(01):参数提取器实战——如何从自然语言中提取结构化数据?
  2. Dify 中级实验(02):问题分类器——智能路由引擎如何四路分发?
  3. Dify 中级实验(03):模板转换实战——如何用零 Token 完成文本加工?
  4. Dify 中级实验(04):迭代进阶——如何批量处理数据并守住性能边界?
  5. Dify 中级实验(05):并行执行——如何让多路任务同时跑?
  6. Dify 中级实验(06):变量聚合——如何确定性合并多路分支结果?
  7. Dify 中级实验(07):子工作流——如何把公共逻辑做成可复用积木?
  8. Dify 中级实验(08):代码节点进阶——如何用标准库处理文件与数据?
  9. Dify 中级实验(09):HTTP 节点进阶——如何搞定认证、分页与错误重试?
  10. Dify 中级实验(10):知识库深度调优——如何科学评估检索质量?
  11. Dify 中级实验(11):高级 RAG 流水线——如何搭建多路检索与精排?
  12. Dify 中级实验(12):Agent 深度配置——如何让智能体自主调用工具?
  13. Dify 中级实验(13):多 Agent 协作——如何编排多个智能体分工干活?
  14. Dify 中级实验(14):对话变量与状态管理——如何让工作流记住多轮对话的状态?
  15. Dify 中级实验(15):条件分支高阶策略——多条件路由如何避免分支爆炸?
  16. Dify 中级实验(16):错误处理与降级——工作流如何有尊严地失败?
  17. Dify 中级实验(17):调试监控与性能优化——响应慢和 Token 超支如何定位?
  18. Dify 中级实验(18):插件开发入门——如何把工作流变成 Agent 可调用的工具?
  19. Dify 中级实验(19):综合实战——如何把 19 个实验串成一条生产级流水线?
  20. Dify 中级实验(20):综合实战——自动化报告生成流水线如何从数据到周报一步到位?

联系我

15088711270

手机端点击号码可直接拨打 · 桌面端可复制

微信二维码

扫码加微信 · 备注「门户」更快通过