215 0

[其他] 大模型学习记录(七)---------RAG [推广有奖]

  • 0关注
  • 0粉丝

等待验证会员

学前班

80%

还不是VIP/贵宾

-

威望
0
论坛币
0 个
通用积分
0
学术水平
0 点
热心指数
0 点
信用等级
0 点
经验
30 点
帖子
2
精华
0
在线时间
0 小时
注册时间
2018-11-14
最后登录
2018-11-14

楼主
年轻的潜行者 发表于 2025-12-3 16:33:14 |AI写论文

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币

RAG(检索增强生成)技术介绍

1. 什么是RAG?

RAG,全称为Retrieval-Augmented Generation(检索增强生成),是一种融合了信息检索与大语言模型生成能力的技术架构。其核心思想是在生成回答之前,先从外部知识库中检索出与用户问题相关的文档片段,再将这些内容连同原始问题一并输入到语言模型中,从而生成更准确、可靠且上下文相关性更强的回复。

通过分析提供的r1_rag.py代码可以发现,一个典型的RAG系统通常包含以下几个关键模块:

  • 文档处理与分块:将原始长文本按语义或长度划分为较小的片段(chunks),便于后续处理。
  • 文本嵌入:利用嵌入模型将文本转换为高维向量表示,实现语义层面的数字化表达。
  • 向量存储:借助向量数据库(如FAISS)对文本向量进行高效存储和索引。
  • 检索系统:基于语义相似度算法,在向量空间中快速定位与查询最相关的文档片段。
  • 生成模型:结合检索结果和用户提问,由大语言模型生成最终的回答。
import os
from langchain.schema import Document
from dotenv import load_dotenv
from langchain_community.vectorstores import FAISS
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.embeddings import HuggingFaceBgeEmbeddings, FastEmbedEmbeddings, FakeEmbeddings
load_dotenv()


if __name__ == '__main__':
    origin_data = {
        "ID": "64fa9b27b82641eb8ecbe14c",
        "event": "2023年7月28日,国家卫生健康委在全国范围内开展“启明行动”——防控儿童青少年近视健康促进活动,发布《防控儿童青少年近视核心知识十条》。",
        "news1": "2023-07-28 10:14:27作者:白剑峰来源:人民日报    ,正文:为在全社会形成重视儿童眼健康的良好氛围,持续推进综合防控儿童青少年近视工作落实,国家卫生健康委决定在全国持续开展“启明行动”——防控儿童青少年近视健康促进活动,并发布了《防控儿童青少年近视核心知识十条》。本次活动的主题为:重视儿童眼保健,守护孩子明眸“视”界。强调预防为主,推动关口前移,倡导和推动家庭及全社会共同行动起来,营造爱眼护眼的视觉友好环境,共同呵护好孩子的眼睛,让他们拥有一个光明的未来。国家卫生健康委要求,开展社会宣传和健康教育。充分利用网络、广播电视、报纸杂志、海报墙报、培训讲座等多种形式,广泛开展宣传倡导,向社会公众传播开展儿童眼保健、保护儿童视力健康的重要意义,以《防控儿童青少年近视核心知识十条》为重点普及预防近视科学知识。创新健康教育方式和载体,开发制作群众喜闻乐见的健康教育科普作品,利用互联网媒体扩大传播效果,提高健康教育的针对性、精准性和实效性。指导相关医疗机构将儿童眼保健和近视防控等科学知识纳入孕妇学校、家长课堂内容。开展儿童眼保健及视力检查咨询指导。医疗机构要以儿童家长和养育人为重点,结合眼保健和眼科临床服务,开展个性化咨询指导。要针对儿童常见眼病和近视防控等重点问题,通过面对面咨询指导,引导儿童家长树立近视防控意识,改变不良生活方式,加强户外活动,养成爱眼护眼健康行为习惯。提高儿童眼保健专科服务能力。各地要积极推进儿童眼保健专科建设,扎实组织好妇幼健康职业技能竞赛“儿童眼保健”项目,推动各层级开展比武练兵,提升业务能力。",
        "questions": "国家卫生健康委在2023年7月28日开展的“启明行动”是为了防控哪个群体的哪种健康问题,并请列出活动发布的指导性文件名称。",
        "answers": "启明行动”是为了防控儿童青少年的近视问题,并发布了《防控儿童青少年近视核心知识十条》。"
    }
    docs = [Document(page_content=origin_data['news1'], metadata={'source': origin_data['ID']})]

    # 分割文档, 将文本分割为多个文档片段
    text_splitter = RecursiveCharacterTextSplitter(
        chunk_size=256,                     # 每个文档片段的最大字符数
        chunk_overlap=50,                   # 每个文档片段之间的重叠字符数
    )
    split_docs = text_splitter.split_documents(docs)
    # 对文本进行编码
    embedding = FakeEmbeddings(size=768)
    # 对文档片段进行编码
    embeddings = embedding.embed_documents([doc.page_content for doc in split_docs])
    

    # 创建向量存储,使用FAISS.from_embeddings方法
    # 需要创建(text, embedding)元组的列表
    text_embeddings = list(zip([doc.page_content for doc in split_docs], embeddings))
    # 元数据也需要单独提取
    metadatas = [doc.metadata for doc in split_docs]
    vectordb = FAISS.from_embeddings(text_embeddings, embedding, metadatas=metadatas)
    # 也可以使用FAISS.from_documents方法创建向量存储, 使用from_documents方法时,会自动调用模型对象的 .embed_documents() 方法来生成向量
    vectordb = FAISS.from_documents(split_docs, embedding)
    index_folder_path = "data/faiss_index"

    index_name = "0"

    # 保存索引
    vectordb.save_local(index_folder_path, index_name)

    # 加载索引  allow_dangerous_deserialization 加载由不受信任的源生成的索引文件时需要
    vectordb = FAISS.load_local(index_folder_path, embedding, index_name, allow_dangerous_deserialization=True)

    # 创建检索器
    retriever = vectordb.as_retriever(search_kwargs={"k": 2})
    from langchain_openai import ChatOpenAI

    # 创建模型,API key可以直接写在代码里,也可以从本地环境获取
    api_key = os.getenv("DEEPSEEK_API_KEY")
    llm = ChatOpenAI(temperature=0, model_name="deepseek-chat", api_key=api_key, base_url="https://api.deepseek.com/beta")
    from langchain.chains import RetrievalQA

    # 创建链
    chain = RetrievalQA.from_chain_type(llm=llm,
                                        chain_type="stuff",
                                        retriever=retriever,
                                        return_source_documents=True)

    # 运行链
    response = chain.invoke(origin_data['questions'])
    print(response)

2. RAG 的主要应用场景

结合代码实现方式及RAG自身的技术优势,该技术适用于多种需要精准信息提取和智能生成的场景:

智能问答系统

如示例代码所示,可通过构建特定文档集合的知识库,实现针对某一领域或主题的智能问答功能。用户提出问题后,系统自动检索相关内容并生成结构化回答。

企业级专业知识访问

企业可将内部手册、技术文档、研究报告等资料整合为统一知识库,借助RAG提供高效的智能查询服务,帮助员工快速获取所需信息,提升工作效率。

信息检索与内容摘要

面对大量非结构化文本数据时,RAG能够快速筛选出与查询意图匹配的信息段落,并生成简洁明了的摘要,显著减少人工阅读负担。

深度文档理解与分析

支持对复杂文档进行深层次解析,提取关键事实、关系或结论,并能回应涉及多跳推理的复合型问题。

定制化知识服务

根据不同用户群体的需求,构建垂直领域的专属知识库,提供个性化、专业化的内容推荐与响应服务。

3. 使用 RAG 的核心优势

提升回答准确性与可信度

通过引入外部知识作为上下文支撑,RAG为语言模型提供了真实的数据依据,有效避免了“凭空捏造”式的错误输出,大幅提高了回答质量。

解决模型知识滞后问题

传统大语言模型的知识来源于训练数据,存在明显的时间局限性。而RAG可通过动态更新知识库的方式,使系统具备回答最新事件的能力——例如代码中处理的是2023年的新闻内容,说明其支持时效性强的信息查询。

增强结果可解释性

在调用模型时启用return_source_documents=True参数,即可返回生成所依据的原始文档片段,让用户清楚了解答案来源,提升系统的透明性和信任度。

降低幻觉发生概率

由于生成过程依赖于实际检索到的文本内容,RAG机制天然抑制了语言模型产生虚构信息的风险,特别适合医疗、金融等高精度要求的应用场景。

灵活的知识管理机制

如代码中所示,知识库可通过save_localload_local方法实现本地持久化存储与加载,支持随时增删改查文档内容,无需重新训练整个模型,极大降低了维护成本。

面向特定领域的高度适配性

相较于通用语言模型广泛但浅层的知识覆盖,RAG允许构建聚焦于某一专业领域的知识体系,从而提供更具深度和针对性的回答服务。

import os
from langchain.schema import Document
from dotenv import load_dotenv
from langchain_community.vectorstores import FAISS
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.embeddings import HuggingFaceBgeEmbeddings, FastEmbedEmbeddings, FakeEmbeddings
import os
import bs4
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain_community.document_loaders import WebBaseLoader
from langchain_community.vectorstores import FAISS
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_openai import ChatOpenAI
from langchain.chains import RetrievalQA
load_dotenv()



if __name__ == '__main__':
    web_url = "https://www.gov.cn/yaowen/liebiao/202510/content_7045602.htm"
    loader = WebBaseLoader(
            web_url,
            bs_kwargs=dict(parse_only=bs4.SoupStrainer(id="UCAP-CONTENT"))
        )
    docs = loader.load()

    # 分割文档, 将文本分割为多个文档片段
    text_splitter = RecursiveCharacterTextSplitter(
        chunk_size=256,                     # 每个文档片段的最大字符数
        chunk_overlap=50,                   # 每个文档片段之间的重叠字符数
    )
    split_docs = text_splitter.split_documents(docs)
    # 对文本进行编码,size和分割文档的chunk_size不是同一个概念,size是每个文档片段的向量维度,常用768,1024
    embedding = FakeEmbeddings(size=768)
    # 对文档片段进行编码
    embeddings = embedding.embed_documents([doc.page_content for doc in split_docs])
    

    # 创建向量存储,使用FAISS.from_embeddings方法
    # 需要创建(text, embedding)元组的列表
    text_embeddings = list(zip([doc.page_content for doc in split_docs], embeddings))
    # 元数据也需要单独提取
    metadatas = [doc.metadata for doc in split_docs]
    vectordb = FAISS.from_embeddings(text_embeddings, embedding, metadatas=metadatas)
    # 也可以使用FAISS.from_documents方法创建向量存储, 使用from_documents方法时,会自动调用模型对象的 .embed_documents() 方法来生成向量
    # vectordb = FAISS.from_documents(split_docs, embedding)
    index_folder_path = "data/faiss_index"

    index_name = "0"

    # 保存索引
    vectordb.save_local(index_folder_path, index_name)

    # 加载索引  allow_dangerous_deserialization 加载由不受信任的源生成的索引文件时需要
    vectordb = FAISS.load_local(index_folder_path, embedding, index_name, allow_dangerous_deserialization=True)

    # 创建检索器
    retriever = vectordb.as_retriever(search_kwargs={"k": 2})
    from langchain_openai import ChatOpenAI

    # 创建模型,API key可以直接写在代码里,也可以从本地环境获取
    api_key = os.getenv("DEEPSEEK_API_KEY")
    llm = ChatOpenAI(temperature=0, model_name="deepseek-chat", api_key=api_key, base_url="https://api.deepseek.com/beta")
    from langchain.chains import RetrievalQA

    # 创建链
    chain = RetrievalQA.from_chain_type(llm=llm,
                                        chain_type="stuff",
                                        retriever=retriever,
                                        return_source_documents=True)

    # 运行链
    response = chain.invoke("会议的内容是什么")
    print(response)

4. 代码应用实例

(1)基于Python字典数据的RAG实现

该案例展示了如何使用结构化字典数据构建RAG流程,整体步骤如下:

  1. 读取原始数据
  2. 对数据进行分块处理
  3. 对每个文本块进行向量化编码
  4. 创建本地向量存储(如FAISS)
  5. 构建检索器以支持语义搜索
  6. 初始化生成模型
  7. 执行端到端的查询调用

本例采用FakeEmbeddings模拟嵌入过程,便于测试流程完整性;实际部署时可替换为HuggingFaceBgeEmbeddings、FastEmbedEmbeddings等真实嵌入模型(可能需配置API key)。同时,向量数据库使用Faiss并将索引保存至本地文件,方便后续重复调用与扩展。

(2)基于网页数据的RAG实现

此用例与上述字典数据方案基本一致,仅需更改数据源读取部分——即将docs前的数据获取逻辑替换为网页抓取或HTML解析流程,后续的分块、嵌入、检索和生成环节保持不变。这种方式使得RAG系统可以直接基于互联网公开信息进行实时问答,拓展了应用场景的边界。

总结

RAG技术通过有机结合信息检索与语言生成两大能力,有效弥补了大语言模型在知识准确性、时效性和可解释性方面的短板。它不仅提升了AI系统的可靠性,还为企业级知识管理和个性化信息服务提供了可行路径。随着向量数据库性能的优化以及嵌入模型的发展,RAG将在更多垂直领域发挥关键作用,成为构建下一代智能系统的重要基石。

二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:学习记录 embeddings Generation Embedding documents

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
加好友,备注jltj
拉您入交流群
GMT+8, 2025-12-5 12:50