核心功能: - 新增 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
7.6 KiB
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 索引
运维指南
启动流程
-
扫描知识库目录
开始扫描知识库目录: knowledge_base/ 知识库索引加载完成,共 5 个文档 -
验证索引
- 检查日志中文档数量是否符合预期
- 如有 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}'
限制与注意事项
当前限制
-
L0 索引持久化
- 索引存储在内存中
- 应用重启需要重新扫描
- 解决方案:启动时自动扫描,通常 < 1s
-
章节锚点(MVP 未实现)
- sectionTitle 参数预留
- availableSections 字段返回 null
- 后续 Phase 2 实现
-
批量导入
- 当前仅支持单文件上传
- 大量文档需要循环调用 API
最佳实践
-
编写高质量 frontmatter
- keywords 精准且全面
- summary 简洁明了
- 避免关键词重复(导致多匹配)
-
知识库目录组织
knowledge_base/ ├── api/ # API 相关 ├── domain/ # 领域知识 └── troubleshoot/ # 故障排查 -
监控告警
- 慢查询: totalTime > 2s
- 失败率: > 10%
- L0 索引加载失败
后续增强方向
Phase 2 候选特性
-
章节锚点
- 支持 sectionTitle 参数
- 直接定位到文档特定章节
- 减少返回内容长度
-
L0 索引持久化
- 序列化到文件
- 避免重启扫描
-
批量导入工具
- 支持目录批量导入
- 进度监控
-
知识库管理 API
- CRUD 接口
- 在线编辑
-
向量化元数据
- 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 文档或联系团队。