别再只会调大模型了:用 Python 搭一套自己的知识库问答系统(RAG 实战指南)

举报
Echo_Wish 发表于 2026/03/02 15:52:57 2026/03/02
【摘要】 别再只会调大模型了:用 Python 搭一套自己的知识库问答系统(RAG 实战指南)

别再只会调大模型了:用 Python 搭一套自己的知识库问答系统(RAG 实战指南)

大家好,我是 Echo_Wish。

这两年很多人玩大模型,张口就是“接个 API 就行”。
但真正落地的时候你会发现一个残酷现实:

大模型很聪明,但它对你公司的资料一无所知。

你让它回答:

  • 公司内部规范?
  • 产品技术白皮书?
  • 项目历史文档?
  • 你的博客沉淀?

它只能开始“编”。

这时候,RAG(Retrieval-Augmented Generation)就登场了。

今天我带你从 0 开始,用 Python 搭一个自己的知识库问答系统。
不整虚的,直接实战。


一、RAG 到底是什么?一句话讲明白

RAG = 检索 + 大模型生成。

流程非常简单:

用户问题
   ↓
向量检索(从知识库找相关内容)
   ↓
把检索结果拼进 prompt
   ↓
交给大模型生成答案

也就是说:

模型负责“说话”,知识库负责“内容”。

你不给模型资料,它只能瞎猜;
你给它精准资料,它就能像专家一样回答。


二、系统整体架构长什么样?

先看一个简化版结构图:

核心组件就四块:

  1. 文档加载
  2. 文本切块
  3. 向量化(Embedding)
  4. 向量检索 + LLM 生成

我们一步步来。


三、第一步:准备文档

假设我们有一堆 Markdown / PDF / TXT 文档。

先装几个依赖:

pip install langchain faiss-cpu sentence-transformers openai

四、第二步:文档切块(Chunking)

很多人忽略这一点。

如果你把整本 PDF 一次性 embedding,
检索效果会差得离谱。

正确做法是:切块。

from langchain.text_splitter import RecursiveCharacterTextSplitter

text = open("knowledge.txt", "r", encoding="utf-8").read()

splitter = RecursiveCharacterTextSplitter(
    chunk_size=500,
    chunk_overlap=100
)

docs = splitter.create_documents([text])

print("切块数量:", len(docs))

为什么要 overlap?

因为语义是连续的,
你不做重叠,信息会断层。


五、第三步:生成向量(Embedding)

Embedding 是 RAG 的灵魂。

我们用 sentence-transformers 举例:

from sentence_transformers import SentenceTransformer
import numpy as np

model = SentenceTransformer("all-MiniLM-L6-v2")

texts = [doc.page_content for doc in docs]
embeddings = model.encode(texts)

print("向量维度:", embeddings.shape)

此时,每个文本块都变成了一个向量。

这就是“语义表示”。


六、第四步:构建向量数据库

这里我们用 FAISS。

import faiss

dimension = embeddings.shape[1]
index = faiss.IndexFlatL2(dimension)

index.add(np.array(embeddings))

print("向量库大小:", index.ntotal)

现在你已经有了一个可搜索的知识库。


七、第五步:实现检索

当用户提问时:

query = "公司数据库怎么做备份?"

query_vec = model.encode([query])

D, I = index.search(np.array(query_vec), k=3)

for idx in I[0]:
    print("命中内容:", texts[idx])

这一步会返回最相关的 3 段文本。

注意:

RAG 的好坏,80% 在检索。

如果检索错了,后面再强的大模型都没用。


八、第六步:交给大模型生成答案

把检索到的内容拼进 prompt:

import openai

context = "\n".join([texts[i] for i in I[0]])

prompt = f"""
基于以下资料回答问题:

{context}

问题:{query}
"""

response = openai.ChatCompletion.create(
    model="gpt-4o-mini",
    messages=[{"role": "user", "content": prompt}]
)

print(response["choices"][0]["message"]["content"])

此时,大模型不是“猜”,
而是“基于资料回答”。

这就是 RAG 的核心价值。


九、做成一个简单问答系统

我们封装一下:

def ask_question(query):
    query_vec = model.encode([query])
    D, I = index.search(np.array(query_vec), k=3)
    
    context = "\n".join([texts[i] for i in I[0]])
    
    prompt = f"""
    基于以下资料回答问题:
    {context}
    问题:{query}
    """
    
    response = openai.ChatCompletion.create(
        model="gpt-4o-mini",
        messages=[{"role": "user", "content": prompt}]
    )
    
    return response["choices"][0]["message"]["content"]

你已经拥有一个基础知识库问答系统。


十、真实落地要注意什么?

说点真话。

很多人做 RAG 做着做着发现:

  • 检索不准
  • 答案乱拼
  • 重复内容多
  • 上下文不连贯

这时候你要做三件事:

1️⃣ 优化切块策略

不是固定 500 字就完事。
有时候按标题切更好。

2️⃣ 用更强的 Embedding 模型

Embedding 决定检索质量。

3️⃣ 做 rerank

可以再加一层排序模型,提升命中质量。


十一、我的一点感受

我自己做过很多 RAG 项目。

最大的误区是:

把 RAG 当成“接 API”。

其实它更像一个“搜索系统 + 提示工程”的融合体。

你需要理解:

  • 向量空间
  • 语义相似度
  • Prompt 结构
  • 数据治理

RAG 做得好,是企业级生产力工具。
做得不好,就是一个高级“拼接器”。


十二、未来怎么玩?

再往前一步,可以加:

  • 多知识库路由
  • 权限控制
  • 实时更新
  • 增量向量索引
  • Agent 自动调用

RAG 不是终点。

它是企业智能化的入口。


结尾

如果你还没做过 RAG,我建议你一定动手试一次。

当你第一次看到模型准确引用你自己的文档回答问题时——

那种感觉,就像你亲手造了一个“会读书的助理”。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。