llama-index rag框架笔记

文章目录

rag是一个概念。llama-index是一个实现rag的具体框架。

这么理解,无论哪个rag工具,都会有这些问题,而llama都实现了:

你想读 PDF?它有 SimpleDirectoryReader。

你想切分文字?它有 SentenceSplitter。

你想存向量?它有 VectorStoreIndex。

你想提问?它有 QueryEngine。

llama大概的流程是:

读取文件 | 根据文件创建向量索引 | 根据索引存库、或者查询。

示例用的llama-index版本是0.14.19

基础示例

1、安装依赖

bash 复制代码
安装 LlamaIndex 核心和文件读取支持
pip install llama-index llama-index-readers-file

安装 Ollama 连接器 (用于连接本地 LLM)
pip install llama-index-llms-ollama llama-index-embeddings-ollama

这里用的阿里云百炼openApi,所以额外安装如下依赖。
pip install llama-index-llms-dashscope llama-index-embeddings-dashscope

2、创建data目录,data目录下常见文件test.txt,内容为:

txt 复制代码
阿里云百炼是阿里云推出的一站式大模型应用开发平台。
它集成了通义千问系列模型,支持快速构建 RAG 应用。
LlamaIndex 可以通过 DashScope 连接器轻松调用百炼上的模型。

3、创建python文件llama_index_demo.py,代码:

python 复制代码
import os
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader, Settings
from llama_index.llms.dashscope import DashScope
from llama_index.embeddings.dashscope import DashScopeEmbedding

def main():
    # 1. 设置 API Key
    # 建议将 Key 设置到环境变量中,或者在这里直接替换字符串
    API_KEY = os.getenv("DASHSCOPE_API_KEY", "YOUR API KEY")
    print(f"🔍 代码读取到的API_KEY:{API_KEY}")

    # 2. 配置模型
    # model_name 可以是 qwen-turbo, qwen-plus, qwen-max 等
    llm = DashScope(model_name="qwen-plus", api_key=os.getenv("DASHSCOPE_API_KEY"))

    # 配置嵌入模型 (DashScope 提供了专门的 embedding 模型)
    # model_name 通常是 text-embedding-v1 或 text-embedding-v2
    embed_model = DashScopeEmbedding(model_name="text-embedding-v2", api_key=os.getenv("DASHSCOPE_API_KEY"))

    # 将配置应用到全局设置
    Settings.llm = llm
    Settings.embed_model = embed_model

    # 3. 加载数据
    if not os.path.exists("data"):
        os.makedirs("data")
        with open("data/test.txt", "w", encoding="utf-8") as f:
            f.write("阿里云百炼提供了一站式的大模型服务,通义千问是其核心模型。")

    documents = SimpleDirectoryReader("data").load_data()
    print(f"📚 成功加载了 {len(documents)} 个文档。")

    # 4. 构建索引
    print("⚙️ 正在构建向量索引 (调用百炼 Embedding API)...")
    index = VectorStoreIndex.from_documents(documents)

    # 5. 创建查询引擎
    query_engine = index.as_query_engine()

    # 6. 开始问答
    print("\n✅ 准备就绪!请输入问题:")
    while True:
        query = input("\n❓ 用户: ")
        if query.lower() == 'quit' or query.lower() == 'exit':
            break

        try:
            # 这里会触发:检索 -> 组装提示词 -> 调用通义千问 -> 返回结果
            response = query_engine.query(query)
            print(f"🤖 通义千问: {response}")
        except Exception as e:
            print(f"发生错误: {e}")

if __name__ == "__main__":
    main()

4、运行该代码,会弹出交互对话框
5、依次测试如下问题,看看效果

python 复制代码
阿里云百炼是什么 # 期待效果 按照文档里的内容来答
这段文档里提到了哪个核心模型 # 期待效果 按照文档里的内容来答
文档里提到的作者是谁 # 期待效果 文本里并没有,所以应该回答文档里没有提到
文档里有没有说李彦宏是谁 # 期待效果 文本里并没有,所以应该回答文档里没有提到
我想搭建一个 AI 应用,这个平台能帮我吗 # 期待效果 文档里并没有,但是它可以智能的答出来

实测输出结果和预期基本一致,成功。

SimpleDirectoryReader

读取整个文件夹

代码:

python 复制代码
from llama_index.core import SimpleDirectoryReader

# 读取 ./data 目录下所有支持的文件
documents = SimpleDirectoryReader(input_dir="./data").load_data()
读取单个或指定多个文件
python 复制代码
# 只读取这一个文件
documents = SimpleDirectoryReader(
    input_files=["./data/only_this_file.pdf"]
).load_data()

# 或者读取多个指定的文件
documents = SimpleDirectoryReader(
    input_files=["./data/a.txt", "./data/b.docx"]
).load_data()
读取文件夹(包含子目录)
python 复制代码
documents = SimpleDirectoryReader(
    input_dir="./data", 
    recursive=True  # 开启递归,连子文件夹里的文件也读出来
).load_data()
只读特定格式或排除特定文件

这个示例,既包含需要的格式,也包含排除的格式:

python 复制代码
documents = SimpleDirectoryReader(
    input_dir="./data",
    required_exts=[".pdf"],  # 只要 PDF 文件,其他的忽略
    exclude=["./data/ignore_me.txt"] # 排除这个文件
).load_data()

VectorStoreIndex

VectorStoreIndex 的方法主要围绕创建、检索和管理 这三个环节。

它是与知识库沟通的总枢纽,从数据的入库、查询、更新,几乎所有核心的操作都离不开它。

创建

VectorStoreIndex.from_documents(documents, ...)

这是最常用、最便捷的方法。你只需要把加载好的文档列表传给它,它就会自动完成文档切分、向量化和索引构建的全过程。
VectorStoreIndex(nodes, ...)

如果你需要对索引过程进行更精细的控制,比如手动定义和预处理每一个文本块(Node),就可以先创建好 Node 列表,然后通过这个构造函数直接创建索引。

根据textNode进行创建

例如这里就是先定义了根据nodes创建,然后再往里面添加数据。

代码:

python 复制代码
import os
from llama_index.core import VectorStoreIndex, Settings
from llama_index.core.schema import TextNode
from llama_index.llms.dashscope import DashScope
from llama_index.embeddings.dashscope import DashScopeEmbedding

def main():
    print("🚀 正在初始化阿里云百炼环境...")

    # --- 1. 配置 API Key ---
    # 建议先在终端运行: export DASHSCOPE_API_KEY="sk-你的KEY"
    # 如果没有环境变量,代码会尝试使用下面的占位符(记得替换!)
    API_KEY = os.getenv("DASHSCOPE_API_KEY", "sk-这里替换成你的真实KEY")

    if "这里替换" in API_KEY:
        print("⚠️ 警告:请记得在代码中填入真实的 DASHSCOPE_API_KEY!")

    # --- 2. 配置 LLM (大语言模型) ---
    # 用于最后的回答生成
    llm = DashScope(model_name="qwen-plus", api_key=API_KEY)

    # --- 3. 配置 Embedding (向量化模型) ---
    # 【关键】用于将 TextNode 的文本转化为向量
    # 阿里云百炼常用的 embedding 模型是 text-embedding-v1 或 v2
    embed_model = DashScopeEmbedding(model_name="text-embedding-v2", api_key=API_KEY)

    # --- 4. 全局应用配置 (可选但推荐) ---
    # 这样后面创建索引时,不需要每次都传 llm 和 embed_model
    Settings.llm = llm
    Settings.embed_model = embed_model

    print("✅ 模型配置完成!\n")

    # --- 5. 手动构建 TextNode 列表 ---
    print("🧱 正在构建手动数据...")
    node_list = []

    node_1 = TextNode(
        text="LlamaIndex 是一个用于构建 RAG 应用的框架,它能连接你的私有数据和大模型。",
        metadata={"来源": "技术文档", "标签": "定义"}
    )
    node_list.append(node_1)

    node_2 = TextNode(
        text="阿里云百炼提供了通义千问系列模型,包括 qwen-turbo, qwen-plus 和 qwen-max。",
        metadata={"来源": "阿里云官网", "标签": "产品介绍"}
    )
    node_list.append(node_2)

    node_3 = TextNode(
        text="DashScopeEmbedding 是 LlamaIndex 中用于调用阿里云 Embedding API 的类。",
        metadata={"来源": "开发文档", "标签": "API说明"}
    )
    node_list.append(node_3)

    # --- 6. 基于 Node 创建索引 ---
    print("⚙️ 正在调用阿里云 API 计算向量并构建索引...")
    # 因为上面配置了 Settings,这里直接传 nodes 即可
    index = VectorStoreIndex(nodes=node_list)

    # --- 7. 查询验证 ---
    query_engine = index.as_query_engine()

    print("\n" + "=" * 30)
    response = query_engine.query("阿里云百炼提供了哪些模型?")

    print(f"❓ 问题: 阿里云百炼提供了哪些模型?")
    print(f"🤖 回答: {response}")
    print("=" * 30)

    # 打印参考来源,确认检索到了 node_2
    print("\n🔍 参考来源节点:")
    for node in response.source_nodes:
        print(f"- {node.node.text[:50]}... (元数据: {node.node.metadata})")


if __name__ == "__main__":
    main()
检索

主要有两种:
index.as_query_engine()

这是最常用的方法。它会返回一个查询引擎,你直接调用 query_engine.query("你的问题") 就能获得一个完整的答案。这个引擎内部封装了"检索-增强-生成"(RAG)的完整流程。
index.as_retriever()

这个方法返回一个检索器。它只负责"检索",即根据问题找到最相关的文本块(Node),但不负责生成最终答案。当你需要更灵活地处理检索结果时(例如,先检索再自己拼接提示词),就会用到它。

管理

index.insert(document)

当你有新文档加入时,不需要重建整个索引,可以直接用这个方法将新文档插入到现有索引中。
index.delete(ref_doc_id)

当某个文档过期或需要删除时,可以通过这个方法将其从索引中移除。
index.refresh(ref_doc_id)

如果某个源文档的内容被更新了,可以用这个方法刷新索引中对应的部分。

总而言之,VectorStoreIndex 是你与知识库交互的总枢纽,从数据的"入库"到"查询"再到"更新",几乎所有核心操作都围绕着它展开。

settings

在 LlamaIndex 中,Settings 是一个全局单例对象,相当于整个应用的"总控制台"。通过配置它,你可以避免在每个函数里重复传递参数。

python 复制代码
import os
from llama_index.core import Settings
from llama_index.llms.dashscope import DashScope
from llama_index.embeddings.dashscope import DashScopeEmbedding
from llama_index.core.node_parser import SentenceSplitter

# 1. LLM 配置 (大脑)
# 负责生成回答、理解语义
Settings.llm = DashScope(
    model_name="qwen-plus", 
    api_key=os.getenv("DASHSCOPE_API_KEY")
)

# 2. Embedding Model 配置 (翻译官)
# 负责将文本转化为向量,用于检索
Settings.embed_model = DashScopeEmbedding(
    model_name="text-embedding-v2", 
    api_key=os.getenv("DASHSCOPE_API_KEY")
)

# 3. 文本切分配置 (工匠)
# 控制文档如何被切成小块 (Nodes)
# chunk_size: 每个块的大小 (一般 512-1024)
# chunk_overlap: 块之间的重叠部分 (保持上下文连贯,一般设为 chunk_size 的 10%-20%)
Settings.text_splitter = SentenceSplitter(
    chunk_size=1024, 
    chunk_overlap=20
)

# 4. 上下文窗口配置 (记忆容量)
# 告诉 LlamaIndex 你的模型最多能"读"多少字
# qwen-plus 通常支持 32k 或更长,这里设置一个保守值防止报错
Settings.context_window = 4096

# 5. 其他高级参数
# Settings.num_output = 512  # 限制模型生成的最大长度
# Settings.callback_manager = ... # 用于日志监控或 Token 统计
settings常见参数说明
参数名 作用 推荐值 (阿里云百炼) 说明
llm 指定大模型 DashScope(model_name="qwen-plus") 决定回答的质量。
embed_model 指定向量化模型 DashScopeEmbedding(model_name="text-embedding-v2") 必须配置,否则默认走 OpenAI 会报错。
text_splitter 指定切分规则 SentenceSplitter(chunk_size=1024, chunk_overlap=20) 决定检索的颗粒度。太小丢失语义,太大检索不精准。
context_window 上下文窗口大小 40968192 防止检索回来的内容太多,超过了模型的承受能力。
num_output 最大生成长度 512 限制回答的长度,防止模型啰嗦。
相关推荐
青梅煮酒与君饮2 小时前
浅谈大模型、Agent、Function Calling、MCP、Skill、Subagent、Langchain、Workflow
人工智能·python·语言模型·langchain·llama
MimCyan3 小时前
prompt越狱手册(个人笔记记录-2026.03.31)
笔记·prompt
Heartache boy3 小时前
野火STM32_HAL库版课程笔记-TIM通道捕获应用之超声波测距
笔记·stm32·单片机
Yu_Lijing3 小时前
基于C++的《Head First设计模式》笔记——访问者模式
c++·笔记·设计模式
浅念-3 小时前
Linux 进程与操作系统
linux·运维·服务器·网络·数据结构·笔记·网络协议
刘若里3 小时前
【论文阅读】自适应稀疏自注意力——可直接用!
论文阅读·人工智能·笔记·深度学习·计算机视觉
滴_咕噜咕噜3 小时前
WPF项目实战视频《五》(主要为项目实战-客户端)
笔记
老虎06273 小时前
LeetCode热题100 刷题笔记(第六天)双指针 「 盛最多水的容器」
笔记·算法·leetcode