feat(knowledge): breadcrumb分块上下文 & LookupKnowledgeTool日志优化
- DocumentChunk新增breadcrumb字段,分块时构建完整标题层级路径 - DocumentChunkService splitByHeadings维护标题层级栈算法 - VectorIndexService 将breadcrumb写入Milvus metadata - LookupKnowledgeTool日志替换为结构化摘要,替代原始MD预览 - L0返回策略:唯一匹配用正文摘要,多匹配+L1有结果仅元数据(不读文件) - 新增buildCompactSummary / buildMetadataOnlySummary方法 - 安装frontend-design skill - 创建mvp/文档目录(架构设计+会话存储方案) - 更新测试适配新逻辑
This commit is contained in:
@@ -49,7 +49,7 @@ class LookupKnowledgeToolTest {
|
||||
when(knowledgeIndexService.exactMatch("ERR_TIMEOUT"))
|
||||
.thenReturn(List.of(entry));
|
||||
when(knowledgeIndexService.readDocument("test.md", 2000))
|
||||
.thenReturn("Test content");
|
||||
.thenReturn("Test content * 用于构建紧凑摘要 * keyword2");
|
||||
|
||||
// 执行查询
|
||||
LookupResult result = tool.lookupKnowledge("ERR_TIMEOUT");
|
||||
@@ -59,7 +59,11 @@ class LookupKnowledgeToolTest {
|
||||
assertNotNull(result.getPrimary());
|
||||
assertEquals("high", result.getPrimary().getConfidence());
|
||||
assertEquals("exact_L0", result.getPrimary().getMatchType());
|
||||
assertEquals("Test content", result.getPrimary().getContent());
|
||||
// 唯一匹配 → buildCompactSummary(),内容为结构化摘要
|
||||
String content = result.getPrimary().getContent();
|
||||
assertTrue(content.contains("文档: Test Doc"));
|
||||
assertTrue(content.contains("摘要: Test summary"));
|
||||
assertTrue(content.contains("Test content"));
|
||||
assertNull(result.getSupplement()); // 高置信度不调用 L1
|
||||
|
||||
// 验证 L1 未被调用
|
||||
@@ -71,7 +75,9 @@ class LookupKnowledgeToolTest {
|
||||
// 准备 L0 多个匹配
|
||||
KnowledgeEntry entry1 = KnowledgeEntry.builder()
|
||||
.filePath("doc1.md")
|
||||
.title("测试文档1")
|
||||
.keywords(List.of("超时"))
|
||||
.summary("这是一个测试文档")
|
||||
.build();
|
||||
|
||||
KnowledgeEntry entry2 = KnowledgeEntry.builder()
|
||||
@@ -81,8 +87,7 @@ class LookupKnowledgeToolTest {
|
||||
|
||||
when(knowledgeIndexService.exactMatch("超时"))
|
||||
.thenReturn(List.of(entry1, entry2));
|
||||
when(knowledgeIndexService.readDocument("doc1.md", 2000))
|
||||
.thenReturn("Content 1");
|
||||
// 多匹配 + L1 有结果 → buildMetadataOnlySummary(),不读文件,不调用 readDocument
|
||||
|
||||
// 准备 L1 结果
|
||||
VectorSearchService.SearchResult l1Result = new VectorSearchService.SearchResult();
|
||||
@@ -99,14 +104,20 @@ class LookupKnowledgeToolTest {
|
||||
assertTrue(result.isFound());
|
||||
assertNotNull(result.getPrimary());
|
||||
assertEquals("low", result.getPrimary().getConfidence()); // 多个匹配 = 低置信度
|
||||
assertEquals("Content 1", result.getPrimary().getContent());
|
||||
// 多匹配 + L1 有结果 → 仅元数据摘要
|
||||
String content = result.getPrimary().getContent();
|
||||
assertTrue(content.contains("文档: 测试文档1"));
|
||||
assertTrue(content.contains("摘要: 这是一个测试文档"));
|
||||
assertTrue(content.contains("关键词: 超时"));
|
||||
assertTrue(content.contains("来源: doc1.md"));
|
||||
|
||||
assertNotNull(result.getSupplement()); // 低置信度调用 L1
|
||||
assertEquals("L1 content", result.getSupplement().getContent());
|
||||
assertEquals("semantic_L1", result.getSupplement().getMatchType());
|
||||
|
||||
// 验证 L1 被调用
|
||||
// 验证 L1 被调用,readDocument 未被调用(多匹配不走 buildCompactSummary)
|
||||
verify(vectorSearchService).searchSimilarDocuments("超时", 3, null);
|
||||
verify(knowledgeIndexService, never()).readDocument(anyString(), anyInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user