用 Dify Agent 调用外部工具:以天气查询为例,演示工具定义到调用的完整链路
在很多企业场景中,用户真正需要的并不只是“与 AI 对话”,而是“让 AI 基于外部能力完成一项动作”。
这正是 Agent 价值开始体现的地方。
与普通问答应用不同,Agent 的重点不只是生成一句回答,而是围绕任务完成展开完整链路:
- 理解用户意图
- 判断是否需要调用工具
- 选择正确工具
- 组装调用参数
- 接收工具返回结果
- 基于结果生成最终回复
为了更容易说明这条链路,天气查询是一个非常典型的例子。它足够简单,同时又完整覆盖了 Agent 调用外部工具时最核心的能力结构。
一、什么是“工具调用”
所谓工具调用,可以理解为:模型在判断自身无法可靠回答某个问题时,通过外部能力获取信息,再将结果组织为最终输出。
以天气查询为例,一条典型流程如下:
用户:今天东京天气怎么样?
→ Agent 判断:这是一个需要实时信息的问题
→ 调用天气 API
→ 获取温度、天气状态、风力、降水概率
→ 生成最终回答
这意味着,关键点不在于模型“是否知道天气”,而在于模型“是否知道什么时候必须去查天气”。
二、Dify Agent 中常见的两种策略
在 Dify 的 Agent 场景中,工具调用通常会围绕两类方式展开:
- ReAct:模型通过“思考 → 行动 → 观察”的方式逐步决定下一步
- Function Calling:模型直接输出工具名称与参数,以结构化方式发起调用
ReAct 更适合的情况
- 任务目标相对开放
- 需要多步推理
- 希望观察思考过程与调用路径
- 需要调试复杂行为链路
Function Calling 更适合的情况
- 任务结构明确
- 工具调用路径稳定
- 对响应速度与参数准确性要求更高
- 输出格式要求结构化
对于天气查询这类任务,Function Calling 往往更直接;而对于“结合天气、交通与日程安排给出出行建议”这类更开放任务,ReAct 的灵活性会更高。
三、为什么天气查询是一个典型 Agent 场景
天气查询具备一个标准 Agent 场景的全部特征:
- 问题依赖实时数据
- 需要调用外部 API
- 参数结构清晰,例如城市与日期
- 返回结果结构化,例如温度、天气状态、降水概率
- 最终结果需要自然语言表达,而不是原始 JSON
因此,天气查询并不只是一个简单示例,而是理解 Agent 工具调用全链路最适合的入门案例之一。
四、第一步:定义工具能力
在 Dify Agent 中,工具本质上是一种可被模型调用的外部能力。
以天气查询为例,定义一个工具时,至少需要明确以下三项内容。
1. 工具名称
例如:
get_weatherquery_weather
名称应尽量清晰,便于模型理解用途。
2. 工具描述
例如:
- 用于查询指定城市在指定日期的天气情况
- 返回天气状态、温度、湿度、风力与降水概率
描述质量会直接影响模型是否能正确判断使用场景,因此不应写得过于泛化。
3. 输入参数
天气查询最常见的参数包括:
city:城市名date:日期unit:温度单位(可选)
在企业场景中,参数定义越清晰,调用稳定性通常越高。
五、第二步:接入外部天气 API
工具定义完成后,下一步是接入真正提供数据的外部服务。
常见接入方式包括:
- 使用公开天气 API
- 调用企业内部中间服务
- 通过 HTTP 请求访问第三方天气接口
这一步的重点不是 API 本身有多复杂,而是保证输入输出结构足够稳定。
一个较理想的返回结构通常类似:
{
"city": "东京",
"date": "2026-04-12",
"condition": "多云",
"temperature_min": 14,
"temperature_max": 22,
"rain_probability": "30%",
"wind": "东北风 3级"
}
对于 Agent 而言,返回结构越清晰,后续生成的结果就越稳定。
六、第三步:让 Agent 学会“什么时候调用工具”
在实践中,这一步经常被低估。
很多团队会把重点放在“工具接通没有”,但真正决定体验的,通常是模型是否知道:
- 哪类问题必须调用天气工具
- 哪类问题可以直接基于已有上下文回答
- 参数不完整时是否需要先追问
一个基础约束示例
可以在系统提示词中加入类似规则:
当用户询问天气、温度、降雨、风力、适合穿什么、是否适合出行等与天气相关的问题时,优先调用天气工具,而不是直接凭空回答。
如果缺少城市或日期,请先追问用户。
这样做的目的,是减少模型在实时信息场景中的主观猜测。
七、第四步:处理不完整输入
真实用户的输入并不会总是完整。例如:
- “今天适合出门吗?”
- “东京天气呢?”
- “明天大阪会下雨吗?”
在这类情况下,Agent 需要具备两种基础能力。
1. 自动补全可推断信息
例如“今天”可以被解析为当前日期。
2. 主动追问缺失参数
如果用户只说“天气怎么样”,却没有说明城市,就应优先追问:
- “请问你想查询哪个城市的天气?”
这一能力非常关键,因为它直接决定 Agent 是否表现得像一个可用系统,而不只是一个偶尔能成功调用工具的演示原型。
八、第五步:把结构化结果转化为可用回答
工具返回的是结构化数据,但用户真正需要的是可执行、可理解的结论。
例如,当用户问:
“明天东京适合带伞吗?”
Agent 不应机械复述原始 JSON,而更适合输出类似结果:
- 明天东京多云转小雨,最高 21℃,降水概率 60%,建议携带雨具出门。
进一步还可以生成更场景化的表达:
- 如果明天有户外安排,建议准备轻便雨伞,以应对短时降雨。
这也是 Agent 与普通 API 调用的核心差异:工具负责取数,模型负责解释与表达。
九、为什么天气查询通常更适合 Function Calling
天气查询之所以特别适合 Function Calling,是因为它符合以下特点:
- 调用目标明确
- 参数结构稳定
- 返回值结构明确
- 不需要长链路推理
相比 ReAct,它通常有三个明显优势:
-
响应更快
减少不必要的思考文本生成。 -
参数更稳
更容易输出符合要求的结构化调用参数。 -
成本更低
可以减少额外 token 消耗。
因此,如果 Agent 的任务主要是“查天气、查库存、查订单、查价格”一类标准动作,Function Calling 通常会是更适合的第一选择。
十、从天气查询扩展到企业场景
天气查询只是一个教学案例,但它背后对应的,其实是一整类企业场景:
- 查库存
- 查工单状态
- 查订单进度
- 查客户信息
- 查会议室预订情况
- 查报销审批状态
这些问题与天气查询有一个共同点:
它们都不是让模型凭空生成答案,而是让模型先调用数据能力,再组织结果。
一旦天气查询这条链路被搭建清楚,企业通常就可以把同样的模式迁移到更多内部业务系统中。
十一、推荐的设计原则
在 Agent 工具调用设计中,一个非常实用的原则是:
让工具尽量结构化,让模型尽量少猜测。
具体来说,应尽量做到:
- 工具描述清晰
- 参数定义清晰
- 返回字段清晰
- 对实时信息场景明确要求“必须调用工具”
- 对缺失参数场景明确要求“先追问再调用”
这类基础设计,往往比单纯更换模型更能提升系统可靠性。
结语
以天气查询为例,Dify Agent 调用外部工具的完整链路可以被清晰地拆解为:
- 定义工具
- 接入 API
- 约束调用时机
- 处理参数补全
- 将结果组织为用户可理解的回答
这条链路的本质,不是让模型成为一个什么都知道的万能体,而是让模型在合适的时候调用外部能力。
对于企业而言,这种能力往往比“更会聊天”更重要。因为在真实业务中,更常见的需求不是“写一段更漂亮的话”,而是:
帮我查、帮我拿、帮我判断,并把结果整理成我可以直接使用的输出。
而这正是 Dify Agent 与工具调用最值得关注的价值所在。