Dify 高级实验08智能告警——如何用 AI 替代固定阈值监控Dify 实验系列 · 高级 08/10 | 实验编号DIFY-103-08基于 Dify 1.16.1 实测2026-081. 业务场景先讲一个我们实际遇到的场景。一家 SaaS 公司的运维团队凌晨两点被告警电话吵醒——监控系统报「数据库连接超时」值班同学爬起来一看日志里就那么几条 ERROR等他想进一步排查时故障已经自己恢复了。第二天复盘才发现那只是网络抖动系统自动重连成功了。可同样的告警上周真的把数据库搞挂了那次因为响应慢了十分钟线上服务中断了半小时。固定阈值监控的尴尬就在这里同一个告警有时候是虚惊有时候是真灾——阈值规则根本分不清。我们第一次接手监控告警时第一反应也是「把阈值调准一点不就行了」。后来才发现——阈值规则理解不了上下文而「数据库连接超时」到底是网络抖动还是数据库挂了恰恰需要看上下文才能判断。这是规则的死角却是 LLM 的主场把日志喂给它它能说出「这是抖动不用管」还是「这是故障立刻升级」。这不是个例。任何「靠固定阈值做监控」的团队都是这个模式CPU 超过 90% 就告警、日志出现 ERROR 就告警——阈值定低了告警风暴淹没真故障阈值定高了真故障被漏掉。规则理解不了上下文而「数据库连接超时」是网络抖动还是数据库挂了恰恰需要看上下文才能判断。2. 场景痛点这个流程的痛点在运维值班同学身上体现得最直接告警风暴固定阈值误报率高深夜被无关告警吵醒是常态——狼来了喊多了真故障来了反而没人第一时间响应。上下文缺失告警只给「CPU 95%」这种孤立数字不说前因后果——值班同学还得手动翻日志、查指标故障定位慢MTTR 居高不下。误报漏报并存同样是 ERROR网络抖动和数据库宕机在阈值规则眼里一样——该升级的没升级不该升级的疯狂打扰分级处置形同虚设。处置经验不沉淀每个故障怎么判断、怎么处理都靠老运维的经验——人走了经验就没了新人值班只能边翻文档边猜。本质上固定阈值的瓶颈是「规则理解不了上下文」——监控的价值不在「报不报」而在「报得准不准、报完能不能直接定位根因」。3. 方案为什么是这套智能告警范式Dify 工作流里的「解析 → AI 分析 → 分级路由 → 汇聚报告」链路把监控从「阈值报警」升级成「AI 判断 分级处置」。选它的理由我们实际对比过LLM 理解上下文区分真假异常把解析后的日志喂给 LLM让它判断「是否真异常、等级、根因、建议措施」——同样是 ERROR能区分网络抖动和数据库挂了这是阈值规则做不到的JSON 输出 代码展平分级路由可靠LLM 输出 JSON代码节点解析并展平为可见字符串字段IF/ELSE 按 critical/warning/info 三级分流——紧急告警建工单、一般告警发通知、正常仅记录汇聚报告沉淀处置经验三个分支最终统一生成结构化诊断报告根因、影响模块、建议措施都在——值班同学拿到的是结论不是一堆日志。这篇文章我们就用它搭一个「智能日志告警系统」粘贴一段系统日志AI 判断是否异常、按等级分流处置输出结构化诊断报告。4. 整体架构criticalwarninginfo开始raw_logsCode 解析日志级别/模块/错误信息 统计LLM 异常分析输出 JSONCode 解析异常等级json.loads severity 白名单兜底 展平 7 字段IF/ELSE 等级分支Code 紧急告警 创建工单Code 一般告警通知Code 记录日志不通知LLM 生成诊断报告结束链路很清晰入口收原始日志 → 结构化解析 → AI 分析 → 分级路由 → 汇聚诊断报告。分级路由是这个架构的处置中枢——critical 建工单、warning 发通知、info 只记录三级分流互不干扰最后统一汇聚成一份诊断报告。5. 模块设计5.1 解析日志cd_parse_logs输出parsed_entriesarray[object]供下游代码消费与parsed_jsonstring供 LLM 引用——array[object] 在变量选择器不可见defmain(raw_logs:str)-dict:importjson lines(raw_logsor).strip().split(\n)parsed[]forlineinlines:ifnotline.strip():continueentry{raw:line,level:info,module:,message:}ifERRORinlineorFATALinline:entry[level]errorelifWARNinline:entry[level]warnif]inline:entry[module]line.split(])[0].strip([)entry[message]line.split(])[-1].strip()else:entry[message]line parsed.append(entry)return{parsed_entries:parsed,parsed_json:json.dumps(parsed,ensure_asciiFalse),total:len(lines),errors:sum(1foreinparsedife[level]error),warnings:sum(1foreinparsedife[level]warn)}5.2 异常分析 LLMlm_analyze枚举字段必须给判定规则只写 critical/warning/info 不给规则LLM 会随意输出下游分支全走错你是一个系统运维工程师。分析以下系统日志判断是否存在异常。 解析后的日志共 {{#cd_parse_logs.total#}} 条{{#cd_parse_logs.errors#}} 个错误{{#cd_parse_logs.warnings#}} 个警告 {{#cd_parse_logs.parsed_json#}} 输出 JSON只输出 JSON不要输出其他任何内容 {has_anomaly: true/false, severity: critical/warning/info, root_cause: 根因分析, affected_modules: [模块1, 模块2], suggested_action: 建议措施, auto_resolvable: true/false} 判定规则只有 critical 或 warning 才算异常正常日志 severity 为 info。5.3 解析异常等级cd_parse_analysis对 LLM 的text做re.search(r\{.*\})json.loads——这要求 lm_analyze 必须reasoning_format: separated否则思考混入 text 解析必失败。severity 白名单兜底boolean 展平为字符串defmain(llm_text:str)-dict:importjson,re text(llm_textor).strip()analysis{}mre.search(r\{.*\},text,re.DOTALL)ifm:try:parsedjson.loads(m.group(0))ifisinstance(parsed,dict):analysisparsedexceptException:analysis{}severitystr(analysis.get(severity,info)).lower()ifseveritynotin(critical,warning,info):severityinfo# 白名单兜底affectedanalysis.get(affected_modules,[])or[]affected_text、.join(str(x)forxinaffected)ifisinstance(affected,list)elsestr(affected)return{severity:severity,has_anomaly:trueifanalysis.get(has_anomaly)elsefalse,root_cause:str(analysis.get(root_cause,))or无明显异常,suggested_action:str(analysis.get(suggested_action,))or无需处理,affected_modules:affected_text,auto_resolvable:trueifanalysis.get(auto_resolvable)elsefalse,analysis_json:json.dumps(analysis,ensure_asciiFalse)}5.4 等级分支cond_severity三个 case 全部is字符串比较每个分支一个代码节点cd_critical/cd_warning/cd_info输出同名字段alert_message/alert_type/notify_result/ticket_id。5.5 汇聚诊断报告lm_report三分支汇聚共享一个 LLM——prompt 只引用分支前的字段cd_parse_logs / cd_parse_analysis不引用分支输出避免三分支同名字段歧义长报告节点同样要求「直接输出报告正文」你是一个系统运维专家。基于以下日志解析结果和异常分析生成一份完整的诊断报告。 日志概况共 {{#cd_parse_logs.total#}} 条日志{{#cd_parse_logs.errors#}} 个错误{{#cd_parse_logs.warnings#}} 个警告。 异常分析结论 - 是否异常{{#cd_parse_analysis.has_anomaly#}} - 异常等级{{#cd_parse_analysis.severity#}} - 根因分析{{#cd_parse_analysis.root_cause#}} - 影响模块{{#cd_parse_analysis.affected_modules#}} - 建议措施{{#cd_parse_analysis.suggested_action#}} 输出一份结构化的诊断报告包含1. 摘要 2. 异常详情 3. 根因分析 4. 建议措施 5. 后续监控建议。直接输出报告正文。6. 运行验证输入raw_logs期望行为实测正常日志INFO 为主severityinfo走「记录日志」分支诊断报告标注无异常与预期一致含 ERROR 的日志severitywarning一般告警通知 根因分析与预期一致含多次 CRITICAL/FATAL 的日志severitycritical紧急告警 创建工单ticket_id 形如 TK-xxxxxx与预期一致LLM 输出非法 JSON / 无 severity 字段白名单兜底 severityinfo流程不中断与预期一致cd_parse_analysis 防御7. 实战坑坑现象修复LLM 输出 JSON 被代码节点json.loads解析失败未启用推理标签分离时思考过程混入textre.search取到含think的片段、json.loads抛异常流程卡住lm_analyze显式reasoning_format: separateddify103_02 实测解析失败流程卡在步骤 0枚举字段 severity 不给判定规则LLM 随意输出 critical/warning/info告警分支全走错该紧急告警的只发了普通通知prompt 给显式规则「只有 critical 或 warning 才算异常」 代码白名单兜底 default infodify102_08_01 实测缺陷同源has_anomaly/auto_resolvable用 boolean 输出boolean 在变量选择器不可见下游引用取不到旧写法曾把拦截信息转述成「无法获取数据」展平为true/false字符串if-else 用is比较2026-07-31 dify-103 实测诊断报告长输出text为空思考与输出共享 max_tokens 预算默认 2000被挤空或内容写进思考部分lm_reportmax_tokens提到 4000-8000 prompt「直接输出报告正文不要输出任何解释性文字」dify103_09 lm_format 实测多分支汇聚共享下游 LLM三个分支代码输出字段同名alert_message 等汇聚 prompt 引用分支输出会歧义、取不到汇聚 LLM 只引用分支前的字段cd_parse_logs/cd_parse_analysis分支输出不进 promptdify103_08 交付实证8. 实验文档及源码获取实验文档完整操作步骤DIFY-103-08系统监控与智能告警.md源码可直接导入dify103_08_系统监控与智能告警.yml文章聚焦核心配置与采坑点实验的完整分步操作节点搭建/参数表/调试指引见实验文档原文。下一篇Dify 高级实验09测试用例生成——如何让 AI 自动产出测试用例 你在这个实验的场景里踩过什么坑欢迎评论区分享你的实战经验。