fix: 补齐知识库工作流文档标题
This commit is contained in:
@@ -74,7 +74,7 @@ public class KnowledgeProviderImpl implements KnowledgeProvider {
|
|||||||
private Map<String, Object> toWorkflowDocument(
|
private Map<String, Object> toWorkflowDocument(
|
||||||
Document document, Object knowledgeId) {
|
Document document, Object knowledgeId) {
|
||||||
JSONObject result = JSONObject.from(document);
|
JSONObject result = JSONObject.from(document);
|
||||||
result.put("title", document.getTitle());
|
result.put("title", resolveWorkflowTitle(document));
|
||||||
result.put("content", document.getContent());
|
result.put("content", document.getContent());
|
||||||
result.put(
|
result.put(
|
||||||
"documentId",
|
"documentId",
|
||||||
@@ -82,4 +82,30 @@ public class KnowledgeProviderImpl implements KnowledgeProvider {
|
|||||||
result.put("knowledgeId", knowledgeId);
|
result.put("knowledgeId", knowledgeId);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取工作流文档标题,兼容历史检索结果只在元数据中保存来源标题的情况。
|
||||||
|
*
|
||||||
|
* @param document 检索文档
|
||||||
|
* @return 工作流文档标题
|
||||||
|
*/
|
||||||
|
private String resolveWorkflowTitle(Document document) {
|
||||||
|
String title = trimToNull(document.getTitle());
|
||||||
|
if (title != null) {
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
title = trimToNull(document.getMetadata("sourceFileName"));
|
||||||
|
if (title != null) {
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
return trimToNull(document.getMetadata("question"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private String trimToNull(Object value) {
|
||||||
|
if (value == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String text = String.valueOf(value).trim();
|
||||||
|
return text.isEmpty() ? null : text;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -496,6 +496,7 @@ public class DocumentCollectionServiceImpl extends ServiceImpl<DocumentCollectio
|
|||||||
}
|
}
|
||||||
String sourceFileName = hitSnapshot.findSourceFileName(item.getId());
|
String sourceFileName = hitSnapshot.findSourceFileName(item.getId());
|
||||||
if (StringUtil.hasText(sourceFileName)) {
|
if (StringUtil.hasText(sourceFileName)) {
|
||||||
|
item.setTitle(sourceFileName);
|
||||||
item.addMetadata("sourceFileName", sourceFileName);
|
item.addMetadata("sourceFileName", sourceFileName);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -594,6 +595,7 @@ public class DocumentCollectionServiceImpl extends ServiceImpl<DocumentCollectio
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
List<Map<String, String>> faqImages = readFaqImages(faqItem);
|
List<Map<String, String>> faqImages = readFaqImages(faqItem);
|
||||||
|
item.setTitle(faqItem.getQuestion());
|
||||||
item.setContent(buildFaqPromptContent(faqItem, faqImages));
|
item.setContent(buildFaqPromptContent(faqItem, faqImages));
|
||||||
|
|
||||||
Map<String, Object> metadataMap = item.getMetadataMap() == null
|
Map<String, Object> metadataMap = item.getMetadataMap() == null
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ public class KnowledgeProviderImplTest {
|
|||||||
document.setTitle("文档标题");
|
document.setTitle("文档标题");
|
||||||
document.setContent("文档内容");
|
document.setContent("文档内容");
|
||||||
document.addMetadata("documentId", BigInteger.valueOf(420));
|
document.addMetadata("documentId", BigInteger.valueOf(420));
|
||||||
|
document.addMetadata("sourceFileName", "元数据标题");
|
||||||
document.addMetadata("legacyKey", "legacy-value");
|
document.addMetadata("legacyKey", "legacy-value");
|
||||||
|
|
||||||
DocumentCollectionService service =
|
DocumentCollectionService service =
|
||||||
@@ -65,6 +66,52 @@ public class KnowledgeProviderImplTest {
|
|||||||
((Map<?, ?>) item.get("metadataMap")).get("legacyKey"));
|
((Map<?, ?>) item.get("metadataMap")).get("legacyKey"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证历史检索结果缺少顶层标题时,会从保留的来源元数据回填。
|
||||||
|
*
|
||||||
|
* @throws Exception 注入测试依赖失败时抛出
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void shouldResolveTitleFromSourceMetadataWhenTitleMissing()
|
||||||
|
throws Exception {
|
||||||
|
Document document = new Document();
|
||||||
|
document.setId(BigInteger.valueOf(43));
|
||||||
|
document.setTitle(" ");
|
||||||
|
document.setContent("文档内容");
|
||||||
|
document.addMetadata("sourceFileName", "来源文档.pdf");
|
||||||
|
document.addMetadata("question", "不应优先使用的问题");
|
||||||
|
|
||||||
|
Document faqDocument = new Document();
|
||||||
|
faqDocument.setId(BigInteger.valueOf(44));
|
||||||
|
faqDocument.setContent("FAQ 内容");
|
||||||
|
faqDocument.addMetadata("question", "如何申请账号?");
|
||||||
|
|
||||||
|
DocumentCollectionService service =
|
||||||
|
mock(DocumentCollectionService.class);
|
||||||
|
when(service.search(any(KnowledgeRetrievalRequest.class)))
|
||||||
|
.thenReturn(List.of(document, faqDocument));
|
||||||
|
KnowledgeProviderImpl provider = new KnowledgeProviderImpl();
|
||||||
|
setField(provider, "documentCollectionService", service);
|
||||||
|
|
||||||
|
KnowledgeNode knowledgeNode = new KnowledgeNode();
|
||||||
|
knowledgeNode.setId("knowledge-node");
|
||||||
|
List<Map<String, Object>> result = provider
|
||||||
|
.getKnowledge(BigInteger.valueOf(88))
|
||||||
|
.search("问题", 10, knowledgeNode, null);
|
||||||
|
|
||||||
|
Assert.assertEquals(2, result.size());
|
||||||
|
Assert.assertEquals("来源文档.pdf", result.get(0).get("title"));
|
||||||
|
Assert.assertEquals("如何申请账号?", result.get(1).get("title"));
|
||||||
|
Assert.assertEquals(
|
||||||
|
"来源文档.pdf",
|
||||||
|
((Map<?, ?>) result.get(0).get("metadataMap"))
|
||||||
|
.get("sourceFileName"));
|
||||||
|
Assert.assertEquals(
|
||||||
|
"如何申请账号?",
|
||||||
|
((Map<?, ?>) result.get(1).get("metadataMap"))
|
||||||
|
.get("question"));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 注入测试依赖。
|
* 注入测试依赖。
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -113,6 +113,7 @@ public class DocumentCollectionServiceImplTest {
|
|||||||
Assert.assertEquals("内部关键词召回应扩容到业务 topK 的 5 倍", 5, searcher.lastRequestCount);
|
Assert.assertEquals("内部关键词召回应扩容到业务 topK 的 5 倍", 5, searcher.lastRequestCount);
|
||||||
Assert.assertEquals("知识库过滤后只应保留完成态文档", 1, result.size());
|
Assert.assertEquals("知识库过滤后只应保留完成态文档", 1, result.size());
|
||||||
Assert.assertEquals(completedChunkId, result.get(0).getId());
|
Assert.assertEquals(completedChunkId, result.get(0).getId());
|
||||||
|
Assert.assertEquals(completedDocument.getTitle(), result.get(0).getTitle());
|
||||||
Assert.assertEquals("completed chunk", result.get(0).getContent());
|
Assert.assertEquals("completed chunk", result.get(0).getContent());
|
||||||
Assert.assertEquals(String.valueOf(knowledgeId), searcher.lastKnowledgeId);
|
Assert.assertEquals(String.valueOf(knowledgeId), searcher.lastKnowledgeId);
|
||||||
Assert.assertEquals(
|
Assert.assertEquals(
|
||||||
@@ -184,6 +185,7 @@ public class DocumentCollectionServiceImplTest {
|
|||||||
|
|
||||||
Assert.assertEquals(1, result.size());
|
Assert.assertEquals(1, result.size());
|
||||||
Document item = result.get(0);
|
Document item = result.get(0);
|
||||||
|
Assert.assertEquals(faqItem.getQuestion(), item.getTitle());
|
||||||
Assert.assertEquals(
|
Assert.assertEquals(
|
||||||
tech.easyflow.ai.entity.DocumentCollection.TYPE_FAQ,
|
tech.easyflow.ai.entity.DocumentCollection.TYPE_FAQ,
|
||||||
item.getMetadata("resultType")
|
item.getMetadata("resultType")
|
||||||
|
|||||||
Reference in New Issue
Block a user