Dify 中级实验(12):Agent 深度配置——如何让智能体自主调用工具?
Dify 中级实验(12):Agent 深度配置——如何让智能体自主调用工具?
Dify 实验系列 · 中级 12/20 | 实验编号:DIFY-102-13
基于 Dify 1.16.1 实测(2026-08)
1. 业务场景
先讲一个我们实际遇到的场景。
一家电商公司的运营团队想做一个「业务助手」:销售问「最近订单怎么样?」,它去查数据;运营说「把促销数据算一下」,它跑分析;主管说「给王经理发个会议通知」,它真的把消息发出去。一开始他们以为这只是「把对话模型接进来」的事,结果发现完全不是——闲聊模型只会在对话框里聊天,它不会自己去查数据、不会主动调工具、更不知道什么时候该发消息。真正能干活的助手,必须能自己决定做什么、用什么工具做、按什么顺序做。
我们第一次接这类需求时,第一反应也是「把模型换聪明点不就行了」。真正动手配起来才发现——「会聊」和「会干活」之间隔着的不是模型,是工具:模型再聪明,手上没有工具可调,也只会礼貌地说一句「我无法访问外部系统」。
这不是个例。任何「用户一句话、系统要动手办事」的场景都是这个模式:客服机器人要查订单状态再回复、HR 助手要查员工档案再开证明、运维助手要查服务状态再告警——「会聊」和「会干活」之间,隔着工具调用这道坎。
2. 场景痛点
这个流程的痛点,在运营团队的「业务助手」项目上体现得最直接:
- 只会聊、不会干:普通对话模型对「查一下数据」只能回复「我无法访问外部系统」,所有动手的活还得人去做,助手形同虚设。
- 不知道该用哪个工具:就算模型能调工具,面对「查订单」「算数据」「发消息」多个工具,它经常用错——用代码解释器去查数据,用消息工具去算数,工具长期闲置或乱用。
- 破坏性操作没有确认:助手直接按指令把消息发出去了,内容错了、接收人错了,没有挽回余地——业务上这是事故级的问题。
- 行为边界不可控:不约束规则的话,模型想怎么干就怎么干,同样的指令两次执行行为不一致,没法上线。
本质上,「助手能不能干活」不取决于模型多聪明,而取决于给它挂了什么工具、定了什么规则——工具即能力边界。
3. 方案:为什么是 Agent + 自定义工具
Dify 的 Agent 应用(agent-chat) 就是为「自主调用工具干活」设计的:模型 + Function Calling 策略 + 工具列表 + 行为规则,四件套配齐,Agent 就能自己决定何时调用什么工具。而工具从哪来?任何工作流发布后都可以变成自定义工具——这正是本实验的关键能力。
选它的理由:
- Function Calling 策略稳定可控:相比 ReAct 的文本推理,function_call 让模型直接输出结构化的函数调用,工具选择更准、更省 Token;
- 工具能力可自建:不用等官方插件,内部系统(查数据、发消息、跑报表)都能通过工作流发布成工具挂给 Agent;
- 行为规则可约束:pre_prompt 里写清工具选择策略和确认规则,破坏性操作强制先确认,把 Agent 的行为边界定死。
这篇文章我们就用它搭一个「全栈业务助手」:Agent 自主决定何时调用内置时间工具、代码解释器和自定义「发送消息」工具,完成「查数据 → 分析 → 生成报告 → 发通知」的完整业务动作。
4. 整体架构
13_02(工具载体,workflow 模式):
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 |
必须显式填 simple 或 advanced |
| agent-chat 用 blocking 响应模式 | 应用不可用/调用报错 | agent-chat 只支持 streaming,必须用 streaming |
| 工具描述写得太简略 | LLM 不知道何时该用,工具长期闲置 | 描述写清「做什么/何时用/参数含义」(实验文档设计约束) |
| 工作流没发布就去找工具 | Agent 工具列表里找不到 send_message | 先「发布为工具」再挂载;改动后需重新发布(实验文档设计约束) |
| 破坏性操作不设确认规则 | 一条指令就发出真实通知 | pre_prompt 里写「发送前请用户确认」(实验文档设计约束) |
8. 实验文档及源码获取
- 实验文档(完整操作步骤):DIFY-13:Agent深度配置与自定义工具.md
- 源码一(Agent 应用):dify102_13_01_全栈业务助手.yml
- 源码二(自定义工具):dify102_13_02_发送消息工具.yml
文章聚焦核心配置与采坑点;实验的完整分步操作(节点搭建/参数表/调试指引)见实验文档原文。
下一篇:Dify 中级实验(13):多 Agent 协作——如何编排多个智能体分工干活?
💬 你在这个实验的场景里踩过什么坑?欢迎评论区分享你的实战经验。
更多推荐



所有评论(0)