Files
SuperBizAgent-java/mvp/architecture/archive/2026-07-05-legacy/session-dedup-knowledge-map.md

6.6 KiB
Raw Permalink Blame History

会话级去重与知识域地图

文档级去重 + 知识域地图注入 Planner,解决 ISS-001 Executor 重复召回同一文档问题。


一、整体架构

本 change 包含两个独立但互补的部分:

Part A: 工具层去重
  LookupKnowledgeTool
    ├── 维护 ConcurrentHashMap<sessionId, Set<filePath>>(JVM 内)
    ├── 每次检索前过滤已召回文档
    └── SessionContextHolder.clear() 时同步清理

Part B: 知识域地图
  ┌─────────────────────────────────────────────┐
  │ 文档上传 (DocumentManagementService)         │
  │   → LLM 生成 doc.covers + doc.when_to_retrieve │
  │   → 存入 api_document.metadata             │
  │   → 触发域级重算 (KnowledgeDomainService)   │
  └─────────────────────────────────────────────┘
         ↓
  ┌─────────────────────────────────────────────┐
  │ 域级聚合 (KnowledgeDomainService)            │
  │   → 读取同域所有文档的 when_to_retrieve      │
  │   → LLM 生成 domain.when_to_retrieve        │
  │   → 存入 knowledge_domain 表                │
  └─────────────────────────────────────────────┘
         ↓
  ┌─────────────────────────────────────────────┐
  │ 启动 (KnowledgeIndexService.loadIndex)       │
  │   → 加载 knowledge_domain 表                │
  │   → 某域无记录则触发域级生成                 │
  └─────────────────────────────────────────────┘
         ↓
  ┌─────────────────────────────────────────────┐
  │ Planner prompt (ChatService)                │
  │   → 注入 knowledge map(域级)               │
  │   → Planner 做粗粒度检索决策                 │
  └─────────────────────────────────────────────┘

二、Part A:工具层去重

RetrievedDocTracker

session 级已召回文档追踪组件,将去重责任从 LLM 移交到工具层。

ConcurrentHashMap<String, Set<String>> retrieved
  key: sessionId
  value: Set<filePath>
方法 作用
isAlreadyRetrieved(sessionId, filePath) 检查文档是否已召回
markRetrieved(sessionId, filePath) 记录已召回文档
clearSession(sessionId) 清理会话记录(SessionContextHolder.clear 触发)

去重流程

lookup_knowledge(query)
  → L0 检索 → 命中一批文档
  → 遍历结果,过滤 isAlreadyRetrieved=true 的文档
  → 剩余文档作为 primary/supplement 返回
  → 实际返回的文档调用 markRetrieved

三、Part B:知识域地图

Frontmatter 新增字段

文档上传时 LLM 自动生成以下两个字段:

covers: ["支付失败排查", "扣款无回调"]        # 业务场景标签
when_to_retrieve: "用户描述支付失败、超时时"   # 文档级检索时机

knowledge_domain 表

CREATE TABLE knowledge_domain (
    id              BIGINT AUTO_INCREMENT PRIMARY KEY,
    domain_id       VARCHAR(64)  NOT NULL UNIQUE,
    description     VARCHAR(256),
    when_to_retrieve TEXT,
    document_count  INT DEFAULT 0,
    updated_at      DATETIME,
    created_at      DATETIME
);

Knowledge Map(注入 Planner 的 YAML)

available_knowledge_domains:
  - domain_id: "payment"
    description: "支付链路问题排查"
    when_to_retrieve: "用户问题涉及支付、退款、对账时检索;优先检索一次,勿重复"
    documents:
      - title: "支付失败排查手册"
        covers: ["支付超时", "扣款无回调"]
      - title: "退款处理指南"
        covers: ["退款未到账", "退款状态异常"]
  - domain_id: "infrastructure"
    ...

注入链路

文档上传/删除
  → KnowledgeDomainService.onDocumentChange(category)
    → 读取同域所有文档的 when_to_retrieve
    → LLM 聚合为 domain.when_to_retrieve
    → 写入 knowledge_domain 表

应用启动
  → KnowledgeIndexService.loadIndex()
    → 加载 knowledge_domain → 无记录则触发聚合
    → ChatService.buildChatPlannerAgent() 注入 prompt

Planner prompt 中包含知识域地图
  → Planner 做粗粒度检索决策("查 payment 域")
  → Executor 收到步骤后执行具体检索

四、关键设计决策

决策 方案 原因
域级 when_to_retrieve 存 DB 持久化 避免每次重启调 LLM,文档变更时只重算受影响域
文档级 when_to_retrieve 存 metadata JSON 沿用现有路径 无需新增数据库字段
RetrievedDocTracker 独立于 SessionContextHolder 职责分离 SessionContextHolder 只持有 sessionId,Tracker 是业务状态
Planner 只看域级 分层决策 文档级 when_to_retrieve 留 Executor 筛选(Phase 2)
LLM 调用同步执行 上传时即时生成 接受约 1-2s 延迟,保证数据库和 L0 索引立即一致

五、Agent 边界

Planner 角色:知道"有什么域"
  └─ 知识域地图:选定要检索的域(一次规划)

Executor 角色:知道"做了什么"
  └─ 行动记忆:域级 + 文档级去重(ISS-002 升级为双层记忆)

Part B(知识域地图)只注入 Planner prompt,不注入 Executor prompt。Executor 只通过 RetrievedDocTracker 知道自己已检索了哪些文档,不需要知道全局域有哪些。


六、数据库变更

V009

CREATE TABLE knowledge_domain (
    id              BIGINT AUTO_INCREMENT PRIMARY KEY,
    domain_id       VARCHAR(64)  NOT NULL UNIQUE,
    description     VARCHAR(256),
    when_to_retrieve TEXT,
    document_count  INT DEFAULT 0,
    updated_at      DATETIME,
    created_at      DATETIME
);

七、参考资料

  • 架构文档:mvp/architecture/knowledge-retrieval-architecture.md
  • 使用指南:mvp/architecture/knowledge-retrieval-usage.md
  • OpenSpec:openspec/changes/archive/2026-06-30-session-dedup-knowledge-map/