第三单元 —— 第三课:持续运行的 RAG 问答程序 上课程序运行慢在三个环节加载本地 Embedding 模型每次执行脚本都会启动新的 Python 进程并把 BGE 模型从磁盘加载到内存。模型虽然已经缓存不再重复下载但仍需重新加载。重新生成知识库向量InMemoryVectorStore每次启动都会重新计算资料的向量。当前只有三条资料影响较小资料很多时会明显变慢。等待 DeepSeek 网络响应检索结束后还需要调用一次 DeepSeek API速度受网络和服务状态影响。上一课运行时HF_TOKEN是下载限速提示不是错误。模型已缓存后可以避免联网检查embeddings HuggingFaceEmbeddings( model_nameBAAI/bge-small-zh-v1.5, model_kwargs{ device: cpu, local_files_only: True, }, encode_kwargs{normalize_embeddings: True}, )实际项目不会为每个问题重新启动脚本而是程序启动一次 → 加载模型一次 → 建立向量库一次 → 连续回答多个问题因此第一次启动可能较慢但同一程序中的后续提问会快很多。这一课可以把它改造成一个持续运行的知识库聊天程序。所以本课目标Embedding 模型和向量库只初始化一次然后连续回答问题。保存为unit3_lesson3_rag_chat.pyimport os import time from langchain_openai import ChatOpenAI from langchain_huggingface import HuggingFaceEmbeddings from langchain_core.vectorstores import InMemoryVectorStore from langchain_core.prompts import ChatPromptTemplate from langchain_core.output_parsers import StrOutputParser start_time time.perf_counter() # 1. 知识库 texts [ 星河书店的注册用户也称为会员购买图书可以享受九折优惠。, 星河书店周一至周五营业到晚上八点。, 星河书店周六和周日营业到晚上十点。, 星河书店支持七天内凭购物小票退货。, ] # 2. 加载已经下载到本地的 Embedding 模型 embeddings HuggingFaceEmbeddings( model_nameBAAI/bge-small-zh-v1.5, model_kwargs{ device: cpu, local_files_only: True, }, encode_kwargs{normalize_embeddings: True}, ) # 3. 建立向量库和检索器 vector_store InMemoryVectorStore.from_texts( textstexts, embeddingembeddings, ) retriever vector_store.as_retriever( search_kwargs{k: 1} ) # 4. 创建回答链 model ChatOpenAI( modeldeepseek-v4-flash, base_urlhttps://api.deepseek.com, api_keyos.environ[DEEPSEEK_API_KEY], ) prompt ChatPromptTemplate.from_template( 请根据资料简洁回答问题。 可以识别常见的同义表达但不能添加资料中没有的事实。 找不到答案时请回答“资料中没有相关信息”。 资料 {context} 问题 {question} ) answer_chain prompt | model | StrOutputParser() initialization_time time.perf_counter() - start_time print(f初始化完成耗时 {initialization_time:.2f} 秒。) print(输入 exit 可以结束程序。) # 5. 持续接收问题 while True: question input(\n你).strip() if question.lower() exit: print(程序已结束。) break if not question: continue question_start time.perf_counter() documents retriever.invoke(question) context \n.join( document.page_content for document in documents ) answer answer_chain.invoke({ context: context, question: question, }) question_time time.perf_counter() - question_start print(检索资料, context) print(AI, answer) print(f本次耗时{question_time:.2f} 秒)运行.venv\Scripts\activate python unit3_lesson3_rag_chat.py可以连续测试会员买书有优惠吗 周日几点关门 买书后可以退货吗 书店提供送货服务吗 exit这次 Embedding 模型只在程序启动时加载一次。后续每个问题主要耗时会来自 DeepSeek API而不是重复加载本地模型。