Files
SuperBizAgent-java/handoff/2026-06-24-lookup-knowledge-integration.md
T
zhuyongxin d6229f3385 feat(knowledge): 完成 L0+L1 混合检索集成
核心功能:
- 新增 FrontmatterParser 解析 YAML frontmatter
- 新增 KnowledgeIndexService L0 内存索引
- 新增 LookupKnowledgeTool 混合检索工具
- 增强 DocumentManagementService 文件保存和索引同步

技术实现:
- 数据库迁移 V004: api_document.metadata (TEXT)
- 依赖新增: snakeyaml 2.0
- 配置新增: knowledge.base-path
- 可观测性: requestId 追踪 + 性能日志

质量保证:
- 单元测试: 31/31 通过
- 测试覆盖: FrontmatterParser(11), KnowledgeIndexService(13), LookupKnowledgeTool(7)
- 启动验证: L0 索引正常加载

归档文档:
- OpenSpec: openspec/changes/lookup-knowledge-integration/
- devflow 档案: devflow/projects/2026-06-24-lookup-knowledge-integration/
- handoff: handoff/2026-06-24-lookup-knowledge-integration.md
2026-06-24 16:07:10 +08:00

7.6 KiB
Raw Blame History

Lookup Knowledge Integration - Handoff Document

变更概述

变更名称: L0+L1 混合检索集成
完成日期: 2026-06-24
OpenSpec 路径: openspec/changes/lookup-knowledge-integration/

一句话总结

为 Agent 提供混合检索工具(lookup_knowledge),优先使用 L0 精确匹配,必要时补充 L1 语义检索,支持 Markdown frontmatter 元数据管理。


核心变更

1. 新增服务

FrontmatterParser (com.superbiz.agent.service.FrontmatterParser)

  • 解析 Markdown 文件头的 YAML frontmatter
  • 必填字段:title, keywords, summary
  • 可选字段:category, version, author

KnowledgeIndexService (com.superbiz.agent.service.KnowledgeIndexService)

  • L0 内存索引,启动时扫描 knowledge_base/ 目录
  • 精确关键词匹配(不区分大小写)
  • 线程安全(CopyOnWriteArrayList)

2. 增强服务

DocumentManagementService

  • 上传时保存原始文件到 knowledge_base/{category}/{filename}
  • 解析 frontmatter 并存储到 api_document.metadata (JSON)
  • 上传成功后更新 L0 索引
  • 删除时同步清理本地文件和 L0 索引

3. 新增工具

LookupKnowledgeTool (com.superbiz.agent.tool.LookupKnowledgeTool)

  • Agent 可调用工具:lookup_knowledge(query)
  • L0 唯一匹配 → 高置信度 → 不调用 L1
  • L0 多匹配/未匹配 → 低置信度 → 调用 L1
  • 返回:primary (L0) + supplement (L1)

4. 数据库变更

Flyway V004: api_document 表新增 metadata 列

ALTER TABLE api_document 
ADD COLUMN metadata TEXT COMMENT 'Frontmatter 元数据 (JSON)';

5. 配置变更

application.yml

knowledge:
  base-path: knowledge_base/

pom.xml

<dependency>
    <groupId>org.yaml</groupId>
    <artifactId>snakeyaml</artifactId>
    <version>2.0</version>
</dependency>

使用方式

Agent 调用示例

场景 1: 唯一匹配(高置信度)

Agent: lookup_knowledge("ERR_TIMEOUT")

返回:
{
  "found": true,
  "primary": {
    "content": "# 支付网关错误码\n\n## ERR_TIMEOUT\n...",
    "source": "knowledge_base/api/payment-errors.md",
    "matchType": "exact_L0",
    "confidence": "high"
  },
  "supplement": null
}

场景 2: 多个匹配(低置信度 + L1 补充)

Agent: lookup_knowledge("超时")

返回:
{
  "found": true,
  "primary": {
    "content": "...",
    "confidence": "low"
  },
  "supplement": {
    "content": "语义相关的内容片段...",
    "matchType": "semantic_L1"
  }
}

文档上传示例

带 frontmatter 的 Markdown:

---
title: 支付网关错误码定义
keywords: [ERR_TIMEOUT, 超时, 支付网关]
summary: 记录了支付网关所有核心错误码的含义及排查方向
category: api
---

# 正文内容

上传后:

  • 文件保存: knowledge_base/api/payment-errors.md
  • L0 索引: keywords 用于精确匹配
  • L1 索引: 正文内容向量化

可观测性

日志追踪

查询流程(带 requestId):

[a1b2c3d4] 收到知识库查询请求: query=ERR_TIMEOUT
[a1b2c3d4] L0精确匹配完成: matches=1, time=2ms
[a1b2c3d4] 置信度判断: highConfidence=true, reason=唯一匹配
[a1b2c3d4] L0唯一匹配,跳过L1检索
[a1b2c3d4] 查询完成: found=true, confidence=high, totalTime=5ms

文档上传:

开始上传文档: fileName=payment-errors.md, size=1024 bytes
解析到frontmatter: title=支付网关错误码, keywords=[ERR_TIMEOUT], time=5ms
文档分块完成: chunks=3, time=12ms
文档向量索引完成: docId=abc123, time=850ms
文档已加入L0索引: docId=abc123, title=支付网关错误码
文档上传完成: totalTime=920ms

关键指标

  • L0 查询耗时: < 10ms
  • L0+L1 总耗时: < 500ms
  • 文档上传耗时: < 2s(含向量化)

详细文档

参考:.docs/knowledge-observability.md


测试覆盖

单元测试(31/31 通过)✅

  • FrontmatterParserTest: 11 个用例

    • 有效/无效/格式错误 frontmatter
    • 边界情况(空文件、缺少必填字段)
  • KnowledgeIndexServiceTest: 13 个用例

    • 精确匹配(单个/多个/零个)
    • 不区分大小写
    • 文档读取(成功/失败/超长截断)
  • LookupKnowledgeToolTest: 7 个用例

    • 唯一匹配(高置信度,不调用 L1)
    • 多个匹配(低置信度,调用 L1)
    • 未匹配(仅返回 L1)

启动验证 ✅

  • Flyway V004 迁移成功执行
  • KnowledgeIndexService 正常扫描并加载索引
  • 测试文档成功解析并加入 L0 索引

运维指南

启动流程

  1. 扫描知识库目录

    开始扫描知识库目录: knowledge_base/
    知识库索引加载完成,共 5 个文档
    
  2. 验证索引

    • 检查日志中文档数量是否符合预期
    • 如有 WARN 日志,检查 frontmatter 格式

故障排查

问题 1: L0 索引为空

  • 原因: knowledge_base/ 目录不存在或无 .md 文件
  • 解决: 检查目录权限,确保至少有一个带 frontmatter 的 .md 文件

问题 2: 查询总是调用 L1

  • 原因: L0 未匹配或多个匹配
  • 解决: 检查查询关键词是否在文档的 keywords 列表中

问题 3: 文档上传后未进入 L0 索引

  • 原因: frontmatter 格式错误或缺少必填字段
  • 解决: 检查 WARN 日志,修正 frontmatter 格式

日志分析

查看单次查询完整流程:

grep "[requestId]" logs/application.log

统计 L0 命中率:

grep "L0精确匹配完成" logs/application.log | \
  awk -F'matches=' '{print $2}' | \
  awk -F',' '{print $1}' | \
  sort | uniq -c

查看慢查询:

grep "totalTime=" logs/application.log | \
  awk -F'totalTime=' '{print $2}' | \
  awk -F'ms' '{if ($1 > 1000) print}'

限制与注意事项

当前限制

  1. L0 索引持久化

    • 索引存储在内存中
    • 应用重启需要重新扫描
    • 解决方案:启动时自动扫描,通常 < 1s
  2. 章节锚点(MVP 未实现)

    • sectionTitle 参数预留
    • availableSections 字段返回 null
    • 后续 Phase 2 实现
  3. 批量导入

    • 当前仅支持单文件上传
    • 大量文档需要循环调用 API

最佳实践

  1. 编写高质量 frontmatter

    • keywords 精准且全面
    • summary 简洁明了
    • 避免关键词重复(导致多匹配)
  2. 知识库目录组织

    knowledge_base/
    ├── api/          # API 相关
    ├── domain/       # 领域知识
    └── troubleshoot/ # 故障排查
    
  3. 监控告警

    • 慢查询: totalTime > 2s
    • 失败率: > 10%
    • L0 索引加载失败

后续增强方向

Phase 2 候选特性

  1. 章节锚点

    • 支持 sectionTitle 参数
    • 直接定位到文档特定章节
    • 减少返回内容长度
  2. L0 索引持久化

    • 序列化到文件
    • 避免重启扫描
  3. 批量导入工具

    • 支持目录批量导入
    • 进度监控
  4. 知识库管理 API

    • CRUD 接口
    • 在线编辑
  5. 向量化元数据

    • title/summary 也参与 L1 检索
    • 提升语义检索准确度

相关文档

  • OpenSpec: openspec/changes/lookup-knowledge-integration/

    • proposal.md
    • design.md
    • specs/functional-specs.md
    • tasks.md
    • decisions.md
  • 可观测性: .docs/knowledge-observability.md

  • 测试: src/test/java/com/superbiz/agent/

    • service/FrontmatterParserTest.java
    • service/KnowledgeIndexServiceTest.java
    • tool/LookupKnowledgeToolTest.java

联系人

开发者: Claude Code
完成时间: 2026-06-24
审核状态: ✅ 已归档

如有问题,请参考 OpenSpec 文档或联系团队。