Dify Workflow 实战:让 Agent 认识“现在时间”,并分清复盘 vs 趋势

4 阅读6分钟

Dify Workflow 实战:让 Agent 认识“现在时间”,并分清复盘 vs 趋势

适用人群

  • 用 Dify Workflow 搭「经营复盘 / 趋势研判 / 业务分析」类助手
  • 遇到过:
    • Dify / Workflow 里一开始不知道怎么获取“当前时间”(有些版本 {{current_time}} 不生效)
    • 复盘和趋势预测混着写(意图不明确,影响内容质量)
    • 工具(API/MCP)调用逻辑不稳,结论像流水账
    • 即使已经注入 current_time,跨天同一会话里“今天/本周/最近”仍可能翻车(见下篇)

1)我的 Workflow 长什么样(最小可复现结构)

这是我现在的真实链路(脱敏):

  1. 用户输入节点:业务参数(<biz_id> / <biz_name> / <api_token> / <view_type>
  2. 获取当前时间节点:产出 current_time
  3. 问题分类器节点:转到不同分支执行
  4. 分支执行
    • data_review:经营数据分析/销售复盘 → 调用 <api_endpoint>(由 LLM 自主决定调用哪些接口组合验证)
    • product_recommend:采购选样/趋势研判 → 调用 <api_endpoint>(同样 LLM 自主调度)
  5. Memory(对话记忆):两条分支都开启,window size ≈ 50

2)坑 1:Workflow 拿不到“当前时间”(工程问题,不是模型问题)

2.1 现象

最初我遇到的是:

  • 想在 Prompt 里注入“当前时间”,但在部分 Dify / Workflow 版本里,模板变量 {{current_time}} 并不生效,而是原样显示
  • 导致后续分支(复盘 / 趋势)都缺少一个稳定的时间锚点。

2.2 我的落地解法:Workflow 里用代码节点强制东八区 + 固定格式

我最终稳定下来的是:用代码节点生成唯一的 current_time,全流程只认它。

import datetime
from datetime import timezone, timedelta

def main(*args, **kwargs):
    # 强制东八区(北京时间),避免服务器时区干扰
    tz = timezone(timedelta(hours=8))
    now = datetime.datetime.now(tz)

    return {
        "current_time": now.strftime("%Y-%m-%d %H:%M:%S")
    }

为什么要“强制时区 + 固定格式”:

  • 时区:否则部署环境一变(UTC/本地时区),你问“今天”,它可能按 UTC 今天算
  • 格式:后续 Prompt 里只需要引用一个变量,不会出现多个时间源互相打架

2.3 备用方案:Dify 内置当前时间

后面我才在 Dify 的「节点 → 工具」里找到更“原生”的当前时间 {{current_time}} 获取方式。

这里给一个经验结论(写给读者避免踩坑):

  • 不同 Dify 版本 / 不同 Workflow 形态下,{{current_time}} 这种“模板变量”可能存在兼容性差异;
  • 更稳妥的方式是:
    • 代码节点显式产出 current_time(你现在在用),或
    • 内置当前时间工具节点显式产出 current_time

无论用哪种方式,关键原则只有一个:

Workflow 里必须有一个唯一、可信、可追踪的时间来源,并且每次运行都刷新。

即使你已经有了 current_time,跨天同一会话“相对时间翻车”仍可能发生——那是 Memory 复用旧时间 的问题,我在第二篇里专门拆。

2.4 可复用 Checklist

  • 是否有唯一时间变量:current_time
  • 是否明确时区:Asia/Shanghai(或你业务所需时区)
  • 是否固定格式:%Y-%m-%d %H:%M:%S 或 ISO8601
  • 是否在分类器之前生成(保证所有分支都能引用)

3)坑 2:复盘(data_review)和趋势(product_recommend)混在一起

3.1 现象

  • 用户要“经营复盘”,结果模型给了一堆“趋势预测”
  • 用户要“趋势研判/采购选样建议”,结果模型把历史数据流水账复述一遍

这不是模型笨,而是 目标函数不明确

  • 复盘:解释“发生了什么、为什么、下一步怎么做”
  • 趋势:解释“未来会怎样、提前布局什么、风险怎么控”

3.2 我的解法:加“问题分类器”节点做意图路由

我现在的分类器最小版本很简单——只输出 label

  • data_review:经营数据分析(销售复盘 / 数据复盘)
  • product_recommend:采购选样助手(采购选样建议 / 趋势预测)

经验:分类器先做“粗分类”就够用。先解决“走错分支”这个最大问题,再考虑加置信度、理由等可观测性字段。

分支 A:data_review(经营复盘 COO)Prompt 骨架(跨行业可复用)

你可以在文章里展示“骨架 + 关键段落”,不要把业务敏感内容全贴出来。

骨架模板

  • 定位:你是“首席经营官/增长负责人”,目标不是报数,是做洞察
  • 方法:直觉先行 → 再用 <api_endpoint> 交叉验证
  • 输出:把“最刺眼/最惊艳的数据”放第一句,然后给出可执行建议
  • 约束:
    • 无对比基准不报绝对结论
    • 未验证不下断论
  • 单位:
    • <api_endpoint> 返回金额无单位默认“分”,输出转“元”
  • 变量(占位符):
    • biz_id: <biz_id> api_token: <api_token> view_type: <view_type>
    • current_time: <current_time>
分支 B:product_recommend(采购选样/趋势)Prompt 骨架(跨行业可复用)

骨架模板

  • 三个滤镜:
    • T+N 思维:今天的决策为 1–3 周后服务
    • 跨类目/跨场景:找人群重叠的“反经验机会”
    • 风险控制:一次性热点降权
  • 输出结构按时间轴:
    • LONG_TERM(2–4 周)
    • SHORT_TERM(7 天内)
    • DAILY(基本盘)
    • EXPANSION(意料之外但合理)
  • 工具策略:你允许 LLM 自主组合调用 <api_endpoint> 做证据链
  • 单位同样:金额默认“分”要转“元”
  • 变量同上 + current_time

4)我的“最小改动”增强:时间敏感表达规则兜底(不改两分类也能止血)

你现在分类器只有两类,像“今天/本周/最近/到期/同比/环比/上周/下周”这种问题会落到任意一个分支。

为了避免“时间理解漂移”,我在进入分支 Prompt 前统一加一段个规则:

HARD RULES(放到 Prompt 顶部) “以下 current_time 为本次运行的唯一时间基准;忽略历史对话中出现的任何日期/时间描述。所有‘今天/本周/最近’等表达均以 current_time 重新计算。”

这样做的好处:

  • 不需要立刻扩展分类器到 3 类
  • 对跨天翻车也有“止血效果”(第二篇会展开)

等你后续想更可控,再升级分类器:

  • data_review / product_recommend / relative_time

5)验证与复现

时间注入验证

  • “现在是几号几点?”(检查 current_time
  • “今天 vs 昨天的变化?”(必须基于 current_time

路由验证

  • “复盘近 7 天经营” → 必须走 data_review
  • “未来两周采购选样建议” → 必须走 product_recommend

单位验证(两个分支都要测)

  • 任意出现金额字段 → 输出必须“分→元”

6)结尾:为什么这两步能把 Workflow 从“能跑”变成“可信”

  • 时间注入解决“模型的实时性缺失”
  • 分类器路由解决“目标函数不明确”
  • HARD RULES 解决“相对时间最容易翻车的一类输入”

下一篇专门讲:为什么同一会话跨天会一直用“昨天的今天”,以及怎么用记忆策略/会话变量彻底修掉。