LlamaIndex 简介

背景和价值

LlamaIndex的目标是简化数据处理和LLMs集成的过程,让开发者和用户能够轻松构建基于数据的LLMs应用,如文档问答、数据增强的聊天机器人、知识代理等。

LlamaIndex 一般是和LangChain一起使用,可以提高开发效率。

切片策略

LlamaIndex(现称GPT Index)提供了多种文本切片策略,旨在平衡语义连贯性和检索效率。以下是其核心切片策略的详细介绍:

一、基于长度的传统切片

1. 固定Token数量切片

  • 原理:将文本按固定Token数(如512、1024)分割,支持重叠窗口(如20%重叠率)。
  • 优势:简单高效,适用于均匀结构的文本。
  • 局限性:可能截断完整语义单元(如句子、段落)。
  • 代码示例
    from llama_index.node_parser import SimpleNodeParser
    
    node_parser = SimpleNodeParser(
        chunk_size=512, 
        chunk_overlap=100,  # 重叠100个Token
        tokenizer=lambda text: text.split()  # 自定义分词器
    )
    

2. 递归字符分割

  • 原理:优先在语义边界(如\n\n.、空格)处分割,避免生硬截断。
    from llama_index.node_parser import SentenceSplitter
    
    node_parser = SentenceSplitter(
        separators=["\n\n", "\n", ". ", " ", ""],
        chunk_size=1024,
        chunk_overlap=200
    )
    

二、语义感知切片策略

1. 语义相似性分块器

  • 核心逻辑:通过嵌入模型(如OpenAIEmbedding)计算相邻文本块的语义相似度,当相似度低于阈值时进行切分。
  • 参数配置
    • buffer_size:考虑的上下文窗口大小(默认1)。
    • breakpoint_percentile_threshold:相似度阈值(如95%)。
  • 代码示例
    from llama_index.node_parser import SemanticSplitterNodeParser
    from llama_index.embeddings import OpenAIEmbedding
    
    embed_model = OpenAIEmbedding()
    node_parser = SemanticSplitterNodeParser(
        embed_model=embed_model,
        buffer_size=2,  # 考虑前后2个句子
        breakpoint_percentile_threshold=90
    )
    

2. 层次语义分割

  • 原理:结合文档结构(标题、章节)和语义边界进行多层次切分。
  • 适用场景:学术论文、技术文档等结构化文本。
  • 代码示例
    from llama_index.node_parser import HierarchicalNodeParser
    
    node_parser = HierarchicalNodeParser.from_defaults(
        chunk_sizes=[2048, 512, 128],  # 三个层次的块大小
        separators=[
            ["\n\n\n", "\n\n"],  # 第一层:章节
            ["\n", ". "],        # 第二层:段落
            [" ", ""]            # 第三层:句子
        ]
    )
    

三、基于元数据的智能切片

1. 自动标题提取

  • 功能:自动识别文本中的标题,并将其作为元数据附加到切片节点。
  • 代码示例
    from llama_index.node_parser import MetadataExtractor, SentenceSplitter
    
    metadata_extractor = MetadataExtractor(
        extractors=[
            {"extractor": "TitleExtractor", "parameters": {"key": "title"}}
        ]
    )
    
    node_parser = SentenceSplitter(
        metadata_extractor=metadata_extractor
    )
    

2. 实体感知切分

  • 原理:通过命名实体识别(NER)保留关键实体的上下文完整性。
  • 插件支持:可集成spaCy、Stanford NER等工具。

四、高级混合策略

1. 动态滑动窗口

  • 原理:根据文本复杂度动态调整窗口大小(如复杂段落使用更小的块)。
  • 实现方式
    from llama_index.node_parser import SentenceWindowNodeParser
    
    node_parser = SentenceWindowNodeParser(
        window_size=3,  # 每个块包含3个句子
        window_metadata_key="window",
        original_text_metadata_key="original_text"
    )
    

2. 查询感知切分

  • 原理:根据用户查询主题,优先保留相关内容的完整性。
  • 依赖组件:需结合检索器(如VectorStoreIndex)动态调整。

五、对比与最佳实践

策略 优势 局限性 适用场景
固定Token分割 简单可控 可能截断语义 均匀结构文本
递归字符分割 保留语义边界 依赖分隔符设置 通用文本
语义相似性分块 自动识别语义边界 计算开销大 长文档、语义连贯文本
层次分割 保留文档结构 需明确层级规则 学术论文、报告
动态窗口 适应文本复杂度 参数调优困难 混合复杂度文本

最佳实践建议

  1. 对结构化文档(如书籍):使用HierarchicalNodeParser结合标题层次。
  2. 对问答场景:使用SentenceWindowNodeParser保留上下文窗口。
  3. 对长文本摘要:使用SemanticSplitterNodeParser确保语义连贯。
  4. 多模态数据:通过MetadataExtractor附加图片/表格引用信息。

六、自定义扩展

LlamaIndex支持通过继承NodeParser类实现自定义切片策略:

from llama_index.node_parser import NodeParser
from llama_index.schema import Document, Node

class CustomNodeParser(NodeParser):
    def get_nodes_from_documents(
        self, documents: list[Document], show_progress: bool = False
    ) -> list[Node]:
        # 自定义切片逻辑
        nodes = []
        for doc in documents:
            # 实现自定义切片...
            nodes.append(...)
        return nodes

七、性能优化

  1. 缓存机制:对不变的文档启用persist_dir缓存切片结果。
  2. 批量处理:使用show_progress=True监控大文档处理进度。
  3. 嵌入模型选择:轻量级模型(如SentenceTransformer)可提升语义分块速度。

通过合理选择和组合上述策略,可显著提升RAG系统的上下文理解能力和检索准确率。

OpenAIEmbedding 和替代方案

OpenAIEmbedding 在使用时会产生费用,并非免费服务

四、对比其他模型

模型 优势 局限 适用场景
shibing624/text2vec-base 中文原生支持,轻量级 对专业领域适配性弱 通用中文场景
GanymedeNil/text2vec-large-chinese 更高精度,参数量更大 推理速度较慢 对精度要求高的场景
sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2 多语言支持,跨语言检索 中文特定任务效果略逊 中英文混合场景
OpenAI text-embedding-ada-002 零样本学习能力强,跨领域泛化好 需API调用,有成本 对成本不敏感的场景

二、与其他模型对比

模型 参数量 中文支持 领域适配性 速度 内存占用
text2vec-large-chinese 326M 原生优化 通用+垂直微调 中速 1.3GB
shibing624/text2vec-base 110M 原生优化 通用 快速 0.4GB
sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2 110M 多语言 跨语言任务 快速 0.4GB
OpenAI text-embedding-ada-002 - 非原生 零样本泛化 依赖API -
  • 性能定位
    • 精度优于轻量级模型(如MiniLM),接近OpenAI Ada-002。
    • 速度慢于专用轻量级模型,但支持本地部署。

切片质量评估

  • 使用Ragas评估切片质量:
    from ragas.metrics import faithfulness, context_recall
    from ragas.evaluation import evaluate
    
    # 评估检索上下文的召回率和忠实度
    results = evaluate(dataset, faithfulness=faithfulness, context_recall=context_recall)
    
    

参考资料

https://e.naixuejiaoyu.com/p/t_pc/course_pc_detail/video/v_6563740ee4b04c1093ff3002?product_id=p_65638491e4b04c1093ff30e1&type=6

posted @ 2025-05-18 21:17  向着朝阳  阅读(267)  评论(0)    收藏  举报