进阶25 分钟
RAG 代码化:拆开 Dify 的黑盒
Embedding、向量库、检索链——用代码重做 Dify 知识库,理解平台替你做了什么。
Dify 篇你拖拽过知识库,这一章用代码重做一遍——看看平台替你做了什么。
Dify 帮你藏了什么
Dify 把五步包装成了三步拖拽。代码化不是「更难」,是把控制权拿回来。
用 LangChain 写一个最小 RAG
第一步:文档分段
import { RecursiveCharacterTextSplitter } from "@langchain/textsplitters";
const splitter = new RecursiveCharacterTextSplitter({
chunkSize: 1000, // 每段最多 1000 字符
chunkOverlap: 200, // 段间重叠 200 字符,防止语义被切断
});
const chunks = await splitter.splitDocuments(docs);
// 结果:[{ pageContent: "第一段…", metadata: { source: "faq.md" } }, …]
为什么需要分段? Embedding 模型对短文本效果更好(一段话算一个向量,比整篇文档算一个向量精准)。分段是检索质量的基础。
为什么要重叠? 如果一个答案恰好跨两个段落的边界,重叠区能保证至少有一个完整的段包含它。
第二步:Embedding + 向量库
import { OpenAIEmbeddings } from "@langchain/openai";
import { MemoryVectorStore } from "langchain/vectorstores/memory";
const embeddings = new OpenAIEmbeddings({
openAIApiKey: process.env.DEEPSEEK_API_KEY,
modelName: "text-embedding-v3",
});
// 内存向量库(开发用;生产换 PGVector / Milvus)
const vectorStore = await MemoryVectorStore.fromDocuments(chunks, embeddings);
Embedding 做的事:把每段文字变成一个高维向量(如 1536 维),语义相近的段落在向量空间中距离也近。
第三步:检索链
import { RetrievalQAChain } from "langchain/chains";
import { ChatOpenAI } from "@langchain/openai";
const llm = new ChatOpenAI({ modelName: "deepseek-chat" });
const chain = RetrievalQAChain.fromLLM(llm, vectorStore.asRetriever({
k: 3, // 取最相似的前 3 段
}));
const answer = await chain.invoke({
query: "盐焗鸡能放几天?",
});
这行代码内部做了什么:
- 把「盐焗鸡能放几天?」计算成向量
- 在向量库里找到最相似的 3 段
- 把这 3 段拼进 Prompt:「以下是参考资料:… 请基于资料回答」
- 调用 LLM 生成回答
Dify vs 代码的取舍
| 维度 | Dify | LangChain 代码 |
|---|---|---|
| 上手速度 | 30 分钟 | 半天 |
| 分段策略 | 固定(自动 + 自定义分隔符) | 完全可控(Recursive/Token/Markdown) |
| Embedding 模型 | 内置几种 | 任意(OpenAI/本地/免费) |
| 向量库 | 内置 | 任意(PGVector/Milvus/Qdrant/Memory) |
| 检索策略 | Top-K | Top-K + MMR + 过滤 + 重排 |
| 调试 | 黑盒(只能看最终回答) | 透明(每一步都能打日志) |
| 部署 | 平台托管 | 你的服务器 |
经验法则:原型用 Dify,产品用代码。Dify 帮你快速验证「RAG 能不能解决这个问题」,代码帮你在验证后做深度优化。
本章要点
- Dify 的三步拖拽底下是五步:分段 → Embedding → 存储 → 检索 → 拼 Prompt
- 分段是检索质量的基础——chunkSize 和 overlap 直接影响召回率
- Embedding 把文字变成向量,语义相近 = 距离相近
- RetrievalQAChain 一行代码完成检索+生成,但内部每一步都可替换
- 原型用 Dify,产品用代码——先验证可行性,再拿回控制权
→ 下一章:MCP 协议