feat(knowledge): 会话级去重 + 知识域地图注入 Planner 解决 ISS-001 重复检索

- RetrievedDocTracker: sessionId → Set<filePath> 会话级去重,LookupKnowledgeTool Step 5 过滤已检索文档
- KnowledgeDomainService: 域级聚合,LLM 生成 when_to_retrieve,构建 knowledge map YAML
- DocumentFieldEnricher: 上传时 LLM 补全 covers + whenToRetrieve(含同域文档排除上下文)
- KnowledgeDomain entity + V009 迁移: 域级元数据持久化,避免重启重复 LLM 调用
- ChatService: 注入 knowledge map 到 Planner prompt,会话结束时清理去重状态
- KnowledgeIndexService: 手写 JSON 解析替换为 Jackson ObjectMapper,启动时补建缺失域记录
- chat-planner-prompt: 新增知识库检索规则(按域 when_to_retrieve 判断,每域最多一次检索)
- doc-field-enricher-prompt / domain-summary-prompt: 外部化 LLM 提示词
This commit is contained in:
zhuyongxin
2026-07-01 10:47:46 +08:00
parent 2a796da490
commit bb44140901
17 changed files with 642 additions and 106 deletions
@@ -18,3 +18,9 @@
- 每个步骤应该是一个可以独立执行的任务
- 步骤要具体可操作,不要模糊
- 如果问题需要查知识库,明确在步骤中说明要查什么
## 知识库检索规则
- 制定步骤前,先查看下方 `available_knowledge_domains`(如果存在)
- 根据每个域的 `when_to_retrieve` 判断是否需要检索该域
- 每个域最多安排一次检索步骤;已覆盖的域不要重复安排
- 如果用户问题与某个域无关,不要安排对该域的检索
@@ -0,0 +1,31 @@
你是知识库文档标注助手。为文档生成两个检索辅助字段。
## 生成规则
1. covers:该文档覆盖的业务场景(3-5 个简洁中文短语)
2. whenToRetrieve:用一句话描述何时检索此文档,不超过 40 字
- 必须包含正向场景(什么问题查本文档)
- 必须包含反向排除(什么问题容易误判但不应查本文档)
- 格式:"正向场景;不包含反向排除词"
## Few-shot 示例
文档标题:支付失败排查手册
同域其他文档:退款处理指南
→ {"covers": ["支付超时", "扣款无回调", "支付网关报错"], "whenToRetrieve": "支付失败/超时/无回调时检索;不含退款对账问题"}
文档标题:退款处理指南
同域其他文档:支付失败排查手册
→ {"covers": ["退款未到账", "退款状态异常", "退款被拒"], "whenToRetrieve": "退款异常/未到账时检索;不含支付失败问题"}
文档标题:MySQL 连接池配置
同域其他文档:Redis 缓存配置指南、Flyway 数据库迁移
→ {"covers": ["连接池耗尽", "数据库OOM", "慢查询"], "whenToRetrieve": "连接池/数据库性能问题时检索;不含Redis缓存或迁移问题"}
## 待分析文档
文档标题:%s
文档摘要:%s
同域其他文档:%s
文档内容节选:
%s
请严格返回 JSON 格式,不要有其他内容:
{"covers": ["场景1", "场景2", ...], "whenToRetrieve": "描述"}
@@ -0,0 +1,21 @@
你是知识库域级路由设计助手。根据域内文档和系统其他域信息,生成一条域级检索指引。
## 当前域:%s
## 域内文档
%s
## 系统其他域(用于判断边界)
%s
## 生成要求
1. 用一句话描述"什么场景下 Planner 应该选择检索这个域"
2. 必须覆盖该域所有文档的适用场景,做合理抽象(不要简单拼接)
3. 必须包含明确的边界判断:
- 正向:什么问题属于这个域
- 反向:什么问题容易被误判为属于这个域,但实际应该检索其他域
4. 反向边界必须引用其他域的 domain_id,格式:"X类问题查{domain_id}"
5. 不超过 60 字
6. 语言要让 Planner 能做"检索/不检索"的二分判断
只返回纯文本指引,不要 JSON 或 markdown。