最小可运行的 RAG示例

AI5天前发布 beixibaobao
5 0 0

上面代码是一个可用的 LangChain + 阿里云通义千问 RAG 最小示例。其逻辑非常清晰,就是:加载 → 切分 → 向量化 → 检索 → QA。

https://item.jd.com/15261772.html

# -*- coding: utf-8 -*-
"""
Created on Thu Jul 24 21:03:45 2025
@author: liguo
"""
from langchain_community.document_loaders import TextLoader
from langchain_community.indexes import VectorstoreIndexCreator
from langchain_text_splitters import CharacterTextSplitter
from langchain_community.embeddings import DashScopeEmbeddings  # 👈 替换 QwenEmbeddings
from langchain_community.vectorstores import Chroma
from langchain.chains import RetrievalQA
from langchain_community.llms import Tongyi  # Qwen
import os
# 设置阿里云 DashScope API Key(必须)
api_key=os.getenv("DASHSCOPE_API_KEY")  # 👈 替换为你自己的 API Key
def basic_rag_flow():
    # 1. 加载文档 —— 修复编码问题
    loader = TextLoader("example.txt", encoding='utf-8')
    documents = loader.load()
    # 2. 分割文档
    text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
    texts = text_splitter.split_documents(documents)
    # 3. 创建嵌入和向量存储(使用通义千问的 Embedding 模型)
    embeddings = DashScopeEmbeddings(
        model="text-embedding-v1",  # 阿里云提供的嵌入模型
        dashscope_api_key=os.environ["DASHSCOPE_API_KEY"]
    )
    vectorstore = Chroma.from_documents(texts, embeddings)
    # 4. 构建检索器
    retriever = vectorstore.as_retriever()
    # 5. 创建RAG链(使用通义千问大模型)
    llm = Tongyi(
        model_name="qwen-max",  # 也可以用 "qwen-plus", "qwen-turbo" 等
        api_key=api_key,
        temperature=0.1
    )
    qa_chain = RetrievalQA.from_chain_type(
        llm=llm,
        chain_type="stuff",
        retriever=retriever,
        return_source_documents=True  # 可选:返回参考文档
    )
    # 6. 执行查询并输出结果
    query = "请总结文档的主要内容"
    result = qa_chain.invoke({"query": query})  # 👈 注意:新版推荐用 invoke
    print("问题:", query)
    print("回答:", result["result"])
    # 可选:打印参考文档
    # for doc in result["source_documents"]:
    #     print("参考文档片段:", doc.page_content[:200], "...")
    return qa_chain
# 调用函数以执行流程
if __name__ == "__main__":
    basic_rag_flow()

下面我按模块 + 按流程对你给出的代码做一次完整解析,并明确说明:

👉 这个示例到底在演示什么?

👉 每一步解决了什么问题?


一、这个示例整体在演示什么?

这是一个“最小可运行的 RAG(检索增强生成)示例”

它演示了如何用 LangChain + 阿里云通义千问(Qwen)​ 完成:

“基于本地文档内容回答问题”

也就是:

📄 本地文本文件

🔍 向量检索

🤖 大模型生成答案

这正是 RAG 的核心流程


二、RAG 的核心思想(先看这个)

RAG = Retrieval-Augmented Generation

用户问题
   ↓
从文档中检索相关内容
   ↓
把相关内容交给大模型
   ↓
生成基于事实的回答

✅ 目的:

  • 减少大模型幻觉

  • 利用私有数据

  • 不依赖模型训练


三、代码结构总览

basic_rag_flow()
├─ 1. 加载文档
├─ 2. 切分文档
├─ 3. 向量化 + 存入向量库
├─ 4. 构建检索器
├─ 5. 构建 RAG 问答链
└─ 6. 执行查询

四、逐段代码解析


✅ 1️⃣ 导入依赖(基础设施)

from langchain_community.document_loaders import TextLoader
from langchain_community.indexes import VectorstoreIndexCreator
from langchain_text_splitters import CharacterTextSplitter
from langchain_community.embeddings import DashScopeEmbeddings
from langchain_community.vectorstores import Chroma
from langchain.chains import RetrievalQA
from langchain_community.llms import Tongyi

📌 这些模块分别对应:

模块

作用

TextLoader

读取本地文本

CharacterTextSplitter

文本切分成块

DashScopeEmbeddings

阿里云向量模型

Chroma

向量数据库

RetrievalQA

RAG 问答链

Tongyi

通义千问 LLM


✅ 2️⃣ 加载文档(数据来源)

loader = TextLoader("example.txt", encoding='utf-8')
documents = loader.load()

📌 这一步在做什么?

  • 从本地加载 example.txt

  • 返回一个 Document对象列表

  • 每个 Document 包含:

    page_content = 文本内容
    metadata = {"source": "example.txt"}

✅ 这是 RAG 的数据入口


✅ 3️⃣ 文本切分(非常关键)

text_splitter = CharacterTextSplitter(
    chunk_size=1000,
    chunk_overlap=0
)
texts = text_splitter.split_documents(documents)

📌 为什么一定要切分?

  • Embedding 模型有长度限制

  • 向量检索更适合“小块语义”

  • LLM 上下文有限

📌 切分后变成:

texts = [
  Document(...),
  Document(...),
  Document(...)
]

每一段都是一个 可独立检索的语义单元


✅ 4️⃣ 向量化 & 向量库(检索基础)

embeddings = DashScopeEmbeddings(
    model="text-embedding-v1",
    dashscope_api_key=os.environ["DASHSCOPE_API_KEY"]
)

📌 这一步在做什么?

  • 文本 → 向量(数字)

  • 使用的是阿里云的 text-embedding-v1

vectorstore = Chroma.from_documents(texts, embeddings)

📌 Chroma 做了什么?

  • 把所有文本块存成向量

  • 建立索引

  • 支持 相似度搜索

✅ 到这里,你已经拥有了一个 “可检索的知识库”


✅ 5️⃣ 构建检索器(Retriever)

retriever = vectorstore.as_retriever()

📌 Retriever 的作用:

给定一个问题 → 返回最相关的文档片段

等价于:

问题 → 向量化 → 相似度匹配 → Top-K 文档

✅ 6️⃣ 构建 RAG 问答链(核心)

llm = Tongyi(
    model_name="qwen-max",
    api_key=api_key,
    temperature=0.1
)

📌 LLM 负责:

  • 理解问题

  • 阅读检索到的文档

  • 生成最终答案


qa_chain = RetrievalQA.from_chain_type(
    llm=llm,
    chain_type="stuff",
    retriever=retriever,
    return_source_documents=True
)

📌 RetrievalQA做了什么?

自动完成这个流程:

用户输入问题
   ↓
Retriever 找相关文档
   ↓
把问题和文档拼在一起
   ↓
LLM 生成答案

📌 chain_type="stuff"的含义:

  • 把所有检索到的文档 直接塞进 prompt

  • 简单、直观

  • 适合文档不太长的场景


✅ 7️⃣ 执行查询

query = "请总结文档的主要内容"
result = qa_chain.invoke({"query": query})

📌 实际发生了什么?

  1. 问题 → embedding

  2. 去 Chroma 里找相关内容

  3. 拼接成类似这样的 prompt:

根据以下内容回答问题:
[文档片段1]
[文档片段2]
问题:请总结文档的主要内容
  1. Qwen 生成答案


五、这个示例“演示了什么能力”?

✅ 它不是一个玩具,而是一个 标准 RAG 模板,展示了:

能力

是否演示

私有数据接入

文本向量化

向量检索

大模型增强生成

LangChain 标准用法

阿里云通义千问集成


六、一句话总结

这个示例演示了:如何使用 LangChain + 阿里云 DashScope,构建一个基于本地文档的检索增强生成(RAG)问答系统。

最小可运行的 RAG示例

© 版权声明

相关文章