Cloudflare Workers AI Vision

用 Cloudflare Workers AI 调用视觉模型(Llama 3.2 11B Vision)分析图片,返回结构化 JSON。

#type / howto #status / growing #tech / ai #resource / cloudflare

[!info] related notes

Cloudflare Workers AI Vision

目标

用 Cloudflare Workers AI 的视觉模型分析图片帧,返回结构化 JSON,用于视频素材理解。

前置条件

  • Cloudflare 账号
  • 已安装 Node.js 和 Wrangler
  • 已同意 Meta Llama 模型 License

能用哪个模型

推荐:

@cf/meta/llama-3.2-11b-vision-instruct

适用场景:visual recognition、image reasoning、captioning、answering questions about an image。

免费额度

Workers AI 免费计划每天 10,000 Neurons,所有限制每天 UTC 00:00 重置。超出后请求会失败,需要 Workers Paid 计划按用量计费。

成本控制建议:

  • 每个视频最多抽 5~8 帧
  • 每张图片压缩到 512px 或 768px 宽
  • prompt 尽量短
  • 重复视频做缓存
  • 每个用户每天限制分析次数

步骤

1. 创建 Worker 项目

npm create cloudflare@latest video-frame-analyzer
cd video-frame-analyzer

选择 Worker only → TypeScript → 不立即部署。

2. 配置 wrangler.toml

name = "video-frame-analyzer"
main = "src/index.ts"
compatibility_date = "2026-06-09"

[ai]
binding = "AI"

binding = "AI" 是关键,后续代码中通过 env.AI 调用模型。

3. 同意 Meta 模型 License

首次使用需要同意 Meta License 和 Acceptable Use Policy:

curl https://api.cloudflare.com/client/v4/accounts/$CLOUDFLARE_ACCOUNT_ID/ai/run/@cf/meta/llama-3.2-11b-vision-instruct \
  -X POST \
  -H "Authorization: Bearer $CLOUDFLARE_AUTH_TOKEN" \
  -d '{ "prompt": "agree" }'

需要 CLOUDFLARE_ACCOUNT_IDCLOUDFLARE_AUTH_TOKEN

4. 编写 Worker 代码

src/index.ts

export interface Env {
  AI: Ai;
}

type AnalyzeRequest = {
  image: string;       // base64 编码的图片
  prompt?: string;     // 可选,自定义分析 prompt
};

export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    if (request.method !== "POST") {
      return Response.json({ error: "Only POST" }, { status: 405 });
    }

    const url = new URL(request.url);
    if (url.pathname !== "/analyze-frame") {
      return Response.json({ error: "Not found" }, { status: 404 });
    }

    let body: AnalyzeRequest;
    try {
      body = await request.json();
    } catch {
      return Response.json({ error: "Invalid JSON" }, { status: 400 });
    }

    if (!body.image) {
      return Response.json({ error: "Missing image" }, { status: 400 });
    }

    const userPrompt = body.prompt ?? `
你是一个短视频素材分析助手。请分析这张视频帧,只返回 JSON。

{
  "description_cn": "中文画面描述",
  "shot_type": "product_closeup | unboxing | usage_demo | lifestyle | talking_head | other",
  "main_subject": "主体",
  "objects": ["物体1", "物体2"],
  "has_person": true,
  "has_product": true,
  "quality": "clear | blurry | dark | low_quality",
  "marketing_role": "hook | pain_point | product_intro | feature_demo | proof | cta | b_roll",
  "tags": ["标签"]
}`;

    const result = await env.AI.run(
      "@cf/meta/llama-3.2-11b-vision-instruct",
      {
        messages: [
          { role: "system", content: "Always output valid JSON." },
          { role: "user", content: userPrompt }
        ],
        image: body.image
      }
    );

    return Response.json({ ok: true, result });
  }
} satisfies ExportedHandler<Env>;

调用模式:env.AI.run(model, { messages, image })。图片可以是 base64 字符串或 URL。

5. 本地测试

wrangler dev --remote

--remote 是必要的,因为 Workers AI 需要远程资源。本地开发时加这个 flag 才能正常调用模型。

测试请求:

# 先将图片转 base64
node -e "console.log(require('fs').readFileSync('./test.jpg').toString('base64'))"

# 发送请求
curl -X POST http://localhost:8787/analyze-frame \
  -H "Content-Type: application/json" \
  -d '{"image": "base64字符串..."}'

6. 部署

wrangler deploy

部署后获得 URL:https://video-frame-analyzer.xxxx.workers.dev

返回值处理

模型有时会把 JSON 包在 Markdown 代码块里,后端需要做清洗:

import json, re

def parse_vision_response(raw_text):
    text = raw_text.strip()
    text = re.sub(r"^```(?:json)?", "", text).strip()
    text = re.sub(r"```$", "", text).strip()
    return json.loads(text)

后端调用示例(Python)

import base64
import requests

WORKER_URL = "https://video-frame-analyzer.xxxx.workers.dev/analyze-frame"

def analyze_frame(image_path):
    with open(image_path, "rb") as f:
        b64 = base64.b64encode(f.read()).decode("utf-8")

    resp = requests.post(WORKER_URL, json={"image": b64})
    resp.raise_for_status()
    return resp.json()

设计 Prompt 的要点

  • 明确要求”只返回 JSON,不要 Markdown”
  • 指定字段名和可选值,减少模型自由发挥
  • 用中文 prompt 得到中文描述,用英文 prompt 得到英文描述
  • system message 可以加 “Always output valid JSON” 强化约束
  • 不要让模型输出太长的分析,会消耗更多 token

边界与易混淆点

  • Workers AI 不是 OpenAI API:调用方式是 env.AI.run(),不是 HTTP 请求到 OpenAI 端点
  • 不能直接上传视频:Worker 只接收图片(base64 或 URL),视频需要在本地抽帧后再传
  • 免费额度是 Neurons 不是请求数:不同模型消耗 Neurons 不同,Vision 模型消耗较高
  • 本地开发需要 --remote:Workers AI 的 binding 在纯本地模式下不可用

相关链接

创建于 2026/6/9 更新于 2026/6/23