Files
LangBot/plugins/KnowledgeEngine/LangRAG/benchmarks/datasets/hard_multihop_zh.json

290 lines
14 KiB
JSON
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"id": "hard_multihop_zh_v1",
"description": "Harder synthetic Chinese retrieval dataset inspired by HotpotQA/BEIR/MIRACL-style evaluation: multi-hop gold documents, near-duplicate distractors, table-like facts, negation, and parser/retrieval configuration tradeoffs. Content is original and stored in-repo for deterministic regression testing.",
"methodology_references": [
"https://hotpotqa.github.io/",
"https://arxiv.org/abs/1809.09600",
"https://arxiv.org/abs/2104.08663",
"https://github.com/project-miracl/miracl"
],
"documents": [
{
"id": "doc_external_parser",
"title": "外部 Parser 的结构化输出",
"content": "GeneralParsers 的目标是把原始文件转换为 LangRAG 可以直接使用的 ParseResult。ParseResult 包含 text、sections 和 metadata。sections 会携带 heading、level、page 等结构信息,适合后续 section-aware chunking。metadata 可以记录 page_count、has_tables、has_images、vision_used、vision_failed_count 等解析统计。它不负责向量检索,也不负责生成最终答案。",
"sections": [
{
"heading": "ParseResult",
"level": 1,
"page": 1,
"content": "ParseResult 包含 text、sections 和 metadata。sections 会携带 heading、level、page 等结构信息。metadata 可以记录 page_count、has_tables、has_images、vision_used、vision_failed_count 等解析统计。"
},
{
"heading": "职责边界",
"level": 1,
"page": 2,
"content": "GeneralParsers 不负责向量检索,也不负责生成最终答案。"
}
]
},
{
"id": "doc_internal_parser",
"title": "LangRAG 内置轻量 Parser",
"content": "LangRAG 内置 FileParser 是 fallback 方案,只在没有外部 parsed_content 时使用。它可以读取 txt、pdf、docx、markdown 和 html 的基础文本,但不会提供丰富的 page metadata、vision 统计或稳定的 section 层级。这个轻量 parser 适合兜底,不适合复杂 PDF、扫描件、嵌入图片和表格密集文档。",
"sections": [
{
"heading": "Fallback Parser",
"level": 1,
"page": 1,
"content": "LangRAG 内置 FileParser 只在没有外部 parsed_content 时使用。"
},
{
"heading": "能力限制",
"level": 1,
"page": 1,
"content": "内置 parser 不会提供丰富的 page metadata、vision 统计或稳定的 section 层级,不适合复杂 PDF、扫描件、嵌入图片和表格密集文档。"
}
]
},
{
"id": "doc_section_chunking",
"title": "Section-aware chunking",
"content": "当 LangRAG 收到 parser sections 时,chunk 策略会按 section 独立切分,而不是把全文拍平成一个长字符串。chunk metadata 中会保存 heading、level、page、heading_path、has_table 和 section_index。检索结果可以把这些字段带回给模型,引用也可以包含页码和 heading_path。没有 sections 时,LangRAG 只能做普通 flat chunking。",
"sections": [
{
"heading": "结构化分块",
"level": 1,
"page": 3,
"content": "当收到 parser sections 时,chunk 策略会按 section 独立切分。metadata 保存 heading、level、page、heading_path、has_table 和 section_index。"
},
{
"heading": "无结构回退",
"level": 1,
"page": 3,
"content": "没有 sections 时,LangRAG 只能做普通 flat chunking。"
}
]
},
{
"id": "doc_parent_child",
"title": "Parent-child 索引细节",
"content": "parent_child 索引使用两层文本单元。parent chunk 比较大,用来承载完整上下文;child chunk 比较小,用来嵌入和匹配查询。向量库中存储的 document 是 child_text,但 metadata.text 返回 parent text。检索后按照 document_id 和 parent_index 去重,只保留每个 parent 中距离最好的 child。因此 parent_child 更适合需要完整段落证据的问答,但会增加向量数量。",
"sections": [
{
"heading": "父子索引",
"level": 1,
"page": 4,
"content": "parent chunk 承载完整上下文;child chunk 用来嵌入和匹配查询。metadata.text 返回 parent text。"
},
{
"heading": "去重逻辑",
"level": 2,
"page": 4,
"content": "检索后按照 document_id 和 parent_index 去重,只保留每个 parent 中距离最好的 child。"
}
]
},
{
"id": "doc_query_rewrite",
"title": "查询重写与混合检索",
"content": "LangRAG 支持 HyDE、Multi-Query 和 Step-Back。HyDE 先生成假设答案段落,再用它进行检索。Multi-Query 会生成多个查询变体并合并去重。Step-Back 会生成更抽象的问题来召回背景文档。对于 hybrid 和 full_text,重写后的 query_text 必须传给向量库的关键词侧,否则只会改变向量侧,关键词匹配得不到收益。",
"sections": [
{
"heading": "Rewrite 策略",
"level": 1,
"page": 5,
"content": "HyDE 生成假设答案段落,Multi-Query 生成多个查询变体,Step-Back 生成更抽象的问题。"
},
{
"heading": "Hybrid 注意事项",
"level": 2,
"page": 5,
"content": "对于 hybrid 和 full_text,重写后的 query_text 必须传给向量库的关键词侧。"
}
]
},
{
"id": "doc_context_window",
"title": "上下文窗口",
"content": "context_window 会在检索命中后尝试读取同一文档中相邻的检索单元,并写入 metadata.context_before 与 metadata.context_after。这个能力依赖 vector_get_by_ids。不同索引策略的向量 ID 规则不同:chunk 使用 doc_0;parent_child 使用 doc_p0_c0;qa 使用 doc_0_qa0。如果 ID 规则不匹配,context_window 会取不到相邻内容。",
"sections": [
{
"heading": "Context Window",
"level": 1,
"page": 6,
"content": "context_window 会读取相邻检索单元,并写入 context_before 与 context_after。"
},
{
"heading": "ID 规则",
"level": 2,
"page": 6,
"content": "chunk 使用 doc_0;parent_child 使用 doc_p0_c0;qa 使用 doc_0_qa0。"
}
]
},
{
"id": "doc_qa_index",
"title": "QA 索引",
"content": "QA 索引在摄入阶段对每个 chunk 调用 LLM,生成问题和答案。向量嵌入的是生成的问题,metadata 中保存 question、answer、source_chunk 和 text。这个策略可能提高自然问题匹配,但摄入成本更高,且依赖 qa_llm_model_uuid 的稳定性。没有配置 qa_llm_model_uuid 时,QA 索引应该失败而不是静默退化。",
"sections": [
{
"heading": "生成问题",
"level": 1,
"page": 7,
"content": "QA 索引对每个 chunk 调用 LLM,生成问题和答案。向量嵌入的是生成的问题。"
},
{
"heading": "成本与依赖",
"level": 1,
"page": 7,
"content": "QA 索引摄入成本更高,依赖 qa_llm_model_uuid 的稳定性。"
}
]
},
{
"id": "doc_table_pdf",
"title": "表格和 PDF 解析",
"content": "复杂 PDF 中,表格、页眉页脚和扫描页会干扰普通文本抽取。GeneralParsers 的 PDF parser 会尝试保留页面边界、把表格转换成 Markdown 表格、过滤重复 header/footer,并在配置 vision 模型后处理扫描页 OCR 和嵌入图片。表格被转换后,LangRAG 的 section-aware chunking 会尽量避免把 Markdown 表格切坏。",
"sections": [
{
"heading": "PDF 表格",
"level": 1,
"page": 8,
"content": "GeneralParsers 会把表格转换成 Markdown 表格,并过滤重复 header/footer。"
},
{
"heading": "OCR 与图片",
"level": 2,
"page": 8,
"content": "配置 vision 模型后,可以处理扫描页 OCR 和嵌入图片。"
}
]
},
{
"id": "doc_vector_weight",
"title": "Hybrid 检索权重",
"content": "hybrid 检索融合向量距离和关键词距离。vector_weight 越高,越偏向语义向量;vector_weight 越低,越偏向关键词匹配。包含参数名、错误码、文件名或产品型号的查询通常需要提高关键词侧权重。开放式概念问题通常更依赖向量语义。错误地把所有查询都设置成同一个权重,会掩盖召回问题。",
"sections": [
{
"heading": "权重含义",
"level": 1,
"page": 9,
"content": "vector_weight 越高越偏向语义向量,越低越偏向关键词匹配。"
},
{
"heading": "查询类型",
"level": 1,
"page": 9,
"content": "参数名、错误码、文件名或产品型号查询需要提高关键词侧权重;开放式概念问题更依赖向量语义。"
}
]
},
{
"id": "doc_delete",
"title": "删除与数据一致性",
"content": "LangRAG 删除文档时调用 vector_delete,并通过 file_ids 参数传入 document_id。这个行为要求每个 chunk metadata 都包含 file_id。若 ingest 过程中一部分 chunk 已写入但后续失败,系统需要能通过同一个 file_id 清理残留向量。删除逻辑和 context_window 不共享 ID 规则,删除主要依赖 metadata.file_id。",
"sections": [
{
"heading": "删除向量",
"level": 1,
"page": 10,
"content": "删除文档时调用 vector_delete,并通过 file_ids 参数传入 document_id。"
},
{
"heading": "一致性",
"level": 1,
"page": 10,
"content": "每个 chunk metadata 都应包含 file_id,便于清理残留向量。"
}
]
},
{
"id": "doc_distractor_general",
"title": "普通文本搜索说明",
"content": "一个简单搜索系统可以只做关键词匹配。它不需要 embedding_model_uuid,也不需要 parser sections。关键词搜索在短文本上速度快,但遇到同义词、抽象问题和跨段落证据时容易遗漏。这个文档包含 parser、chunk、metadata 等词,但并不描述 LangRAG 的外部 Parser 或 section-aware chunking 细节。"
},
{
"id": "doc_distractor_vision",
"title": "相机 OCR 备忘录",
"content": "移动端相机应用可以对图片进行 OCR,识别票据和名片。它也会保存 metadata,例如拍摄时间和设备型号。这个文档提到 vision、OCR 和 metadata,但与 GeneralParsers 的 PDF 扫描页处理、LangRAG 分块和向量检索没有直接关系。"
},
{
"id": "doc_distractor_weather",
"title": "天气和办公室通知",
"content": "明天下午可能下雨,办公室门禁系统维护。请不要把这个文档当作 RAG 评测相关资料。它只用于制造无关干扰。"
}
],
"queries": [
{
"id": "q_multihop_parser_chunk",
"query": "为什么外部 Parser 的 sections 能改善 LangRAG 的 chunk metadata 和引用?",
"type": "bridge",
"relevant_document_ids": ["doc_external_parser", "doc_section_chunking"],
"relevant_headings": ["ParseResult", "结构化分块"]
},
{
"id": "q_internal_vs_external",
"query": "复杂 PDF、扫描件和表格密集文档为什么不应该只依赖 LangRAG 内置 parser?",
"type": "comparison",
"relevant_document_ids": ["doc_internal_parser", "doc_table_pdf"],
"relevant_headings": ["能力限制", "PDF 表格"]
},
{
"id": "q_parent_context",
"query": "如果希望用小 chunk 精确匹配但返回完整段落证据,应选择哪种索引,原因是什么?",
"type": "bridge",
"relevant_document_ids": ["doc_parent_child"],
"relevant_headings": ["父子索引"]
},
{
"id": "q_rewrite_hybrid",
"query": "Multi-Query 在 hybrid 检索中为什么必须把重写后的 query_text 传给关键词侧?",
"type": "causal",
"relevant_document_ids": ["doc_query_rewrite", "doc_vector_weight"],
"relevant_headings": ["Hybrid 注意事项", "权重含义"]
},
{
"id": "q_context_id_rules",
"query": "context_window 对 chunk、parent_child、qa 三种索引分别应该怎样构造相邻向量 ID?",
"type": "lookup",
"relevant_document_ids": ["doc_context_window"],
"relevant_headings": ["ID 规则"]
},
{
"id": "q_qa_cost",
"query": "QA 索引为什么可能提高自然问题匹配,但摄入成本和稳定性风险更高?",
"type": "tradeoff",
"relevant_document_ids": ["doc_qa_index"],
"relevant_headings": ["生成问题", "成本与依赖"]
},
{
"id": "q_delete_cleanup",
"query": "如果 ingest 部分成功后失败,删除文档时依靠哪个 metadata 字段清理残留向量?",
"type": "failure_mode",
"relevant_document_ids": ["doc_delete"],
"relevant_headings": ["一致性"]
},
{
"id": "q_keyword_weight",
"query": "包含参数名、错误码或文件名的查询,hybrid 检索应该怎样调整 vector_weight?",
"type": "comparison",
"relevant_document_ids": ["doc_vector_weight"],
"relevant_headings": ["查询类型"]
},
{
"id": "q_vision_not_camera",
"query": "LangBot 的解析器处理扫描 PDF 时,vision 模型承担什么角色?不要回答移动端相机 OCR。",
"type": "distractor_resistance",
"relevant_document_ids": ["doc_table_pdf"],
"relevant_headings": ["OCR 与图片"]
},
{
"id": "q_parser_boundary",
"query": "GeneralParsers 和 LangRAG 的职责边界是什么,哪个负责解析,哪个负责向量检索?",
"type": "bridge",
"relevant_document_ids": ["doc_external_parser", "doc_section_chunking"],
"relevant_headings": ["职责边界", "结构化分块"]
}
]
}