知识库首页 知识库-人物 DESIGN.md

DESIGN

本地来源:Knowledge/World/人物/seo方法论/seo-knowledge-base/DESIGN.md

SEO Dashboard 设计文档

一、项目概述

1.1 目标

创建一个内部 SEO 工具,通过 YouTube 视频内容自动生成多语言博客文章,提升网站 SEO 效果。

1.2 核心流程

关键词输入 → YouTube 搜索 → 选择视频 → 提取脚本 → AI 生成博客 → 多语言翻译 → 发布到目标站点

1.3 技术约束

  • 页面设置为 noindex(内部工具,不需要被搜索引擎收录)
  • 需要 YouTube Data API v3
  • 需要 AI API(用于脚本提取、博客生成、翻译)

二、开发阶段规划(MVP vs 成熟阶段)

2.1 阶段功能对照表

功能模块 MVP 阶段 成熟阶段 优先级
视频搜索 ✅ 基础搜索、筛选 批量搜索、智能推荐 P0
脚本提取 ✅ YouTube 字幕 Whisper AI 转写 P0
博客生成 ✅ 整体生成(不分模块) 12 模块独立编辑 P0 → P1
博客模块 ✅ 基础 8 模块 完整 12 模块 P0 → P1
多语言翻译 ✅ 3 语言 (en/zh/es) 10+ 语言 P0
图片生成 ❌ 手动上传 ✅ AI 自动生成 P2
竞品分析 ❌ 无 ✅ URL 分析、大纲提取 P2
模板系统 ❌ 无 ✅ 6 种博客模板 P2
Prompt 管理 ✅ 固定 Prompt 自定义 Prompt 库 P1
发布流程 ✅ MDX 导出 + 手动复制 API 自动发布 P1 → P2
多站点支持 ✅ siteId 字段预留 自动发布到多站点 P1
数据分析 ❌ 无 ✅ 生成统计、SEO 效果 P3
批量处理 ❌ 无 ✅ 批量生成、批量翻译 P2
定时任务 ❌ 无 ✅ 自动抓取、自动发布 P3

2.2 MVP 阶段详细需求

MVP 核心功能(必须完成)

┌─────────────────────────────────────────────────────────────────┐
│                     MVP 阶段核心流程                              │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  1. 关键词搜索 YouTube 视频                                       │
│     └── 基础筛选:日期、时长、排序                                │
│                                                                  │
│  2. 提取视频脚本                                                  │
│     └── 使用 YouTube 自动字幕                                    │
│                                                                  │
│  3. AI 生成博客(整体生成,不分模块编辑)                          │
│     ├── 标题 + Meta Description                                  │
│     ├── 正文内容(含引言、要点、总结)                            │
│     └── CTA 行动号召                                             │
│                                                                  │
│  4. 多语言翻译(3 种)                                            │
│     └── en / zh / es                                             │
│                                                                  │
│  5. 导出 MDX 文件                                                 │
│     └── 手动复制到目标项目的 content/blog/ 目录                   │
│                                                                  │
│  6. 数据库存储                                                    │
│     └── 保存视频、博客、草稿记录                                  │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

MVP 阶段暂不做的功能

功能 原因 后续阶段
12 模块独立编辑器 增加复杂度,先整体生成够用 成熟阶段
AI 图片自动生成 手动配图更可控 成熟阶段
竞品 URL 分析 锦上添花功能 成熟阶段
复杂模板系统 先用固定结构 成熟阶段
FAQ Schema 标记 SEO 优化功能 成熟阶段
API 自动发布 先用 MDX 导出 成熟阶段

2.3 成熟阶段详细需求

博客模块升级:从 10 模块到 12 模块

基于 SaaS 博客最佳实践,成熟阶段升级为 12 个模块

序号 模块名称 英文名 MVP 成熟 SEO 价值
1 标题 Title ⭐⭐⭐⭐⭐
2 元描述 Meta Description ⭐⭐⭐⭐⭐
3 特色图片 Featured Image ⭐⭐⭐⭐
4 开头引言 Introduction ⭐⭐⭐⭐
5 目录 Table of Contents ⭐⭐⭐
6 核心要点 Key Takeaways ⭐⭐⭐⭐⭐
7 主要内容 Main Content ⭐⭐⭐⭐⭐
8 案例示例 Examples/Case Study ⭐⭐⭐⭐
9 FAQ 问答 FAQ Section ⭐⭐⭐⭐⭐
10 总结结论 Conclusion ⭐⭐⭐⭐
11 相关文章 Related Articles ⭐⭐⭐
12 行动号召 Call to Action ⭐⭐⭐⭐⭐

新增模块详解

模块 3: 特色图片 (Featured Image)
功能:为博客生成/选择封面图片
MVP:手动上传
成熟:AI 自动生成(使用 KIE API)

输出:
- 主图 URL
- Alt 文本
- 图片尺寸(1200x630 推荐)
模块 5: 目录 (Table of Contents)
功能:自动生成文章目录,提升用户体验
MVP:无
成熟:根据 H2/H3 标题自动生成

输出:
- 带锚点链接的目录列表
- 支持折叠/展开
模块 6: 核心要点 (Key Takeaways)
功能:文章开头的 bullet points 摘要
重要性:Google AI Overview 和 Featured Snippets 优先抓取
MVP:无
成熟:AI 自动提取 3-5 个要点

输出示例:
┌─────────────────────────────────────┐
│ 📌 Key Takeaways                    │
│ • AI upscaling improves quality 4x  │
│ • Best for photos under 2MB         │
│ • Free tools available in 2026      │
└─────────────────────────────────────┘
模块 9: FAQ 问答 (FAQ Section)
功能:结构化问答,可添加 Schema 标记
SEO 价值:极高(FAQ Schema 可获得搜索结果富文本展示)
MVP:无
成熟:AI 生成 3-5 个常见问题

输出格式:
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [...]
}
</script>
模块 11: 相关文章 (Related Articles)
功能:内部链接推荐,提升站内 SEO
MVP:无
成熟:基于标签/关键词自动推荐

输出:
- 2-4 篇相关文章链接
- 包含标题和简短描述

三、页面路由设计

路由 页面名称 功能描述 MVP 成熟
/seo Dashboard 主控制台,显示统计和快捷入口
/seo/search 视频搜索 YouTube 关键词搜索、筛选、结果列表
/seo/video/[id] 视频详情 视频信息、脚本提取、开始生成博客
/seo/blog/new 新建博客 博客生成器 12 模块编辑器
/seo/blog/[id] 博客编辑 编辑已生成的博客
/seo/drafts 草稿箱 未发布的博客草稿
/seo/blogs 已发布文章 所有已发布的博客(按日期索引)
/seo/images 图片管理 文章配图管理
/seo/templates 模板管理 博客模板、URL 参考
/seo/prompts Prompt 管理 12 个模块的 Prompt 模板 ✅ 简化版
/seo/settings 设置 API 配置、语言设置、站点管理

3.1 文章状态流转

┌──────────────────────────────────────────────────────────────┐
│                      文章生命周期                              │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│  [新建] ─────▶ [草稿 draft] ─────▶ [已发布 published]         │
│                     │                      │                 │
│                     │                      │                 │
│                     ▼                      ▼                 │
│              /seo/drafts             /seo/blogs              │
│                     │                      │                 │
│                     └───── [编辑] ◀────────┘                 │
│                                                              │
└──────────────────────────────────────────────────────────────┘

3.2 文章索引方式(按日期分组)

/seo/blogs
├── 2026年1月 (15篇)
│   ├── 2026-01-21: How to Use AI Image Upscaler
│   ├── 2026-01-20: Top 10 AI Video Tools
│   └── ...
├── 2025年12月 (23篇)
│   └── ...
└── 更早...

四、数据库设计

4.1 完整表结构(支持 MVP + 成熟阶段)

// src/db/schema.ts 中新增

// SEO 视频记录
export const seoVideos = pgTable('seo_videos', {
  id: uuid('id').primaryKey().defaultRandom(),
  siteId: varchar('site_id', { length: 50 }), // 多站点支持
  youtubeId: varchar('youtube_id', { length: 32 }).notNull(),
  title: varchar('title', { length: 500 }).notNull(),
  channelName: varchar('channel_name', { length: 255 }),
  channelId: varchar('channel_id', { length: 64 }),
  publishedAt: timestamp('published_at'),
  viewCount: bigint('view_count', { mode: 'number' }),
  likeCount: integer('like_count'),
  commentCount: integer('comment_count'),
  duration: varchar('duration', { length: 32 }),
  description: text('description'),
  thumbnailUrl: varchar('thumbnail_url', { length: 500 }),
  script: text('script'),
  scriptLanguage: varchar('script_language', { length: 10 }),
  createdAt: timestamp('created_at').defaultNow().notNull(),
  updatedAt: timestamp('updated_at').defaultNow().notNull(),
});

// SEO 博客(完整 12 模块支持)
export const seoBlogs = pgTable('seo_blogs', {
  id: uuid('id').primaryKey().defaultRandom(),
  siteId: varchar('site_id', { length: 50 }), // 多站点支持
  videoId: uuid('video_id').references(() => seoVideos.id),

  // 基础信息
  status: varchar('status', { length: 20 }).default('draft'), // draft | published | archived
  language: varchar('language', { length: 10 }).notNull(),

  // 模块 1: 标题
  title: varchar('title', { length: 500 }),
  slug: varchar('slug', { length: 200 }),

  // 模块 2: 元描述
  metaDescription: varchar('meta_description', { length: 200 }),

  // 模块 3: 特色图片(成熟阶段)
  featuredImageUrl: varchar('featured_image_url', { length: 500 }),
  featuredImageAlt: varchar('featured_image_alt', { length: 200 }),

  // 模块 4-8, 10: 正文内容(JSON 存储各模块)
  content: jsonb('content'), // { introduction, mainContent, examples, conclusion }

  // 模块 5: 目录(成熟阶段,自动生成不存储)

  // 模块 6: 核心要点(成熟阶段)
  keyTakeaways: jsonb('key_takeaways'), // ["point1", "point2", ...]

  // 模块 9: FAQ(成熟阶段)
  faqContent: jsonb('faq_content'), // [{question, answer}, ...]

  // 模块 11: 相关文章(成熟阶段,动态查询不存储)

  // 模块 12: CTA
  ctaContent: text('cta_content'),

  // SEO 元数据
  keyword: varchar('keyword', { length: 200 }),
  tags: jsonb('tags'), // ["ai", "video", "tutorial"]
  wordCount: integer('word_count'),
  readingTime: integer('reading_time'), // 分钟数

  // 作者信息(成熟阶段)
  authorId: varchar('author_id', { length: 100 }),
  authorName: varchar('author_name', { length: 200 }),

  // 发布信息
  templateId: uuid('template_id'),
  publishedUrl: varchar('published_url', { length: 500 }),
  publishedAt: timestamp('published_at'),

  // 统计和标记(成熟阶段)
  isFeatured: boolean('is_featured').default(false),
  isPinned: boolean('is_pinned').default(false),
  viewCount: integer('view_count').default(0),

  // 内部链接(成熟阶段)
  internalLinks: jsonb('internal_links'), // [{url, anchorText}, ...]

  createdAt: timestamp('created_at').defaultNow().notNull(),
  updatedAt: timestamp('updated_at').defaultNow().notNull(),
});

// SEO 图片
export const seoImages = pgTable('seo_images', {
  id: uuid('id').primaryKey().defaultRandom(),
  siteId: varchar('site_id', { length: 50 }),
  blogId: uuid('blog_id').references(() => seoBlogs.id),
  moduleIndex: integer('module_index'),
  prompt: text('prompt'),
  model: varchar('model', { length: 100 }),
  imageUrl: varchar('image_url', { length: 500 }),
  altText: varchar('alt_text', { length: 200 }),
  width: integer('width'),
  height: integer('height'),
  createdAt: timestamp('created_at').defaultNow().notNull(),
});

// SEO Prompt 模板
export const seoPrompts = pgTable('seo_prompts', {
  id: uuid('id').primaryKey().defaultRandom(),
  siteId: varchar('site_id', { length: 50 }),
  module: varchar('module', { length: 50 }).notNull(), // 12 模块之一
  name: varchar('name', { length: 200 }).notNull(),
  content: text('content').notNull(),
  variables: jsonb('variables'),
  isDefault: boolean('is_default').default(false),
  createdAt: timestamp('created_at').defaultNow().notNull(),
});

// SEO 博客模板(成熟阶段)
export const seoTemplates = pgTable('seo_templates', {
  id: uuid('id').primaryKey().defaultRandom(),
  siteId: varchar('site_id', { length: 50 }),
  name: varchar('name', { length: 200 }).notNull(),
  type: varchar('type', { length: 50 }).notNull(), // tutorial/list/comparison/review/news/faq
  structure: jsonb('structure'),
  referenceUrls: jsonb('reference_urls'),
  createdAt: timestamp('created_at').defaultNow().notNull(),
});

// 站点配置(多站点支持)
export const seoSites = pgTable('seo_sites', {
  id: varchar('id', { length: 50 }).primaryKey(), // 如 "seedvr", "another-site"
  name: varchar('name', { length: 200 }).notNull(),
  domain: varchar('domain', { length: 200 }).notNull(),
  blogPath: varchar('blog_path', { length: 200 }).default('/blog'),
  languages: jsonb('languages'), // ["en", "zh", "es"]
  defaultLanguage: varchar('default_language', { length: 10 }).default('en'),
  mdxOutputPath: varchar('mdx_output_path', { length: 500 }), // 导出路径
  isActive: boolean('is_active').default(true),
  createdAt: timestamp('created_at').defaultNow().notNull(),
});

4.2 MVP 阶段使用的字段

MVP 阶段只使用以下字段,其他字段可暂时为空:

必用字段 可选字段
seoVideos id, youtubeId, title, script, createdAt 其他全部
seoBlogs id, status, language, title, content, keyword, createdAt featuredImage, faq, keyTakeaways 等
seoPrompts id, module, name, content variables, siteId

五、发布流程设计

5.1 MVP 阶段:MDX 导出 + 手动复制

┌─────────────────────────────────────────────────────────────────┐
│                    MVP 发布流程                                   │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  SEO Dashboard                         目标站点                   │
│  ─────────────                         ─────────                  │
│                                                                  │
│  1. 博客编辑完成                                                  │
│        │                                                         │
│        ▼                                                         │
│  2. 点击"导出 MDX"                                               │
│        │                                                         │
│        ▼                                                         │
│  3. 下载 MDX 文件                                                │
│     ├── how-to-upscale-images.en.mdx                            │
│     ├── how-to-upscale-images.zh.mdx                            │
│     └── how-to-upscale-images.es.mdx                            │
│        │                                                         │
│        ▼                                                         │
│  4. 手动复制到目标项目          ──────▶  content/blog/            │
│        │                                                         │
│        ▼                                                         │
│  5. git commit & push                                            │
│        │                                                         │
│        ▼                                                         │
│  6. 站点自动部署                                                  │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

5.2 MDX 文件格式

---
title: "How to Upscale Images with AI in 2026"
description: "Learn the best techniques for AI image upscaling using the latest tools and technologies."
date: "2026-01-21"
author: "SEO Dashboard"
tags: ["ai", "upscaler", "tutorial"]
featuredImage: "/images/blog/ai-upscaler-guide.jpg"
readingTime: 8
---

## Key Takeaways

- AI upscaling can improve image quality by up to 4x
- Best results with photos under 2MB
- Free tools available in 2026

## Introduction

{introductionContent}

## How AI Upscaling Works

{mainContent}

## Real-World Examples

{examplesContent}

## FAQ

### Q: What is AI image upscaling?

A: AI image upscaling uses machine learning...

### Q: Is it free?

A: Yes, there are free options available...

## Conclusion

{conclusionContent}

## Take Action

{ctaContent}

5.3 成熟阶段:API 自动发布

┌─────────────────────────────────────────────────────────────────┐
│                    成熟阶段发布流程                                │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  1. 选择目标站点                                                  │
│     ├── seedvr.net                                              │
│     ├── another-site.com                                        │
│     └── third-site.org                                          │
│        │                                                         │
│        ▼                                                         │
│  2. 点击"发布"                                                   │
│        │                                                         │
│        ▼                                                         │
│  3. 系统自动:                                                    │
│     ├── 生成 MDX 文件                                           │
│     ├── 上传图片到 R2                                           │
│     ├── 通过 GitHub API 创建 commit                             │
│     └── 触发站点部署                                             │
│        │                                                         │
│        ▼                                                         │
│  4. 返回发布 URL                                                 │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

六、API 设计

6.1 YouTube 相关

GET  /api/seo/youtube/search    - 搜索视频
GET  /api/seo/youtube/video/:id - 获取视频详情
POST /api/seo/youtube/script    - 提取视频脚本

6.2 博客相关

GET    /api/seo/blogs           - 博客列表
POST   /api/seo/blogs           - 创建博客
GET    /api/seo/blogs/:id       - 获取博客详情
PUT    /api/seo/blogs/:id       - 更新博客
DELETE /api/seo/blogs/:id       - 删除博客
POST   /api/seo/blogs/:id/generate   - AI 生成博客内容
POST   /api/seo/blogs/:id/translate  - 翻译博客
POST   /api/seo/blogs/:id/export-mdx - 导出 MDX 文件
POST   /api/seo/blogs/:id/publish    - 发布博客(成熟阶段)

6.3 图片相关(成熟阶段)

GET    /api/seo/images          - 图片列表
POST   /api/seo/images/generate - AI 生成图片
DELETE /api/seo/images/:id      - 删除图片

6.4 模板相关(成熟阶段)

GET    /api/seo/templates       - 模板列表
POST   /api/seo/templates       - 创建模板
PUT    /api/seo/templates/:id   - 更新模板
DELETE /api/seo/templates/:id   - 删除模板
POST   /api/seo/templates/analyze-url - 分析参考 URL

6.5 Prompt 相关

GET    /api/seo/prompts         - Prompt 列表
PUT    /api/seo/prompts/:module - 更新模块 Prompt
POST   /api/seo/prompts/test    - 测试 Prompt

6.6 站点相关(多站点支持)

GET    /api/seo/sites           - 站点列表
POST   /api/seo/sites           - 添加站点
PUT    /api/seo/sites/:id       - 更新站点配置
DELETE /api/seo/sites/:id       - 删除站点

七、完整 API 梳理

7.1 当前项目已有的 API Key(可复用)

API 环境变量 用途 状态
KIE API KIE_API_KEY 生成图片(Nano Banana, Seedream, Grok Image等) ✅ 已配置
OpenRouter OPENROUTER_API_KEY LLM 大模型(GPT-4, Claude等) ✅ 已配置
FAL AI FAL_API_KEY AI 图片/视频生成 ✅ 已配置
Replicate REPLICATE_API_TOKEN 各种AI模型 ✅ 已配置
WaveSpeed WAVESPEED_API_KEY 视频生成 ✅ 已配置
Resend RESEND_API_KEY 邮件发送 ✅ 已配置
R2 Storage STORAGE_* 图片/文件存储 ✅ 已配置

7.2 需要新增的 API Key

API 环境变量 用途 获取地址
YouTube Data API v3 YOUTUBE_API_KEY 视频搜索和信息获取 Google Cloud Console

7.3 SEO Dashboard 需要用到的所有 API

┌─────────────────────────────────────────────────────────────────┐
│                    SEO Dashboard API 架构                        │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  YouTube Data API v3 ──────────────────────┐                    │
│     └── 搜索视频、获取视频详情、获取字幕     │                    │
│                                             ▼                    │
│  OpenRouter LLM API ─────────────────────────────────────────── │
│     ├── 脚本内容理解和分析                                       │
│     ├── 博客内容生成(12个模块)                                 │
│     ├── 多语言翻译                                               │
│     ├── Key Takeaways 提取                                      │
│     ├── FAQ 生成                                                │
│     └── URL 竞品分析                                             │
│                                             │                    │
│  KIE API (图片生成) ─────────────────────────────────────────── │
│     ├── Nano Banana Pro - 文章配图生成                          │
│     ├── Seedream - 风格化配图                                   │
│     └── Grok Image - 高质量图片                                 │
│                                             │                    │
│  R2 Storage ─────────────────────────────────────────────────── │
│     └── 存储生成的图片和博客资源                                 │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

八、图片生成方案(文章配图)

8.1 方案概述

使用当前项目已有的 KIE API 为博客文章自动生成配图,无需额外配置。

8.2 支持的图片生成模型

模型 API 路由 特点 推荐用途
Nano Banana Pro /api/kie-nano-banana-pro/generate 快速、风格多样 通用文章配图
Seedream /api/kie/seedream/generate 梦幻风格 艺术类文章
Grok Image /api/kie/grok/generate 高质量、逼真 产品展示
GPT-4o Image /api/kie/gpt4o-image/generate 理解力强 复杂场景
Qwen Image /api/kie/qwen/generate 中文理解好 中文内容配图

8.3 图片生成流程(成熟阶段)

博客模块内容 ─────────────────────────────────────────────────────┐
     │                                                            │
     ▼                                                            │
LLM 生成图片描述 Prompt ──────────────────────────────────────────┤
     │                                                            │
     ▼                                                            │
选择图片生成模型 ─────────────────────────────────────────────────┤
     │                                                            │
     ▼                                                            │
调用 KIE API 生成图片 ─────────────────────────────────────────── │
     │                                                            │
     ▼                                                            │
上传到 R2 Storage ────────────────────────────────────────────── │
     │                                                            │
     ▼                                                            │
返回图片 URL 插入博客 ─────────────────────────────────────────── │

九、LLM 大模型方案

9.1 使用 OpenRouter API

模型 模型 ID 特点 推荐用途
Claude 3.5 Sonnet anthropic/claude-3.5-sonnet 长文本、创作 博客写作、FAQ 生成
GPT-4 Turbo openai/gpt-4-turbo 最强综合能力 复杂内容生成
GPT-3.5 Turbo openai/gpt-3.5-turbo 快速、便宜 简单任务、翻译
DeepSeek deepseek/deepseek-chat 性价比高 中文内容

9.2 API 调用示例

// src/lib/seo/llm.ts
import OpenAI from 'openai';

const openrouter = new OpenAI({
  apiKey: process.env.OPENROUTER_API_KEY,
  baseURL: 'https://openrouter.ai/api/v1',
});

// 博客内容生成
export async function generateBlogModule(
  script: string,
  module: string,
  prompt: string,
  model: string = 'anthropic/claude-3.5-sonnet'
) {
  const response = await openrouter.chat.completions.create({
    model,
    messages: [
      { role: 'system', content: prompt },
      { role: 'user', content: script }
    ],
    stream: true,
  });
  return response;
}

// Key Takeaways 提取
export async function generateKeyTakeaways(content: string) {
  // 提取 3-5 个核心要点
}

// FAQ 生成
export async function generateFAQ(content: string, keyword: string) {
  // 生成 3-5 个常见问题
}

// 多语言翻译
export async function translateContent(
  content: string,
  targetLang: string,
  model: string = 'openai/gpt-3.5-turbo'
) {
  // 使用便宜的模型做翻译
}

十、多语言处理方案

10.1 当前项目多语言配置

项目已支持 3 种语言: - en - English - zh - 中文 - es - Español

10.2 SEO Dashboard 多语言策略

部分 多语言策略 原因
Dashboard UI 仅英文 内部工具,简化开发
博客内容 支持 3 种语言 与项目一致
Prompt 模板 仅英文 Prompt 本身不需要翻译

10.3 博客多语言生成流程

原始视频脚本(任意语言)
         │
         ▼
    LLM 理解内容
         │
         ▼
 生成英文博客(主语言)
         │
         ├───────────────────────────────────────────┐
         ▼                                           ▼
    翻译成中文                              翻译成西班牙语
         │                                           │
         ▼                                           ▼
    存储 language='zh'                     存储 language='es'

十一、界面布局

11.1 整体布局

┌─────────────────────────────────────────────────────────────┐
│  Logo    SEO Dashboard                    [User] [设置]      │
├─────────┬───────────────────────────────────────────────────┤
│         │                                                   │
│  侧边栏  │              主内容区                             │
│         │                                                   │
│ Dashboard│                                                  │
│ 视频搜索 │                                                  │
│ 草稿箱   │                                                  │
│ 已发布   │                                                  │
│ 图片管理 │                                                  │
│ 模板管理 │                                                  │
│ Prompt  │                                                   │
│ 设置    │                                                   │
│         │                                                   │
└─────────┴───────────────────────────────────────────────────┘

11.2 博客编辑器布局(成熟阶段 12 模块)

┌─────────────────────────────────────────────────────────────┐
│ 博客编辑器                    [预览] [保存] [翻译] [发布]     │
├─────────────────────────────────────────────────────────────┤
│ 源视频: [视频标题]                    关键词: [________]     │
├──────────────────────┬──────────────────────────────────────┤
│  模块列表            │  编辑区                              │
│  ─────────────       │  ─────────────────────────────────   │
│  ✅ 1. 标题          │  ## 模块: 标题                       │
│  ✅ 2. 元描述        │                                      │
│  ✅ 3. 特色图片      │  Prompt: [选择模板 ▼] [编辑]         │
│  ✅ 4. 开头引言      │                                      │
│  ⬜ 5. 目录(自动)    │  ┌────────────────────────────┐      │
│  ✅ 6. 核心要点      │  │                            │      │
│  ✅ 7. 主要内容      │  │  内容编辑区                 │      │
│  ✅ 8. 案例示例      │  │                            │      │
│  ✅ 9. FAQ          │  │                            │      │
│  ✅ 10. 总结结论     │  └────────────────────────────┘      │
│  ⬜ 11. 相关文章(自动)│                                      │
│  ✅ 12. 行动号召     │  字数: 150  [🤖生成] [🔄重新生成]     │
│                      │                                      │
│  [全部生成]          │                                      │
└──────────────────────┴──────────────────────────────────────┘

十二、技术实现要点

12.1 noindex 设置

// src/app/(seo)/layout.tsx
export const metadata: Metadata = {
  robots: {
    index: false,
    follow: false,
  },
};

12.2 YouTube API 集成

  • 使用 YouTube Data API v3
  • 需要配置 YOUTUBE_API_KEY 环境变量
  • 每日配额限制:10,000 单位

12.3 脚本提取方案

  1. YouTube 字幕 API - 优先使用(MVP)
  2. youtube-transcript 库 - 备选方案
  3. Whisper API - 无字幕时使用(成熟阶段)

12.4 AI 生成方案

  • 使用 OpenRouter (Claude 3.5 Sonnet)
  • 流式输出提升体验
  • 重试机制处理失败

十三、文件结构

src/app/(seo)/
├── layout.tsx              # SEO 布局(noindex)
├── seo/
│   ├── page.tsx            # Dashboard
│   ├── search/
│   │   └── page.tsx        # 视频搜索
│   ├── video/
│   │   └── [id]/
│   │       └── page.tsx    # 视频详情
│   ├── blog/
│   │   ├── new/
│   │   │   └── page.tsx    # 新建博客
│   │   └── [id]/
│   │       └── page.tsx    # 编辑博客
│   ├── drafts/
│   │   └── page.tsx        # 草稿箱
│   ├── blogs/
│   │   └── page.tsx        # 已发布文章(按日期索引)
│   ├── images/
│   │   ├── page.tsx        # 图片管理(成熟阶段)
│   │   └── [id]/
│   │       └── page.tsx    # 图片详情
│   ├── templates/
│   │   └── page.tsx        # 模板管理(成熟阶段)
│   ├── prompts/
│   │   └── page.tsx        # Prompt 管理
│   └── settings/
│       └── page.tsx        # 设置

src/components/seo/
├── video-search-form.tsx   # 搜索表单
├── video-list.tsx          # 视频列表
├── video-card.tsx          # 视频卡片
├── script-viewer.tsx       # 脚本查看器
├── blog-editor.tsx         # 博客编辑器
├── module-editor.tsx       # 模块编辑器
├── prompt-editor.tsx       # Prompt 编辑器
├── language-selector.tsx   # 语言选择器
├── template-picker.tsx     # 模板选择器
├── mdx-exporter.tsx        # MDX 导出器
├── key-takeaways-editor.tsx # 核心要点编辑器(成熟阶段)
├── faq-editor.tsx          # FAQ 编辑器(成熟阶段)
└── image-generator.tsx     # 图片生成器(成熟阶段)

src/actions/seo/
├── youtube.ts              # YouTube API 操作
├── blog.ts                 # 博客 CRUD
├── generate.ts             # AI 生成
├── translate.ts            # 翻译
├── export.ts               # MDX 导出
├── template.ts             # 模板操作(成熟阶段)
└── image.ts                # 图片生成(成熟阶段)

src/lib/seo/
├── llm.ts                  # LLM 调用封装
├── youtube.ts              # YouTube API 封装
├── mdx.ts                  # MDX 生成
└── schema.ts               # FAQ Schema 生成(成熟阶段)

十四、开发优先级总结

MVP 阶段(先做这些)

优先级 功能 时间估计
P0 视频搜索页面 -
P0 视频详情 + 脚本提取 -
P0 基础博客生成(整体生成) -
P0 3 语言翻译 (en/zh/es) -
P0 数据库存储 -
P0 MDX 导出功能 -
P0 草稿箱 + 已发布列表 -

成熟阶段(后续迭代)

优先级 功能 依赖
P1 12 模块独立编辑器 MVP 完成
P1 Prompt 自定义管理 MVP 完成
P1 多站点支持 MVP 完成
P2 AI 图片自动生成 P1 完成
P2 竞品 URL 分析 P1 完成
P2 模板系统 P1 完成
P2 FAQ Schema 标记 P1 完成
P2 批量处理 P1 完成
P3 API 自动发布 P2 完成
P3 数据分析统计 P2 完成
P3 定时任务 P2 完成

十五、技术选型总结

需求 方案 阶段 备注
YouTube 搜索 YouTube Data API v3 MVP 需要新增 API Key
内容生成 OpenRouter API (Claude 3.5) MVP 已有
图片生成 KIE API 成熟 已有
翻译 OpenRouter (GPT-3.5) MVP 便宜够用
存储 PostgreSQL + R2 MVP 已有
多语言 3 种 (en/zh/es) MVP 与项目一致
发布 MDX 导出 MVP 手动复制
发布 GitHub API 成熟 自动发布

十六、实现进度追踪

16.1 已完成的页面

页面 路由 状态 说明
Dashboard /seo ✅ 已完成 主控制台,统计和快捷入口
视频搜索 /seo/search ✅ 已完成 YouTube 关键词搜索
草稿箱 /seo/drafts ✅ 占位页面 待实现功能
已发布 /seo/blogs ✅ 占位页面 待实现功能
图片管理 /seo/images ✅ 占位页面 成熟阶段功能
模板管理 /seo/templates ✅ 占位页面 成熟阶段功能
Prompt 管理 /seo/prompts ✅ 占位页面 待实现功能
设置 /seo/settings ✅ 占位页面 待实现功能

16.2 待实现的核心功能

功能 API 端点 优先级 说明
YouTube 搜索 /api/seo/youtube/search P0 关键词搜索视频
脚本提取 /api/seo/youtube/script P0 提取视频字幕
博客生成 /api/seo/blogs/generate P0 AI 生成博客内容
多语言翻译 /api/seo/blogs/translate P0 翻译到 zh/es
MDX 导出 /api/seo/blogs/export-mdx P0 导出文件

十七、三步工作流程详解

17.1 完整流程

┌─────────────────────────────────────────────────────────────────┐
│                    SEO Dashboard 三步流程                        │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  第一步:关键词 → YouTube 视频 URL                               │
│  ─────────────────────────────────────────────────────────────  │
│  • 输入关键词(如 "ai image upscaler")                          │
│  • 调用 YouTube Data API v3 搜索                                │
│  • 返回视频列表(标题、URL、时长、观看数等)                      │
│  • 支持筛选:日期、时长、排序方式                                 │
│  • 结果存储为 JSON 文件(不用数据库)                            │
│                                                                  │
│  第二步:批量提取视频脚本                                         │
│  ─────────────────────────────────────────────────────────────  │
│  • 从 URL 列表批量提取字幕/脚本                                  │
│  • 使用 youtube-transcript-api 或 yt-dlp                        │
│  • 本地可直接循环处理                                            │
│  • Vercel 需要任务队列(Inngest/Cron)                          │
│  • 脚本存储为 JSON 文件                                          │
│                                                                  │
│  第三步:AI 生成博客文章                                          │
│  ─────────────────────────────────────────────────────────────  │
│  • 选择脚本 → 调用 OpenRouter API                               │
│  • 使用 Claude 3.5 Sonnet 生成博客                              │
│  • 按模板结构生成内容                                            │
│  • 使用 GPT-3.5 Turbo 翻译到其他语言                            │
│  • 导出 MDX 文件到目标站点                                       │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

17.2 存储方案(无数据库)

data/seo/
├── searches/           # 搜索结果
│   └── {keyword}-{date}.json
├── videos/             # 视频信息
│   └── {video_id}.json
├── scripts/            # 提取的脚本
│   └── {video_id}.json
├── drafts/             # 博客草稿
│   └── {slug}.json
└── published/          # 已发布博客
    └── {slug}/
        ├── en.mdx
        ├── zh.mdx
        └── es.mdx

十八、脚本提取方案对比

18.1 方案对比表

方案 类型 优点 缺点 推荐场景
youtube-transcript-api Python 库 最稳定、最流行、专门做字幕 需要 Python 环境 ✅ 本地开发首选
yt-dlp CLI 工具 最强大、支持字幕+音频+视频 需要安装额外工具 备选方案
YouTube Captions API 官方 API 官方支持 需要 OAuth 认证,复杂 生产环境

18.2 youtube-transcript-api 使用示例

# scripts/extract_transcript.py
from youtube_transcript_api import YouTubeTranscriptApi

def get_transcript(video_id):
    """提取视频字幕"""
    try:
        # 尝试获取中文字幕,失败则获取英文
        transcript_list = YouTubeTranscriptApi.list_transcripts(video_id)

        # 优先获取手动字幕
        try:
            transcript = transcript_list.find_manually_created_transcript(['zh', 'en'])
        except:
            # 回退到自动生成字幕
            transcript = transcript_list.find_generated_transcript(['zh', 'en'])

        # 合并所有文本
        full_text = ' '.join([t['text'] for t in transcript.fetch()])
        return full_text
    except Exception as e:
        return f"Error: {str(e)}"

18.3 yt-dlp 使用示例

# 提取字幕(不下载视频)
yt-dlp --write-sub --sub-lang en --skip-download "https://youtube.com/watch?v=xxx"

# 仅列出可用字幕
yt-dlp --list-subs "https://youtube.com/watch?v=xxx"

十九、本地开发 vs Vercel 部署

19.1 关键差异

特性 本地开发 Vercel 部署
超时限制 无限制 10-60 秒(Serverless)
批量处理 简单循环即可 需要任务队列(Inngest)
文件存储 本地文件系统 需要云存储(R2)
Python 脚本 直接运行 需要 Edge Function 或外部服务
开发体验 更自由 有限制但更稳定

19.2 开发策略

┌─────────────────────────────────────────────────────────────────┐
│                    开发部署策略                                   │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  阶段一:本地开发(当前阶段)                                      │
│  ─────────────────────────────────────────────────────────────  │
│  • 所有功能先在本地实现                                           │
│  • 使用本地文件存储 JSON                                         │
│  • Python 脚本直接调用                                           │
│  • 批量处理用简单循环                                            │
│  • 无超时限制                                                    │
│                                                                  │
│  阶段二:Vercel 部署(后续)                                      │
│  ─────────────────────────────────────────────────────────────  │
│  • 单个操作可直接迁移                                            │
│  • 批量操作需要改用 Inngest 任务队列                             │
│  • Python 脚本改用 Edge Function 或外部 API                     │
│  • JSON 存储改用 R2 云存储                                       │
│  • 考虑超时限制优化                                              │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

19.3 批量处理差异

本地开发(简单循环):

// 本地可以直接循环
async function batchExtractScripts(videoIds: string[]) {
  const results = [];
  for (const id of videoIds) {
    const script = await extractScript(id);
    results.push(script);
    await delay(1000); // 避免请求过快
  }
  return results;
}

Vercel 部署(任务队列):

// Vercel 需要使用 Inngest
import { inngest } from '@/lib/inngest';

export const batchExtract = inngest.createFunction(
  { id: 'batch-extract-scripts' },
  { event: 'seo/batch-extract' },
  async ({ event, step }) => {
    const { videoIds } = event.data;

    // 每个视频作为独立步骤
    for (const id of videoIds) {
      await step.run(`extract-${id}`, async () => {
        return await extractScript(id);
      });
    }
  }
);

二十、YouTube API 配额说明

20.1 免费配额

操作 配额消耗 每日免费额度
搜索 100 单位/次 10,000 单位
视频详情 1 单位/次 = 100 次搜索
字幕列表 50 单位/次 或 200 次视频详情

20.2 配额计算示例

假设每天需要:
- 搜索 20 个关键词 × 100 单位 = 2,000 单位
- 获取 200 个视频详情 × 1 单位 = 200 单位
- 总计:2,200 单位 < 10,000 单位 ✅ 足够使用

二十一、Vercel 部署方案详解

21.1 Vercel 的限制

Vercel 是 Serverless 平台,本质上是"按需启动的临时服务器":

限制类型 具体限制 影响
执行超时 Hobby: 10秒, Pro: 60秒 批量任务无法完成
无状态 每次请求都是新环境 无法保持长连接
文件系统只读 只有 /tmp 可写 无法本地存储 JSON
无 Python 环境 只支持 Node.js/Edge Runtime 无法直接运行 Python 脚本

21.2 Inngest 是什么?

Inngest = 托管的任务队列服务(类似邮局)

你的应用                Inngest(邮局)              后台任务
   │                        │                        │
   │  发送任务               │                        │
   ├──────────────────────→│                        │
   │  "提取100个视频脚本"    │                        │
   │                        │  分发任务               │
   │                        ├──────────────────────→│
   │                        │  "提取视频1"            │
   │                        ├──────────────────────→│
   │                        │  "提取视频2"            │
   │                        ├──────────────────────→│
   │                        │  ...                   │
   │                        │                        │
   │  立即返回给用户         │                        │  慢慢执行
   │←──────────────────────┤                        │  不受超时限制

优点: - 不受 Vercel 超时限制 - 自动重试失败任务 - 有免费额度

缺点: - 需要注册新服务 - 需要配置 Webhook - 增加架构复杂度

21.3 独立 Python Worker 是什么?

Python Worker = 单独跑的 Python 脚本服务器

Vercel (Next.js)          独立服务器 (Python)
      │                         │
      │  HTTP 请求              │
      ├───────────────────────→│
      │  "提取这个视频脚本"      │  运行 Python 脚本
      │                         │  youtube-transcript-api
      │                         │  yt-dlp
      │  返回脚本内容           │
      │←───────────────────────┤

实现方式: 1. Railway/Render 免费托管 - 部署一个 Flask/FastAPI 服务 2. VPS(如阿里云/腾讯云) - 自己的服务器跑 Python 脚本 3. Vercel + Supabase Edge Functions - 使用 Deno 运行 Python


二十二、所有部署方案对比

22.1 方案全景图

方案 成本 复杂度 性能 推荐指数
方案1: 本地开发 免费 ⭐ 简单 ⭐⭐⭐⭐⭐ 最快 ✅✅✅ MVP 首选
方案2: VPS 服务器 ¥50/月 ⭐⭐ 中等 ⭐⭐⭐⭐⭐ 最快 ✅✅ 个人使用推荐
方案3: Vercel + Railway Python 免费 ⭐⭐⭐ 复杂 ⭐⭐⭐⭐ 快 ✅ 适合多人协作
方案4: Vercel + Inngest 免费 ⭐⭐⭐⭐ 最复杂 ⭐⭐⭐ 中等 ⚠️ 大规模需要
方案5: 全 Serverless (无 Python) 免费 ⭐⭐ 中等 ⭐⭐ 慢 ⚠️ 不推荐

22.2 详细方案说明

方案1: 本地开发(当前阶段)✅

你的电脑(本地)
├── Next.js 前端页面(pnpm dev)
├── Next.js API 路由(YouTube 搜索、博客生成)
├── Python 脚本(提取字幕)
└── JSON 文件存储(data/seo/)

优点: - 无需任何配置,直接开发 - 无超时限制,随便跑 - 文件系统随便用 - 调试方便

缺点: - 只能你自己用 - 电脑关了就不能用

适合场景: - ✅ MVP 开发阶段 - ✅ 个人使用 - ✅ 测试和验证想法


方案2: VPS 服务器(最简单的生产方案)✅✅

阿里云/腾讯云 轻量服务器(¥50/月)
├── Next.js 应用(pm2 运行)
├── Python 脚本(直接调用)
├── JSON 文件存储(/var/www/data/)
└── Nginx 反向代理

部署步骤:

# 1. 购买服务器(Ubuntu 22.04)
# 2. 安装 Node.js + Python
sudo apt update
sudo apt install nodejs npm python3 python3-pip

# 3. 克隆项目
git clone your-repo.git
cd your-project

# 4. 安装依赖
pnpm install
pip3 install youtube-transcript-api

# 5. 启动应用
pm2 start npm --name "seo-dashboard" -- start

# 6. 配置 Nginx
# 完成!直接用域名访问

优点: - 完全控制,想干啥干啥 - 无超时限制 - 文件存储简单 - 性能好

缺点: - 需要自己维护服务器 - 需要一定运维知识 - 每月约 ¥50 成本

适合场景: - ✅ 个人长期使用 - ✅ 多个网站共用工具 - ✅ 不想折腾各种云服务


方案3: Vercel + Railway Python Worker ✅

Vercel (前端 + API)          Railway (Python 服务)
      │                            │
      │  用户访问网页              │
      │                            │
      │  调用 YouTube 搜索         │
      │                            │
      │  调用 Python 服务 ────────→│  提取脚本
      │                            │  youtube-transcript-api
      │  ←────────────────────── │  返回结果
      │                            │
      │  保存到 R2 Storage         │

Railway 是什么? - 免费的 Python/Docker 托管平台 - 每月免费 $5 额度(约 500 小时运行时间) - 自动从 GitHub 部署

部署步骤:

# 1. 创建 Python 服务 (railway-python-worker/)
# main.py
from fastapi import FastAPI
from youtube_transcript_api import YouTubeTranscriptApi

app = FastAPI()

@app.get("/transcript/{video_id}")
def get_transcript(video_id: str):
    transcript = YouTubeTranscriptApi.get_transcript(video_id)
    return {"script": " ".join([t["text"] for t in transcript])}
# railway.toml
[build]
builder = "nixpacks"

[deploy]
startCommand = "uvicorn main:app --host 0.0.0.0 --port $PORT"
// 2. Vercel 调用 Railway
// src/lib/seo/transcript.ts
export async function extractTranscript(videoId: string) {
  const response = await fetch(
    `${process.env.RAILWAY_PYTHON_URL}/transcript/${videoId}`
  );
  return response.json();
}

优点: - 前后端分离,架构清晰 - Railway 免费额度够用 - Vercel 负责前端和 API - 自动部署

缺点: - 需要管理两个服务 - 需要配置环境变量 - Railway 和 Vercel 之间有网络延迟

适合场景: - ✅ 团队协作开发 - ✅ 需要公开访问 - ✅ 不想自己管服务器


方案4: Vercel + Inngest(大规模任务队列)⚠️

用户 → Vercel → Inngest 任务队列 → 慢慢执行

只有在以下场景需要: - 每天要处理 1000+ 个视频 - 需要定时自动抓取 - 需要自动重试失败任务

当前阶段不推荐,过度工程化。


方案5: 全 Serverless (不用 Python) ⚠️

使用 Node.js 库替代 Python: - youtube-transcript (npm 包) - 或直接调用 YouTube API

缺点: - Node.js 字幕库不如 Python 稳定 - YouTube API 需要 OAuth 认证(复杂) - 性能和准确性不如 youtube-transcript-api

不推荐,除非你非常讨厌 Python。


二十三、推荐的开发路径

23.1 三阶段路径

┌─────────────────────────────────────────────────────────────────┐
│                    推荐开发路径                                   │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  第一阶段:本地开发(1-2周)                                      │
│  ─────────────────────────────────────────────────────────────  │
│  • 在本地实现所有功能                                            │
│  • 验证工作流程是否满足需求                                       │
│  • 测试文章质量                                                  │
│  • 优化 Prompt 模板                                             │
│  → 成本:免费                                                   │
│  → 部署:不需要                                                 │
│                                                                  │
│  第二阶段:VPS 部署(第3周)                                      │
│  ─────────────────────────────────────────────────────────────  │
│  • 购买轻量服务器(阿里云/腾讯云)                                │
│  • 直接把本地代码搬上去                                          │
│  • 配置域名和 HTTPS                                             │
│  • 可以随时随地访问                                              │
│  → 成本:¥50/月                                                 │
│  → 复杂度:低(基本不用改代码)                                  │
│                                                                  │
│  第三阶段(可选):Serverless 优化(未来)                         │
│  ─────────────────────────────────────────────────────────────  │
│  • 如果需要多人使用                                              │
│  • 或者需要自动扩容                                              │
│  • 再考虑 Vercel + Railway 方案                                 │
│  → 成本:免费(小规模)                                          │
│  → 复杂度:中等(需要拆分前后端)                                │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

23.2 当前应该做什么?

答案:先在本地把功能做完!

不用考虑 Inngest、不用考虑 Railway、不用考虑 Serverless。

  1. 第一步:实现 YouTube 搜索 - 创建 /api/seo/youtube/search API - 存储结果到 data/seo/searches/ JSON 文件

  2. 第二步:实现脚本提取 - 创建 Python 脚本 scripts/extract_transcript.py - Next.js API 调用 Python 脚本 - 存储结果到 data/seo/scripts/ JSON 文件

  3. 第三步:实现博客生成 - 使用 OpenRouter API (Claude 3.5 Sonnet) - 生成博客内容 - 导出 MDX 文件

等所有功能都验证 OK 了,再考虑部署到服务器。


二十四、实现完成总结(2026-01-21)

24.1 ✅ 已完成的功能

所有核心功能已实现并可用:

功能 状态 API 端点 文件位置
YouTube 搜索 ✅ 完成 /api/seo/youtube/search route.ts
单视频提取 ✅ 完成 /api/seo/youtube/extract route.ts
批量提取 ✅ 完成 /api/seo/youtube/batch-extract route.ts
AI 生成博客 ✅ 完成 /api/seo/blog/generate 已存在
MDX 导出 ✅ 完成 /api/seo/blog/export-mdx route.ts
JSON 存储 ✅ 完成 - storage.ts

24.2 技术实现细节

脚本提取方案(最终选择)

选择:Node.js youtube-transcript

# 安装
pnpm add youtube-transcript

# 使用
import { YoutubeTranscript } from 'youtube-transcript';
const transcript = await YoutubeTranscript.fetchTranscript(videoId);

为什么选这个? - ✅ 与 Next.js 无缝集成(无需 Python) - ✅ 免费(无 API 费用) - ✅ 已实现缓存机制 - ✅ 适合个人/小团队使用

IP 限制和速率控制

YouTube 官方限制(所有方案都一样):

单 IP 限制:
- 正常:~100 请求/小时
- 限速:101-150 请求/小时(变慢)
- 封禁:151+ 请求/小时(429 错误)

解决方案(已实现):
✅ 每个视频间隔 1 秒(batch-extract API)
✅ 缓存机制(避免重复请求)
✅ 错误处理(失败继续处理下一个)

实际使用建议:
- 每小时最多处理 100 个视频
- 或每天分批处理 500 个视频(5批 × 100个)

存储架构(JSON 文件)

data/seo/
├── searches/           # 搜索结果
│   └── {keyword}-{date}.json
├── videos/             # 视频信息
│   └── {video_id}.json
├── scripts/            # 提取的脚本(带缓存)
│   └── {video_id}.json
├── drafts/             # 博客草稿
│   └── {slug}.json
└── published/          # 已发布博客
    └── {slug}/
        ├── en.mdx
        ├── zh.mdx
        └── es.mdx

优点: - ✅ 无需数据库 - ✅ 本地开发友好 - ✅ 易于备份和迁移 - ✅ Git 可管理(可选)

24.3 访问和权限

路由访问

# 正确的访问 URL
http://localhost:3000/seo        # 英文(默认)
http://localhost:3000/zh/seo     # 中文
http://localhost:3000/es/seo     # 西班牙语

权限要求

⚠️ 重要:SEO Dashboard 需要 admin 权限

代码位置:src/app/[locale]/(protected)/seo/layout.tsx

// 需要登录
if (!session) {
  notFound();
}

// 只有 admin 才能访问
if (session.user.role !== 'admin') {
  notFound();
}

SEO 设置

所有 /seo 路由已配置 robots:

export const metadata: Metadata = {
  title: 'SEO Dashboard',
  robots: {
    index: false,    // ✅ 禁止搜索引擎索引
    follow: false,   // ✅ 禁止跟踪链接
  },
};

24.4 使用流程(完整)

阶段 1:单视频测试(5 分钟)

1. 启动开发服务器
   pnpm dev

2. 访问 SEO Dashboard
   http://localhost:3000/seo
   (确保以 admin 身份登录)

3. 搜索视频
   - 输入关键词:"seedvr2"
   - 查看搜索结果
   - 结果自动保存到:data/seo/searches/

4. 提取脚本
   - 选择一个视频
   - 点击"提取脚本"
   - 脚本保存到:data/seo/scripts/{video_id}.json

5. 生成博客
   - 使用提取的脚本
   - AI 生成博客内容
   - 保存草稿到:data/seo/drafts/{slug}.json

6. 导出 MDX
   - 选择语言(en/zh/es)
   - 导出文件到:data/seo/published/{slug}/{lang}.mdx

阶段 2:批量处理(10-20 分钟)

1. 批量搜索
   - 搜索多个关键词
   - 收集视频 ID 列表

2. 批量提取(API 调用)
   POST /api/seo/youtube/batch-extract
   {
     "videoIds": ["id1", "id2", ..., "id50"]
   }

   特点:
   - 自动检查缓存(已提取的跳过)
   - 每个视频间隔 1 秒
   - 详细进度统计

3. 批量生成博客
   - 遍历所有脚本
   - 逐个生成博客
   - 手动审阅质量

4. 批量导出 MDX
   - 多语言导出
   - 自动生成 frontmatter

阶段 3:日常维护(建议)

每天工作流程:
1. 搜索 1-2 个新关键词
2. 批量提取 50 个视频脚本
3. 生成 5-10 篇博客
4. 审阅 + 导出高质量内容

每周总计:
- 搜索:5-10 个关键词
- 提取:250 个视频脚本
- 生成:25-50 篇博客
- 发布:10-20 篇优质文章

24.5 成本分析(个人使用)

方案对比(月处理 500 个视频)

方案 月成本 处理时间 优点 缺点
当前实现 $0 8分钟(分批) 免费、稳定 需要分批
TranscriptAPI $5 4分钟 快速、无限制 付费
Python 方案 $0 10分钟 最稳定 需要 Python

推荐:继续使用当前免费方案

原因: - ✅ 月处理 500 个视频完全够用 - ✅ 成本 $0 - ✅ 无需额外部署 - ✅ 适合个人/小团队

24.6 环境变量配置

必需的环境变量(已配置):

# ✅ YouTube API(已配置)
YOUTUBE_API_KEY="your_youtube_api_key_here"

# ✅ OpenRouter API(已配置)
OPENROUTER_API_KEY="your_openrouter_api_key_here"

# ✅ 认证相关(已配置)
BETTER_AUTH_SECRET="your_secret_here"
GOOGLE_CLIENT_ID="your_google_client_id"
GOOGLE_CLIENT_SECRET="your_google_client_secret"

# ✅ 基础配置(已配置)
NEXT_PUBLIC_BASE_URL="https://seedvr2.net"

所有必需的环境变量都已配置完成!

24.7 常见问题解答

Q1: 为什么访问 /seo 显示 404?

A: 需要满足两个条件: 1. 已登录 2. 账号角色是 admin

检查方法:

SELECT id, email, role FROM user WHERE email = '你的邮箱';

修改角色:

UPDATE user SET role = 'admin' WHERE email = '你的邮箱';

Q2: 提取脚本时遇到 429 错误怎么办?

A: YouTube 限流了,解决方法:

1. 检查是否短时间内提取了 >100 个视频
2. 等待 1 小时后再继续
3. 增加延迟时间(修改 batch-extract API 的 delay)
4. 或分批处理:每批 50 个,间隔 1 小时

Q3: 某些视频无法提取脚本?

A: 可能的原因:

❌ 视频没有字幕
❌ 字幕被禁用
❌ 区域限制(国家/地区限制)
❌ 会员专属视频

解决方案:
✅ 系统会自动使用视频描述作为备用
✅ 或手动添加脚本内容
✅ 或跳过该视频

Q4: 生成的博客质量不满意怎么办?

A: 优化方向:

1. 调整 AI Prompt(在 generate API 中)
2. 增加上下文信息(视频标题、描述)
3. 使用更强大的模型(GPT-4、Claude Opus)
4. 人工审阅和编辑草稿

Q5: 如何备份数据?

A: 数据都在 data/seo/ 目录:

# 备份所有数据
cp -r data/seo/ backup/seo-$(date +%Y%m%d)/

# 或使用 Git(如果添加到版本控制)
git add data/seo/
git commit -m "Backup SEO data"

# 或压缩备份
tar -czf seo-backup-$(date +%Y%m%d).tar.gz data/seo/

24.8 下一步优化(可选)

短期(1-2 周): - [ ] 优化 AI Prompt 提高博客质量 - [ ] 添加批量导出功能(一键导出所有草稿) - [ ] 添加搜索历史和统计面板

中期(1-2 月): - [ ] 实现定时任务(每天自动搜索+提取) - [ ] 添加质量评分(自动评估博客质量) - [ ] 集成 GitHub API(自动提交 MDX 到仓库)

长期(按需): - [ ] VPS 部署(如果需要远程访问) - [ ] 代理池(如果需要大规模抓取) - [ ] 多人协作(如果团队使用)

24.9 技术债务和注意事项

已知限制:

  1. IP 限制 - YouTube 单 IP 每小时限制 ~100 请求 - 建议分批处理,避免被限流

  2. 缓存策略 - 当前使用永久缓存(除非手动删除) - 未来可考虑添加过期机制

  3. 错误重试 - 当前失败后不重试 - 可添加指数退避重试机制

  4. 并发控制 - 当前使用简单循环(顺序处理) - 可优化为并发处理(控制并发数)

安全性注意:

  • ✅ 所有 SEO 路由需要 admin 权限
  • ✅ 已设置 robots noindex/nofollow
  • ✅ API 端点已验证登录状态
  • ⚠️ 建议定期检查访问日志

24.10 总结

核心成果: - ✅ 完整的 YouTube → AI 博客工作流 - ✅ 无需数据库的 JSON 存储方案 - ✅ 适合个人/小团队的免费实现 - ✅ 所有功能可立即使用

技术栈: - Next.js 15 + TypeScript - youtube-transcript (npm) - OpenRouter API (Claude 3.5 Sonnet) - JSON 文件存储

适用场景: - ✅ 个人博客 SEO 优化 - ✅ 内容创作辅助工具 - ✅ YouTube 视频内容分析 - ✅ 多语言内容生成

开始使用:

# 1. 启动服务器
pnpm dev

# 2. 访问 Dashboard(需要 admin 权限)
http://localhost:3000/seo

# 3. 开始你的第一个工作流
搜索 → 提取 → 生成 → 导出

二十五、最新修改记录(2026-01-21)

25.1 搜索页面工作流程修正

原始问题

最初实现的搜索页面 (/seo/search) 只支持单个 URL 输入,不符合实际需求。

用户反馈

"这个不太对呀,应该是我输入关键词,然后获取批量的搜索结果的全部youtube url相关的呀然后脚本也自动获取吧,可以单个单个的,不然不是多个批量任务要排队吗,或者用api是不是也可以呀,而且我前面给你发了,你是不是可以直接给我搜索调用api都给我弄出来json格式就好了这样我可以直接在网页上查看加载一下呀"

正确的工作流程

关键词输入 → YouTube 批量搜索 → 批量选择视频 → 批量提取脚本 → JSON 导出

实现的功能

  1. 关键词搜索 - 输入关键词(如 "ai video generator") - 调用 YouTube Data API v3 - 返回批量视频列表

  2. 批量选择 - 复选框批量选择视频 - 支持全选/取消全选 - 显示选择数量

  3. 批量提取脚本 - 一次提取多个视频 - 自动检查缓存(已提取的跳过) - 显示提取进度和状态 - 每个视频间隔 1 秒(避免限流)

  4. JSON 导出 - 在网页上预览 JSON - 下载完整的 JSON 文件 - 包含搜索结果和提取结果

文件修改

  • src/app/[locale]/(protected)/seo/search/page.tsx - 完全重写
  • src/app/api/seo/youtube/search/route.ts - 已存在
  • src/app/api/seo/youtube/batch-extract/route.ts - 已存在

25.2 批量处理的 API 超时风险分析

潜在问题

当前 batch-extract API 的实现方式: - 串行处理:一个接一个提取视频脚本 - 延迟机制:每个视频延迟 1 秒避免 YouTube 限流 - 时间计算:50 个视频 = 至少 50 秒

风险评估

  • Next.js API 路由默认超时:60 秒
  • Vercel 免费版超时:10 秒
  • 如果用户选择 50-100 个视频,很可能会超时

解决方案对比

方案 优点 缺点 适用场景
限制最大选择数量 改动最小,避免超时 需要分批操作 ✅ MVP 首选
添加进度提示 用户体验略好 仍有超时风险 折中方案
流式响应 (SSE) 真实进度,不超时 实现复杂 未来优化

用户使用场景

用户明确表示:"本地处理为主,网页端主要是查看,后期再弄网页版处理,现在本地可以直接处理,全部不限额"

结论: - ✅ 本地开发无超时限制 - ✅ 可以直接批量处理 100+ 个视频 - ✅ 不需要限制数量 - ⚠️ 未来部署到 Vercel 时再考虑优化

25.3 Templates 和 Prompts 功能状态

当前状态

两个页面都是 占位页面,只有 UI 展示,没有实际功能:

Templates 页面 (/seo/templates) - ✅ 有 4 个预设模板展示(教程类、评测类、清单类、对比类) - ❌ 没有实际功能实现 - ❌ 不能创建/编辑/删除模板 - ❌ 不能应用模板到博客生成

Prompts 页面 (/seo/prompts) - ✅ 有系统 Prompt 和自定义 Prompt 区分 - ❌ 只有占位数据(preview 只是示例文本) - ❌ 不能编辑/保存 Prompt - ❌ 不能测试 Prompt 效果

待实现功能

Templates 功能需求 1. 从参考 URL 提取结构(网页端) 2. 保存模板到 JSON 文件(本地) 3. 博客生成时选择模板 4. 根据模板结构生成内容

Prompts 功能需求 1. 编辑系统 Prompt(博客生成、翻译等) 2. 创建自定义 Prompt 3. 测试 Prompt 效果(预览生成结果) 4. Prompt 版本管理

等待用户提供内容

用户表示会提供一些内容,需要优化 prompt 和 template 做几个版本。

25.4 本地测试计划

测试任务

  1. 关键词搜索测试 bash 关键词: "seedvr2" 预期: 获取所有相关视频 目标: 形成完整的 JSON 数据

  2. 批量提取测试 bash 选择: 前 20 个视频 测试: 批量提取脚本 验证: 缓存机制和错误处理

  3. JSON 数据验证 bash 检查: 数据完整性 确认: 可以在网页上查看 导出: 下载 JSON 文件

25.5 自动化脚本实现

脚本功能

创建了 scripts/fetch-seedvr2-videos.ts 脚本,一键完成: 1. YouTube 关键词搜索(获取 50 个视频) 2. 视频详细信息提取(时长、播放量、点赞数等) 3. 批量提取字幕脚本(自动延迟避免限流) 4. 保存完整 JSON 数据到本地 data/seo/ 目录 5. 生成人类可读的摘要文档

使用方式

pnpm fetch-seedvr2

测试结果

  • 总视频数: 50 个
  • 成功提取: 37 个
  • 有字幕视频: 0 个(所有视频字幕均被禁用)
  • 提取失败: 13 个
  • 数据文件: data/seo/seedvr2-complete-*.json (103.93 KB)

关键发现

所有 seedvr2 视频的字幕都被禁用,但视频描述非常详细,包含: - 技术细节 - 使用方法 - 相关链接 - 配置说明

建议: 使用 video.description 字段而非 video.script 来生成博客内容。

25.6 网页查看接口实现

API 接口 (/api/seo/data)

  • GET - 列出所有 JSON 数据文件
  • 返回文件名、大小、修改时间
  • 按修改时间倒序排列
  • GET?file=xxx.json - 获取指定文件内容
  • 返回完整 JSON 数据
  • 包含统计信息

UI 页面 (/seo/data)

功能特性: - 左侧:文件列表(显示大小、修改时间) - 右侧:内容查看器 - 统计卡片(总视频数、成功数、字幕数、失败数) - JSON 完整预览 - 下载按钮

访问方式: 在 SEO Dashboard 侧边栏选择 "Data Files" 即可访问 /seo/data 页面。

导航更新

src/components/seo/seo-sidebar.tsx 中添加了:

{ id: 'data', label: 'Data Files', href: '/seo/data', icon: FileJson }

25.7 下一步工作

已完成

  • [x] 更新 DESIGN.md 文档
  • [x] 本地调用 API 测试 seedvr2 关键词搜索
  • [x] 验证批量提取功能
  • [x] 导出示例 JSON 数据
  • [x] 创建网页查看接口
  • [x] 更新侧边栏导航

等待用户输入

  • [ ] 接收用户提供的 Prompt 优化内容
  • [ ] 接收用户提供的 Template 参考资料
  • [ ] 根据用户需求实现 Prompts 管理功能
  • [ ] 根据用户需求实现 Templates 管理功能

未来优化

  • [ ] Prompt 编辑器实现
  • [ ] Template 提取工具实现
  • [ ] 博客生成时支持选择模板
  • [ ] Prompt 版本管理和测试功能

文档版本: v5.1 更新日期: 2026-01-21 更新内容: 完成 seedvr2 自动化脚本、创建网页查看接口、更新侧边栏导航

本文档为站内渲染。原始文件本地路径:saas/source/knowledge-people/Knowledge-World-人物-seo方法论-seo-knowledge-base-DESIGN-782c5c.md(仅本地保留,不入库不部署)