前面五篇你学会了 Token、Prompt、Embedding、向量库 Chroma、文档分块------零件齐了。这一篇把它们拼成一条线:一个端到端的最小 RAG 系统。我还造了一个"任何 LLM 都不可能知道"的虚构内部工具 WingFlow,专门用来看 RAG 到底能不能让模型"先现原形、再答对"。
开篇:LLM 不是全知,它只是"背过题"
你有没有发现一个矛盾:前面五篇你让 LLM 答 K8s 问题,它答得头头是道;可一旦问到你们公司自研的部署平台、内部的告警规则、上周刚改的运维手册------它立刻开始一本正经地胡说。
这不是模型笨,是它的知识停在训练截止那一天 ,你公司的内部知识它根本没见过。你逼它答,它就只能"编",行话叫幻觉(Hallucination)。
RAG(Retrieval-Augmented Generation,检索增强生成)就是来治这个病的。一句话讲透:RAG 不让 LLM 靠记忆答题,而是先去你的资料库里"翻出相关段落",再把段落和问题一起喂给 LLM,让它基于资料作答。
我写了一个不到 260 行的 rag.py,把前五篇学的全用上了,还特意造了一个虚构的内部工具 WingFlow(任何 LLM 都不可能知道),专门用来看 RAG 到底能不能让模型"先现原形、再答对"。
🚀 在开始前:把环境搭起来
这一篇把前五篇的依赖全部继承,再额外加 Chroma + Anthropic SDK 的两个变量:
powershell
# 1. 装依赖(Day3-5 那些)
pip install chromadb dashscope anthropic
# 2. 设环境变量------这一篇是"双 Key 架构"
# (a) embedding 通道:复用 Day3/4/5 那一套
$env:DASHSCOPE_API_KEY = "<你的 API Key>"
$env:DASHSCOPE_EMB_MODEL = "<你的 Embedding 模型名>"
$env:DASHSCOPE_DIM = "1024"
# (b) chat 通道:复用 Day1/2 那一套(Anthropic SDK 标准变量)
$env:ANTHROPIC_API_KEY = "<你的 API Key>"
$env:ANTHROPIC_MODEL = "<你的模型名>"
$env:ANTHROPIC_BASE_URL = "https://<你的 MaaS 平台域名>/anthropic"
# 3. 把两个文件放当前目录:
# - rag.py (主脚本, 一气跑完 7 步)
# - k8s_with_internal.md (5 章 K8s 手册 + 1 章虚构 WingFlow)
# 4. 跑
python rag.py
SRE 类比 :embedding 和 chat 走两个不同平台,就像你用 Prometheus 拉指标、用 Loki 存日志------不同子系统用最适合的工具,不强求"一套全家桶"。生产里 RAG 系统几乎一定是这种"组合架构"。
一、RAG 是什么:给 LLM 配一场"开卷考试"
闭卷考试:LLM 凭训练记忆答题 → 遇到没见过的就编。 开卷考试:先翻书(检索),再答题(生成)→ 答案有据可查。
RAG 就是把"翻书"这个动作工程化。完整数据流就 7 步,记住这个顺序,整篇就通了:
scss
load(读文档) → chunk(切块) → embed(向量化)
→ store(入库 Chroma) → retrieve(按问题检索 top-k)
→ augment(把资料拼进 prompt) → generate(LLM 生成答案)
SRE 类比:retrieve 就像你收到告警后,先去 Grafana 翻对应面板的曲线、去日志系统 grep 关键字,再综合判断根因。RAG 不过是把"人翻监控"变成"程序翻向量库"。
二、为什么非上 RAG 不可:三个反直觉事实
- LLM 的知识有截止日。问通用 K8s 它能答,问你上周上线的内部平台,它脑子里是空的。
- 私有/内部知识它永远学不到。除非你把资料喂进上下文,否则它只能瞎猜。
- 幻觉不是 bug,是特性。LLM 的本质是"预测下一个最合理的 token",你逼它答不知道的,它最合理的做法就是编一个听起来对的------这恰恰最危险。
所以 RAG 的价值不是"让模型变聪明",而是给模型一个它本来不知道、但你能提供的真实信息源。
三、关键代码拆解:端到端 pipeline
我的 rag.py 把 pipeline 完整跑通,而且大量复用前五篇的轮子------这就是工程累积的快感。
块 2:load + chunk + embed + store
python
with open(DOC_PATH) as f:
doc = f.read()
chunks = recursive_split(doc, chunk_size=500, overlap=50) # 复用 D-05
ef = DashScopeEmbeddingFunction(DASH_KEY, EMB_MODEL, DIM) # 复用 D-04
client = chromadb.PersistentClient(path=DATA_DIR) # D-04 Chroma
col = client.create_collection(name=COLLECTION_NAME, embedding_function=ef)
col.add(documents=chunks, ids=ids)
recursive_split:直接搬上一篇的递归切块(段落>句子>词,overlap=50)。DashScopeEmbeddingFunction:搬 Day4 的封装,调你的 Embedding 模型(1024 维)。- Chroma 持久化入库,collection 叫
k8s_wingflow。
retrieve:检索 top-3
python
results = col.query(query_texts=[q], n_results=TOP_K, include=["documents", "distances"])
retrieved = results["documents"][0] # TOP_K=3,取回 3 块最相关的资料
这一步就是 Day4 学的语义检索,取回和问题最像的 3 个 chunk。
augment:把资料拼进 prompt(RAG 的灵魂)
python
def build_rag_prompt(question, retrieved_chunks):
context = "\n\n---\n\n".join(
f"[资料 {i+1}]\n{c}" for i, c in enumerate(retrieved_chunks)
)
system = (
"你是 K8s + 内部工具 WingFlow 的技术助手。"
"回答必须基于下面 [资料 X] 提供的事实,不要编造。"
"如果资料不足,直接说「资料里没找到相关信息」,不要瞎猜。"
"回答里要标注引用了哪几条 [资料 X]。"
)
user = f"问题: {question}\n\n参考资料:\n{context}"
return system, user
这段是 Day2 Prompt 工程的直接应用,也是 RAG 防幻觉的三条铁律:

- 只基于资料答------锁死知识边界;
- 资料不足就说没找到------宁可拒答不编造;
- 标注引用 资料 X------让答案可溯源,人工可核对。
generate:调 LLM(双 key 架构)
python
def llm_call(system_prompt, user_prompt):
client = anthropic.Anthropic(
api_key=ANTHROPIC_API_KEY,
base_url=ANTHROPIC_BASE_URL,
)
resp = client.messages.create(
model=ANTHROPIC_MODEL,
max_tokens=500,
system=system_prompt,
messages=[{"role": "user", "content": user_prompt}],
)
text = "".join(b.text for b in resp.content if getattr(b, "type", "") == "text")
return text, usage

一个值得记的工程决策 :脚本里 Chat 模型切回 Day1-2 用过的 Anthropic SDK 兼容厂商 (避免 chat 模型被某家免费档卡住)。所以整套系统是双 Key 架构:
| 环节 | 模型 | 厂商 |
|---|---|---|
| Embedding | 你的 Embedding 模型(1024 维) | DASHSCOPE(Day3-5 同款) |
| Chat | 你的模型名 via Anthropic SDK | MaaS 平台(Day1-2 同款) |
SRE 类比 :就像用同一个
kubectl连不同集群------anthropicSDK 是统一客户端,base_url指向平台的兼容端点,换厂商不换代码。生产里 embedding 和 chat 用不同家,是常态不是例外。
四、实验设计:WingFlow 是"幻觉试金石"
文档 k8s_with_internal.md 是 5 章 K8s 手册 + 1 章虚构的 WingFlow 内部平台(版本号、CLI、CRD、灰度字段全是编的)。任何 LLM 训练数据里都没有 WingFlow,所以:
- 无 RAG 直接问:LLM 只能凭空编一个 WingFlow 的排障步骤------必翻车。
- 有 RAG:检索到 5.2/5.4 节真实内容,LLM 基于资料答对。
脚本用 4 个 query 同时跑"无 RAG"和"有 RAG"两种模式对比:
makefile
Q1: Pod 卡在 Pending 怎么排查 (通用 K8s)
Q2: 容器反复崩溃 CrashLoopBackOff 怎么 debug (通用 K8s)
Q3: WingFlow 部署报 WingFlowAgentTimeout 怎么排查 (WingFlow 专属)
Q4: WingFlow 怎么配灰度发布? 用什么字段? (WingFlow 专属)
对每个 query,脚本打印 [1] WITHOUT RAG 和 [2] WITH RAG 两种答案 + 检索到的 资料 X + 耗时 + token 数。
五、预期对比:RAG 赢在哪(诚实说明)
你跑脚本会看到真实输出。基于设计意图,预期结论是确定的(WingFlow 在文档里有、在 LLM 训练数据里无):

| Query | 无 RAG | 有 RAG |
|---|---|---|
| Q1 Pod Pending | 能答,但无引用、可能混通用经验 | 命中 1.1 节,带 资料 X 引用,更准 |
| Q2 CrashLoopBackOff | 能答,泛泛而谈 | 命中 1.2 节,含 OOM 针对性步骤 |
| Q3 WingFlowAgentTimeout | 必编造(它根本不知道 WingFlow) | 命中 5.2 节,给出 5 步真实排障 |
| Q4 WingFlow 灰度字段 | 必编造(canarySteps 是编的) | 命中 5.4 节,给出 strategy: canary + canarySteps 配置 |
核心结论 :通用问题两者都能答,RAG 胜在"有据可查";WingFlow 这类内部知识,无 RAG 直接现原形,有 RAG 才能答对------这就是 RAG 存在的根本理由。
⚠️ 说明:上表是"基于脚本设计与文档内容"的预期,具体答案文字和耗时/token 以你本地跑
rag.py的输出为准,我没有编造运行结果。
六、5 大误区
- "RAG 是让 LLM 变聪明" ------ 错。RAG 不提升模型智商,只是给它递小抄。模型本身的能力上限不变。
- "检索块越多越好" ------ 错。top-k 太大,无关资料污染上下文,反而带偏答案,一般 3~5 足够。
- "不分块直接 RAG" ------ 错。整篇当一块(Day5 说过),语义稀释 + 超长超限,检索精度崩。
- "RAG 能消除所有幻觉" ------ 错。检索不到相关资料时,LLM 仍可能编;system 里的"资料不足就说没找到"才是最后一道闸。
- "Prompt 随便写" ------ 错。
build_rag_prompt的三条铁律(基于资料/不编造/标引用)是 RAG 防胡说的命门,Day2 的功夫在这用上了。
七、学习建议(照着做一遍)
- 手跑
rag.py:设好DASHSCOPE_API_KEY(embedding)和ANTHROPIC_API_KEY(chat)两个环境变量,看 4 个 query 的两种答案对比。 - 记住双 Key 架构:embedding 和 chat 用不同厂商很正常,别被"一套模型走天下"误导。
- 调 top-k:从 3 试到 5,看答案质量拐点,不是越大越好。
- system 约束不能省:RAG 的 prompt 一定要写"基于资料、不编造、标引用",这是防幻觉的工程护栏。
- 造自己的 WingFlow:拿一份公司内部文档(规章制度、内部平台手册),问 LLM 一个它必不知道的细节,验证 RAG 是否真的"先现原形、再答对"。
📦 配套代码(克隆就能跑)
powershell
# 1. 准备目录
mkdir my-ai-day6
cd my-ai-day6
# 2. 装依赖
pip install chromadb dashscope anthropic
# 3. 设环境变量(双 Key 架构)
$env:DASHSCOPE_API_KEY = "<你的 API Key>"
$env:DASHSCOPE_EMB_MODEL = "<你的 Embedding 模型名>"
$env:DASHSCOPE_DIM = "1024"
$env:ANTHROPIC_API_KEY = "<你的 API Key>"
$env:ANTHROPIC_MODEL = "<你的模型名>"
$env:ANTHROPIC_BASE_URL = "https://<你的 MaaS 平台域名>/anthropic"
# 4. 把这两个文件放当前目录:
# - rag.py (主脚本, 7 步一气跑完)
# - k8s_with_internal.md (5 章 K8s 手册 + 1 章虚构 WingFlow)
# 5. 跑
python rag.py
跑通后看 4 个 query 的 [1] WITHOUT RAG 和 [2] WITH RAG 对比------亲眼看 WingFlow 这种"训练数据里完全没有"的内部知识,无 RAG 怎么编、有 RAG 怎么答对。这就是 RAG 存在的根本证据。
🔧 本地化配置(重要!)
上面代码里的 <你的 API Key> / <你的模型名> / <你的 MaaS 平台域名> 是通用占位符。这一篇的"双 Key 架构"对应两套 env:
| 占位符 | 替换为 | 在哪查 |
|---|---|---|
<你的 API Key> (embedding) |
你平台的 Embedding API Key | 平台控制台 → API Key 管理 |
<你的 Embedding 模型名> |
你平台支持的 Embedding 模型 | 平台控制台 → 模型列表 → "文本向量" 类目 |
<你的 API Key> (chat) |
你平台的 Chat API Key | 同上 |
<你的模型名> |
你平台的 Chat 模型 | 平台控制台 → 模型列表 → "对话" 类目 |
<你的 MaaS 平台域名> |
你的 MaaS 平台域名(去掉 https://) | 平台控制台首页 |
k8s_with_internal.md |
✅ 保留 (脚本读的文件名,跟 DOC_PATH 强绑定) |
|
DASHSCOPE_* |
✅ 保留(DashScope SDK 公开标准) | |
ANTHROPIC_* |
✅ 保留(Anthropic SDK 公开标准) | |
chroma_rag 数据目录 |
✅ 保留(脚本生成的公开约定) |
说明:
- 双 env 不是冗余。embedding 走一家(免费档友好),chat 走另一家(能力更强),是工程上常见的拆分。
- 两套
*_API_KEY可以是同一个值------如果你只有一家平台的 Key,两个变量填同一个也能跑。 <你的 MaaS 平台域名>/anthropic是 Anthropic 兼容协议的接入点 。如果你的平台不兼容 Anthropic SDK,把client = anthropic.Anthropic(...)换成openai.OpenAI(base_url=..., api_key=...)即可,其余代码不变。- API Key 绝对不要写进代码或提交到 Git。
- Day1-Day6 全部跑过:你已经具备亲手搭一个"公司知识库问答机器人"的全部基础。
总结:从 Token 到 RAG,一条线串完了
回头看这条学习线:
- Day1 Token / 上下文 / temperature / max_tokens / Tool Use------看懂 LLM 怎么"读"和"说";
- Day2 Prompt 工程------学会用结构约束模型行为(这一篇的 system 铁律就是它的应用);
- Day3 Embedding------把文本变成可计算的向量;
- Day4 Chroma------把向量存起来、能语义检索;
- Day5 Chunking------把长文档切成可被精准检索的单元;
- Day6(这一篇)------把上面五块焊成一条 RAG 流水线,让 LLM 基于你的资料开口说话。
一句话收住:Embedding 让文本可计算,向量库让文本可检索,分块让检索更准,而 RAG 让检索到的资料真正变成 LLM 的答案。 前五天是零件,这一篇是整车。
如果你一直跟到这,你已经具备亲手搭一个"公司知识库问答机器人"的全部基础了。建议把六篇按顺序收藏,从 Day1 的脚本跑起,每一篇都是下一章的铺垫。
下一篇预告:D-07 让 RAG 更靠谱------重排序 / 元数据过滤 / 评估指标
最小 RAG 跑通了,但**"检索准不准、答案对不对"凭感觉**------工业级 RAG 系统必须有三件套:重排序(Rerank) 把 top-50 再精排成 top-3、元数据过滤 按时间/作者/部门缩小范围、评估指标 用 Hit Rate / MRR / faithfulness 量化效果。下一篇我们就把这三件事跑通,把"玩具 RAG"升级成"生产 RAG"。
关注我,把 AI 从"能跑"学到"能上生产"。
这里是「运维视角学 AI」,一个用 SRE 思维拆解 AI 的一线实战笔记。
💬 你最想拿哪份内部文档搭个 RAG?评论区聊聊。
📌 回复「Day5」复习 Chunking 三策略,回复「Day4」复习 Chroma CRUD。
⭐ 收藏这篇,跑 RAG 时先回来对照 5 大误区和三铁律。
话题标签:#AI学习笔记 #RAG #检索增强生成 #大模型实战 #向量数据库 #幻觉治理 #SRE学AI #Prompt工程
