AIGC应用实战:从零构建企业级RAG检索增强生成系统的完整方案

为什么企业需要RAG检索增强生成系统

大语言模型的训练数据存在截止日期,无法获取企业内部知识库的实时信息。AIGC应用落地过程中,模型幻觉和知识时效性是最突出的两个问题。检索增强生成(Retrieval-Augmented Generation)通过外部知识库检索与模型生成相结合的方式,有效解决了这两个痛点。

一套可用的RAG系统包含四个核心模块:文档处理与向量化、向量存储与检索、Prompt组装与模型调用、结果后处理与评估。这篇文章会从工程实现的角度,逐步拆解每个模块的技术选型和配置细节。

文档处理与向量化模块设计

文档处理是RAG系统的入口,决定了后续检索的质量上限。企业场景下,知识文档格式多样——PDF、Word、Markdown、HTML、甚至扫描件。处理流程分为三步:

第一步:文档解析与文本提取

PDF解析推荐PyMuPDF,速度快且对表格和公式有较好的保留能力。Word文档用python-docx提取段落。扫描件需要先走OCR,PaddleOCR在中文场景下识别率较高。

import fitz  # PyMuPDF

def extract_pdf_text(file_path):
    doc = fitz.open(file_path)
    text_chunks = []
    for page_num, page in enumerate(doc):
        text = page.get_text("text")
        if text.strip():
            text_chunks.append({
                "page": page_num + 1,
                "content": text.strip()
            })
    return text_chunks

第二步:文本分块(Chunking)

分块策略直接影响检索精度。固定长度分块最简单,但会切断语义完整性。推荐按段落+滑动窗口的方式分块,块大小512 token,重叠128 token,在语义完整性和检索召回率之间取得平衡。

def chunk_text(text, chunk_size=512, overlap=128):
    tokens = text.split()
    chunks = []
    start = 0
    while start < len(tokens):
        end = start + chunk_size
        chunk = " ".join(tokens[start:end])
        chunks.append(chunk)
        start += chunk_size - overlap
    return chunks

第三步:向量化嵌入

中文场景下,bge-large-zh-v1.5和m3e-base是两个主流选择。bge-large在C-MTEB基准上综合排名第一,m3e-base在轻量级部署场景表现优秀。向量化用sentence-transformers库:

from sentence_transformers import SentenceTransformer

model = SentenceTransformer('BAAI/bge-large-zh-v1.5')

def embed_texts(texts, batch_size=32):
    embeddings = []
    for i in range(0, len(texts), batch_size):
        batch = texts[i:i+batch_size]
        emb = model.encode(batch, normalize_embeddings=True)
        embeddings.extend(emb.tolist())
    return embeddings

注意启用normalize_embeddings,余弦相似度检索时归一化向量可以省去计算分母步骤。

向量存储与检索引擎选型

向量数据库选型需考虑数据规模和查询延迟:

- FAISS:本地部署首选,10万级以下文档性能最佳,支持IVF+PQ索引压缩
- Milvus:分布式场景推荐,支持多副本和水平扩展,百万级数据qps稳定
- Chroma:快速原型验证用,API简洁但不适合生产环境
- Elasticsearch 8.x:已有ES集群可直接启用dense_vector字段,减少组件维护

生产环境推荐Milvus 2.x,搭建示例如下:

from pymilvus import connections, Collection, FieldSchema, CollectionSchema, DataType

connections.connect(host="localhost", port="19530")

# 定义Collection
fields = [
    FieldSchema(name="id", dtype=DataType.INT64, is_primary=True, auto_id=True),
    FieldSchema(name="embedding", dtype=DataType.FLOAT_VECTOR, dim=1024),
    FieldSchema(name="text", dtype=DataType.VARCHAR, max_length=4096),
    FieldSchema(name="source", dtype=DataType.VARCHAR, max_length=512),
]
schema = CollectionSchema(fields, description="enterprise_knowledge_base")
collection = Collection("kb_vectors", schema)

# 创建IVF_FLAT索引
index_params = {
    "metric_type": "COSINE",
    "index_type": "IVF_FLAT",
    "params": {"nlist": 128}
}
collection.create_index(field_name="embedding", index_params=index_params)

检索时采用混合检索策略——向量相似度检索+关键词BM25检索加权融合,能将Top-5召回率提升15%-25%。

Prompt工程与模型调用模块

RAG场景下的Prompt模板要明确区分"检索到的上下文"和"用户问题",避免模型混淆信息来源。推荐的模板结构:

RAG_PROMPT_TEMPLATE = "你是一个专业的知识助手。请严格根据以下参考资料回答用户问题。如果参考资料中没有相关信息,请明确说明无法回答,不要编造内容。

参考资料:
{context}

用户问题:{question}

回答:"

模型调用建议使用流式输出,配合SSE推送到前端提升用户体验。OpenAI兼容接口的调用方式:

import openai

client = openai.OpenAI(
    api_key="your-api-key",
    base_url="https://api.example.com/v1"
)

def generate_answer(query, retrieved_docs):
    context = "\n\n".join([f"[文档{i+1}] {doc}" 
                             for i, doc in enumerate(retrieved_docs)])
    
    response = client.chat.completions.create(
        model="your-model-name",
        messages=[{
            "role": "user",
            "content": RAG_PROMPT_TEMPLATE.format(
                context=context, question=query
            )
        }],
        temperature=0.1,
        stream=True
    )
    
    for chunk in response:
        if chunk.choices[0].delta.content:
            yield chunk.choices[0].delta.content

temperature设为0.1是因为RAG场景下需要精确回答,降低随机性。max_tokens根据业务需求设置,一般2048够用。

结果后处理与评估体系

RAG系统的输出需要两层校验:

第一层:事实性校验。把模型输出与检索到的原文进行比对,检测是否存在幻觉。简单做法是用n-gram重叠度做快速过滤,重叠度低于30%的输出标记为"待人工审核"。

第二层:完整性校验。检查回答是否覆盖了用户问题的所有子问题。把用户问题拆解为子问题列表,逐条确认回答是否涵盖。

评估指标用RAGAS框架,重点关注三个维度:

- Faithfulness(忠实度):回答是否严格基于检索到的上下文
- Answer Relevancy(相关性):回答与用户问题的相关程度
- Context Precision(上下文精度):检索到的文档片段中有效信息的比例

# RAGAS评估示例
from ragas import evaluate
from ragas.metrics import faithfulness, answer_relevancy, context_precision

results = evaluate(
    dataset=eval_dataset,
    metrics=[faithfulness, answer_relevancy, context_precision]
)
print(results)

生产环境部署清单

一套完整的RAG系统上线前,需要确认以下配置项:

- 向量数据库配置nlist参数,10万文档建议nlist=128,100万文档建议nlist=256
- 嵌入模型部署用vLLM或TEI(Text Embeddings Inference),批量请求时吞吐量提升3-5倍
- 检索模块设置超时阈值,向量检索200ms内返回,超时降级为关键词检索
- 知识库增量更新机制:新文档入库后走全流程,向量写入后立即生效
- 日志记录每次检索的query、top-k文档ID、模型输出,用于后续分析检索质量

RAG系统的调优是持续过程。上线后通过日志分析低分query的模式,迭代优化分块策略和Prompt模板,逐步提升系统的可用性和准确性。

原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/aigc-ying-yong-shi-zhan-cong-ling-gou-jian-qi-ye-ji-rag/

(0)
小编小编
上一篇 12小时前
下一篇 11小时前

相关推荐