【observability】【evaluation25】LlamaIndex Transforms 评估案例

【observability】【evaluation25】LlamaIndex Transforms 评估案例
本案例演示了如何评估 LlamaIndex 中不同转换(Transform)组件的质量包括文档解析器和元数据提取器。通过系统性的评估帮助开发者选择最适合其应用场景的数据处理策略。1. 案例目标本案例的主要目标是评估不同文档解析器测试不同的句子分割策略特别是重叠设置对检索增强生成(RAG)系统性能的影响。评估不同元数据提取器比较各种元数据提取方法如摘要提取、问答对提取对系统回答质量的影响。建立评估框架提供一套完整的评估流程包括数据集生成、评估指标定义和结果比较。优化数据处理管道通过实验结果指导如何构建高效的文档摄取管道(IngestionPipeline)。2. 技术栈与核心依赖LlamaIndex核心框架用于构建RAG系统和数据处理管道OpenAI API用于语言模型和嵌入模型Pandas用于数据处理和结果展示Jupyter Notebook用于交互式实验和结果可视化核心依赖包# 核心LlamaIndex包 !pip install llama-index # 文件读取器 %pip install llama-index-readers-file # OpenAI集成 %pip install llama-index-llms-openai %pip install llama-index-embeddings-openai3. 环境配置本案例需要配置OpenAI API密钥可以通过环境变量设置import os os.environ[OPENAI_API_KEY] your-api-key-here同时需要设置Pandas显示选项以便完整查看评估结果import pandas as pd pd.set_option(display.max_rows, None) pd.set_option(display.max_columns, None) pd.set_option(display.width, None) pd.set_option(display.max_colwidth, None)4. 案例实现4.1 数据准备案例使用特斯拉2020年和2021年的10-K财务报告作为测试数据# 下载特斯拉财务报告 !wget https://www.dropbox.com/scl/fi/mlaymdy1ni1ovyeykhhuk/tesla_2021_10k.htm?rlkeyqf9k4zn0ejrbm716j0gg7r802dl1 -O tesla_2021_10k.htm !wget https://www.dropbox.com/scl/fi/rkw0u959yb4w8vlzz76sa/tesla_2020_10k.htm?rlkeytfkdshswpoupav5tqigwz1mp7dl1 -O tesla_2020_10k.htm # 使用FlatReader加载文档 from llama_index.readers.file import FlatReader from pathlib import Path reader FlatReader() docs reader.load_data(Path(./tesla_2020_10k.htm))4.2 评估数据集生成为了评估不同转换策略的效果首先需要生成一个黄金评估数据集from llama_index.core.evaluation import DatasetGenerator, QueryResponseDataset from llama_index.llms.openai import OpenAI from llama_index.embeddings.openai import OpenAIEmbedding from llama_index.readers.file import FlatReader from llama_index.core.node_parser import HTMLNodeParser, SentenceSplitter from llama_index.core.ingestion import IngestionPipeline from pathlib import Path import nest_asyncio nest_asyncio.apply() # 创建摄取管道 reader FlatReader() docs reader.load_data(Path(./tesla_2020_10k.htm)) pipeline IngestionPipeline( documentsdocs, transformations[ HTMLNodeParser.from_defaults(), SentenceSplitter(chunk_size1024, chunk_overlap200), OpenAIEmbedding(), ], ) eval_nodes pipeline.run(documentsdocs) # 生成评估数据集 eval_llm OpenAI(modelgpt-3.5-turbo) dataset_generator DatasetGenerator( eval_nodes[:100], llmeval_llm, show_progressTrue, num_questions_per_chunk3, ) # 生成100个问答对 eval_dataset await dataset_generator.agenerate_dataset_from_nodes(num100) eval_dataset.save_json(data/tesla10k_eval_dataset.json)4.3 评估器设置定义评估指标和评估器from llama_index.core.evaluation import ( CorrectnessEvaluator, SemanticSimilarityEvaluator, ) from llama_index.core.evaluation.eval_utils import ( get_responses, get_results_df, ) from llama_index.core.evaluation import BatchEvalRunner # 创建评估器 evaluator_c CorrectnessEvaluator(llmeval_llm) evaluator_s SemanticSimilarityEvaluator(llmeval_llm) evaluator_dict { correctness: evaluator_c, semantic_similarity: evaluator_s, } batch_eval_runner BatchEvalRunner( evaluator_dict, workers2, show_progressTrue )4.4 评估函数定义定义一个通用的评估函数用于测试不同的管道配置from llama_index.core import VectorStoreIndex async def run_evals( pipeline, batch_eval_runner, docs, eval_qs, eval_responses_ref ): # 获取查询引擎 nodes pipeline.run(documentsdocs) # 定义向量索引 (top-k 2) vector_index VectorStoreIndex(nodes) query_engine vector_index.as_query_engine() pred_responses get_responses(eval_qs, query_engine, show_progressTrue) eval_results await batch_eval_runner.aevaluate_responses( eval_qs, responsespred_responses, referenceeval_responses_ref ) return eval_results4.5 实验1不同句子分割策略评估测试不同重叠设置对性能的影响from llama_index.core.node_parser import HTMLNodeParser, SentenceSplitter # 定义不同重叠设置的句子分割器 sent_parser_o0 SentenceSplitter(chunk_size1024, chunk_overlap0) sent_parser_o200 SentenceSplitter(chunk_size1024, chunk_overlap200) sent_parser_o500 SentenceSplitter(chunk_size1024, chunk_overlap600) html_parser HTMLNodeParser.from_defaults() parser_dict { sent_parser_o0: sent_parser_o0, sent_parser_o200: sent_parser_o200, sent_parser_o500: sent_parser_o500, } # 为每个解析器创建管道 from llama_index.embeddings.openai import OpenAIEmbedding from llama_index.core.ingestion import IngestionPipeline pipeline_dict {} for k, parser in parser_dict.items(): pipeline IngestionPipeline( documentsdocs, transformations[ html_parser, parser, OpenAIEmbedding(), ], ) pipeline_dict[k] pipeline # 运行评估 eval_results_dict {} for k, pipeline in pipeline_dict.items(): eval_results await run_evals( pipeline, batch_eval_runner, docs, eval_qs, ref_response_strs ) eval_results_dict[k] eval_results4.6 实验2不同元数据提取器评估测试不同元数据提取器对性能的影响from llama_index.core.extractors import ( TitleExtractor, QuestionsAnsweredExtractor, SummaryExtractor, ) # 定义不同的提取器 extractor_dict { summary: SummaryExtractor(in_placeFalse), qa: QuestionsAnsweredExtractor(in_placeFalse), default: None, } # 固定解析器设置 html_parser HTMLNodeParser.from_defaults() sent_parser_o200 SentenceSplitter(chunk_size1024, chunk_overlap200) # 为每个提取器创建管道 pipeline_dict {} for k, extractor in extractor_dict.items(): if k default: transformations [ html_parser, sent_parser_o200, OpenAIEmbedding(), ] else: transformations [ html_parser, sent_parser_o200, extractor, OpenAIEmbedding(), ] pipeline IngestionPipeline(transformationstransformations) pipeline_dict[k] pipeline # 运行评估 eval_results_dict_2 {} for k, pipeline in pipeline_dict.items(): eval_results await run_evals( pipeline, batch_eval_runner, docs, eval_qs, ref_response_strs ) eval_results_dict_2[k] eval_results5. 案例效果5.1 句子分割策略评估结果不同重叠设置的评估结果如下配置名称正确性得分语义相似度sent_parser_o04.3100.972838sent_parser_o2004.3350.978842sent_parser_o5004.2700.971759分析适度的重叠200个字符表现最佳在正确性和语义相似度上都取得了最高分。无重叠0个字符的性能居中。过大的重叠600个字符反而降低了性能可能是因为引入了过多冗余信息。5.2 元数据提取器评估结果不同元数据提取器的评估结果如下配置名称正确性得分语义相似度summary4.3150.976951qa4.3550.978807default4.3050.978451分析问答对提取器qa在正确性得分上表现最佳表明生成问答对有助于提高回答质量。在语义相似度方面三种配置差异不大但问答对提取器仍然略占优势。摘要提取器summary相比默认配置略有提升但不如问答对提取器明显。6. 案例实现思路6.1 整体架构本案例采用了系统性的实验方法通过控制变量来评估不同组件的影响数据准备使用真实世界的财务文档作为测试数据确保实验的实用价值。评估数据集生成利用LLM自动生成问答对创建标准评估数据集。组件隔离测试分别测试文档解析器和元数据提取器避免相互干扰。多维度评估同时考虑正确性和语义相似度提供全面的性能评估。6.2 关键技术点摄取管道(IngestionPipeline)LlamaIndex的IngestionPipeline是本案例的核心组件它允许将多个转换步骤串联起来pipeline IngestionPipeline( documentsdocs, transformations[ HTMLNodeParser.from_defaults(), # HTML解析 SentenceSplitter(chunk_size1024, chunk_overlap200), # 文本分块 OpenAIEmbedding(), # 嵌入生成 ], )评估指标案例使用了两种主要评估指标正确性评估器(CorrectnessEvaluator)使用LLM评估生成答案与参考答案的正确性。语义相似度评估器(SemanticSimilarityEvaluator)计算生成答案与参考答案的语义相似度。批量评估运行器(BatchEvalRunner)使用BatchEvalRunner可以并行运行多个评估器提高评估效率batch_eval_runner BatchEvalRunner( evaluator_dict, workers2, show_progressTrue )6.3 缓存机制案例中提到了使用缓存来优化性能特别是在测试多个提取器时# 持久化缓存以便重用 for k, pipeline in pipeline_dict.items(): pipeline.cache.persist(f./cache/{k}.json)这种缓存机制可以避免重复计算特别是在处理大型文档集时非常有用。7. 扩展建议7.1 实验扩展更多文档类型测试当前案例主要使用HTML文档可以扩展测试PDF、Markdown等不同格式的文档。更多分块策略测试不同的分块大小和重叠设置找到最优参数组合。组合提取器测试同时使用多种提取器的效果如摘要问答对组合。不同嵌入模型评估不同嵌入模型如OpenAI、Cohere、本地模型对性能的影响。7.2 评估方法扩展人工评估结合人工评估提供更准确的质量判断。领域特定评估针对特定领域如法律、医疗设计专门的评估指标。端到端评估不仅评估检索质量还评估最终用户体验。成本效益分析评估不同配置下的API调用成本和性能平衡。7.3 系统优化自适应分块根据文档内容动态调整分块策略。智能提取器选择根据文档类型自动选择最适合的提取器。增量评估支持对新增数据的增量评估避免全量重新计算。分布式处理对于大规模数据集实现分布式评估处理。8. 总结本案例展示了如何系统性地评估LlamaIndex中不同转换组件的性能为构建高效的RAG系统提供了数据支持。通过实验我们得出以下关键结论适度的文本重叠在文档分块时适度的重叠如200个字符可以提高检索和回答质量但过多的重叠可能引入噪声。元数据提取的价值适当的元数据提取特别是问答对提取可以显著提高系统回答的正确性。评估框架的重要性建立系统的评估框架对于优化RAG系统至关重要可以帮助开发者做出数据驱动的决策。平衡性能与成本在选择组件配置时需要平衡性能提升与API调用成本找到最适合应用场景的方案。本案例提供的评估方法和框架可以广泛应用于各种RAG系统的优化帮助开发者构建更高效、更准确的信息检索和问答系统。