docs(issue): archive legacy issues and add iss-015

This commit is contained in:
zhuyongxin
2026-07-23 19:54:01 +08:00
parent 529f4ff43b
commit 49180abccf
18 changed files with 186 additions and 40 deletions
@@ -1,170 +0,0 @@
# ISS-003 MVP 设计与实现 Review 收敛
**状态**:待规划
**严重程度**:高
**发现时间**:2026-07-03
**来源**:MVP 版本设计与实现 review
---
## 背景
当前 MVP 已具备 Chat、Planner/Executor/Verifier、知识检索、诊断会话落库、反馈与 case library 等主线能力,但设计文档、运行时实现和可验证性之间仍存在明显偏差。
本 issue 用来收敛本次 review 的主要风险,方便后续拆 OpenSpec change 或工程任务。
---
## 核心问题
### P0:敏感配置直接提交到仓库
`src/main/resources/application.yml` 中包含真实基础设施地址、数据库密码、Redis 密码、Milvus token、LLM API key。
`src/test/java/com/superbiz/agent/service/SimpleMilvusTest.java` 中也硬编码了 Milvus/Zilliz token。
**影响**:
- 密钥泄漏后需要立即轮换。
- 合并 worktree 后会扩大泄漏面。
- `show-sql: true` 与 DEBUG 日志可能进一步暴露业务数据。
**建议**:
- 立即轮换已提交的 token/password/api-key。
- 将敏感配置改为环境变量或本地 profile 覆盖。
- 提交 `application-example.yml` 或 `.env.example`,不要提交真实值。
### P1:测试体系不能稳定离线运行
`mvn test` 编译阶段通过,但 surefire 阶段大量失败,主要原因是测试直接依赖外部 MySQL、Redis、Milvus、LLM/Embedding 服务。
典型失败:
- MySQL/Flyway 连接失败导致 repository、Redis、Spring context 测试失败。
- Milvus 连接测试出现 `DEADLINE_EXCEEDED`。
- 当前环境下 Mockito inline mock maker self-attach 失败。
**影响**:
- 无法在合并前获得可靠的回归信号。
- 实现变更与环境故障混在一起,问题定位成本高。
**建议**:
- 将纯单测、H2/JPA slice、外部集成测试分离。
- 用 Maven profile 或 JUnit tag 区分 `unit` / `integration`。
- 默认 `mvn test` 只跑不依赖外部服务的测试。
### P1:会话管理设计与实现不一致
`mvp/architecture/archive/2026-07-05-legacy/session-management.md` 设计 Redis 作为主会话存储,带 `session:{session_id}` 和 TTL。
实际 `/api/chat` 在 `ChatController` 中使用 JVM 内存 `ConcurrentHashMap` 管理历史消息,`RedisSessionManager` 虽然存在但没有接入 controller。
**影响**:
- 应用重启后会话历史丢失。
- 多实例部署时会话不一致。
- Redis TTL 与设计中的生命周期不生效。
- 前端 chat session id 与后端 diagnosis session id 存在分裂。
**建议**:
- 明确 MVP 阶段是否接受内存会话。
- 如果接受,需要同步更新文档并标注限制。
- 如果不接受,应将 `ChatController` 接入 `SessionManager`,统一 session id 与 diagnosis session id 的关系。
### P1:Verifier 证据链仍不完整
`ToolTraceSummaryService` 期望从 `tool_invocation` 汇总 `lookup_knowledge`、`query_logs`、`query_metrics`、`query_order` 等证据工具。
当前只有 `LookupKnowledgeTool` 主动写入 `tool_invocation`。`QueryMetricsTools` 和 `QueryLogsTools` 返回 JSON,但没有落库。
**影响**:
- verifier 无法稳定审计日志、指标、订单等非知识库工具事实。
- `thought` 或模型输出中看起来做了很多推理,但可追溯工具调用证据不足。
- 用户侧可观测性仍然偏低。
**建议**:
- 抽象统一的 `ToolInvocationRecorder`。
- 所有 evidence tool 都必须记录 input、output preview、success、duration、trace id。
- verifier 只消费结构化 trace summary,不依赖模型自由文本回忆工具调用。
### P1:上传文档路径存在重复拼接风险
`DocumentManagementService.saveToLocal()` 返回的是包含 `knowledge_base` 前缀的本地路径。
`KnowledgeIndexService.readDocument()` 又执行 `Paths.get(knowledgeBasePath, filePath)`。
**影响**:
- 上传文档进入 L0 索引后,命中时读取原文可能拼成 `knowledge_base/knowledge_base/...`。
- 这会降低 L0 命中后的答案质量,并造成“命中但读不到原文”的隐性故障。
**建议**:
- 统一 `filePath` 语义:要么存相对 `knowledge.base-path` 的路径,要么存绝对路径。
- `readDocument()` 对 absolute path、已带 base path 的 relative path 做兼容。
- 增加上传文档后 L0 命中并读取原文的回归测试。
### P2:SupervisorAgent 构建后未使用
`ChatService.executeChatComplex()` 中创建了 `SupervisorAgent`,但实际仍通过 `callAgent(planner/executor/verifier)` 手写顺序编排。
**影响**:
- 代码与设计文档中的 multi-agent 编排表述不一致。
- 后续维护者容易误判当前已由 Supervisor 执行调度。
**建议**:
- 删除未使用的 `SupervisorAgent` 构建,明确当前是手写编排。
- 或真正切到 Spring AI Alibaba SupervisorAgent flow,并补充行为验证。
### P2:生产安全边界偏弱
`SessionConfiguration` 使用 `activateDefaultTyping + LaissezFaireSubTypeValidator` 配置 Redis JSON 反序列化。
`WebMvcConfig` 对所有路径放开 CORS。
**影响**:
- Redis 若被非可信写入,存在多态反序列化风险。
- CORS 全放开适合本地 MVP,不适合公开环境。
**建议**:
- Redis value 使用明确 DTO 类型或受限 subtype validator。
- CORS 改为按 profile 配置允许域名。
---
## 优先级建议
1. 先处理敏感配置和密钥轮换,避免合并后扩大泄漏范围。
2. 建立可离线运行的单测基线,让默认 `mvn test` 可用于合并门禁。
3. 统一 session id 与 session storage,解决前后端、Redis、diagnosis session 的语义分裂。
4. 补齐所有 evidence tool 的 `tool_invocation` 落库,提升 verifier 可追溯性。
5. 修正上传文档路径语义,并补回归测试。
6. 清理或真正启用 `SupervisorAgent`,避免设计和实现长期漂移。
---
## 相关文件
- `src/main/resources/application.yml`
- `src/test/java/com/superbiz/agent/service/SimpleMilvusTest.java`
- `src/main/java/com/superbiz/agent/controller/ChatController.java`
- `src/main/java/com/superbiz/agent/service/session/impl/RedisSessionManager.java`
- `src/main/java/com/superbiz/agent/service/ToolTraceSummaryService.java`
- `src/main/java/com/superbiz/agent/tool/LookupKnowledgeTool.java`
- `src/main/java/com/superbiz/agent/agent/tool/QueryMetricsTools.java`
- `src/main/java/com/superbiz/agent/agent/tool/QueryLogsTools.java`
- `src/main/java/com/superbiz/agent/service/DocumentManagementService.java`
- `src/main/java/com/superbiz/agent/service/KnowledgeIndexService.java`
- `src/main/java/com/superbiz/agent/service/ChatService.java`
- `src/main/java/com/superbiz/agent/config/SessionConfiguration.java`
- `src/main/java/com/superbiz/agent/config/WebMvcConfig.java`
@@ -1,59 +0,0 @@
# ISS-004 Executor 域级检索水位控制(Phase 2)
**状态**:待规划
**严重程度**:低
**发现时间**:2026-07-01
**关联**:ISS-002(Executor 无约束重复调用 lookup_knowledge)
---
## 现象
ISS-002 修复后,`lookup_knowledge` 调用已经从 20+ 次收敛到约 10 次,但仍存在同一批 domain 之间反复横跳的冗余调用。
当前文档级去重能阻止重复内容进入上下文,但不能阻止 LLM 继续发起相似检索请求。
---
## 根因
Prompt 软约束依赖 LLM 自觉遵守。在 ReactAgent 自主决策模式下,模型倾向于“再确认一步”,而不是信任已有信息。
---
## 影响
- 不影响核心答案正确性。
- 增加每轮检索耗时和 token 消耗。
- 长会话中冗余调用会随 session 继续累积。
---
## 建议方案
在代码层增加域级检索水位控制,而不是只依赖 prompt。
水位指标可以包括:
- 当前 session 内 `lookup_knowledge` 调用次数。
- 当前 session 已检索 domain 数量。
- 当前 session token 消耗。
- 最近一次检索结果的 `relevanceLevel`。
决策矩阵示例:
| 水位 | PRECISE | HIGHLY_RELEVANT | REFERENCE | DEDUPED |
|---|---|---|---|---|
| 低 | 可继续 | 可继续 | 可定向补充 | 停止 |
| 中 | 可继续 | 建议停止 | 可定向补充 | 停止 |
| 高 | 停止 | 停止 | 停止 | 停止 |
---
## 相关文件
- `src/main/java/com/superbiz/agent/dto/LookupResult.java`
- `src/main/java/com/superbiz/agent/tool/RetrievedDocTracker.java`
- `src/main/java/com/superbiz/agent/tool/LookupKnowledgeTool.java`
- `src/main/resources/prompts/chat-executor-prompt.md`
- `mvp/architecture/archive/2026-07-05-legacy/action-memory-relevance.md`
@@ -1,54 +0,0 @@
# SuperBizAgent ISS-014 交接文档
## 当前上下文
- 分支:`refactor/chat-single-react-harness`
- 任务:停止端到端验证,提交当前代码,更新 ISS-014,并交接后续开发。
- 本轮没有继续启动服务或发送真实请求;9900 端口确认没有监听进程。
- 工作区仍包含用户已有的文档、技能和演示输出改动;提交时只纳入 ISS-014 实现相关文件。
## 本次已完成
1. 新增独立追加式 `diagnosis_trace_event` 审计表和记录器,覆盖 Run、Routing、Agent、Tool、Evidence、Semantic、Release 生命周期事件。
2. Knowledge Query 使用 `BeanOutputConverter<KnowledgeAnswerDraft>` 注入实际 JSON Schema,修复缺少 Schema 导致的 `Knowledge answer is invalid`。
3. Fallback 增加 `failure_stage`、`observed_facts`、`validation_issues`,为失败提供可操作的阶段、事实和校验信息,同时不暴露 Prompt、原始 Draft 或 Tool 载荷。
4. 新增 `agent_reasoning_audit` 表、Repository、Hook 持久化和专用查询接口。只保存模型供应商实际返回的 reasoning 元数据,长度上限 32000 字符;普通 Trace 只展示是否存在及字节数,不返回原文。
5. ISS-014 已更新,记录上述实现、成功用例、协议边界变化和后续工作。
## 已知验证结果
- Diagnosis 成功:`mvp-demo-success-e2e-20260722-2032` / `e72d9c7b-2f78-44c8-9086-f2e9d6987f24`,SUCCESS,8455 tokens,1 次 Tool 调用。
- Knowledge Query 成功:`mvp-demo-order-timeout-fixed-20260723` / `2b704d1b-8f11-40ee-a4c6-5e5e04d3847c`,SUCCESS,1998 tokens。
- 已通过的重点测试:`HarnessAgentAuditHookTest`、`DiagnosisReleaseUseCaseTest`、`DiagnosisTraceServiceTest`、`HarnessContractTest`、`HarnessChatConfigurationTest`、`ApplicationExecutorsTest`、`ChatApplicationUseCaseTest`、`JpaToolInvocationAuditSinkTest`、`JpaDiagnosisTraceRecorderTest`,以及编译和 `git diff --check`。
- V015 真实数据库迁移、reasoning endpoint 的真实数据库/E2E 尚未验证。
## 后续实现顺序
1. 为 Diagnosis Agent 增加硬停止策略:限制证据轮次、阻止重复 `lookup_knowledge`,在预算耗尽前强制输出最终 Draft。
2. 给 Evidence Repair 注入真实 `DiagnosisDraft` Schema,消除运行时 `PARSE_ERROR`。
3. 使用真实 Provider 验证 reasoning metadata;无 reasoning 时也要写入 `reasoning_available=false` 的审计记录。
4. 在受控环境验证 V015 迁移和 reasoning 查询接口,并用精确 `sessionId + runId` 对齐数据。
5. 评估 reasoning 审计表的访问控制、保留期限和加密策略。
6. 继续细化工具成功但无法构造 verified snapshot 时的 fallback 事实和校验问题。
## 重要约束
- 不恢复完整端到端验证,除非用户明确要求。
- 不把 reasoning 审计内容当作事实证据,也不加入普通 SSE、Trace 或业务结果。
- 不提交无关用户文件、演示输出、环境配置和凭据。
- ISS-014 的后续阶段仍按独立 sm-flow/OpenSpec、归档、提交后再进入下一阶段。
## 建议技能
- `diagnose`:继续处理 Agent 重复工具调用、预算耗尽和 Evidence Repair 解析失败。
- `sm-flow`:开始下一阶段实现时按 OpenSpec-first 流程执行和归档。
- `gitnexus-debugging`:定位 Agent 停止条件和跨 Harness 调用链问题。
- `gitnexus-impact-analysis`:编辑共享 Harness/Agent 方法前评估调用影响。
## 关键文件
- Issue:`mvp/issues/active/ISS-014-single-react-agent-harness-aci-ptk-refactor.md`
- Trace:`src/main/java/com/superbiz/agent/harness/audit/`、`src/main/java/com/superbiz/agent/service/DiagnosisTraceService.java`
- Reasoning:`src/main/java/com/superbiz/agent/domain/entity/AgentReasoningAudit.java`、`src/main/java/com/superbiz/agent/harness/audit/HarnessAgentAuditHook.java`、`src/main/resources/db/migration/V015__create_agent_reasoning_audit.sql`
- Fallback:`src/main/java/com/superbiz/agent/harness/release/SafeFallbackFactory.java`
- Knowledge:`src/main/java/com/superbiz/agent/harness/application/executor/KnowledgeQueryExecutor.java`
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,103 @@
# ISS-015 诊断运行质量与 Reasoning 审计收敛
**状态**:待实施
**严重程度**:高
**发现时间**:2026-07-23
**来源**:ISS-014 阶段 7 及后续真实 E2E 验证
**关联**:ISS-014、ISS-004、executor-evidence-attribution-hallucination
---
## 1. 背景
ISS-014 已完成单体 Diagnosis ReAct Agent、Harness、ACI Tool、EvidenceGuard、SemanticGuard、SSE 和旧架构清理,并通过阶段 7 E2E 以及后续 Diagnosis/Knowledge Query 成功用例验证主链路。真实 E2E 同时暴露了新的运行质量问题:Agent 可能重复检索直至预算耗尽,Evidence Repair 可能因输出 Schema 不完整而解析失败,Reasoning 审计能力尚未完成真实 Provider 和数据库验证,安全 Fallback 在部分失败路径下仍缺少足够信息。
这些问题发生在 ISS-014 架构切换和验收之后,不重新打开 ISS-014,也不改变已经冻结的单体 Agent/Harness/ACI 架构。本 Issue 作为后续唯一追踪入口。
## 2. 用户体验问题
### 2.1 审计需要保留 Agent 思考记录
用户需要在后续审计中查看 Agent 的思考过程,确认它为什么选择某个 Tool、如何从观察结果继续行动以及在哪个阶段停止。该记录必须是独立的审计数据,不能混入业务事实、Evidence Snapshot、普通 Trace 或 SSE,也不能把未由 Provider 返回的内容伪造成思考记录。
### 2.2 失败结果不能只给空泛结论
当前失败路径可能直接返回“当前证据无法完成真实性校验,无法确认根因”。这虽然避免了无依据结论,但没有告诉用户已经观察到什么、校验在哪个阶段失败、缺少哪些信息以及下一步可以怎么查,导致用户无法判断系统是否真的执行过有效排查。
Fallback 必须在不暴露 Prompt、原始 Draft、原始 Tool 载荷和内部异常的前提下,提供有界的 `failure_stage`、`observed_facts`、`validation_issues`、查询范围、已完成的 Tool/证据阶段和可执行的 `next_steps`。
## 3. 已有验证基线
- Diagnosis 成功:`sessionId=mvp-demo-success-e2e-20260722-2032`,`runId=e72d9c7b-2f78-44c8-9086-f2e9d6987f24`,`release_outcome=SUCCESS`,总 Token 8455,Tool 调用 1 次。
- Knowledge Query 成功:`sessionId=mvp-demo-order-timeout-fixed-20260723`,`runId=2b704d1b-8f11-40ee-a4c6-5e5e04d3847c`,`release_outcome=SUCCESS`,总 Token 1998。
- 失败会话 `session_ud9pzde7r_1784785531138` 暴露两类问题:Evidence Repair `PARSE_ERROR`;Diagnosis Agent 重复调用 `lookup_knowledge`,最终在 12 次 Tool 调用、45087 Token 后进入 `BUDGET_EXHAUSTED`。
- `diagnosis_trace_event`、信息化 Fallback、`agent_reasoning_audit` 和 reasoning 查询接口已经实现并通过 focused tests;真实 Provider/V015 验证仍属于本 Issue。
## 4. 目标
1. Agent 在证据轮次或单 Tool 预算接近上限时停止继续检索,并生成当前证据允许的最终 Draft。
2. Evidence Repair 使用真实 `DiagnosisDraft` JSON Schema,消除结构修复阶段的 `PARSE_ERROR`。
3. Reasoning 审计在真实 Provider 返回和不返回 reasoning 的两种情况下都有明确、可查询的审计结果。
4. Reasoning 原文保持独立受限存储,不进入普通 SSE、Trace、证据快照或业务结果。
5. Fallback 在不泄露 Prompt、Draft 和原始 Tool 数据的前提下,说明失败阶段、已观察事实和校验问题。
6. 用户在失败时至少能知道系统执行到哪个阶段、看到了哪些有界事实、哪些校验未通过以及下一步应补充什么信息。
## 5. 实施阶段
### 阶段 1:Diagnosis Agent 硬停止策略
- 限制证据收集轮次和重复 `lookup_knowledge`。
- 在预算耗尽前向 Agent 注入停止信号并要求输出最终 Draft。
- 区分正常 ReAct 轮次、新 Tool Action 和真正的预算耗尽。
- 增加重复检索、临界预算和无足够证据时的回归测试。
### 阶段 2:Evidence Repair Schema
- 使用框架 `BeanOutputConverter<DiagnosisDraft>` 或等价结构化转换器注入实际 JSON Schema。
- 保持 Repair 无 Tool、最多一次、失败即安全 Fallback 的现有边界。
- 覆盖合法修复、Schema 非法、解析失败和二次 EvidenceGuard 失败。
### 阶段 3:Reasoning 审计验证与治理
- 使用真实 Provider 验证 reasoning metadata 的键和返回行为。
- Provider 不返回 reasoning 时写入 `reasoning_available=false`,不得伪造内容。
- 验证 V015 数据库迁移和 `sessionId + runId` 精确 reasoning 查询。
- 明确 reasoning 审计接口的访问控制、保留期限和加密要求。
### 阶段 4:Fallback 信息质量与最终 E2E
- 工具成功但无法构造 verified snapshot 时,返回有界 `observed_facts` 和 `validation_issues`。
- 确保普通 Trace 只记录 `reasoning_available/reasoning_bytes`,不返回 reasoning 原文。
- 运行至少一个 Diagnosis SUCCESS、一个信息化 FALLBACK 和一个 reasoning unavailable 的真实 E2E。
- 按 exact `sessionId + runId` 核对 SSE、Trace、Reasoning Audit、ToolInvocation 和 Run 终态。
## 6. 验收标准
- 重复检索场景不会因第 9 次同 Tool 调用才被动触发 `BUDGET_EXHAUSTED`。
- Agent 在有证据时可形成合法 Draft;证据不足时形成无强结论的合法 Draft 或信息化 Fallback。
- Evidence Repair 的真实模型输出不再出现因缺失 `DiagnosisDraft` Schema 导致的 `PARSE_ERROR`。
- V015 在真实数据库中迁移成功,reasoning 查询严格校验 path `sessionId` 与 query `runId` 的归属关系。
- Provider 无 reasoning 时仍有审计记录;Provider 有 reasoning 时原文只存在于受限审计接口。
- 普通 SSE、Trace、日志、Evidence Snapshot 和发布结果均不包含 reasoning 原文、Prompt 或原始 Tool 载荷。
- 审计查询能按精确 `sessionId + runId` 返回每个 Agent 模型步骤的 reasoning 可用性、步骤顺序、字节数和受限原文;不存在跨 Session/Run 串读。
- 失败 Fallback 不再只返回固定的“无法确认根因”文本;至少包含失败阶段、非敏感观察事实、具体校验问题、证据范围/缺口和下一步建议。
- `observed_facts` 和 `validation_issues` 有长度和字段边界,不能泄露 Prompt、完整上下文、原始 Tool 响应、凭据或内部堆栈。
- 在无证据、EvidenceGuard 失败、Evidence Repair 失败、SemanticGuard UNSUPPORTED 和预算耗尽等路径下,用户都能区分失败原因,而不是收到同一种空泛结论。
- 三类最终 E2E 证据和精确数据库核验完成归档。
## 7. 流程门禁
- 每个阶段使用独立 OpenSpec change 和完整串行 sm-flow。
- 每阶段完成 Apply、focused tests、验收证据、Archive 和独立 Git commit 后再进入下一阶段。
- 阶段 1-3 不运行完整 live E2E;阶段 4 统一完成最终真实验证。
- 不重新引入 Planner/Executor/Verifier/Composer、业务 Graph、第二 Chat 入口或通用工作流 DSL。
## 8. 相关文件
- `mvp/issues/archived/ISS-014-single-react-agent-harness-aci-ptk-refactor.md`
- `src/main/java/com/superbiz/agent/harness/agent/DiagnosisAgentFactory.java`
- `src/main/java/com/superbiz/agent/harness/release/EvidenceRepair.java`
- `src/main/java/com/superbiz/agent/harness/release/SafeFallbackFactory.java`
- `src/main/java/com/superbiz/agent/harness/audit/HarnessAgentAuditHook.java`
- `src/main/java/com/superbiz/agent/service/DiagnosisTraceService.java`
- `src/main/resources/db/migration/V015__create_agent_reasoning_audit.sql`
@@ -1,133 +0,0 @@
# Executor 证据归因幻觉
**状态**:待规划
**严重程度**:高
**发现时间**:2026-07-07
**来源**:Trace Workbench 复核 / 最近 Chat 诊断会话低置信分析
**关联**:ISS-005(证据链补齐与降级契约收敛)、ISS-006(固定诊断评测集与回归 Harness)、`chat-verifier-agent`、`diagnosis-playbook-skills`
---
## 背景
最近连续多条 Chat 诊断会话都被 Verifier 判定为 `LOW_CONFID`。这些会话并不是没有调用工具;相反,它们大多完成了 `lookup_knowledge`、`query_metrics`、`query_logs` 等证据工具调用。
问题出在 Executor 的最终答案:它拿到部分真实工具返回后,将以下三类内容混在一起输出为“本次事故结论”:
1. 本次工具直接返回的事实。
2. runbook、知识库或历史案例里的通用模式。
3. 模型基于经验补全的推断。
Verifier 随后逐条核查 `executor_final_answer`,发现大量关键事实没有对应工具证据,于是按规则输出 `LOW_CONFID`。
---
## 现象
最近 5 条 Chat 诊断会话均为低置信:
| session | verdict | groundedness_score | direct_evidence | indirect_support | no_evidence |
|---|---:|---:|---:|---:|---:|
| `e2e-mysql-skill-rag-20260706-2355` | LOW_CONFID | 0.50 | 2 | 14 | 5 |
| `e2e-mysql-skill-rag-20260706-2312` | LOW_CONFID | 0.37 | 4 | 11 | 14 |
| `e2e-mysql-skill-rag-20260706-2255` | LOW_CONFID | 0.10 | 1 | 2 | 18 |
| `e2e-mysql-skill-rag-20260706-2242` | LOW_CONFID | 0.53 | 3 | 9 | 4 |
| `e2e-mysql-skill-rag-20260706-2230` | LOW_CONFID | 0.20 | 1 | 2 | 11 |
典型无证据断言:
- `order-service 出现 OutOfMemoryError: Java heap space`
- `OrderService.processLargeOrder() 内存泄漏导致 JVM OOM`
- `频繁 Full GC(10 分钟 15 次,平均 850ms)`
- `users + user_profiles 慢查询 2.8s,全表扫描`
- `UPDATE orders 锁等待 2.1s`
- `user-service DB 查询超时 5.2s~5.8s`
这些事实要么没有出现在工具返回中,要么属于其它服务或历史案例,不能作为当前会话的直接事实。
---
## 根因判断
这是一个经典的 Agent 幻觉问题,但更准确地说是:
**Executor 的证据归因幻觉。**
Executor 已经调用了工具,但在综合答案阶段没有严格区分:
- `direct evidence`:工具本次实际返回的事实
- `reference / runbook`:流程指导、历史模式、建议方向
- `hypothesis`:基于已知证据的推测
- `missing evidence`:还没有被工具证实的内容
因此它会把“可能相关的历史模式”写成“当前事故事实”,并把“建议排查方向”写成“已确认根因”。
---
## 影响
- Verifier 正确拦截后,最近 Chat 会话长期停留在 `LOW_CONFID`。
- 用户侧结果虽然带免责声明,但仍难以直观看出哪些内容是真实证据、哪些只是推测。
- 评测里 verdict 分布会被 Executor 输出质量拖低,掩盖工具链本身是否已经足够。
- 面试讲解时容易被追问:既然工具都调用了,为什么答案仍然不可信?
---
## 本 issue 目标
收紧 Executor 的最终输出契约,避免把未证实内容写成确认结论。
完成后应做到:
1. Executor 最终答案明确分区:
- `已证实事实`
- `合理推测`
- `证据缺口`
- `建议动作`
2. `已证实事实` 只能来自本轮 evidence tools 的返回。
3. runbook / skill / 知识库中的流程和历史案例不得直接作为本次事故事实。
4. 其它服务的证据不得迁移为当前服务事实。
5. 根因结论必须绑定至少一条直接或间接证据;否则只能放入 `合理推测` 或 `证据缺口`。
6. Verifier 的 `LOW_CONFID` 缺口应能直接映射回 Executor 的分区错误。
---
## 范围
### In scope
- 修改 `chat-executor-prompt.md`,加入证据分区和证据归因规则。
- 必要时在 `ChatService.buildChatExecutorAgent(...)` 中注入更明确的最终答案格式约束。
- 增加 focused tests,覆盖 Executor prompt 中的证据边界规则。
- 增加或更新诊断 eval fixture,验证 unsupported claims 不会出现在确认结论中。
- Trace Workbench 可继续消费 Verifier 缺口展示低置信原因。
### Out of scope
- 不放宽 Verifier 的 PASS 判定矩阵。
- 不通过调高 `verifier.low-confidence-threshold` 掩盖问题。
- 不把 runbook 或 skill 内容写入 `tool_invocation` 伪装成事实证据。
- 不新增数据库 schema。
---
## 验收标准
- 对 MySQL 连接池耗尽类 case,Executor 输出中:
- 已证实事实只包含工具返回的服务、指标、日志、慢 SQL 等事实。
- OOM、Full GC、连接泄漏等未证实内容只能出现在推测或证据缺口中。
- 不再把 `order-service` / `user-service` 事实混入 `payment-service` 当前事故。
- Verifier 对同类会话的 `no_evidence` 数量明显下降。
- 若证据不足,最终用户输出明确说明“当前无法确认根因”,而不是补全一个完整事故故事。
- 评测报告能捕捉 unsupported confirmed claims 的回归。
---
## 相关文件
- `src/main/resources/prompts/chat-executor-prompt.md`
- `src/main/resources/prompts/chat-verifier-prompt.md`
- `src/main/java/com/superbiz/agent/service/ChatService.java`
- `src/main/java/com/superbiz/agent/service/ToolTraceSummaryService.java`
- `src/test/java/com/superbiz/agent/service/ChatServiceSequentialAgentTest.java`
- `mvp/eval/`
-377
View File
@@ -1,377 +0,0 @@
# RAG 检索重构计划
**状态**:待规划
**严重程度**:高
**发现时间**:2026-07-05
**范围**:RAG、检索、知识库、Agent Tool、AIOps 诊断证据链
---
## 目标
将当前自研 RAG MVP 重构为“成熟框架能力 + 业务可观测编排”的架构:
```text
Agent
-> lookup_knowledge Tool
-> L0 domain/entity hint
-> query augmentation / transformer
-> Spring AI Retriever / VectorStore
-> metadata filter
-> document postprocess
-> neighbor / section expansion
-> evidence packing
-> tool_invocation record
```
核心原则:
1. 通用 RAG 基础设施尽量交给 Spring AI / Spring AI Alibaba。
2. Agent 工具入口、AIOps 业务语义、证据追踪继续保留在项目内。
3. 不把系统改成隐式 Chat RAG,仍然保留显式 `lookup_knowledge` 工具调用。
4. 分阶段迁移,避免一次性推倒当前可运行链路。
---
## 当前问题汇总
当前 RAG 已经打通上传、切片、向量化、L0/L1 召回和工具调用记录,但主要问题集中在:
1. **检索基础设施偏自研**
- Milvus 写入和查询直接使用 SDK。
- topK、threshold、metadata filter、结果结构由业务代码维护。
- 后续接入 Spring AI RAG 能力会有重复适配成本。
2. **L0 职责过重**
- 当前 L0 可能被当成最终召回决策。
- 关键词质量不稳定时容易误召回。
- 更适合作为 domain/entity hint,而不是最终答案来源。
3. **query 构造不稳定**
- 主要依赖 Agent 传入原始 query。
- AIOps payload 中的 alertName、service、metric、symptom 没有稳定进入检索 query。
4. **上下文重建不足**
- 同章节被切成多个 chunk 后,命中片段不会自动扩展前后文。
- `breadcrumb` 存在 metadata 中,但没有充分参与 embedding、filter 或 context packing。
5. **缺少检索后处理**
- 缺少统一 evidence block。
- 缺少去重、token budget、hitReason、source 结构化输出。
6. **缺少量化评测**
- 目前主要靠接口回放、日志和 `tool_invocation` 人工判断。
- 还没有 golden query set、Recall@K、MRR、NDCG 等检索评测。
---
## 保留设计
这些设计值得保留,并作为重构后的项目亮点:
### 1. `lookup_knowledge` 显式 Agent Tool
保留显式工具调用,不直接用隐式 Advisor 取代。
原因:
- 面试项目重点是 Agent 工程,不是普通 Chat RAG。
- 显式工具调用能展示 Agent 何时检索、检索了什么、证据如何支撑诊断。
- `tool_invocation`、evidence score、diagnosis session 都依赖这条链路。
### 2. L0
保留 L0,但降级为:
- domain detector
- entity extractor
- metadata filter generator
- explainability signal
不再默认执行:
```text
L0 unique hit -> 直接返回
```
目标职责:
```text
query / payload
-> L0 matched keywords/entities/domain
-> metadata filter + query augmentation
-> retriever
```
### 3. metadata
保留并加强 metadata:
```text
docId
chunkIndex
totalChunks
title
breadcrumb
category
source
```
后续可扩展:
```text
sectionId
parentSection
documentType
domain
tags
version
```
metadata 是 filter、上下文扩展、证据追踪、可解释性的基础。
### 4. Markdown-aware chunking
保留当前 Markdown 结构化切片思路:
- 识别标题层级
- 生成 `title`
- 生成 `breadcrumb`
- 保留 `chunkIndex`
- 尽量不打断列表和代码块
可以替换或复用框架能力的是底层 token 长度控制和 overlap 策略,而不是完全抛弃结构化切片。
### 5. `tool_invocation` 证据追踪
保留并增强:
```text
sessionId
query
rewrittenQuery
matchedKeywords
domain/entities
retrievedDocs
scores
hitReasons
evidence
duration
relevanceLevel
```
这是后续检索评测、诊断质量评估、面试讲解的基础。
### 6. AIOps payload 到 query 的业务映射
保留 AIOps 场景逻辑:
- alertName
- service
- metric
- symptom
- category/domain
这些是业务语义,不能完全交给通用框架隐式处理。
---
## 替换设计
这些能力适合逐步交给 Spring AI / Spring AI Alibaba:
| 当前能力 | 目标能力 | 说明 |
|---|---|---|
| Milvus SDK 直接写入/查询 | Spring AI `VectorStore` | 减少基础设施代码 |
| 自研 `VectorSearchService` 检索细节 | `VectorStoreDocumentRetriever` | 标准化 topK、threshold、filter |
| 手写 query 拼接 | Query Transformer / 模板化 query augmentation | 先规则化,后框架化 |
| 手写结果拼接 | DocumentPostProcessor / evidence postprocess | 做去重、压缩、证据块 |
| L0 最终召回判断 | L0 domain/entity hint | 降低误召回风险 |
---
## 分阶段计划
### Phase 0:重构前基线
目标:先固定当前行为,避免重构后不知道是否变好。
任务:
- 固化 10-20 条 golden queries。
- 覆盖 Chat 和 AIOps 场景。
- 每条 query 标注 expected doc、breadcrumb、关键 chunk 或 evidence。
- 用当前链路跑一遍,记录 baseline。
- 初始离线基线落在 `eval/rag-retrieval/`,用于后续 change 对比。
验收:
- 有可重复运行的检索回放清单。
- 能记录当前 Recall@K、first hit rank 或人工 hit level。
### Phase 1:L0 降级为 domain/entity hint
目标:保留 L0 价值,降低 L0 误决策风险。
任务:
- `KnowledgeIndexService` 输出 matched keywords、domain、entities。
- `LookupKnowledgeTool` 不再把 L0 unique hit 作为默认最终结果。
- 将 L0 结果用于 query augmentation 和 metadata filter。
- `tool_invocation` 记录 L0 hit reason。
验收:
- L0 命中不会绕过向量检索直接返回。
- 检索记录能看到 domain/entities/matchedKeywords。
- AIOps payload 能生成稳定领域 hint。
### Phase 2:Evidence Postprocess 和上下文打包
目标:先提升 Agent 实际拿到的证据质量。
任务:
- 定义 evidence block:
```text
source
docId
chunkIndex
title
breadcrumb
score
hitReason
content
expandedFrom
```
- 对检索结果做去重。
- 支持命中 chunk 的相邻 chunk / 同章节扩展。
- 加 token 或字符预算控制。
- 返回给 Agent 的内容按 evidence block 组织。
验收:
- 同一 docId/chunkIndex 不重复进入上下文。
- 命中 chunk 可以补充前后文。
- `tool_invocation` 记录 postprocess 前后候选数量和最终 evidence 数量。
### Phase 3:Spring AI VectorStore 旁路验证
目标:验证框架能力,不直接替换主链路。
任务:
- 引入 Spring AI Milvus VectorStore。
- 建立旁路 `SpringAiVectorSearchService` 或适配层。
- 同一批 golden queries 同时跑旧链路和新链路。
- 对比 topK、metadata、score、filter 行为。
验收:
- 旁路检索可跑通。
- metadata 不丢失。
- 查询结果与当前链路差异可解释。
- 不影响现有 Chat / AIOps 主链路。
### Phase 4:替换底层 VectorSearchService
目标:对外接口不变,内部检索切到 Spring AI VectorStore / Retriever。
任务:
- 保持 `LookupKnowledgeTool` 调用方式不变。
- `VectorSearchService` 内部迁移到 Spring AI 检索抽象。
- 支持 topK、similarity threshold、category metadata filter。
- 保留旧实现一段时间作为 fallback。
验收:
- Chat / AIOps 检索链路行为兼容。
- golden queries 不低于 baseline。
- 检索结果仍能完整记录到 `tool_invocation`。
### Phase 5:Query Transformer 和框架化 PostProcessor
目标:在稳定的 VectorStore 基础上接入更成熟 RAG 能力。
任务:
- AIOps 场景优先使用模板化 query augmentation。
- 需要时接入 Spring AI Query Transformer / MultiQuery。
- 将现有 evidence postprocess 抽象成 DocumentPostProcessor 风格。
- 可选接入 rerank,但不作为第一优先级。
验收:
- 原始 query 和 rewritten query 都可追踪。
- query rewrite 失败可以 fallback。
- postprocess 行为可配置、可记录、可回放。
---
## 暂不做
以下能力暂不进入近期重构:
1. 不做完整自研 RRF 框架。
2. 不直接把 `lookup_knowledge` 替换成隐式 Advisor。
3. 不一口气迁移所有 RAG ETL。
4. 不先引入 Elasticsearch / OpenSearch,除非评测证明 BM25 必须。
5. 不先上 cross-encoder / LLM rerank,先做规则型 evidence postprocess。
---
## 风险
### 1. Milvus schema 兼容风险
当前 collection 是项目自建,Spring AI VectorStore 可能有自己的 schema 假设。需要旁路验证。
### 2. 检索行为变化风险
框架检索分数和当前 L2 score 可能不完全一致,需要 golden queries 对比。
### 3. 可观测性丢失风险
如果迁移到隐式 Advisor,可能丢失工具调用证据链。因此 Spring AI RAG 能力应优先封装在 `lookup_knowledge` 内部。
### 4. 重构范围膨胀风险
RAG、Agent、AIOps、数据库记录互相关联,必须分阶段推进,每阶段都保持可运行。
---
## 合并来源
本计划合并以下问题和改造方向:
- [rag-chunk-context-reconstruction.md](../rag/rag-chunk-context-reconstruction.md)
- [rag-breadcrumb-embedding-gap.md](../rag/rag-breadcrumb-embedding-gap.md)
- [rag-l0-l1-fusion-ranking.md](../rag/rag-l0-l1-fusion-ranking.md)
- [rag-l0-keyword-matching-quality.md](../rag/rag-l0-keyword-matching-quality.md)
- [rag-l1-score-calibration.md](../rag/rag-l1-score-calibration.md)
- [rag-context-packing-and-reranking.md](../rag/rag-context-packing-and-reranking.md)
- [rag-upload-chunk-parameter-drift.md](../rag/rag-upload-chunk-parameter-drift.md)
- [rag-query-rewrite-gap.md](../rag/rag-query-rewrite-gap.md)
- [rag-spring-ai-vectorstore-migration.md](../rag/rag-spring-ai-vectorstore-migration.md)
- [rag-spring-ai-query-transformer.md](../rag/rag-spring-ai-query-transformer.md)
- [rag-spring-ai-document-postprocessor.md](../rag/rag-spring-ai-document-postprocessor.md)
- [rag-l0-domain-entity-hint.md](../rag/rag-l0-domain-entity-hint.md)
- [rag-spring-ai-advisor-boundary.md](../rag/rag-spring-ai-advisor-boundary.md)
---
## 相关文件
- `src/main/java/com/superbiz/agent/tool/LookupKnowledgeTool.java`
- `src/main/java/com/superbiz/agent/service/KnowledgeIndexService.java`
- `src/main/java/com/superbiz/agent/service/VectorSearchService.java`
- `src/main/java/com/superbiz/agent/service/VectorIndexService.java`
- `src/main/java/com/superbiz/agent/service/DocumentChunkService.java`
- `src/main/java/com/superbiz/agent/service/DocumentManagementService.java`
- `src/main/java/com/superbiz/agent/service/AiOpsService.java`
- `src/main/java/com/superbiz/agent/service/ToolInvocationRecorder.java`
- `src/main/resources/application.yml`
- `pom.xml`