news 2026/5/7 9:40:23

极简LLM入门指南5

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
极简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,支持增量更新
答案幻觉上下文不足增加检索数量,验证答案
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/18 5:43:14

极简LLM入门指南 7

【LLM实操系列07】Agent开发:构建自主AI智能体 在开始之前,建议先完成第04篇(理解ReAct概念)和第03篇(API调用)。你需要理解工具调用和思考-行动-观察循环的基本概念,并安装langchain及相关工具…

作者头像 李华
网站建设 2026/5/4 8:26:12

DesktopNaotu终极指南:10分钟掌握免费离线思维导图

DesktopNaotu终极指南:10分钟掌握免费离线思维导图 【免费下载链接】DesktopNaotu 桌面版脑图 (百度脑图离线版,思维导图) 跨平台支持 Windows/Linux/Mac OS. (A cross-platform multilingual Mind Map Tool) 项目地址: https://gitcode.com/gh_mirror…

作者头像 李华
网站建设 2026/5/1 3:01:11

GHelper深度评测:华硕ROG笔记本硬件控制的革命性突破

GHelper深度评测:华硕ROG笔记本硬件控制的革命性突破 【免费下载链接】g-helper Lightweight Armoury Crate alternative for Asus laptops. Control tool for ROG Zephyrus G14, G15, G16, M16, Flow X13, Flow X16, TUF, Strix, Scar and other models 项目地址…

作者头像 李华
网站建设 2026/5/3 20:52:23

LobeChat作为Web入口整合多个AI服务的最佳实践

LobeChat:构建统一 AI 服务入口的现代实践 在今天,几乎每个开发者都曾面对这样一个场景:你手握 OpenAI、Claude、Gemini 的 API 密钥,本地还跑着一个 Ollama 实例,想要对比不同模型的表现,却不得不在多个网…

作者头像 李华
网站建设 2026/5/7 8:08:15

WPF 轻量级工业边缘网关:支持 PLC 数据采集、条件触发与 HTTP 上报

前言工业自动化领域,设备数据的采集、处理与上传是开发智能监控系统的基础。面对不同品牌 PLC、协议不统一、开发门槛高、部署复杂等问题,常常让大家不知所措。有没有一种工具,既能图形化配置设备连接,又能灵活定义数据处理逻辑&a…

作者头像 李华
网站建设 2026/5/3 7:00:38

OpenCVSharp:学习最佳匹配矩形检测

前言今天来学习一下OpenCVSharp中最佳匹配矩形检测的例子。其过程可以分为ORB特征检测、特征匹配、最佳匹配筛选、单应性计算与矩形绘制。效果:实践ORB特征检测进行ORB特征检测:using var img1 new Mat(FirstImagePath, ImreadModes.Color); usingvar i…

作者头像 李华