阶段:G4-工具与外部生态 | 预计耗时:90 分钟(含一次性安装建库)| 前置:G4-01 结构化输出与工具进阶 新依赖:
pip install langchain-text-splitters chromadb sentence-transformers -i https://pypi.tuna.tsinghua.edu.cn/simple代码:要你自己敲成langgraph-learn/examples/g4_rag.py这是 G7 实战项目 A(知识库问答)的技术地基——企业 RAG 是调研里 Top3 技能
学习目标
- 跑通最小 RAG 链路:文档切块 → 向量化入库 → 检索 → 带引用回答
- 把检索包成图里的一个节点,与"不够好就改写重查"的循环结合(这才是 LangGraph 做 RAG 的独特价值)
- 本机性能预期:bge-small 模型约 100MB,CPU 上完全可用
核心知识
1. 最小 RAG 四步
# ① 切块:长文档切成小段(中文约 300-500 字一段,带重叠)
from langchain_text_splitters import RecursiveCharacterTextSplitter
chunks = RecursiveCharacterTextSplitter(chunk_size=400, chunk_overlap=50).split_text(doc_text)
# ② 向量化:中文用 bge-small-zh(CPU 可跑)
from sentence_transformers import SentenceTransformer
model = SentenceTransformer("BAAI/bge-small-zh-v1.5") # 首次下载约 100MB
vectors = model.encode(chunks, normalize_embeddings=True)
# ③ 入库:Chroma 本地向量库(存 E 盘,不占 C)
import chromadb
col = chromadb.PersistentClient(path="./chroma_db").get_or_create_collection("kb")
col.add(documents=chunks, embeddings=vectors.tolist(), ids=[f"c{i}" for i in range(len(chunks))])
# ④ 检索:问题→向量→最近邻
hits = col.query(query_embeddings=model.encode([q]).tolist(), n_results=3)
回答时把命中文本贴进 prompt,并要求模型标注引用了哪几段——溯源是交付的硬要求。
2. 为什么不是"链"而是"图":自适应循环
朴素 RAG 检索质量差就硬着头皮回答。LangGraph 版可以:
grade(检索质量评分节点,用结构化输出打 0-10 分)
├─ ≥6 → answer 节点(带引用回答)
└─ <6 → rewrite 节点(改写问题)→ 回 retrieve(最多重试 2 次)→ 还不行 → 如实告知
"不够好自动改写重查"就是 G1-03 条件边循环的直接应用——链式框架做不到,图天然支持。
实验任务
任务 1:建库(30 分钟,一次性)
找 3 篇真实资料(产品手册/规章制度任意,共约 5000 字),走完 ①②③ 建好本地库。首次下载 bge 模型约 100MB,走 hf-mirror:export HF_ENDPOINT=https://hf-mirror.com。
任务 2:朴素问答(20 分钟)
写 g4_rag.py:检索 top3 → 拼 prompt → 回答。准备 3 个问题:2 个库里有的、1 个库里没有的——没有的那个模型如果一本正经编答案,你就亲眼见到了 RAG 要解决的第二个问题(拒答)。
任务 3:加质量循环(30 分钟)
- 加
grade节点(结构化输出:relevance 0-10 + 理由) - 加条件边:低分 → rewrite → retrieve(上限 2 次);高分 → answer
- 用"库里没有"的问题测试:应最终走到"如实告知"分支而不是编造
验收标准
衔接下一阶段
知识接上了 → G4-03 MCP 与多模型路由:接标准生态 + 省钱架构。