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

极简LLM入门指南5

【LLM实操系列05】RAG实战:知识库问答系统从0到生产

在开始之前,建议先完成第03篇(API调用)和第04篇(Prompt技巧)的学习。你需要理解Embedding(文本向量化)的基本原理,并安装langchain、chromadb等依赖。

10分钟实现最简RAG

什么是RAG?

检索增强生成 = 搜索相关文档 + 结合文档回答问题

Embedding是什么?

Embedding将文本转换为高维向量表示。语义相似的文本会有相似的向量,这使得我们可以用它来计算文本相似度和进行语义搜索。

最小可运行代码

# pip install langchain chromadb openai tiktokenfromlangchain.embeddingsimportOpenAIEmbeddingsfromlangchain.vectorstoresimportChromafromlangchain.chat_modelsimportChatOpenAIfromlangchain.chainsimportRetrievalQA# 1. 准备文档docs=["Python是1991年发布的编程语言","JavaScript主要用于网页开发","Rust注重内存安全和性能"]# 2. 创建向量库embeddings=OpenAIEmbeddings()vectordb=Chroma.from_texts(docs,embeddings)# 3. 创建RAG链llm=ChatOpenAI(temperature=0)qa=RetrievalQA.from_chain_type(llm=llm,retriever=vectordb.as_retriever())# 4. 提问answer=qa.run("Python是什么时候发布的?")print(answer)# 输出:Python是1991年发布的

生产级RAG架构

完整实现

importosfromtypingimportList,Dict,Anyimportnumpyasnpfromdataclassesimportdataclass@dataclassclassDocument:"""文档数据结构"""content:strmetadata:Dict[str,Any]embedding:np.ndarray=NoneclassProductionRAG:"""生产环境RAG系统"""def__init__(self,embedding_model="text-embedding-ada-002",llm_model="gpt-3.5-turbo",vector_db="chroma"):# 初始化组件self.embeddings=OpenAIEmbeddings(model=embedding_model)self.llm=ChatOpenAI(model=llm_model,temperature=0)# 向量数据库ifvector_db=="chroma":self.vectordb=Chroma(persist_directory="./chroma_db",embedding_function=self.embeddings)elifvector_db=="faiss":fromlangchain.vectorstoresimportFAISS self.vectordb=FAISS.load_local("./faiss_index",self.embeddings)# 文档处理器self.text_splitter=self._init_splitter()def_init_splitter(self):"""智能文档分块"""fromlangchain.text_splitterimportRecursiveCharacterTextSplitterreturnRecursiveCharacterTextSplitter(chunk_size=500,# 块大小chunk_overlap=100,# 重叠separators=["\n\n",# 段落"\n",# 行"。",# 句号"!",# 感叹号"?",# 问号";",# 分号",",# 逗号" "# 空格])defadd_documents(self,file_paths:List[str]):"""批量添加文档"""fromlangchain.document_loadersimport(PDFLoader,TextLoader,UnstructuredWordDocumentLoader,CSVLoader)loaders={'.pdf':PDFLoader,'.txt':TextLoader,'.docx':UnstructuredWordDocumentLoader,'.csv':CSVLoader}all_docs=[]forpathinfile_paths:ext=os.path.splitext(path)[1].lower()loader_class=loaders.get(ext,TextLoader)loader=loader_class(path)# 加载并分块docs=loader.load()splits=self.text_splitter.split_documents(docs)all_docs.extend(splits)# 添加到向量库self.vectordb.add_documents(all_docs)print(f"已添加{len(all_docs)}个文档块")defsearch(self,query:str,k=3,use_rerank=True):"""增强搜索"""# 1. 初步检索docs=self.vectordb.similarity_search(query,k=k*2ifuse_rerankelsek)# 2. 重排序(可选)ifuse_rerank:docs=self._rerank(query,docs,top_k=k)returndocsdef_rerank(self,query:str,docs:List,top_k:int):"""使用CrossEncoder重排序"""fromsentence_transformersimportCrossEncoder# 加载重排序模型(首次会下载)reranker=CrossEncoder('cross-encoder/ms-marco-MiniLM-L-6-v2')# 计算相关性分数pairs=[[query,doc.page_content]fordocindocs]scores=reranker.predict(pairs)# 按分数排序doc_scores=list(zip(docs,scores))doc_scores.sort(key=lambdax:x[1],reverse=True)return[docfordoc,_indoc_scores[:top_k]]defquery(self,question:str,use_memory=False):"""智能问答"""# 检索相关文档docs=self.search(question)# 构建上下文context="\n\n".join([d.page_contentfordindocs])# 生成答案ifuse_memory:fromlangchain.memoryimportConversationBufferWindowMemory memory=ConversationBufferWindowMemory(k=3)fromlangchain.chainsimportConversationalRetrievalChain chain=ConversationalRetrievalChain.from_llm(llm=self.llm,retriever=self.vectordb.as_retriever(),memory=memory)response=chain({"question":question})else:# 自定义Promptprompt=f""" 基于以下信息回答问题。如果信息不足,请说"根据提供的信息无法回答"。 信息:{context}问题:{question}回答:"""response=self.llm.predict(prompt)return{"answer":response,"sources":[{"content":d.page_content,"metadata":d.metadata}fordindocs]}

向量数据库选型

对比表

数据库性能易用性成本适用场景
Chroma⭐⭐⭐⭐⭐⭐⭐⭐免费原型/小规模
FAISS⭐⭐⭐⭐⭐⭐⭐⭐免费单机高性能
Pinecone⭐⭐⭐⭐⭐⭐⭐⭐$70+/月SaaS云服务
Weaviate⭐⭐⭐⭐⭐⭐⭐⭐免费+云混合搜索
Milvus⭐⭐⭐⭐⭐⭐⭐⭐免费大规模生产

快速集成代码

# 1. Chroma(最简单)fromlangchain.vectorstoresimportChroma vectordb=Chroma.from_texts(texts,embeddings,persist_directory="./db")# 2. FAISS(最快)fromlangchain.vectorstoresimportFAISS vectordb=FAISS.from_texts(texts,embeddings)vectordb.save_local("./faiss_index")# 3. Pinecone(云服务)importpineconefromlangchain.vectorstoresimportPinecone pinecone.init(api_key="xxx",environment="us-east-1")vectordb=Pinecone.from_texts(texts,embeddings,index_name="my-index")# 4. Weaviate(混合搜索)fromlangchain.vectorstoresimportWeaviateimportweaviate client=weaviate.Client("http://localhost:8080")vectordb=Weaviate(client,index_name="Documents",text_key="content")

性能优化技巧

1. 智能分块策略

defsmart_chunking(text:str,max_tokens=500):"""基于语义的智能分块"""importtiktoken enc=tiktoken.encoding_for_model("gpt-3.5-turbo")# 按段落分割paragraphs=text.split('\n\n')chunks=[]current_chunk=[]current_tokens=0forparainparagraphs:para_tokens=len(enc.encode(para))ifcurrent_tokens+para_tokens>max_tokens:# 保存当前块ifcurrent_chunk:chunks.append('\n\n'.join(current_chunk))current_chunk=[para]current_tokens=para_tokenselse:current_chunk.append(para)current_tokens+=para_tokensifcurrent_chunk:chunks.append('\n\n'.join(current_chunk))returnchunks

2. 混合检索

classHybridSearch:"""结合关键词和语义搜索"""def__init__(self,vectordb):self.vectordb=vectordbfromrank_bm25importBM25Okapi self.bm25=Noneself.corpus=[]defindex_documents(self,documents):"""构建双索引"""# 向量索引self.vectordb.add_documents(documents)# BM25索引tokenized_corpus=[doc.page_content.split()fordocindocuments]self.bm25=BM25Okapi(tokenized_corpus)self.corpus=documentsdefsearch(self,query:str,k=5):"""混合搜索"""# 语义搜索semantic_results=self.vectordb.similarity_search(query,k=k)# 关键词搜索tokenized_query=query.split()bm25_scores=self.bm25.get_scores(tokenized_query)top_indices=np.argsort(bm25_scores)[-k:][::-1]keyword_results=[self.corpus[i]foriintop_indices]# 合并去重seen=set()final_results=[]fordocinsemantic_results+keyword_results:ifdoc.page_contentnotinseen:seen.add(doc.page_content)final_results.append(doc)iflen(final_results)>=k:breakreturnfinal_results

3. 缓存优化

fromfunctoolsimportlru_cacheimporthashlibclassCachedRAG:"""带缓存的RAG系统"""def__init__(self,rag_system):self.rag=rag_system self.cache={}@lru_cache(maxsize=1000)def_get_embedding_cached(self,text:str):"""缓存Embedding"""returnself.rag.embeddings.embed_query(text)defquery_with_cache(self,question:str):"""缓存查询结果"""# 生成查询键query_hash=hashlib.md5(question.encode()).hexdigest()# 检查缓存ifquery_hashinself.cache:print("Cache hit!")returnself.cache[query_hash]# 执行查询result=self.rag.query(question)# 保存缓存self.cache[query_hash]=resultreturnresult

实战部署

Docker部署

# docker-compose.ymlversion:'3.8'services:rag-api:build:.ports:-"8000:8000"environment:-OPENAI_API_KEY=${OPENAI_API_KEY}volumes:-./data:/app/data-./vectordb:/app/vectordbchromadb:image:chromadb/chromaports:-"8001:8000"volumes:-./chroma_data:/chroma/chroma

FastAPI服务

fromfastapiimportFastAPI,UploadFile,FilefrompydanticimportBaseModelimportuvicorn app=FastAPI()rag_system=ProductionRAG()classQuery(BaseModel):question:strk:int=3@app.post("/upload")asyncdefupload_document(file:UploadFile=File(...)):"""上传文档"""# 保存文件file_path=f"./uploads/{file.filename}"withopen(file_path,"wb")asf:content=awaitfile.read()f.write(content)# 添加到RAGrag_system.add_documents([file_path])return{"message":"文档已上传并索引"}@app.post("/query")asyncdefquery(q:Query):"""查询接口"""result=rag_system.query(q.question,k=q.k)returnresult@app.get("/stats")asyncdefstats():"""系统统计"""return{"total_documents":len(rag_system.vectordb.get()['ids']),"model":"gpt-3.5-turbo","embedding_model":"text-embedding-ada-002"}if__name__=="__main__":uvicorn.run(app,host="0.0.0.0",port=8000)

常见问题解决

问题原因解决方案
回答不准确检索质量差优化分块大小,增加overlap
速度慢每次都计算embedding使用缓存,批量处理
成本高调用API频繁本地embedding模型
文档更新困难没有版本管理增加metadata,支持增量更新
答案幻觉上下文不足增加检索数量,验证答案
http://www.cnnetsun.cn/news/75116.html

相关文章:

  • 深圳市47个数据中心一览表
  • 从零开始搭建AutoGPT:基于大模型的智能体自动化任务实践
  • Apk Pure开发者如何利用LLama-Factory压缩模型适配移动设备?
  • 16个自动驾驶算法从感知到模型部署,超全!
  • PKHeX.Mobile终极指南:移动端宝可梦存档编辑完全教程
  • 21、时间点与持续时间建模:原理、应用与挑战
  • 如何快速掌握网站下载:WebSite-Downloader 完整使用指南
  • 27、时态数据库概念解析
  • 30、数据库镜像重建中的闪回管理与SQL注入防范
  • Wan2.2-T2V-5B模型API封装实践:集成到Web应用的步骤详解
  • Typora支持HTML5音频播放:完美呈现ACE-Step输出效果
  • 39、使用MRTG进行网络监控的全面指南
  • AI+教育的未来发展趋势:人机环境系统智能
  • 8个降AI率工具推荐,本科生课堂汇报必备
  • 1、雾无线接入网络:5G 及 6G 通信的新范式
  • 卫星轨道预测终极指南:5步掌握SGP4模型核心应用
  • 中国科学技术大学学位论文LaTeX模板完整指南
  • 16、雾无线接入网络中的计算卸载与原型设计
  • 18、雾无线接入网络(F-RAN):原型、性能评估与未来挑战
  • Snakemake中的样本配对与文件处理
  • 工业防水平板电脑WPPC-H1520T(P)在食品加工湿环境中的部署与应用开发实践
  • 探索数字组合的艺术
  • Shiny模块化开发:解决Tab选中问题
  • AutoGPT与SQLite轻量数据库集成:适用于小型项目的本地存储方案
  • Jenkins Pipeline调用LLama-Factory训练任务,实现无人值守AI训练
  • 中小学教育AI工具开发:架构师的数据主权方案
  • 如何快速上手 Harepacker-resurrected:从入门到精通的完整指南
  • 百万 Token 也能无损压缩?C3 模型用“级联压缩”重新定义长上下文挑战
  • GOBI 2025 全球开源商业创新大会顶级嘉宾阵容公开!4 大 Panel 火力全开
  • 安卓私密文件同步终极方案:Syncthing-Android完全指南