From f4f0c63325632333e5db9b321bf98746d0c32c02 Mon Sep 17 00:00:00 2001 From: zhuyongxin Date: Thu, 25 Jun 2026 15:56:49 +0800 Subject: [PATCH] =?UTF-8?q?fix(knowledge):=20=E4=BF=AE=E5=A4=8D=20readDocu?= =?UTF-8?q?ment=20=E6=96=87=E4=BB=B6=E8=B7=AF=E5=BE=84=E6=8B=BC=E6=8E=A5?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 问题 L1 语义检索返回文档后,尝试读取文档内容时报错: ``` 读取文档失败: api/payment-errors.md java.nio.file.NoSuchFileException: api\payment-errors.md ``` **原因**: - `KnowledgeEntry.filePath` 存储的是相对路径(如 `api/payment-errors.md`) - `readDocument()` 方法直接使用相对路径读取,未拼接 `knowledge_base` 前缀 - 导致找不到文件 ## 修复内容 ### 1. 添加 knowledge.base-path 配置 ```java @Value("${knowledge.base-path:knowledge_base}") private String knowledgeBasePath; ``` **默认值**:`knowledge_base`(当前工作目录下) ### 2. 修复 readDocument 方法 ```java public String readDocument(String filePath, int maxChars) { // 拼接完整路径:knowledge_base + 相对路径 Path fullPath = Paths.get(knowledgeBasePath, filePath); String content = Files.readString(fullPath); // ... } ``` **修复前**: ``` 读取: api/payment-errors.md 实际路径: <当前目录>/api/payment-errors.md ❌ ``` **修复后**: ``` 读取: api/payment-errors.md 实际路径: knowledge_base/api/payment-errors.md ✅ ``` ## 数据流 ``` L1 语义检索 ↓ 返回 KnowledgeEntry filePath = "api/payment-errors.md" ↓ readDocument("api/payment-errors.md", 2000) ↓ 拼接路径: Paths.get("knowledge_base", "api/payment-errors.md") ↓ 完整路径: "knowledge_base/api/payment-errors.md" ↓ Files.readString(fullPath) ↓ 返回文档内容 ✅ ``` ## 配置 在 `application.yml` 中可以自定义路径: ```yaml knowledge: base-path: ./knowledge_base # 默认值 ``` 或者绝对路径: ```yaml knowledge: base-path: /data/knowledge_base ``` ## 验证 ```bash # 1. 启动应用 mvn spring-boot:run # 2. 提问触发 L1 你:支付为什么会失败? # 3. Agent 应该: # - lookup_knowledge("支付为什么会失败") # - L0 失败 → L1 语义检索 # - 找到 api/payment-errors.md # - 读取文件内容成功 ✅ # - 返回文档内容给用户 ``` ## 相关代码路径 - `KnowledgeIndexService.readDocument()` - 文件读取 - `KnowledgeEntry.filePath` - 存储相对路径 - `LookupKnowledgeTool` - 调用 readDocument --- SELECT | 0 .../superbiz/agent/service/KnowledgeIndexService.java | 11 ++++++++--- .../agent/repository/ApiDocumentRepositoryTest.java | 4 ++-- .../repository/DiagnosisRecordRepositoryTest.java | 2 +- 4 files changed, 11 insertions(+), 6 deletions(-) create mode 100644 SELECT diff --git a/SELECT b/SELECT new file mode 100644 index 0000000..e69de29 diff --git a/src/main/java/com/superbiz/agent/service/KnowledgeIndexService.java b/src/main/java/com/superbiz/agent/service/KnowledgeIndexService.java index 1d144ca..a97270b 100644 --- a/src/main/java/com/superbiz/agent/service/KnowledgeIndexService.java +++ b/src/main/java/com/superbiz/agent/service/KnowledgeIndexService.java @@ -29,6 +29,9 @@ import java.util.stream.Stream; @Service public class KnowledgeIndexService { + @Value("${knowledge.base-path:knowledge_base}") + private String knowledgeBasePath; + @Autowired private ApiDocumentRepository apiDocumentRepository; @@ -195,13 +198,15 @@ public class KnowledgeIndexService { /** * 读取文档内容 * - * @param filePath 文件路径 + * @param filePath 文件相对路径(如 api/payment-errors.md) * @param maxChars 最大字符数 * @return 文档内容(前 maxChars 字符),失败返回 null */ public String readDocument(String filePath, int maxChars) { try { - String content = Files.readString(Paths.get(filePath)); + // 拼接完整路径:knowledge_base + 相对路径 + Path fullPath = Paths.get(knowledgeBasePath, filePath); + String content = Files.readString(fullPath); if (content.length() > maxChars) { return content.substring(0, maxChars) + "..."; @@ -210,7 +215,7 @@ public class KnowledgeIndexService { return content; } catch (IOException e) { - log.error("读取文档失败: {}", filePath, e); + log.error("读取文档失败: {}/{}", knowledgeBasePath, filePath, e); return null; } } diff --git a/src/test/java/com/superbiz/agent/repository/ApiDocumentRepositoryTest.java b/src/test/java/com/superbiz/agent/repository/ApiDocumentRepositoryTest.java index 6fe2034..5ef1a3b 100644 --- a/src/test/java/com/superbiz/agent/repository/ApiDocumentRepositoryTest.java +++ b/src/test/java/com/superbiz/agent/repository/ApiDocumentRepositoryTest.java @@ -40,7 +40,7 @@ class ApiDocumentRepositoryTest { .filePath("/uploads/api-spec.md") .fileHash("abc123hash") .fileSize(1024L) - .faultCategory(FaultCategory.EXTERNAL_API) + .faultCategory(FaultCategory.API) .faultSource("广东") .apiName("查询接口") .status("PENDING") @@ -167,7 +167,7 @@ class ApiDocumentRepositoryTest { .docId(UUID.randomUUID().toString()) .fileName("guangdong-api.md") .faultSource("广东") - .faultCategory(FaultCategory.EXTERNAL_API) + .faultCategory(FaultCategory.API) .build(); repository.save(doc); diff --git a/src/test/java/com/superbiz/agent/repository/DiagnosisRecordRepositoryTest.java b/src/test/java/com/superbiz/agent/repository/DiagnosisRecordRepositoryTest.java index 6f825a5..da07f12 100644 --- a/src/test/java/com/superbiz/agent/repository/DiagnosisRecordRepositoryTest.java +++ b/src/test/java/com/superbiz/agent/repository/DiagnosisRecordRepositoryTest.java @@ -38,7 +38,7 @@ class DiagnosisRecordRepositoryTest { .sessionId("session-001") .businessId("order-12345") .traceId("trace-abc123") - .faultCategory(FaultCategory.EXTERNAL_API) + .faultCategory(FaultCategory.API) .faultSource("广东") .faultTarget("http://api.example.com/query") .errorCode("40003")