-
Data Governance Dev authored
动机 用户在结果表看到红 ! 标记的不合规行时,只能从 tooltip 看违反哪条规则, 但不知道为什么错、这条规则的代码是否真的实现了规则描述。需要点 ! 直接问 LLM,让模型同时审计数据违规原因和 规则 vs 代码 一致性。 同一字段常违反多条规则(如「11 位数字」+「号段分配」),需要开多个 tab 并行诊断。 改动 backend - core/ai_explain.py (新): explain_issue() 拼 prompt 调 LLM,解析 JSON, 失败时附带上次原文 + 修复提示自动重试,最多 3 次;JSON 解析失败不抛异常, 降级返回原文 + consistency='unknown' - routers/ai.py: 新增 POST /api/ai/explain_issue 端点 (ExplainIssueRequest/ExplainIssueResponse Pydantic) - routers/queries.py: _evaluate_row() 的 issues 字典追加 rule_id - core/session_manager.py: CompiledFieldRules.rules 快照元组 6 元→7 元 (追加 rule_id),让 _evaluate_row 能拿到规则 id frontend - components/ExplainIssueDialog.vue (新): Teleport + 自定义 .modal 模式 · ctx-strip 顶部展示字段名 + 原始值(所有 tab 共享) · 多 tab 行:每条违规规则一个 tab,打开即 Promise.allSettled 并行调 LLM · 每个 tab 独立 loading/result/error 状态(互不干扰) · tab 标题旁小圆点:加载中蓝色脉冲 / 失败红
⚠ / 完成按 consistency 染色(绿✓ / 红! / 黄? / 灰·) · 单 issue 时隐藏 tab 行 · 「重新分析」只重跑当前 active tab - components/ResultTable.vue: .err-flag 加 cursor:pointer + @click.stop, emitExplainIssue() 把该字段所有命中的 issue 都 enrich 后塞进 issues[] 一起 emit(之前只取第一条,第二条违规原因被忽略) - views/DataQualityView.vue: 监听 explain-issue → 打开 ExplainIssueDialog - api/ai.js: explainIssue(payload) 导出 LLM Prompt 关键设计 - 系统提示强调「先想清楚再用严格 JSON 输出」 - 用户提示拆任务 1(违规原因)+ 任务 2(一致性审查), 加 ASCII 双引号避坑(历史踩坑:value 里用裸 " 会让 json.loads 中断) - 一致性三档:match / code_bug / rule_ambiguous 关键决策 - Promise.allSettled 而非 Promise.all:单条 LLM 失败不应拖垮其他 tab - LLMUnavailable 不重试(无 key / 网络挂 / 限流):立即降级返回 - 重试时附上次原文:让 LLM 看到自己刚才错在哪,比纯说「修一下 JSON」有效 - 「重新分析当前规则」而非「全部重试」:定位精准,省 token E2E 验证 - regex 类型:consistency='code_bug'(LLM 正确识别硬性限制年份的 bug) - number 类型:consistency='rule_ambiguous'(LLM 指出「0-150 是否合理」需业务再斟酌) - npx vite build → ✓ built in 10.92s(1638 modules transformed,无报错) 注 - work-logs/2026-08-24.md 已记录三轮迭代详情 + 踩坑 - 另有 4 个 web3/tests/*.png modified 未提交(与本功能无关)5cb07f5a