RAG 知识库工作流
第 16 章:RAG 知识库工作流
检索增强生成(RAG)是将企业私有文档与大语言模型结合的最成熟方案。它解决了 LLM 不知道你公司内部知识的根本问题:把文档向量化存入数据库,用户提问时先检索相关片段,再将片段喂给 LLM 生成答案。n8n 从 v1.x 开始原生支持整个 RAG 链路——向量存储、文档加载、Embeddings 计算——无需写一行代码,全程可视化搭建。本章从原理讲起,手把手完成企业知识库问答机器人的完整搭建。
16.1 RAG 原理:五个核心步骤
理解 RAG 的工作原理,有助于在 n8n 中做出正确的节点选型和参数配置。完整的 RAG 系统分为两条流水线:
索引流(一次性或定期执行)
文档加载(PDF/Word/网页/Notion)→ 文本分块(Chunk Size + Overlap)→ 向量化(Embeddings 模型)→ 存入向量库(Qdrant/Pinecone)
查询流(每次用户提问时执行)
用户问题(原始文本)→ 问题向量化(同款 Embeddings)→ 语义检索(Top-K 相似片段)→ LLM 生成(片段 + 问题 → 答案)
为什么要分块(Chunk)? 向量化模型有 Token 上限(如 text-embedding-3-small 支持最多 8191 Token),且短文本的语义更精准。通常将文档切割为 500-1000 Token 的片段,相邻片段设置 10-20% 的重叠(Overlap)以避免切断句子语义。
16.2 向量存储节点选型
n8n 支持多种主流向量数据库,通过统一的接口节点操作:
| 向量库 | 部署方式 | 适用场景 | 成本 |
|---|---|---|---|
| Qdrant | 自托管 Docker / Qdrant Cloud | 中大型企业知识库,数据不出境需求 | 自托管免费 |
| Pinecone | 全托管云服务 | 快速验证、无运维压力 | 免费层 + 按量计费 |
| PGVector | PostgreSQL 扩展 | 已有 PG 数据库、避免引入新组件 | 与 PG 共享成本 |
| Supabase Vector | 托管 PGVector | 小团队快速上线 | 免费层可用 |
推荐:数据安全要求高的企业选 Qdrant 自托管;快速验证场景选 Pinecone;已有 PostgreSQL 的团队选 PGVector(零额外运维成本)。
16.3 文档加载节点
n8n 提供多种文档加载节点,对应不同的数据来源:
- Default Data Loader:处理 n8n 工作流中已经存在的二进制数据(如 HTTP 下载的文件)
- Binary Input Loader:从表单上传或 Webhook 收到的文件读取文本
- GitHub Document Loader:直接从 GitHub 仓库读取 Markdown/代码文件
- Notion Document Loader:从 Notion 页面读取内容,保留标题层级
对于 PDF 和 Word 文件,先用 HTTP Request 节点下载文件到 n8n 二进制流,再用 Extract from File 节点(支持 PDF/DOCX/TXT)提取纯文本,最后送入向量化流程。
16.4 Embeddings 节点配置
Embeddings 模型将文本转换为高维向量。n8n 支持以下 Embeddings 提供方:
- OpenAI Embeddings:推荐使用
text-embedding-3-small(1536维,价格极低,约 $0.02/百万 Token) - Azure OpenAI Embeddings:企业合规场景,数据留在 Azure 租户
- Ollama Embeddings:完全本地运行,使用 nomic-embed-text 等模型,零 API 费用
- Cohere Embeddings:多语言支持较好,中文效果优于 OpenAI Embeddings
重要: 索引流和查询流必须使用完全相同的 Embeddings 模型。如果建库时用了 text-embedding-3-small,查询时也必须用 text-embedding-3-small,否则向量空间不匹配,检索结果将毫无意义。
16.5 完整 RAG 流水线搭建
Part 1:索引工作流(文档入库)
这条工作流负责将文档处理后存入向量库,通常在新文档上传时触发(Webhook)或定期批量处理(Schedule)。
// 索引工作流节点配置片段
{
"nodes": [
{
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"parameters": {
"httpMethod": "POST",
"path": "ingest-document",
"responseMode": "lastNode"
}
},
{
"name": "Embeddings OpenAI",
"type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
"parameters": {
"model": "text-embedding-3-small"
}
},
{
"name": "Character Text Splitter",
"type": "@n8n/n8n-nodes-langchain.textSplitterCharacterTextSplitter",
"parameters": {
"chunkSize": 800,
"chunkOverlap": 100
}
},
{
"name": "Qdrant Vector Store",
"type": "@n8n/n8n-nodes-langchain.vectorStoreQdrant",
"parameters": {
"mode": "insert",
"qdrantCollection": "company_kb"
}
}
]
}
Part 2:查询工作流(用户问答)
这条工作流在用户提问时触发,执行检索和生成两个阶段。
// 查询工作流 RAG Chain 配置
{
"name": "Vector Store Retriever",
"type": "@n8n/n8n-nodes-langchain.vectorStoreQdrant",
"parameters": {
"mode": "retrieve",
"qdrantCollection": "company_kb",
"topK": 5,
"scoreThreshold": 0.7
}
}
// scoreThreshold: 相似度阈值,低于此分数的结果被过滤
// 取值范围 0-1,建议从 0.6 开始调试
// topK: 返回最相似的 K 个文档片段
配置 RAG Chain 节点
将 Vector Store Retriever 连接到 Retrieval QA Chain 节点,该节点会自动完成:检索 → 将片段注入提示词 → 调用 LLM → 返回答案。你只需配置系统提示和 LLM 模型。
提示词最佳实践: 在 RAG Chain 的系统提示中明确告诉模型"只根据提供的上下文回答,如果上下文中没有相关信息,直接说不知道"。这可以显著减少幻觉,是企业级知识库的必备指令。
16.6 实战:企业知识库问答机器人
场景描述:公司有数百个产品手册、FAQ 文档和操作规程,员工通过飞书群 @ 机器人提问,机器人秒级返回准确答案,并附上来源文档名称。
完整工作流设计
索引工作流(在文档更新时运行):
- Schedule 触发(每天凌晨 2 点)
- Google Drive 节点:列出指定文件夹的所有文件(支持 PDF/DOCX/TXT)
- Loop Over Items:遍历每个文件
- HTTP Request 节点:下载文件内容
- Extract from File 节点:提取纯文本
- Character Text Splitter 节点:chunkSize=800, overlap=100
- Embeddings OpenAI 节点:text-embedding-3-small
- Qdrant 节点(insert 模式):存入 company_kb 集合,metadata 中记录文件名和来源 URL
问答工作流(飞书消息触发):
- 飞书 Webhook:接收 @机器人 的消息,提取问题文本
- Embeddings OpenAI 节点:对问题向量化
- Qdrant 节点(retrieve 模式):topK=5,scoreThreshold=0.65
- Code 节点:提取检索结果中的文档名称,格式化为来源列表
- Retrieval QA Chain 节点:LLM 生成回答
- 飞书发送消息节点:回复用户,附带来源文档列表
来源文档提取代码片段
// Code 节点:从向量检索结果提取来源文档名
const docs = $input.all();
const sources = [...new Set(
docs.map(d => d.json.metadata?.source || '未知来源')
)];
return [{
json: {
sourceList: sources.map((s, i) => `${i+1}. ${s}`).join('\n'),
context: docs.map(d => d.json.pageContent).join('\n\n---\n\n')
}
}];