本文将从底层逻辑拆解RAG(检索增强生成)技术原理,通过numpy等Python基础库手把手教你搭建完整RAG系统。内容涵盖RAG核心概念解析、标准化工作流程拆解,以及文本提取、智能分块、向量嵌入、语义检索、精准生成等全环节实现细节,帮你跳出“调参工具人”误区,真正掌握RAG技术内核。

一、深入理解RAG(检索增强生成)技术
1.1 为什么需要RAG?——解决LLM的核心痛点
大语言模型(LLM)虽具备强大的自然语言处理能力,但在实际应用中存在三大关键痛点:
- 生成内容不可靠:容易产生与事实不符的“幻觉信息”,尤其在专业领域可能导致严重误导。
- 知识时效性不足:训练数据存在“截止日期”,无法获取实时或最新领域知识。
- 推理过程不透明:属于“黑盒模型”,难以追溯答案来源,合规性与可信度受限。
检索增强生成(RAG)技术的核心价值,就是通过引入“外部特定领域数据”,为LLM补充专属知识,从而针对性解决上述问题。例如在企业知识库问答、行业报告分析等场景中,RAG能让LLM基于指定文档生成精准、可溯源的回答。
1.2 标准化RAG工作流拆解
完整的RAG技术流程可分为“数据预处理”与“实时交互”两大阶段,也就是行业常说的数据索引阶段和检索生成阶段。

阶段1:数据索引(离线预处理)
该阶段主要完成“原始数据→可检索向量”的转换,为后续快速查询做准备,核心步骤包括:
- 数据加载:导入PDF、Word、TXT等格式的原始文档,支持单文件或多文件批量处理。
- 智能分块:将长文档切割为语义完整的短文本块(如500字符/块),同时保留部分重叠内容(如50字符重叠),避免切断关键信息。
- 向量嵌入:使用专业嵌入模型(如OpenAI Embeddings、BGE-M3),将文本块转换为计算机可识别的数值向量。
- 向量存储:将生成的向量存入向量数据库(如Chroma、Milvus),利用数据库的索引能力提升后续检索速度。
阶段2:检索生成(实时交互)
当用户发起查询时,系统通过以下步骤生成回答:
- 查询向量化:用与“数据索引阶段”相同的嵌入模型,将用户问题转换为查询向量。
- 语义匹配检索:计算查询向量与向量数据库中所有向量的相似度(常用余弦距离、欧几里得距离),筛选出最相关的Top-N文本块(如Top5)。
- LLM精准生成:将用户问题与检索到的相关文本块结合,作为Prompt输入LLM,让模型基于指定上下文生成回答,确保内容精准且可溯源。
1.3 快速上手:基于LangChain的PDF问答RAGdemo
借助成熟的Python库,只需几十行代码就能搭建基础RAG应用。目前主流的RAG开发框架包括LangChain、LlamaIndex,以下以LangChain为例,实现PDF文档问答功能。
核心依赖库
- LangChain:负责串联数据加载、分块、检索、生成全流程。
- OpenAI Embeddings:提供文本向量嵌入能力。
- Chroma:轻量级开源向量数据库,适合快速原型开发。
- PyPDFLoader:专门用于提取PDF文件中的文本内容。
完整代码实现
import os
# 导入LangChain核心模块
from langchain_community.document_loaders import PyPDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.vectorstores import Chroma
from langchain.prompts import ChatPromptTemplate
from langchain.chat_models import ChatOpenAI
# 配置关键参数
OPENAI_API_KEY = os.getenv('OPENAI_API_KEY') # 建议通过环境变量配置,避免明文暴露
DOC_PATH = "knowledge_base/alphabet_10K_2022.pdf" # PDF文件路径
CHROMA_PATH = "alphabet_rag_db" # 向量数据库存储路径
# ---------------------- 1. 数据索引阶段 ----------------------
# 1.1 加载PDF并提取文本
pdf_loader = PyPDFLoader(DOC_PATH)
pdf_pages = pdf_loader.load() # 按页面拆分的文本列表
# 1.2 智能分块(500字符/块,50字符重叠)
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=500,
chunk_overlap=50,
separators=["\n\n", "\n", ". ", " ", ""] # 按语义优先级拆分
)
text_chunks = text_splitter.split_documents(pdf_pages)
# 1.3 生成向量并存入Chroma
embedding_model = OpenAIEmbeddings(openai_api_key=OPENAI_API_KEY)
chroma_db = Chroma.from_documents(
documents=text_chunks,
embedding=embedding_model,
persist_directory=CHROMA_PATH
)
chroma_db.persist() # 持久化存储,避免重复计算
# ---------------------- 2. 检索生成阶段 ----------------------
# 2.1 接收用户查询
user_query = "该文档中提到的主要风险有哪些?"
# 2.2 语义检索Top5相关文本块(默认使用余弦相似度)
retrieved_docs = chroma_db.similarity_search_with_score(user_query, k=5)
# 2.3 构建Prompt(严格限定基于上下文回答)
context_content = "\n\n".join([doc.page_content for doc, _score in retrieved_docs])
PROMPT_TEMPLATE = """
请仅基于以下上下文内容回答问题:
{context}
问题:{question}
回答要求:
1. 内容必须完全来自上述上下文,不添加外部知识;
2. 分点清晰说明,无需解释回答逻辑;
3. 避免使用“根据上下文”“文中提到”等表述。
"""
prompt = ChatPromptTemplate.from_template(PROMPT_TEMPLATE).format(
context=context_content,
question=user_query
)
# 2.4 调用LLM生成回答
llm_model = ChatOpenAI(openai_api_key=OPENAI_API_KEY, model_name="gpt-3.5-turbo")
final_answer = llm_model.predict(prompt)
# 输出结果
print("LLM生成回答:\n", final_answer)
示例输出结果
LLM生成回答:
该文档中提到的主要风险包括:
1. 投资价值下降的风险;
2. 产品与服务 adoption 率不足的风险;
3. 因修改、恐怖袭击、自然灾害等因素导致的运营干扰或中断风险;
4. 商业秘密泄露及相关法律、财务风险;
5. 声誉、财务及监管合规方面的暴露风险;
6. 平台被滥用及用户数据误用的风险;
7. 因技术错误或漏洞导致的服务中断或故障风险;
8. 国际业务运营相关的风险。
掌握了基础RAG流程后,接下来我们将深入底层,用numpy等基础库“手撕”RAG核心模块,彻底理解每一步的实现逻辑。
二、底层实战:用基础库从零搭建RAG系统
在构建更复杂的 RAG 架构之前,我们先从最基础的版本入手。整个流程可以分为以下几个关键步骤:
1.数据导入: 加载并预处理原始文本数据,为后续处理做好准备。
2.文本分块: 将长文本分割成较小的段落或句子,以提高检索效率和相关性。
3.创建 Embedding: 使用嵌入模型将文本块转换为向量表示,便于进行语义层面的比较与匹配。
4.语义搜索: 根据用户输入的查询内容,在已有向量库中检索出最相关的文本块。
5.响应生成: 基于检索到的相关内容,结合语言模型生成最终的回答输出。
2.1 设置环境
首先,我们需要安装并导入必要的库:
# !pip install numpy
# !pip install pymupdf
# !pip install dashscope
# !pip install openai
# !pip install scikit-learn
import os
import numpy as np
import json
import fitz
import dashscope
from openai import OpenAI
2.2 从PDF文件中提取文本
首先我们需要一个文本数据源。我们使用PyMuPDF库从PDF文件中提取文本,这里定义一个函数来从PDF中提取文本:
def extract_text_from_pdf(pdf_path):
# 打开PDF文件
document = fitz.open(pdf_path)
all_text = "" # 初始化一个空字符串存储提取出的文本
# 遍历PDF中的每一页
for page_num in range(document.page_count):
page = document[page_num] # 获取页面
text = page.get_text("text") # 从页面提取文本
all_text += text # 将提取出的文本追加到all_text字符串
return all_text # 返回提取出的文本
2.3 对提取出的文本进行分块
有了提取出的文本后,我们将它分成较小的、有重叠的块,以提高检索准确性。
def chunk_text(text_input, chunk_size, overlap_size):
text_chunks = [] # 初始化一个列表存储文本块
# 循环遍历文本,步长为(chunk_size - overlap_size)
for i in range(0, len(text_input), chunk_size - overlap_size):
text_chunks.append(text_input[i:i + chunk_size]) # 追加从i到i+chunk_size的文本块到text_chunks列表
return text_chunks # 返回文本块列表
2.4 设置OpenAI API客户端
初始化OpenAI客户端用于生成嵌入和响应。
核心:选择一个合适的 Embedding Model,BGE-M3 ,BGE-large-zh
client = OpenAI(
api_key=os.getenv("DASHSCOPE_API_KEY"), # 如果您没有配置环境变量,请在此处用您的API Key进行替换
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1" # 百炼服务的base_url
)
2.5 提取并分块PDF文件中的文本
现在,我们加载PDF,提取文本,并将其分割成块。
# 定义PDF文件路径
pdf_path = "knowledge_base/智能编码助手通义灵码.pdf"
# 从PDF文件中提取文本
extracted_text = extract_text_from_pdf(pdf_path)
# 将提取出的文本分割成1000字符大小的块,重叠部分为100字符
text_chunks = chunk_text(extracted_text, 1000, 100)
# 打印创建的文本块数量
print("文本块数量:", len(text_chunks))
# 打印第一个文本块
print("\n第一个文本块:")
print(text_chunks[0])
2.6 创建文本块的嵌入向量
嵌入向量将文本转换为数值向量,允许高效地进行相似度搜索。这里用了阿里云的embedding模型“text-embedding-v3”。
# 创建文本块的嵌入向量
def create_embeddings(texts, model="text-embedding-v3"):
"""
输入一组文本(字符串或列表),返回对应的嵌入向量列表
"""
if isinstance(texts, str):
texts = [texts] # 确保输入为列表形式
completion = client.embeddings.create(
model=model,
input=texts,
encoding_format="float"
)
# 将响应转换为 dict 并提取所有 embedding
data = json.loads(completion.model_dump_json())
embeddings = [item["embedding"] for item in data["data"]]
return embeddings
2.7 执行语义搜索
我们通过计算余弦相似度来找到与用户查询最相关的文本块。
from sklearn.metrics.pairwise import cosine_similarity
# 语义搜索函数
def semantic_search(query, text_chunks, embeddings=None, k=2):
"""
在 text_chunks 中找出与 query 最相关的 top-k 文本块
参数:
query: 查询语句
text_chunks: 候选文本块列表
embeddings: 对应的嵌入向量列表(如果已提前计算)
k: 返回最相关的结果数量
返回:
top_k_chunks: 最相关的 top-k 文本块
"""
if embeddings is None:
embeddings = create_embeddings(text_chunks) # 如果没有提供,则自动生成
else:
assert len(embeddings) == len(text_chunks), "embeddings 和 text_chunks 必须长度一致"
query_embedding = create_embeddings(query)[0] # 获取查询的嵌入
# 计算相似度
similarity_scores = []
for i, chunk_embedding in enumerate(embeddings):
score = cosine_similarity([query_embedding], [chunk_embedding])[0][0]
similarity_scores.append((i, score))
# 排序并取 top-k
similarity_scores.sort(key=lambda x: x[1], reverse=True)
top_indices = [index for index, _ in similarity_scores[:k]]
return [text_chunks[index] for index in top_indices]
最后,执行查询操作,并打印结果。
# 执行语义搜索
query = '通义灵码的智能体能力是什么?'
top_chunks = semantic_search(query, text_chunks, k=2)
# 输出结果
print("Query:", query)
for i, chunk in enumerate(top_chunks):
print(f"Context {i + 1}:\n{chunk}\n=====================================")
2.8 基于检索块生成响应
# 初始化 DashScope 客户端(使用阿里云通义千问)
client = OpenAI(
api_key=os.getenv("DASHSCOPE_API_KEY"), # 确保提前设置好环境变量
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"
)
# 设置系统提示词
SYSTEM_PROMPT = (
"你是一个 AI 助手,必须严格根据提供的上下文内容进行回答。"
"如果无法从提供的上下文中直接得出答案,请回复:'我无法根据现有信息回答这个问题。'"
)
def generate_response(system_prompt, user_message, model="qwen-max"):
"""
使用 DashScope 的通义千问模型生成基于上下文的回答。
参数:
system_prompt (str): 控制 AI 行为的系统指令
user_message (str): 用户输入的问题及上下文
model (str): 使用的模型名称,默认为 qwen-plus
返回:
str: 模型生成的回答内容
"""
response = client.chat.completions.create(
model=model,
temperature=0.0, # 温度设为0,保证输出确定性
max_tokens=512, # 可按需调整最大输出长度
messages=[
{"role": "system", "content": system_prompt},
{"role": "user", "content": user_message}
]
)
return response.choices[0].message.content.strip()
# 示例 top_chunks(假设这是 semantic_search 返回的结果)
top_chunks = [
"通义灵码是一个基于 AI 的智能编程助手。",
"文件编辑能力包括自动补全、错误修复和代码重构等功能。"
]
query = "通义灵码的智能体能力是什么?"
# 构建用户 prompt(包含上下文 + 问题)
user_prompt = "\n".join([f"上下文 {i + 1}:\n{chunk}" for i, chunk in enumerate(top_chunks)])
user_prompt += f"\n\n问题:{query}"
# 生成 AI 回答
answer = generate_response(system_prompt, user_prompt)
# 输出结果
print("AI 回答:")
print(answer)
2.9 评估回答
# 定义评估系统的提示词
evaluate_system_prompt = (
"你是一个智能评估系统,负责评估 AI 助手的回答质量。"
"如果 AI 助手的回答与真实答案非常接近,请打 1 分;"
"如果回答错误或与真实答案不相关,请打 0 分;"
"如果回答部分符合真实答案,请打 0.5 分。"
"请直接输出评分结果:0、0.5 或 1。"
)
#构建评估 prompt 并获取评分
evaluation_prompt = f"""
用户问题: {query}
AI 回答:{answer}
真实答案: {ideal_answer}
请根据以下标准进行评分:
- 如果 AI 回答与真实答案非常接近 → 输出 1
- 如果回答错误或不相关 → 输出 0
- 如果部分匹配 → 输出 0.5
"""
evaluation_result = generate_response(evaluate_system_prompt, evaluation_prompt)
# 输出最终评分
print("AI 回答评分:", evaluation_result)
如何学习大模型 AI ?
由于新岗位的生产效率,要优于被取代岗位的生产效率,所以实际上整个社会的生产效率是提升的。
但是具体到个人,只能说是:
“最先掌握AI的人,将会比较晚掌握AI的人有竞争优势”。
这句话,放在计算机、互联网、移动互联网的开局时期,都是一样的道理。
我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。
我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多互联网行业朋友无法获得正确的资料得到学习提升,故此将并将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。
这份完整版的大模型 AI 学习资料已经上传优快云,朋友们如果需要可以微信扫描下方优快云官方认证二维码免费领取【保证100%免费】


为什么要学习大模型?
我国在A大模型领域面临人才短缺,数量与质量均落后于发达国家。2023年,人才缺口已超百万,凸显培养不足。随着AI技术飞速发展,预计到2025年,这一缺口将急剧扩大至400万,严重制约我国AI产业的创新步伐。加强人才培养,优化教育体系,国际合作并进是破解困局、推动AI发展的关键。


大模型入门到实战全套学习大礼包
1、大模型系统化学习路线
作为学习AI大模型技术的新手,方向至关重要。 正确的学习路线可以为你节省时间,少走弯路;方向不对,努力白费。这里我给大家准备了一份最科学最系统的学习成长路线图和学习规划,带你从零基础入门到精通!

2、大模型学习书籍&文档
学习AI大模型离不开书籍文档,我精选了一系列大模型技术的书籍和学习文档(电子版),它们由领域内的顶尖专家撰写,内容全面、深入、详尽,为你学习大模型提供坚实的理论基础。

3、AI大模型最新行业报告
2025最新行业报告,针对不同行业的现状、趋势、问题、机会等进行系统地调研和评估,以了解哪些行业更适合引入大模型的技术和应用,以及在哪些方面可以发挥大模型的优势。

4、大模型项目实战&配套源码
学以致用,在项目实战中检验和巩固你所学到的知识,同时为你找工作就业和职业发展打下坚实的基础。

5、大模型大厂面试真题
面试不仅是技术的较量,更需要充分的准备。在你已经掌握了大模型技术之后,就需要开始准备面试,我精心整理了一份大模型面试题库,涵盖当前面试中可能遇到的各种技术问题,让你在面试中游刃有余。

适用人群

第一阶段(10天):初阶应用
该阶段让大家对大模型 AI有一个最前沿的认识,对大模型 AI 的理解超过 95% 的人,可以在相关讨论时发表高级、不跟风、又接地气的见解,别人只会和 AI 聊天,而你能调教 AI,并能用代码将大模型和业务衔接。
- 大模型 AI 能干什么?
- 大模型是怎样获得「智能」的?
- 用好 AI 的核心心法
- 大模型应用业务架构
- 大模型应用技术架构
- 代码示例:向 GPT-3.5 灌入新知识
- 提示工程的意义和核心思想
- Prompt 典型构成
- 指令调优方法论
- 思维链和思维树
- Prompt 攻击和防范
- …
第二阶段(30天):高阶应用
该阶段我们正式进入大模型 AI 进阶实战学习,学会构造私有知识库,扩展 AI 的能力。快速开发一个完整的基于 agent 对话机器人。掌握功能最强的大模型开发框架,抓住最新的技术进展,适合 Python 和 JavaScript 程序员。
- 为什么要做 RAG
- 搭建一个简单的 ChatPDF
- 检索的基础概念
- 什么是向量表示(Embeddings)
- 向量数据库与向量检索
- 基于向量检索的 RAG
- 搭建 RAG 系统的扩展知识
- 混合检索与 RAG-Fusion 简介
- 向量模型本地部署
- …
第三阶段(30天):模型训练
恭喜你,如果学到这里,你基本可以找到一份大模型 AI相关的工作,自己也能训练 GPT 了!通过微调,训练自己的垂直大模型,能独立训练开源多模态大模型,掌握更多技术方案。
到此为止,大概2个月的时间。你已经成为了一名“AI小子”。那么你还想往下探索吗?
- 为什么要做 RAG
- 什么是模型
- 什么是模型训练
- 求解器 & 损失函数简介
- 小实验2:手写一个简单的神经网络并训练它
- 什么是训练/预训练/微调/轻量化微调
- Transformer结构简介
- 轻量化微调
- 实验数据集的构建
- …
第四阶段(20天):商业闭环
对全球大模型从性能、吞吐量、成本等方面有一定的认知,可以在云端和本地等多种环境下部署大模型,找到适合自己的项目/创业方向,做一名被 AI 武装的产品经理。
- 硬件选型
- 带你了解全球大模型
- 使用国产大模型服务
- 搭建 OpenAI 代理
- 热身:基于阿里云 PAI 部署 Stable Diffusion
- 在本地计算机运行大模型
- 大模型的私有化部署
- 基于 vLLM 部署大模型
- 案例:如何优雅地在阿里云私有部署开源大模型
- 部署一套开源 LLM 项目
- 内容安全
- 互联网信息服务算法备案
- …
学习是一个过程,只要学习就会有挑战。天道酬勤,你越努力,就会成为越优秀的自己。
如果你能在15天内完成所有的任务,那你堪称天才。然而,如果你能完成 60-70% 的内容,你就已经开始具备成为一名大模型 AI 的正确特征了。
这份完整版的大模型 AI 学习资料已经上传优快云,朋友们如果需要可以微信扫描下方优快云官方认证二维码免费领取【保证100%免费】

893

被折叠的 条评论
为什么被折叠?



