• 欢迎访问少将全栈,学会感恩,乐于付出,珍惜缘份,成就彼此、推荐使用最新版火狐浏览器和Chrome浏览器访问本网站。
  • 吐槽,投稿,删稿,交个朋友
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏少将全栈吧

从零搭建一个最小可用的RAG系统:代码、索引与检索三步走(2026实战)

AI Coding 实测 admin 21小时前 12次浏览 已收录 扫描二维码

引言

很多独立开发者想给产品接上”问答自己文档”的能力,一上来就被一堆概念劝退。其实最小可用的RAG没有你想的那么复杂:把文档切碎、向量化、存进索引,然后查的时候先向量检索再让LLM生成答案。本文用纯Python从零搭一个能跑的最小RAG,全程可复现。

为什么你需要RAG,而不是直接把文档塞给LLM

直接把几千页文档拼进提示词里,token成本和超时都扛不住。RAG的思路是”先缩小范围再回答”:只在检索到的最相关片段上生成答案。这样既省token,又降低幻觉——答案有原文出处可查。根据LangChain官方文档,检索增强生成是目前落地最广的企业级LLM应用范式之一。

RAG的三个核心模块

拆开看就三件事:文档切分与向量化、向量索引、检索+生成。任何一个环节做得糙,整体效果都打折。下面按顺序做。

第一步:文档切分与向量化

切分决定了检索的单位。我用定长加overlap的方式:每块500字符、重叠80字符,避免句子被拦腰截断导致语义丢失。向量化这里直接用OpenAI官方Embedding接口(text-embedding-3-small,官方定价每百万token约$0.02),够用且便宜。

from openai import OpenAI
client = OpenAI()

def split_text(text, chunk=500, overlap=80):
    return [text[i:i+chunk] for i in range(0, len(text), chunk-overlap)]

def embed(texts):
    resp = client.embeddings.create(model="text-embedding-3-small", input=texts)
    return [d.embedding for d in resp.data]

第二步:建索引与向量存储

小规模场景我直接上一个简单的向量库就够了,甚至可以先用内存里的列表暴力扫描(几千条完全没问题)。真要上规模再换pgvector这类带HNSW索引的方案。这里演示一个最小可运行的NaiveIndex,方便你理解检索原理。

import numpy as np

class NaiveIndex:
    def __init__(self):
        self.chunks, self.vecs = [], []
    def add(self, chunks, vecs):
        self.chunks += chunks
        self.vecs += vecs
    def search(self, q_vec, top_k=3):
        scores = np.dot(self.vecs, q_vec)
        idx = np.argsort(scores)[::-1][:top_k]
        return [self.chunks[i] for i in idx]

用余弦相似度(归一化后等价于点积)找出最相关的3个片段,这就是检索层。

第三步:检索 + 生成

检索到相关片段后,把内容放进system prompt,让模型只基于这些片段回答,并明说”不知道就说不知道”。这能显著压低幻觉概率。

def ask(question, index, top_k=3):
    q_vec = embed([question])[0]
    ctx = "\n---\n".join(index.search(q_vec, top_k))
    resp = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[
            {"role": "system",
             "content": "只根据提供的资料回答,资料里没有的明说不知道。"},
            {"role": "user",
             "content": f"资料:\n{ctx}\n\n问题:{question}"},
        ])
    return resp.choices[0].message.content

到这里,一个能回答你文档问题的最小RAG就成立了。

上线前一定要做的两件优化

第一,切分策略值得调:结构化文档按标题切比定长切更准。第二,别把所有检索结果都塞进去,top_k控制在3-5,多了噪音反而拉低答案质量。想查更细,参考Haystack或LlamaIndex的官方最佳实践文档,很多坑前人已经踩过。

小结

RAG没那么玄,核心就”切、存、查、答”四步。先跑通最小闭环,再逐步优化切分和索引,比一开始就上重型框架务实得多。

喜欢 (0)赏
[🍬谢谢你请我吃糖果🍬🍬~]
分享 (0)
关于作者:
少将,关注Web全栈开发、项目管理,持续不断的学习、努力成为一个更棒的开发,做最好的自己,让世界因你不同。