n8n YouTube Assistant:用 n8n + Supabase 构建可检索的 YouTube 视频知识库 Agent
2026/9/17 19:12:40 网站建设 项目流程

n8n YouTube Assistant:用 n8n + Supabase 构建可检索的 YouTube 视频知识库 Agent

【免费下载链接】ottomator-agentsAll the open source AI Agents hosted on the oTTomator Live Agent Studio platform!项目地址: https://gitcode.com/GitHub_Trending/ot/ottomator-agents

导读

本文围绕 n8n-youtube-agent 展开,它是由 Dominik Fretz 编写、托管在 oTTomator Live Agent Studio 平台上的一个开源 n8n Agent 工作流:只需粘贴一个 YouTube 链接,工作流便会自动抓取视频字幕、调用大模型生成摘要/要点/行动项/金句/标签,并把全文与向量化切片一并写入 Supabase,之后你就可以像聊天一样对它提问——获取单个视频的总结、追问题或跨视频语义搜索。读完本文,你将掌握该工作流从 Webhook 入口、意图分类、字幕抓取、向量入库到检索问答的完整节点链路,能够将其导入自己的 n8n 实例、配置四类凭证并落地运行。

一、Agent 概览:它是如何工作的

根据 README,该 Agent 的核心职责是:根据视频 URL 加载 YouTube 字幕,将字幕写入向量存储(vector store),同时生成摘要、关键要点、引文等信息并存入 Supabase 数据库。在此基础上,你可以与已入库的视频对话:请求摘要、针对特定视频追问,或跨视频检索(例如"之前哪个视频讲到过某本书/某个工具/某个人")。

从 YouTube_Agent.json 的节点清单可以看到,工作流共包含56 个节点,其中既有n8n-nodes-base的基础节点(Webhook、HTTP Request、Code、Switch、Set、Merge、XML、Supabase),也有@n8n/n8n-nodes-langchain的 AI 编排节点(AI Agent、Structured Output Parser、Vector Store、Embeddings、Text Splitter、Buffer Memory、Chat Model),整体可拆解为四条主流程:

流程关键节点职责
入口与意图识别Webhook → Prep Input Fields → AI Agent(分类器)→ Switch接收请求,把用户输入分类为add / summarize / search / respond
添加视频(add)Code 提取 ID → 查重 → 抓取字幕 → 生成摘要/标签 → 写入 videos 表与向量库把新视频完整入库
总结视频(summarize)按 videoId 查 videos 表 → AI Agent1 → Gather output data基于已存摘要回答追问
搜索视频(search)Search Agent + Supabase Vector Store(检索工具)向量检索历史视频并作答

二、依赖与凭证:运行前需要准备什么

README 明确列出了四项核心依赖:

  • Claude Haiku(Anthropic)——负责所有 LLM 推理任务;
  • OpenAI Embedding Model——生成文本向量;
  • Supabase——关系表 + 向量存储 + 检索函数;
  • Supadata——第三方 YouTube 字幕抓取 API。

对应的必须配置的凭证(见 README "Required configuration setup"):

  1. YouTube Data API 凭证:用于 "Fetch video details" 节点,抓取视频标题、描述、频道名(节点使用youTubeOAuth2Api凭证类型);
  2. Supadata 凭证:用于https://api.supadata.ai/v1/youtube/transcript接口(HTTP Headerx-api-key);
  3. OpenAI 凭证:用于embeddingsOpenAi节点生成向量;
  4. Anthropic Claude 凭证:用于 5 个 Agent 节点共用的lmChatAnthropic聊天模型。

此外,还需通过supabase.table.sql在 Supabase 中建表。值得注意的是,除 Supadata 路径外,工作流还内置了一套备用字幕获取方案(见 Sticky Note 说明):直接请求https://www.youtube.com/watch?v={video_id}页面,从 HTML 中解析"captions"JSON 得到字幕 baseUrl,再抓取字幕 XML 并解析拼接。该方案的优势是不依赖第三方 API,但工作流作者在 Sticky Note 中明确警告:"如果你这样用得太多,可能会被迫登录以证明你不是机器人"——因此建议优先使用 Supadata。

三、数据库设计:videos 表与向量检索函数

supabase.table.sql 定义了整套数据层,分为三个部分。

3.1 videos 表:视频结构化信息

create table public.videos ( id bigint generated by default as identity not null, created_at timestamp with time zone not null default now(), video_id text null, title text null, description text null, summary text null, keypoints text[] null, actionable text[] null, quotes text[] null, tags text[] null, channel text null, transcript text null, constraint videos_pkey primary key (id) ) TABLESPACE pg_default;

这张表是"添加视频"分支的落点,字段与 LLM 输出一一对应:video_id(去重主键依据)、title/channel/description(来自 YouTube Data API)、summary/keypoints/actionable/quotes/tags(来自 Claude 的结构化输出)、transcript(完整字幕文本)。

3.2 youtube_agent_data 表:向量存储

create table youtube_agent_data ( id bigserial primary key, content text, -- 对应 Document.pageContent metadata jsonb, -- 对应 Document.metadata embedding vector(1536) -- 1536 维,适配 OpenAI 嵌入模型,按需修改 );

这张表存的是字幕切片的向量化结果。注释明确说明content对应 LangChain 的Document.pageContentmetadata对应Document.metadata——与 n8n 的 Supabase Vector Store 节点(tableName: youtube_agent_data)直接对接。vector(1536)是 OpenAI 默认嵌入(text-embedding-3-small 等)的输出维度,若更换其他嵌入模型(如 3072 维的 text-embedding-3-large)需同步调整。

3.3 match_youtube_data 函数:语义检索

create function match_youtube_data ( query_embedding vector(1536), match_count int default null, filter jsonb DEFAULT '{}' ) returns table ( id bigint, content text, metadata jsonb, similarity float ) language plpgsql as $$ #variable_conflict use_column begin return query select id, content, metadata, 1 - (youtube_agent_data.embedding <=> query_embedding) as similarity from youtube_agent_data where metadata @> filter order by youtube_agent_data.embedding <=> query_embedding limit match_count; end; $$;

这是 pgvector 标准的余弦距离检索函数:<=>为余弦距离,1 - distance得到相似度;metadata @> filter支持按 JSONB 元数据过滤;limit match_count控制返回条数。n8n 的 Vector Store 节点(Insert / Retrieve)都通过queryName: match_youtube_data引用该函数。

四、入口与意图分类:把"人话"变成结构化指令

4.1 Webhook 入口

工作流以 HTTP Webhook(路径invoke-youtube-agent,POST 方法,headerAuth认证)接收外部请求。下游 "Prep Input Fields" 节点从{{ $json.body }}中提取四个字段:

字段表达式说明
query{{ $json.body.query }}用户问题文本
user_id{{ $json.body.user_id }}用户标识
request_id{{ $json.body.request_id }}请求唯一 ID
session_id{{ $json.body.session_id }}会话标识,用于对话记忆

同时,"Add User Message to DB" 节点会把用户消息以 LangChainHumanMessage的 JSON 结构(type: humancontent)写入messages表,作为会话历史持久化。

4.2 分类 Agent:结构化输出 + 分支路由

分类 Agent(AI Agent 节点)的 System Prompt 非常关键,它把用户输入归类为四类动作:

{ "action_type": "add|summarize|search|respond", "video_url": "<url or null>", "video_title": "<title or null>", "search_query": "<search terms or null>", "confidence": <0.0-1.0>, "response": "response" }

规则如下:

  • 用户只给 YouTube 链接 →add
  • 用户针对某视频(带 URL 或标题)询问内容 →summarize
  • 用户想从历史视频中找特定信息 →search
  • 能直接回答的问题 →respond(此时必须返回response字段给用户)。

Prompt 中给出了 8 个示例,覆盖了"直接贴链接""带指令添加""要求总结""按主题回忆视频""询问能力"等典型场景。该 Agent 通过 Structured Output Parser 节点(jsonSchemaExample定义了action_type / video_url / video_title / search_query / confidence / response字段)强制输出合法 JSON,随后由 Switch 节点按action_type值分发到四条分支(addrespondsummarizesearch)。

五、Add 流程:从链接到完整知识库条目

这是工作流最复杂的部分,Sticky Note 将其标注为 "# Add",由多个子阶段串联而成。

5.1 提取视频 ID 并查重

"Code" 节点内置了getYouTubeVideoId()函数,用正则匹配四种 URL 形态:

const patterns = [ /(?:youtube\.com\/watch\?v=|youtu\.be\/|youtube\.com\/embed\/)([^&?/]+)/, /youtube\.com\/v\/([^&?/]+)/, /youtube\.com\/shorts\/([^&?/]+)/ ];

即支持youtube.com/watch?v=youtu.be/youtube.com/embed/youtube.com/v/youtube.com/shorts/五种常见链接格式。拿到videoId后,"Check if video exists" 节点以 Rest 风格查询 Supabase:

https://[Your Supabase Project ID].supabase.co/rest/v1/videos?video_id=eq.{{ $json.videoId }}&select=id&limit=1

若记录已存在(If row exists 判断),则直接返回提示:"The video with the id xxx is already in the database.",避免重复入库。

5.2 抓取视频信息与字幕

未重复的视频进入 "Get Video ID" 节点,并行触发两个请求:

  • Fetch Video Details:调用 YouTube Data APIhttps://www.googleapis.com/youtube/v3/videos?part=snippet&id={video_id}(使用 YouTube OAuth2 凭证),再经 "Extract video details" 节点取出titledescriptionchannelName(分别对应响应的items[0].snippet.title / description / channelTitle);
  • Get transcript from SUPADATA:调用https://api.supadata.ai/v1/youtube/transcript?text=true&videoId={video_id},Header 携带x-api-key(Supadata API key),返回纯文本字幕,经 "Join transcript in code1" 节点整理为{ transcript }

两条结果在 "Merge1" 节点汇合后,分别喂给两个并行的 Agent:

  • Summarize agent:System Prompt 要求"作为 YouTube 字幕专家",输出四要素 JSON——summary(摘要)、keypoints(关键要点)、actionable-tasks(可执行任务)、extracted-quotes(原文金句),配套的 Structured Output Parser2 的 schema 示例与此一致;
  • Tag generator agent:要求生成"至少 10 个标签"用于后续分类检索,System Prompt 明确"只返回 JSON,不要任何多余文字",配套 Structured Output Parser1 的 schema 为{ "tags": ["tag"] }

两个 Agent 的输出经 "Merge" 节点按索引合并(Summarize 在 index 0、Tag 在 index 1),再统一写入 Supabase。

5.3 结构化入库与向量化切片

"Add video to supabase" 节点把 10 个字段写入videos表,其中 summary/keypoints/actionable/quotes/tags 直接来自 Merge 合并后的结构化输出,title/channel/description 来自 YouTube API,video_id/transcript 来自前面节点——字段名与 supabase.table.sql 中的列严格对应。

与此同时,向量入库链路由四个 LangChain 节点协作完成:

节点配置作用
Recursive Character Text SplitterchunkOverlap: 100递归字符切分器,切片间保留 100 字符重叠以维持上下文连续性
Default Data LoaderjsonData: {{ $json.data }},metadata 携带video_id把字幕文本包装成带元数据的 Document
Embeddings OpenAI默认配置生成 1536 维向量
Insert documentstableName: youtube_agent_dataqueryName: match_youtube_data写入 Supabase 向量表

注意 metadata 中的video_id被注入到每个切片的metadata字段——这正对应match_youtube_data函数中metadata @> filter的过滤能力,使得后续检索可以按视频维度精确定位。

入库成功后,"Generate output message" 节点拼接成功提示:"The video '{title}' by {channelName} was added successfully!",最终所有分支的输出统一经 "Add AI Message to DB"(以 LangChainAIMessage结构写入messages表)→ "Prep Output Fields"(包装成success: true+message.content)→ "Respond to Webhook" 返回给调用方。

六、Summarize / Search 流程:与知识库对话

6.1 按视频总结(summarize)

"Code1" 节点复用同一个getYouTubeVideoId()函数解析 URL,随后 "Supabase" 节点按video_id查询videos表,由 "Gather fields" 节点把title / description / summary / keypoints / actionable / channel / query / videoId / session_id组装起来,交给AI Agent1。该 Agent 的 Prompt 把已入库的结构化信息以 XML 标签的形式注入:

<title>{{ $json.title }}</title> <channel>{{ $json.channel }}</channel> <description>{{ $json.description }}</description> <summary>{{ $json.summary }}</summary> <key-points>{{ $json.keypoints }}</key-points> <tasks>{{ $json['actionable-tasks'] }}</tasks> <human>{{ $json.query }}</human>

Prompt 同时约束了输出风格:"直接回答用户问题,不要提'Based on the provided summary'"。这意味着 summarize 分支不再重复调用 LLM 分析长字幕,而是基于入库时已生成的摘要做轻量推理,响应更快、成本更低。

6.2 跨视频语义搜索(search)

搜索分支由Search Agent驱动,它挂载了两个工具:

  • Supabase Vector Store(retrieve-as-tool 模式):工具名video_transcript_query,描述为"使用搜索词从向量库中检索相关视频",topK: 6(每次检索返回最多 6 条最相关切片),Embedding 同样来自 OpenAI;
  • get_video_by_videoId(supabaseTool):通过$fromAI('videoId')让 Agent 自行决定按视频 ID 查询结构化记录。

Search Agent 的 Prompt 会把分类器输出的search_query传入:"Use your tool to search for relevant videos and respond to the human",并要求在回答后把命中的video_id<video_ids>标签列表返回,每项前缀 YouTube URL——这样用户不仅能看到答案,还能拿到原始视频链接,例如:

<video_ids> <video_id>https://www.youtube.com/watch?v=xyz123</video_id> </video_ids>

6.3 会话记忆

"Window Buffer Memory" 节点使用自定义会话键{{ $json.session_id }},挂载到分类 Agent 与 AI Agent1 上,为多轮对话提供滑动窗口式上下文记忆;配合messages表的持久化,Agent 可以在跨请求的会话中保持连贯。

七、如何部署到自己的 n8n 实例

参照 README 的说明,部署步骤可以归纳为:

  1. 准备依赖服务:注册并准备 Supabase 项目、Anthropic API Key、OpenAI API Key、YouTube Data API OAuth2 凭证、Supadata API Key;
  2. 初始化数据库:在 Supabase SQL Editor 中执行 supabase.table.sql,一次性创建videos表、youtube_agent_data向量表与match_youtube_data检索函数(需启用 pgvector 扩展);
  3. 导入工作流:在 n8n 中新建 Workflow → Import from File,选择 YouTube_Agent.json;
  4. 配置凭证:为 Supabase、OpenAI、Anthropic、YouTube OAuth2、Supadata(HTTP Header)分别创建 Credential,并替换各节点 URL 中的[Your Supabase Project ID]占位符与x-api-key值;
  5. 激活 Webhook:启动工作流后,向POST /webhook/invoke-youtube-agent发送包含query(及可选user_id / request_id / session_id)的 JSON 请求即可调用。

八、源码级细节与可扩展方向

  • 备用字幕方案的代价:工作流内置的"从 YouTube 页面 HTML 解析字幕"分支(Extract transcript url → Fetch transcript → XML → Join transcript in code)会先做多重错误判断——检测到g-recaptcha时返回 "Too Many Requests"、缺少playabilityStatus返回 "Transcript unavailable"、无captionTracks时返回 "Transcript disabled"——作者在 Sticky Note 中建议仅在 Supadata 不可用时启用,避免触发反爬限制。
  • 去重是设计的默认行为:Check if video exists 的select=id&limit=1与 If row exists 分支保证了同一视频不会被重复抓取与重复向量化,避免知识库膨胀。
  • 可扩展方向match_youtube_datafilter jsonb参数已具备按元数据(如video_id、未来可加的channel)过滤检索的能力;vector(1536)维度、topK: 6chunkOverlap: 100均可按嵌入模型与业务场景调整;分类 Agent 的 System Prompt 也可扩展更多动作类型(如"翻译字幕""导出笔记")。

该 Agent 是 oTTomator agents 集合的一部分,完整的源码级工作流定义见 YouTube_Agent.json,数据库脚本见 supabase.table.sql,整体能力说明与配置清单见 README。

【免费下载链接】ottomator-agentsAll the open source AI Agents hosted on the oTTomator Live Agent Studio platform!项目地址: https://gitcode.com/GitHub_Trending/ot/ottomator-agents

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询