在这里插入图片描述
文章目录

RAG

尽管大型语言模型展现了惊人的通识能力,但我们深知其固有的局限性:参数化知识的静态性、事实性幻觉以及领域知识的缺失。传统的微调方案虽能注入新知识,但成本高昂、灵活性差,且难以解决知识实时性问题。在此背景下,检索增强生成 作为一种将模型参数化知识与非参数化外部知识库动态结合的范式,成为了构建高性能、高可信度AI应用的事实标准。

RAG的核心思想是在LLM的生成过程之前,引入一个检索阶段,从大规模、可信的外部知识库中动态检索相关信息,并将其作为上下文提示给LLM,从而约束和增强模型的生成结果。本质上,它让模型学会了‘在回答问题前先查阅资料’。

RAG的技术架构分解

在这里插入图片描述
模块一:检索器 - 寻找相关的信息

  • 密集向量检索:
    • 核心:将查询和文档映射到同一高维向量空间,通过近似最近邻搜索查找最相似的文档。
    • 技术栈:Sentence-BERT/Contriever 等双编码器模型用于产生Embedding;FAISS, HNSW, SCANN 等库用于高效索引和检索。
    • 关键挑战: Embedding模型的质量决定了检索效果的上限。领域适配的Embedding模型至关重要。
  • 稀疏检索:
    • 代表: BM25, 一种经典且强大的基于词频的检索算法。
    • 优势: 对精确关键词匹配、命名实体等任务非常有效,无需训练。
  • 混合检索:
    • 策略:结合密集检索的语义理解能力和稀疏检索的精确匹配能力。
    • 融合方法: Reciprocal Rank Fusion, 加权分数融合等。这是目前工业界的主流方案,以求在召回率和准确率之间达到最佳平衡。

模块二:增强 - 准备给模型的“参考资料”

  • 重排序:
    • 目的: 初检返回的Top-K结果中可能存在与查询语义相关但实际不有用的文档。重排序使用更精细的模型(如Cross-Encoder)对(Query, Doc)对进行精细化打分,重新排序,提升Top结果的精度。
  • 上下文压缩:
    • 问题: 检索到的完整文档可能包含大量冗余信息,消耗宝贵的上下文窗口并引入噪声。
    • 解决方案:
    • 抽取式: 仅提取与查询最相关的句子或段落。
    • 抽象式: 使用一个小型模型对长文档进行摘要,再将摘要送入LLM。

模块三:生成器 - 基于上下文的答案合成

  • Prompt工程:
    • 构建清晰的指令,明确要求模型基于给定的上下文回答问题。
    • 关键指令模式:“请严格根据以下背景信息回答问题。如果背景信息中不包含答案,请直接说‘根据已知信息无法回答该问题’。”
  • 生成控制:
    • 可以通过调整temperature等参数,控制生成的专业性和创造性。

示例代码

import os
from langchain_community.document_loaders import TextLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_community.vectorstores import FAISS
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain import hub
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough

# 设置 OpenAI API Key (请替换为您的密钥)
os.environ["OPENAI_API_KEY"] = "your-openai-api-key"

# 1. 加载文档 (这里以本地txt文件为例)
loader = TextLoader("path/to/your/document.txt")
documents = loader.load()

# 2. 文档分割
text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=1000,  # 块大小
    chunk_overlap=200  # 块重叠
)
docs = text_splitter.split_documents(documents)

# 3. 创建向量数据库
embeddings = OpenAIEmbeddings()
vectorstore = FAISS.from_documents(docs, embeddings)

# 4. 创建检索器
retriever = vectorstore.as_retriever(
    search_type="similarity",  # 检索方式:相似度
    search_kwargs={"k": 4}     # 返回top-4个相关文档块
)

# 5. 定义Prompt模板 (使用LangChain Hub的RAG prompt)
prompt = hub.pull("rlm/rag-prompt")

# 6. 初始化LLM
llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0)

# 7. 定义RAG处理链
def format_docs(docs):
    """将检索到的文档格式化为单个字符串"""
    return "\n\n".join(doc.page_content for doc in docs)

rag_chain = (
    {"context": retriever | format_docs, "question": RunnablePassthrough()}
    | prompt
    | llm
    | StrOutputParser()
)

# 8. 使用RAG链进行问答
question = "什么是机器学习?"
answer = rag_chain.invoke(question)
print(f"问题: {question}")
print(f"答案: {answer}")

系列文章

【大语言模型】-- OpenAI定义的五个AGI发展阶段
【大语言模型】-- Fine-tuning 微调
【大语言模型】-- 私有化部署
【大语言模型】-- Prompt Engineering 提示工程
【大语言模型】-- Function Calling函数调用
【大语言模型】-- RAG
【大语言模型】-- Agent
【大语言模型】-- 一些概念

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐