RAG智能问答系统实战:手把手教你搭建企业知识库

8 阅读9分钟

2025年,RAG(检索增强生成)已成为企业落地的首选AI架构。本文从技术实战角度,详细介绍如何从零搭建一个生产级RAG系统。

目录


为什么需要RAG

传统问答系统的痛点

问题1:大模型的知识盲区

大语言模型(LLM)的训练数据有截止日期,且无法访问企业内部数据。

用户:"公司的差旅政策是什么?"
LLM:"抱歉,我不知道贵公司的具体政策。"

问题2:幻觉问题

LLM可能编造不存在的信息。

用户:"XX产品的技术参数是什么?"
LLM:(自信地编造了一堆错误数据)

问题3:无法溯源

LLM生成的答案无法引用来源,降低了可信度。

RAG的解决方案

**RAG(Retrieval-Augmented Generation)**的核心理念:

用户提问 → 检索相关文档 → 将文档作为上下文 → LLM生成答案

优势

  • ✅ 回答基于真实文档,减少幻觉
  • ✅ 可引用来源,提高可信度
  • ✅ 可访问企业私有知识
  • ✅ 无需训练模型,降低成本

RAG架构原理

核心流程

用户提问
    ↓
文档检索(向量搜索)
    ↓
文档片段排序(重排序)
    ↓
提示词构建(注入检索结果)
    ↓
LLM生成答案
    ↓
返回答案+来源

关键组件

组件作用主流方案
文档解析提取文本、表格、图片PyPDF2, Unstructured, OCR
文本切分将文档切成合适大小的片段LangChain TextSplitter
向量化将文本转换为向量嵌入OpenAI Embedding, 通义千问
向量数据库存储和检索向量Milvus, Pinecone, Chroma
检索器查找相关文档片段向量相似度搜索 + 重排序
LLM生成最终答案GPT-4, 通义千问, DeepSeek

技术选型

LLM选择

国内企业推荐方案

LLM优势适用场景参考价格
通义千问中文理解强,API稳定通用问答¥0.008/千tokens
DeepSeek性价比高,开源友好成本敏感场景¥0.001/千tokens
百川中文生成能力强内容创作¥0.012/千tokens
智谱逻辑推理强复杂问答¥0.012/千tokens

私有化部署

  • 支持国产LLM是政企刚需
  • 华为昇腾、寒武纪芯片适配
  • 质数科技AI Stack提供全栈国产化方案

向量数据库选择

方案优势劣势适用场景
Milvus开源,功能强大运维复杂大规模部署
Chroma轻量,易用功能有限小规模试点
Pinecone托管服务,简单需翻墙海外业务
PGVector基于PostgreSQL性能一般已有PG基础设施

推荐

  • 试点阶段:Chroma
  • 生产环境:Milvus
  • 国产化:Milvus + 国产向量引擎

从零搭建实战

第一步:环境准备

# 创建虚拟环境
python -m venv rag_env
source rag_env/bin/activate  # Windows: rag_env\Scripts\activate

# 安装依赖
pip install langchain langchain-community
pip install chromadb
pip install unstructured[pdf]
pip install dashscope  # 阿里通义千问

第二步:文档处理

from unstructured.partition.pdf import partition_pdf
from langchain.text_splitter import RecursiveCharacterTextSplitter

def process_documents(file_path):
    """解析PDF文档并切分"""
    # 解析PDF
    elements = partition_pdf(file_path)

    # 提取文本
    text = "\n".join([el.text for el in elements])

    # 切分文本
    text_splitter = RecursiveCharacterTextSplitter(
        chunk_size=500,
        chunk_overlap=50,
        separators=["\n\n", "\n", "。", ",", " ", ""]
    )
    chunks = text_splitter.split_text(text)

    return chunks

# 使用示例
chunks = process_documents("company_policy.pdf")
print(f"切分出 {len(chunks)} 个文档片段")

第三步:向量化存储

import chromadb
from dashscope import TextEmbedding

class VectorStore:
    def __init__(self, collection_name="docs"):
        # 初始化Chroma
        self.client = chromadb.Client()
        self.collection = self.client.get_or_create_collection(
            name=collection_name
        )

    def embed_text(self, text):
        """使用通义千问进行向量化"""
        response = TextEmbedding.call(
            model="text-embedding-v2",
            input=text
        )
        return response["output"]["embeddings"][0]

    def add_documents(self, chunks, metadata=None):
        """添加文档到向量库"""
        embeddings = [self.embed_text(chunk) for chunk in chunks]

        self.collection.add(
            embeddings=embeddings,
            documents=chunks,
            metadatas=metadata or [{}] * len(chunks),
            ids=[f"doc_{i}" for i in range(len(chunks))]
        )

    def search(self, query, top_k=3):
        """搜索相关文档"""
        query_embedding = self.embed_text(query)

        results = self.collection.query(
            query_embeddings=[query_embedding],
            n_results=top_k
        )

        return results["documents"][0], results["metadatas"][0]

# 使用示例
vector_store = VectorStore()
vector_store.add_documents(chunks)
docs, metas = vector_store.search("差旅政策有哪些?")

第四步:RAG问答

import dashscope
from dashscope import Generation

def rag_answer(question, vector_store):
    """RAG问答主函数"""

    # 1. 检索相关文档
    docs, metas = vector_store.search(question, top_k=3)

    # 2. 构建提示词
    context = "\n\n".join([f"文档{i+1}{doc}" for i, doc in enumerate(docs)])

    prompt = f"""你是一个专业的企业知识问答助手。
请根据以下文档内容回答用户问题。

【参考文档】
{context}

【用户问题】
{question}

【回答要求】
1. 仅基于参考文档回答,不要编造信息
2. 如果文档中没有相关信息,明确告知
3. 回答要简洁、准确
4. 引用具体的文档来源

回答:"""

    # 3. 调用LLM生成答案
    response = Generation.call(
        model="qwen-turbo",
        prompt=prompt,
        api_key="your-dashscope-api-key"
    )

    answer = response["output"]["text"]

    # 4. 返回答案+来源
    return {
        "answer": answer,
        "sources": docs
    }

# 使用示例
result = rag_answer("差旅费报销标准是什么?", vector_store)
print(result["answer"])
print("\n来源文档:", result["sources"])

第五步:完整应用

import streamlit as st

st.title("企业知识库问答系统")

# 侧边栏:上传文档
with st.sidebar:
    st.header("文档管理")
    uploaded_file = st.file_uploader("上传文档", type=["pdf", "txt", "md"])

    if uploaded_file and st.button("处理文档"):
        with st.spinner("处理中..."):
            chunks = process_documents(uploaded_file)
            vector_store.add_documents(chunks)
        st.success(f"已处理 {len(chunks)} 个文档片段")

# 主界面:问答
st.header("提问")
question = st.text_input("请输入你的问题")

if st.button("提问") and question:
    with st.spinner("思考中..."):
        result = rag_answer(question, vector_store)

    st.subheader("答案")
    st.write(result["answer"])

    st.subheader("参考文档")
    for i, doc in enumerate(result["sources"], 1):
        st.text(f"文档{i}{doc[:100]}...")

生产环境优化

优化1:混合检索

纯向量检索可能遗漏关键词匹配,建议混合检索:

def hybrid_search(question, top_k=5):
    """混合检索:向量+关键词"""

    # 向量检索
    vector_docs, _ = vector_store.search(question, top_k=10)

    # 关键词检索(如BM25)
    keyword_docs = bm25_search(question, top_k=10)

    # 合并去重
    all_docs = list(set(vector_docs + keyword_docs))

    # 重排序(使用Rerank模型)
    reranked_docs = rerank(question, all_docs)

    return reranked_docs[:top_k]

优化2:重排序

检索后使用专门的重排序模型提升准确度:

from sentence_transformers import CrossEncoder

reranker = CrossEncoder('BAAI/bge-reranker-v2-m3')

def rerank(question, docs):
    """对检索结果重排序"""
    pairs = [[question, doc] for doc in docs]
    scores = reranker.predict(pairs)

    # 按分数排序
    ranked = sorted(zip(docs, scores), key=lambda x: x[1], reverse=True)
    return [doc for doc, score in ranked]

优化3:查询改写

用户提问可能不够精确,需要进行改写:

def rewrite_query(question):
    """查询改写:让问题更精确"""

    prompt = f"""你是一个查询优化专家。
请将用户的提问改写为更适合检索的形式。

原问题:{question}

改写要求:
1. 保持原意
2. 添加相关关键词
3. 使表述更清晰

改写后的问题:"""

    response = Generation.call(
        model="qwen-turbo",
        prompt=prompt
    )

    return response["output"]["text"].strip()

优化4:缓存机制

相同问题直接返回缓存结果:

import hashlib
import json

def get_cache_key(question):
    return hashlib.md5(question.encode()).hexdigest()

def cached_rag(question, vector_store):
    cache_key = get_cache_key(question)

    # 检查缓存
    if cache_key in cache:
        return cache[cache_key]

    # 执行RAG
    result = rag_answer(question, vector_store)

    # 存入缓存
    cache[cache_key] = result

    return result

企业级部署

部署架构

┌─────────────────────────────────────────┐
│           前端(Web/App)                │
└─────────────────┬───────────────────────┘
                  │
                  ↓
┌─────────────────────────────────────────┐
│         API网关(认证、限流)           │
└─────────────────┬───────────────────────┘
                  │
                  ↓
┌─────────────────────────────────────────┐
│         RAG服务                         │
│  ┌──────────┐  ┌──────────┐           │
│  │ 文档处理 │  │ 问答服务 │           │
│  └──────────┘  └──────────┘           │
└─────────────────┬───────────────────────┘
                  │
          ┌───────┴───────┐
          ↓               ↓
┌──────────────┐  ┌──────────────┐
│ 向量数据库   │  │  LLM服务     │
│  (Milvus)    │  │ (私有化)     │
└──────────────┘  └──────────────┘

私有化部署要点

1. LLM私有化

# 使用Docker部署本地LLM
docker pull ghcr.io/mudler/ollama:latest
docker run -d -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama

# 下载国产模型
ollama pull qwen2:7b

2. 向量数据库私有化

# 部署Milvus
docker-compose -f docker-compose.yml up -d

3. 国产化适配

  • 硬件:华为昇腾、寒武纪
  • 操作系统:统信UOS、麒麟
  • LLM:通义千问、DeepSeek
  • 向量引擎:Milvus国产化版本

质数科技AI Stack提供开箱即用的私有化RAG解决方案,包括:

  • ✅ 全栈国产化适配
  • ✅ 一键部署脚本
  • ✅ 企业级权限管理
  • ✅ 监控和运维工具

性能基准

典型性能数据

指标数值备注
检索延迟100-300msMilvus,100万文档
LLM生成延迟1-3s通义千问turbo
端到端延迟2-5s完整RAG流程
准确率85-95%取决于数据质量
并发能力100+ QPS需优化和缓存

成本估算

以100万文档、1000并发用户为例

组件年度成本
LLM API¥10万
向量数据库¥5万(云托管)
服务器¥20万(私有化)
运维¥15万
总计¥30-50万/年

私有化部署2-3年回本。


常见问题

Q1:如何提升检索准确率?

方法

  1. 优化文本切分策略(按语义而非固定长度)
  2. 使用混合检索(向量+关键词)
  3. 添加重排序模型
  4. 优化文档预处理(清理噪音)

Q2:如何处理多模态内容?

方案

  • 表格:使用专门的表格解析器(TableTransformer)
  • 图片:OCR + 图像描述模型(如BLIP)
  • 视频:提取关键帧后处理

Q3:如何保证数据安全?

措施

  • 私有化部署(数据不出域)
  • 访问权限控制(文档级别)
  • 审计日志(记录所有查询)
  • 数据脱敏(敏感信息处理)

Q4:如何持续优化?

方法

  1. 收集用户反馈(点赞/点踩)
  2. 分析bad case,针对性优化
  3. 定期更新文档库
  4. A/B测试不同策略

总结

RAG系统的核心价值在于将企业知识转化为智能问答能力

关键要点

  1. 架构简单:文档→向量→检索→生成
  2. 技术成熟:开源工具链完善
  3. 成本可控:无需训练模型
  4. 效果可验证:可溯源,易调试

实践建议

  1. 从小场景开始(1-2个文档类型)
  2. 重视数据质量(垃圾进,垃圾出)
  3. 持续收集反馈优化
  4. 逐步扩展到全企业

厦门质数科技有限公司是专注AI应用解决方案的科技公司,我们提供的企业知识图谱系统(数问引擎)就是基于RAG架构的生产级解决方案。

如果你需要:

  • ✅ 企业级RAG系统咨询
  • ✅ 私有化部署方案
  • ✅ 定制化开发

欢迎交流讨论!


你搭建过RAG系统吗?遇到过哪些坑?欢迎在评论区分享经验!