J'Blog

10 课 · LlamaIndex

语义检索

基于 Chroma 向量库,与 Workspace 知识库分离。用自然语言描述你想查的内容。 非管理员每人每天可检索 5 次(消耗站点 AI 配额)。

数据加载(Ingestion)

原文:数据加载 Ingestion

一句话

数据加载(Ingestion)是将原始数据处理成适合 LLM 使用格式的三阶段流程:加载数据、转换数据和索引存储数据。

什么时候翻这页

当你需要将各种格式的数据(如 Markdown、PDF、Word 文档、数据库等)转换为 LlamaIndex 可处理的 Document 对象,并进行分割、添加元数据和嵌入等处理时。

核心概念

  • Ingestion Pipeline(数据加载管道):将原始数据转换为可检索的向量索引的三阶段流程
  • Loaders(加载器):从不同数据源读取数据并转换为 Document 对象的组件
  • Document(文档):包含数据内容和元数据的基本数据单元
  • Node(节点):Document 的子类,表示数据被分割后的块
  • Transformations(转换):对数据进行处理的各种操作,如分割、添加元数据和嵌入
  • Chunk(块):文档被分割后的较小单元,用于检索和 LLM 处理

怎么做

使用加载器(Loaders)

  1. SimpleDirectoryReader:读取目录中的所有文件
from llama_index.core import SimpleDirectoryReader

documents = SimpleDirectoryReader("./data").load_data()
  1. LlamaHub 中的 Reader:从 LlamaHub 下载特定数据源的连接器
from llama_index.core import download_loader
from llama_index.readers.database import DatabaseReader

reader = DatabaseReader(
    scheme=os.getenv("DB_SCHEME"),
    host=os.getenv("DB_HOST"),
    port=os.getenv("DB_PORT"),
    user=os.getenv("DB_USER"),
    password=os.getenv("DB_PASS"),
    dbname=os.getenv("DB_NAME"),
)

query = "SELECT * FROM users"
documents = reader.load_data(query=query)
  1. 直接创建 Document
from llama_index.core import Document

doc = Document(text="text")

数据转换(Transformations)

  1. 高级转换 API
from llama_index.core import VectorStoreIndex

vector_index = VectorStoreIndex.from_documents(documents)
vector_index.as_query_engine()
  1. 自定义转换
from llama_index.core.node_parser import SentenceSplitter
from llama_index.core import Settings

text_splitter = SentenceSplitter(chunk_size=512, chunk_overlap=10)

# 全局设置
Settings.text_splitter = text_splitter

# 或针对特定索引
index = VectorStoreIndex.from_documents(
    documents, transformations=[text_splitter]
)
  1. 使用转换管道
from llama_index.core import SimpleDirectoryReader
from llama_index.core.ingestion import IngestionPipeline
from llama_index.core.node_parser import TokenTextSplitter

documents = SimpleDirectoryReader("./data").load_data()

pipeline = IngestionPipeline(transformations=[TokenTextSplitter(), ...])
nodes = pipeline.run(documents=documents)
  1. 添加元数据
document = Document(
    text="text",
    metadata={"filename": "<doc_file_name>", "category": "<category>"},
)
  1. 直接创建和传递 Nodes
from llama_index.core.schema import TextNode

node1 = TextNode(text="<text_chunk>", id_="<node_id>")
node2 = TextNode(text="<text_chunk>", id_="<node_id>")

index = VectorStoreIndex([node1, node2])

命令 / API 速查

  • SimpleDirectoryReader("./data").load_data() - 从目录加载所有文件
  • VectorStoreIndex.from_documents(documents) - 从文档创建向量索引
  • IngestionPipeline(transformations=[...]) - 创建数据加载管道
  • Document(text="...", metadata={...}) - 创建文档对象
  • TextNode(text="...", id_="...") - 创建文本节点

与 Hello-Agents / LangGraph / 本博客 handbook 索引的联系

本页介绍的数据加载流程与 Chroma 向量库的索引过程密切相关。在 Chroma 中,我们同样需要将文档分割成块(chunks),为每个块生成 embedding,然后将这些块存储到向量数据库中。LlamaIndex 的 Ingestion Pipeline 提供了更高级的抽象,可以处理多种数据源和转换方式,但其核心概念与 Chroma 中的索引流程一致。在 LangGraph 中,这些加载的数据可以作为知识库,被检索器(retriever)调用,用于增强 LLM 的回答。

初学者易错点

  1. 忽略文档分割(chunking)的重要性,导致检索效率低下
  2. 未正确设置 chunk_overlap,导致上下文信息丢失
  3. 忘记为文档添加有意义的元数据,影响后续检索和过滤
  4. 直接使用过长的文档作为输入,超出 LLM 的上下文窗口限制
  5. 未根据数据类型选择合适的 text splitter,导致分割效果不佳

相关词条

官方原文:https://developers.llamaindex.ai/python/framework/understanding/rag/loading/index