diff --git a/mvp/issues/ISS-003-executor-domain-hard-limit.md b/mvp/issues/ISS-003-executor-domain-hard-limit.md deleted file mode 100644 index 5db11b6..0000000 --- a/mvp/issues/ISS-003-executor-domain-hard-limit.md +++ /dev/null @@ -1,146 +0,0 @@ -# ISS-003 Executor 域级检索水位控制(Phase 2) - -**状态**:待规划 -**严重程度**:低(当前软约束已从 20+ 次收敛到 10 次,文档级去重兜住无效调用) -**发现时间**:2026-07-01 -**关联**:ISS-002(Part A 软约束已修,LLM 遵守度不够) - ---- - -## 现象 - -ISS-002 修复后,lookup_knowledge 调用从 20+ 次降到 10 次,但仍有 8 次冗余调用: - -``` -id=138 → infrastructure 首次检索 HIGHLY_RELEVANT -id=139 → infrastructure 变体 → doc_retrieved -id=140 → infrastructure 变体 → doc_retrieved -id=141 → api 首次检索 REFERENCE -id=142 → api 变体 → doc_retrieved -id=143 → infrastructure 变体 → doc_retrieved(又跳回) -id=144-146 → infrastructure 变体 × 3 → doc_retrieved -id=147 → api 变体 → doc_retrieved -``` - -LLM 在两个域之间反复横跳,prompt 第 2 条"禁止换关键词重新检索"被忽略。 - ---- - -## 根本原因 - -Prompt 软约束依赖 LLM 遵守,但 LLM 在自主决策(ReactAgent)模式下倾向于"多确认一步"而不是"相信已有信息"。 - ---- - -## 影响 - -- **可接受**:文档级去重已拦截重复内容,不影响回答质量 -- **可优化**:每次冗余调用浪费 400-500ms 服务端检索时间 -- **长会话风险**:如果 session 持续追问,冗余调用会线性增长 - ---- - -## 方案:质量等级×水位决策矩阵 - -### 核心思路 - -将检索决策权从 LLM 思维链移交到代码层,动态判断是否允许下一次 `lookup_knowledge`。 - -### 决策矩阵 - -``` - 水位 - 低 中 高 - PRECISE 可用 可用 可用/停 - HIGHLY_ 可用 可用 停 - REFERENCE 可定向补 可定向补 停 - DEDUPED 停 停 停 -``` - -### 水位指标 - -| 水位 | 指标 | 说明 | -|------|------|------| -| 低 | lookup_knowledge 调用 ≤ 3 次 | 检索预算充足 | -| 中 | lookup_knowledge 调用 4-8 次 | 适当收紧定向补充 | -| 高 | lookup_knowledge 调用 ≥ 8 次 | 熔断,禁止再查 | - -备选水位指标: -- Token 消耗量 -- 已检索域数(retrievedDomainsThisSession.size()) - -### 熔断 prompt 示例 - -每次工具返回后,代码根据矩阵结果动态拼装约束注入下一步 LLM: - -| 场景 | 熔断 prompt | -|------|------------| -| 水位高 + HIGHLY_RELEVANT | "水位已高,请直接给出最终结论,不要再调用 lookup_knowledge" | -| 水位高 + REFERENCE | "水位已高,lookup_knowledge 已被限制,直接基于已有信息回答" | -| 水位低 + REFERENCE | "水位充足,可针对缺少的维度定向补充检索一次" | -| DEDUPED + 任何水位 | "该内容已检索过,禁止重复调用 lookup_knowledge" | - -### 架构改动 - -``` -ChatService / ChatExecutorAgent 执行循环 - │ - ├─ step N: LLM 调用工具 → lookup_knowledge 返回 - ├─ step N+1: - │ ├─ 读取 LookupResult(relevanceLevel + retrievedDomainsThisSession) - │ ├─ 算当前水位(调用计数 / token / 域数) - │ ├─ 查决策矩阵 → 是否允许继续检索 - │ └─ 拼装熔断 prompt → 注入 LLM 下一步 SystemMessage - ├─ step N+2: LLM 收到约束后的回复 - └─ ... -``` - -### 与现有机制的关系 - -| 机制 | 层 | ISS-002 | ISS-003 | -|------|-----|---------|---------| -| 静态 Prompt 约束 | Prompt | 已实现 | 保留作为基线 | -| 行动记忆(retrievedDomainsThisSession) | 工具返回值 | 已实现 | 复用 | -| 归一化质量等级(relevanceLevel) | 工具返回值 | 已实现 | 复用 | -| 文档级去重(doc_retrieved) | 工具层 | 已实现 | 保留 | -| **域级水位决策矩阵** | 代码层 | — | **新增** | -| DEDUPED 等级启用 | 工具返回值 | 设计预留 | 启用 | - ---- - -## 修法方向 - -### 方案 A:决策矩阵(推荐) - -上述质量等级×水位矩阵,在 ChatService 执行循环中做决策。 - -优点: -- 不依赖 LLM 遵守程度 -- 保留定向补充的合法通道(比硬拦截更灵活) -- 水位指标可配置,运维友好 - -缺点: -- 需要改动 ChatService/ExecutorAgent 执行逻辑 -- 需要定义水位阈值(需实测校准) - -### 方案 B:域级工具层硬限流 - -在 `LookupKnowledgeTool` 入口直接判断 `isDomainRetrieved(sessionId, domain)`,同域直接返回不检索。 - -优点:实现简单,100% 可靠 -缺点:没有"定向补充"的灵活度,误杀合法跨域查询 - -### 建议 - -**方案 A**。利用 ISS-002 已有数据结构和归一化等级,新增决策引擎层,改动量不大且灵活度高。 - ---- - -## 相关文件 - -- `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/action-memory-relevance.md` -- OpenSpec:`openspec/changes/archive/2026-07-01-executor-action-memory-relevance/` diff --git a/mvp/issues/ISS-003-mvp-design-implementation-review.md b/mvp/issues/ISS-003-mvp-design-implementation-review.md new file mode 100644 index 0000000..187bc5e --- /dev/null +++ b/mvp/issues/ISS-003-mvp-design-implementation-review.md @@ -0,0 +1,170 @@ +# 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/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` diff --git a/mvp/issues/ISS-004-executor-domain-hard-limit.md b/mvp/issues/ISS-004-executor-domain-hard-limit.md new file mode 100644 index 0000000..1dc9e90 --- /dev/null +++ b/mvp/issues/ISS-004-executor-domain-hard-limit.md @@ -0,0 +1,59 @@ +# 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/action-memory-relevance.md` diff --git a/mvp/issues/README.md b/mvp/issues/README.md index 868cfde..a98a0b0 100644 --- a/mvp/issues/README.md +++ b/mvp/issues/README.md @@ -4,4 +4,5 @@ |---|---|---|---|---| | ISS-001 | Executor 重复召回同一文档 | 中 | 已修复 | [ISS-001-duplicate-retrieval.md](ISS-001-duplicate-retrieval.md) | | ISS-002 | Executor 无约束重复调用 lookup_knowledge | 中 | 已修复 | [ISS-002-executor-unconstrained-lookup.md](ISS-002-executor-unconstrained-lookup.md) | -| ISS-003 | Executor 域级检索水位控制(Phase 2) | 低 | 待规划 | [ISS-003-executor-domain-hard-limit.md](ISS-003-executor-domain-hard-limit.md) | +| ISS-003 | MVP 设计与实现 Review 收敛 | 高 | 待规划 | [ISS-003-mvp-design-implementation-review.md](ISS-003-mvp-design-implementation-review.md) | +| ISS-004 | Executor 域级检索水位控制(Phase 2) | 低 | 待规划 | [ISS-004-executor-domain-hard-limit.md](ISS-004-executor-domain-hard-limit.md) |