一、什么是RAG机制?

RAG 是 Retrieval-Augmented Generation(检索增强生成)的缩写,是一种结合信息检索与大模型生成能力的技术框架。它的核心思想是:在让大模型回答问题或生成内容前,先从外部知识库中检索出相关信息,作为上下文输入给模型,从而提升回答的准确性、时效性和可解释性。

二、RAG解决了什么问题?

大模型(如 GPT、Deepseek)虽然强大,但有以下局限:
知识滞后:训练数据有时间截止,无法回答最新事件。
幻觉问题:可能编造答案,尤其在缺乏相关知识时。
不可追溯:生成内容难以验证来源。
RAG 通过引入外部知识库,让模型“先查资料再回答”,有效缓解这些问题。

三、RAG的工作流程

1、检索(Retrieval)
用户提问 → 从知识库(如文档、网页、数据库)中检索出最相关的片段(通常用向量检索)。
2、增强(Augmentation)
将检索到的片段作为上下文,与用户问题一起输入大模型。
3、生成(Generation)
大模型基于上下文生成答案,并标注来源(如“根据文档A第3段”)。

⚠️ 注意
RAG 的效果高度依赖检索质量(如知识库是否完整、检索是否精准)和模型生成能力(是否容易受噪声干扰)。因此,实际落地需优化向量数据库、分块策略、重排序模型等环节。

四、使用python编写一个简单的RAG系统

学习来源:https://www.bilibili.com/video/BV1wc3izUEUb?spm_id_from=333.788.videopod.sections&vd_source=6828fb4d926673085198ba0c0839150f
对应的资源都在博主提供的[相应的GitHub],可以前往学习(https://github.com/MarkTechStation/VideoCode/tree/main/%E4%BD%BF%E7%94%A8Python%E6%9E%84%E5%BB%BARAG%E7%B3%BB%E7%BB%9F/rag)

安装依赖
首先请确保你的系统已经安装了 uv 和 Jupyter,否则请参照如下链接安装:
uv: https://docs.astral.sh/uv/getting-started/installation/
Jupyter: https://jupyter.org/install
然后在项目根目录下创建一个名为 .env 的文件,并添加以下内容:

GEMINI_API_KEY=xxx

其中 xxx 为你的 Google Gemini API 密钥。没有密钥的用户可以在 https://aistudio.google.com/apikey 上申请。
然后使用 uv 安装如下 Python 依赖:

uv add sentence_transformers chromadb google-genai python-dotenv

再使用 uv 运行 Jupyter Notebook:

uv run --with jupyter jupyter lab

简单介绍一下这几个库:
1、sentence_transformers
用于将句子、段落快速编码成稠密向量(嵌入)的 Python 库,支持百余种预训练模型,常用于语义搜索、聚类、RAG 等任务。
2、chromadb
轻量级开源向量数据库,可把文本/图像等嵌入向量存到本地或云端,并提供近似最近邻查询,适合快速原型和小中型 RAG 项目。
3、google-genai
Google 官方 SDK,方便调用 Gemini、PaLM 等模型完成文本/多模态生成、嵌入、对话等功能,支持同步与流式接口。
4、python-dotenv
把 .env 文件中的键值对加载为环境变量,避免在代码里硬编码 API Key、数据库地址等敏感配置,一键 load_dotenv() 即可生效。

下面是具体的代码和部分运行结果:
1、读取相应数据,并查看,这也是使用Jupyter的好处,可以写一段运行一段的结果。

from typing import List

def split_into_chunks(doc_file: str) -> List[str]:
    with open(doc_file,'r',encoding='utf-8') as file:
        content = file.read()
    return [chunk for chunk in content.split("\n\n")]
chunks = split_into_chunks("doc.md")
for i,chunk in enumerate(chunks):
    print(f"[{i}] {chunk}\n")

部分输出:
在这里插入图片描述
2、导入Embedding模型,根据文本内容生成嵌入向量。

from sentence_transformers import SentenceTransformer
embedding_model = SentenceTransformer("shibing624/text2vec-base-chinese")
def embed_chunk(chunk):
    embedding = embedding_model.encode(chunk)
    return embedding.tolist()

test_embedding = embed_chunk("测试内容")
print(len(test_embedding))
print(test_embedding)

输出:
在这里插入图片描述
3、

embeddings = [embed_chunk(chunk) for chunk in chunks]
print(len(embeddings))
print(embeddings[0])

输出:
在这里插入图片描述
4、对应着RAG中的检索,即找出与由输入文本问题向量最接近的资料库中的内容。

import chromadb
chromadb_client = chromadb.EphemeralClient()
chromadb_collection = chromadb_client.get_or_create_collection(name="default")
def save_embeddings(chunks, embeddings):
    ids = [str(i) for i in range(len(chunks))]
    chromadb_collection.add(
        documents = chunks,
        embeddings = embeddings,
        ids = ids
    )
save_embeddings(chunks,embeddings)

def retrieve(query, top_k):
    query_embedding = embed_chunk(query)
    results = chromadb_collection.query(
        query_embeddings = [query_embedding],
        n_results=top_k
    )
    return results['documents'][0]
query = "哆啦A梦使用的3个秘密道具分别是什么?"
retrieved_chunks = retrieve(query,5)
for i,chunk in enumerate(retrieved_chunks):
    print(f"[{i}] {chunk}\n")

输出:
在这里插入图片描述
5、增强,在上面检索出的结果中,利用CrossEncoder再次计算与问题向量之间的距离,并找出最接近的资料内容。

from sentence_transformers import CrossEncoder

def rerank(query: str, retrieved_chunks: List[str], top_k: int) -> List[str]:
    cross_encoder = CrossEncoder('cross-encoder/mmarco-mMiniLMv2-L12-H384-v1')
    pairs = [(query,chunk) for chunk in retrieved_chunks]
    scores = cross_encoder.predict(pairs)
    scored_chunks = list(zip(retrieved_chunks,scores))
    scored_chunks.sort(key=lambda x:x[1], reverse = True)
    return [chunk for chunk,_ in scored_chunks][:top_k]
reranked_chunks = rerank(query, retrieved_chunks, 3)
for i, chunk in enumerate(reranked_chunks):
    print(f"[{i}] {chunk}\n")

输出:
在这里插入图片描述
6、生成,将找到的资料与一开始输入的问题,拼接在一起送入大模型,使其根据资料的内容来更准确的回答用户的提问。

from dotenv import load_dotenv
from google import genai
load_dotenv()
google_client = genai.Client()
def generate(query, chunks):
     prompt = f"""你是一位知识助手,请根据用户的问题和下列片段生成准确的回答。

用户问题: {query}

相关片段:
{"\n\n".join(chunks)}

请基于上述内容作答,不要编造信息。"""

     print(f"{prompt}\n\n---\n")

     response = google_client.models.generate_content(
         model="gemini-2.5-flash",
         contents=prompt
     )

     return response.text

answer = generate(query, reranked_chunks)
print(answer)

输出:在这里插入图片描述

五、RAG的具体应用

企业知识问答(如内部HR政策、技术文档)
客服机器人(结合产品手册回答用户问题)
法律/医疗助手(引用条文或文献)
实时新闻总结

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐