本文档详细介绍如何使用n8n搭建一个完整的知识库系统,包括文档索引、向量化存储和智能检索功能。通过本指南,你将学会:
组件 | 技术方案 | 用途 |
|---|---|---|
工作流引擎 | n8n | 编排整个数据处理流程 |
Embedding服务 | ModelScope (Qwen3-Embedding-0.6B) | 将文本转换为1024维向量 |
向量数据库 | Pinecone | 存储和检索向量数据 |
安全认证 | API Key | 保护Webhook接口 |

ms-xxxxxxxx)

关键配置:维度必须设置为1024!
Index Name: knowledge-base
Dimensions: 1024 ← 重要!必须匹配Embedding模型输出维度
Metric: cosine
Region: 选择离你最近的区域knowledge-base-xxx.svc.xxx.pinecone.io)
常见错误:
dimension mismatch 错误 Credential name: ModelScope API
Name: Authorization
Value: Bearer ms-your-token-here注意:
Bearer后面有一个空格
Credential name: Pinecone API
Name: Api-Key
Value: your-pinecone-api-key
创建新工作流:知识库-文档索引
节点类型:Webhook
节点名称:文档上传
配置参数:
参数 | 值 |
|---|---|
HTTP Method | POST |
Path |
|
Response Mode | When Last Node Finishes |
Webhook URL格式:
https://your-n8n-domain.com/webhook/knowledge/upload测试示例:
curl -X POST https://your-n8n-domain.com/webhook/knowledge/upload \
-H "Content-Type: application/json" \
-H "x-api-key: your-custom-api-key-here" \
-d '{
"content": "这是一个测试文档内容。",
"filename": "test-document.txt"
}'
节点类型:IF
节点名称:验证API Key
配置参数:
Conditions > String
Value 1: ={{ $json.headers['x-api-key'] }}
Operation: equal
Value 2: your-custom-api-key-here用途:防止未授权访问,保护Webhook安全。

节点类型:Code
节点名称:文本分块
代码实现:
const text = $input.first().json.body.content || '';
const filename = $input.first().json.body.filename || 'unknown';
const chunkSize = 800; // 每块800字符
const overlap = 200; // 重叠200字符,避免语义断裂
function chunkText(text, size, overlap) {
const chunks = [];
let chunkIndex = 0;
const paragraphs = text.split(/\n\n+/); // 按段落分割
let currentChunk = '';
for (const para of paragraphs) {
// 如果当前块+新段落超过限制,且当前块不为空
if ((currentChunk + para).length > size && currentChunk.length > 0) {
chunks.push({
content: currentChunk.trim(),
index: chunkIndex++
});
// 保留部分重叠内容(直接按字符数截取,支持中英文)
const overlapText = currentChunk.slice(-overlap);
currentChunk = overlapText + '\n\n' + para;
} else {
currentChunk += (currentChunk ? '\n\n' : '') + para;
}
}
// 添加最后一块
if (currentChunk.trim()) {
chunks.push({
content: currentChunk.trim(),
index: chunkIndex
});
}
return chunks;
}
const chunks = chunkText(text, chunkSize, overlap);
// 返回多个item,每个item代表一个文本块
return chunks.map(chunk => ({
json: {
text: chunk.content,
metadata: {
source: filename,
chunkIndex: chunk.index,
totalChunks: chunks.length,
uploadTime: new Date().toISOString()
}
}
}));分块策略说明:
参数 | 值 | 说明 |
|---|---|---|
分块大小 | 800字符 | 适配ModelScope Embedding模型的最佳输入长度 |
重叠大小 | 200字符 | 约25%重叠率,平衡上下文连续性与存储成本 |
分割方式 | 段落优先 | 按 |
元数据 | source, chunkIndex, totalChunks, uploadTime | 支持溯源和分块顺序重建 |
重叠处理逻辑:
slice(-overlap) 直接截取最后N个字符
节点类型:HTTP Request
节点名称:生成Embedding
基础配置:
参数 | 值 |
|---|---|
Method | POST |
URL |
|
Authentication | Predefined Credential Type |
Credential Type | Header Auth |
选择凭据 | ModelScope API |
Headers配置:
Name: Content-Type
Value: application/jsonBody配置:
JSONfx 图标切换到表达式模式 {{ JSON.stringify({
model: 'Qwen/Qwen3-Embedding-0.6B',
input: $json.text,
encoding_format: 'float'
}) }}
重要提示:
={{ 开头,不能有多余空格 encoding_format: 'float' 确保返回浮点数数组完整:Qwen/Qwen3-Embedding-0.6BAPI响应格式:
{
"data": {
"data": [{
"embedding": [
-0.0172576904296875,
-0.0867919921875,
... // 共1024个浮点数
],
"index": 0,
"object": "embedding"
}],
"model": "Qwen/Qwen3-Embedding-0.6B",
"object": "list",
"usage": {
"prompt_tokens": 12,
"total_tokens": 12
}
}
}关键字段说明:
data.data[0].embedding: 1024维浮点数数组,每个值范围在 -1, 1data.data[0].index: 文本块在请求中的索引(单文本为0)usage.prompt_tokens: 消耗的token数,用于计费和监控节点类型:Code
节点名称:格式化数据
代码实现:
// 解析ModelScope返回的数据
const responseData = JSON.parse($input.first().json.data);
const embedding = responseData.data[0].embedding;
// 获取上游节点的元数据
const metadata = $('文本分块').first().json.metadata;
const text = $('文本分块').first().json.text;
// 生成ASCII安全的ID(Pinecone不支持中文ID)
const safeId = `doc_${Date.now()}_${Math.random().toString(36).substr(2, 9)}_${metadata.chunkIndex}`;
// 返回Pinecone标准格式
return [{
json: {
id: safeId, // 唯一ID,纯ASCII字符
values: embedding, // 1024维向量数组
metadata: { // 元数据(可包含中文)
text: text, // 原始文本
source: metadata.source, // 文件名
chunkIndex: metadata.chunkIndex,
totalChunks: metadata.totalChunks,
uploadTime: metadata.uploadTime
}
}
}];
数据格式转换说明:
字段 | 说明 | 示例 |
|---|---|---|
| 向量唯一标识,必须ASCII |
|
| 向量数组 |
|
| 原始文本,用于检索后展示 | "如何重置密码..." |
| 文档来源 | "用户手册.pdf" |
| 块索引 | 0, 1, 2... |
Pinecone向量数据结构:

为什么需要生成随机ID?
id: "测试文档.txt_0" → Pinecone报错(不支持中文)id: "doc_1730012345_abc123_0" → 纯ASCII,安全可用节点类型:HTTP Request
节点名称:存储到Pinecone
基础配置:
参数 | 值 |
|---|---|
Method | POST |
URL |
|
Authentication | Predefined Credential Type |
Credential Type | Header Auth |
选择凭据 | Pinecone API |
注意:URL需要替换为你的Pinecone索引Host,并添加
/vectors/upsert路径
Headers配置:
Name: Content-Type
Value: application/jsonBody配置:
Rawapplication/jsonfx 切换到表达式模式 {{ JSON.stringify({ vectors: [$json] }) }}
关键注意事项:
问题 | 错误示例 | 正确示例 |
|---|---|---|
Body表达式格式 |
|
|
URL路径缺失 |
|
|
Content-Type缺失 | 未添加Header | 必须添加 |
成功返回示例:
{
"upsertedCount": 1
}节点类型:Respond to Webhook
节点名称:返回成功
配置参数:
Respond With: JSON
Response Body: (使用表达式)响应Body表达式:
{{ {
success: true,
message: '文档索引完成',
chunks: $('文本分块').all().length,
filename: $('文本分块').first().json.metadata.source,
timestamp: new Date().toISOString()
} }}成功响应示例:
{
"success": true,
"message": "文档索引完成",
"chunks": 3,
"filename": "product-manual.pdf",
"timestamp": "2025-10-27T12:30:45.123Z"
}响应字段说明:
success: 操作状态标识message: 人类可读的操作结果描述chunks: 文档被分割成的块数,用于验证处理完整性filename: 原始文件名,用于客户端确认timestamp: ISO 8601格式的完成时间,便于日志追踪节点类型:Respond to Webhook
节点名称:返回401
配置参数:
Respond With: JSON
Response Code: 401响应Body表达式:
{{ {
error: 'Unauthorized',
message: '无效的API Key',
timestamp: new Date().toISOString()
} }}错误响应示例:
{
"error": "Unauthorized",
"message": "无效的API Key",
"timestamp": "2025-10-27T12:30:45.123Z"
}HTTP状态码说明:
401 Unauthorized: 表示请求缺少有效的身份认证凭据x-api-key 请求头是否正确
测试命令:
curl -X POST https://your-n8n-domain.com/webhook/knowledge/upload \
-H "Content-Type: application/json" \
-H "x-api-key: your-custom-api-key-here" \
-d '{
"content": "产品特点:支持多语言、实时翻译、智能推荐。\n\n使用方法:登录系统,选择语言,输入内容即可自动翻译。\n\n常见问题:如何切换语言?点击右上角设置按钮,选择目标语言。",
"filename": "product-guide.txt"
}'成功响应(HTTP 200):
{
"success": true,
"message": "文档索引完成",
"chunks": 1,
"filename": "product-guide.txt",
"timestamp": "2025-10-27T12:30:45.123Z"
}认证失败响应(HTTP 401):
{
"error": "Unauthorized",
"message": "无效的API Key",
"timestamp": "2025-10-27T12:30:45.123Z"
}响应分析:
chunks: 1: 文本被分为1块,说明长度在800字符以内chunks 值会相应增加timestamp: 用于日志追踪和性能分析knowledge-base 索引
查看节点输出:
查看执行历史:
浏览器开发者工具:

错误信息:
Bad request - please check your parameters
Vector dimension 1024 does not match the dimension of the index 768原因分析:
Qwen3-Embedding-0.6B 输出1024维解决方案:

错误信息:
Bad request - please check your parameters
Vector ID must be ASCII, but got '产品手册.pdf_0'原因分析:
解决方案:
在"格式化数据"节点中,使用随机生成的ASCII ID:
// ❌ 错误写法
const id = `${metadata.source}_${metadata.chunkIndex}`; // 包含中文
// ✅ 正确写法
const safeId = `doc_${Date.now()}_${Math.random().toString(36).substr(2, 9)}_${metadata.chunkIndex}`;中文文件名保存在 metadata.source 字段中,检索时可以使用。

部署前请确认以下事项:
cosine=/vectors/upsert原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。