为了更深入理解RAG原理,便于调优,这次我们用纯代码,从零开始完成一次RAG探秘之旅。
老规矩,先看最终效果。
我选取了“信贷业务手册.docx”文档作为本地知识库语料,500页,40万字。
在提问后,大模型调用本地知识库进行思考,输出结果还不错。
实现上述效果,基本可分为这几步:
- 处理本地知识库文本
- 完成文本分块、向量化和存储
- 构建RAG版chat
- 增加一个前端页面用于展示
以上步骤我后面会详细展开,在此之前,应大家的私信请求,先带大家了解RAG的原理。
这是落地实现和调优的依据和关键!
一、重要补充
1、RAG的原理
RAG是用本地知识库做补充,让最终的答案能更个性化、更有针对性。
整个过程分为建立索引和检索生成两个大的阶段,具体原理如下:
阶段一:建立索引
1)读取本地知识库文本,包括pdf、doc、ppt、excel、txt、md等;
2)将文本分割成不同的块(trunk),包括Split by Sentences、fix character count、overlapping window、RescursiveCharacterTextSpiltter等方法;
3)将切好的文本块转换成向量;
4)将向量存储到向量数据库,以便后续使用
阶段二:检索生成
1)将用户的Prompt转换成向量
2)将用户提示词向量与向量数据库中的向量做相似度匹配,找到相似的内容
3)把检索出来的相似内容和用户的问题拼接在一起,作为新的Prompt,给到大模型
4)大模型根据新的Prompt进行回答,相当于本地知识库中检索出来的内容将作为上下文供大模型参考
总结下来,RAG的整体运作流程如下:
2、RAG的调优策略
根据RAG原理,不难发现:如果想要获得高质量的、精准的答案,每一个环境都需要做好调优,才能达到最佳效果。
第一,索引建立阶段的调优
1)原始知识库文本的质量提升,包括数据清洗和标准化
2)文本分割成不同的块,分块策略的优化
3)将切好的文本块转换成向量,embbeding模型的调优
4)文本元数据的增强,比如更新时间,方便检索到最新版本
第二,检索阶段的调优
1)使用混合检索策略,比如向量+关键字
2)查询语言转写,相当于对用户的提示词进行治理
3)对向量数据库进行重排序(rerank)
第三,生成阶段的调优
1)优化提示词,比如增加系统提示词,做好限制
2)生成内容控制,比如对llm做微调
3)幻觉抑制,比如设置相似度的置信区间
其他
1)比如使用多模态的Embedding模型,支持图片、表格等非文本数据检索
2)增加评估模块,自动识别无效检索,并调用补充搜索
好了,知道了原理,就开始一步步建立成自己的RAG吧。
二、实现过程
1、环境准备
安装python3.10+以上版本
安装依赖包,可以放在requirements.txt中,通过pip install -r requirements.txt 命令安装
langchain openai faiss-cpu flask unstructured[all-docs] sentence-transformers3) 新建python工程,工程目录如下
RAGChat/ ├── config.json ├── data/ │ └── # 存放导入的文本文件 ├── app.py ├── utils/ │ ├── data_loader.py │ ├── text_splitter.py │ └── embedding.py ├── chatbot/ │ ├── rag_chatbot.py └── frontend/ ├── app.py └── templates/ └── chat.html2、配置文件,confg.json,填写好自己的url、model和apikey
{ "llm": { "default": "deepseek", "models": { "deepseek": { "url": "your_deepseek_url", "model": "your_deepseek_model", "apikey": "your_deepseek_apikey" }, "other_model": { "url": "your_other_model_url", "model": "your_other_model", "apikey": "your_other_model_apikey" } } }, "embedding": { "default": "bge-large-zh-v1.5", "models": { "bge-large-zh-v1.5": { "url": "your_bge_url", "model": "BAAI/bge-large-zh-v1.5", "apikey": "" }, "other_embedding_model": { "url": "your_other_embedding_url", "model": "your_other_embedding_model", "apikey": "your_other_embedding_apikey" } } } }3、处理本地知识库文本
1)删除空白页
2)去除图片,如果图片里有文字,OCR为文字
(因为开源免费的embedding模型就那几个,不支持多模态)
3)word文档转markdown格式
(这样对大模型更友好,转换工具参考AI辅助工具:各种文档转Markdown)
(转换前)
(转换后)
4、文本分块、向量化和存储
1)本地知识库文本,要放到“data/”目录
2)核心代码
- 加载文本:langchain.document_loaders.load_documents
- 文本分块:langchain.document_loaders.RecursiveCharacterTextSplitter(递归)
- 文本向量化:HuggingFaceEmbeddings
- 存储向量:FAISS.from_documents
执行结果
以下为详细代码,如果比较熟悉,可忽略,直接到第5点。
文本加载代码 data_loader.py
import os from langchain.document_loaders import PyPDFLoader, UnstructuredMarkdownLoader, UnstructuredWordDocumentLoader, \ UnstructuredPowerPointLoader, UnstructuredExcelLoader, TextLoader def load_documents(data_dir): if not os.path.exists(data_dir): print(f"数据目录 {data_dir} 不存在,请检查路径。") return [] documents = [] # 遍历数据目录下的所有文件 for root, dirs, files in os.walk(data_dir): for file in files: file_path = os.path.join(root, file) try: if file.endswith('.txt'): loader = TextLoader(file_path, encoding='utf-8') elif file.endswith('.pdf'): loader = PyPDFLoader(file_path) elif file.endswith('.md'): loader = UnstructuredMarkdownLoader(file_path) elif file.endswith(('.doc', '.docx')): loader = UnstructuredWordDocumentLoader(file_path) elif file.endswith(('.ppt', '.pptx')): loader = UnstructuredPowerPointLoader(file_path) elif file.endswith(('.xls', '.xlsx')): loader = UnstructuredExcelLoader(file_path) else: print(f"不支持的文件类型: {file_path},跳过该文件") continue loaded_docs = loader.load() documents.extend(loaded_docs) print(f"成功加载文件: {file_path}") except Exception as e: print(f"加载文件 {file_path} 失败: {e}") return documents文本分割代码 text_splitter.py
from langchain.text_splitter import RecursiveCharacterTextSplitter def split_text(documents): text_splitter = RecursiveCharacterTextSplitter( chunk_size=1000, chunk_overlap=200, length_function=len ) texts = text_splitter.split_documents(documents) return texts from langchain.text_splitter import CharacterTextSplitter def split_text(documents): if not documents: print("输入的文档列表为空,无法进行分割。") return [] text_splitter = CharacterTextSplitter( separator="\n", chunk_size=1000, chunk_overlap=200, length_function=len ) texts = text_splitter.split_documents(documents) print(f"成功分割出 {len(texts)} 个文本块。") return texts文本向量化代码 embedding.py
import json from langchain.embeddings import HuggingFaceEmbeddings def get_embeddings(): with open('config.json', 'r') as f: config = json.load(f) embedding_config = config['embedding']['models'][config['embedding']['default']] model_name = embedding_config['model'] # 如果不能科学上网,可以使用本地模型初始化嵌入 embeddings = HuggingFaceEmbeddings(model_name=model_name) # Test embedding generation test_text = "This is a test sentence." try: test_embedding = embeddings.embed_query(test_text) print(f"Test embedding length: {len(test_embedding)}") except Exception as e: print(f"Error generating test embedding: {e}") return embeddings5、构建RAG版chat
1)先明确流程
在客户输入问题之后,调用大模型之前,先进行本地知识库向量查询,拼接查询结果+历史聊天记录+客户问题=>形成新的提示词,再丢给大模型
2)核心代码:
加载向量:FAISS.load_local
初始化大模型:langchain_openai.ChatOpenAI
检索并生成:RetrievalQA.from_chain_type
以下为RAG聊天机器人核心代码 rag_chatbot.py
import json import os from langchain.vectorstores import FAISS from langchain.chains import RetrievalQA from langchain_openai import ChatOpenAI from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler from utils.data_loader import load_documents from utils.text_splitter import split_text from utils.embedding import get_embeddings class RAGChatbot: def __init__(self, data_dir='data', vectorstore_path='vectorstore'): self.data_dir = data_dir self.vectorstore_path = vectorstore_path self.embeddings = get_embeddings() if os.path.exists(self.vectorstore_path): try: self.vectorstore = FAISS.load_local( self.vectorstore_path, self.embeddings, allow_dangerous_deserialization=True ) print("Successfully loaded vector store from local") except Exception as e: print(f"Failed to load local vector store: {e}, will recreate") self.documents = load_documents(self.data_dir) self.texts = split_text(self.documents) if not self.texts: print("Warning: 'self.texts' list is empty. Please check document loading and splitting.") return self.vectorstore = FAISS.from_documents(self.texts, self.embeddings) self.vectorstore.save_local(self.vectorstore_path) else: self.documents = load_documents(self.data_dir) self.texts = split_text(self.documents) if not self.texts: print("Warning: 'self.texts' list is empty. Please check document loading and splitting.") return self.vectorstore = FAISS.from_documents(self.texts, self.embeddings) self.vectorstore.save_local(self.vectorstore_path) self.qa = self._init_qa_chain() def _init_qa_chain(self): with open('config.json', 'r') as f: config = json.load(f) llm_config = config['llm']['models'][config['llm']['default']] api_key = llm_config.get('apikey') model = llm_config.get('model') temperature = llm_config.get('model_kwargs', {}).get('temperature', 0.7) max_tokens = llm_config.get('model_kwargs', {}).get('max_length', 512) # 添加 StreamingStdOutCallbackHandler 以支持流式输出 llm = ChatOpenAI( base_url=llm_config.get('url'), api_key=api_key, model=model, temperature=temperature, max_tokens=max_tokens, streaming=True, # 这里先移除默认的回调,后面在 ask_stream 中自定义 callbacks=[] ) retriever = self.vectorstore.as_retriever() qa = RetrievalQA.from_chain_type( llm=llm, chain_type="stuff", retriever=retriever ) # 保存 llm 实例到类属性 self.llm = llm return qa def ask_stream(self, question, history): context = "" for item in history: if item['role'] == 'user': context += f"User: {item['content']}\n" elif item['role'] == 'bot': context += f"Bot: {item['content']}\n" context += f"User: {question}\nBot: " class CustomCallbackHandler(StreamingStdOutCallbackHandler): def __init__(self): super().__init__() def on_llm_new_token(self, token: str, **kwargs) -> None: print(f"Received token: {token}") yield token callback_handler = CustomCallbackHandler() try: response = self.qa.stream( {"query": context}, callbacks=[callback_handler] ) for chunk in response: print(f"Received chunk: {chunk}",flush=True) if 'result' in chunk: answer_chunk = chunk['result'] for char in answer_chunk: yield char except Exception as e: print(f"ask_stream 方法出现异常: {e}") yield str(e)6、最后一步,增加一个前端,then have fun
使用flask框架,新增一个前端,支持流式输出和多轮对话。
前端代码包括app.py和chat.html,代码太长,不便附在文中,需要者关注公众号获取。
注意事项
- 工程的目录结构要和上面的保持一致
2)记得在config.json里面配置好自己的apikey
3)启动服务:在工程根目录,执行 python .\frontend\app.py
4)启动之后,通过页面http://localhost:5000进行访问
根目录的app.py是不带前端的版本,提问通过cmd终端发起,前期调试程序的时候可以用。调通之后,可以删除。
最后吐槽一下,用langchain调用国产大模型。以及调试流式生成,真的是废了老鼻子劲了!强烈建议使用llama_index,会方便很多。
想入门 AI 大模型却找不到清晰方向?备考大厂 AI 岗还在四处搜集零散资料?别再浪费时间啦!2025 年AI 大模型全套学习资料已整理完毕,从学习路线到面试真题,从工具教程到行业报告,一站式覆盖你的所有需求,现在全部免费分享!
👇👇扫码免费领取全部内容👇👇
一、学习必备:100+本大模型电子书+26 份行业报告 + 600+ 套技术PPT,帮你看透 AI 趋势
想了解大模型的行业动态、商业落地案例?大模型电子书?这份资料帮你站在 “行业高度” 学 AI:
1. 100+本大模型方向电子书
2. 26 份行业研究报告:覆盖多领域实践与趋势
报告包含阿里、DeepSeek 等权威机构发布的核心内容,涵盖:
- 职业趋势:《AI + 职业趋势报告》《中国 AI 人才粮仓模型解析》;
- 商业落地:《生成式 AI 商业落地白皮书》《AI Agent 应用落地技术白皮书》;
- 领域细分:《AGI 在金融领域的应用报告》《AI GC 实践案例集》;
- 行业监测:《2024 年中国大模型季度监测报告》《2025 年中国技术市场发展趋势》。
3. 600+套技术大会 PPT:听行业大咖讲实战
PPT 整理自 2024-2025 年热门技术大会,包含百度、腾讯、字节等企业的一线实践:
- 安全方向:《端侧大模型的安全建设》《大模型驱动安全升级(腾讯代码安全实践)》;
- 产品与创新:《大模型产品如何创新与创收》《AI 时代的新范式:构建 AI 产品》;
- 多模态与 Agent:《Step-Video 开源模型(视频生成进展)》《Agentic RAG 的现在与未来》;
- 工程落地:《从原型到生产:AgentOps 加速字节 AI 应用落地》《智能代码助手 CodeFuse 的架构设计》。
二、求职必看:大厂 AI 岗面试 “弹药库”,300 + 真题 + 107 道面经直接抱走
想冲字节、腾讯、阿里、蔚来等大厂 AI 岗?这份面试资料帮你提前 “押题”,拒绝临场慌!
1. 107 道大厂面经:覆盖 Prompt、RAG、大模型应用工程师等热门岗位
面经整理自 2021-2025 年真实面试场景,包含 TPlink、字节、腾讯、蔚来、虾皮、中兴、科大讯飞、京东等企业的高频考题,每道题都附带思路解析:
2. 102 道 AI 大模型真题:直击大模型核心考点
针对大模型专属考题,从概念到实践全面覆盖,帮你理清底层逻辑:
3. 97 道 LLMs 真题:聚焦大型语言模型高频问题
专门拆解 LLMs 的核心痛点与解决方案,比如让很多人头疼的 “复读机问题”:
![]()
三、路线必明: AI 大模型学习路线图,1 张图理清核心内容
刚接触 AI 大模型,不知道该从哪学起?这份「AI大模型 学习路线图」直接帮你划重点,不用再盲目摸索!
路线图涵盖 5 大核心板块,从基础到进阶层层递进:一步步带你从入门到进阶,从理论到实战。
L1阶段:启航篇丨极速破界AI新时代
L1阶段:了解大模型的基础知识,以及大模型在各个行业的应用和分析,学习理解大模型的核心原理、关键技术以及大模型应用场景。
L2阶段:攻坚篇丨RAG开发实战工坊
L2阶段:AI大模型RAG应用开发工程,主要学习RAG检索增强生成:包括Naive RAG、Advanced-RAG以及RAG性能评估,还有GraphRAG在内的多个RAG热门项目的分析。
L3阶段:跃迁篇丨Agent智能体架构设计
L3阶段:大模型Agent应用架构进阶实现,主要学习LangChain、 LIamaIndex框架,也会学习到AutoGPT、 MetaGPT等多Agent系统,打造Agent智能体。
L4阶段:精进篇丨模型微调与私有化部署
L4阶段:大模型的微调和私有化部署,更加深入的探讨Transformer架构,学习大模型的微调技术,利用DeepSpeed、Lamam Factory等工具快速进行模型微调,并通过Ollama、vLLM等推理部署框架,实现模型的快速部署。
L5阶段:专题集丨特训篇 【录播课】
![]()
四、资料领取:全套内容免费抱走,学 AI 不用再找第二份
不管你是 0 基础想入门 AI 大模型,还是有基础想冲刺大厂、了解行业趋势,这份资料都能满足你!
现在只需按照提示操作,就能免费领取:
👇👇扫码免费领取全部内容👇👇
2025 年想抓住 AI 大模型的风口?别犹豫,这份免费资料就是你的 “起跑线”!
想入门 AI 大模型却找不到清晰方向?备考大厂 AI 岗还在四处搜集零散资料?别再浪费时间啦!2025 年AI 大模型全套学习资料已整理完毕,从学习路线到面试真题,从工具教程到行业报告,一站式覆盖你的所有需求,现在全部免费分享!
👇👇扫码免费领取全部内容👇👇
一、学习必备:100+本大模型电子书+26 份行业报告 + 600+ 套技术PPT,帮你看透 AI 趋势
想了解大模型的行业动态、商业落地案例?大模型电子书?这份资料帮你站在 “行业高度” 学 AI:
1. 100+本大模型方向电子书
2. 26 份行业研究报告:覆盖多领域实践与趋势
报告包含阿里、DeepSeek 等权威机构发布的核心内容,涵盖:
- 职业趋势:《AI + 职业趋势报告》《中国 AI 人才粮仓模型解析》;
- 商业落地:《生成式 AI 商业落地白皮书》《AI Agent 应用落地技术白皮书》;
- 领域细分:《AGI 在金融领域的应用报告》《AI GC 实践案例集》;
- 行业监测:《2024 年中国大模型季度监测报告》《2025 年中国技术市场发展趋势》。
3. 600+套技术大会 PPT:听行业大咖讲实战
PPT 整理自 2024-2025 年热门技术大会,包含百度、腾讯、字节等企业的一线实践:
- 安全方向:《端侧大模型的安全建设》《大模型驱动安全升级(腾讯代码安全实践)》;
- 产品与创新:《大模型产品如何创新与创收》《AI 时代的新范式:构建 AI 产品》;
- 多模态与 Agent:《Step-Video 开源模型(视频生成进展)》《Agentic RAG 的现在与未来》;
- 工程落地:《从原型到生产:AgentOps 加速字节 AI 应用落地》《智能代码助手 CodeFuse 的架构设计》。
二、求职必看:大厂 AI 岗面试 “弹药库”,300 + 真题 + 107 道面经直接抱走
想冲字节、腾讯、阿里、蔚来等大厂 AI 岗?这份面试资料帮你提前 “押题”,拒绝临场慌!
1. 107 道大厂面经:覆盖 Prompt、RAG、大模型应用工程师等热门岗位
面经整理自 2021-2025 年真实面试场景,包含 TPlink、字节、腾讯、蔚来、虾皮、中兴、科大讯飞、京东等企业的高频考题,每道题都附带思路解析:
2. 102 道 AI 大模型真题:直击大模型核心考点
针对大模型专属考题,从概念到实践全面覆盖,帮你理清底层逻辑:
3. 97 道 LLMs 真题:聚焦大型语言模型高频问题
专门拆解 LLMs 的核心痛点与解决方案,比如让很多人头疼的 “复读机问题”:
![]()
三、路线必明: AI 大模型学习路线图,1 张图理清核心内容
刚接触 AI 大模型,不知道该从哪学起?这份「AI大模型 学习路线图」直接帮你划重点,不用再盲目摸索!
路线图涵盖 5 大核心板块,从基础到进阶层层递进:一步步带你从入门到进阶,从理论到实战。
L1阶段:启航篇丨极速破界AI新时代
L1阶段:了解大模型的基础知识,以及大模型在各个行业的应用和分析,学习理解大模型的核心原理、关键技术以及大模型应用场景。
L2阶段:攻坚篇丨RAG开发实战工坊
L2阶段:AI大模型RAG应用开发工程,主要学习RAG检索增强生成:包括Naive RAG、Advanced-RAG以及RAG性能评估,还有GraphRAG在内的多个RAG热门项目的分析。
L3阶段:跃迁篇丨Agent智能体架构设计
L3阶段:大模型Agent应用架构进阶实现,主要学习LangChain、 LIamaIndex框架,也会学习到AutoGPT、 MetaGPT等多Agent系统,打造Agent智能体。
L4阶段:精进篇丨模型微调与私有化部署
L4阶段:大模型的微调和私有化部署,更加深入的探讨Transformer架构,学习大模型的微调技术,利用DeepSpeed、Lamam Factory等工具快速进行模型微调,并通过Ollama、vLLM等推理部署框架,实现模型的快速部署。
L5阶段:专题集丨特训篇 【录播课】
![]()
四、资料领取:全套内容免费抱走,学 AI 不用再找第二份
不管你是 0 基础想入门 AI 大模型,还是有基础想冲刺大厂、了解行业趋势,这份资料都能满足你!
现在只需按照提示操作,就能免费领取:
👇👇扫码免费领取全部内容👇👇
2025 年想抓住 AI 大模型的风口?别犹豫,这份免费资料就是你的 “起跑线”!