1. RAG 核心架构与技术栈
1. 基础架构
用户查询 → 检索模块(Retriever)→ 生成模块(Generator)→ 结果输出
↳ 向量/语义检索 ↳ 大模型生成
↳ 文档/知识库 ↳ 答案整合
2. 关键技术栈
模块 | 工具 / 技术 | 说明 |
---|---|---|
数据处理 | Python(Pandas/Spacy) | 文档清洗、分块、元数据提取 |
向量存储 | FAISS/Chromadb/Milvus/Elasticsearch | 高效向量检索引擎 |
检索模块 | LangChain/RetrievalQA | 检索逻辑封装(BM25 + 向量混合检索) |
生成模型 | LLaMA/LLaMA2/OpenAI/GPT4 | 主流大模型选择 |
集成框架 | LangChain/FastAPI | 模块化集成与 API 服务化 |
评估工具 | GPT4Eval / 人工评测表 | 答案相关性、完整性评估 |
2. 技术框架与工具选型
- 核心框架:
- LangChain:用于构建LLM应用的统一框架,支持模型调用、任务链管理、工具集成。
- 文档处理:
- pypdf:解析PDF文档,提取文本内容。
- RecursiveCharacterTextSplitter:按自然段落分割文本(块大小512字符,重叠128字符)。
- 向量化与检索:
- bge-small-zh-v1.5:中文向量模型(维度512,支持归一化)。
- Faiss:高效的向量相似度检索库(基于余弦相似度)。
- 生成模型:
- 通义千问Qwen:阿里云大模型(免费额度1,000,000 token),用于生成最终回答。
3. 开发环境配置
- Python环境:
- 版本≥3.8,推荐使用虚拟环境隔离依赖(
python3 -m venv rag_env
)。
- 版本≥3.8,推荐使用虚拟环境隔离依赖(
- 依赖库安装:
pip install langchain pypdf sentence-transformers faiss-cpu dashscope
- 模型与数据:
- 下载预训练的bge-small-zh-v1.5模型(Gitee仓库提供)。
- 准备测试PDF文档(如
test_lesson2.pdf
)。
4. 核心流程实现
1. 索引流程(Indexing):
- PDF解析:使用
PyPDFLoader
提取文本。 - 文本分块:按字符分割(非Token),保留上下文连贯性。
- 向量化:将文本块编码为归一化向量,存入Faiss索引。
- 代码关键函数:
indexing_process()
。
2. 检索流程(Retrieval):
- 查询向量化:将用户问题编码为向量。
- 相似度匹配:在Faiss中检索Top-K相似文本块。
- 代码关键函数:
retrieval_process()
。
3. 生成流程(Generation):
- Prompt构建:结合用户查询与检索到的文本块生成提示词。
- 大模型调用:通过阿里云API调用Qwen生成最终回答(流式输出)。
- 代码关键函数:
generate_process()
。
4. 测试脚本:
- 整合索引、检索、生成流程,支持命令行运行。
- 示例输出展示完整的问答过程。
5. 关键代码片段
1.索引流程
# 加载PDF并分块
pdf_loader = PyPDFLoader(pdf_file, extract_images=False)
text_splitter = RecursiveCharacterTextSplitter(chunk_size=512, chunk_overlap=128)
chunks = text_splitter.split_text(pdf_text)
# 向量化并存储到Faiss
embeddings = [embedding_model.encode(chunk, normalize_embeddings=True) for chunk in chunks]
index = faiss.IndexFlatIP(embeddings_np.shape[1])
index.add(embeddings_np)
2.检索流程(Retrieval)
# 将查询转化为嵌入向量,normalize_embeddings表示对嵌入向量进行归一化
query_embedding = embedding_model.encode(query, normalize_embeddings=True)
# 将嵌入向量转化为numpy数组,Faiss索引操作需要numpy数组输入
query_embedding = np.array([query_embedding])
# 在 Faiss 索引中使用 query_embedding 进行搜索,检索出最相似的前 top_k 个结果。
# 返回查询向量与每个返回结果之间的相似度得分(在使用余弦相似度时,值越大越相似)排名列表distances,最相似的 top_k 个文本块在原始 chunks 列表中的索引indices。
distances, indices = index.search(query_embedding, top_k)
3.生成流程
# 构建Prompt
context = "\n".join([f"参考文档{i+1}:\n{chunk}" for i, chunk in enumerate(chunks)])
prompt = f"根据参考文档回答问题:{query}\n\n{context}"
# 调用Qwen生成回答
responses = dashscope.Generation.call(model=llm_model, messages=messages, stream=True)
4.测试脚本
query="下面报告中涉及了哪几个行业的案例以及总结各自面临的挑战?"
embedding_model = load_embedding_model()
# 索引流程:加载PDF文件,分割文本块,计算嵌入向量,存储在FAISS向量库中(内存)
index, chunks = indexing_process('rag_app/test_lesson2.pdf', embedding_model)
# 检索流程:将用户查询转化为嵌入向量,检索最相似的文本块
retrieval_chunks = retrieval_process(query, index, chunks, embedding_model)
# 生成流程:调用Qwen大模型生成响应
generate_process(query, retrieval_chunks)
6. 实际应用注意事项
- API密钥配置:需从阿里云百炼平台获取Qwen的API密钥。
- 性能优化方向:
- 持久化存储:Faiss索引持久化,避免重复构建。
- 多文档支持:扩展处理多PDF或动态数据源。
- 混合检索:结合关键词检索与向量检索提升精度。
- 扩展组件:
- 上下文管理:支持多轮对话连贯性。
- 隐私保护:敏感信息脱敏处理。
- 知识图谱集成:增强语义推理能力。
7.总结
本文详细演示了基于LangChain的RAG应用快速搭建流程,涵盖PDF解析→文本分块→向量化→检索→生成全链路,并提供了可复用的代码模板。开发者可通过调整技术选型(如替换向量模型、数据库)和扩展功能(如多模态支持、实时数据同步),进一步优化应用场景适配性。