news 2026/11/5 6:44:14

LLM AI大模型 -- RAG

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
LLM AI大模型 -- RAG

RAG

  • jupyter lab的搭建使用
  • RAG系统的基本搭建流程
    • 文档的加载与切割
    • LLM接口封装
    • Prompt模板
  • 向量检索
    • 什么是向量
      • 文本向量
      • 文本向量怎么得到的
    • 向量间的相似度计算
    • 嵌入模型的选择
  • 向量数据库
    • Chroma向量数据库
    • Chroma向量数据库服务
      • 主流向量数据库功能对比
    • 基于向量检索的RAG
  • RAG系统进阶知识
    • 文本分割的粒度

国内模型库: https://www.modelscope.cn

jupyter lab的搭建使用

首先需要创建一个conda环境 进到环境中再执行 不能再base环境下

pip install jupyterlab

切换到想要保存的磁盘

cd F:\LLM


使用以下命令启动jupyterlab:

jupyter lab

RAG系统的基本搭建流程

搭建过程:

  1. 文档加载,并按一定条件切割成片段
  2. 将切割的文本片段灌入检索引擎
  3. 封装检索接口
  4. 构建调用流程:Query->检索->Prompt->LLM->回复

文档的加载与切割

安装下边的两个库

!pip install--upgrade openai# 安装 pdf 解析库!pip install pdfminer.six
frompdfminer.high levelimportextract_pagesfrompdfminer.layoutimportLTTextContainer
defextract_text_from_pdf(filename,page_numbers=None,min_line_length=1):'''从 PDF 文件中(按指定页码)提取文字'''paragraphs=[]buffer=""full_text=""# 提取全部文本fori,page_layoutinenumerate(extract_pages(filename)):# 如果指定了页码范围,跳过范围外的页ifpage_numbersisnotNoneandinotinpage_numbers:continueforelementinpage_layout:ifisinstance(element,LTTextContainer):full_text+=element.get_text()+"\n"# 按空行分隔,将文本重新组织成段落Lines=full_text.split("\n")fortextinlines:iflen(text)>=min_line_length:buffer+=(""+text)ifnottext.endswith("")elsetext.strip("-")elifbuffer:paragraphs.append(buffer)buffer=""ifbuffer:paragraphs.append(buffer)returnparagraphs paragraphs=extract_text_from_pdf("llama2.pdf",min_line_length=10)forparainparagraphs[:4]:print(para+"\n")

LLM接口封装

pip install-U python-dotenv
fromopenaiimportOpenAIimportos#加载环境变量fromdotenvimportload_dotenv,find_dotenv _=load_dotenv(find_dotenv(),verbose=True)client=OpenAI()#封装openai接口defget_completion(prompt,model="gpt-3.5-turbo",temperature=0.7,max_tokens=150,top_p=1.0,frequency_penalty=0.0,presence_penalty=0.0,stop=["\n"]):messages=[{"role":"user","content":prompt}]response=client.chat.completions.create(messages=messages,model=model,temperature=temperature,#模型输出的随机性max_tokens=max_tokens,top_p=top_p,frequency_penalty=frequency_penalty,presence_penalty=presence_penalty,stop=stop)returnresponse.choices[0].message.content

Prompt模板

#创建提示词模板defbuild_prompt(prompt_template,**kwargs):inputs={}fork,vinkwargs.items():ifisinstance(v,list)andall(isinstance(i,str)foriinv):val='\n\n'.join(v)else:val=v inputs[k]=valreturnprompt_template.format(**inputs)

prompt_template = “”
你是一个问答机器人。你的任务是根据下述给定的己知信息回答用户问题
已知信息: 从向量数据库检索出来的原始文档
{context}
用户问:
{query}
如果已知信息不包含用户问题的答案,或者已知信息不足以回答用户的问题,请直接回复"我无法回答您的问题"请不要输出已知信息中不包含的信息或答案。请用中文回答用户问题。

向量检索

什么是向量

向量是一种有大小和方向的数学对象。它可以表示为从一个点到另一个点的有向线段。例如:二维空间中的向量可以表示为(x,y),表示从原点(0,0)到点(x,y)的有向线段。

以此类推,我可以用一组坐标(x0,x1,x2…xn)表示一个 N 维空间中的向量,N 叫向量的维度

文本向量

将文本转成一组N维浮点数,即文本向量又叫Embeddings
向量之间可以计算距离,距离远近对应语义相似度大小

文本向量怎么得到的

1.构建相关(正例)与不相关(负例)的句子对样本
2.训练双塔式模型,让正例间的距离小,负例间的距离大

向量间的相似度计算

importnumpyasnpfromnumpyimportdotfromnumpy.linalgimportnorm
defcos_sim(a,b):#余弦距离 越大越相似'''余弦距离 越大越相似'''returndot(a,b)/(norm(a)*norm(b))defl2(a,b):'''欧式距离 越小越相似'''x=np.asarray(a)-np.asarray(b)returnnorm(x)defget_embeddings(texts,model="text-embedding-ada-002",dimensions=None):'''封装openai的Embedding模型接口'''ifmodel=="text-embedding-ada-002":dimensions=Noneifdimensions:data=client.embeddings.create(input=texts,model=model,dimensions=dimensions).dataelse:data=client.embeddings.create(input=texts,model=model).datareturn[x.embeddingforxindata]
test_query=["测试文本"]vec=get_embeddings(test_query)[0]print(f"Total dimensions:{len(vec)}")print(f"First 10 dimensions:{vec[:10]}")

嵌入模型的选择

  • 标准:找需求相关的语料库来进行文本向量的转换测试,进行评估
    维度越大,标识特征细节提取越丰富

大多数场景下,开源的嵌入模型使用体验都很差
要提升检索召回率,建议对模型进行微调

向量数据库

向量数据库,是专门为向量检索设计的中间件!
向量数据库其实最早在传统的人工智能和机器学习场景中就有所应用。在大模型兴起后,由于目前大模型的token数限制,很多开发者倾向于将数据量庞大的知识、新闻、文献、语料等先通过嵌入(embedding)算法转变为向量数据,然后存储在Chroma等向量数据库中。当用户在大模型、输入问题后,将问题本身也embedding,转化为向量,在向量数据库中査找与之最匹配的相关知识,组成大模型的上下文,将其输入给大模型,最终返回模型处理后的文本给用户,这种方式不仅降低大模型的计算量,提高响应速度,也降低成本,并避免了大模型的tokens限制,是一种简单高效的处理手段。此外向量数据库还在大模型记忆存储等领域发挥其不可替代的作用。

Chroma向量数据库

官方文档:https://docs.trychroma.com/docs/overview/introduction

安装数据库

pip install chromadb
#为了演示方便 取两页paragraphs=extract_text_from_pdf("llama2.pdf",page_numbers=[2,3],min_line_length=10)
importchromadbfromchromadb.configimportSettingsclassMyVectorDBConnector:def__init__(self,collection_name,embedding_fn):#内存模式 实际不能这么用 只能自己玩用 否则服务器一出问题 全丢chroma_client=chromadb.Client(Settings(allow_reset=True))#数据持久化#chroma_client = chromadb.PersistentClient(path="./chroma")#注意:为了演示,实际不需要每次都reset() 不可逆chroma_client.reset()# reset重置数据库 慎用self.collection=chroma_client.get_or_create_collection(name=collection_name)self.embedding_fn=embedding_fndefadd_documents(self,documents):# 向collection中添加文档与向量self.collection.add(embeddings=self.embedding_fn(documents),#每个文档的向量documents=documents#文档的原文ids=[f"id{i}"foriinrange(len(documents))]#每个文档的 id)defsearch(self,query,top_k=10):# 检索向量数据库results=self.collection.query(query_embedding=self.embedding_fn([query]),n_results=top_n)returnresults
#创建一个向量数据库对象vector_db=MyVectorDBConnector(collection_name="llama2",embedding_fn=get_embeddings)#向向量数据库中添加文档vector_db.add_documents(paragraphs)user_query="Llama 2有多少参数"#user_query = "Does Llama 2 have a conversational variant?"results=vector_db.search(user_query,2)forparainresults['documents'][0]:print(para+"\n")

澄清几个关键概念:

  • 向量数据库的意义是快速的检索;
  • 向量数据库本身不生成向量,向量是由 Embedding 模型产生的:
  • 向量数据库与传统的关系型数据库是互补的,不是替代关系,在实际应用中根据实际需求经常同时使用。

Chroma向量数据库服务

Server 端

chroma run--path/db_path

Client 端

importchromadb chromadb_client=chromadb.HttpClient(host='localhost',port=8000)

主流向量数据库功能对比

  • FAISS: Meta 开源的向量检索引擎 https://github已添加到剪贴板research/faiss。
  • Pinecone:商用向量数据库,只有云服务 https:/www.pinecone.io/
  • Milvus: 开源向量数据库,同时有云服务 https://milvus.io/
  • Weaviate:开源向量数据库,同时有云服务 https://weaviate.io/
  • Qdrant: 开源向量数据库,同时有云服务 https://qdrant.tech/
  • PGVector: Postgres 的开源向量检索引擎 https://github.com/pgvector/pgvector
  • RediSearch: Redis 的开源向量检索引擎 https://qithub.com/RediSearch/Redisearch
  • ElasticSearch 也支持向量检索 https://www.elastic.co/enterprise-search/vector-search
    企业推荐标示的向量数据库

基于向量检索的RAG

classRAG_Bot:def__init__(self,vector_db,llm_api,n_results=2):self.vector_db=vector_db self.llm_api=llm_api self.n_results=n_resultsdefchat(self,user_query):# 检索search_results=self.vector_db.search(user_query,self.n_results)# 构建 Promptprompt=build_prompt(prompt_template,search_results=search_results['documents'][0],query=user_query)#调用LLMresponse=self.llm_api(prompt)returnresponse
#创建一个RAG机器人bot=RAG_Bot(vector_db,llm_api=get_completion)user_query="Llama 2有多少参数?"response=bot.chat(user_query)print(response)

RAG系统进阶知识

文本分割的粒度

缺陷

  • 粒度太大可能导致检索不精准,粒度太小可能导致信息不全面
  • 问题的答案可能跨越两个片段
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/11/3 16:42:42

4、深入理解BPF Maps:创建、操作与应用

深入理解BPF Maps:创建、操作与应用 1. BPF Maps简介 在软件工程中,通过消息传递来调用程序行为是一种广泛使用的技术。程序可以通过发送消息来修改另一个程序的行为,同时也能实现程序间的信息交换。BPF(Berkeley Packet Filter)的一个迷人之处在于,运行在内核中的代码…

作者头像 李华
网站建设 2026/11/4 4:15:22

10、深入探索BPF工具:BPFTool与BPFTrace的实用指南

深入探索BPF工具:BPFTool与BPFTrace的实用指南 1. BPFTool的强大功能 BPFTool无需编写和编译代码,就能提供内核中加载程序的大量信息。下面详细介绍其各项功能。 1.1 检查BPF映射 BPFTool不仅能检查和操作BPF程序,还能访问这些程序使用的BPF映射。 - 列出和过滤映射 …

作者头像 李华
网站建设 2026/11/5 7:07:18

14、XDP 编程:从基础到实践

XDP 编程:从基础到实践 1. 数据包处理器 在 XDP(eXpress Data Path)中,数据包处理器是执行 BPF 程序和协调网络栈交互的核心组件。它直接处理来自网卡接收(RX)队列的数据包,确保数据包可读可写,并允许以数据包处理器操作的形式附加后处理裁决。其特点如下: - 运行…

作者头像 李华
网站建设 2026/11/4 15:59:37

X-TRACK DIY制作全攻略:从零打造个性化GPS自行车码表外壳

X-TRACK DIY制作全攻略:从零打造个性化GPS自行车码表外壳 【免费下载链接】X-TRACK A GPS bicycle speedometer that supports offline maps and track recording 项目地址: https://gitcode.com/gh_mirrors/xt/X-TRACK 作为一名骑行爱好者,你是…

作者头像 李华
网站建设 2026/11/4 11:18:18

火山引擎文档中心上线Qwen-Image-Edit-2509接入指南

火山引擎Qwen-Image-Edit-2509接入指南:技术深度解析与应用实践 在电商运营的深夜,一位设计师正为即将到来的大促活动批量修改上千张商品图——每一张都要手动添加“限时折扣”标签、调整文字颜色、对齐排版。这个过程重复枯燥,耗时长达数小时…

作者头像 李华
网站建设 2026/11/4 20:16:28

FLUX.1-dev支持指令微调?多任务学习实践案例分享

FLUX.1-dev支持指令微调?多任务学习实践案例分享 在创意内容爆发的今天,AI生成图像早已不再是“能不能画出来”的问题,而是“能不能听懂我想要什么”的挑战。用户不再满足于输入几个关键词就碰运气出图,他们希望模型能理解复杂语义…

作者头像 李华