当前位置: 首页 > news >正文

8.构建可维护的RAG系统:代码分层与模块化设计

写在前面

咱们后面的功能将会迈进智能体,在这之前我感觉有必要对以前写的代码进行分层重构,这样当后面项目越来越大的时候,咱们维护代码的时候会很清晰。

第一类:纯工具函数

这里函数有一个特点,不依赖FAISS和Memory机制,能力是通用的也不用self,包括split_textclean_textload_pdfsload_documentsprocess_documents这类函数我们可以不放进类,可以创建一个data_loader.py,然后统统将他们搬进去,这样有一个好处,那就是解耦,这样别的项目也能用,使得这些函数不属于RAG系统本身。

# data_loader.pyimportosfrompypdfimportPdfReaderimportredefsplit_text(text,chunk_size=200,overlap=50):chunks=[]foriinrange(0,len(text),chunk_size-overlap):chunks.append(text[i:i+chunk_size])returnchunksdefclean_text(text):text=re.sub(r'\n+','\n',text)# 多行空白换成一行text=re.sub(r'\s+',' ',text)# 将所有连续空白字符(空格、制表符、换行等)替换成单个空格,实现“规范化空白”。returntextdefload_pdfs(folder_path):documents=[]forfilenameinos.listdir(folder_path):iffilename.endswith(".pdf"):path=os.path.join(folder_path,filename)reader=PdfReader(path)text=""forpageinreader.pages:text+=page.extract_text()or""text=clean_text(text)documents.append({"text":text,"source":filename})returndocumentsdefload_documents(folder_path):documents=[]forfilenameinos.listdir(folder_path):iffilename.endswith(".txt"):withopen(os.path.join(folder_path,filename),"r",encoding="utf-8")asf:text=f.read()documents.append({"text":text,"source":filename})returndocumentsdefprocess_documents(documents):all_chunks=[]fordocindocuments:chunks=split_text(doc["text"],chunk_size=200,overlap=50)forcinchunks:all_chunks.append({"text":c,"source":doc["source"]})returnall_chunks

第二类:模型相关函数

这类函数的特点是需要用到API,但是不依赖于RAG内部的结构,这话有点绕嘴,换一种更好理解的方式来说,这类函数不需要用到类变量但是用到了大模型API,包括:get_embeddingdecide_tool,这些函数我们可以另建一个llm_utils.py函数将他们都存下:

# llm_utils.pyimportnumpyasnpimporttimefromopenaiimportOpenAIimportosfromdotenvimportload_dotenv load_dotenv()client=OpenAI(api_key=os.getenv("DEEPSEEK_API_KEY"),base_url="https://api.deepseek.com")client2=OpenAI(api_key=os.getenv("SHUBIAOBIAO_API_KEY"),base_url="https://api.shubiaobiao.com/v1")defget_embedding(text,max_retries=3):forattemptinrange(max_retries):try:response=client2.embeddings.create(model="text-embedding-3-small",input=text)returnnp.array(response.data[0].embedding,dtype="float32")exceptExceptionase:print(f"Embedding失败,第{attempt+1}次重试...")time.sleep(2)print("Embedding最终失败,返回零向量")returnnp.zeros(1536,dtype="float32")# embedding维度defdecide_tool(query):prompt=f""" You are an AI assistant. Decide whether the following question needs document retrieval. Question:{query}Answer ONLY: - "RAG" if it needs document-based answer - "LLM" if it can be answered directly """response=client.chat.completions.create(model="deepseek-chat",messages=[{"role":"user","content":prompt}])returnresponse.choices[0].message.content.strip()

不知道你们注意到没有,我这回在调用API_KEY的时候和以往的方式不太一样,我是用了这种方式os.getenv("DEEPSEEK_API_KEY"),为什么能这样用呢?其实目的是为了更好的管理项目的API,我们用到了一个管理工具dotenv,使用这个工具前需要安装依赖

pip install dotenv

安装完成后,在根目录下创建一个.env的文件,然后将你的API_KEY像这样都写进去:

DEEPSEEK_API_KEY=xxxxxxxxxxxxxxxxxxxxxxxx SHUBIAOBIAO_API_KEY=xxxxxxxxxxxxxxxxxxxxx

这样在需要使用的地方用:

fromdotenvimportload_dotenv load_dotenv()

就能加载我们的API_KEY了,这样还有一个好处,还可以避免我们的项目中有大量用到API的地方暴露我们的API_KEY。

所以最终我们整理好的项目就会像这样,项目分层后,咱们就可以正式迈入后面的智能体开发了:

RagAgent/ │ ├── app.py # FastAPI入口 ├── rag_system.py # RAG核心类 ├── llm_utils.py # embedding / decide_tool ├── data_loader.py # PDF / 文本处理 └── data/ # 你的论文

如果这篇文章对你有帮助,可以点个赞~
完整代码地址:https://github.com/1186141415/A-Paper-Rag-Agent

http://www.jsqmd.com/news/605399/

相关文章:

  • React 组件和 Hook 必须是幂等的
  • seo优化软件入门知识_seo优化软件如何配置
  • OpenClaw:2026年最火个人AI助手,让AI真正帮你干活!
  • macOS下OpenClaw安装全攻略:百川2-13B-4bits量化版对接
  • 【Agentic API 实战】02 重新定义动作:掌握 ACTION 接口分类法
  • 文件夹变应用程序?数据恢复方法来了
  • FramePack实战指南:从零开始构建高效视频扩散工作流
  • 2000行代码实现教学级RISC-V操作系统解析
  • Lombok注解底层原理
  • 告别SRResNet:手把手教你复现NTIRE2017冠军模型EDSR(附PyTorch代码与BN层移除详解)
  • ESP32摄像头+MicroPython实战:5分钟搭建无线人脸检测系统(附完整代码)
  • OpenClaw资源监控:千问3.5-9B实现的系统健康报告
  • 网站seo排名工具有哪些
  • OpenClaw+Qwen3.5-9B科研助手:文献综述与实验设计自动化
  • 丹青识画部署教程:私有化部署中SSL证书与水墨UI HTTPS适配
  • AI Agent爆了!掌握MCP+Skill,2026年23%企业都在用的智能决策黑科技
  • 跨平台实战:Windows与Mac下OpenClaw对接百川2-13B-4bits差异详解
  • 5分钟体验OpenClaw:基于Qwen3.5-9B镜像的云端沙盒部署
  • iPad Mini2降级iOS 10.3.3避坑指南:从固件下载到iCloud绕过(A7芯片专用)
  • java-从零打造学生管理系统
  • OpenClaw安全加固:百川2-13B模型API的权限控制实践
  • BEV模型训练不再难:星图AI平台+PETRV2,新手友好教程
  • 易语言手游中控框架源码|逍遥模拟器专用模板
  • 从CTFT到FFT:六种傅里叶变换的演进与应用全景
  • 华为推送报错6003?手把手教你排查证书指纹不匹配问题(附详细日志抓取步骤)
  • 2026年不干胶复卷机梯队盘点:半自动模切分条复卷机、复卷机设备、无胶复卷机、标签复卷机、物流标签设备、空白标签设备选择指南 - 优质品牌商家
  • 用GD32F103C8T6的PWM驱动舵机:从接线到代码的保姆级教程(附源码)
  • 倩女幽魂手游全自动24小时系统|雷电模拟器多线程中控+自动倒米交易+智能喊话器(含易语言源码)
  • 紧急预警!银河麒麟文件剪切后数据“人间蒸发”?别慌,用数安寻3秒火速救援!
  • OpenClaw轻量部署:Qwen3-4B在树莓派上的优化运行