在大模型的快速发展中,许多人被 ChatGPT、Claude 等对话模型惊艳得目瞪口呆。
然而,我们稍微深挖就会发现,大模型的“超能力”并不总是那么稳定,有时候它可能信心满满地生成错误答案。
于是,一个叫 RAG(Retrieval-Augmented Generation) 的技术应运而生,为大模型的应用开发带来了一次质的飞跃。
大模型应用开发-什么是RAG
RAG,全称是 检索增强生成(Retrieval-Augmented Generation),是一种结合信息检索(IR)和生成式模型的技术框架。简单来说,RAG 的核心思想是“不会就查,不懂别瞎说”。
RAG 的基本逻辑是:
检索阶段:从一个外部知识库中获取相关的文档或信息。
生成阶段:利用检索到的信息,结合大模型生成最终回答。
这样做的好处是显而易见的:
信息更准确:避免模型靠“幻觉”胡编乱造。
灵活性强:可以根据特定任务,接入不同类型的知识库,比如企业文档、产品手册等。
大模型应用开发-RAG的技术框架
RAG 的工作流程通常包含以下几个模块:
01、数据预处理
首先需要一个知识库,可以是公司内部的文档数据库、网络爬取的数据、甚至客户提供的资料。将这些文档处理成可搜索的格式是第一步,通常会:
转为文本格式(如果是 PDF、图片等需要 OCR 技术)。
通过分句或分段,将文本切分为粒度适中的片段。
使用嵌入模型(如 OpenAI 的 text-embedding 模型或 Sentence-BERT)将片段转换为向量,存入向量数据库(如 Pinecone、Weaviate)。
02、信息检索
接下来,当用户提出一个问题时,系统会:
对问题生成向量表示。
在向量数据库中,通过相似度检索找到最相关的文档片段。
检索效率和准确性在这一阶段至关重要,通常会选择高效的检索工具,如 FAISS、Milvus。
03、生成回答
检索到的信息作为上下文,输入到大模型中。大模型通过结合检索结果和自身的推理能力,生成符合语义逻辑的回答。这一步骤通常使用 OpenAI 的 GPT-4 或 Hugging Face 的开源模型。
大模型应用开发-为什么要使用RAG
克服大模型的“幻觉”
大模型有个很大的短板,就是它们的回答并非基于真实的事实,而是基于训练数据的统计规律。RAG 在回答中引入了明确的外部知识来源,大幅减少了“张冠李戴”的情况。
动态更新知识
大模型的训练数据通常有时效性,而通过 RAG,你的系统可以连接到实时更新的知识库,无需每次更新都重新训练模型。
降低开发成本
直接训练一个覆盖广泛知识的大模型代价高昂。而利用 RAG,开发者可以用一个小而通用的模型,通过接入特定领域的知识库,轻松实现定制化应用。
大模型应用开发-RAG 的应用场景
智能客服
很多公司在构建客服机器人时,都遇到一个问题:机器人总是答非所问。通过 RAG,机器人可以从公司知识库中检索最相关的信息,结合大模型生成专业且贴切的回答。
医疗问诊
医疗领域需要严谨的回答。RAG 可以从医学文献数据库中获取最新的研究资料,确保问诊系统不会因为“幻觉”提供错误的健康建议。
法律咨询
律师事务所的知识库包含大量条文和案例,通过 RAG 技术,可以为客户提供精准的法律支持,避免错漏。
教育辅导
RAG 能在教育领域大展拳脚,比如结合教材和题库,提供个性化的学习建议和习题解析。
大模型应用开发-构建RAG应用的关键挑战
在数据质量方面,如果知识库的内容有误,生成的回答同样会出错。因此,知识库的构建需要严格的质量把控。
而且知识库规模越大,检索的时间成本越高。采用高效的向量检索算法,如 HNSW,可以显著提升性能。
将检索结果与生成模型高效结合并非易事。检索到的信息是否足够准确、模型是否能理解检索到的上下文,这些都是需要优化的细节。
大模型应用开发-使用RAG构建问答系统
本次我们使用haystack构建一个产品说明书的问答系统:
haystack github地址: https://github.com/deepset-ai/haystack
Haystack 是一个开源框架,用于构建端到端的 检索增强生成(RAG) 系统和问答(QA)应用。它由 deepset 开发,旨在帮助开发者快速实现复杂的知识管理和问答功能,如基于文档的 QA 系统、聊天机器人、搜索引擎等。
示例代码:
# 安装 haystack
pip install farm-haystack[all]
# 准备资料 产品手册 product_manual.txt
产品名称: 超能智能手表 X1
功能: 支持心率监测、睡眠跟踪、GPS 跟踪、语音助手。
电池续航: 正常使用续航 7 天,重度使用续航 2 天。
充电时间: 2 小时可充满。
兼容性: 适配 Android 6.0 及以上,iOS 11.0 及以上。
注意事项: 请勿将手表暴露在超过 50°C 的环境中。
# 示例代码
from haystack.document_stores import FAISSDocumentStore
from haystack.nodes import EmbeddingRetriever, FARMReader
from haystack.pipelines import ExtractiveQAPipeline
from haystack.schema import Document
# 初始化向量数据库
document_store = FAISSDocumentStore(embedding_dim=768)
# 加载产品说明书数据
def load_manual(file_path):
"""读取产品说明书并格式化为 Haystack 文档"""
with open(file_path, "r", encoding="utf-8") as f:
content = f.read()
return [Document(content=content)]
docs = load_manual("product_manual.txt")
# 将文档写入向量数据库
document_store.write_documents(docs)
# 初始化检索器
retriever = EmbeddingRetriever(
document_store=document_store,
embedding_model="sentence-transformers/all-mpnet-base-v2", # 使用 Sentence-BERT
use_gpu=True
)
# 更新向量数据库中的嵌入
document_store.update_embeddings(retriever)
# 初始化阅读器(生成模型)
reader = FARMReader(model_name_or_path="deepset/roberta-base-squad2", use_gpu=True)
# 构建问答管道
pipeline = ExtractiveQAPipeline(reader, retriever)
# 进行问答
query = "这款手表有什么要注意的吗?"
result = pipeline.run(
query=query,
params={
"Retriever": {"top_k": 3}, # 检索最相关的 3 条文档
"Reader": {"top_k": 1} # 生成最优答案
}
)
# 输出答案
answer = result["answers"][0]
print(f"Question: {query}")
print(f"Answer: {answer.answer}")
# 输出
Batches: 100%
1/1 [00:00<00:00, 4.00it/s]
Inferencing Samples: 100%|██████████| 1/1 [00:02<00:00, 2.22s/ Batches]Question: 这款手表有什么要注意的吗?
Answer: 注意事项: 请勿将手表暴露在超过 50°C