mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-10-31 04:45:23 +08:00
290 lines
14 KiB
JSON
290 lines
14 KiB
JSON
{
|
||
"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": ["职责边界", "结构化分块"]
|
||
}
|
||
]
|
||
}
|