fix(knowledge): RAGFlow 检索 document_ids 为 null 时不入 body,修 P-A 上下文检索永不命中

根因:retrieveChunks 把 document_ids 以 null 放入 body,RAGFlow 要求其为 list,返回 code 102 "documents should be a list" → 检索 fail-closed → chunkCount=0。P-A 检索从未命中(task3/4/5/6 全 0)即此 bug,与 embedding/timeout/数据/授权均无关。修:null 时不传 document_ids(按授权 dataset 全量检索,符合 P-A 检索整个 KB 语义)。补 retrieveChunksShouldOmitDocumentIdsFromBodyWhenNull 回归测试(RagFlowClient 23/0、Retrieval 11/0 全绿)。真验:task7 contextAssembly chunkCount=1 retrievedKbIds=[2] authorizationSnapshotIds=[authsnap-e2e-1],LLM MiniMax-M2.5 基于 grounding 续写,P-A/P-B/P-C 完整 e2e 打通。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
lili 2026-06-24 07:20:07 -07:00
parent 96f8052c94
commit 86c6dbabc2
2 changed files with 23 additions and 1 deletions

View File

@ -144,7 +144,11 @@ public class HttpRagFlowKnowledgeRuntimeClient implements RagFlowKnowledgeRuntim
public RuntimeResult retrieveChunks(RetrieveChunksCommand command) {
Map<String, Object> body = new LinkedHashMap<>();
body.put("dataset_ids", command.ragflowDatasetIds());
body.put("document_ids", command.ragflowDocumentIds());
// RAGFlow 要求 document_ids list; null(不限定具体文档按授权 dataset 全量检索)时不放入 body,
// 否则 RAGFlow 拒绝 code 102 "`documents` should be a list" 检索 fail-closed,P-A 上下文检索永不命中
if (command.ragflowDocumentIds() != null) {
body.put("document_ids", command.ragflowDocumentIds());
}
body.put("question", command.question());
body.put("top_k", command.topK());
body.put("similarity_threshold", command.threshold());

View File

@ -347,6 +347,24 @@ class RagFlowKnowledgeRuntimeClientTest {
assertFalse(result.redactedSummary().contains("private prompt"));
}
@Test
void retrieveChunksShouldOmitDocumentIdsFromBodyWhenNull() {
// 回归:document_ids null(P-A 按授权 dataset 全量检索不限定具体文档)时不得放入 body;
// RAGFlow 要求其为 list, null 会被拒 code 102 "`documents` should be a list" 致检索 fail-closed P-A 永不命中
CapturingHttpRagFlowKnowledgeRuntimeClient client = new CapturingHttpRagFlowKnowledgeRuntimeClient(
"https://ragflow.example", "configured-api-key",
"{\"code\":0,\"data\":{\"chunks\":[{\"content\":\"c\",\"score\":0.9}]}}");
RagFlowKnowledgeRuntimeClient.RuntimeResult result = client.retrieveChunks(
new RagFlowKnowledgeRuntimeClient.RetrieveChunksCommand(100L, 2001L, 4001L,
List.of("dataset-1"), null, "q", 5, 0.2, null, "corr-null-doc", "hash-null-doc", 1));
assertEquals(RagFlowKnowledgeRuntimeClient.Status.SUCCEEDED, result.status());
String requestBody = new String(client.requests.get(0).body(), StandardCharsets.UTF_8);
assertFalse(requestBody.contains("document_ids"), "document_ids 为 null 时不应出现在请求 body");
assertTrue(requestBody.contains("dataset_ids"));
}
@Test
void listChunksShouldSucceedWithoutTopLevelId() {
HttpRagFlowKnowledgeRuntimeClient client = new StubHttpRagFlowKnowledgeRuntimeClient(