Dify流式输出需主动注入中间状态事件才能实时展示过程;启用工作流级流式响应是网络层前提,再通过Text或Code节点发送事件,前端依event类型区分中间态与终态。
☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 多模态理解力帮你轻松跨越从0到1的创作门槛☜☜☜

理解Dify流式输出与中间状态的区别
在Dify中启用流式输出(Streaming)本身不等于自动展示中间状态;默认情况下,即使开启streaming,Answer节点仍只在最终结果生成完毕后才推送完整文本。要让“检索中…”“思考中…”“调用插件xxx…”这类中间过程实时浮现,必须主动触发并注入非最终态的事件流。
启用工作流级流式响应
进入Dify控制台 → 选择目标应用 → 点击「工作流」或「Chatflow」编辑页 → 在右上角「发布设置」中勾选【启用流式响应】。
【未勾选此项,后续所有中间状态事件均不会被前端接收】
该选项会强制后端将response_mode设为streaming,并启用SSE长连接通道,是中间状态推送的网络层前提。
在工作流中插入中间状态事件节点
方法一:使用内置「Text」节点模拟中间反馈
拖入一个Text节点 → 在内容框中输入纯文本如“正在查询知识库…” → 将其放置在RAG检索节点之前 → 连接至后续节点。Dify会在执行到该节点时立即向SSE流推送一条data: {"event":"text","data":"正在查询知识库…"}消息。
方法二:通过「Code」节点发送自定义QueueTextChunkEvent
添加Code节点 → 语言选Python → 输入以下代码:
```python
from core.model_runtime.entities.llm_entities import LLMResultChunk
from events.message_event import QueueTextChunkEvent
# 发送中间状态
event = QueueTextChunkEvent(
task_id=kwargs['task_id'],
text="? 正在解析用户意图…",
chunk_index=0
)
self._queue.append(event)
```
注意:此方法需部署自定义Dify后端(非SaaS版),且Code节点必须配置为同步执行(即不勾选“异步运行”),否则事件可能丢失。
前端监听并区分中间态与终态
第一步:创建EventSource连接,URL末尾添加?response_mode=streaming参数
第二步:监听onmessage事件,对每条data:行做JSON解析
第三步:根据event字段判断类型——当event为"text"且data.content不包含[FINAL]标识时,视为中间状态,追加到预览区并保持光标在末尾;当event为"agent_final"或data包含"final_answer":true时,替换整个预览区内容并禁用加载动画。
关键细节:Dify不会自动给中间状态打标记,你必须在Text节点内容里手动加入可识别前缀(如“⏳”“?”),或在Code节点中统一写入{"status":"intermediate","msg":"..."}结构体,否则前端无法可靠区分“这是中间步骤”还是“这是最终答案的第一个字”。
避免中间状态错乱的三个硬性约束
① 所有中间状态节点必须严格串行排布,不可与LLM节点并行——若RAG检索和LLM生成同时启动,它们各自触发的text事件会按完成时间混序到达,导致“生成回复中…”出现在“检索完成”之前。
② 中间Text节点的内容长度建议控制在20字符内,过长会导致SSE单帧超时断连;超过40字符应拆分为两个Text节点分两次推送。
③ 若使用Code节点注入事件,必须确保其执行耗时<500ms,否则会阻塞后续节点调度,引发整个工作流超时中断。


















