From 198d592dd6d06ff1dd122e6dab0493d47e978073 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=AD=90=E9=BB=98?= <925456043@qq.com> Date: Wed, 2 Sep 2026 18:49:54 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E8=A1=A5=E9=BD=90=E7=9F=A5=E8=AF=86?= =?UTF-8?q?=E5=BA=93=E5=B7=A5=E4=BD=9C=E6=B5=81=E6=96=87=E6=A1=A3=E6=A0=87?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../knowledge/KnowledgeProviderImpl.java | 28 ++++++++++- .../impl/DocumentCollectionServiceImpl.java | 2 + .../knowledge/KnowledgeProviderImplTest.java | 47 +++++++++++++++++++ .../DocumentCollectionServiceImplTest.java | 2 + 4 files changed, 78 insertions(+), 1 deletion(-) diff --git a/easyflow-modules/easyflow-module-ai/src/main/java/tech/easyflow/ai/easyagentsflow/knowledge/KnowledgeProviderImpl.java b/easyflow-modules/easyflow-module-ai/src/main/java/tech/easyflow/ai/easyagentsflow/knowledge/KnowledgeProviderImpl.java index f2dbbd1e..a0e19e8f 100644 --- a/easyflow-modules/easyflow-module-ai/src/main/java/tech/easyflow/ai/easyagentsflow/knowledge/KnowledgeProviderImpl.java +++ b/easyflow-modules/easyflow-module-ai/src/main/java/tech/easyflow/ai/easyagentsflow/knowledge/KnowledgeProviderImpl.java @@ -74,7 +74,7 @@ public class KnowledgeProviderImpl implements KnowledgeProvider { private Map toWorkflowDocument( Document document, Object knowledgeId) { JSONObject result = JSONObject.from(document); - result.put("title", document.getTitle()); + result.put("title", resolveWorkflowTitle(document)); result.put("content", document.getContent()); result.put( "documentId", @@ -82,4 +82,30 @@ public class KnowledgeProviderImpl implements KnowledgeProvider { result.put("knowledgeId", knowledgeId); 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; + } } diff --git a/easyflow-modules/easyflow-module-ai/src/main/java/tech/easyflow/ai/service/impl/DocumentCollectionServiceImpl.java b/easyflow-modules/easyflow-module-ai/src/main/java/tech/easyflow/ai/service/impl/DocumentCollectionServiceImpl.java index 74975372..1488886b 100644 --- a/easyflow-modules/easyflow-module-ai/src/main/java/tech/easyflow/ai/service/impl/DocumentCollectionServiceImpl.java +++ b/easyflow-modules/easyflow-module-ai/src/main/java/tech/easyflow/ai/service/impl/DocumentCollectionServiceImpl.java @@ -496,6 +496,7 @@ public class DocumentCollectionServiceImpl extends ServiceImpl> faqImages = readFaqImages(faqItem); + item.setTitle(faqItem.getQuestion()); item.setContent(buildFaqPromptContent(faqItem, faqImages)); Map metadataMap = item.getMetadataMap() == null diff --git a/easyflow-modules/easyflow-module-ai/src/test/java/tech/easyflow/ai/easyagentsflow/knowledge/KnowledgeProviderImplTest.java b/easyflow-modules/easyflow-module-ai/src/test/java/tech/easyflow/ai/easyagentsflow/knowledge/KnowledgeProviderImplTest.java index 3311bf76..84a22923 100644 --- a/easyflow-modules/easyflow-module-ai/src/test/java/tech/easyflow/ai/easyagentsflow/knowledge/KnowledgeProviderImplTest.java +++ b/easyflow-modules/easyflow-module-ai/src/test/java/tech/easyflow/ai/easyagentsflow/knowledge/KnowledgeProviderImplTest.java @@ -36,6 +36,7 @@ public class KnowledgeProviderImplTest { document.setTitle("文档标题"); document.setContent("文档内容"); document.addMetadata("documentId", BigInteger.valueOf(420)); + document.addMetadata("sourceFileName", "元数据标题"); document.addMetadata("legacyKey", "legacy-value"); DocumentCollectionService service = @@ -65,6 +66,52 @@ public class KnowledgeProviderImplTest { ((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> 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")); + } + /** * 注入测试依赖。 * diff --git a/easyflow-modules/easyflow-module-ai/src/test/java/tech/easyflow/ai/service/impl/DocumentCollectionServiceImplTest.java b/easyflow-modules/easyflow-module-ai/src/test/java/tech/easyflow/ai/service/impl/DocumentCollectionServiceImplTest.java index 1ad9401b..72b76319 100644 --- a/easyflow-modules/easyflow-module-ai/src/test/java/tech/easyflow/ai/service/impl/DocumentCollectionServiceImplTest.java +++ b/easyflow-modules/easyflow-module-ai/src/test/java/tech/easyflow/ai/service/impl/DocumentCollectionServiceImplTest.java @@ -113,6 +113,7 @@ public class DocumentCollectionServiceImplTest { Assert.assertEquals("内部关键词召回应扩容到业务 topK 的 5 倍", 5, searcher.lastRequestCount); Assert.assertEquals("知识库过滤后只应保留完成态文档", 1, result.size()); 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(String.valueOf(knowledgeId), searcher.lastKnowledgeId); Assert.assertEquals( @@ -184,6 +185,7 @@ public class DocumentCollectionServiceImplTest { Assert.assertEquals(1, result.size()); Document item = result.get(0); + Assert.assertEquals(faqItem.getQuestion(), item.getTitle()); Assert.assertEquals( tech.easyflow.ai.entity.DocumentCollection.TYPE_FAQ, item.getMetadata("resultType")