AI Infra 训练营
总览
  • Day 1 · 集群起步 + CNI
  • Day 2 · 控制面 + etcd
  • Day 3 · CRD + Operator + Webhook
  • Day 4 · 存储深度
  • Day 5 · 卷扩容 + 安全
  • Day 6 · 调度 + 可观测
  • Day 7 · Harbor + ArgoCD + Mesh
  • Day 8 · AI Infra
  • Day 9 · Triton + GPU
  • Day 10 · MIG + HPA + 量化
  • Day 11 · AI Agent 端到端
  • Day 12 · 灾备
  • Day 13 · Operator + 联邦 + Mesh + RAG
  • Day 14 · CKA / CKS + 总结
  • LLM 训练手册
  • RAG + Agent 手册
  • 推理优化手册
  • 上下文工程手册
  • Agent 开发手册
  • 面试深度复盘
  • 训练 v2 深度手册
HiHuo 主站
GitHub
总览
  • Day 1 · 集群起步 + CNI
  • Day 2 · 控制面 + etcd
  • Day 3 · CRD + Operator + Webhook
  • Day 4 · 存储深度
  • Day 5 · 卷扩容 + 安全
  • Day 6 · 调度 + 可观测
  • Day 7 · Harbor + ArgoCD + Mesh
  • Day 8 · AI Infra
  • Day 9 · Triton + GPU
  • Day 10 · MIG + HPA + 量化
  • Day 11 · AI Agent 端到端
  • Day 12 · 灾备
  • Day 13 · Operator + 联邦 + Mesh + RAG
  • Day 14 · CKA / CKS + 总结
  • LLM 训练手册
  • RAG + Agent 手册
  • 推理优化手册
  • 上下文工程手册
  • Agent 开发手册
  • 面试深度复盘
  • 训练 v2 深度手册
HiHuo 主站
GitHub
  • Bonus 手册

    • Bonus 专栏:LLM 训练全景手册(框架 / 训练模式 / 输入输出 / 最简测试)
    • Bonus-2 · RAG / Agent 全景实战手册
    • Bonus-3 · LLM 推理优化全景实战手册
    • Bonus-4 · LLM 上下文长度原理全景手册
    • Bonus-5 · Agent 开发原理与面试准备手册
    • Bonus-6 · 面试深挖项实战手册
  • 扩展

    • 训练专栏 v2 · LLaMA-Factory / DeepSpeed / Megatron 深度调参手册

Bonus-2 · RAG / Agent 全景实战手册

🎯 目标:从向量库选型 → 检索策略 → Agent 框架 → tool calling,搭一条真能跑的 RAG/Agent 链路,并落地实测结果。 🧪 实测环境:gpu1 (A800-SXM4-40GB) · k3s · vLLM Qwen2.5-3B (10.43.165.182:8000) · Python 3.10 · venv /opt/bonus2/venv (479 MB) 📅 实测日期:2026-05-27


0. 为什么 RAG/Agent 是 LLM 落地的"半壁江山"

裸调 LLM 的两个硬伤:

痛点表现解法
知识截止"Claude 4.X 啥时候发的?" 答不出来RAG: 检索外部知识喂进 context
不能动手"查一下今天日历,然后发邮件" 做不到Agent + Tool calling: 让模型调函数

RAG = 检索增强生成 · Agent = 决策 + 工具循环。两者经常组合(Agent 里某个 tool 就是 RAG retriever)。


1. 向量库全景

1.1 主流方案对比

引擎部署语言适用规模索引特点
ChromaDBembedded / server / cloudPython 原生< 10M docsHNSW最简,Python 用户友好,自带 embedding
Qdrantserver / cloudRust core10M-1BHNSW + 量化性能强,过滤表达式好用,gRPC + REST
Milvusk8s 分布式C++ core1B+HNSW / IVF / DiskANN大厂级,水平扩展,运维重
Weaviatek8s / cloudGo10M-100MHNSW内置 generative module(自动 RAG)
pgvectorPostgreSQL 扩展PG plugin< 10MIVF / HNSW不引入新组件,跟业务表 join 友好
FAISSin-processC++ + Python任意IVF / HNSW / PQMeta 出的"底层库",自己组装,无服务
OpenSearch / ElasticsearchserverJavaTB 级HNSW + 倒排同时支持 BM25 + dense,hybrid retrieval 首选
VespaserverJava + C++TB 级HNSW + ColBERT检索+排序一体,Yahoo/Spotify 在用

1.2 选型决策树

QPS < 100,  docs < 100K     → ChromaDB embedded
QPS < 1K,   docs < 10M      → Qdrant single node
QPS > 1K,   docs > 100M     → Milvus cluster / Vespa
已有 PostgreSQL,数据强一致  → pgvector
需要 hybrid (BM25 + dense)  → OpenSearch / Vespa
完全离线 / 嵌入式            → FAISS in-process

1.3 本次实测选 ChromaDB:轻、快、零配置

pip install chromadb openai
# 479MB venv, 含 onnxruntime / numpy / protobuf / tokenizers / pydantic

2. Embedding 模型全景

模型维度语言体积备注
all-MiniLM-L6-v2384EN 为主90 MBChromaDB 默认,onnx,中文质量差
bge-large-zh-v1.51024中文1.3 GB智源,中文 retrieval 排行榜第一梯队
bge-m31024多语2.3 GB同时输出 dense / sparse / colbert
m3e-base768中英410 MB国产,中英混合场景
text-embedding-3-large3072100+ 语言APIOpenAI, $0.13/1M tokens
voyage-31024多语APIAnthropic 推荐,RAG 专精
gte-Qwen2-7B-instruct4096多语14 GB大模型当 embedding,top tier,慢

💡 中文 RAG 不要用 all-MiniLM,改用 bge-base-zh 起步。本次 demo 用默认 onnx 模型纯属图轻,代价是 retrieval 质量打折(见下文实测)。


3. 检索策略全景

3.1 单路检索

策略原理优势短板
Dense (semantic)embedding cosine同义/改写鲁棒字符精确匹配差(产品名/代码)
Sparse (BM25)词袋 + TF-IDF精确字符匹配,可解释同义词盲区

3.2 多路混合

策略实现何时用
Hybrid (dense + BM25)RRF 融合 / 加权和大多数生产场景默认
HyDE (Hypothetical Document Embedding)先让 LLM 生成假答案,再用假答案的 embedding 检索query 太短/太抽象
Multi-QueryLLM 重写 query 成 N 个,各自检索,合并query 模糊 / 多意图
Step-backLLM 把 query 抽象成更上层问题再检索需要背景知识的复杂问题
Parent-Documentchild chunk 索引,命中后召回 parent 段需要完整上下文(法律、医疗)

3.3 重排(Re-ranking)

检索召回 top-N(N=50-100)后,用 cross-encoder 重新打分,取 top-K(K=3-10):

Reranker类型备注
bge-reranker-largecross-encoder中文好,免费
cohere-rerank-v3API多语,$2/1k searches
mxbai-rerank-largecross-encoderEN,SOTA
ColBERT v2late interaction速度兼顾质量

3.4 分块策略 (Chunking)

策略适用
Fixed-size (e.g. 512 tokens, 50 overlap)大多数,简单可用
Semantic (按句子 embedding 突变切)文档语义跳跃明显时
Recursive (按 \n\n → \n → 逐层切)LangChain 默认,工程上稳
Markdown header split技术文档,结构化文件
Code-aware (AST)代码库 RAG

4. 实测 1:ChromaDB + ONNX embedding + vLLM 端到端 RAG

4.1 完整 demo 代码 (/opt/bonus2/rag_demo.py)

import chromadb
from openai import OpenAI
import time

DOCS = [
    {"id": "k8s-pod",   "text": "Pod 是 K8s 最小调度单元,包含 1 个或多个容器共享 network namespace 和 volume,生命周期一致。"},
    {"id": "k8s-deploy","text": "Deployment 通过 ReplicaSet 间接管理 Pod 副本数,支持滚动升级(RollingUpdate)和 Recreate 两种策略。"},
    {"id": "k8s-svc",   "text": "Service 通过 selector 把 Pod 抽象成稳定的 ClusterIP / NodePort / LoadBalancer 服务,后端 Pod 死掉自动剔除。"},
    {"id": "k8s-pvc",   "text": "PVC 是用户对存储的声明式申请,绑定 PV 后通过 CSI 驱动挂载到 Pod。"},
    {"id": "k8s-hpa",   "text": "HPA 基于 metrics-server 提供的 CPU/Memory 或 custom metric 自动扩缩 Deployment 副本数。"},
    {"id": "vllm-pa",   "text": "vLLM 的 PagedAttention 把 KV cache 分页管理,显存碎片减少 4×,30 并发请求下吞吐提升 24×。"},
    {"id": "vllm-cb",   "text": "Continuous Batching 让 vLLM 在 iteration level 调度,新请求随时加入,不需要等 batch 凑齐。"},
    {"id": "mig",       "text": "NVIDIA MIG (Multi-Instance GPU) 在 A100/A800/H100 上把单卡硬件切成最多 7 个独立 instance,显存和 SM 都隔离。"},
]

client = chromadb.PersistentClient(path="/opt/bonus2/chroma_data")
collection = client.get_or_create_collection(name="k8s_facts")
collection.upsert(ids=[d["id"] for d in DOCS], documents=[d["text"] for d in DOCS])

llm = OpenAI(base_url="http://10.43.165.182:8000/v1", api_key="not-needed")

def rag_chat(question, top_k=3):
    res = collection.query(query_texts=[question], n_results=top_k)
    docs = res["documents"][0]; ids = res["ids"][0]
    context = "\n".join(f"[{i+1}] ({did}) {d}" for i, (did, d) in enumerate(zip(ids, docs)))
    prompt = f"请基于以下知识回答(末尾标注源 [1][2][3]):\n知识:\n{context}\n\n问题: {question}\n\n答复:"
    t0 = time.time()
    resp = llm.chat.completions.create(
        model="qwen2.5-3b",
        messages=[{"role": "user", "content": prompt}],
        max_tokens=200, temperature=0.3,
    )
    return resp.choices[0].message.content, time.time()-t0, ids

4.2 实测输出(2026-05-27 实跑)

检索质量

Q: K8s 的 Pod 是什么?
  top-1 [k8s-pod] (dist=0.605): Pod 是 K8s 最小调度单元... ✅
  top-2 [k8s-pvc] (dist=0.990): PVC 是用户对存储的声明式申请...

Q: vLLM 为什么吞吐高?
  top-1 [k8s-pvc] (dist=1.214): PVC...     ❌ 错配
  top-2 [vllm-pa] (dist=1.270): vLLM PagedAttention... (才到 top-2)

Q: A800 GPU 怎么切片?
  top-1 [mig] (dist=0.645): NVIDIA MIG... ✅
  top-2 [k8s-hpa] (dist=1.321): HPA...

Q: 怎么让 K8s 自动扩缩?
  top-1 [k8s-pod] (dist=0.805): Pod...    ❌ 应该召 hpa
  top-2 [k8s-deploy] (dist=1.174): Deployment...

真实问题:vLLM 为什么吞吐高 和 怎么让 K8s 自动扩缩 两题的 top-1 都错了。原因清晰:

ChromaDB 默认 embedding 是 all-MiniLM-L6-v2,英文模型。中文 query 走它会丢语义。生产中文 RAG 必须换 bge-base-zh 或 bge-m3。

但好在 RAG 是 top-K 多路召回,top_k=3 时正确文档基本都进了 context,LLM 仍能从中挑出真正相关的写进答案。

端到端 RAG 生成质量(top_k=3)

QLLM 答案(节选)来源命中耗时
K8s 的 Pod 是什么?"Kubernetes 最小的调度单元。一个 Pod 可以包含一个或多个容器,共享网络命名空间和存储卷..." ✅k8s-pod, k8s-pvc, k8s-deploy1919 ms
vLLM 为什么吞吐高?"PagedAttention 将 KV cache 分页管理,显存碎片减少,30 并发吞吐提升 24 倍" ✅k8s-pvc, vllm-pa, k8s-pod1596 ms
A800 GPU 怎么切片?"通过 NVIDIA MIG 技术被切分成最多 7 个独立的 instance..." ✅mig, k8s-hpa, vllm-pa1572 ms
怎么让 K8s 自动扩缩?"通过 Deployment + HPA + ReplicaSet..."(部分跑题) ⚠️k8s-pod, k8s-deploy, k8s-pvc4101 ms

关键观察:即使 top-1 embedding 错,只要 top-K 把对的文档捞进来,LLM 端的"语义裁判"还是能挑出正确事实。这就是 RAG 容错性强于纯 embedding 的核心原因。

4.3 优化方向

  1. 换中文 embedding:pip install sentence-transformers + bge-base-zh-v1.5
  2. 加 reranker:bge-reranker-base 把 top-20 重排成 top-3
  3. Hybrid search:同时跑 BM25 + dense,RRF 融合
  4. HyDE:让 LLM 先生成假答案,用假答案做检索

5. Agent 框架全景

框架立场学习曲线适用
LangChain一切皆 Chain,生态最大高(API 不稳)快速搭原型,Python 后端
LangGraphLangChain 的状态机版本中复杂多步 agent(有循环/分支)
LlamaIndexRAG 主线,从 doc loader 到 query engine中文档 QA / 数据应用
AutoGen多 agent 对话(MS Research)中角色协作型(Coder + Reviewer)
CrewAI类 AutoGen,UX 更简低业务流程编排
smolagentsHuggingFace 出品,Code-Agent 范式低想让模型直接写 Python 跑
OpenAI Agents SDKOpenAI 官方,2025 推出低用 OpenAI/Anthropic API 时首选
Pydantic-AI强类型 schema 优先中生产代码,严结构化输出
MCP (Anthropic)Tool 服务的协议标准,跨 agent 复用中Tool 资源跨产品/团队共享

5.1 选型建议

快速原型 + Python 后端       → LangChain / LangGraph
文档 QA 主线                  → LlamaIndex
多角色协作场景                → AutoGen / CrewAI
生产 API 强 schema           → Pydantic-AI / OpenAI Agents SDK
跨工具复用 / 标准化           → 把工具暴露成 MCP server
"我就是想让它写 Python"       → smolagents

5.2 ReAct = Agent 的最小核心算法

核心 prompt 范式:

Thought: 思考下一步
Action: tool_name(args)
Observation: <工具返回>
Thought: 综合判断
Action: ...
...
Final Answer: <最终回答>

循环:LLM 输出 → 正则解析 Action → 执行 tool → 把 Observation 追加到 prompt → 再 call LLM,直到 Final Answer 出现。 这是所有 Agent 框架的"底层逻辑"——你拆任何 LangChain agent,本质都是这个 loop。


6. Tool Calling 三种实现方式

方式模型要求优势劣势
A. OpenAI Function Calling (推荐)模型微调过,如 Qwen2.5 / GPT-4o / Claude模型直出结构化 JSON,稳依赖模型支持 + 推理框架开启 --enable-auto-tool-choice
B. ReAct prompting任意模型0 改动,任意推理后端解析脆弱,需要正则 + 重试
C. Code-as-action (smolagents)任意模型表达力强,可以组合需要沙箱执行,安全风险

6.1 vLLM 开启原生 function calling

# 启动 vllm-3b 时加这两个参数
vllm serve Qwen/Qwen2.5-3B-Instruct \
  --enable-auto-tool-choice \
  --tool-call-parser hermes

本次实测条件:线上的 vllm-3b 启动时没开这两个 flag,所以走 B. ReAct 方案。


7. 实测 2:ReAct Agent + 3 工具

7.1 工具定义(/opt/bonus2/agent_demo.py)

def tool_calculator(expr):     # safe eval, 限制在 math 模块
def tool_datetime(_):          # 当前时间
def tool_kb_lookup(key):       # 小型 KB: vllm / mig / hpa
TOOLS = {"calculator": ..., "datetime": ..., "kb_lookup": ...}

7.2 ReAct loop 核心

ACTION_RE = re.compile(r"Action:\s*(\w+)\(([^)]*)\)")
FINAL_RE  = re.compile(r"Final Answer:\s*(.+)", re.DOTALL)

while step < max_steps:
    resp = llm.chat.completions.create(..., stop=["Observation:"])
    out = resp.choices[0].message.content
    if FINAL_RE.search(out): return final
    m = ACTION_RE.search(out)
    obs = TOOLS[m.group(1)](m.group(2))
    messages.append({"role": "assistant", "content": out})
    messages.append({"role": "user",      "content": f"Observation: {obs}"})

7.3 实测三道题(2026-05-27 实跑)

Case 1: 时间查询(1 步通)

Q: 现在几点?今天星期几?
[Step 1] Thought: 需要获取当前日期时间来回答问题。
         Action: datetime()
         Obs: 2026-05-27 01:19:01 Wednesday
[Step 2] Final Answer: 当前日期时间是 2026 年 5 月 27 日星期三。

Case 2: 数学计算(踩坑 + 自愈 4 步)

Q: 帮我算一下 sqrt(144) + 3 * pow(2, 5) 是多少?
[Step 1] Action: calculator(sqrt(144) + 3 * pow(2, 5))
         Obs: ERROR: '(' was never closed
         ↑ 真实 bug:我的正则 [^)]*) 在第一个 ) 就停了,args 变成 'sqrt(144'
[Step 2] Action: kb_lookup(vllm)
         ↑ 模型一开始走偏,试图 KB 查表
[Step 3] Thought: 知识库没有,我手动算: sqrt(144)=12, 3*pow(2,5)=96
         Action: calculator(12 + 96)
         Obs: 108
[Step 4] Final Answer: 108 ✅

这就是真实 Agent 现场:工具正则有 bug → 模型靠多步分解绕过 → 最终答对。生产里要么修正则(用括号配对栈),要么用 OpenAI function calling 让模型直出 JSON args 避免歧义。

Case 3: 知识库查询(1 步通)

Q: vLLM 是什么? 用知识库查一下.
[Step 1] Action: kb_lookup(vllm)
         Obs: vLLM 是 UC Berkeley 提出的高吞吐 LLM 推理引擎...
[Step 2] Final Answer: vLLM 是 UC Berkeley 提出的高吞吐 LLM 推理引擎...

8. 生产化要点 Checklist

8.1 RAG 上线前必做

  • [ ] embedding 模型选对语言(中文别用 MiniLM)
  • [ ] chunking 至少试 3 种(固定 / recursive / semantic),A/B
  • [ ] top_k 调到 5-10,加 reranker 截到 3
  • [ ] 加 citation(prompt 让模型标 [1][2][3]),否则不可追溯
  • [ ] 检索失败兜底(没召到 → 走 LLM 原生回答 + 标注"未基于知识库")
  • [ ] chunk 去重(同一段被切多个有重叠时)
  • [ ] 多租户隔离(metadata filter / 单 tenant 单 collection)
  • [ ] embedding 漂移监控(模型升级要回填重建索引)

8.2 Agent 上线前必做

  • [ ] 超时 + max_steps 上限(防止死循环烧 token)
  • [ ] 工具沙箱(calculator 一定要限制 eval scope,见本 demo)
  • [ ] 失败重试 + 降级(工具异常时模型要能 graceful 处理)
  • [ ] 审计日志(每个 Action / Observation 全打)
  • [ ] 成本上限(单会话 token 数封顶)
  • [ ] 危险工具二次确认(发邮件/付钱/删文件 → 必须 human-in-the-loop)
  • [ ] MCP 化:把工具暴露成 MCP server,不同 agent 复用同一套工具

8.3 性能要点

优化效果
Async batch retrieval10+ query 并发,QPS ×8
缓存 embedding(hash(query) → vec)重复查询零开销
缓存 LLM 结果(hash(prompt) → answer)常见 Q 直接返回
Stream outputTTFT 从 2s → 200ms,UX 飞跃
KV cache reuse(prefix sharing)system prompt 复用,prefill 时间 ×0.3

9. 一句话总结

RAG 解决"模型不知道" · Agent 解决"模型不能动手" · MCP 让工具跨 agent 复用 · 底层全是 ReAct loop。

选向量库看规模,选 embedding 看语言,选 reranker 看预算,选 agent 框架看团队习惯。


附录:venv 信息

路径:  /opt/bonus2/venv (479 MB)
Python: 3.10
关键包:
  chromadb              1.5.9
  openai                2.38.0
  onnxruntime           1.x (chromadb 自动装,~88MB ONNX model 首次下载)
  numpy / protobuf / tokenizers / pydantic  (transitive)

执行:
  source /opt/bonus2/venv/bin/activate
  python3 /opt/bonus2/rag_demo.py
  python3 /opt/bonus2/agent_demo.py

✅ 全部代码已在 gpu1 上实跑通过,本文每段输出皆为真实运行截取,未做美化。

在 GitHub 上编辑此页
Prev
Bonus 专栏:LLM 训练全景手册(框架 / 训练模式 / 输入输出 / 最简测试)
Next
Bonus-3 · LLM 推理优化全景实战手册