上周我把手上一套多模态内容生产流水线整体切到了 Vertex AI 上,Gemini 3 Pro/Flash 负责文本生成与理解,Veo 3.1 负责视频生成,一套凭证、一个项目,把原先分散在好几个地方的处理逻辑全部收拢了。这篇就把完整的接入过程拆开讲,从服务账号权限、Python SDK 初始化,到 Gemini 3 Pro/Flash 的调用姿势、Veo 3.1 的异步视频生成与轮询,再到成本和排障,全程按我实际跑过的路子来。想尽快把 Gemini 3 系列和 Veo 3.1 接进自己业务的读者,可以直接按下面的顺序操作。
1. 项目视角:这套接入方案到底在解决什么问题
1.1 Vertex AI 和裸调模型接口的差别在哪
很多人一开始会图省事,直接拿 Gemini 的公共 API 地址去请求,或者想自己在 GPU 机器上部署一个开源模型来做推理。前者适合个人做 Demo,后者适合对数据隔离有执念的团队,但放到真实业务里,两者都有明显短板:公共入口没有细粒度的权限管控,业务密钥很容易混到前端代码里;自部署则要自己扛 GPU 资源、扩缩容、模型版本更新,光维护成本就够喝一壶的。
Vertex AI 作为云侧托管入口,核心价值在于把模型调用、权限、审计、配额全部统一到一套体系里。我只需要在项目里建好服务账号、绑好角色,所有推理请求都会走云管家的鉴权和日志链。视频生成这种吃 GPU 资源的任务更是如此,Veo 3.1 这类模型如果自己买卡跑,成本几乎不可控,但在 Vertex AI 上只要发起异步任务,底层的排队、调度、重试都由平台处理,我拿到的是一个稳定的 API。
这套方案还有一个容易被低估的好处:文本、图像、视频模型在同一个项目下管理,账单清晰,我记得清每个模块花了多少钱。Gemini 3 Pro/Flash 处理文本和多模态,Veo 3.1 输出视频,所有请求都能在云控制台的监控面板里看到调用量和错误分布。
1.2 Gemini 3 Pro/Flash 与 Veo 3.1 各自在我这套流水线里的角色
借这个项目说清楚分工。我做的是一条营销素材生成流水线:输入一段产品描述,系统先用 Gemini 3 Flash 做关键词抽取和结构化,再用 Gemini 3 Pro 生成完整的分镜脚本和视觉描述,最后把脚本改写成视频提示词,交给 Veo 3.1 生成若干条候选视频。
选择依据很简单:Flash 响应快、单价低,适合批量预处理;Pro 推理能力强,适合需要长上下文和复杂指令的环节。Veo 3.1 则是真正把内容从文字变成视频的一环,它和 Gemini 是两类模型,接入方式也有差异,后面专门讲。
如果你没有现成场景,也可以先跑一个最小化闭环:调用 Gemini 3 Pro 生成一段讲解文案,再用 Veo 3.1 把这段文案的主题扩展成视频。哪怕只是验证链路,整套接入跑通后,后续加业务逻辑就很快。
2. 动手前的准备:项目、权限与 SDK 初始化
2.1 先把项目和 API 打开
我建议先在云控制台里单独建一个项目,别往老项目里塞,因为模型预览阶段可能有独立的配额和服务限制,独立项目可以避免影响线上其他业务。建好项目后,需要手动启用 Vertex AI API,这一步很多人容易漏,结果后面调用时报 403 或者找不到模型。
区域方面,我固定用的是 us-central1。这不是随手选的,Gemini 3 Pro/Flash 和 Veo 3.1 的模型版本在这个区域覆盖最全,配额也相对好申请。其他一些区域只开放了部分模型,或者预览模型没同步,容易出现模型名正确但请求还是报 400 的情况。建议你在初始化客户端时统一把 location 写成一个常量,后面所有请求都会复用,排查问题时也能少一个变量。
另外,Gemini 3 系列目前很多还是预览版本,预览模型通常不保证 SLA,但接口形态和正式版基本一致。如果你的项目里看不到对应模型,先进预览名单或者等正式版本放量,再用同样代码重试。
2.2 三种凭证方式,别一上来就下 JSON 密钥
接入 Vertex AI 绕不开鉴权。我见过太多人第一步就去下载服务账号 JSON 密钥,然后放到代码仓库里,这是非常危险的做法。凭证配置要根据运行环境区分处理:
- 本地开发:优先使用 Application Default Credentials,执行登录命令后,SDK 会自动读取本地凭证,不需要写死在代码里。
- 云服务器或容器:创建独立服务账号,绑定最小权限角色,再把密钥文件通过环境变量的方式注入,不建议提交到代码仓库。
- 云内工作负载(比如托管计算实例或容器集群):直接开启 Workload Identity,让实例用绑定身份去调用 Vertex AI,连密钥文件都不需要管理。
权限角色我推荐只给roles/aiplatform.user。这个角色足够发起推理请求、管理模型相关资源,又不会给太高权限。有人图省事直接绑了 Owner,一旦密钥泄露,整个项目都有风险。
服务账号和角色的关系我常比喻成门禁卡和门禁权限:服务账号是那张卡,角色是卡上对应的开门权限。光建了卡没绑角色,请求会一直报 403。
2.3 初始化 Python 环境
项目里我全程用的是 Python 和官方 SDK。安装命令很简单,新版本 SDK 已经把 Gemini 和 Veo 的客户端都封装好了,不用再单独装其他包。
pip install --upgrade google-cloud-aiplatform pip install --upgrade google-cloud-storage安装完后,本地开发先做一次身份登录:
gcloud auth application-default login然后设置项目常量,写一个最简单的初始化脚本验证链路是否通。这个步骤看起来基础,但我每次接入新环境都会先跑通它,避免后面排了半天错,结果问题出在网络代理或环境变量上。
import vertexai from vertexai.generative_models import GenerativeModel PROJECT_ID = "my-demo-project" LOCATION = "us-central1" vertexai.init(project=PROJECT_ID, location=LOCATION) model = GenerativeModel("gemini-3-pro-preview") resp = model.generate_content("请回复:链路正常") print(resp.text)能正常输出“链路正常”,说明项目、区域、权限、SDK 全部就绪,可以进入正式业务开发。
3. Gemini 3 Pro/Flash 接入的代码级拆解
3.1 Gemini 3 Pro:复杂任务怎么用
需要做深度推理、长文本分析、代码生成、多步拆解时,我会把请求交给 Gemini 3 Pro。它比 Flash 更“沉”,但在复杂任务上的准确率和格式稳定性明显更好。
一个实际例子:营销素材流水线里,我要根据一段产品描述生成投放用的传播方案,包含目标人群、核心卖点、文案框架和行动号召。这种任务如果交给 Flash,经常会有抽风式发挥;换成 Pro 之后,配合低温度参数,输出结构稳定很多。
model = GenerativeModel("gemini-3-pro-preview") resp = model.generate_content( "请根据以下产品描述,生成一套完整的营销传播方案:\n" "包含目标人群、核心卖点、文案框架、行动号召四部分,中文输出。\n\n" "产品:一款支持指纹、人脸、NFC、临时密码的智能门锁。", generation_config={ "temperature": 0.3, "max_output_tokens": 2048, }, ) print(resp.text)这里温度参数我调到 0.3,是因为营销方案虽需要一点创意,但核心结构要稳定,温度太高容易跑偏。等到做标题发散测试时,才会把 temperature 调到 0.7 以上增加随机性。如果你的业务场景本身就是开放创作,温度可以给高一些;如果是抽取、分类、决策,温度尽量往低了压。
另一个关键参数是max_output_tokens。它决定模型最多输出多少 token,而不是“生成到满意为止”。我踩过输出被截断的坑,后来处理长任务时会提前估算输出长度,宁可设大一点,也不能让结果停在半句话上。
3.2 Gemini 3 Flash:批量流水线里真正的主力
如果你也做批量处理,会发现 Flash 才是日常主力。它的推理能力比 Pro 弱,但胜在响应快、成本低。我流水线里的关键词抽取、信息清洗、意图分类,全部交给 Flash 跑。
这里有一个很实用的技巧:让 Flash 直接输出 JSON,并且用response_mime_type约束返回格式。这样就不需要自己写正则或者靠提示词去猜输出结构,解析成本直线下降。
flash_model = GenerativeModel("gemini-3-flash-preview") resp = flash_model.generate_content( "从以下文本中提取品牌、型号、价格和促销信息,输出 JSON。\n\n" "文本:某品牌新款智能门锁上市,型号 X6,限时优惠价 2399 元,下单送安装服务。", generation_config={ "temperature": 0.1, "max_output_tokens": 1024, "response_mime_type": "application/json", }, ) print(resp.text)Flash 配合低温度加 JSON 模式,是我目前最省心的组合。一条请求能把非结构化文本变成可入库的结构化数据,吞吐也扛得住。给一个对比表,方便你按任务类型选模型:
| 维度 | Gemini 3 Pro | Gemini 3 Flash |
|---|---|---|
| 复杂推理 | 强,适合多步骤拆解 | 中,适合简单推理 |
| 响应速度 | 相对慢 | 明显快 |
| 单次成本 | 高 | 低 |
| 典型场景 | 长文档分析、代码生成、方案设计 | 信息抽取、分类、关键词提取、路由分发 |
| 输出稳定性 | 高 | 中,需配合低温度使用 |
一句话总结:预算充足、任务复杂用 Pro;高并发、成本敏感用 Flash。我一般让 Flash 做第一道处理,把需要深度推理的少数请求再转给 Pro,整体成本能降一大截。
3.3 多模态输入:图片、文档、音视频怎么传
Gemini 3 系列天生支持多模态输入,但很多人不知道该怎么把图片传进去。SDK 里提供了一个很直接的方式:用Image.load_from_file读取本地图片,然后作为第一个 message 传入。
我实际用于产品实拍图审核:让模型检查图片里有没有包装破损、标签遮挡、画面是否清晰,输出结构化结论。这类视觉任务如果自己训练一个分类模型,数据采集成本极高;用 Gemini 的多模态接口,几条 prompt 就能跑起来。
from vertexai.generative_models import Image image = Image.load_from_file("product_photo.png") resp = pro_model.generate_content( [ image, "这是一张产品实拍图,请检查是否存在包装破损、标签遮挡、清晰度不足的问题," "逐项输出检查结果。", ], generation_config={ "temperature": 0.2, "max_output_tokens": 512, }, ) print(resp.text)除了图片,Gemini 也能接收 PDF、音视频文件,做法是转成 Part 对象再传入。这块我要提醒一句:多模态输入的 token 消耗比纯文本高得多,尤其图片和视频,模型需要把非文本内容转换成视觉特征。批量做图像审核前,先算一下 token 成本,免得月底账单吓一跳。
4. Veo 3.1 视频生成接入
4.1 视频生成的模型入口和 Gemini 不在一个 API 上
Veo 3.1 虽然和 Gemini 3 系列都在 Vertex AI 项目里,但接入方式有一个关键差异:视频生成不是简单的同步请求,而是异步长任务。原因是视频生成需要大量 GPU 计算,一次推理可能要几十秒到数分钟,模型不可能保持长时间 HTTP 连接等你拿结果。
所以 Veo 3.1 的流程是:提交生成请求后,返回一个长时间运行的操作标识,前端或者后端逻辑拿着这个标识去轮询任务状态,直到任务成功或失败。这个设计和发送一条消息完全不同,刚开始接入的人很容易以为接口卡住了,其实是异步机制在起作用。
在 SDK 层面,可以通过独立的VideoGenerationModel入口访问,模型名类似veo-3.1-preview。如果你的项目还没开放预览,调用时会提示模型不可用,这个看区域配额和权限开放情况。
4.2 用 Python 生成第一段短视频
先看一段能直接跑的代码。我的习惯是把视频提示词单独维护成一个变量,方便后续迭代。
from vertexai.preview.vision_models import VideoGenerationModel video_model = VideoGenerationModel.from_pretrained("veo-3.1-preview") prompt = ( "一只橘猫蹲在窗台上看日落,身后是城市天际线," "镜头从侧面缓慢推近,电影感,暖色调,浅景深" ) response = video_model.generate_videos( prompt=prompt, number_of_videos=1, duration_seconds=8, aspect_ratio="16:9", fps=30, ) print(response.videos[0].uri)生成成功后,返回结果里会有一个 GCS 存储路径,视频文件已经落在云存储桶里。这个 URI 可以直接用于后续分发,也可以下载到本地再处理。
参数部分提一下我的经验:duration_seconds我一般控制在 8 秒以内,单段视频越长,生成时间和成本越高,8 秒足够表达一个完整镜头;aspect_ratio按投放渠道来选,短视频平台用 9:16,B 站或 YouTube 用 16:9;fps用 24 或 30 都可以,动态场景选 30,静态氛围片选 24 更有电影感。
4.3 异步轮询与结果落地
如果你的 SDK 版本较旧,或者需要更精细控制任务状态,可以直接用 REST 方式提交请求,然后轮询操作。提交请求的命令大致长下面这样,需要把项目 ID 和区域替换成你自己的:
curl -X POST \ -H "Authorization: Bearer $(gcloud auth print-access-token)" \ -H "Content-Type: application/json" \ "https://us-central1-aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/us-central1/publishers/google/models/veo-3.1-preview:predict" \ -d '{ "instances": [ { "prompt": "一只橘猫蹲在窗台上看日落,电影感,暖色调" } ], "parameters": { "durationSeconds": 8, "aspectRatio": "16:9", "fps": 30 } }'返回结果里会包含一个操作 ID,拿着它去轮询:
curl -X GET \ -H "Authorization: Bearer $(gcloud auth print-access-token)" \ "https://us-central1-aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/us-central1/operations/OPERATION_ID"轮询时要注意,任务状态可能长时间停留在running。我自己的经验是 8 秒视频一般 1 到 3 分钟内出结果,高峰期会更久。不要做太激进的重试,建议每隔 5 到 10 秒查一次,连续查询一段时间后如果仍在运行,就保持轮询而不是反复重新提交,否则可能产生重复扣费。
拿到生成结果后,我通常会再从 GCS 把视频下载到本地做后处理,比如加字幕、转码、切开片段。下载可以直接用存储客户端:
from google.cloud import storage client = storage.Client(project=PROJECT_ID) bucket_name = video_uri.split("/")[2] blob_name = "/".join(video_uri.split("/")[3:]) bucket = client.bucket(bucket_name) blob = bucket.blob(blob_name) blob.download_to_filename("output.mp4") print("已保存到本地 output.mp4")这样一条 Veo 3.1 视频生成链路就完整闭环了。
5. 参数调优与成本控制
5.1 文本输出的稳定性参数怎么调
Gemini 3 系列的generation_config里,最值得花时间调的是temperature、top_p和max_output_tokens。
temperature控制随机性,数值越低输出越发散程度越低。信息抽取、分类、结构化输出这类任务,我建议 0 到 0.2;内容创作、头脑风暴可以上调到 0.7 到 0.9。注意温度太高不只是“更有创意”,还可能带来事实幻觉和格式混乱,生产环境里不是越高越好。
top_p是采样阈值,和temperature类似但机制不同。我的习惯是固定top_p为 0.95 或者干脆不设,只调温度,因为两个参数同时改容易出现不可预期的行为。
max_output_tokens很多人随手填个 256,结果长文书生成到一半被截断。如果你任务输出可能超过 1000 token,就先设 2048 或者更大,后面根据实际返回再收敛。多花一点 token 比截断后重试更省钱。
| 任务场景 | temperature | max_output_tokens | 备注 |
|---|---|---|---|
| 信息抽取、JSON 输出 | 0.0-0.1 | 1024 | 配合 response_mime_type |
| 文案改写 | 0.7-0.9 | 2048 | 保留一点发散性 |
| 代码生成 | 0.2-0.3 | 4096 | 太长可分步生成 |
| 图像审核 | 0.2 | 512 | 输出固定结论 |
5.2 视频生成的关键参数与提示词写法
Veo 3.1 的核心玩法在于提示词,这比 Gemini 写 prompt 更讲究结构。我总结了一个固定套路:主体 + 动作 + 环境 + 镜头 + 光线 + 风格。例如:
一只橘猫蹲在窗台上看日落,身后是城市天际线,镜头从侧面缓慢推近,电影感,暖色调,浅景深。
这个提示词里,主体是橘猫,动作是蹲着看日落,环境是窗台和城市天际线,镜头是缓慢推近,光线和风格是暖色调加电影感。每部分都描述明确,生成结果的可控性会好很多。
相反,如果只写“一只猫看日落”,Veo 3.1 有很大自由发挥空间,出来的画面可能不是你想要的。视频生成的提示词比文本生成更依赖细节描述,艺术风格、镜头运动、光线方向,这些都对最终视觉效果有直接影响。
另外要注意,视频生成也有内容审核机制。包含暴力、血腥、裸露或明显违规元素的提示词,任务会直接失败,返回的失败原因里通常会有审核相关描述。遇到这种情况,不要反复重试同一个提示词,先改写内容。
5.3 成本账怎么算,Flash 前置是我目前最有效的手段
成本控制是接入 Gemini 3 和 Veo 3.1 后最现实的问题。Gemini 文本按 token 计费,视频按生成时长计费,两者加起来,如果流程设计不合理,账单很容易失控。
我先说一个典型错误做法:直接拿 Gemini 3 Pro 对每一条原始文本做大段长文总结,再丢给 Veo 3.1 生成视频。这样 Pro 的高单价算一次,Veo 的高时长又算一次,成本翻倍。
我现在的方法是分层处理:先用 Flash 做第一步结构化,把原始内容压缩成几百字的脚本要点;只有需要深度润色或扩写的时候才交给 Pro;最后基于压缩后的脚本生成视频提示词,再调用 Veo 3.1。Flash 单价低、速度快,在它这里跑掉的大量预处理任务,整体成本只有原来 Pro 直连的零头。
视频成本的大头在时长和数量。一次性能生成多条候选视频听着美好,但每条都计入费用。我建议先只用一条验证画面风格,确认 prompt 没问题后再批量多出几条备选。这个习惯能帮你省下相当一部分视频生成预算。
配额方面,预览模型有严格限制,尤其是 Veo 3.1,并发和每日生成次数都受配额管控。批量任务建议任务排队,而不是一次性发起几十个并发请求。撞到 429 后,指数退避重试比无脑重试更有效。
6. 排障实录:接入期最常踩的 6 个坑
6.1 403 不是密钥错了,是权限没给全
现象是请求发出去,返回 403,提示当前用户没有权限。很多人第一反应是重新生成密钥,其实多半是服务账号建了,但 IAM 角色没绑。去云控制台检查服务账号是否绑定了roles/aiplatform.user,没绑就补上。这种情况在我接入初期出现过好几次,密钥本身完全没问题。
6.2 预览模型配额很容易撞 429
Gemini 3 系列和 Veo 3.1 预览阶段配额都比较紧。我在跑营销素材流水线时,一个批次发出 20 个视频生成请求,其中一半返回 429。解决方式是把请求拆成小批量,加指数退避重试。如果业务确实需要高并发,提前申请配额提升,预留两三个工作日。
6.3 Veo 任务失败往往是提示词命中审核
Veo 3.1 任务返回失败,常见原因不是接口问题,而是提示词内容被安全过滤器拦了。有次我写了一个包含深夜街头的暴力打斗场景的提示词,任务直接失败。后来改成“深夜街头,灯光昏暗,气氛紧张”的暗示性描述,才顺利生成。注意审核边界,用更艺术化的语言表达冲突情节。
6.4 模型名和区域写错会返回 400/404
模型名称区分大小写,并且要带版本标记,写错一个字都会 404。另外,某些模型不支持你配置的区域,如果确认模型名没问题,检查当前 location。我见过一个项目把 location 配到其他区域,Gemini 能通,Veo 却一直失败,最后改成 us-central1 就正常了。
6.5 长文本截断与 max_output_tokens 不够用
业务需要生成 3000 字长文时,如果max_output_tokens只设了 1024,输出会在中途停止,而且不会报错。这种问题最难发现,因为请求是成功的,只是结果不完整。我在文案生成任务里就把上限拉到 4096,宁可浪费一点配额,也不能让客户拿到的文案停在半句。
6.6 SDK 版本差异导致字段名对不上
不同版本的 SDK,返回对象字段名可能有差异,比如 Veo 生成结果里,videos[0].uri在不同版本可能是generated_videos[0].gcs_uri。代码报 AttributeError 时,先用dir(response)或打印整个对象看结构,别凭记忆写字段名。这个习惯能帮你省下不少排查时间。
| 现象特征 | 可能原因 | 处理建议 |
|---|---|---|
| 401 Unauthorized | 本地凭证过期 | 重新执行 gcloud auth application-default login |
| 403 Forbidden | 服务账号缺少角色 | 绑定 roles/aiplatform.user |
| 404 Model not found | 模型名拼错或区域不支持 | 检查大小写、版本标记、区域 |
| 429 Resource exhausted | 配额不足或并发过高 | 拆批、退避重试、提额申请 |
| Veo 任务失败 | 提示词命中安全审核 | 改写题材和表达方式 |
| AttributeError | SDK 版本字段名不一致 | 打印响应对象确认字段结构 |
项目跑到现在,我最深的体会是:接入 Gemini 3 Pro/Flash 和 Veo 3.1 本身不复杂,复杂的是把权限、配额、成本、异步任务这些外围逻辑处理好。现在再开新项目,我一定会先跑通一条最小链路,从 Flash 抽取开始,到 Pro 生成脚本,再到 Veo 出一段 8 秒视频,全流程验证完再往上叠业务。最后再分享一个小技巧:视频提示词里把镜头运动和光线方向写得越具体,Veo 3.1 的出片越接近你想要的效果,这比换更大的模型参数来得实在。