000:簡單 RAG 入門

本文是 refine-rag 系列教程的第一篇,帶你體驗(yàn)一下 RAG 的簡單流程。
本文所有代碼都在:https://github.com/zonezoen/refine-rag

前言

在學(xué)習(xí) RAG 之前,我們先來對比一下 RAG 和 AI Agent 的概念,只有先了解這些概念,才能繼續(xù)往前推進(jìn)。

什么是RAG

簡單來說就是允許你查閱書本,再來回答問題。

標(biāo)準(zhǔn)一點(diǎn)來說(也是簡化過的):

  1. 整理原始文檔,比如:pdf、word、excel、ppt 等
  2. 把整理好的文檔內(nèi)容進(jìn)行清洗、切塊
  3. 把切塊好的數(shù)據(jù)向量化,并存儲到向量數(shù)據(jù)庫中
  4. 用戶問一個問題
  5. 把這個問題的字符串向量化
  6. 然后根據(jù)【問題向量】去向量數(shù)據(jù)庫查找相似的知識點(diǎn)
  7. 把查到的知識和問題一起傳遞給大模型
  8. 大模型根據(jù)查到的知識點(diǎn)來回答問題
    當(dāng)然了,這個流程也是簡化過的,不過不用在意,這個只是便于你理解這個概念。

還有你需要知道的是:RAG 可以解決一些時效性的問題和幻覺問題。相比 Fing-turning 微調(diào),RAG 更節(jié)省成本,而且數(shù)據(jù)可以溯源,可以知道相關(guān)的知識點(diǎn)源自哪個文檔。

或許看這個流程圖或許會更直觀一點(diǎn)

[圖片上傳失敗...(image-dc436d-1772686621447)]

什么是AI Agent

如果把 RAG 比作是查知識庫,那么 AI Agent 就是可以執(zhí)行具體任務(wù)的助手。主要包括這幾個特點(diǎn):

  1. 規(guī)劃:規(guī)劃步驟,比如說買機(jī)票可以先查日期,再查天氣,然后買機(jī)票
  2. 記憶:可以記住聊天上下文
  3. 工具使用:可以決定使用查天氣的 API 還是執(zhí)行一段 Python 代碼
  4. 執(zhí)行:規(guī)劃好之后,可以執(zhí)行具體的任務(wù),并根據(jù)結(jié)果來執(zhí)行下一步任務(wù)

主流RAG框架

目前主流的 RAG 框架有 LlamaIndex、langchain、Dify 等,我這邊選擇前面兩個來做個示例:

大模型也分別選了 千問和 DeepSeek 來做展示:

環(huán)境準(zhǔn)備

1. Python 環(huán)境要求

  • Python 3.8 或更高版本(推薦 3.10+)
  • 建議使用虛擬環(huán)境

2. 安裝依賴包

LlamaIndex 示例所需依賴:

pip install llama-index
pip install llama-index-llms-dashscope
pip install llama-index-embeddings-dashscope
pip install dashscope
pip install python-dotenv

LangChain 示例所需依賴:

pip install langchain
pip install langchain-community
pip install langchain-huggingface
pip install langchain-deepseek
pip install langchain-text-splitters
pip install python-dotenv
pip install sentence-transformers  # HuggingFace embeddings 依賴

一鍵安裝所有依賴:

pip install llama-index llama-index-llms-dashscope llama-index-embeddings-dashscope \
            dashscope langchain langchain-community langchain-huggingface \
            langchain-deepseek langchain-text-splitters python-dotenv sentence-transformers

3. API Key 配置

本文所有代碼都在:https://github.com/zonezoen/refine-rag
創(chuàng)建 .env 文件,放到項(xiàng)目根目錄:

# DeepSeek API 配置
DEEPSEEK_API_KEY=sk-xxx
# 千問
DASHSCOPE_API_KEY=sk-yyy

如何獲取 API Key:

LlamaIndex 示例(千問)

文件名: 01_LlamaIndex.py

import os
from llama_index.llms.dashscope import DashScope, DashScopeGenerationModels
from llama_index.embeddings.dashscope import DashScopeEmbedding
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader, Settings

from dotenv import load_dotenv

os.environ['USER_AGENT'] = 'my-rag-app/1.0'
load_dotenv()
DATA_DIR = "./data"

# 1. 配置 LLM
Settings.llm = DashScope(
    model_name=DashScopeGenerationModels.QWEN_MAX,
    api_key=os.getenv("DASHSCOPE_API_KEY")
)

# 2. 設(shè)置嵌入模型
Settings.embed_model = DashScopeEmbedding(
    model_name='text-embedding-v2',
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    timeout=60,  # 增加超時時間
    max_retries=5  # 增加重試次數(shù)
)

# 3. 加載與索引
if not os.path.exists(DATA_DIR):
    print(f"錯誤:未找到路徑 {DATA_DIR}")
else:
    # 建議直接使用絕對路徑,避免相對路徑帶來的困擾
    print("正在加載文檔...")
    documents = SimpleDirectoryReader(DATA_DIR).load_data()

    print("正在創(chuàng)建索引(此步涉及 Embedding 接口調(diào)用)...")
    index = VectorStoreIndex.from_documents(documents)

    # 4. 查詢
    query_engine = index.as_query_engine()

    print("正在提問...")
    response = query_engine.query("2026春運(yùn)時間是什么時候?")
    print(f"AI 回答結(jié)果:\n{response}")

運(yùn)行方式:

python 01_LlamaIndex.py

運(yùn)行結(jié)果:

正在加載文檔...
正在創(chuàng)建索引(此步涉及 Embedding 接口調(diào)用)...
正在提問...
AI 回答結(jié)果:
2026年春運(yùn)的時間是從2月2日至3月13日。

LangChain 示例(DeepSeek)

文件名: 02_LangChain_DeepSeek.py

import os
from dotenv import load_dotenv

os.environ['USER_AGENT'] = 'my-rag-app/1.0'
load_dotenv()

# 1. 加載數(shù)據(jù)
from langchain_community.document_loaders import TextLoader

# 隨便復(fù)制一些即時新聞放到 txt 文件中,例如:https://baike.baidu.com/item/2026%E5%B9%B4%E6%98%A5%E8%BF%90/66941026?fromModule=home_hotspot
loader = TextLoader(
    file_path="data/a.txt",
    encoding="utf-8"  # 如果是中文文件,確保使用 utf-8 編碼
)

docs = loader.load()

# 2. 文檔分塊
from langchain_text_splitters import RecursiveCharacterTextSplitter

text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
all_splits = text_splitter.split_documents(docs)

# 3. 設(shè)置嵌入模型
# 使用本地 HuggingFace 模型(推薦,免費(fèi)且穩(wěn)定),可能需要科學(xué)網(wǎng)絡(luò)
from langchain_huggingface import HuggingFaceEmbeddings

embeddings = HuggingFaceEmbeddings(
    model_name="BAAI/bge-small-zh-v1.5",  # 中文模型
    model_kwargs={'device': 'cpu'},
    encode_kwargs={'normalize_embeddings': True}
)

# 4. 存到向量數(shù)據(jù)庫中,為了方便測試,這里使用內(nèi)存數(shù)據(jù)庫
from langchain_core.vectorstores import InMemoryVectorStore

vector_store = InMemoryVectorStore(embeddings)
vector_store.add_documents(all_splits)

# 5. 構(gòu)建用戶查詢,針對前面的即時新聞提問
question = "2026春運(yùn)時間是什么時候?"

# 6. 在向量數(shù)據(jù)庫中搜索最相似的文檔
retrived_docs = vector_store.similarity_search(question, k=3)
docs_content = "\n\n".join(doc.page_content for doc in retrived_docs)

# 7. 構(gòu)建提示模板
from langchain_core.prompts import ChatPromptTemplate

prompt = ChatPromptTemplate.from_template(
    """
    基于以下上下文回答問題。如果沒有結(jié)果,就說沒有找到對應(yīng)信息。
                上下文: {context}
                問題: {question}
                回答:
    """
)

# 8. 把結(jié)果和問題都發(fā)給大模型,生成答案
from langchain_deepseek import ChatDeepSeek

llm = ChatDeepSeek(
    model="deepseek-chat",  # DeepSeek API 支持的模型名稱
    temperature=0.7,  # 隨機(jī)性
    max_tokens=2048,  # 最大輸出長度
    api_key=os.getenv("DEEPSEEK_API_KEY")  # 從環(huán)境變量加載API key
)

answer = llm.invoke(prompt.format(question=question, context=docs_content))
print(answer.content)  # 只打印回答內(nèi)容

運(yùn)行方式:

python 02_LangChain_DeepSeek.py

運(yùn)行結(jié)果:

2026年春運(yùn)時間為2026年2月2日至2026年3月13日。

學(xué)習(xí)路徑

  1. 簡易RAG 學(xué)習(xí)
  2. LCEL 語法學(xué)習(xí)
  3. LangChain 讀取數(shù)據(jù)
    1. LangChain 讀取文本數(shù)據(jù)
    2. LangChain 讀取圖片數(shù)據(jù)
    3. LangChain 讀取 PDF 數(shù)據(jù)
    4. LangChain 讀取表格數(shù)據(jù)
  4. 文本切塊
  5. 向量嵌入
  6. 向量存儲
  7. 檢索前處理
  8. 索引優(yōu)化
  9. 檢索后處理
  10. 響應(yīng)生成
  11. 系統(tǒng)評估

項(xiàng)目地址

本文所有代碼示例都在 GitHub 開源:

https://github.com/zonezoen/refine-rag

歡迎 Star 和 Fork,一起學(xué)習(xí) RAG 技術(shù)!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容