RAG智能问答系统运维开发实操笔记
日常运维开发过程中,梳理RAG智能问答系统的实操细节、问题排查及优化思路,记录每一步实操心得,既是对运维开发工作的复盘,也是个人技术积累的沉淀,全程围绕实际项目代码展开,聚焦运维业务场景下的落地与优化,不堆砌理论,以实操为主。
一、系统基础概述(运维开发前置认知)
本次实操的RAG智能问答系统,基于通义千问Qwen大模型、LangChain框架构建,核心用于本地文档(Word、PDF、TXT)的智能检索与问答,适配日常运维场景中“快速查询文档关键信息”的需求。系统整体流程清晰,分为8个核心模块,运维开发过程中,重点关注各模块的稳定性、可用性及可优化点,以下结合实操代码,记录每一步的运维开发细节与心得。
二、核心代码实操记录(运维开发基准)
系统所有运维开发操作均围绕以下核心代码展开,每一步均结合运维场景标注关注点,便于后续复用、排查问题,实操过程中已验证代码可正常运行,重点记录代码对应的运维开发要点:
python # 1.模型准备(运维开发重点:API密钥管理、模型调用稳定性,是系统运行的基础) DASHSCOPE_API_KEY = "***" from langchain_community.llms import Tongyi # 大模型(运维开发关注点:参数调整、版本兼容性,直接影响问答效果与稳定性) llm = Tongyi(model_name='qwen-max', dashscope_api_key=DASHSCOPE_API_KEY, temperature=1) #print(llm) # 运维调试常用:开启可验证模型初始化是否成功,快速定位启动异常 # 向量化模型(运维开发关注点:响应速度、可用性,直接决定检索效率) from langchain_community.embeddings import DashScopeEmbeddings embeddings = DashScopeEmbeddings(dashscope_api_key=DASHSCOPE_API_KEY, model='text-embedding-v2')
# 2. 文献读取(运维开发重点:文档路径有效性、格式兼容性,是用户使用的基础) from langchain_community.document_loaders import PyPDFLoader,Docx2txtLoader,TextLoader loader = Docx2txtLoader('C:/Users/shi/Desktop/damoxingdata/git_and_gitlab_install.docx') #print(loader) # 调试用:排查路径错误、加载器异常 documents = loader.load() #print(documents) # 调试用:验证文档加载完整性,避免预处理环节出错
# 3.文档预处理(运维开发重点:数据清洗效果,直接影响检索精度,减少后续运维成本) import re documents[0].page_content = re.sub('\n{2,}', '\n', documents[0].page_content) documents[0].page_content = re.sub('\t', '', documents[0].page_content)
# 4. 文档拆分(运维开发重点:参数优化,平衡检索速度与语义连贯性,适配不同文档长度) from langchain.text_splitter import RecursiveCharacterTextSplitter,CharacterTextSplitter # 实例化切分器(运维开发中可根据文档类型调整参数) text_spliter = RecursiveCharacterTextSplitter(chunk_size=1024, chunk_overlap=50) # 切分后的文档(关注点:避免语义断裂,减少检索漏项) chunk_documents = text_spliter.split_documents(documents) #print(chunk_documents)
# 5.向量化和存储(运维开发重点:存储方式选择、容量监控,避免数据丢失) from langchain_community.vectorstores import Qdrant vectorstore = Qdrant.from_documents( documents=chunk_documents, # 切分后的文档 embedding=embeddings, # 词嵌入模型 location=':memory:', # 本地存储(运维可改为持久化路径,避免重启丢失数据) collection_name='docx' # 存储的名称,便于多文档区分管理 )
# 6.检索器(运维开发重点:检索精度、响应速度,直接影响用户体验) retriever = vectorstore.as_retriever(search_type='mmr', search_kwargs={'k':5}) # print(retriever)
# 7. 构建RAG(运维开发重点:链路稳定性,避免断连,降低故障排查成本) template = '''基于以下的文档回答问题:{context}。 回答的时候只能用中文。如果你找不到答案,那就回答:"对不起,我没有找到相关的知识"。 我的问题是:{question} ''' from langchain_core.prompts import ChatPromptTemplate # 构建提示词(运维关注点:模板完整性,避免生成无关回答,减少用户投诉) prompt = ChatPromptTemplate.from_template(template) # 输出解析器(运维关注点:解析异常排查,确保输出格式规范) from langchain_core.output_parsers import StrOutputParser output_parser = StrOutputParser()
# 构建链(运维开发重点:链路串联,便于后续故障定位、模块替换) def format_docs(docs): return '\n\n'.join([i.page_content for i in docs])
from langchain_core.runnables import RunnablePassthrough chain = ({'context': retriever | format_docs , 'question':RunnablePassthrough() } | prompt | llm | output_parser)
# 8. 阅读问答应用(运维开发重点:可用性测试,验证系统实际效果,提前发现问题) print(chain.invoke('git怎么安装?')) |
验证
![1774839236835_03F93796-95BB-41f9-996D-516B3E27E743]()
三、实操心得与运维开发思考(个人沉淀)
3.1 各模块运维开发重点与实操心得
结合上述代码实操,每一个模块的开发与运维都有明确的侧重点,实操过程中积累了1.文档预处理与拆分模块
这两个模块直接影响检索精度,实操中初始设置的chunk_size=1024、chunk_overlap=50,在处理长文档时出现语义断裂,导致检索结果不连贯,后续通过多次调试,根据文档平均长度,将chunk_size调整为800、chunk_overlap调整为100,平衡了检索速度与语义连贯性。同时,预处理环节新增了特殊符号过滤逻辑,解决了部分文档因特殊字符导致的预处理失败问题,提升了系统稳定性。
运维开发中,这类参数优化需要结合实际使用场景,不能照搬默认配置,后续计划新增参数自适应功能,根据文档类型自动调整拆分参数,进一步减少人工运维成本。
2. 向量化与存储模块
初始采用内存存储(location=':memory:'),适合测试环境,但生产环境中存在重启后数据丢失的问题,后续将存储路径改为本地持久化存储(./qdrant_db),并新增数据自动备份流程(每日凌晨备份),避免数据丢失。同时,向量库的容量监控也很重要,实操中曾出现容量溢出导致系统卡顿,后续新增容量阈值告警,当容量达到80%时触发提醒,及时清理无效数据,保障系统流畅运行。
3. 检索器与RAG链路模块
检索器的k值设置的是5,实操中发现,k值过大导致检索速度变慢,k值过小则容易遗漏相关内容,经过多次测试,确定k=5为最优值,兼顾速度与精度。RAG链路的稳定性是运维重点,曾出现链路断连的情况,排查后发现是format_docs函数调用异常,后续优化了函数逻辑,新增异常捕获机制,当链路出现问题时,自动重启链路并记录日志,便于后续排查原因,降低故障处理时间。
提示词模板的完整性也很关键,实操中曾因模板缺失部分约束,导致大模型生成无关回答,后续完善模板逻辑,明确回答规范,减少了用户投诉,也降低了运维工作量。
6. 问答应用模块
日常运维中,需定期测试系统可用性,每天随机输入2-3个常见问题(如代码中的“git怎么安装”),验证系统响应速度与回答准确性。实操中曾出现回答“找不到相关知识”的异常,排查后发现是检索器未正确匹配文本块,后续优化了检索逻辑,提升了匹配精度,同时新增了异常日志,便于快速定位问题。
3.2 常见故障及解决方法(实操总结)
运维开发过程中,遇到过各类故障,每一次排查都是经验的积累,整理如下,便于后续快速处理,减少故障耗时:
- 故障1:API调用失败 → 排查密钥有效性、配额是否充足,若密钥过期,替换新密钥;若配额不足,申请扩容或等待重置。
- 故障2:文档加载失败 → 检查路径是否正确、文档是否加密/损坏,路径含中文空格时,自动过滤空格;加密文档提醒用户解密后上传。
- 故障3:检索结果偏差大 → 调整chunk参数、检索器k值,检查预处理是否彻底,优化检索逻辑。