FA 一键诊断 — Dify 编排功能设计 v2.1
前置阅读:
版本记录:
- v1.0 (2026-06-17):初稿
- v2.0 (2026-06-22):新增 device_id 输入 + N4c device_id 解析节点;N5 拆为 N5a IOT 注入 + N5b Asset 历史数据注入;N6 Prompt 增加资产历史上下文
- v2.1 (2026-06-23):System 自定义化改造:N1 扩展返回 systems+components;N2 Prompt system
{% for %}动态渲染;新增 N1c Code Node safety_tip 提取;N7 Prompt 安全提示改为数据驱动- v2.2 (2026-07-02):命名重构。文档内概念名更新:System→类别(Category),Component→标签(Tag)。Dify 变量名同步更新。
1. Workflow 总览
1.1 节点清单
| 序号 | 链路 | 名称 | 说明 |
|---|---|---|---|
| N0 | — | 接收参数 | 接收工单描述 + 可选 asset_id + 可选 device_id |
| N1 | 分类 | 拉取分类标签 | 从管理后台获取当前项目可选的 category 列表 + tag 列表 |
| N1c | 分类 | 提取安全提示 | 从 category_list 中匹配当前 category 提取对应的 safety_tip |
| N2 | 分类 | 故障分类 | LLM 判断设备类别、诊断标签、故障现象、置信度 |
| N3 | 分类 | 置信度判定 | 置信度 ≥ 阈值走精确检索,< 阈值走宽检索 |
| N4a | 分类 | 知识库精确检索 | 按 设备类别 + 诊断标签 双条件过滤,取 Top-5 |
| N4b | 分类 | 知识库宽检索 | 仅按 设备类别 单条件过滤,取 Top-3 |
| N5 | 数据 | 设备 ID 解析 | 根据 asset_id 查对应 device_id(有 device_id 则直接用),统一 IOT 查询入口 |
| N6 | 数据 | 多维数据注入 | 有 device_id 则拉 IOT 实时值+告警;有 asset_id 则拉历史报修/巡检/保养/零件 |
| N7 | 生成 | 生成诊断报告 | LLM 综合工单描述 + 分类标签 + 知识库 + IOT + 资产历史 + 安全提示,输出排障建议 |
| N8 | 输出 | 返回结果 | 返回分类标签 + 诊断报告 + 引用来源 + 数据可用性标记 |
1.2 输入变量
| 变量 | 来源 | 必填 | 说明 |
|---|---|---|---|
work_order_description | 工单系统传入 | ✅ | 工单故障描述原文 |
asset_id | 工单系统传入 | — | 关联的资产 ID,有则查资产历史数据 + 解析 device_id |
device_id | 工单系统传入 | — | 关联的设备 ID(报警转工单场景直接携带),有则查 IOT |
current_work_order_id | 工单系统传入 | ✅ | 当前发起诊断的工单 ID,N5b 据此排除历史数据中的自身,防止自引用 |
low_confidence_threshold | 工作流变量,默认 0.5 | ✅ | 低置信度阈值,可在 Dify 面板调参 |
各类历史数据的时间范围和条数上限在 Dify 工作流变量面板中按类型独立配置(见 §2.1),不通过工单系统入参控制。
2. 节点详细设计
2.1 N0 — Start 与工作流变量
接收工单系统传入四个核心字段:work_order_description(必填)、asset_id(可选)、device_id(可选)、current_work_order_id(必填)。
asset_idvsdevice_id的关系:工单系统只需传入有的字段。人工报修工单通常只有asset_id(如 AST-2023-0042),报警转工单可能直接带device_id(如 DEV-AHU-020)。一键诊断内部通过 N5 节点 统一处理映射关系。
各类历史数据的时间范围和条数上限在 Dify Workflow 的「变量」面板中按类型独立配置:
| 变量 | 默认值 | 说明 |
|---|---|---|
LOW_CONFIDENCE_THRESHOLD | 0.5 | 低置信度阈值,confidence < 此值 时触发宽检索,并通过 is_low_confidence 告知前端 |
REPAIR_DAYS | 365 | 报修记录回溯天数 |
REPAIR_TOP_K | 5 | 报修记录最多取多少条 |
MAINTENANCE_DAYS | 730 | 保养记录回溯天数(保养周期较长,默认 2 年) |
MAINTENANCE_TOP_K | 5 | 保养记录最多取多少条 |
INSPECTION_DAYS | 365 | 巡检记录回溯天数 |
INSPECTION_TOP_K | 5 | 巡检记录最多取多少条 |
PARTS_DAYS | 365 | 零配件更换记录回溯天数 |
PARTS_TOP_K | 5 | 零配件更换记录最多取多少条 |
NO_CITATION_HINT | "暂无可参考的知识库文档,诊断建议由 AI 基于通用常识生成。" | 知识库检索无结果时,返回给前端的话术 |
2.2 N1 — HTTP Request:拉取分类标签(Categories + Tags)
| 配置项 | 值 |
|---|---|
| 方法 | GET |
| URL | /api/v1/diagnosis/classification-labels |
| 超时 | 5s |
| 输出变量 | category_list(JSON array)+ tag_list(JSON array) |
v3.0 变更:原 v2.0 的
GET /api/v1/diagnosis/componentsendpoint 已废弃,统一合并为分类标签组合接口。v4.0 命名重构:返回字段从systems/components改为categories/tags。
响应示例:
{
"categories": [
{"id": 1, "name": "建筑结构", "description": "建筑物本体结构相关设备,含门窗、幕墙、电梯井道等", "safety_tip": "⚠️ 结构问题...优先评估安全风险"},
{"id": 2, "name": "电气", "description": "供配电系统设备,含变压器、配电柜、UPS、继电器等", "safety_tip": "⚠️ 排查前必须断电..."},
{"id": 3, "name": "弱电智能化", "description": "弱电与智能化系统设备,含安防监控、门禁、传感器、会议系统等", "safety_tip": "⚠️ 带电排查时注意弱电设备额定电压..."}
],
"tags": [
{"category_id": 2, "category": "电气", "tag": "UPS", "description": "不间断电源,含蓄电池组,常见品牌科士达/山特/施耐德"},
{"category_id": 2, "category": "电气", "tag": "继电器", "description": "电磁/固态继电器,控制回路通断"},
...
]
}
category_list和tag_list将在 N2 打标 Prompt 和 N7 生成报告 Prompt 中作为变量注入。安全提示由新增的 N1c 代码节点(参见 §2.8)从中提取。
2.3 N2 — LLM:打标
| 配置项 | 值 |
|---|---|
| 模型 | DeepSeek-V3 / Qwen-Max |
| 上下文 | 前文变量 |
| Temperature | 0.1(需稳定输出) |
| 输出格式 | JSON |
System Prompt:
{# FA_一键诊断_打标_Prompt #}
你是一个设备故障分类专家。根据工单描述,输出设备故障分类标签。
## category 候选值
{% for cat in category_list %}
- {{cat.name}}{% if cat.description %}:{{cat.description}}{% endif %}
{% endfor %}
## tag 候选列表
{% for item in tag_list %}
- {{item.tag}}({{item.category}}){% if item.description %}:{{item.description}}{% endif %}
{% endfor %}
## 分类原则
1. 先判断设备属于哪个 category,再匹配最接近的 tag
2. 若工单涉及多个设备,以主要故障设备为准
3. 若候选列表无匹配项,输出最接近的新名称
4. symptom 用短语概括故障现象,如"不亮""漏水""堵塞""异响""无法启动"
## 工单描述
{{work_order_description}}
## 输出格式
严格输出 JSON,不要其他内容:
{
"category": "弱电智能化",
"tag": "闸机",
"symptom": "无法升降",
"confidence": 0.9
}
- category: 必须从候选 category 列表中选 1 个
- tag: 优先从候选列表选;若无匹配,填最接近的名称
- symptom: 短语概括故障现象
- confidence: 0~1 小数。≥0.8 设备明确,0.5~0.8 可推断,<0.5 描述模糊输出变量:category, tag, symptom, confidence
2.4 N3 — IF/ELSE:置信度分支
| 条件 | 表达式 | 后续节点 |
|---|---|---|
| 高/中置信 | confidence >= | N4a(精确检索) |
| 低置信 | confidence < | N4b(宽检索) |
阈值通过 Dify 工作流变量面板统一管理,无需改代码。
is_low_confidence通过 N7 输出告知前端是否展示提示。
2.5 N4a / N4b — Knowledge Retrieval:知识库检索
N4a — 精确检索(confidence ≥ 0.5):
| 配置项 | 值 |
|---|---|
| 知识库 | FA 诊断知识库 |
| 检索模式 | 混合检索(向量 + 关键词) |
| Top-K | 5 |
| 相似度阈值 | 0.3 |
Metadata Filter:
{
"operator": "and",
"conditions": [
{"field": "category", "operator": "eq", "value": "{{category}}"},
{"field": "tag", "operator": "eq", "value": "{{tag}}"}
]
}N4b — 宽检索(confidence < 0.5):
| 配置项 | 值 |
|---|---|
| Knowledge Base | FA 诊断知识库 |
| 检索模式 | 混合检索 |
| Top-K | 3 |
| 相似度阈值 | 0.2 |
Metadata Filter:
{
"operator": "and",
"conditions": [
{"field": "category", "operator": "eq", "value": "{{category}}"},
{"field": "doc_nature", "operator": "not_in", "value": ["保修卡", "合格证"]}
]
}输出变量:rag_context(检索结果数组),每个 chunk 含 document_title, content, score
2.6 N1c — Code Node:category_safety_tip 提取
用途:从 N1 返回的 category_list 中,根据 N2 输出的 值,匹配查找对应的安全提示 safety_tip。如果 N2 输出的是低置信度未命中任何类别,则返回空字符串。
| 配置项 | 值 |
|---|---|
| 类型 | Code Node |
| 输入变量 | category_list(来自 N1)、category(来自 N2) |
| 输出变量 | category_safety_tip(string) |
逻辑描述:遍历 category_list,找到 name 等于 N2 输出 category 的那一项,取其 safety_tip 字段赋给 category_safety_tip。若未匹配到任何类别,返回空字符串。
时序说明:N1c 与 N3 置信度分支是并行关系——N1c 等待 N1 和 N2 输出后即可执行,与 N4a/N4b 知识库检索不冲突。N1c 的输出
category_safety_tip仅被 N7(诊断报告生成)使用。
2.7 N5 — HTTP Request:device_id 解析
用途:统一处理 asset_id → device_id 的映射关系,确保后续 IOT 数据拉取有统一的 device_id 入口。
| 配置项 | 值 |
|---|---|
| 方法 | GET |
| URL | /api/v1/assets//device |
| 超时 | 3s |
| 条件执行 | 仅 device_id 为空 且 asset_id 不为空时执行 |
| 失败处理 | 静默跳过,不阻断流程 |
| 输出变量 | resolved_device_id(string 或 null) |
内部逻辑:
N4c 执行后更新 device_id:
输入 device_id → 直接用,跳过 N4c
无 device_id + 有 asset_id → 调接口查 asset.device_id 映射
├── 有映射 → device_id = 映射值
└── 无映射 → device_id = null(该资产无物联接入)
无 device_id + 无 asset_id → device_id = null时序说明:N4c(设备 ID 解析)与 N1→N2(分类检索链路)是两条独立并行的分支,从 Start 后同时执行。分类链路负责打标和知识库检索,数据链路负责拉取 IOT + 资产历史,最终在 N6 汇合——互不依赖,并行不悖。
2.8 N6 — HTTP Request:多维数据上下文注入
N5a — IOT 数据注入(device_id 驱动)
| 配置项 | 值 |
|---|---|
| 方法 | GET |
| URL | /api/v1/devices//diagnosis-context |
| 超时 | 3s |
| 条件执行 | device_id 不为空时执行 |
| 失败处理 | 静默跳过,不阻断流程 |
| 输出变量 | iot_data(null 或 JSON 对象) |
响应示例:
{
"device_id": "DEV-AHU-001",
"snapshot_time": "2026-06-18T14:21:00+08:00",
"properties": [
{"name": "回风温度", "value": 30.5, "unit": "°C", "range": null},
{"name": "回风温度设定", "value": 24.0, "unit": "°C", "range": null},
{"name": "送风温度", "value": 22.3, "unit": "°C", "range": "14~18"},
{"name": "送风温度设定", "value": 18.0, "unit": "°C", "range": null},
{"name": "运行模式", "value": "制冷", "unit": null, "range": null},
{"name": "风机运行状态", "value": "运行", "unit": null, "range": null},
{"name": "风机变频器频率反馈", "value": 45.0, "unit": "Hz", "range": "20~50"},
{"name": "冷水阀阀位反馈", "value": 18.5, "unit": "%", "range": "60~80"},
{"name": "新风温度", "value": 36.2, "unit": "°C", "range": null},
{"name": "新风阀阀位反馈", "value": 25.0, "unit": "%", "range": null},
{"name": "初效滤网报警", "value": "正常", "unit": null, "range": null},
{"name": "中效滤网报警", "value": "正常", "unit": null, "range": null}
],
"alarms": [
{"description": "无告警记录(近30天)", "level": null, "time": null}
]
}
properties包含物模型实时值,alarms为告警记录。两者均可能为空。
N5b — Asset 历史数据注入(asset_id 驱动)
| 配置项 | 值 |
|---|---|
| 方法 | GET |
| URL | /api/v1/assets//diagnosis-context?repair_days=&repair_top_k=&maintenance_days=&maintenance_top_k=&inspection_days=&inspection_top_k=&parts_days=&parts_top_k=&exclude_order= |
| 超时 | 3s |
| 条件执行 | asset_id 不为空时执行 |
| 失败处理 | 静默跳过,不阻断流程 |
| 输出变量 | asset_history(null 或 JSON 对象) |
后端过滤规则:所有工单仅取
status = "已完成";repair_orders额外排除id == exclude_order;maintenance_records/inspection_records仅取"已保养"/"已巡检"状态;时间范围和条数由各类型的独立参数控制(repair_days/maintenance_days/inspection_days/parts_days等)。
响应示例:
{
"asset_id": "AST-2026-0608-007",
"device_id": "DEV-AHU-001",
// 历史报修工单(动态表单,fields 由工作流引擎配置,非结构化 items)
"repair_orders": [
{
"id": "WO-2025-0115-003",
"time": "2025-01-15",
"description": "冷水阀执行器更换",
"fields": [
{"name": "资产名称", "value": "空调机组AHU-001"},
{"name": "专业类型", "value": "综合维修"},
{"name": "是否紧急", "value": "一般"}
]
}
],
// 历史保养记录(仅已保养,含保养项明细,排除 保养标准·数据类型=图片 )
"maintenance_records": [
{
"time": "2026-03-10",
"conclusion": "正常",
"items": [
{"name": "清洗滤网", "value": "正常"},
{"name": "风机皮带", "value": "正常"},
{"name": "冷水阀执行器", "value": "正常"}
]
}
],
// 历史巡检记录(仅已巡检,含巡检项明细,排除 巡检标准·数据类型=图片)
"inspection_records": [
{
"time": "2026-06-22 15:25:39",
"conclusion": "正常",
"items": [
{"name": "文本输入项", "method": "检查方法说明…", "value": "xxx"},
{"name": "选项", "value": "对"},
{"name": "数值(必填)", "value": "100"}
]
},
{
"time": "2026-06-05",
"conclusion": "正常",
"items": []
}
],
// 零配件更换记录
"parts_replacements": [
{"time": "2025-01-15", "part_name": "冷水阀执行器(TAC原厂)", "part_type": "办公用品类", "quantity": 1}
]
}| 字段 | 来源(资产详情页 Tab) | 说明 |
|---|---|---|
repair_orders | Tab 4 — 报修 | 该资产历史报修工单,动态表单字段见 §2.7.2 |
maintenance_records | Tab 6 — 保养 | 仅取"已保养"记录,含各保养项详情(详见 §2.7.1) |
inspection_records | Tab 5 — 巡检 | 仅取"已巡检"记录,含各巡检项详情(详见 §2.7.1) |
parts_replacements | Tab 8 — 零配件更换 | 该资产历史零件更换记录(仅保留 part_name/part_type/quantity,去掉更换人) |
2.7.1 界面参照
| 类型 | 工单详情 | 点/字段详情 |
|---|---|---|
| 巡检 | ![]() | ![]() |
| 保养 | ![]() | ![]() |
| 报修 | ![]() | — |
| 零配件 | ![]() | — |
2.7.2 筛选与裁剪规则
所有 N5b 返回的数据受以下参数控制,Dify 工作流变量和工单系统入参均可覆盖:
| 维度 | 规则 |
|---|---|
| 状态筛选 | 仅取 status = "已完成"(报修)/ "已巡检"(巡检)/ "已保养"(保养) |
| 时间范围 | 各类型独立配置:REPAIR_DAYS(报修)、MAINTENANCE_DAYS(保养)、INSPECTION_DAYS(巡检)、PARTS_DAYS(零配件) |
| 条数上限 | 各类型独立配置:REPAIR_TOP_K(报修)、MAINTENANCE_TOP_K(保养)、INSPECTION_TOP_K(巡检)、PARTS_TOP_K(零配件) |
| 排除当前单 | repair_orders 排除 id == current_work_order_id |
2.9 N7 — LLM:生成诊断报告(SSE 流式)
| 配置项 | 值 |
|---|---|
| 模型 | DeepSeek-V3 / Qwen-Max |
| 上下文 | N2 + N4 + N5a + N5b 输出 |
| Temperature | 0.3 |
| 最大 Token | 4096 |
| 输出方式 | SSE 流式(response_mode: streaming) |
System Prompt:
{# FA_一键诊断_生成报告_Prompt #}
你是一个专业的设备运维诊断助手。根据工单信息和参考文档,为工单受理人提供排障建议。
## 安全提示
{% if category_safety_tip %}
⚠️ {{category_safety_tip}}
{% endif %}
## 当前工单(待诊断)
- 工单 ID:{{current_work_order_id}}
- 故障描述:{{work_order_description}}
- 设备类别:{{category}}
- 诊断标签:{{tag}}
- 故障现象:{{symptom}}
- 分类置信度:{{confidence}}
## 设备实时状态(IOT)
{{iot_data}}
## 资产历史记录(已完成的工单,不含当前单)
{{asset_history}}
## 参考文档
{{rag_context}}
## 输出要求
1. **可能原因**(按可能性排序,3-5 条)
2. **排查步骤**(按优先级排列,每步可操作、可验证)
3. 涉及参考文档中的故障码/参数/阈值时,请注明出处
4. 注意对 IOT 数据与资产历史记录做交叉分析——单独一条信息可能没有价值,多条融合可能浮现根因
5. 无参考文档时,根据通用常识给出建议
6. 结尾注明:「本建议仅供参考,如有疑难请升级处理」
## 输出格式
用 Markdown 自由输出,标题用 `##`。结尾注明「本建议仅供参考,如有疑难请升级处理」。前端不做结构化拆分——LLM 输出的 Markdown 通过 SSE
text_chunk事件流式推送,前端逐字渲染。
SSE 事件流:
| 事件 | 触发时机 | 数据 |
|---|---|---|
workflow_started | 工作流开始 | task_id, diagnosis_id |
text_chunk | LLM 逐段生成 | {"text": "## 可能原因\n1. ..."} |
node_finished (N7) | LLM 生成完毕 | {"outputs": {"diagnosis_report": "..."}} |
workflow_finished | 工作流结束 | 完整 JSON(含 classification + references) |
前端收到 workflow_finished 后渲染引用来源栏。
2.9 N8 — End:输出
N7 流式结束后,workflow_finished 携带完整结构化数据。references 直接从 N4a/N4b 知识库检索节点输出中提取,不做 LLM 过滤——检索到什么就返回什么。
输出格式:
{
"diagnosis_id": "diag_20260617_001",
"classification": {
"category": "弱电智能化",
"tag": "闸机",
"symptom": "无法升降",
"confidence": 0.9,
"is_low_confidence": false
},
"references": [
{
"document_title": "广宁闸机V6使用手册",
"source_file_url": "oss://kb-fa/门禁道闸/GNG闸机V6.pdf"
}
],
"citation_hint": null,
"has_knowledge_match": true,
"has_iot_data": false,
"has_asset_history": true
}| 字段 | 说明 |
|---|---|
citation_hint | 引用为空时的话术,由 Dify 工作流变量控制。有引用时为 null,前端渲染正常引用栏;无引用时为预设话术,前端直接展示 |
citation_hint在 Dify 工作流变量中通过NO_CITATION_HINT配置,默认值:"暂无可参考的文档,诊断建议由 AI 基于通用常识生成。"
3. 异常处理
| 场景 | 处理 |
|---|---|
| HTTP N1 超时/失败 | tag_list 回退到内置默认列表(硬编码兜底) |
| LLM N2 超时 | 返回 {error: "打标服务暂不可用"} |
| LLM N2 输出非 JSON | 正则提取 + 重试 1 次;仍失败则返回 confidence: 0 |
| 知识库检索无结果 | N6 走 LLM 常识兜底,references 为空数组 |
| HTTP N4c 超时/失败 | device_id = null,静默跳过,后续 IOT 数据不可用 |
| HTTP N5a 超时/失败 | iot_data = null,静默跳过 |
| HTTP N5b 超时/失败 | asset_history = null,静默跳过 |
| LLM N6 超时 | 返回 {error: "诊断服务暂不可用,请稍后重试"} |
4. API 调用(SSE 流式)
Dify Workflow 对外暴露流式 API,供工单系统「一键诊断」按钮调用:
POST /v1/workflows/run
Content-Type: application/json
{
"inputs": {
"work_order_description": "G馆1楼入口闸机翼臂无法升降",
"asset_id": "AST-2024-0882",
"device_id": null
},
"response_mode": "streaming",
"user": "operator_zhang"
}使用
streaming模式,前端通过 EventSource 接收 SSE 事件流。诊断报告逐字渲染,引用来源在流结束后一次性展示。
文档版本:v2.1最后更新:2026-06-23作者:强哥
版本记录
| 版本 | 日期 | 变更 |
|---|---|---|
| v1.0 | 2026-06-17 | 初稿 |
| v2.0 | 2026-06-22 | 新增 device_id 输入 + N4c device_id 解析节点;N5 拆为 N5a IOT 注入 + N5b Asset 历史数据注入;N6 Prompt 增加资产历史上下文 |
| v2.2 | 2026-07-02 | 命名重构:文档内概念名更新 System→Category, Component→Tag,Dify 变量名同步更新 |
| v2.1 | 2026-06-23 | System 自定义化改造:N1 API 扩展为 classification-labels 返回 categories+tags;N2 Prompt category 候选值改为 {% for %} 动态渲染;新增 N1c Code Node 提取 safety_tip;N7 Prompt 安全提示改为 数据驱动 |






