2026-09-17 · 原文发布日
用n8n给Next.js站点搭RAG问答后端
n8n模板:暴露一个带Header鉴权的Webhook给Next.js调用,先查Redis缓存,未命中时用OpenAI生成向量并检索Pinecone,再由带记忆的Agent产出含引用和置信度的JSON答案,结果写回Redis并记录到Postgres,答案可信时回调Next.js触发ISR页面刷新。
原文要点
该免费模板(Oneclick AI Squad发布)把n8n变成Next.js站点的RAG后端:暴露一个用x-api-key请求头鉴权的Webhook,接收Next.js服务端发来的query、conversationId、tenantId和namespace,校验失败返回结构化400;用确定性缓存键先查Redis,命中直接返回;未命中时用OpenAI生成嵌入,按命名空间在Pinecone检索,再由带窗口记忆的Agent产出含引用与置信度的结构化JSON答案,写回Redis(带TTL)并记录到Postgres的rag_conversation_turns表;答案可信时异步回调Next.js的/api/revalidate触发对应ISR标签刷新。
这次做成什么
给已有Next.js站点加一个带缓存和日志的RAG问答接口:前端提问→n8n返回答案与引用→可信答案触发页面刷新。本指南按真实调用顺序说明各环节怎么配,并给出可直接用的建表SQL、测试请求体和Next.js回调端点示例代码。
准备什么
- 一个已部署的Next.js应用(13及以上,使用App Router)
- n8n实例并能从Next.js服务器公网访问到
- OpenAI API密钥,用于嵌入与对话模型
- Redis实例(自托管或云服务)及连接凭据
- Postgres数据库及建表权限
- 已建好并按命名空间存有嵌入文档的Pinecone索引
具体怎么做
建Postgres日志表
先在Postgres执行下方DDL建rag_conversation_turns表,字段与模板记录的conversation、query、answer、citations、groundedness、confidence、latency、cacheHit、createdAt对应。表不存在时模板写日志节点会直接报错,问答主流程虽可能返回但排查问题会失去记录。
配置Webhook与鉴权
导入模板后,在Webhook节点设置Header Auth,请求头名固定为x-api-key,值用一个长随机串,并只配置在Next.js服务端的环境变量里,绝不放到NEXT_PUBLIC_开头的变量中。工作流的配置区把allowedNamespaces改成你Pinecone里实际存在的命名空间列表,同时核对最大query长度、缓存TTL和模型选择。
接通缓存与检索
填入Redis和Pinecone凭据,向量存储节点选中你的索引。模板的缓存键由query和namespace等字段确定性生成,因此同一命名空间下完全相同的问题会直接走缓存。用下方测试请求体发两次:第一次cacheHit应为false并写入Pinecone检索和Postgres日志,第二次cacheHit应为true且响应明显更快。
实现Next.js回调端点并联调
在Next.js项目创建app/api/revalidate/route.ts(示例代码见材料),校验共享密钥后调用revalidateTag。把该端点的完整URL和密钥填回工作流的nextjsRevalidateUrl与nextjsRevalidateSecret。最后在Next.js页面组件中用Server Action向n8n Webhook发POST,渲染返回的answer与citations。
可直接复制的材料
rag_conversation_turns建表SQL
本站独立编写的示例DDL,字段名需与模板插入节点实际映射核对后再用,可按需增删列。
CREATE TABLE rag_conversation_turns (
id BIGSERIAL PRIMARY KEY,
conversation_id TEXT NOT NULL,
tenant_id TEXT NOT NULL,
namespace TEXT NOT NULL,
query TEXT NOT NULL,
answer TEXT,
citations JSONB,
groundedness BOOLEAN,
confidence NUMERIC(4,3),
latency_ms INTEGER,
cache_hit BOOLEAN DEFAULT FALSE,
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX idx_rag_turns_conversation ON rag_conversation_turns (conversation_id, created_at);Next.js的/api/revalidate回调端点示例
本站独立编写的示例代码,供对接模板回调用;secret与tag字段名需与模板回调节点实际发送的字段核对。
// app/api/revalidate/route.ts
import { revalidateTag } from "next/cache";
import { NextRequest, NextResponse } from "next/server";
export async function POST(req: NextRequest) {
const body = await req.json().catch(() => null);
if (!body || body.secret !== process.env.N8N_REVALIDATE_SECRET) {
return NextResponse.json({ ok: false, error: "unauthorized" }, { status: 401 });
}
if (typeof body.tag !== "string" || !body.tag) {
return NextResponse.json({ ok: false, error: "missing tag" }, { status: 400 });
}
revalidateTag(body.tag);
return NextResponse.json({ ok: true, revalidated: body.tag });
}调用Webhook的完整测试请求体
本站虚构的测试请求;namespace必须在工作流allowedNamespaces白名单内且在Pinecone中已有数据,x-api-key替换为真实配置值。
POST https://你的n8n域名/webhook/rag-chat
Headers:
Content-Type: application/json
x-api-key: 替换为你在Webhook节点配置的长随机串
Body:
{
"query": "退款政策里写的处理时限是多久?",
"conversationId": "conv-demo-0001",
"tenantId": "tenant-demo",
"namespace": "docs-zh"
}输入与输出示例
本站虚构演示,非原作者运行结果;延迟与置信度为示意参考值,非实测性能承诺。
输入
用上面的测试请求体连续发送两次(namespace为docs-zh,问题为退款时限),Pinecone该命名空间已存有虚构《退款政策》文档嵌入,其中写明"审核通过后3个工作日内原路退回"。对应输出
第一次响应(缓存未命中):{"answer":"根据《退款政策》,退款将在审核通过后3个工作日内原路退回。","citations":[{"source":"退款政策.pdf","namespace":"docs-zh"}],"grounded":true,"confidence":0.91,"cacheHit":false,"latencyMs":1850};随后n8n向/api/revalidate发送{"secret":"...","tag":"docs-zh"}。第二次相同请求响应:answer与citations相同,"cacheHit":true,"latencyMs":45。做完检查这些
- 缺少x-api-key或值错误的请求被拒绝,合法请求正常进入流程
- 缺query、conversationId或namespace不在白名单时,返回结构化400错误而不是500
- 同一问题第二次请求cacheHit为true,且Postgres中两次都有日志行且cache_hit标记正确
- 答案JSON包含answer、citations、confidence字段,citations能对应到Pinecone中的实际文档
- grounded为true时Next.js日志出现/api/revalidate调用并成功revalidateTag
- Postgres表中每行的latency_ms、created_at均有合理非空值
容易卡住的地方
- 模板只负责检索,Pinecone索引和命名空间里的文档嵌入需要你提前用别的流程灌入;空命名空间检索不到任何内容,回答将失去引用依据,务必先用真实文档灌库再上线
- x-api-key若写进前端代码或NEXT_PUBLIC_变量会被任何人窃取调用,必须只放在服务端
- 缓存键是确定性生成的,文档更新后相同问题仍可能命中旧缓存,需按TTL等待或主动清Redis键
- 回调触发ISR依赖你自行实现/api/revalidate端点并回填URL与密钥,两端密钥不一致会静默刷新失败
- confidence分数是模型自评的参考信号,不应直接当作事实准确率对外展示
本站借助AI整理来源事实,独立编写中文操作指南与示例。示例不代表实际运行结果;来源效果尚未由本站独立复现。付费模板与模型、服务费用分别计算。
- 原文标题
- Serve a RAG chat backend for Next.js using OpenAI, Redis, and Pinecone
- 原作者
- Oneclick AI Squad
- 原始发布日期
- 2026-09-17T04:58:05.259Z
- 来源
- https://n8n.io/workflows/19669