Files
siemens_ragas/docs/superpowers/specs/2026-06-16-optimization-advisor-design.md
wangwei f5c2dce64a feat(advisor): add optimization advisor module
- rag_eval/advisor/: new package with rules engine, LLM analyzer, writer
  - rules.py: 7-metric diagnostic rules (warning/critical thresholds, top-3 low samples)
  - llm_analyzer.py: Chinese optimization report via judge_model, graceful fallback
  - writer.py: writes optimization_advice.md + log summary
  - __init__.py: run_advisor() entry point (no-op when optimization_advisor=False)
- Scenario.optimization_advisor: new bool field (default False)
- ScenarioModel: same field added, loader.py透传
- RunArtifactPaths.advice_md: new path field
- factory.py: build_models() now public; build_metric_pipeline() accepts pre-built llm/embeddings
- runner.py: lifts llm, passes to pipeline and advisor; calls run_advisor() at end
- siemens online YAML: optimization_advisor: true enabled
- tests: 9 rules tests + 6 writer tests, all pass
- docs: advisor section added to engine-flow.md and architecture.md

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-16 17:06:19 +08:00

226 lines
8.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 优化顾问模块设计 Spec
- 日期2026-06-16
- 状态:已确认,进入实现。
## 1. 目标
在现有 RAG 评测流程结束后,新增一个**优化顾问模块**Optimization Advisor根据本次评测的多项指标分数与低分样本自动诊断指标偏低的原因并给出针对性的优化建议输出为中文 Markdown 报告 + 日志摘要。
对应架构设计 §11优化策略将"指标到动作的映射"§11.2)从文档形式落地为代码自动执行。
---
## 2. 决策摘要
| 决策点 | 选择 |
|---|---|
| 输出形式 | `optimization_advice.md`(文件)+ 控制台/日志摘要(双输出) |
| 生成机制 | 规则引擎定位异常指标 → LLM 结合低分样本二次解读(两层) |
| 触发方式 | YAML 场景文件显式声明 `optimization_advisor: true`,默认关闭 |
| LLM 实例 | 复用 `build_models()` 已创建的 `llm` 实例,不重建 client |
| 包位置 | `rag_eval/advisor/`(独立包,对外暴露 `run_advisor()` 单一入口) |
---
## 3. 架构
### 3.1 执行链路
```
run_scenario()
→ load_scenario() # 读 YAML解析 optimization_advisor 字段
→ build_models() # 已有:创建 llm, embeddings
→ build_metric_pipeline() # 已有
→ Evaluator.evaluate() # 已有:打分 → EvaluationResult
→ write_run_artifacts() # 已有scores.csv / summary.md / ...
→ run_advisor( # 新增3 行)
result, scenario, llm, artifact_paths
)
→ rules.diagnose(score_rows) # 规则引擎:返回 Diagnosis 列表
→ llm_analyzer.analyze(diags, samples) # LLM生成中文 Markdown 建议
→ writer.write(advice, paths) # 写文件 + 打日志
```
### 3.2 新增文件
```
rag_eval/advisor/
__init__.py ← 暴露 run_advisor(),外部唯一入口
rules.py ← 纯函数规则引擎,无 LLM可单独单测
llm_analyzer.py ← 接收 llm 实例 + 诊断结构 → 中文 Markdown
writer.py ← 写 optimization_advice.md打日志摘要
```
### 3.3 修改文件(最小改动)
| 文件 | 改动 |
|---|---|
| `rag_eval/shared/models.py` | `Scenario``optimization_advisor: bool = False` 字段 |
| `rag_eval/config/schema.py` | `ScenarioModel` 加同名字段 + 透传到 `Scenario` |
| `rag_eval/config/loader.py` | 透传 `optimization_advisor``Scenario` 构造 |
| `rag_eval/reporting/artifacts.py` | `RunArtifactPaths``advice_md: Path` 字段 + `build_artifact_paths()` 加赋值 |
| `rag_eval/execution/runner.py` | `run_scenario()` 末尾:`build_models` 返回 llm 传入,条件调用 `run_advisor()` |
### 3.4 输出产物
```
outputs/online/siemens-pdf-question-bank/<run_id>/
scenario.snapshot.yaml
scores.csv
invalid.csv
summary.md
metadata.json
optimization_advice.md ← 新增optimization_advisor: true 时生成)
```
---
## 4. 规则引擎rules.py
### 4.1 数据结构
```python
@dataclass
class Diagnosis:
metric: str # 指标名
mean_score: float # 本次均值
threshold: float # 警戒阈值
severity: str # "warning" | "critical"
root_causes: list[str] # 可能原因(来自架构设计 §11.2
suggested_actions: list[str] # 对应可调阶段
low_samples: list[dict] # 分数最低的 N 条样本(含 question/answer/ground_truth
```
### 4.2 七条指标诊断规则
阈值参考 RAG 评测最佳实践,分 warning / critical 两档:
| 指标 | warning | critical | 根因方向 | 对应优化阶段§11.2 |
|---|---|---|---|---|
| `faithfulness` | < 0.7 | < 0.5 | 生成未严格基于检索片段 / 幻觉 | 生成 prompt grounding开启校验 |
| `answer_relevancy` | < 0.7 | < 0.5 | 回答偏离问题 / 格式冗余 | 查询改写生成 prompt 格式 |
| `context_recall` | < 0.7 | < 0.5 | 检索遗漏关键信息 | 多查询问题分解Step-back加大过召回 |
| `context_precision` | < 0.6 | < 0.4 | 检索引入过多噪声 / 排序差 | 后检索重排压缩相关性过滤 |
| `noise_sensitivity` | > 0.3 | > 0.5 | 回答被噪声片段干扰(越低越好) | 后检索相关性过滤、重排 |
| `factual_correctness` | < 0.6 | < 0.4 | 回答事实与标准答案偏差大 | 检索与生成综合优化 |
| `semantic_similarity` | < 0.7 | < 0.5 | 回答语义与标准答案差距大 | 生成 prompt检索质量 |
> 注:`noise_sensitivity` 越低越好0=完全不受噪声影响),其阈值方向与其余相反。
### 4.3 低分样本选取
每个触发诊断的指标取该指标分数最低的 **top-3** 样本排除 NaN附入 `Diagnosis.low_samples`字段包含 `sample_id / question / answer / ground_truth / <metric_score>`
---
## 5. LLM 分析器llm_analyzer.py
### 5.1 输入
- `diagnoses: list[Diagnosis]` 规则引擎输出仅触发阈值的指标
- `llm` 已有 RAGAS LLM 实例scenario judge_model
- `scenario_name: str` 用于报告标题
### 5.2 Prompt 设计
使用**一次 LLM 调用**把所有触发诊断的指标和低分样本一起发送
```
你是一个 RAG 系统优化专家,正在分析西门子医疗 CT 文档问答系统的评测结果。
请用中文撰写一份优化建议报告,格式为 Markdown。
## 评测诊断摘要
{for each diagnosis: 指标名、均值、阈值、可能原因、建议动作}
## 低分样本示例
{for each diagnosis: top-3 低分样本的 question / answer / ground_truth}
## 要求
1. 按指标分节(## 指标名),先解释"为什么低",再给出"具体怎么改"
2. "具体怎么改"要结合低分样本的具体内容,而不只是泛泛建议
3. 最后写一节 ## 优先优化次序,按性价比排序(参考:不增加调用次数的优先)
4. 语言简洁,面向工程师,不要废话
```
### 5.3 输出
LLM 返回的 Markdown 字符串直接写入 `optimization_advice.md`在报告头部追加运行元信息)。
### 5.4 失败降级
LLM 调用失败超时/异常降级为**纯规则报告**只输出规则引擎的诊断结构不含 LLM 解读文件照常写出错误信息写入报告末尾不阻断整个评测流程
---
## 6. 写出层writer.py
### 6.1 文件写出
`optimization_advice.md` 结构
```markdown
# 优化建议报告 — <scenario_name>
- run_id: `<run_id>`
- 生成时间: `<timestamp>`
- judge_model: `<model>`
---
<LLM 生成的 Markdown 正文>
```
### 6.2 日志摘要
`run_advisor()` 完成后向 `logger.info` 打印一条精简摘要单行适合 `run_eval.bat` 结束后一眼扫到
```
[advisor] 触发诊断 3 项: faithfulness(0.42, critical) context_recall(0.58, warning) noise_sensitivity(0.41, critical)
[advisor] 优化建议已写出: outputs/online/.../optimization_advice.md
```
---
## 7. YAML 配置
场景文件新增一个顶层字段
```yaml
optimization_advisor: true # 默认 falsetrue 时评测结束后自动生成优化建议
```
后续若需精细配置阈值覆盖top-N 低分样本数可扩展为
```yaml
optimization_advisor:
enabled: true
top_low_samples: 3 # 每个指标取几条低分样本(默认 3
# thresholds: # 可选:覆盖默认阈值
# faithfulness: 0.65
```
本轮实现仅支持 `optimization_advisor: true/false`扩展接口预留但不实现
---
## 8. 测试策略
| 测试 | 文件 | 说明 |
|---|---|---|
| 规则引擎单测 | `tests/test_advisor_rules.py` | 纯函数 LLM覆盖每条规则的 warning/critical 触发NaN 跳过low_samples 选取 |
| writer 单测 | `tests/test_advisor_writer.py` | mock Diagnosis 列表验证 md 文件写出格式和日志输出 |
| 集成可选 | 现有 `tests/test_online_eval.py` | 验证 `optimization_advisor: true` 场景下 advice_md 存在 |
LLM 分析器不写单测依赖网络由集成场景覆盖
---
## 9. 不覆盖(本轮边界)
- 不支持跨版本对比分析只分析本次 run
- 不支持批量场景聚合建议
- 不建设 Web UI 展示
- LLM 分析器 prompt 本轮不做多语言适配直接中文
- advisor 阈值本轮硬编码在 `rules.py`不从 YAML 读取