本篇总结了从 Google Gemini 网页端逆向提取 Veo 视频生成 (Veo Video Generation) 能力,并将其封装为标准化 模型上下文协议 (Model Context Protocol, MCP) 工具供 AI 代理 (AI Agent) 调用的完整架构、协议细节与工程实践。


1. 核心架构设计与流程

在 LLM Agent 体系中,文生视频属于高耗时(几十秒到数分钟)、大产物体积(数 MB 至数十 MB 的 MP4 二进制)的任务。如果直接向 Agent 的对话上下文中追加 Base64 编码,会直接打爆模型的上下文窗口(Context Window Blowout),导致后续对话崩溃。

因此,封装设计遵循三层架构:

  1. 底座运行时 (Runtime Gateway):gemini-web2api-go 运行在本地/服务器(端口 8083),处理 TLS 指纹伪装 (Chrome 146)、XSRF Token 换取、会话创建、异步轮询与鉴权下载。
  2. 下载与资产服务 (Asset Storage):生成的 MP4 自动存入公共下载资产区(/var/www/downloads/videos/),映射公网直链(https://6767.chat/downloads/videos/<job_id>.mp4)。
  3. MCP 工具接口 (Agent MCP Layer):向 Claude Code、Antigravity、Cursor 等 Agent 提供 generate_video 和 get_video_status 工具,返回轻量且结构化的 XML 元数据与可点击播放链接。
Agent 发起调用 generate_video(prompt, aspect_ratio="16:9")
   │
   ▼
[MCP Server (server.mjs / video_mcp.py)]
   │ 提交 POST /v1/videos
   ▼
[Gemini Web2API Go 网关 (8083)]
   │ 1. 注入 inner[49]=11 (toolVideo), inner[55]=16 (16:9)
   │ 2. 发起 StreamGenerate 请求,获取会话 CID
   │ 3. 异步轮询 batchexecute: hNvQHb,直到出现 response_data 链接
   │ 4. 过滤 18 项 Google 白名单 Cookie,下载 MP4 产物
   │ 5. 调用 rpc GzXR5e 自动清理云端会话记录
   ▼
[下载并落盘] -> /var/www/downloads/videos/{job_id}.mp4
   │
   ▼
[返回 Agent] -> <video_result status="completed"><url>https://...</url></video_result>

2. Gemini 网页端 Veo 协议逆向关键参数

2.1 请求载荷构造

  • 工具开关:inner[49] = 11 代表启用 Veo 视频生成模型。
  • 画幅指定:inner[55] = 16 为 16:9 横屏,17 为 9:16 竖屏。
  • XSRF 鉴权:登录态请求表单中必须带上 at 字段(即页面中的 SNlM0e Token),否则上游直接返回 400 xsrf 错误。

2.2 异步轮询 (hNvQHb)

视频生成耗时较长,不能阻塞 HTTP 连接。

  • 采用 RPC hNvQHb 周期性(建议 6~8 秒)拉取该 CID 的历史帧;
  • 过滤出包含 contribution.usercontent.google.com/download 且带有 response_data 的真实下载链接;
  • 若出现 can't generate that video,代表触发了 Google 的安全审查与内容政策限制,应立即终止轮询。

2.3 产物下载防 403 踩坑规则

  • Cookie 严格白名单:Google 下载服务器对携带的主机专属 Cookie(如 __Host-1PLSID、OSID)会返回 403,只接收特定的 18 项域 Cookie(HSID, SSID, APISID, SAPISID, SID, __Secure-1PSID, NID 等)。
  • OPI 参数:下载链接尾部必须补全 filename=artifact&opi=103135050。
  • 302 重定向维持 Cookie:下载跨域重定向时,HTTP 客户端必须显式在新域继续携带 Cookie。

3. MCP 工具定义与返回值规范

3.1 工具定义 (Tools)

  • generate_video:

    • prompt (string, required): 提示词;
    • aspect_ratio (enum, optional): 16:9 | 9:16;
    • wait_for_completion (boolean, optional, default: true): 是否阻塞等待完成;
    • timeout_seconds (number, optional, default: 360): 最长等待时间。
  • get_video_status:

    • job_id (string, required): 任务查询 ID。

3.2 XML 响应格式 (避免 Base64 撑爆上下文)

<video_result status="completed" job_id="video_7c8d9e2a1b3f4051">
  <url>https://6767.chat/downloads/videos/video_7c8d9e2a1b3f4051.mp4</url>
  <file_path>/var/www/downloads/videos/video_7c8d9e2a1b3f4051.mp4</file_path>
  <size>4.85 MB (5085520 bytes)</size>
  <prompt>A cute golden retriever puppy running on the green grass under bright sunshine, cinematic 4k</prompt>
  <elapsed>48s</elapsed>
  <markdown>[点击预览/播放视频](https://6767.chat/downloads/videos/video_7c8d9e2a1b3f4051.mp4)</markdown>
</video_result>

4. 关键踩坑点与排障经验

  1. 匿名降级导致 Veo 无法产出视频:

    • 现象:任务一直处于 in_progress,轮询 6 分钟后报错 hNvQHb 里没等到可下载的产物链接。
    • 根因:Google 只对登录态且具备视频生成配额的账号(Gemini Advanced / Google One AI Premium)开放 Veo。当服务器上的 cookie.json 过期或被 Google 判定登出时,网关降级为匿名访问,上游完全不会渲染视频。
    • 解决:在控制台(/gemini-web2api/)或 cookie.json 中导入有效登录态 Cookie。
  2. Stdio MCP 进程 stdout 污染:

    • MCP 协议基于 stdin/stdout 的 JSON-RPC 2.0 传输。如果代码中(包括导入的第三方库)使用 print() 或 console.log() 输出调试信息,会导致客户端 JSON 解析崩溃。
    • 解决:所有日志与调试信息一律强制重定向至 stderr。

本文归档于个人知识库 · 领域:CS & AI · 模块:04 Project_CS_AI/AI apps