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, Wrangler
- 相关概念: 视觉语言模型 VLM
- 应用场景: 视频素材理解管线, 视频关键帧提取
- 所属 MOC: AI MOC
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_ID 和 CLOUDFLARE_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 在纯本地模式下不可用