LlamaIndex 基础的使用

一、安装与基础知识

安装

安装 LlamaIndex 基础包以及入门所需依赖:

pip install llama-index
pip install llama-index-llms-openai
pip install llama-index-embeddings-huggingface
pip install -U pymilvus llama-index-vector-stores-milvus

基础知识

  • Token 限制:128k token = 131,072 token(1k = 1024)。单次最大可处理 131,072 个 token 的输入。
  • Token 估算
    • 1 个汉字 ≈ 0.5–0.8 token(通常取 0.6 token)。
    • 1 个英文单词 ≈ 1.3 token。
  • top_k:语义索引的节点数量,即检索多少条数据。

二、大语言模型(LLM)配置

1. 安装

pip install llama-index-llms-openai

2. 注册大语言模型

Settings 中注册自定义大语言模型,确保模型在 llama-index 中可用。如果模型不在默认支持列表中,需要手动注册。

from llama_index.llms.openai.utils import ALL_AVAILABLE_MODELS, CHAT_MODELS

# 定义模型及其 token 限制
MOONSHOT_MODELS = {
    "kimi-k2-0711-preview": 131072,  # 128k token
}
DEEPSEEK_MODELS = {
    "deepseek-chat": 131072,  # 128k token
}
QWEN_MODELS = {
    "qwen-plus": 131072,  # 128k token
}

# 更新模型列表
ALL_AVAILABLE_MODELS.update(QWEN_MODELS)
ALL_AVAILABLE_MODELS.update(MOONSHOT_MODELS)
ALL_AVAILABLE_MODELS.update(DEEPSEEK_MODELS)
CHAT_MODELS.update(MOONSHOT_MODELS)
CHAT_MODELS.update(DEEPSEEK_MODELS)
CHAT_MODELS.update(QWEN_MODELS)

# 更简洁的写法
# ALL_AVAILABLE_MODELS.update(MOONSHOT_MODELS | DEEPSEEK_MODELS | QWEN_MODELS)
# CHAT_MODELS.update(MOONSHOT_MODELS | DEEPSEEK_MODELS | QWEN_MODELS)

3. 封装大语言模型

示例:封装千问(Qwen)模型。

from llama_index.core import Settings
from llama_index.llms.openai import OpenAI

def qwen_llm(**kwargs):
    llm = OpenAI(
        api_key="",
        model="qwen-plus",
        api_base="https://dashscope.aliyuncs.com/compatible-mode/v1",
        temperature=0.7,
        **kwargs
    )
    return llm

4. 调用大语言模型

(1)简单对话
  • 非流式输出
response = qwen_llm().complete("你是什么大模型")
print(response)
  • 流式输出
handle = qwen_llm().stream_complete("你是什么大模型")
for token in handle:
    print(token.delta, end="", flush=True)
(2)复杂聊天
  • 非流式输出
from llama_index.core.llms import ChatMessage

messages = [
    ChatMessage(role="system", content="你是一个助手"),
    ChatMessage(role="user", content="你是什么大模型"),
]
chat_response = qwen_llm().chat(messages)
print(chat_response)
  • 同步流式输出
chat_response = qwen_llm().stream_chat(messages)
for token in chat_response:
    print(token.delta, end="", flush=True)
  • 异步流式输出
import asyncio
from llama_index.core.llms import ChatMessage

async def main():
    messages = [
        ChatMessage(role="system", content="你是一个助手"),
        ChatMessage(role="user", content="你是什么大模型"),
    ]
    stream = await qwen_llm().astream_chat(messages)
    async for chunk in stream:
        print(chunk.delta, end="")

if __name__ == "__main__":
    asyncio.run(main())

5. 全局配置大语言模型

from llama_index.core import Settings
Settings.llm = qwen_llm()

三、嵌入模型(Embedding Model)配置

1. 安装

pip install llama-index-embeddings-huggingface

2. 封装嵌入模型

示例:使用 BAAI/bge-small-zh-v1.5 模型。

from llama_index.embeddings.huggingface import HuggingFaceEmbedding

def embed_model_local_bge_small(**kwargs):
    embed_model = HuggingFaceEmbedding(
        model_name="BAAI/bge-small-zh-v1.5",
        cache_folder="./embed_cache",
        **kwargs
    )
    return embed_model

3. 全局配置嵌入模型

from llama_index.core import Settings
Settings.embed_model = embed_model_local_bge_small()

四、构建 RAG(检索增强生成)

1. 文档加载

(1)文档(Document)

文档是原始数据源(如 PDF、网页、数据库记录、API 返回)的容器。

(2)节点(Node)

文档切分后的“原子片段”,包含元数据(如来源、页码、邻居块等)。

(3)连接器(Reader)

连接器将不同数据源的数据摄取为 DocumentNode

  • 简单目录读取器(SimpleDirectoryReader): 支持 Markdown、PDF、Word、PowerPoint、图像、音频和视频。
from llama_index.core import SimpleDirectoryReader
reader = SimpleDirectoryReader(input_dir="data", recursive=True)
  • 数据库读取器(DatabaseReader)
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"),
)
(4)创建文档对象
  • 通过读取器创建
documents = reader.load_data()
# 数据库示例
# query = "SELECT * FROM users"
# documents = reader.load_data(query=query)
  • 直接创建
from llama_index.core import Document
doc = Document(text="text")

2. 向量索引创建与存储

(1)创建向量索引(VectorStoreIndex)
  • 通过文档创建
from llama_index.core import VectorStoreIndex
from llama_index.core.node_parser import SentenceSplitter
index = VectorStoreIndex.from_documents(
    documents,
    transformations=[SentenceSplitter(chunk_size=512, chunk_overlap=10)]
)
  • 通过节点创建
node_parser = SentenceSplitter(chunk_size=512, chunk_overlap=10)
nodes = node_parser.get_nodes_from_documents(documents)
index = VectorStoreIndex(nodes)
  • 从向量数据库获取
from llama_index.vector_stores.milvus import MilvusVectorStore
vector_store = MilvusVectorStore(
    token=os.getenv("MILVUS_TOKEN"),
    uri=os.getenv("MILVUS_URL"),
    collection_name=collection_name,
    dim=512,
    overwrite=False,
    db_name="test"
)
index = VectorStoreIndex.from_vector_store(vector_store)
(2)存储向量索引
  • 本地存储
index.storage_context.persist(persist_dir='index')
  • Milvus 存储:见“五、使用 Milvus 存储 RAG”。

五、使用 RAG

1. 获取向量索引对象

(1)从已构建的向量索引获取
  • 本地索引
from llama_index.core import StorageContext, load_index_from_storage
storage_context = StorageContext.from_defaults(persist_dir="./index")
index = load_index_from_storage(storage_context)
  • 远程索引(Milvus)
from llama_index.vector_stores.milvus import MilvusVectorStore
vector_store = MilvusVectorStore(
    token="root:Milvus",
    uri="http://192.168.10.70:19530",
    collection_name=collection_name,
    dim=512,
    overwrite=False,
    db_name="test"
)
index = VectorStoreIndex.from_vector_store(vector_store)
(2)直接构建
  • 从文档
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader
from llama_index.core.node_parser import SentenceSplitter
documents = SimpleDirectoryReader("data", recursive=True).load_data()
index = VectorStoreIndex.from_documents(
    documents,
    transformations=[SentenceSplitter(chunk_size=512, chunk_overlap=10)]
)
  • 从节点
node_parser = SentenceSplitter(chunk_size=512, chunk_overlap=10)
nodes = node_parser.get_nodes_from_documents(documents)
index = VectorStoreIndex(nodes)

2. 查询

(1)检索器(Retriever)

不涉及 LLM,直接从索引中检索相关节点。

from llama_index.core.retrievers import VectorIndexRetriever
retriever = VectorIndexRetriever(index=index, similarity_top_k=10)
nodes = retriever.retrieve("梅宇是谁")
for n in nodes:
    print(f"得分={n.score:.3f}\t文本={n.text[:100]}…")
(2)路由器(Router)

决定使用哪个检索器从知识库中检索上下文。

(3)节点后处理器(Node Postprocessor)

对检索到的节点进行二次过滤或重新排序。

(4)响应合成器(Response Synthesizer)

结合用户查询和检索到的文本块,通过 LLM 生成最终答案。

六、使用 Milvus 存储 RAG

安装

pip install -U pymilvus llama-index-vector-stores-milvus

1. 获取 Milvus 向量索引

from llama_index.vector_stores.milvus import MilvusVectorStore
from llama_index.core import VectorStoreIndex
vector_store = MilvusVectorStore(
    token="root:Milvus",
    uri="http://192.168.10.70:19530",
    collection_name=collection_name,
    dim=512,
    overwrite=False,
    db_name="test"
)
index = VectorStoreIndex.from_vector_store(vector_store)

2. 存储新向量索引

from llama_index.core import StorageContext
storage_context = StorageContext.from_defaults(vector_store=vector_store)
# 方法 1:通过节点
index = VectorStoreIndex(nodes, storage_context)
# 方法 2:通过文档
index = VectorStoreIndex.from_documents(documents, storage_context)
vector_store.client.flush(collection_name)  # 刷新集合

3. 添加新节点到 Milvus

(1)直接插入
index = VectorStoreIndex.from_vector_store(vector_store)
index.insert_nodes(nodes)
(2)合并索引
storage_context = StorageContext.from_defaults(vector_store=vector_store)
index = VectorStoreIndex(nodes, storage_context)
# 或
index = VectorStoreIndex.from_documents(documents, storage_context)

七、向量索引对象(Index)

1. 向量索引对象类型

(1)通过文档构建
from llama_index.core import SimpleDirectoryReader, VectorStoreIndex
documents = SimpleDirectoryReader("data", recursive=True).load_data()
index = VectorStoreIndex.from_documents(documents)
(2)通过节点构建
from llama_index.core.node_parser import SentenceSplitter
node_parser = SentenceSplitter()
nodes = node_parser.get_nodes_from_documents(documents)
index = VectorStoreIndex(nodes)
(3)加载本地索引
from llama_index.core import StorageContext, load_index_from_storage
storage_context = StorageContext.from_defaults(persist_dir="./index")
index = load_index_from_storage(storage_context)
(4)加载 Milvus 索引
vector_store = MilvusVectorStore(
    token="root:Milvus",
    uri="http://192.168.10.71:19530",
    collection_name=collection_name,
    dim=512,
    overwrite=False
)
index = VectorStoreIndex.from_vector_store(vector_store)

2. 索引对象方法

(1)聊天引擎(as_chat_engine)
  • 非流式
chat_engine = index.as_chat_engine()
response = chat_engine.chat("梅宇是谁")
print(response)
  • 流式
for token in chat_engine.stream_chat("梅宇是谁").response_gen:
    print(token, end="")
(2)查询引擎(as_query_engine)
  • 非流式
query_engine = index.as_query_engine(similarity_top_k=10)
response = query_engine.query("梅宇是谁")
print(response)
  • 流式
query_engine = index.as_query_engine(similarity_top_k=10, streaming=True)
for token in query_engine.query("梅宇是谁").response_gen:
    print(token, end="")
(3)插入节点
index.insert_nodes(nodes)
(4)创建检索器
retriever = index.as_retriever()
nodes = retriever.retrieve("梅宇是谁")

八、文档切分

1. 句子长度切分(机械切分)

from llama_index.core.node_parser import SentenceSplitter
splitter = SentenceSplitter(chunk_size=512, chunk_overlap=20)
nodes = splitter.get_nodes_from_documents(documents)

2. 语义切分

from llama_index.core.node_parser import SemanticSplitterNodeParser
splitter = SemanticSplitterNodeParser(
    embed_model=embed_model_local_bge_small(),
    breakpoint_percentile_threshold=95
)
nodes = splitter.get_nodes_from_documents(documents)

九、全局配置(Settings)

1. 大语言模型配置

from llama_index.core import Settings
Settings.llm = qwen_llm()

2. 嵌入模型配置

Settings.embed_model = embed_model_local_bge_small()

3. 文档分块大小

Settings.chunk_size = 512

4. 分块重叠区域

Settings.chunk_overlap = 10

5. 分割器配置

from llama_index.core.node_parser import SentenceSplitter
text_splitter = SentenceSplitter(chunk_size=512, chunk_overlap=10)
Settings.text_splitter = text_splitter

十、本地与远程索引区别

本地索引

  • 需手动持久化,使用 index.storage_context.persist(persist_dir='index')
  • 默认覆盖之前的索引,使用 insert_nodes 可追加不覆盖。

远程索引(Milvus)

  • 自动持久化,overwrite 参数决定是否覆盖:
    • True:覆盖之前索引。
    • False:追加新索引,保留旧索引。

示例

本地索引
  • 创建并存储
index = VectorStoreIndex.from_documents(documents)
index.storage_context.persist(persist_dir='index')
  • 加载
storage_context = StorageContext.from_defaults(persist_dir="./index")
index = load_index_from_storage(storage_context)
  • 覆盖
storage_context = StorageContext.from_defaults(persist_dir="./index")
index = VectorStoreIndex.from_documents(documents, storage_context)
index.storage_context.persist(persist_dir='index')
  • 追加
storage_context = StorageContext.from_defaults(persist_dir="./index")
index = load_index_from_storage(storage_context)
index.insert_nodes(nodes)
index.storage_context.persist(persist_dir='index')
远程索引
  • 加载
vector_store = MilvusVectorStore(
    token="root:Milvus",
    uri="http://192.168.10.70:19530",
    collection_name=collection_name,
    dim=512,
    overwrite=False
)
index = VectorStoreIndex.from_vector_store(vector_store)
  • 存储
storage_context = StorageContext.from_defaults(vector_store=vector_store)
index = VectorStoreIndex.from_documents(documents, storage_context)
vector_store.client.flush(collection_name)
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐