AI PLAY玩法更新持续收录
← 回到更新流

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索引

具体怎么做

  1. 建Postgres日志表

    先在Postgres执行下方DDL建rag_conversation_turns表,字段与模板记录的conversation、query、answer、citations、groundedness、confidence、latency、cacheHit、createdAt对应。表不存在时模板写日志节点会直接报错,问答主流程虽可能返回但排查问题会失去记录。

  2. 配置Webhook与鉴权

    导入模板后,在Webhook节点设置Header Auth,请求头名固定为x-api-key,值用一个长随机串,并只配置在Next.js服务端的环境变量里,绝不放到NEXT_PUBLIC_开头的变量中。工作流的配置区把allowedNamespaces改成你Pinecone里实际存在的命名空间列表,同时核对最大query长度、缓存TTL和模型选择。

  3. 接通缓存与检索

    填入Redis和Pinecone凭据,向量存储节点选中你的索引。模板的缓存键由query和namespace等字段确定性生成,因此同一命名空间下完全相同的问题会直接走缓存。用下方测试请求体发两次:第一次cacheHit应为false并写入Pinecone检索和Postgres日志,第二次cacheHit应为true且响应明显更快。

  4. 实现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