返回项目分享

KDAgent:让大模型做工业过程根因分析,并且能证明它有没有胡说

Python 实验框架,在 SWaT / WADI 水务测试床的 Top-10 候选结果上比较不同 LLM 的根因分析能力;四种消融设置加双分支确定性融合,自动产出 Accuracy@1/3/5、有效 JSON 率与幻觉率,并留下完整审计记录。

维护中

要回答的问题

工业过程出事之后,「根因是什么」 traditionally 靠算法给候选列表: 基于传递熵之类的因果分析(TA-RCA)能算出一批 Top-10 候选变量,但它给的是统计关系,不是解释。 大模型有可能补上「解释」这一段——前提是它真的在推理,而不是把候选列表用漂亮话复述一遍, 甚至干脆挑一个不在列表里的答案。

所以这个项目我没有做成一个「RCA 应用」,而是做成了一套可复现的对比实验框架: 同一份输入,跑不同的方法组合,看指标差在哪,并且每一次调用都留下可审计的原始记录。

实验设计

输入是统一的案例格式(llm_prompt_cases.jsonl):每条案例带 TA-RCA 的 Top-10 候选、 按时间窗切出的时序证据,以及真值标签。方法上分五档:

  1. 直接提示(plain prompting);
  2. RAG 检索增强提示;
  3. 迭代自修正 Agent(iterative self-refinement);
  4. RAG + 自修正 Agent 的组合;
  5. 双分支确定性融合(本方法:时序证据分支 + RAG 分支,再做确定性合并)。

官方矩阵是 5 个模型 × 5 个条件,一条命令跑完(scripts/run_final_experiments.py)。 每个案例重复推理 --num_runs 次,temperature、max_tokens、可选的 thinking_budget 全部固定, 目的是让「换个模型」和「换个提示词」这两种差异能被分开看。

指标里我最在意两个

  • Accuracy@1 / @3 / @5:真值排到第几,比只看 Top-1 更能反映排序质量;
  • hallucination_rate:模型给出的根因不在候选集合里的比例。 这个指标是我认为整个评测里最有价值的一条——它直接回答「模型是在推理还是在编」。

另外还记 valid_json_rate(结构化输出可用率)和 average_confidence, 以及迭代 Agent 与 RAG 各自的诊断指标(比如第几轮才开始收敛、检索有没有命中)。

为了「可复现」做的工程

这部分比模型调用更花时间:

  • 模型统一走 OpenAI 兼容接口,在 configs/models.yaml 里配 DashScope、DeepSeek、智谱等, 同一套流水线换供应商不用改代码;
  • 密钥只从环境变量读(配置里写 api_key_env 的变量名),不进代码、不进配置、不进日志; 缺某个 key 时跳过该模型并在日志里报告,而不是整批中断;
  • 调用侧:指数退避加抖动(base * 2^(attempt-1) 再叠加 0–30% 抖动)、超时、失败容错;
  • 解析侧:先按 JSON 解析,失败退化成正则兜底,再做确定性校验—— 答案必须落在候选集合内,否则直接判为无效或幻觉;
  • 审计链完整:原始响应存 JSONL、解析结果摊平成 CSV、聚合指标出 JSON/CSV, 每个模型每个条件一套;
  • analysis/ 下的脚本可以在完全不调用任何 LLM API 的情况下重算指标, 改统计口径不用重新花钱跑一遍;
  • 依赖同时给 requirements.txt 和 requirements-lock.txt(锁定版本), 后者用于严格复现报告里的结果;
  • 有单元测试和用 mock 模型跑的端到端冒烟测试,verify_csv.py 用来校验一次运行产出的 CSV。

现在的状态与下一步

框架、消融矩阵、指标与离线复算脚本都可用;具体的实验数字我不写在这里, 全部以仓库 outputs/ 下的原始响应与聚合指标为准—— 数字要能被重算才有意义,抄进文档里迟早会过期。

下一步想做的是:把检索稳健性实验(scripts/run_retrieval_robustness.py)扩到更多扰动, 以及给双分支融合里「确定性」那部分再收紧一些。

技术栈

Python 3.9+,openai、chromadb、pandas、numpy、pyyaml、tenacity、tqdm、requests; 向量检索用 ChromaDB,数据集为 SWaT(主)与 WADI。

对这个项目有问题或建议?讨论留在仓库里更容易被看到,欢迎 到仓库提 Issue