)
LlamaIndex DatasetGenerator 解析从文档自动生成 RAG 评估问答数据集QueryResponseDataset【免费下载链接】llama_indexLlamaIndex is the leading document agent and OCR platform项目地址: https://gitcode.com/GitHub_Trending/ll/llama_index本文基于 LlamaIndex 官方 API 文档页 evaluation/dataset_generation.md 所索引的两个核心类DatasetGenerator与QueryResponseDataset结合 dataset_generation.py 的完整源码实现与 test_dataset_generation.py 测试用例讲解如何把原始文档自动转换为「问题 参考答案」数据集用于 RAG 系统的检索/回答质量评估。读完本文你将掌握该模块的全部构造参数、默认提示词、内部两阶段生成流程、JSON 持久化方式以及当前的弃用deprecated状态与迁移方向。1. 评估数据集在 LlamaIndex 评估体系中的位置LlamaIndex 的评估模块llama_index/core/evaluation/init.py导出了完整的一套评估组件FaithfulnessEvaluator、CorrectnessEvaluator、AnswerRelevancyEvaluator、ContextRelevancyEvaluator、RetrieverEvaluator等以及批处理框架BatchEvalRunner。这些评估器大多需要一份「查询 → 参考回答」的数据集作为输入或对照基准而DatasetGenerator与QueryResponseDataset正是解决「数据集从哪里来」的组件DatasetGenerator给定一组文档节点借助 LLM 为每个节点chunk生成若干问题并可进一步基于同一节点生成对应答案产出 Q/A 对QueryResponseDataset承载生成结果的 Pydantic 数据模型管理「query id → query / response」两个映射支持 JSON 存取。两个类均在llama_index.core.evaluation包中直接导出见init.py 中__all__列表的DatasetGenerator、QueryResponseDataset因此标准导入方式为from llama_index.core.evaluation import DatasetGenerator, QueryResponseDataset2. 数据结构QueryResponseDatasetQueryResponseDataset定义于 dataset_generation.py#L52-L110是一个 PydanticBaseModel只有两个字段字段类型说明queriesDict[str, str]查询 id → 问题文本responsesDict[str, str]查询 id → 参考回答仅生成问题时可为空其关键方法在源码中的行为如下from_qr_pairs(qr_pairs)L71-L80类方法从List[Tuple[str, str]]的 (query, response) 对构建数据集id 使用从 0 开始的整数字符串dataset QueryResponseDataset.from_qr_pairs([ (问题一, 答案一), (问题二, 答案二), ])qr_pairs属性L82-L93返回[(query, response), ...]列表若某个query_id在responses中不存在会抛出ValueError这是保证 Q/A 严格配对的防御性检查。questions属性L95-L98返回全部问题文本列表即list(self.queries.values())。JSON 持久化L100-L110save_json(path)调用self.model_dump()后以 4 空格缩进写入文件QueryResponseDataset.from_json(path)读取 JSON 并cls(**data)重建实例。这一对方法使数据集可以落盘为训练/评估语料配合评估器或下游微调流程复用。3. DatasetGenerator构造参数与文档预处理3.1 直接构造基于已有节点DatasetGenerator的构造函数签名L134-L163及参数默认值如下参数类型 / 默认值说明nodesList[BaseNode]必填用于生成问题的节点列表llmOptional[LLM]默认Settings.llm生成所用语言模型callback_managerOptional[CallbackManager]默认Settings.callback_manager回调管理器num_questions_per_chunkint 10每个 chunk 希望生成的问题数量类文档说明「每个文档按 512 词切分」text_question_templateBasePromptTemplate \| None问题生成提示词模板默认DEFAULT_QUESTION_GENERATION_PROMPTtext_qa_templateBasePromptTemplate \| None答案生成模板默认DEFAULT_TEXT_QA_PROMPTquestion_gen_querystr \| None触发问题生成的「元问题」默认为「Teacher/Professor 出题」提示见下metadata_modeMetadataMode MetadataMode.NONE取节点文本时是否附带元数据show_progressbool False是否用 tqdm 显示异步进度条构造函数中的两处默认值值得注意question_gen_query的默认值是把num_questions_per_chunk内插进的一段「出题教师」指令L153-L160You are a Teacher/Professor. Your task is to setup {num_questions_per_chunk} questions for an upcoming quiz/examination. The questions should be diverse in nature across the document. Restrict the questions to the context information provided.也就是说num_questions_per_chunk本身并不会硬性限制 LLM 输出条数而是通过提示词引导期望数量最终数量以 LLM 实际返回的行为准可用num参数事后截断见第 4 节。metadata_mode默认为MetadataMode.NONE即喂给 LLM 的上下文是纯节点文本不带元数据。3.2from_documents从 Document 出发的一体化入口from_documents类方法L165-L210在直接构造基础上多了文档到节点的转换与关键词过滤两步dataset_generator DatasetGenerator.from_documents( documents, llmllm, transformationstransformations, # 默认 Settings.transformations num_questions_per_chunk10, required_keywordsNone, # 节点需同时包含的关键词 exclude_keywordsNone, # 节点需排除的关键词 show_progressFalse, )源码中的处理链为切分run_transformations(documents, transformations, ...)使用Settings.transformations默认即 SentenceSplitter 体系把Document切成节点关键词过滤构造一个KeywordNodePostprocessor(required_keywords..., exclude_keywords...)先把节点包成NodeWithScore列表再postprocess_nodes过滤L189-L199。这让你可以只针对含特定术语或剔除特定术语的片段出题过滤后的节点列表传入DatasetGenerator.__init__。4. 生成流程源码剖析两阶段异步管线核心逻辑全部在_agenerate_dataset(nodes, num, generate_response)L212-L297。同步方法generate_questions_from_nodes/generate_dataset_from_nodes只是通过asyncio_run包装对应异步版本L314-L322。4.1 第一阶段逐节点提问Question Generation对每一个节点将该节点包装成单节点SummaryIndex节点内容取自node.get_content(metadata_modeself._metadata_mode)并保留node.metadata通过index.as_query_engine(llmself.llm, text_qa_templateself.text_question_template, use_asyncTrue)构造查询引擎——注意此处复用 SummaryIndex 的 text-QA 引擎但注入的是问题生成模板以self.question_gen_query为输入发起aquery把所有任务收集进query_tasks最后asyncio.gather若show_progressTrue则走tqdm_asyncio.gather并发等待L223-L255。num参数在此处作为节点级上限if num is not None and len(query_tasks) num: break即最多只为前num个节点发起提问任务。4.2 输出清洗与问题 id 分配每个节点返回的原始文本按行切分后做清洗L256-L267result str(response).strip().split(\n) cleaned_questions [ re.sub(r^\d[\).\s], , question).strip() for question in result ] cleaned_questions [q for q in cleaned_questions if len(q) 0] cur_queries {str(uuid.uuid4()): question for question in cleaned_questions}要点正则^\d[\).\s]剥掉行首的序号前缀1.、2)、3等兼容不同 LLM 的输出格式空行被丢弃每条问题分配一个uuid.uuid4()字符串作为 query id并update进全局queries字典。4.3 第二阶段可选的答案生成Answer Generationagenerate_dataset_from_nodesgenerate_responseTrue会为每个节点生成的每条问题用同一个单节点 SummaryIndex再查一次——这次使用标准答案模板self.text_qa_templateL269-L283qa_query_engine index.as_query_engine( llmself.llm, text_qa_templateself.text_qa_template, ) qr_task qa_query_engine.aquery(query)由于查询引擎只挂载了对应节点生成的答案严格锚定在该 chunk 上天然形成「问题-出处节点」闭环。每个节点的 QA 任务同样asyncio.gather并发执行结果写入responses_dict[query_id]。4.4num截断与返回最后若指定了num会把query_ids截断为前num个并同步裁剪queries与responses_dictL287-L295最终返回QueryResponseDataset(queriesqueries, responsesresponses_dict)。5. 默认提示词全文与自定义方式5.1 问题生成模板模块内定义DEFAULT_QUESTION_GENERATION_PROMPTL37-L45全文Context information is below. --------------------- {context_str} --------------------- Given the context information and not prior knowledge. generate only questions based on the below query. {query_str}其中{context_str}是节点文本{query_str}填入question_gen_query默认即第 3.1 节的「出题教师」指令。5.2 答案生成模板框架默认模板text_qa_template默认取自 default_prompts.py#L99-L111 的DEFAULT_TEXT_QA_PROMPTContext information is below. --------------------- {context_str} --------------------- Given the context information and not prior knowledge, answer the query. Query: {query_str} Answer:5.3 PromptMixin统一提示词定制入口DatasetGenerator继承自PromptMixin实现了_get_prompts/_update_promptsL324-L340因此既可以在构造时传入text_question_template、text_qa_template也可以在实例上用set_prompts(...)覆盖。docs/examples/evaluation/QuestionGeneration.ipynb 演示了完整用法框架内也有 prompt_mixin.ipynb 可参考 PromptMixin 机制本身。6. 可复现的最小使用示例综合第 3–5 节的 API 签名一个端到端的最小示例如下需要配置一个可用的 LLM 后端from llama_index.core import Document, SentenceSplitter, Settings from llama_index.core.evaluation import DatasetGenerator, QueryResponseDataset documents [ Document(textLlamaIndex 是一个用于构建 LLM 应用的文档框架。), Document(textLlamaIndex 支持向量检索、摘要索引等多种索引结构。), ] generator DatasetGenerator.from_documents( documents, transformations[SentenceSplitter()], num_questions_per_chunk5, question_gen_query请基于上下文为考试出 5 道简答题只输出题目。, show_progressTrue, ) # 只生成问题列表 questions generator.generate_questions_from_nodes(num10) # 生成「问题 参考答案」数据集并落盘 dataset: QueryResponseDataset generator.generate_dataset_from_nodes(num10) dataset.save_json(eval_dataset.json) dataset QueryResponseDataset.from_json(eval_dataset.json) print(dataset.qr_pairs[:3])注意num的语义它限制的是「最多处理多少个节点」与「最终保留多少条问题」第 4.1、4.4 节而不是精确控制 LLM 每节点的输出条数。7. 测试用例mock LLM 下的行为验证单测 test_dataset_generation.py 用 mock LLM 验证了上述管线的两次调用结构。该 mock 的拼接规则是「query:context[:context2]」断言清晰地展示了每个节点的调用顺序# 第一次调用是生成问题 assert qr_pairs[0][0] gen_question:hello_world # 第二次调用是生成答案 assert qr_pairs[0][1] gen_question:hello_world:hello_worldqr_pairs[0][0]问题 元问题gen_question 节点内容hello_world对应第一阶段qr_pairs[0][1]答案 问题本身再作为 query 查同一个节点对应第二阶段两个节点hello_world、foo_bar各产出一对 Q/Alen(qr_pairs) 2验证了「逐节点建索引」的行为。该测试同时覆盖了自定义text_question_template指定PromptType.QUESTION_ANSWER与question_gen_query的传入路径。8. 弃用状态与迁移方向需要特别强调的适用前提这两个类在当前源码中均已标记弃用且是无条件触发actionalwaysQueryResponseDatasetDeprecated in favor of \LabelledRagDataset which should be used instead.L48-L51DatasetGeneratorDeprecated in favor of \RagDatasetGenerator which should be used instead.L113-L116其 docstring 中也保留了早期声明「NOTE: this is a beta feature, subject to change!」。也就是说现有基于DatasetGenerator的调用仍可运行类仍被导出、测试仍在维护但调用时会收到弃用告警新项目建议直接使用弃用信息推荐的后继者RagDatasetGenerator/LabelledRagDataset仓库中 docs/examples/llama_dataset/labelled-rag-datasets.ipynb 示例演示了 Labelled RAG Dataset 的用法可作为迁移参考若你正在阅读较早版本的教程或示例如 QuestionGeneration.ipynb其中的 API 与本文源码解析一致但应知晓其在新版本中的弃用定位。9. 小结DatasetGeneratorQueryResponseDataset提供了 LlamaIndex 中「文档 → 问题→ 参考答案」自动化数据集管线的完整闭环输入侧from_documents完成切分Settings.transformations与KeywordNodePostprocessor关键词过滤生成侧逐节点建单节点SummaryIndex两阶段aquery问题生成 → 答案生成全部asyncio.gather并发输出经序号清洗与uuid4编号后汇总输出侧QueryResponseDataset以 id 映射管理 Q/A 配对qr_pairs属性带配对完整性校验save_json/from_json支持落盘复用可定制性PromptMixin机制允许替换问题模板、答案模板与元问题现状两个类均已弃用官方指向RagDatasetGenerator与LabelledRagDataset作为替代存量代码可用但新开发建议走新接口。【免费下载链接】llama_indexLlamaIndex is the leading document agent and OCR platform项目地址: https://gitcode.com/GitHub_Trending/ll/llama_index创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考