本文定义 AIStudio2API 使用的 Google AI Studio 私有协议、认证状态、WAA 运行时、JSON+protobuf 数组、增量事件、工具与媒体链。模型方法、限制和能力由账户的实时 ListModels 返回,公开 API 将原始结构投影为规范事件和兼容响应。
| 用途 | 入口 | 格式 |
|---|---|---|
| 页面 origin | https://aistudio.google.com |
HTTPS |
| MakerSuite RPC | https://alkalimakersuite-pa.clients6.google.com/$rpc/google.internal.alkali.applications.makersuite.v1.MakerSuiteService/<METHOD> |
application/json+protobuf |
| WAA RPC | https://waa-pa.clients6.google.com/$rpc/google.internal.waa.v1.Waa/<METHOD> |
application/json+protobuf |
| BotGuard interpreter | https://www.google.com/js/bg/<INTERPRETER_HASH>.js |
JavaScript |
| Drive discovery | https://clients6.google.com/discovery/v1/apis/drive/v3/rest?pp=0&fields=…&key=<API_KEY>&%24unique=gc953 |
JSON |
| Drive 上传 | https://content.googleapis.com/upload/drive/v3/files?uploadType=multipart&key=<API_KEY> |
multipart/related |
| Drive resumable 上传 | https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable&fields=id |
分块 HTTPS body |
| Drive 下载 | https://www.googleapis.com/drive/v3/files/<FILE_ID>?alt=media |
HTTPS body |
MakerSuite 请求使用以下公共头:
| Header | 来源 |
|---|---|
content-type |
固定为 application/json+protobuf |
user-agent |
账户固定指纹的 Firefox UA |
x-user-agent |
官网 gRPC-Web 标识 |
x-goog-api-key |
AI Studio 首页或当前官网请求动态值 |
x-goog-authuser |
当前账户官网请求 |
x-aistudio-visit-id |
首页初始化或当前官网请求 |
x-aistudio-g1-tier |
GetAiStudioBenefitTier 返回值映射为 TIER0、TIER1 或 TIER2 |
x-goog-ext-519733851-bin |
当前官网请求动态值;SpiderMonkey WAA 后端由 GetLoggingContext 编码 |
authorization |
三段 SAPISID 签名 |
cookie |
当前账户对目标 RPC 可见的 Cookie |
origin、referer |
https://aistudio.google.com |
accept-language |
账户 locale |
请求头 x-goog-api-key 是 AI Studio 页面使用的动态公共值,与用户创建的 Google Cloud API key 不同;免费网页链仍依赖 Cookie、SAPISID 签名和 WAA proof。
受 WAA 保护的 GenerateContent 由服务进程以 Firefox 152 网络形状经账户固定出口发送;其他 MakerSuite 与 Drive 请求使用同账户固定出口的 Go HTTP transport。WAA_BACKEND=camoufox 时受保护请求通过账户固定指纹 Camoufox 页面发送,保留原生 Firefox TLS、HTTP/2、请求头、Cookie 与页面指纹。
JSON+protobuf 使用数组表示 protobuf message。数组索引从 0 开始,protobuf field 从 1 开始,因此 field N 对应索引 N-1。Google 响应允许省略空槽并形成 [,value];解码器先把省略槽规范化为 null,再从完整 JSON 根值中提取 repeated message。HTTPS chunk 仅提供字节序列,业务事件起止由数组结构确定。
协议核心使用以下 MakerSuite RPC:
| RPC | 用途 |
|---|---|
ListModels |
读取模型、方法、限制、默认参数与能力选项 |
CountTokens |
权威输入 token 计数 |
GenerateContent |
文本、思考、函数、Google 工具、图片、语音与音乐 |
GenerateAccessToken |
获取 Drive bearer token |
GetAppFolder |
读取对话附件所在的应用文件夹 ID |
GenerateTitle |
生成 API 试用页的对话标题 |
GenerateTitle 正文为 ["<提示词>","<回答>","<WAA_PROOF>"],没有回答时回答位为 null,响应为 ["<标题>"]。
AI Studio 页面初始化还包含以下控制面 RPC:
| RPC | 用途 |
|---|---|
GetLoggingContext |
页面日志上下文与条款同意状态 |
AcceptTerms |
同意 AI Studio 条款 |
GetUserPreferences |
用户偏好与欢迎状态 |
UpdateUserPreferences |
更新欢迎状态等用户偏好 |
ListPromos |
页面活动信息 |
GetAiStudioBenefitTier |
账户权益枚举与 tier 请求头 |
ListRecentApplets |
最近 Applet |
ListPrompts |
提示词目录 |
GetUserRestrictions |
账户限制 |
ListIncidentsHistory |
服务事件记录;页面打开期间从启动时的那次请求起每 10 分钟请求一次 |
管理进程启动时加载账户并准备公共头。POST /api/control/start 刷新实时模型目录、预热 WAA Worker并启用数据面,业务能力随后按需调用对应 RPC。
本文中的数据面指处理公开 API 请求、可通过 Stop/Start 启停的生成服务。
authorization 由三个 Cookie 分别签名:
| 令牌标签 | Cookie |
|---|---|
SAPISIDHASH |
SAPISID |
SAPISID1PHASH |
__Secure-1PAPISID |
SAPISID3PHASH |
__Secure-3PAPISID |
三段使用相同的 Unix 秒级时间戳:
source = "<TIMESTAMP> <COOKIE_VALUE> https://aistudio.google.com"
digest = lowercase_hex(SHA1(source))
token = "<LABEL> <TIMESTAMP>_<DIGEST>"
authorization = token_1 + " " + token_2 + " " + token_3
MakerSuite 响应的 Set-Cookie 在响应头到达时与账户最新 storage-state.json 串行合并并原子写回。签名、Cookie 选择和过期判断均以请求时重新读取的账户状态为准。
Windows Chrome 导入从 Profile 恢复 OAuth 与 Device Bound Session Credentials:
Chrome Local State + Profile Preferences + Web Data/token_service
-> Gaia ID、v20 refresh token 密文、wrapped binding key(可为空)
-> 解开 App-Bound v20 主密钥
-> AES-256-GCM 解密 refresh token
-> 有 binding key:OAuthMultilogin sentinel 请求取得 DBSC challenge
-> NCrypt 设备密钥签发 ES256 assertion
-> X25519/HPKE 解密服务端 Cookie
-> 没有 binding key:MultiBearer 头的 OAuthMultilogin 直接返回明文 Cookie
-> 保存 Playwright storage state 结构与续签材料
Chrome 运行期间以排他锁打开 Web Data,程序把 Web Data 与 Web Data-wal 复制到临时目录后只读打开,读取后删除副本。Local State.os_crypt.app_bound_encrypted_key 使用 Base64 编码并带 APPB 前缀。程序把内嵌 ABE helper 加载到独立、隐藏的 Chrome 进程中,取得 32 字节主密钥;临时进程树由 Windows Job Object 管理。token_service.encrypted_token 使用 v20 || nonce[12] || ciphertext+tag,以该主密钥执行 AES-GCM 解密。
设备绑定的账号 OAuthMultilogin 使用 MultiOAuth 头,token_service.binding_key 为空的账号使用 MultiBearer <refresh token>:<Gaia ID> 头,一次请求返回明文 Cookie。MultiOAuth 第一次 assertion 为 DBSC_CHALLENGE_IF_REQUIRED,响应提供 challenge;第二次 assertion 的 JWT header 使用 ES256 与 DEVICE_BOUND_SESSION_CREDENTIALS_ASSERTION。payload 绑定 Google OAuth client、challenge、设备公钥 issuer 和临时 HPKE 公钥。Cookie 密文使用 X25519、HKDF-SHA256 与 AES-128-GCM 解密。
OAuthMultilogin 以该 Profile 的 Chrome 身份发出,请求头与 Chrome GaiaAuthFetcher 相同:HTTP/2 下依次为 content-length、authorization、content-type、sec-fetch-site: none、sec-fetch-mode: no-cors、sec-fetch-dest: empty、user-agent、accept-encoding: gzip, deflate, br, zstd、accept-language 与 priority: u=4, i。user-agent 的主版本取 User Data 的 Last Version;accept-language 取 Profile Preferences 的 intl.accept_languages,没有该项时取 intl.selected_languages,按 Chromium 的规则在带地区的语言后补主语言并依次加 q=0.9 到 q=0.1。导入与续签都读取账户导入来源的 User Data 目录中当前的 Chrome 版本与该 Profile 的语言设置,来源没有记录目录时读取稳定版 Chrome 的默认目录。
Chrome 导入状态在 storage-state.json 的 aistudio2api 扩展中保存来源(浏览器、User Data 目录、Profile 与邮箱)、Gaia ID、refresh token 与 wrapped binding key。登录页跳转、签名 Cookie 失效、HTTP 401 与协议 Code 16 进入同一认证恢复流程,覆盖 Worker 预热、按需启动、普通 RPC、受保护 RPC 与 Live 建连。服务优先在同一账户出口续签 Cookie;保存的 OAuth 材料被拒绝时,从当前 Chrome 匹配原账户邮箱与 Gaia ID,更新来源材料。没有 aistudio2api 扩展的账户在本机 Chrome 登录着同一邮箱时,从 Chrome 导入该邮箱的材料并写入扩展,此后按 Chrome 导入账户续签。有效 Cookie 提交后使动态头失效、关闭该账户 WAA runtime,并重放一次。恢复失败后,服务以账户的指纹、出口与保存的 Cookie 打开 AI Studio 新对话页:被转到 Google 登录页时账户标为 auth_required,管理事件同步发布账户状态,后续调度使用其他合格账户;页面正常打开时账户状态不变,只有该次请求失败或换号。
认证恢复等待同账户的正常请求结束;并发失效复用一次提交结果。替换登录材料推进认证代际,旧请求的认证结果按代际和请求顺序写回;生成正常结束后确认认证有效。HTTP 403、协议 Code 7 与 Drive unauthorized_client 保留模型权限或 Drive 授权含义。隔离 Camoufox 登录和外部 storage state 在本机 Chrome 没有同一邮箱时只使用各自的登录材料。
storage-state.json 保留 Playwright 根字段和未知扩展字段,已定义形状如下。wrapped_binding_key 是 Go []byte 的 Base64 JSON 字符串。
{
"cookies": [
{
"name": "<NAME>",
"value": "<VALUE>",
"domain": ".example.com",
"path": "/",
"expires": -1,
"httpOnly": true,
"secure": true,
"sameSite": "Lax",
"partitionKey": "<OPTIONAL>"
}
],
"origins": [
{
"origin": "https://example.com",
"localStorage": [{"name": "<NAME>", "value": "<VALUE>"}]
}
],
"aistudio2api": {
"source": {"browser": "chrome", "profile": "<PROFILE>", "email": "<EMAIL>"},
"oauth": {
"gaia_id": "<GAIA_ID>",
"refresh_token": "<REFRESH_TOKEN>",
"wrapped_binding_key": "<BASE64>"
}
}
}Cookie 的 name、value、domain、path、expires、httpOnly、secure、sameSite 与可选 partitionKey 原样持久化;sameSite 接受空值、Lax、Strict 或 None。origin 必须包含 scheme 与 host。请求 Cookie 过滤过期项与不匹配的 Secure/domain/path 条目,按 path 长度降序、同长度按持久化顺序发送;普通 HTTP 响应的 Set-Cookie 按 name、domain、path 替换或删除未分区项,替换项留在原位置,新项排在末尾,同名分区项独立保留。浏览器恢复时按持久化顺序逐个写入 Cookie,partitionKey 映射到 BiDi storageKey.sourceOrigin,空值使用默认分区;浏览器导出的 Cookie 中,恢复时写入的项保持写入顺序,之后出现的项排在其后。
| 文件 | 内容 |
|---|---|
auth/<Google 邮箱>/account.json |
邮箱、enabled、proxy、locale、timezone、auth_user |
auth/<Google 邮箱>/storage-state.json |
Cookie、localStorage 和可选 Chrome 续签材料 |
auth/<Google 邮箱>/camoufox-fingerprint.json |
账户固定的 navigator、屏幕、字体、WebGL、语言、地区和时区配置 |
auth/<Google 邮箱>/runtime-state.json |
账户权益、实测模型资格、冷却与 Drive/视频资源绑定 |
auth/<Google 邮箱>/pairing-renewal.json |
远程配对上传签发的续签凭据 SHA-256 与最近一次配对续签时间 |
auth/<Google 邮箱>/camoufox-cache/ |
该账户 Camoufox 的 HTTP 磁盘缓存与 Firefox 启动缓存,运行中的 WAA Worker 独占 |
auth/.leases/<Google 邮箱>.lock |
同一账户目录的跨进程占用锁 |
auth/.leases/<Google 邮箱>.runtime.lock |
每次 runtime-state.json 读取、合并与写回的短事务锁 |
[用户缓存]/AIStudio2API/runtime-leases/<Google 邮箱>.lock |
当前电脑上该邮箱的 WAA Worker 占用锁 |
Google 邮箱的小写形式同时作为账户目录、管理页面标识和日志来源。新账户的 locale 与 timezone 读取当前电脑设置,管理页面使用浏览器语言和 IANA 时区;CLI 使用操作系统语言和时区。初始化、WAA、MakerSuite、OAuth 续签和 Drive 使用账户固定代理。locale 同时设置 navigator language、Accept-Language 与地区,timezone 设置浏览器时区;重新登录和 WAA runtime 复用同一账户指纹。同一电脑上的多个进程按邮箱共享 WAA runtime lease,调度器只会为未被占用的邮箱创建 Worker。
runtime-state.json 根字段为 cooldowns、resources、model_access、benefit_tier、catalog_fingerprint。cooldown value 为 {until,reason?};model access value 为 {state,checked_at,reason?};resource value 为 {kind?,name?,mime?,size?,purpose?,created_at,video?:{model,seconds,size,file?},alias?,sha256?,video_duration?,used_at?,display_name?}:alias 为上传时指定的公开文件 ID,sha256 为内容的 SHA-256 摘要(Base64),video_duration 为视频时长(纳秒),used_at 为内联附件最近被请求引用的时间,display_name 为内联附件在请求中给出的文件名。
每次运行状态事务先取得 auth/.leases/<账户>.runtime.lock,每 25ms 尝试一次,等待上限为 2 秒;携带调用方 context(Go 取消上下文)的事务在调用方取消或 deadline 更早到达时立即结束。取得锁后重新读取当前磁盘值,只合并目标字段,以临时文件原子替换 runtime-state.json,再同步内存状态与资源归属。锁等待失败、读取失败、写回失败和 unlock 失败均返回原始错误链。
调度器按实时模型方法、capability、AccessModes 和账户权益选择候选,优先使用已经成功调用目标 scope(模型资格与冷却的状态记录范围)的预热账户,再按目标模型最近一次真实首事件耗时排序。常驻 Worker 优先覆盖可调用模型更多的账户。预热数量低于上限时提升待机账户,预热账户均忙时等待并发槽位。同账号 WAA proof 串行生成,已准备的 MakerSuite HTTP 请求并发执行;首个活动请求获取 .leases/<邮箱>.lock,最后一个释放。Drive file、视频任务与结果 file 始终使用创建账户。
GetAiStudioBenefitTier 请求为 [],响应 field 1 的枚举映射如下。[]、[null] 和 [0] 均表示 Free;响应存在后续字段时,权益仍由 field 1 决定。
| 值 | 权益 | RPC Header |
|---|---|---|
| 0 | Free | 无 |
| 1 | Pro | X-AIStudio-G1-Tier: TIER1 |
| 2 | Ultra | X-AIStudio-G1-Tier: TIER2 |
| 3 | Plus | X-AIStudio-G1-Tier: TIER0 |
官网为 GenerateContent、CountTokens、Interaction、Code Assistant 与 StreamExtractVideoFrames 注入该 header。模型 field 83 描述访问方式:1 为付费 API key,3 为 Pro/Ultra 订阅,4 为 Ultra 订阅。公开模型目录合并全部账户的实时 ListModels 记录;账户调度使用 AccessModes、BenefitTier 与成功调用历史选择具体账户。
GetLoggingContext 请求为 []。响应 field 6 存在且为否、field 7 存在时,官网要求账户同意条款:功能开关开启且 field 10 为空或 0 时进入 /onboarding 条款表单,否则弹出条款对话框。两处提交的 AcceptTerms 请求如下,成功响应为 []:
| 字段 | 值 |
|---|---|
| 1 | "users/me" |
| 3 | 日志上下文 field 7,为 0 时省略 |
| 4、5 | 邮件订阅,未勾选时省略 |
| 6 | 1 |
| 7 | 日志上下文 field 15,为 0 时省略 |
| 9 | 条款对话框为 1,onboarding 表单为 5 |
服务在每个账户本进程的首次目录同步前读取 GetLoggingContext,需要同意时按 field 10 选择 field 9,以不订阅邮件发送 AcceptTerms;成功后本进程内不再读取,失败时本次目录同步失败,下次同步重新读取。
官网启动时 GetLoggingContext 返回 HTTP 403、错误体 [7,"Region not supported."] 或 [7,"Account not supported."] 时,页面跳转到 https://aistudio.google.com/docs/available-regions。
服务对任一 RPC 的这两种错误报告 AI Studio 不支持当前出口地区或账户,错误文字附上游原文、该跳转页与处理方法(为该账户或全局代理换用支持地区的出口):
- 目录同步失败时账户状态显示该原因,已有目录的账户同样显示
- SpiderMonkey Worker 启动时读取
GetLoggingContext得到该错误即失败 - Camoufox Worker 订阅页面导航事件,页面开始导航到
available-regions页后,后续页面操作立即以该原因失败
受保护请求使用以下链路:
Waa/Create
-> decode challenge
-> load interpreter by current hash
-> initialize official VM lifecycle
-> SHA-256(binding prompt) as lowercase hex
-> snapshot({TYb:{content:<DIGEST>}})
-> write fresh proof into request
-> send protected MakerSuite RPC
WAA_BACKEND=camoufox 时官方 VM 运行在账户固定指纹的 Camoufox 页面,受保护请求由页面 XMLHttpRequest 发送;最后一轮是带文本的 user 轮次的 GenerateContent 由页面应用在输入框写入该轮文本并点击 Run 时发出(与页面上一轮的对话相同时点击 Rerun),proof 由页面应用以服务给出的 binding 摘要生成,发送时正文换成服务编码的请求正文;WAA_BACKEND=spidermonkey 时 VM 运行在服务进程内的 SpiderMonkey 与 Firefox 形状宿主中,受保护请求由 Go HTTP 以 Firefox 152 网络形状发送。
Waa/Create 请求是 JSON+protobuf 数组。Worker 启动时只带 request key,VM 刷新时追加当前 interpreter hash 与上一 VM 的无绑定 snapshot:
["lmnUSbltwc5ULv48iKLX"]
["lmnUSbltwc5ULv48iKLX", "<INTERPRETER_HASH>", "<PREVIOUS_SNAPSHOT>"]响应外层索引 1 是 Base64 challenge,解码后每个字节加 97,得到 message ID、interpreter、program、全局函数名与 client experiments 状态。interpreter 按 hash 缓存,摘要为 SHA-256 的 Base64URL 无 padding 编码;program 属于当前 Create 生命周期,proof 绑定当前 prompt 摘要与 VM 内部状态,每个请求生成新的 proof。
snapshot 的底层输入是四槽数组,首槽承载 binding:
[{content: sha256(bindingPrompt)}, undefined, undefined, undefined]返回值是 ! 开头的 proof。GenerateContent、CreateInteractionStream、CreateInteraction 与 GetInteractionStream 写入 field 5,Build 代理写入 field 3,Build 写代码助手 CodeAssistantOffline 写入 field 2,Bidi 的每个客户端 wire 写入 field 6;原请求的其他槽位保持不变。GenerateContent 按 contents 和 parts 原顺序以单个空格连接。
Waa/Ping 请求和成功响应:
["lmnUSbltwc5ULv48iKLX", "<BOTGUARD_RESPONSE>"]
[]field 1 是 request_key,field 2 是 botguard_response。正确 proof、损坏 proof、省略 field 2、错误 request key 与无账户认证均可返回 HTTP 200 和 []。Ping 成功表示 WAA RPC、API consumer identity 与字段类型可达;Worker VM、snapshot proof、binding、账户会话、模型资格和 GenerateContent 接受状态由实际受保护业务 RPC 判定。
生成服务启动时按配置的常驻数与启动并发数预热账户 WAA Worker。一个账户 Worker 为该账户的所有普通生成模型提供 proof,业务模型切换直接复用当前 Worker;同一账户的 snapshot 串行执行。
请求正文:
[]响应根形状为 [[<MODEL_ROW>, ...]]。模型列表位于 field 1,后续根字段不改变模型目录。模型行字段:
| JSON 索引 | protobuf field | 内容 |
|---|---|---|
| 0 | 1 | models/<MODEL_ID> |
| 2 | 3 | 版本 |
| 3 | 4 | 显示名称 |
| 4 | 5 | 描述 |
| 5 | 6 | 输入 token 上限 |
| 6 | 7 | 输出 token 上限 |
| 7 | 8 | 支持的方法 |
| 8 | 9 | 默认 temperature |
| 9 | 10 | 默认 topP |
| 10 | 11 | 默认 topK |
| 22 | 23 | 模型阶段码:1 UNSTABLE_EXPERIMENTAL、2 EXPERIMENTAL、3 PREVIEW、4 STABLE、5 LEGACY、6 DEPRECATED、7 RETIRED |
| 56 | 57 | 模型别名 |
| 64 | 65 | 主能力码 |
| 66 | 67 | TTS voice 列表 |
| 70 | 71 | 视频配置 |
| 71 | 72 | thinking 默认配置 |
| 74 | 75 | 次能力码 |
| 75 | 76 | 图片宽高比码 |
| 76 | 77 | 图片输出分辨率码 |
| 77 | 78 | Paid 标记,值 2 时显示 Paid |
| 78 | 79 | Interaction 配置:索引 2 为后台任务,索引 3 类型 1 为 agent、2 为模型 |
| 81 | 82 | 官网新建对话时默认开启的设置与工具的能力码 |
| 82 | 83 | 模型访问方式 |
能力码映射:
| 码 | 能力 | 码 | 能力 |
|---|---|---|---|
| 1 | chat model | 9 | code execution |
| 10 | function declarations | 12 | Google Search |
| 13 | URL Context | 20 | video route |
| 21 | image route | 25 | thinking |
| 26 | live route | 35 | thinking budget |
| 37 | speech route | 43 | media resolution |
| 47 | aspect ratio | 49 | output resolution |
| 52 | thinking level | 53 | music route |
| 54 | image search | 58 | Google Maps |
| 59 | private Interaction route | 85 | TTS 分段说话人 |
| 69 | Agentic 视频理解 | ||
| 46 | Live 实时翻译 | 48 | Build 写代码助手可选 |
未知能力码按原值保留为 capability_code_<N> 或 secondary_capability_code_<N>。
公开模型对象为已知主能力码增加以下语义键:
| 码 | capability 键 | 码 | capability 键 |
|---|---|---|---|
| 1 | chat_model |
9 | code_execution |
| 10 | function_declarations |
12 | google_search |
| 13 | browse |
20 | video_route |
| 21 | image_route |
25 | thinking |
| 26 | live_route |
35 | thinking_budget |
| 37 | speech_route |
43 | media_resolution |
| 47 | aspect_ratio |
49 | output_resolution |
| 52 | thinking_level |
53 | music_route |
| 54 | image_search |
58 | google_maps |
| 59 | thinking_summaries |
74 | transcription_word_timestamps |
| 69 | agentic_video |
||
| 76 | transcription_language_codes |
77 | transcription_output |
| 80 | transcription_speaker_labels |
81 | transcription_custom_vocabulary |
| 84 | transcription_smart |
85 | speech_metadata |
| 46 | speech_translation |
48 | code_assistant |
每个主能力码都保留为 capability_code_<N>,同时为上表中的已知码增加语义键;次能力码保留为 secondary_capability_code_<N>;field 82 中默认开启的码保留为 default_capability_code_<N>;有 field 79 的模型带 interactions_api,其中经后台任务生成的模型另带 interaction_task。
图片与视频选项使用枚举码:
| 类型 | 码值映射 |
|---|---|
| 图片/视频宽高比 | 1=1:1、2=9:16、3=16:9、4=3:4、5=4:3、6=3:2、7=2:3、8=5:4、9=4:5、10=21:9、11=9:21、12=1:4、13=4:1、14=1:8、15=8:1 |
| 图片分辨率 | 1=1K、2=2K、3=4K、4=512 |
| 视频时长 | 1=5s、2=6s、3=7s、4=8s、5=4s |
| 视频分辨率 | 1=720p、2=1080p、3=4k、4=368p、5=360p |
视频模型 field 71 的宽高比、时长和分辨率分别位于子索引 4、5、9;子索引 7 含 3 而子索引 9 为空时,分辨率为官网默认的 720p、1080p、4k。子索引 7 含 4 时模型接受起始帧与尾帧,含 5 时接受参考图,公开为 video_inputs 的 frames 与 reference_images。TTS field 67 是 repeated voice row,每行索引 0 为 voice name。thinking field 72 的默认 level 位于子索引 5。
field 57 alias 可以是 ["models/<ALIAS>"],也可以是 repeated row;row 形状时取每行索引 0 并移除 models/ 前缀。公开 capability_options 的键全集为 aliases、voices、image_aspect_ratios、image_output_resolutions、video_aspect_ratios、video_durations_seconds、video_output_resolutions、video_inputs、video_duration_range、video_frame_rates 和 video_tasks;没有值的键省略。Omni 的 field 71 子索引 10 为时长滑块的下限、上限、步长与默认值,公开为 video_duration_range 的 min=、max=、step=、default= 四项;子索引 11 为帧率,1 公开为 24fps;field 85 为视频任务,1–5 公开为 text_to_video、image_to_video、reference_to_video、edit、extend。各键的取值保持上游目录的顺序,多个账户的目录合并时按首次出现的顺序去重;API 试用页以 video_output_resolutions 的第一项为 Omni 的默认分辨率。
纯文本且无 system:
["models/<MODEL_ID>", [<CONTENT>, ...]]含 system、inline data、外部媒体或 Drive file:
["models/<MODEL_ID>", null, ["models/<MODEL_ID>", [<CONTENT>, ...], null, null, null, <SYSTEM>]]请求形状选择:
| 条件 | 根结构 | GenerateContent 子消息位置 |
|---|---|---|
| 纯文本 contents | [model, contents] |
— |
| system instruction | [model, null, generate] |
$[2][5] |
| function / Google tools | [model, null, generate] |
$[2][6] |
| media resolution | [model, null, generate] |
$[2][3][17] |
| inline data、external media、Drive、function call/result、code result | [model, null, generate] |
$[2][1] |
响应为 [totalTokens, system, [content, ...], [tool, ...], null, [[modality, tokenCount], ...]]。system 与每个 content 为 [[partTokens...], roleTokens],没有系统指令时 system 为 [];每个 tool 为 [[functionDeclarationTokens...]],不含函数声明的工具为 []。请求中的系统指令带 user 角色,上游把它的角色 token 计入 totalTokens 与 TEXT 模态;Gemini API 的系统指令没有角色,服务从这两处减去系统指令的角色 token 数。
计数请求的分辨率为请求级分辨率,未设置时取全部媒体 Part 共同指定的分辨率。Part 分辨率各不相同且 Build 通道启用时经 Build 通道 ProxyUnaryCall 发送 POST /v1beta/models/<MODEL_ID>:countTokens,请求体为 {"generateContentRequest":{model,contents,systemInstruction?,tools?,generationConfig?:{mediaResolution}}},响应为 {totalTokens,systemInstructionsTokens,contentTokens,toolTokens?,promptTokensDetails};Playground 目录没有、Build 目录列出 countTokens 的模型同样经 Build 计数。
包含 system 与函数声明的完整计数请求:
[
"models/gemini-3.6-flash",
null,
[
"models/gemini-3.6-flash",
[
[
[[null, "调用 ping 检查服务"]],
"user"
]
],
null,
null,
null,
[
[[null, "你是诊断助手"]],
"user"
],
[
[null, [["ping", "检查服务"]]]
]
]
]响应为单元素数组:
[<INPUT_TOKEN_COUNT>]
索引 0 是权威输入 token 数。其他槽按不透明协议字段保留。
Content 形状:
[[<PART>, ...], "user|model"]带 finish reason 的模型完成帧可以使用 [null,"model"],该帧只提供终止状态与 usage。
客户端 tool result 使用 user role。Part 字段:
| JSON 索引 | protobuf field | 内容 |
|---|---|---|
| 1 | 2 | 文本 |
| 2 | 3 | inline data [mime, base64] |
| 5 | 6 | Drive file [fileId] |
| 6 | 7 | 外部媒体 [mime, url] |
| 7 | 8 | executable code [languageCode, code] |
| 8 | 9 | code execution result [outcomeCode, output] |
| 10 | 11 | function call [name, Struct, callId?] |
| 11 | 12 | function result [name, Struct, callId?] |
| 12 | 13 | thought boolean |
| 14 | 15 | thought signature |
| 15 | 16 | 视频静态处理元数据 [startOffset?, endOffset?, fps?];offset 为 [seconds,nanos?] |
| 17 | 18 | 上传附件 [mime, 上传路径, 文件名, 字节数],字节数为十进制字符串;用于 Build 写代码助手,见 Build 通道 第 8 节 |
| 22 | 23 | transcription metadata [text, speaker?, timestamp spans?] |
| 25 | 26 | 服务端媒体处理调用 [13, name?, Struct?, callId?] |
| 26 | 27 | 服务端媒体处理结果 [13, name?, Struct?, callId?] |
| 39 | 40 | 视频处理模式:1 STATIC、2 AGENTIC |
field 26 与 27 是服务端工具调用与结果 [toolType?, name?, Struct?, callId?],toolType 为 MCP=1(Gemini API 名 CUSTOM)、Google Search=2、URL Context=3、Google Maps=8、媒体处理=13;MCP 结果的 toolType 为空。外部媒体 [mime, url, null, null, null, displayName?] 的第 6 项为附件文件名。
system instruction 每个文本分段一个 Part:
[[[null, "<SYSTEM_TEXT_1>"], [null, "<SYSTEM_TEXT_2>"]], "user"]根消息字段:
| JSON 索引 | protobuf field | 内容 |
|---|---|---|
| 0 | 1 | models/<MODEL_ID> |
| 1 | 2 | contents |
| 2 | 3 | safety settings |
| 3 | 4 | generation config |
| 4 | 5 | fresh WAA proof |
| 5 | 6 | system instruction |
| 6 | 7 | tools |
| 10 | 11 | 固定值 1,自动续写模型省略 |
| 11 | 12 | 历史中最后一个模型轮的 turnToken |
| 13 | 14 | tool config [[<[lat,lng]?>, <languageCode?>, <TIMEZONE>], null, <includeServerSideToolInvocations?>] |
| 14 | 15 | 用户 Cloud API key,免费网页链保持 null |
| 16 | 17 | 自动续写轮的续写 token |
safety settings:
[
[null, null, 7, 5],
[null, null, 8, 5],
[null, null, 9, 5],
[null, null, 10, 5]
]每项为 [null, null, 类别, 阈值],编号与 Gemini API 枚举相同:类别 HARM_CATEGORY_HARASSMENT=7、HATE_SPEECH=8、SEXUALLY_EXPLICIT=9、DANGEROUS_CONTENT=10、CIVIC_INTEGRITY=11;阈值 BLOCK_LOW_AND_ABOVE=1、BLOCK_MEDIUM_AND_ABOVE=2、BLOCK_ONLY_HIGH=3、BLOCK_NONE=4、OFF=5。Playground 没有 HARM_CATEGORY_JAILBREAK 的编号,含该类别的请求经 Build 通道发送。非图片模型默认发送上面 7–10 四类 OFF,Gemini 协议请求中的类别按名称覆盖或追加;图片模型只发送请求中的类别,没有时为 null。上游对 HARM_CATEGORY_UNSPECIFIED(0)与 DEROGATORY 至 DANGEROUS(1–6)返回 400,这些类别与 HARM_CATEGORY_IMAGE_* 不发送;其他未知名称在发送前返回 400 并列出可用类别,未知阈值同样在发送前返回 400。
generation config 字段:
| JSON 索引 | protobuf field | 内容 |
|---|---|---|
| 1 | 2 | stop sequences |
| 3 | 4 | max output tokens |
| 4 | 5 | temperature |
| 5 | 6 | topP |
| 6 | 7 | topK |
| 7 | 8 | response MIME type |
| 8 | 9 | response schema |
| 13 | 14 | 固定值 1 |
| 45 | 46 | 自动续写模型为 1 |
| 14 | 15 | response modalities:TEXT=1、IMAGE=2、AUDIO=3 |
| 15 | 16 | speech config |
| 16 | 17 | thinking config [1, budget?, null, level] |
| 17 | 18 | media resolution:LOW=1、MEDIUM=2、HIGH=3、ULTRA_HIGH=4 |
| 18 | 19 | seed |
| 26 | 27 | image config [aspectRatio?, imageSize?] |
| 31 | 32 | transcription config |
生成参数校验:
| 参数 | 默认来源 | 有效值 |
|---|---|---|
| max output | ListModels field 7,自动续写模型为 inputTokenLimit |
1..model.outputTokenLimit,自动续写模型为 1..model.inputTokenLimit |
| temperature | ListModels field 9 | 0..2 |
| topP | ListModels field 10 | 0..1 |
| topK | ListModels field 11 | 非负整数 |
| thinking level | ListModels field 72 | Low=1、Medium=2、High=3、Minimal=4 |
| thinking budget | 请求值 | 模型能力码包含 thinking budget |
- max output 大于模型上限时按上限发送
reasoning_effort / thinkingLevel / Anthropic output_config.effort 接受 none、minimal、low、medium、high、xhigh、max,xhigh 与 max 按 high 处理,THINKING_LEVEL_UNSPECIFIED 视为未设置。none 在只支持 thinking budget 的模型使用预算 0,支持 thinking level 的模型使用最低可用 level。模型只有 thinking level 能力时,显式 budget 按 0、1024、8192 以内与更大预算分别退化为 minimal、low、medium、high;没有 thinking level 能力的模型忽略其余 effort,两类能力都缺少时同时忽略 budget。
生成与计数请求的模型名可以带思考后缀 <模型 ID>(<值>),例如 gemini-4-argon(low)、gemini-2.5-pro(16384)。值不区分大小写:none、minimal、low、medium、high、xhigh、max 作为思考强度,非负整数作为思考预算,auto 与 -1 使用模型默认思考设置;后缀覆盖请求体中的思考强度与预算,去掉后缀的模型 ID 用于调度、请求日志与用量统计。其他值返回 400。
能力码 48 的模型在目录中另有 <模型 ID>-build 条目,经 Build 写代码助手生成,思考后缀写在 -build 之后,例如 gemini-3.8-flash-build(low);条目定义、请求与流格式见 Build 通道 第 8 节。
模型名等于 MODEL_MAPPING 中的别名(可带 models/ 前缀)时,生成、计数、embedding、Live、视频与转录请求先换成映射的模型名,再解析思考后缀,映射目标可以带后缀,例如 fast:gemini-4-argon(low);别名本身带后缀时以该后缀替换目标自带的后缀,例如 fast(high) 按 gemini-4-argon(high) 处理。同一别名写了多次时以第一项为准,映射只替换一次。/v1/models 与 /v1beta/models 在目录之后列出目标在目录中的别名,字段取自目标模型;与目录 ID 同名的别名替换该条目。
response modalities:
wire 指发送给上游的原始数组字段。
| 输出 | wire | 默认路由 |
|---|---|---|
| text | [1] |
chat |
| image | [2] |
image route |
| image + text | [2,1] |
显式组合请求 |
| audio | [3] |
speech / music route |
AUDIO 采用独立输出模态,与其他模态同时请求时按模型能力取交集。JSON Schema type code 为 string=1、number=2、integer=3、boolean=4、array=5、object=6;schema 支持 format、description、nullable、enum、items、properties、required 和 field 23 propertyOrdering。
以下最小组合请求包含 system、文本、函数声明、generation config、WAA proof 与账户时区。连续空槽保持在同行,字段含义查上表:
[
"models/gemini-3.6-flash",
[
[
[[null, "调用 ping 检查服务"]],
"user"
]
],
[
[null, null, 7, 5],
[null, null, 8, 5],
[null, null, 9, 5],
[null, null, 10, 5]
],
[null, null, null, 512, 0.2, 0.95, 40, null, null, null, null, null, null, 1],
"!WAA_PROOF",
[
[[null, "你是诊断助手"]],
"user"
],
[
[null, [["ping", "检查服务"]]]
],
null,
null,
null,
1,
null,
null,
[[null, null, "Asia/Taipei"]]
]GenerateContent 返回持续增长的 JSON+protobuf 根数组,根索引 0 是 repeated frames。帧结构:
| 路径 | 内容 |
|---|---|
$[0][frame][0] |
candidates |
$[0][frame][0][0][0] |
candidate content |
$[0][frame][0][0][1] |
finish reason code |
$[0][frame][0][0][6] |
citations |
$[0][frame][0][0][7] |
grounding metadata |
$[0][frame][2] |
usage |
$[0][frame][7] |
turnToken |
$[0][frame][3] 且 frame 0 为空 |
interaction metadata |
传输正文是一个 JSON 根值,网络 chunk 提供字节;解码器在 $[0] 中每出现一个完整 repeated frame 时立即消费该 frame。每个内容帧包含一个 candidate,candidate content 为 [[parts...], "model"]。完成帧可以同时携带最后一组 Part、usage、turnToken 和 finish reason,根数组解析完成后结束读取。出错时根索引 1 为流尾 google.rpc 状态 [code, message, details],code 不为 0 时按 Build 通道 的流尾状态表换算 HTTP 状态,以该上游错误结束回复。turnToken 为 v1_ 加 Base64 protobuf,field 2 为该响应的 responseId,同一响应的各帧相同;服务以该 responseId 作为 Gemini 输出的 responseId。
从 $[0] 提取出的文本帧:
[
[
[
[
[[null, "42"]],
"model"
]
]
]
]随后到达的完成帧包含 finish=1、usage 和 turnToken:
[
[[null, 1]],
null,
[27, 1, 28, null, null, null, null, 0, null, 0],
null,
null,
null,
null,
"v1_TURN_TOKEN"
]高频路径速查:
| 结构 | JSONPath | 内容 |
|---|---|---|
| GenerateContent | $[0] |
model |
| GenerateContent | $[1] |
contents |
| GenerateContent | $[3] |
generation config |
| GenerateContent | $[4] |
WAA proof |
| GenerateContent | $[5] |
system instruction |
| GenerateContent | $[6] |
tools |
| GenerateContent | $[13][0][2] |
timezone |
| response root | $[0][frame] |
repeated frame |
| candidate content | $[0][frame][0][0][0] |
[[parts], "model"] |
| candidate finish | $[0][frame][0][0][1] |
finish reason code |
| candidate finish message | $[0][frame][0][0][3] |
finish message |
| Part text | ...parts[part][1] |
text |
| Part inline data | ...parts[part][2] |
[mime, base64] |
| Part function call | ...parts[part][10] |
[name, Struct, callId?] |
| Part thought | ...parts[part][12] |
boolean |
| Part signature | ...parts[part][14] |
signature |
| frame usage | $[0][frame][2] |
usage array |
| frame turnToken | $[0][frame][7] |
turnToken |
Part 文本带 part[12]=1 时属于 reasoning summary,普通文本属于可见正文;带 part[12]=1 的内联图片是图片模型思考过程中的草图,不作为输出媒体返回,最终图片以普通 Part 另行返回;part[14] 是 thought signature。签名可以附在文本、函数调用或独立空 Part 上,下一轮必须原样回传:
| 公开协议 | 签名输入 | 签名输出 |
|---|---|---|
| OpenAI Chat | assistant tool call 的 extra_content.google.thought_signature |
tool call 的同名扩展字段 |
| OpenAI Responses | reasoning.encrypted_content 紧邻后续 function_call |
include 含 reasoning.encrypted_content 时为 reasoning item 的 encrypted_content |
| Anthropic | thinking 或 redacted_thinking block 的 signature |
thinking block 的 signature |
| Gemini | 数据 Part 或独立 Part 的 thoughtSignature |
Part 的 thoughtSignature |
OpenAI Chat 的 assistant tool call 未带 extra_content 时,服务按调用 ID、函数名和参数补回本进程最近签发的签名;查不到时写入 skip_thought_signature_validator。
Playground 通道的历史模型轮与官网同形:服务在进程内按 API key 与对话摘要保存最近 1000 次生成的模型轮,内容为上游按帧给出的思考 Part、正文 Part、函数调用与只带签名的空文本 Part([null,"",…,<signature>]),以及最后一帧的 turnToken。客户端回传的模型轮与保存的回复在正文(忽略空白)、函数调用名称与参数上相同、且之前的对话相同时,发往上游前换成保存的 Part,函数调用沿用客户端的 ID,历史中最后一个模型轮的 turnToken 写入根消息 field 12。带内联媒体的回复与以模型轮结尾的请求不保存;STRIP_THOUGHT_SIGNATURES 打开时不补回。
Anthropic redacted thinking block 以 data 承载同一份不透明状态;适配器在输入与输出两侧保留该值。流式响应不输出文本之后到达的签名。
reasoning summary 是服务端返回的摘要文本。thought signature 作为下一轮请求的协议状态字段原样回传。
协议核心按网络顺序输出 text、reasoning、tool_call、executable_code、code_execution_result、grounding、citation、media、thought_signature、usage、finish 和 error。
grounding metadata 字段:
| JSON 索引 | 内容 |
|---|---|
| 0 | search entry point [renderedContent?, sdkBlob?] |
| 1 | grounding chunks |
| 2 | grounding supports |
| 3 | retrieval metadata,动态分数位于子索引 1 |
| 4 | web search queries |
| 5 | 第二个 repeated web search query 槽 |
| 6 | Maps widget context token |
索引 4、5 按槽位与元素顺序合并并去重。
oneof 表示同组字段中最多选择一种值。
grounding chunk 的 oneof 索引 0/1/2 分别为 web、retrieved context、maps;内部字段依次为 URI、title、text、place ID。support 为 [segment, chunkIndices, confidenceScores],segment 为 [partIndex,startIndex,endIndex,text]。candidate citations 的 entries 位于 metadata 索引 0,每项 URL 在索引 2、title 在索引 3。
包含 web chunk、maps chunk、正文 support、检索分数和查询词的 raw metadata:
[
["<div>Search results</div>", "SDK_BLOB"],
[
[["https://example.com/gemini", "Gemini Guide", "Protocol overview"]],
[null, null, ["https://maps.google.com/?cid=1", "Google Taipei", "", "ChIJ_demo"]]
],
[
[[0, 0, 12, "Gemini Guide"], [0], [0.98]]
],
[null, 0.91],
["Gemini AI Studio protocol"],
null,
"MAPS_WIDGET_CONTEXT_TOKEN"
]Code Execution 的 language code 为 0=LANGUAGE_UNSPECIFIED、1=PYTHON。执行结果 outcome code 为 0=OUTCOME_UNSPECIFIED、1=OUTCOME_OK、2=OUTCOME_FAILED、3=OUTCOME_DEADLINE_EXCEEDED。
完成帧 usage:
| 数组索引 | 语义 | 规范字段 |
|---|---|---|
| 0 | input tokens | input_tokens |
| 1 | visible output tokens | output_tokens |
| 2 | total tokens | total_tokens |
| 3 | 输入中命中上游隐式缓存的 tokens | cached_tokens |
| 7 | tool tokens | tool_tokens |
| 9 | thought tokens | reasoning_tokens |
完整 usage 按上游原值返回;请求带系统指令时,上游把系统指令 user 角色的 1 个 token 计入 input、total 与 TEXT 输入模态,Gemini API 不计,服务从这三处减去。上游每帧都带累计 usage,服务把它写入该帧的事件。完成帧省略 visible output tokens 时,服务按上游 total 与其余分类字段恢复该值。完整 usage 缺失时,内置 Gemini SentencePiece tokenizer 在本地统计可观测输入、工具声明、reasoning summary 和实际输出。
OpenAI 与 Anthropic 的输入统计为 input + tool,输出统计为 visible output + reasoning。Gemini 分别投影 promptTokenCount、candidatesTokenCount、thoughtsTokenCount 与 totalTokenCount。缓存命中数在 Chat 中为 prompt_tokens_details.cached_tokens,在 Responses 中为 input_tokens_details.cached_tokens,两者都包含在输入统计内;Anthropic 的 cache_read_input_tokens 为缓存命中数,input_tokens 为输入统计减去缓存命中数,cache_creation_input_tokens 为 0;Gemini 在命中时输出 cachedContentTokenCount。Build 通道的缓存命中数来自 usageMetadata.cachedContentTokenCount。思考用量在 Chat 中为 completion_tokens_details.reasoning_tokens,在 Responses 中为 output_tokens_details.reasoning_tokens,在 Anthropic 中为 output_tokens_details.thinking_tokens。Chat 的 prompt_tokens_details 与 completion_tokens_details 另含 audio_tokens(上游音频模态细分之和)与值为 0 的 accepted_prediction_tokens、rejected_prediction_tokens。Gemini usageMetadata 省略值为 0 的计数;Build 通道上游给出 billedToolCalls、toolCallStats、modelInvocationTokenCounts、rawPromptTokenCount 与 nonGroundingModelInvocationTokenCounts 时原样输出,Playground 通道的 usage 没有这些字段。隐藏思考用量来自上游 usage field 9;本地 fallback 统计服务端返回的 reasoning summary。
Anthropic 流式 message_start 在首个上游帧带输入用量时写入该用量,否则写入本地输入估算:收到请求时取下文本与工具 JSON,在后台用内嵌 Gemma 3 分词模型计数,与等待上游首个事件同时进行,1 KB 以上文本的计数按内容缓存;最终 message_delta 使用完成 usage 覆盖为权威输入与输出统计。
携带 stop sequence 的 GenerateContent 与 CreateInteractionStream 请求并行执行同账户 CountTokens。正文匹配实际序列时,协议核心关闭生成流,使用 CountTokens 的输入总数以及已输出的正文、reasoning 和工具统计构造最终 usage;计数失败时仍返回 stop_sequence 终态并省略 usage。
ListModels 能力码 91(目录能力 output_continuation)的模型由官网分轮生成超过 32768 token 的输出,输出长度上限为该模型的 inputTokenLimit:
- 请求的 generation config field 46 为
1,根 field 11 省略;max output 大于 32768 时首轮发送 32768 - 候选 field 9(JSON 索引 8)给出续写 token。完成帧以
max_tokens结束且同一帧带 token、本轮上限小于请求的输出总量,或以终止原因 22 结束时,本轮不形成终态 - 下一轮复制原请求,根消息 field 17 写入最近的 token,max output 为
min(输出总量, (轮次 + 1) × 32768),轮次从 0 计 - 终止原因 22 而响应没有 token 时请求失败
各轮正文、思考与工具事件按顺序输出为一个响应,终态取最后一轮。usage 以最后一轮为基础,visible output、thought 与 tool tokens 逐轮累加,total 为最后一轮 total 加之前各轮的这三项。未指定输出上限时输出总量为模型的 inputTokenLimit。输出总量超过 32768 的自动续写请求只经 Playground 调度,未指定输出上限且含 File Search、serviceTier、store:false 等经 Build 通道发送的设置时仍可经 Build,按 Build 的单轮上限发送;请求期限为 REQUEST_TIMEOUT,每个续写轮开始时重新计时。每个续写轮在日志中记一条“上游调用”,模式后附 续写=<轮次>。
| code | reason | code | reason |
|---|---|---|---|
| 0 | unspecified | 1 | stop |
| 2 | max_tokens | 3 | safety |
| 4 | recitation | 5 | other |
| 6 | language | 7 | blocklist |
| 8 | prohibited_content | 9 | spii |
| 10 | malformed_function_call | 11 | image_safety |
| 12 | unexpected_tool_call | 13 | too_many_tool_calls |
| 14 | image_prohibited_content | 15 | image_other |
| 16 | no_image | 17 | image_recitation |
| 18 | missing_thought_signature | 19 | malformed_response |
| 22 | continuation | 其他整数 | provider_<code> |
Build 通道的 Gemini API 终止原因去掉 FINISH_REASON_ 前缀后转为上表的同名小写原因,上表没有的名称为 provider_<小写名称>。上游以 malformed_function_call、unexpected_tool_call 或 malformed_response 结束,或流在完成帧之前中断、以 5xx 流尾状态结束,且这次生成没有输出正文、函数调用与媒体时(不输出给客户端的搜索、网址上下文、地图与文件检索步骤不计入,MCP 调用计入),服务在同一账户上以同一请求重新生成,最多再生成 3 次,之后按最后一次的终止原因或中断错误结束;被重新生成取代的那一次的网页来源与引用不输出,每次重新生成从头匹配停止序列,上一次暂存的停止序列前缀不输出,重新生成的请求发送失败时本次生成以该错误结束。两个通道第一次带终止原因的帧中的内容事件标记为结束帧,自动续写中转入下一轮的帧不标记;Gemini 流式输出把结束帧的内容放进最后一块。
候选 field 5($[0][frame][0][0][4])为安全评级 [[null, null, 类别, 概率, blocked?], ...],类别编号与安全设置相同,概率 NEGLIGIBLE=1、LOW=2、MEDIUM=3、HIGH=4;输入拒绝帧 [null,[block_reason,ratings?,message]] 的 ratings 为同形数组。Build 通道读取候选与 promptFeedback 的 safetyRatings。
generation config、安全设置、工具与转写配置在选择账户前按各账户已载入的模型目录校验,任一账户的条目接受即通过。
- 流式请求在写出响应头前等待首个事件:参数错误与首个事件之前的上游错误按非流式返回 HTTP 状态与错误对象;10 秒内没有事件时先写出响应头,此后的错误以各协议的流内错误事件返回
- 非流式请求收齐上游事件后再输出,上游流中途中断或在完成帧之前结束时换号重发
NONSTREAM_KEEPALIVE=true时,Chat Completions、Responses、Messages、GeminigenerateContent、Interactions 与图片生成的非流式请求在 10 秒内没有结果时先写出200与Content-Type: application/json,之后每 10 秒写出一个换行,结果就绪后写出 JSON 正文;此后的错误以各协议的错误对象作为正文,访问日志与请求账本记录错误的 HTTP 状态FAKE_STREAM=true时,上述协议的流式请求按非流式方式生成:收齐上游事件、中途中断时换号重发,再以各协议的流式事件输出;等待期间按下文的流式心跳保持连接
错误响应根形状为 [null,[code,message,...]]。输入被上游拒绝时帧为 [null,[block_reason,null,message]]:
- Gemini GenerateContent 返回 200 与不含
candidates的promptFeedback:{blockReason,blockReasonMessage},流式时作为唯一一帧发送 - 其他协议返回 400,错误消息包含拒绝原因与上游说明
协议核心保留 HTTP 状态、协议 code 与 message;公开适配器映射为 OpenAI、Anthropic 或 Gemini 错误对象。Chat、Responses、Anthropic Messages 与 Gemini GenerateContent 将媒体模型的普通文本作为文本结果输出;专用图片端点要求图片结果。终态如下:
- HTTP/协议错误形成失败
- 读取上游响应时连接中断或上游流在完成帧之前结束,报告为上游流中断与已接收帧数
- 上游 finish reason 作为正常终态保留并映射到各公开协议
各协议的具体终态转换如下:
| 上游终态 | OpenAI Chat | OpenAI Responses | Anthropic Messages | Gemini GenerateContent |
|---|---|---|---|---|
stop 且包含函数调用 |
tool_calls,旧式 functions 请求为 function_call |
completed,保留 function call item |
tool_use |
STOP,保留 functionCall Part |
stop_sequence |
stop |
completed |
stop_sequence 与实际序列 |
STOP |
max_tokens |
length |
incomplete/max_output_tokens |
max_tokens |
MAX_TOKENS |
continuation |
length |
incomplete/max_output_tokens |
max_tokens |
CONTINUATION |
safety、recitation、blocklist、prohibited_content、spii、图片对应原因与 provider_* |
content_filter |
incomplete/content_filter |
refusal |
对应 Gemini 枚举或 OTHER |
| other、language、malformed_function_call、malformed_response、签名缺失等其他终态 | stop,含函数调用时 tool_calls |
completed |
end_turn,含函数调用时 tool_use |
对应 Gemini 枚举 |
内容拦截终态优先于同一结果中的工具调用终态,已产生的正文、reasoning、工具事件和 usage 保持在响应中。provider_* 在 Chat choice、Responses response、Anthropic message 或 message_delta 的 provider_finish_reason 中保留原值;Gemini 对 Build 通道的 provider_<名称> 输出大写的原枚举名,对 Playground 的 provider_<编号> 输出 OTHER 并用 finishMessage 保留编号。malformed_response(Playground 编号 19)在 AI Studio 页面显示为 Content blocked。
根 field 7 是 repeated Tool:
| 工具 | Tool 数组形状 |
|---|---|
| Function declarations | [null, [[name, description?, schema?, null, behavior?], ...]] |
| Code Execution | [[]] |
| Google Search | [null,null,null,[null,[searchTypes]]],searchTypes 索引 0 为 [] |
| Image Search | 同一 Search tool,searchTypes 索引 1 为 [] |
| URL Context | 8 槽数组,索引 7 为 [] |
| Google Maps | 11 槽数组,索引 10 为 [],enableWidget 时为 [true] |
| Computer Use | 6 槽数组,索引 5 为 [null, null, environment, null, excludedPredefinedFunctions?],environment 浏览器为 1 |
| MCP | 9 槽数组,索引 8 为 [[name, [url, headers?, timeout?, sseReadTimeout?, terminateOnClose?], allowedTools?], ...];headers 为按键排序的 [[key, value], ...],Duration 为 [seconds, nanos],allowedTools 为 [[toolName, ...]] |
FunctionDeclaration field 5 为 behavior,只在 Live 会话的函数声明中发送:BLOCKING 编码为 1,NON_BLOCKING 编码为 2;UNSPECIFIED 与省略相同,不写该字段,其他取值在建立会话前返回 invalid_request 错误帧。Build 通道写入 Gemini API 字段 behavior。generateContent 与 Gemini API 一样不使用 behavior。
Search tool 的 index 3 是 [timeRange?,searchTypes]。timeRange 为 [start?,end?],每个时间值编码为 ["<UNIX_SECONDS>"];searchTypes 的索引 0/1 分别启用 web 与 image search。
公开工具名称归一化后再生成上述 Tool 数组:
| AI Studio 工具 | OpenAI Chat / Responses | Anthropic | Gemini |
|---|---|---|---|
| function declarations | function |
空 type 或 custom |
functionDeclarations |
| Google Search | web_search、web_search_preview |
web_search_* |
googleSearch、googleSearchRetrieval |
| Image Search | image_search |
image_search |
imageSearch |
| URL Context | url_context |
web_fetch_*、url_context |
urlContext |
| Code Execution | code_interpreter |
code_execution_* |
codeExecution |
| Google Maps | google_maps |
google_maps |
googleMaps |
| Computer Use | — | — | computerUse |
| MCP | — | — | mcpServers |
Interactions 的 google_search、google_maps、computer_use、mcp_server 与 file_search 工具分别对应上表的 Google Search 或 Image Search、Google Maps、Computer Use、MCP 与 Gemini fileSearch。File Search 只经 Build 通道发送。
根 field 7 按请求声明逐项编码,函数声明和各类 Google 工具按上表对应的 Tool entry 编码。模型的工具范围取自实时能力码,模型不支持的函数声明与 Google 工具在发送前丢弃,声明的工具全部丢弃时工具选择按 auto 处理;模型没有 function declarations 能力时,历史函数调用与结果改写为 {"functionCall":{"args":…,"name":…}}、{"functionResponse":{"name":…,"response":…}} 文本。根 field 14 为 ToolConfig;field 1 retrieval config 为 [[latitude, longitude]?, languageCode?, timezone]。客户端设置 includeServerSideToolInvocations,或请求同时携带函数声明与 Google 工具、MCP 时,field 3 include_server_side_tool_invocations 为 true,由上游在同一轮内执行服务端工具并返回函数调用。声明 URL context 时 field 3 同样为 true:Playground 只在 URL_CONTEXT 工具结果的 url_metadata 中给出各网址的读取状态,响应末帧的 grounding 只有读取成功的来源链接;客户端没有要求工具步骤且没有函数调用时,这些步骤连同其签名不输出,回传工具步骤的签名时上游返回 400 Invalid thought signature。
编码器将全部函数声明合并为一个 Tool entry;Google Search 与 Image Search 合并为一个 search entry 并分别占用 searchTypes 索引 0/1;Code Execution、URL Context 与 Maps 各占一个 entry。Google Maps 与 Code Execution/URL Context 构成互斥工具组,每个请求选择其中一组。Anthropic server tool 的定义规则见“Anthropic Messages”节。
Playground 的 GenerateContent 与 CountTokens 接受最长 63 字符的函数名。更长的名称在函数声明、历史函数调用与函数结果中统一编码为原名的前 50 个字符、_ 与原名 SHA-256 前 6 字节的十六进制,共 63 字符;上游返回的函数调用在交给公开协议前换回声明的原名。写代码助手与 Live 会话按原名发送。
函数 JSON Struct 使用 protobuf Struct/Value 数组:map 为 [[[key,value],...]];Value oneof 索引 0..5 分别表示 null、number、string、bool、Struct、ListValue。对象键排序后编码。
例如以下函数参数:
{
"city": "Taipei",
"days": 2,
"metric": true,
"note": null,
"units": ["C", "F"]
}编码后的 Struct 为:
[
[
["city", [null, null, "Taipei"]],
["days", [null, 2]],
["metric", [null, null, null, true]],
["note", [0]],
[
"units",
[
null,
null,
null,
null,
null,
[[[null, null, "C"], [null, null, "F"]]]
]
]
]
]完整 function call Part 的关键槽位为:
[
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
["multiply", [[["a", [null, 21]], ["b", [null, 2]]]], "call_01"],
null,
null,
null,
"!THOUGHT_SIGNATURE"
]其中 Part 索引 10 保存 function call,索引 14 保存 thought signature。
Playground 的函数参数载体和结构化输出 Schema 使用以下 protobuf fields:
| JSON Schema | Field | JSON Schema | Field |
|---|---|---|---|
type |
1 | format |
2 |
description |
3 | nullable |
4 |
enum |
5 | items |
6 |
properties |
7 | required |
8 |
minProperties |
9 | maxProperties |
10 |
minimum |
11 | maximum |
12 |
minLength |
13 | maxLength |
14 |
pattern |
15 | example |
16 |
oneOf |
17 | anyOf |
18 |
allOf |
19 | not |
20 |
maxItems |
21 | minItems |
22 |
propertyOrdering |
23 |
结构化输出 Schema 归一化规则:
| 输入结构 | 编码结果 |
|---|---|
可选字段显式 null |
移除未设置字段;example:null 保留为数据值,const 按常量规则校验,属性名称保留 |
零参数函数的空定义、null、{} 或 true |
object 参数结构 |
开放的 {}、true 与缺少元素定义的 array |
开放节点:可空的 anyOf,分支为 string、number、boolean 与元素为这三种的 array |
Gemini type:"TYPE_UNSPECIFIED" |
按无类型节点处理 |
非负整数约束写成字符串 int64 或 1.0 |
按整数编码 |
items:false |
空数组约束 maxItems=0;与正数 minItems 同时设置时返回参数错误 |
not:false |
移除空否定约束 |
not:true、not:{}、根 false、必填属性的 false |
返回禁止所有值的参数错误 |
可选属性的 false |
移除该属性 |
not:{type:"null"} |
设置 nullable=false |
字符串或字符串数组形式的 not |
字符串枚举排除约束 |
$schema、default、additionalProperties、exclusiveMinimum、propertyNames、prefixItems |
从 wire schema 中省略 |
required 中未在 properties 定义的属性 |
补充不限类型的属性定义 |
指向根 $defs 或 definitions 的本地 $ref |
Playground 展开为被引用的定义,完整 Schema 写入说明;循环引用保留开放节点 |
type: [T, "null"] |
根类型 T 与 nullable=true |
anyOf / oneOf 的 null 分支 |
移除 null 分支并设置 nullable=true |
多个非 null type |
开放根节点与完整类型集合的 anyOf |
组合 Schema 缺少根 type |
相同类型的分支推导根类型;混合类型保留开放根节点,相同 items 可写入根节点 |
其他节点缺少 type |
含 properties 为 object,含 items 或 prefixItems 为 array;字符串约束推导 string,其余为开放节点 |
array 缺少 items |
prefixItems 中带类型的项组成 anyOf;其余使用开放元素节点 |
| 其他 Schema 字段 | 按层级与类型编码,完整 Schema 写入说明 |
结构化输出以客户端的 JSON Schema 为输出契约:无法直接编码的 Schema(如数值 const、单独的 null 类型)按层级与类型编码,根说明附完整 Schema,两个通道使用同一结果。含开放节点,或 JSON Schema 含 additionalProperties(非 false)、prefixItems、propertyNames、exclusiveMinimum、exclusiveMaximum、uniqueItems 的结构化输出在启用 Build 时使用 Build 通道并原样发送,没有账户能经 Build 服务时使用 Playground;Playground 的 Schema 没有任意类型与 additionalProperties 字段,这类请求以 JSON 模式发送(response_mime_type 为 application/json,不带 response_schema),完整 JSON Schema 作为最后一段系统指令。非对象 Schema 返回参数错误。
函数声明以客户端的 JSON Schema 为参数契约。Playground 对开放节点、混合联合、引用、数值枚举与常量生成可发送的参数载体,将完整 Schema 放入工具说明;普通可表达声明保持原编码,历史调用与工具结果保持原值。Build 使用 parametersJsonSchema,保留组合分支与约束。strict:true 和 Gemini VALIDATED 在完整工具事件返回前校验原始参数契约;不符合契约的上游调用返回协议错误。本地无法编译的 Schema(如外部 URL 引用)只随声明发送,不做本地校验。
auto 由模型决定调用,none 省略 tools。指定函数使用声明子集;Playground 将调用要求写入生成指令并核对实际返回,Build 使用原生 functionCallingConfig。客户端工具选择映射如下:
| 公开协议 | 自动与关闭 | 要求调用 |
|---|---|---|
| OpenAI Chat / Responses | 默认、auto、none |
required、named function |
| Anthropic | 默认、auto、none |
any、named tool |
| Gemini | 默认、AUTO、NONE、VALIDATED |
ANY 与 allowedFunctionNames |
函数调用响应 Part 为 [name, Struct, callId?];下一轮 function result 使用同一形状并原样带回 thought signature。tool result 显式提供函数名时保留该值;缺少名称时,先按 call ID 关联当前轮尚未返回结果的调用,未匹配且仅剩一个调用时使用其名称。每个结果对应一个调用,调用与结果之间的助手文本不影响关联,新一轮普通对话开始后重新建立关联;存在歧义或缺少调用记录时返回参数错误。函数参数和结果使用 JSON object,非对象的参数与结果封装为 {"result":<VALUE>},与 Build 的 Gemini API 编码相同。
四个协议的工具结果为内容块数组(每个元素带 type)时,文本块以换行相连写成 {"result":"<文本>"},错误结果写成 {"error":"<文本>"};图片、文档、音频与视频块按所属协议的媒体规则转换,作为紧随该函数结果的 Part 发送;其他块以 JSON 文本并入结果文本。Gemini functionResponse.parts 中的 inlineData 与 fileData 同样作为紧随该函数结果的 Part 发送。
GenerateAccessToken ["users/me"]
-> response ["<BEARER_TOKEN>"]
GetAppFolder []
-> response ["<FOLDER_ID>"]
GET clients6.google.com Drive v3 discovery(每个账户第一次上传前一次)
-> POST content.googleapis.com Drive multipart/related
part 1: {"name":"<NAME>","parents":["<FOLDER_ID>"]}
part 2: Content-Transfer-Encoding: base64
-> {"kind":"drive#file","id":"<FILE_ID>","name":"<NAME>","mimeType":"<MIME>"}
-> GenerateContent Part field 6 ["<FILE_ID>"]
已知长度的上传与官网对话面板的 gapi 上传相同:key 为页面的 x-goog-api-key;正文以固定分隔串 uhgzr7onafciig6fij3kisl4q 依次写 `
--<分隔串>、元数据部分头与
、元数据 JSON、
--<分隔串>、文件部分头与
、文件的 base64、
--<分隔串>--,Content-Type为multipart/related; boundary="<分隔串>"。上传与 discovery 都带 X-JavaScript-User-Agent: google-api-javascript-client/1.1.0、X-Requested-With: XMLHttpRequest、X-Goog-Encode-Response-If-Executable: base64与X-ClientDetails(账户指纹的 appVersion、platform与 User-Agent 按 encodeURIComponent 编码),经 CORS 预检发送;上传以 bearer token 授权、带Sec-Fetch-Site: cross-site与Sec-Fetch-Storage-Access: none,discovery 以 Cookie、SAPISID 签名与 X-Goog-AuthUser授权、带Sec-Fetch-Site: same-site`。
Drive token、上传和下载使用文件所属账户的固定出口。文件 ID 与账户绑定写入 runtime-state.json;生成请求可以组合不同账户的文件,其他账户的文件会临时复制到本次生成账户;失败尝试的副本随即回收,成功尝试的副本在请求结束后回收。
生成请求的内联附件优先上传到本次生成账户,正文使用 Drive file Part。上传的文件以请求给出的文件名命名,没有文件名时为 inline-media-<序号>,模型以这个名称引用附件。上传的文件以 inline-media 绑定写入该账户的 runtime-state.json,记录 MIME、内容的 SHA-256、请求给出的文件名与最近使用时间,不出现在公开文件接口中;同一账户之后的请求中 MIME、内容与文件名都相同的附件直接引用该文件,同一请求中相同的附件只上传一次;闲置 1 小时且没有进行中的请求引用的文件,在该账户下一次带内联附件的请求结束时删除,没有后续请求时由生成服务每 10 分钟一次的闲置资源回收删除。GenerateContent 返回 404 且请求引用了已上传的内联附件时,服务以 GET https://www.googleapis.com/drive/v3/files/<ID> 查询这些文件,解除已不存在的文件的绑定,在同一账户重新上传后重试一次。GenerateAccessToken 明确返回 401、Code 16 和 OAuth error: unauthorized_client 时,正文保留原始 inline data Part,账户继续参与普通生成调度;其他令牌错误保持失败语义。上传使用公开适配器输出的 MIME 和字节内容。图片、音频、视频、PDF 等附件的支持范围由所选模型决定。普通文本和 YouTube 外部媒体保持各自的 Part 编码。
POST /v1/files 的未知长度上传使用 Drive resumable upload 和 8 MiB 分块,GET /v1/files/{id} 从资源绑定读取文件名、大小、purpose 与创建时间;客户端取消会终止上传并释放账户租约。公开文件字段见“Files、Transcribe 与媒体”节。
gemini-3.5-transcribe 使用 Drive file Part 与 GenerateContent generation config field 32。转录配置子字段如下:
| protobuf field | 内容 |
|---|---|
| 5 | word timestamps,启用值为 1 |
| 6 | speaker labels,启用值为 1 |
| 7 | repeated custom vocabulary |
| 8 | repeated language codes |
| 9 | smart transcription,启用值为 2 |
转录元数据位于响应 Part field 23,子字段 1 为文本、2 为 speaker label、3 为 repeated timestamp span。每个 span 的 field 2 与 field 3 分别是开始和结束时间,时间消息使用 seconds 与 nanos。公开转录端点见“Files、Transcribe 与媒体”节。
三类媒体复用 GenerateContent:
| 路由 | generation config | 响应 |
|---|---|---|
| Nano image | modalities [2],image config [aspectRatio?, imageSize?] |
Part field 3 [mime, base64] |
| TTS | modalities [3],speech config |
Part field 3 音频 chunk |
| Lyria | modalities [3] |
Part field 3 音频 chunk |
单声音 speech config 为 [[[voiceName]]]。TTS 模型的请求没有设置声音时使用官网默认声音 Zephyr。多说话人 speech config 为 [null,null,[null,[[speaker,[[voiceName]]],...],mode?]],mode 1 为 VERBATIM、2 为 CONVERSATIONAL。文本 Part field 41 为 SpeechMetadata [speaker?, style?];能力码 85 的 TTS 模型要求多说话人请求的每个文本 Part 带 speaker,且台词不写 ## Transcript:。相邻且 MIME 相同的音频 Part 按到达顺序拼接。图片宽高比、图片分辨率与 TTS voice 必须来自当前模型能力选项。
GenerateImage 发给实时目录中带 predict 方法的模型,WAA proof 位于 field 3,binding 为提示词:
[
"models/<MODEL_ID>",
"<PROMPT>",
"<WAA_PROOF>",
[<SAMPLE_COUNT>, "<NEGATIVE_PROMPT>", "<ASPECT_RATIO>", "<IMAGE_SIZE>"]
]配置数组中未设置的项为 null,末尾的 null 省略。响应 field 1 为 repeated 图片:1 base64 数据、2 MIME、3 被安全策略拦下的原因(字符串,非空即拦下)。
模型目录 field 79 类型为 2 且不是后台任务的模型(gemini-omni-1.1-flash、gemini-omni-flash-preview)不接受 GenerateContent,四套公开生成接口对这类模型改用 CreateInteractionStream,账户选择、Worker 与 WAA 与 GenerateContent 相同,WAA proof 位于 field 5,binding 为发送的全部文本以空格连接:
[1, 1, null, <INTERACTION>, "<WAA_PROOF>", 1]| interaction 索引 | 内容 |
|---|---|
| 6 | system instruction |
| 17 | ["models/<MODEL_ID>", [null,null,null,null,null,<THINKING_LEVEL>,1,<MAX_OUTPUT_TOKENS>]],历史中没有模型输出时配置索引 24 为 [],设置视频任务时为 [<TASK>](1–5 依次为 text_to_video、image_to_video、reference_to_video、edit、extend) |
| 26 | [[<STEP>...]],用户 step 为 [[<CONTENT>...]],模型 step 为 [null,[<CONTENT>...]];文本 content 为 [[<TEXT>]],Drive 附件 content 为 [null×8,["<DRIVE_FILE_ID>"]] |
| 53 | 输出格式 [[[null,null,null,[null,null,null,<ASPECT>,[<SECONDS>],<RESOLUTION>]]]]:宽高比 1 为 16:9、2 为 9:16,分辨率 1–4 为 360p、720p、1080p、4k,省略时取模型 video_output_resolutions 的第一项;任务为 edit 时 interaction 只到索引 26 |
thinking level 取值 MINIMAL=1、LOW=2、MEDIUM=3、HIGH=4,由 reasoning_effort 或思考预算按模型支持的等级换算,默认使用目录默认等级。Interaction 请求接受 user、assistant 与 tool 消息,tool 消息按 user 处理,相邻同角色消息合并为一个 step,历史函数调用、函数结果与代码执行改写为 Gemini API JSON 文本,assistant 消息中的附件移到下一个 user step;内联附件先上传到所选账户的 Drive,再以 file ID 引用,文件 ID 不参与 binding。音频附件由上游以 code 3 Audio input modality is not enabled for this model 拒绝,映射为 HTTP 400;函数声明与 Google 工具不发送,stop sequences 与 GenerateContent 相同在本地匹配,temperature、topP、topK 与 seed 不发送。
视频设置来自 Interactions response_format 的 {"type":"video","aspect_ratio","duration","resolution"} 与 generation_config.video_config.task,或 Gemini API generationConfig.responseFormat 的 video.aspectRatio、video.duration、video.resolution 与扩展字段 generationConfig.videoConfig.task;Interactions response_modalities 的 video 与 Gemini API generationConfig.responseModalities 的 VIDEO 等同于不带设置的视频输出格式;duration 取 "4s" 或秒数并四舍五入为整秒,宽高比与分辨率换成最接近的上游取值,无法解析的取值与未知任务返回 400。
响应为 [[<EVENT>...], <STATUS>?]。事件索引 10 的 content delta 中 field 1 为正文、field 2 至 5 为图片、音频、文档与视频 [<MIME 枚举>,"<BASE64>"]、field 6 为思考摘要,分别映射为 text、媒体与 reasoning 事件;索引 19 的最终 interaction 状态 3 产生 usage(输入、输出、思考、总 token 位于 usage 索引 0、4、8、9)与 stop 终态,状态 4、5 返回错误。事件列表后的 google.rpc 状态按 code 映射 HTTP 状态,额度 code 8 为 429;首个正文事件之前的错误进入换号与冷却,之后的错误以流内 error 结束。
媒体 MIME 枚举与官网前端相同,枚举为 null 或不在表中时取该类的默认 MIME:
| 字段 | 枚举 | 默认 |
|---|---|---|
| 图片 field 2 | 1 png、2 jpeg、3 webp、4 heic、5 heif、7 gif、8 bmp、9 tiff | image/jpeg |
| 音频 field 3 | 1 wav、2 mp3、3 aiff、4 aac、5 ogg、6 flac、7 mpeg、8 m4a、9 l16、10 s16le、11 opus、12 alaw、13 mulaw | audio/wav |
| 文档 field 4 | 1 pdf | application/pdf |
| 视频 field 5 | 1 mp4、2 mpeg、3 mpg、4 mov、5 avi、6 x-flv、7 webm、8 wmv、9 3gpp | video/mp4 |
模型目录 field 79 为后台任务的模型(deep-research-preview-04-2026、deep-research-max-preview-04-2026、antigravity-preview-09-2026)经两个 RPC 生成:CreateInteraction 创建任务,GetInteractionStream 按 interaction ID 读取任务的增量与终态。两个 RPC 的 WAA proof 都位于 field 5,CreateInteraction 的 binding 为发送的全部文本以空格连接,GetInteractionStream 的 binding 为 interaction ID:
[null, 1, 1, <INTERACTION>, "<WAA_PROOF>", 1]
["<INTERACTION_ID>", 1, null, null, "<WAA_PROOF>", 1, "models/<AGENT>"]| interaction 索引 | 内容 |
|---|---|
| 6 | system instruction |
| 7 | 工具列表,见下文 |
| 16 | 续接的上一轮 interaction ID |
| 18 | agent 目标,见下文 |
| 22 | Antigravity 的远程环境 [null,null,1] |
| 26 | 与 Omni Interaction 相同的 step 列表,见下文 |
agent 目标的 field 1 为 agent 名称。Deep Research 为 ["<AGENT>", null, [<思考摘要>, <可视化>, <协作规划>]]:思考摘要 1 为 auto、2 为 none,可视化 2 为 auto、1 为 off,协作规划开启时为 true、关闭时省略,默认 [1,2]。field 79 InteractionConfig 的 field 6 给出默认模型的 agent(Antigravity)为 ["<AGENT>"],指定模型或 token 上限时 field 12 为 ["<MODEL>",null,null,null,null,null,<MAX_TOTAL_TOKENS>]。公开 Interactions 的 agent_config 按官方取值写入这些位置。
工具列表依次为代码执行 [null,[]]、函数声明 [["<NAME>","<DESCRIPTION>",<PARAMETERS>]](参数为 google.protobuf.Value)、Google 搜索 [null,null,null,null,null,[]] 与 URL 上下文 [null,null,[]],Interactions 请求带 tools 时只用列出的工具,空列表时省略索引 7;其他请求与不带 tools 的 Interactions 请求在模型目录 field 82 默认开启的代码执行(9)、Google 搜索(12)与 URL 上下文(13)之上加入请求的工具,Deep Research 默认为搜索与 URL 上下文,Antigravity 另有代码执行;没有任何工具时省略索引 7。MCP 服务器、File Search、Computer Use 与其他 Google 工具在发送前返回 400 INVALID_ARGUMENT。
step 列表只包含用户内容:历史中的模型轮、服务端工具步骤、代码执行与函数调用不发送,其中的附件也不上传,相邻的用户内容合并为一个 step。公开 Interactions 以 previous_interaction_id 续接同一 agent 的后台任务时,索引 16 为该任务的 interaction ID,step 列表只有本次输入,请求固定使用创建该任务的账户。
CreateInteraction 响应索引 0 为 interaction ID。GetInteractionStream 的事件格式与 Omni Interaction 相同;content delta 另有 field 2 图片 [1,"<BASE64 PNG>"] 与 field 10 引用 [[[<START>,<END>,null,["<URL>"]]...]],起止为正文中引用标记的字符位置,分别映射为 image/png 媒体与 citation 事件。最终 interaction 不含 usage,状态 3 产生 stop 终态。调用方在终态前断开时,服务以 ["interactions/<INTERACTION_ID>"] 发送 CancelInteraction 停止上游任务;取消在后台以同一账户发送,调用方释放账户租约后取得请求槽位,期限 1 分钟。
官网 Build 应用经宿主页调用 MakerSuite 代理 RPC 访问 Gemini API,免费账户在两个通道上计入同一模型的同一份每日请求次数。UPSTREAM_CHANNELS 启用 build 时,生成请求在 Build 通道上编码为 Gemini API JSON:
["/v1beta/models/<MODEL_ID>:streamGenerateContent", "<GEMINI_API_JSON>", "<WAA_PROOF>"]
["/v1beta/models/<MODEL_ID>:generateContent", "<GEMINI_API_JSON>", "<WAA_PROOF>", "POST"]前者发往 ProxyStreamedCall,后者发往 ProxyUnaryCall。WAA proof 位于 field 3,binding 为路径与请求体以空格连接后的 SHA-256。两个 RPC 的选择与权益头、模型目录、资格、调度与冷却、请求字段映射、响应解码、错误映射与未接入范围见 Build 通道。Playground 目录没有的 embedding、Live 与实时音乐模型只经 Build:embedding 经 ProxyUnaryCall 调用 :batchEmbedContents,Part 分辨率不同的计数与 Playground 目录没有的模型的计数经 ProxyUnaryCall 调用 :countTokens,Live 与实时音乐经宿主页 WebChannel v1/proxy:proxyBidiStreamedCall 转发 Gemini Live JSON,每条消息为 [路径, JSON, WAA proof]。
GET /v1/live 与 GET /v1/robotics/stream 升级为 WebSocket,首个客户端帧为 setup,公开帧与事件见“Live 与 Robotics 公开帧”节。两个入口都使用客户端提供的模型,并由实时模型目录的 bidiGenerateContent 方法选择账户;Build 目录以 bidiGenerateMusic 提供的模型(如 lyria-realtime-exp)为实时音乐会话。Playground 目录没有的 Live 与实时音乐模型经 Build 通道,帧与事件相同,wire 见 Build 通道。上游握手、backchannel 就绪和 setup complete 共用 INIT_TIMEOUT,随后依次发送 session_opened 与 setup_complete。
上游 WebChannel 由握手、前向 POST、长轮询 backchannel 与 terminate 组成。握手 query 使用 VER=8、随机 RID、CVER=22、X-HTTP-Session-Id=gsessionid 与 count=0;响应 header 给出 gsessionid,首个控制 envelope 为:
[[0,["c","<SID>","",8]]]后续前向请求的 query 字段为 VER、gsessionid、SID、RID、AID、zx、t;form 字段依次为 count=<N>、ofs=<OFFSET>、req0___data__ 至 req<N-1>___data__。客户端消息按到达顺序排队,同一时间只有一个前向 POST,在途期间到达的消息合并进下一个 POST,每个 POST 最多 25 条,与官网页面一致。audio 与 image 帧入队即返回,text、tool_response、media_end 等待自身所在 POST 的 ACK,因此 media_end 返回时此前的媒体帧均已送达;前向 POST 失败后,队列内与后续发送均返回该错误。成功响应是三个整数的 ACK 数组,三个槽只校验整数形状,第二槽不绑定本地 RID、AID 或 ofs。HTTP 200 且 ACK 合法后提交 RID+1 与 ofs+N;失败、取消或 ACK 无效时保持原值。
backchannel 使用 RID=rpc、当前 SID、gsessionid 与 AID。每个网络帧为十进制长度、LF 和对应 JSON 文本,长度按 UTF-16 码元计数:
<DECIMAL_UTF16_LENGTH><LF>
<JSON_TEXT>
JSON 根值包含 repeated [serverAID,payload] envelope。payload 解码成功并按顺序发布后,将 AID 提交为 max(currentAID,serverAID)。首次 backchannel 建立后的临时读取失败保留 SID、gsessionid 与已提交 AID 并重新连接;首次建立失败、协议终态、显式 close 或不可恢复错误进入关闭链。会话状态为 new -> handshaking -> ready -> reconnecting -> ready,关闭路径依次进入 closing -> closed。
tool_call 事件携带单个函数调用;一条上游消息包含多个调用时按顺序发送多条事件。tool_call_cancellation.tool_call_ids 携带被取消的调用 ID。新的 session_resumption.session_token 原子替换上一枚 token;后续 setup 携带该 token 时绑定原账户恢复。
Live 纯文本与实时音乐使用模型 scope,Live 音频/图像和 Robotics 使用 bidi-media:<modelID> scope,经 Build 通道时 scope 前加 build:。上游 Code 7 通过 error 事件返回并结束当前连接,Code 13 以 HTTP 500 的 error 事件结束连接。
上游 Bidi 客户端 wire 使用六槽或七槽稀疏数组。setup 位于外层 field 7:
| setup JSON 索引 | protobuf field | 内容 |
|---|---|---|
| 0 | 1 | models/<MODEL_ID> |
| 1 | 2 | generation configuration |
| 2 | 3 | tools |
| 6 | 7 | [sessionToken];无 token 时 Live 对话与 Robotics 为 [],实时翻译与转录省略 |
| 7 | 8 | [104857,[52428]] buffering 参数;实时翻译与转录省略 |
| 9 | 10 | 输入音频转录参数;空数组,实时转录的语言写在子索引 7 |
| 10 | 11 | 固定空数组 |
| 15 | 16 | timezone [null,null,null,null,[zone]] |
Live 对话与 Robotics 的 configuration 使用 18 槽数组:
| JSON 索引 | 内容 |
|---|---|
| 14 | 输出 modalities;TEXT=[1]、AUDIO=[3] |
| 15 | Live voice [[["Zephyr"]]] |
| 16 | thinking [1,null,null,level];Live Minimal=4、Robotics High=3 |
| 17 | MediaResolution 固定值 2 |
实时翻译模型不接受 MediaResolution,configuration 使用 31 槽:索引 13 为 0、14 为 [3]、30 为 TranslationConfig [echoTargetLanguage 0/1, targetLanguageCode]。实时转录模型只接受 TEXT 输出,configuration 为 [null×14,[1]]。两者均不带 voice 与 thinking。上游在 serverContent 索引 5、6 返回输入与翻译文本,实时转录在索引 10 返回当前累计的临时输入转写,映射为 interim_input_transcription,音频结束后在索引 5 返回最终输入转写。
最小 setup 外层形状:
[
null, null, null, null, null, null,
[
"models/<MODEL_ID>",
[null, null, null, null, null, null, null, null, null, null, null, null, null, null, [3], [[["Zephyr"]]], [1, null, null, 4], 2],
null,
null, null, null,
[],
[104857, [52428]],
null,
[],
[],
null, null, null, null,
[null, null, null, null, ["Asia/Taipei"]]
]
]后续客户端 wire:
| 公开帧 | 外层位置 | 子消息 |
|---|---|---|
text |
index 2 / field 3 | realtime input index 4 保存文本 |
audio |
index 2 / field 3 | realtime input index 1 保存 [mime,base64] |
image |
index 2 / field 3 | realtime input index 3 保存 [mime,base64] |
media_end |
index 2 / field 3 | realtime input index 2 为 1 |
tool_response |
index 3 / field 4 | 子消息 index 1 保存 repeated [name,Struct,id,willContinue?],will_continue 为真时 index 3 为 1 |
setup 与每个后续客户端 wire 都在发送前把 fresh WAA proof 写入外层 index 5 / field 6。snapshot binding 输入:
| wire | binding prompt |
|---|---|
| setup | models/<MODEL_ID>,随后按声明顺序追加每个 name + " " + description,各段以单个空格连接 |
| text、audio、image、media end | 空字符串 |
| tool response | 第一条 function response 的 call ID |
服务端业务 message 索引:
| JSON 索引 | 内容 |
|---|---|
| 1 | setup complete |
| 2 | server content |
| 3 | tool calls |
| 4 | tool cancellation |
| 5 | usage raw |
| 6 | go away raw |
| 7 | session resumption |
server content 的 index 0/1/2/4/5/6 分别为 model content、turn complete、interrupted、generation complete、input transcription、output transcription;model content 的 index 0 是 repeated Part。transcription 子索引 0/1/2/3 分别为 text、finished、duration milliseconds、language code。tool calls 位于 message index 3 的子索引 1,每项为 [name,Struct,id];tool cancellation 位于 message index 4 的子索引 0,值为 repeated call ID。session resumption 子索引 0/1 分别为 token 与 resumable。对象状态错误形状为 {"__sm__":{"status":[[[code,message]]]}};字符串 payload "noop"、"close"、"stop" 分别表示空操作、正常关闭与错误停止。
| 协议 | 端点 |
|---|---|
| OpenAI Chat | GET /v1/models、GET /v1/models/{id}、POST /v1/chat/completions |
| OpenAI Responses | POST /v1/responses、POST /v1/responses/input_tokens、POST /v1/responses/compact、GET /v1/responses/{id}、DELETE /v1/responses/{id}、GET /v1/responses/{id}/input_items、POST /v1/responses/{id}/cancel |
| OpenAI Embeddings | POST /v1/embeddings |
| OpenAI 媒体 | POST /v1/images/generations、POST /v1/images/edits、POST /v1/audio/speech、POST /v1/videos、GET /v1/videos、GET /v1/videos/{id}、DELETE /v1/videos/{id}、GET /v1/videos/{id}/content |
| Anthropic | POST /v1/messages、POST /v1/messages/count_tokens |
| Gemini | GET /v1beta/models、GET /v1beta/models/{model}、POST /v1beta/models/{model}:generateContent、:streamGenerateContent、:countTokens、:embedContent、:batchEmbedContents、:predict、:predictLongRunning、GET /v1beta/operations/{id}、GET /v1beta/models/{model}/operations/{id} |
各协议输出对象的字段顺序与官方输出相同:Gemini GenerateContent、模型、计数、文件与错误对象按 Gemini API 官方响应与 proto 字段号的顺序,Chat、Responses、Anthropic 与 OpenAI 其余资源按官方文档响应示例的顺序,Interactions 为 type 在前、其余按字母序;顺序表由官方响应与文档生成,内嵌于 internal/api/field_order.json,表中没有的字段排在已知字段之后并按字母序。函数参数、元数据与 JSON Schema 等调用方数据保持原有顺序。
扩展端点:
| 协议 | 端点 |
|---|---|
| OpenAI 与 Anthropic 文件 | POST /v1/files、GET /v1/files、GET /v1/files/{id}、GET /v1/files/{id}/content、DELETE /v1/files/{id} |
| OpenAI 转录与翻译 | POST /v1/audio/transcriptions、POST /v1/audio/translations |
| 实时 WebSocket | GET /v1/live、GET /v1/robotics/stream |
| Gemini Interactions | POST /v1beta/interactions、GET /v1beta/interactions/{id}、DELETE /v1beta/interactions/{id}、POST /v1beta/interactions/{id}/cancel,/v1 前缀相同 |
| Gemini 文件 | POST /upload/v1beta/files、GET /v1beta/files、GET /v1beta/files/{id}、DELETE /v1beta/files/{id} |
动态路由的注册形状为 GET /v1/models/{model...}、GET /v1beta/models/{model...}、GET /v1/responses/{response}、DELETE /v1/responses/{response}、GET /v1/responses/{response}/input_items、POST /v1/responses/{response}/cancel、GET /v1/files/{file}、GET /v1/files/{file}/content、DELETE /v1/files/{file}、GET /v1/videos/{video}、DELETE /v1/videos/{video}、GET /v1/videos/{video}/content、POST /v1beta/models/{action}、GET /v1beta/operations/{operation}、GET/DELETE /v1/interactions/{id}、GET/DELETE /v1beta/interactions/{id}、POST /v1/interactions/{id}/cancel、POST /v1beta/interactions/{id}/cancel 与 GET/DELETE /v1beta/files/{file};端点表中的 {id} 表示对应资源标识。
公开 /v1 与 /v1beta 接受 Authorization: Bearer、X-API-Key、X-Goog-API-Key 或 ?key=,任一来源与配置的 key 相同即通过;配置为空时关闭本地 API key 校验,此时 Origin 为 null 或非 localhost、非回环地址的 http/https 页面请求按 API key 错误拒绝(OpenAI 与 Anthropic 路由 401,Gemini 路由与官方相同:没有 key 为 403,带 key 为 400),不带 Origin 的客户端与其他 scheme 不受限制。/v1*、/upload/ 与 /health 响应允许任意 origin,并以 Access-Control-Expose-Headers: * 暴露响应头;OPTIONS 预检不经过 API key 校验,允许 GET/POST/PUT/DELETE/OPTIONS,Access-Control-Allow-Headers 回显请求的 Access-Control-Request-Headers。/v1* 请求体上限约为 684 MiB,可容纳 Base64 编码的 512 MiB 文件。/upload/v1beta/files 使用相同的认证与请求体上限;可续传上传的分块请求发往 start 响应 X-Goog-Upload-URL 给出的地址,凭其中的 upload_id 鉴权,不需要 API key。
/api 控制面在 ADMIN_AUTH_ENABLED=false 时要求来源地址为 loopback 且 Host 为 localhost 或回环地址;开启登录后,通过管理员账号和密码签发的 Cookie 会话访问。管理请求执行 same-origin 校验并携带 Cache-Control: no-store。全部响应携带 X-Frame-Options: DENY、Content-Security-Policy: frame-ancestors 'none'、X-Content-Type-Options: nosniff 与 Referrer-Policy: no-referrer。GET /health 返回 {"status":"ok"}。
POST /api/auth/login 接受 {"username":"<ADMIN_USERNAME>","password":"<ADMIN_PASSWORD>","remember":false},成功返回 {"enabled":true,"authenticated":true,"username":"<ADMIN_USERNAME>"}:
- 会话 Cookie 为
aistudio_admin,Path 为/api,使用 HttpOnly、SameSite=Strict;HTTPS 或代理设置X-Forwarded-Proto: https时附带 Secure - 有效期 12 小时;
remember为true时有效期 30 天,会话写入runtime/admin-sessions.json,管理进程重启后保留,管理员账号或密码变化后失效 - 登录失败返回 401,同一来源一分钟内连续失败 5 次后返回 429 与
Retry-After: 60
GET /api/auth/session 返回相同的状态结构,未登录时账号为空。POST /api/auth/logout 返回 204,撤销当前会话并取消关联管理请求。
| 控制能力 | 端点 |
|---|---|
| 管理登录 | GET /api/auth/session、POST /api/auth/login、POST /api/auth/logout |
| 状态与模型 | GET /api/status、GET /api/models |
| 生成服务 | POST /api/control/start、POST /api/control/stop |
| 账户 | GET /api/accounts、POST /api/accounts、GET/POST /api/accounts/import/chrome、GET /api/accounts/import/browsers、POST /api/accounts/import/cookies/discover、POST /api/accounts/import/cookies、PUT /api/accounts/{id}、DELETE /api/accounts/{id} |
| 账户任务 | GET /api/accounts/tasks、DELETE /api/accounts/tasks/{id} |
| 账户认证与刷新 | POST /api/accounts/{id}/login、POST /api/accounts/{id}/refresh、GET /api/login-view/{view}(WebSocket) |
| 远程配对 | GET /api/pairing、POST /api/pairing、POST /api/pairing/accounts、PUT /api/pairing/accounts/{account}/cookies |
| 配置 | GET /api/config、PUT /api/config、GET /api/first-event-latency |
| 冷却与请求 | GET /api/cooldowns、GET /api/requests、POST /api/requests/{id}/cancel |
| 用量与正文 | GET /api/usage、GET /api/usage/records、GET /api/usage/records.csv、GET /api/requests/{id}/body |
| 日志与事件 | DELETE /api/logs、GET /api/events |
管理 API 使用 DTO(data transfer object)表示请求、响应和事件对象。端点结果:
| 端点 | 成功状态 | body |
|---|---|---|
GET /api/status |
200 | AdminStatus |
GET /api/models |
200 | {"models":[Model,...]} |
GET /api/accounts |
200 | {"accounts":[AdminAccount,...]} |
POST /api/accounts |
202 | {"task":AccountTask} |
GET /api/accounts/import/chrome |
200 | {"profiles":[ChromeImportProfile,...]} |
POST /api/accounts/import/chrome |
202 | {"task":AccountTask} |
GET /api/accounts/import/browsers |
200 | {"browsers":[CookieBrowser,...]} |
POST /api/accounts/import/cookies/discover |
200 | {"accounts":[CookieBrowser,...]} |
POST /api/accounts/import/cookies |
202 | {"task":AccountTask} |
GET /api/accounts/tasks |
200 | {"tasks":[AccountTask,...]} |
DELETE /api/accounts/tasks/{id} |
204 | 空 body |
GET /api/pairing |
200 | PairingToken |
POST /api/pairing |
201 | PairingToken |
POST /api/pairing/accounts |
201 | {"account":AdminAccount,"renewal_token":"<续签凭据>"} |
PUT /api/pairing/accounts/{account}/cookies |
200 | {"account":AdminAccount} |
PUT /api/accounts/{id} |
200 | {"account":AdminAccount} |
POST /api/accounts/{id}/login |
202 | {"task":AccountTask} |
POST /api/accounts/{id}/refresh |
200 | AccountRefresh |
DELETE /api/accounts/{id} |
204 | 空 body |
POST /api/control/start、stop |
200 | AdminStatus |
GET /api/config、PUT /api/config |
200 | RuntimeConfig |
GET /api/first-event-latency |
200 | {"latencies":[FirstEventLatency,...]} |
GET /api/cooldowns |
200 | {"cooldowns":[AdminCooldown,...]} |
GET /api/requests |
200 | {"requests":[AdminRequest,...]} |
POST /api/requests/{id}/cancel |
204 | 空 body |
GET /api/usage |
200 | UsageReport |
GET /api/usage/records |
200 | UsageRecordPage |
GET /api/usage/records.csv |
200 | 带 UTF-8 BOM 的 CSV 附件 |
GET /api/requests/{id}/body |
200 | RequestBody |
DELETE /api/logs |
204 | 空 body |
GET /api/events |
200 SSE | {"type":"<TYPE>","data":<DTO>} |
POST /api/pairing/accounts的令牌无效或过期时返回 401pairing_token_invalid,账户已存在时返回 409account_existsPUT /api/pairing/accounts/{account}/cookies的续签凭据与该账户不符时返回 401pairing_renewal_invalid,账户不存在时返回 404account_not_found,Cookie 无法生成 SAPISID 授权时返回 400invalid_account- 一份 Cookie 可包含同一浏览器中多个 Google 账户的会话,第 N 个会话对应官网
/u/N/与请求头X-Goog-AuthUser: N。POST /api/accounts/import/cookies/discover从 u/0 起依次打开各会话的对话页,列出每个会话登录的账户;GET /api/accounts/import/browsers为每个浏览器的每个会话各列一项。POST /api/accounts/import/cookies中每项的auth_user选择导入的会话,省略时为 0;账户的auth_user写入account.json,运行时以/u/N/页面与X-Goog-AuthUser: N访问官网,浏览器重新登录后为 0 - 添加、导入与重新登录账户在账户任务中运行:请求解析 body 后返回 202 与任务,任务不随请求或管理页面关闭而结束;任务中的账户依次处理,单个账户失败时在该项记下错误码与原因后继续下一个,Cookie 无法解析或缺少登录 Cookie 为
invalid_cookies,调试地址连接或读取失败为cdp_unavailable,账户已存在为account_exists;有账户失败时任务以failed结束,否则为done。结束的任务保留到DELETE /api/accounts/tasks/{id}关闭,对进行中的任务调用它会取消任务,任务不存在时返回 404task_not_found;任务列表变化时GET /api/events推送account_tasks事件,连接建立时先推送当前列表 GET /api/pairing返回仍在有效期内的配对令牌,没有时返回 404pairing_token_missing;POST /api/pairing签发新令牌,此前的令牌随之失效GET /api/requests/{id}/body在没有保存正文时返回 404request_body_not_foundPOST /api/accounts与POST /api/accounts/{id}/login的 body 可带view,即管理页面为本次登录生成的登录窗口 ID;POST /api/accounts/{id}/login也接受空 body。服务器没有图形界面,或请求来自非回环地址、带Forwarded或X-Forwarded-For时,登录画面经同一 ID 的GET /api/login-view/{view}传递,任务的view为该 ID;登录窗口断开后以同一 ID 重新连接,继续显示当前画面GET /api/login-view/{view}推送{"type":"status","status":"starting|waiting|saving"}、{"type":"dialog","dialog":{"kind","message","value"}|null},以及{"type":"frame","context","url","title","width","height","scale"}后紧跟一条 JPEG 二进制消息;客户端发送{"type":"pointer","action":"move|down|up","x","y","button","context"}、{"type":"wheel","x","y","dx","dy","context"}、{"type":"key","action":"down|up","key","context"}、{"type":"text","text","context"}与{"type":"dialog","accept","text"},坐标与宽高为页面 CSS 像素,key为KeyboardEvent.key
管理 DTO 字段:
| DTO | 字段 |
|---|---|
AdminStatus |
state、running、ready、version、active_requests、accounts、camoufox |
AdminAccountCounts |
total、ready、busy、cooldown、auth_required |
AdminCamoufox |
ready、可选 download(received、total) |
AdminAccount |
id、label、enabled、state、proxy、locale、timezone、models、benefit_tier、message、可选 pairing_renewed_at |
AccountCreateInput |
proxy、locale、timezone |
AccountInput |
label、enabled、proxy、locale、timezone |
ChromeImportProfile |
id、profile、display_name、email、locale |
AccountRefresh |
account、previous_tier、tier、previous_models、models |
ChromeImportInput |
accounts(每项 id 与 email)、proxy、locale、timezone |
CookieImportInput |
cookies、proxy(识别 Cookie 中的账户时提交) |
CookieAccountsInput |
items(每项 email、cookies 或 cdp、可选 auth_user:Cookie 中的会话序号 0–9,默认 0)、proxy、locale、timezone;cdp 导入时 locale、timezone 为空则取该浏览器页面的语言与时区 |
AccountTask |
id、kind(login、relogin、chrome、cookies、browser)、可选 view、state(running、done、failed)、items、started_at |
AccountTaskItem |
label(账户邮箱,浏览器登录完成前为空)、state(pending、running、done、failed)、可选 code、error |
CookieBrowser |
address、browser、email、auth_user、locale、timezone、imported、signed_out、error |
PairingToken |
token、expires_at |
AccountStateInput |
label、locale、timezone、storage_state、可选 auth_user(默认 0)、可选 fingerprint |
AdminCooldown |
account_id、account_label、model_id、until、可选 reason |
AdminRequest |
id、model、account_id、account_label、state、started_at |
AdminLog |
time、level、source、message、event;请求事件携带 request,包含 id、state、HTTP status、model、duration_ms、tool_calls、usage 与诊断字段,字段口径见 logging.md |
AdminEvent |
type、data |
UsageLatency |
avg_ms、p50_ms、p95_ms、p99_ms |
UsageStats |
requests、succeeded、failed、canceled、rate_limited、input_tokens、cached_tokens、reasoning_tokens、reply_tokens、total_tokens、duration、first_event、queue_avg_ms、可选 last_at |
UsageReport |
from、to、bucket_seconds、generated_at、可选 latest_at、totals、previous、recent、cost、previous_cost、unpriced_models、buckets、stack_by、series、groups、pairs、options |
UsageRecord |
id、time、protocol、path、model、account、channel、status、state、duration_ms、first_event_ms、queue_ms、input_tokens、cached_tokens、reasoning_tokens、reply_tokens、total_tokens、tool_calls、error、attempts、has_body |
UsageRecordPage |
items、可选 next_cursor |
RequestAttempt |
account、channel、error、duration_ms、可选 hedge、superseded |
FirstEventLatency |
model、channel、samples、p95_ms |
RequestBody |
id、time、request、request_size、response、response_size |
AdminStatus.state 为 STOPPED、LAUNCHING 或 RUNNING;running 只在 RUNNING 为 true;ready 要求 RUNNING 且至少一个账户处于 ready 或 busy;version 来自构建信息;active_requests 是当前进程请求注册表数量;camoufox.ready 表示本机已有所需版本的 Camoufox,下载进行时 camoufox.download 给出已收与总字节,续传时已收字节包含已下载部分,总字节未知时为 0。AdminAccount.message 保存当前状态原因,models 是该账户实时目录 ID。until 与 started_at 使用 RFC 3339 JSON time。
GET /api/usage 的参数:
| 参数 | 含义 |
|---|---|
from、to |
必填,RFC 3339 时间 |
tz |
IANA 时区,默认 UTC |
bucket |
分桶秒数 60、300、900、3600、86400,或 auto |
model、account、channel、protocol、state |
维度筛选,逗号分隔多个取值 |
stack |
series 的堆叠维度,默认 model |
- 统计区间为
[from, to),长度不超过 93 天,分桶数不超过 1500 tz决定按天分桶的自然日与分钟、小时分桶的对齐- 同一维度的多个取值为或,不同维度之间为且
stack取上述五个筛选维度之一
auto 按范围长度选择粒度:2 小时以内 1 分钟,12 小时以内 5 分钟,8 天以内 1 小时,更长按天。buckets 从包含 from 的对齐分桶开始,空分桶补零;previous 是紧邻 from 之前的等长周期;recent 统计最近 5 分钟。cost、previous_cost 与每个分桶的 cost 是按 Gemini API 与 Vertex AI 公布的当前文本单价估算的美元费用:未命中缓存的输入 token × 输入单价 + 缓存命中 token × 缓存单价 +(推理 + 回复)token × 输出单价,按提示长度分档的模型按每个请求的输入 token 选档,单价表只含文本生成模型,图片、音频、视频、语音与嵌入模型计为 0,unpriced_models 按名称列出范围内有 token 但没有单价的模型。succeeded 包含 completed、tool_calls、limited 与 blocked,rate_limited 是 HTTP 429 的失败数;duration 与 first_event 只统计成功请求,分位数相对误差约 0.5%。groups 按 model、account、channel、protocol、state 与 HTTP 状态码 status 列出全部取值,pairs 是账户与模型的组合,series 取请求数前 8 的取值,其余合并为 other: true 的一组。options 列出范围内出现过的维度取值,不受筛选影响。latest_at 是账本中最新一条记录的完成时间。
GET /api/usage/records 与 records.csv 接受同样的 from、to 与维度筛选,另有 status(HTTP 状态码)与 q(匹配请求 ID 或错误文本的子串)。记录按完成时间与 ID 倒序;limit 为 1 到 200,默认 50;next_cursor 原样传回 cursor 读取更早的一页。attempts 列出本次请求在最终结果之前未成功的上游尝试(account、channel、error、duration_ms)。CSV 导出范围内全部符合条件的记录,以 =、+、-、@、制表符或回车开头的文本加单引号前缀。
Chrome 导入列表按 Preferences.account_info 中的 Gaia ID 与邮箱逐个列出账号,同一 Profile 可以包含多个账号,同一邮箱只列出一次。ChromeImportProfile.id 为 <Profile>/<Gaia ID>;导入读取 token_service 中 service 为 AccountId-<Gaia ID> 的凭据。管理页列表默认不勾选,并提供全选。CLI 的 --profile 导入该 Profile 下的全部账号,交互编号对应单个账号。
POST /api/pairing 需要管理会话,签发 10 分钟内有效的配对令牌;再次签发使上一令牌失效。服务只在内存中保存令牌的摘要,管理进程重启后令牌失效。POST /api/pairing/accounts 不经过管理会话、loopback 与 same-origin 检查,凭 Authorization: Bearer <token> 导入一个账户,令牌有效期内可多次调用;body 上限 1 MiB。AccountStateInput.storage_state 必须能生成 SAPISID 授权,邮箱取认证扩展中的来源邮箱,没有时取 label;fingerprint 是隔离登录生成的 camoufox-fingerprint.json 内容。配对导入的账户使用服务端默认代理。上传成功的响应带该账户专属的 renewal_token,服务只在账户目录的 pairing-renewal.json 保存它的 SHA-256。PUT /api/pairing/accounts/{account}/cookies 同样不经过管理会话,凭 Authorization: Bearer <renewal_token> 以 body {"cookies":[StateCookie,...]}(上限 1 MiB)替换该账户认证状态中的 Cookie,认证扩展保持不变;处理时等该账户进行中的请求结束,重置该账户的 WAA Worker,账户回到 ready,pairing-renewal.json 记下续签时间,AdminAccount.pairing_renewed_at 为该时间(RFC 3339),没有经配对续签的账户不带这个字段。续签凭据只能更新签发它的账户,账户删除时随账户目录删除。
AccountCreateInput启动隔离 Camoufox 登录,邮箱由 AI Studio 页面读取ChromeImportInput.account_ids可一次选择多个账号CookieImportInput.cookies接受 Cookie 扩展导出的 storage state 或 Cookie 数组 JSON、Netscape cookies.txt 和一行 Cookie 请求头,只保留 google.com 及其子域的 Cookie,label为账户邮箱;cdp非空时改从该远程调试地址读取浏览器的全部未分区 CookieAccountInput.label必须与不可变的 Google 邮箱 ID 一致,locale与timezone必须非空;proxy使用 HTTP、HTTPS 或 SOCKS5 origin,可带user:password@,不含 path、query 或 fragment
新增、导入、登录和验证成功后立即刷新该账户模型目录,并发布最新账户与模型事件。
PUT /api/accounts/{id} 的提交顺序固定为:校验不可变邮箱 ID,取得账户独占租约,创建未发布的新固定出口,关闭当前 Worker 并把新 Worker 配置标记为 pending(尚未发布),在模型目录写锁内原子写入 account.json 并更新账户池,随后发布 Worker 配置、替换固定出口、释放租约并重建模型缓存。account.json 写入是唯一持久提交点。提交前的出口创建、Worker 关闭或写入错误会丢弃这份待发布配置并保持旧配置;已经关闭的 Worker 由后续请求按旧配置重建。持久写入后,新配置、Worker 配置与固定出口共同成为已提交状态。租约释放错误保留该提交状态并返回原始 unlock 错误;释放成功后记录完成日志并同步模型缓存。
RuntimeConfig 字段。response-only 表示字段由服务器填充,客户端提交的值不参与保存:
| 字段 | 读写与生效时机 |
|---|---|
auth_states、proxy、init_timeout、request_timeout |
保存值;下一次启动生成服务时使用 |
warm_worker_limit、max_active_workers、warm_startup_concurrency、per_account_concurrency |
保存值;下一次启动生成服务时使用 |
build_native_nonstream |
保存值;下一次启动生成服务时决定非流式请求是否优先选择 Build |
nonstream_keepalive、fake_stream |
保存值;下一次启动生成服务时决定非流式请求是否保活、流式请求是否按非流式生成 |
youtube_links |
保存值;下一次启动生成服务时决定是否把用户消息文本中的 YouTube 链接作为视频外部媒体发送 |
first_event_hedge |
保存值;off、auto 或正整数秒,下一次启动生成服务时决定原请求等待首字多久后发起备用请求 |
auto_start |
保存值;下一管理进程就绪后是否自动启动生成服务 |
request_body_log |
保存值;保存后立即决定是否保存请求与响应正文 |
admin_auth_enabled、admin_username |
保存值;下一管理进程使用 |
admin_password |
只写;省略时保留现值,下一管理进程使用 |
admin_password_set |
response-only;是否已保存管理密码 |
listen_addr、proxy_api_key |
保存值;下一管理进程使用 |
active_listen_addr、active_proxy_api_key |
response-only;当前管理进程固定值 |
management_restart_required |
response-only;保存的监听地址、API key 或管理凭据与当前管理进程不同 |
service_restart_required |
response-only;保存的生成服务配置与当前生成服务实例不同 |
PUT /api/config 原子保存配置。监听地址、API key 和管理凭据在管理进程重启后生效;Worker 容量保存后立即作用于当前生成服务;账户路径、代理、timeout、临时对话与上游通道选项在 Stop/Start 创建的新生成服务实例中生效。启动时读取最新配置;配置加载、校验、实例创建失败或启用前取消时保留原实例,切换到新实例后由它完成启动或进入 STOPPED。
GET /api/events 的初始顺序为 status、models、accounts、最近 200 条 log、cooldowns、按开始时间排序的活动 request。后续事件的 data 形状:
type |
data |
|---|---|
status |
AdminStatus |
models |
{"models":[Model,...]} |
accounts |
{"accounts":[AdminAccount,...]} |
log |
AdminLog |
cooldowns |
[AdminCooldown,...] |
request |
AdminRequest,状态变化时重复发送同一 ID |
管理错误统一为:
{"error":{"code":"invalid_request","message":"..."}}控制面错误码包括 control_plane_forbidden、control_plane_origin_forbidden、invalid_request、invalid_account、account_not_found、account_busy、account_required、request_not_found 和 upstream_error。
| HTTP | 管理错误码 |
|---|---|
| 400 | invalid_request、invalid_account、account_required |
| 403 | control_plane_forbidden、control_plane_origin_forbidden |
| 404 | account_not_found、request_not_found |
| 409 | account_busy |
| 上游状态或 502 | upstream_error |
运行状态机如下。page catalog 表示账户会话页面载入时的 GetAiStudioBenefitTier 与 ListModels 响应,pending account 表示等待下一轮目录重试的账户:
process start
-> control plane ready
-> STOPPED
POST /api/control/start
-> LAUNCHING
-> load CachedModels
-> if cache is empty, read the page catalog of every enabled ready/busy account
and wait for the first non-empty live catalog
-> prewarm up to WARM_WORKER_LIMIT workers
with WARM_STARTUP_CONCURRENCY bootstraps
-> first worker ready, or every warmable account is cooling
-> RUNNING
-> with a cache, read page catalogs after the first worker result
-> continue the catalog sync and remaining worker prewarm in background
-> every 30s, reload the page of every pending account
-> every 24h from the catalog sync start, reload the page of every enabled ready/busy account one at a time
request
-> if no catalog has the model, wait for the running 24h round,
or start one now when the last round began over 10 minutes ago
-> resolve model and endpoint capability
-> acquire one PER_ACCOUNT_CONCURRENCY slot
-> prepare WAA proof
-> send MakerSuite RPC
-> stream frames
-> release slot
POST /api/control/stop
-> cancel launch or active requests
-> bound catalog sync shutdown to 2s
-> close WAA workers
-> bound unfinished lifecycle-transition wait to 12s
-> STOPPED
请求状态使用 queued、running、completed、cancelled、failed。视频状态使用 queued、completed、failed,对应 progress 0 或 100。
模型目录驻留在当前 generation(runtimeGeneration 表示的一次生成服务实例)的内存中;新 generation 载入各账户目录中目录指纹与 runtime-state.json 一致的 catalog.json 作为缓存,公开目录与请求编码使用的模型条目都由其中保存的 ListModels 响应解析得到。启动先用当前 generation 的 catalog.CachedModels() 建立公开快照。缓存非空时直接进入 Worker 预热,首个 Worker 有结果后为每个 enabled 且处于 ready 或 busy 的账户开始后台目录同步;缓存为空时立即开始。目录同步读取账户会话页面载入时的响应:有常驻 Worker 的账户取它最近一次页面载入,没有的账户在 Worker 容量允许时启动 Worker,否则临时载入一个页面,取得响应后关闭;还没有目录的账户同时读取,已有目录的账户逐个读取。可预热的账户全部处于冷却时,预热不返回错误,生成服务直接进入 RUNNING,预热在最早的冷却结束时开始。每个非空结果到达时立即从 CachedModels 合并公共目录并发布 accounts、models;生成服务已经 RUNNING 时同时触发 Worker 预热,新 generation 的首个非空结果还会解除启动等待。全账户同步结束时,auth_required 集合发生变化会补发一次账户与模型快照,并记录同步成功数、非空数、公共模型数、待重试账户数和耗时。第一个 Worker 就绪后重新读取当前缓存,并在持有账户与配置变化锁时把服务状态设为 RUNNING。
账户状态:
| 状态 | 调度语义 |
|---|---|
ready |
认证有效且存在可用槽位 |
busy |
存在独占操作、认证刷新或活动请求 |
cooldown |
全局 * 冷却仍有效 |
auth_required |
账户级认证失败 |
unavailable |
当前运行时不可用 |
disabled |
配置已停用 |
busy账户仍按PER_ACCOUNT_CONCURRENCY判断剩余槽位- 模型 scope 冷却不改变账户状态,只影响对应请求的候选分类
认证状态写回携带 authGeneration 与 checkedAt,仅应用账户对象、authGeneration 值与时间均匹配当前状态的结果;相同时间以 ready 为最终状态。模型访问和冷却写回携带 modelAccessGeneration 与 checked_at,仅应用 modelAccessGeneration 值匹配且时间不早于当前状态的结果;相同时间以 verified 为最终状态。verified 表示该账户已经成功调用对应模型或能力。
ModelAccessKey(scope, model) 先移除 models/ 前缀;空 scope 返回 canonical model ID(规范化模型 ID),非空 scope 返回 <scope>:<canonicalModelID>。各能力使用以下值:
| 能力 | scope | 成功记录 |
|---|---|---|
| 普通生成 | <modelID> |
规范事件 EventFinish 到达时写 verified |
| CountTokens | count-tokens:<modelID> |
清 scope 冷却,保留普通生成资格 |
| Transcribe | <modelID> |
非空 text 或 segments 写 verified |
| Live 文本 | <modelID> |
setup complete 写 verified;每次 text 开始一次模型资格检查 |
| Live 音频/图像 | bidi-media:<modelID> |
media 开始媒体资格检查 |
| Robotics | bidi-media:<modelID> |
text 开始模型资格检查 |
Code 7 保留当前 operation scope 的 verified 状态;认证失败更新账户级 auth_required。上传、临时文件清理等非生成失败使用全局 * 冷却。
正文、reasoning、工具、usage 与首事件用于输出和性能统计;终态前断流、客户端取消或错误保持原有验证状态。
Bidi setup 成功使用 lease(本次会话持有的账户租约)的 checkedAt。此后每个会更新模型资格的轮次分配会话内严格递增的 attempt 时间,turn_complete 消费对应 attempt 并写入资格。Code 7 不更新模型资格。Bidi 认证成功与 401 使用相同 attempt 顺序,setup 后较晚返回的 401 可以更新账户为 auth_required。
确认浏览器进程退出后,将 process 和 Worker 状态设置为 closed。关闭失败时保留 Worker、runtime lease、warm 标记与 generation(Worker 实例版本号);后续 Stop 即使服务状态已经是 STOPPED,也会再次执行 Worker reset。Camoufox 关闭阶段上界为 BiDi 3 秒、进程终止与等待 5 秒、profile 删除 2 秒;各阶段错误使用 errors.Join 保留。
模型目录 fan-out 绑定当前生成服务的 context。启动失败、启动取消或 Stop 会取消全部目录任务,并最多等待 2 秒确认后台目录协程退出。Stop 遇到尚未完成的 LAUNCHING 或其他启动/停止切换时,等待 transition channel(切换完成通知 channel)的上界为 12 秒;该上界覆盖 2 秒目录退出与有界 Worker 清理,超时错误与清理错误使用 errors.Join 返回。
按需热替换先启动 pending Worker(正在启动、尚未发布的替代 Worker),再关闭旧 Worker;旧实例成功退出后,替代 Worker 才成为当前 Worker。旧实例关闭和替代 Worker 回收同时失败时,两者都保留等待再次清理,并各占一个活动容量槽;达到容量上限后停止新建 Worker。完整生成服务 Stop/Start 的顺序为:Start 创建新生成服务实例前先重试停止旧实例,旧 PID 未退出时返回停止错误并保留原实例。
Worker 进程故障、Worker 被替换与协议 Code 5 会重建当前账户 Worker 并在原账户重放一次。
模型目录重试的 pending 集合保存等待再次同步的账户 ID。启动期全账户同步、以及新增、登录或在管理端启用后的单账户同步,遇到任意错误或成功返回空目录时加入;返回非空目录时移除;删除账户同时移除。全账户后台同步结束后启动单个 30 秒 ticker(Go 定时器),每次按启动期同步的方式重新载入排序后的待重试账户的会话页面,并在任务开始时复核该 ID 仍在 pending 集合中。错误或空目录继续保留;每个非空成功立即更新账户缓存与公共目录快照、发布 accounts 和 models,并在 RUNNING 状态触发 Worker 预热。批次结束时,auth_required 集合发生变化会补发当前账户与模型快照;即时单账户同步无论成功或失败都立即发布当前快照。启动期同步、单账户同步与 30 秒重试中的每个账户读取占用该账户的一个普通并发槽位,与生成请求和 Worker 启动共用 PER_ACCOUNT_CONCURRENCY。
同一循环从全账户同步开始时起每 24 小时巡检一轮:逐个重新载入全部 enabled 且处于 ready 或 busy 的账户的会话页面,读取页面载入时的 GetAiStudioBenefitTier 与 ListModels 响应(启用 Build 时另读 Build 目录;账户本进程的首次读取先按条款同意处理 GetLoggingContext):
- 每个账户占用一个普通并发槽位,与生成请求共用
PER_ACCOUNT_CONCURRENCY,槽位已满的账户跳过本轮 - 请求的模型不在任何账户的目录中时,巡检正在读取一轮的第一个账户则请求等它读完;没有进行中的一轮且距上一轮开始已超过 10 分钟时,巡检立即开始一轮,请求等这一轮读完第一个账户后再查找模型,仍没有时返回模型不存在,其余账户在后台继续读取;下一轮巡检从这一轮开始时计时
- 读取经认证续签,续签后仍为认证失败时账户转为
auth_required - 权益或目录变化时写回
benefit_tier与目录,权益变化清除该账户的模型资格记录,更新公共目录快照并发布accounts和models - 订阅模型的生成遇到额度错误时,同一读取在后台对该账户执行一次,同一账户每分钟最多一次
- 管理端的立即刷新等待该账户的独占租约,任何状态的账户都执行同一读取,管理页断开连接不中止
- 账户从未成功读取目录时
benefit_tier为Unknown,message为最近一次读取失败的原因
模型目录投影:
| 规则 | 结果 |
|---|---|
| OpenAI | model list 与同形单个 model 对象 |
| Anthropic | 带 Anthropic-Version 时为 Anthropic Models API 格式 |
| Gemini | 模型名称 models/<ID> |
| 单模型解析 | 正式 ID 优先于别名 |
| 多账户同模型 | methods、capabilities、能力选项与 access modes 取并集,paid 取逻辑 OR |
| 多账户 token limit | 输入和输出上限分别取正数最小值 |
| 模型别名 | 来自 ListModels field 57 |
| 请求匹配 | model ID/alias、method、capability、AccessModes、账户权益与运行状态 |
| 候选排序 | verified 与目标模型首事件耗时 |
| capability 约束 | 端点要求与账户实时能力同时命中 |
- 未验证账户仍可进入候选
管理模型对象完整字段:
{
"id": "gemini-example",
"name": "Gemini Example",
"description": "...",
"methods": ["countTokens", "generateContent"],
"input_token_limit": 1048576,
"output_token_limit": 65536,
"capabilities": {"thinking": true, "capability_code_25": true},
"capability_options": {"aliases": ["gemini-example-latest"]},
"access_modes": [3, 4],
"thinking_levels": ["LOW", "MEDIUM", "HIGH"],
"default_thinking_level": "MEDIUM",
"paid": true
}OpenAI GET /v1/models:
{
"object": "list",
"data": [{
"id": "gemini-example",
"object": "model",
"created": 0,
"owned_by": "google",
"name": "Gemini Example",
"description": "...",
"supported_generation_methods": ["countTokens", "generateContent"],
"input_token_limit": 1048576,
"output_token_limit": 65536,
"capabilities": {},
"capability_options": {},
"access_modes": [],
"thinking_levels": ["low", "medium", "high"],
"default_thinking_level": "medium",
"paid": true,
"channels": ["playground", "build"]
}]
}支持思考档位的模型带 thinking_levels 与 default_thinking_level:档位按目录 field 72 的顺序排列,默认档位是请求未指定思考参数时使用的档位。管理模型对象与 Gemini 条目使用 MINIMAL、LOW、MEDIUM、HIGH,OpenAI 条目使用对应的小写值,与 reasoning_effort 的取值相同。
请求携带 Anthropic-Version 时,同一路由返回:
{
"data": [{"type":"model","id":"gemini-example","display_name":"Gemini Example","created_at":"1970-01-01T00:00:00Z","max_input_tokens":1048576,"max_tokens":65536,"capabilities":{"batch":{"supported":false},"citations":{"supported":false},"code_execution":{"supported":true},"context_management":{"supported":true,"clear_thinking_20251015":{"supported":true},"clear_tool_uses_20250919":{"supported":true},"compact_20260112":{"supported":true}},"effort":{"supported":true,"low":{"supported":true},"medium":{"supported":true},"high":{"supported":true},"xhigh":{"supported":false},"max":{"supported":false}},"image_input":{"supported":true},"pdf_input":{"supported":true},"structured_outputs":{"supported":true},"thinking":{"supported":true,"types":{"enabled":{"supported":true},"adaptive":{"supported":true}}}},"lifecycle":"active","line":null,"deprecated_at":null,"retires_at":null}],
"has_more": false,
"first_id": "gemini-example",
"last_id": "gemini-example"
}max_input_tokens 与 max_tokens 取实时目录的输入与输出 token 上限,目录缺失时为 null。capabilities 按实时目录给出:thinking 及其 enabled、adaptive 两种类型随模型是否支持思考,effort 的 low、medium、high 对应模型支持的思考档位,xhigh 与 max 按 high 执行,supported 为 false;image_input 与 pdf_input 随对话模型,code_execution 与 structured_outputs 随目录的代码执行与结构化输出能力;batch 与 citations 的 supported 为 false,context_management 与其三种编辑为 true。limit 为 1–1000 的整数,超出范围返回 400 invalid_request_error;省略时为 20。after_id 返回该模型之后的一页,before_id 返回之前的一页,has_more 表示该方向是否还有模型,first_id、last_id 为本页首尾 ID。lifecycle(含 lifecycle[] 与逗号分隔写法)不包含 active 时返回空列表。单模型路由返回与列表项相同的对象,失败响应使用 Anthropic 错误对象。
Gemini GET /v1beta/models 返回 {"models":[...]},单模型路由直接返回一个对象。字段为 name、baseModelId(模型 ID)、displayName、description、supportedGenerationMethods(上游目录中该模型的方法里本服务提供的 generateContent、countTokens、createCachedContent、embedContent、batchEmbedContents、predict、predictLongRunning,按上游顺序)、inputTokenLimit、outputTokenLimit、可选 temperature、maxTemperature、topP、topK、modelStage(ListModels field 23 或 Build 目录给出的模型阶段)、thinking、thinkingLevels、defaultThinkingLevel、capabilities、capabilityOptions、accessModes、paid、channels。
生成服务未进入 RUNNING 且还没有任何账户目录时,模型列表与单模型查询返回 503,与生成请求相同。
GET /v1/models/{model} 与 GET /v1beta/models/{model} 接受 models/ 前缀;这两个模型查询入口以及生成、计数、视频、转录与 Bidi 同时接受 canonical ID 和 capability_options.aliases 中的 alias;alias 在调度和发送上游前换成对应的 canonical ID。
管理模型中的 description、token limits、capabilities、capability options、access modes 与 false paid 使用 omitempty;OpenAI 和 Gemini 响应始终包含身份、methods 与 token limits,并在 map/slice 非空或 paid=true 时增加对应扩展字段。
管理目录合并全部账户的上游实时模型集合,顺序沿用各账户 ListModels 的上游顺序:只出现在后一个账户目录中的模型排在它在该目录中的前一个模型之后,没有前一个已知模型时排在该目录首个已知模型之前,该目录没有已知模型时排在末尾;在此顺序上依次排列有可用通道的普通模型、经后台任务生成的 agent(interaction_task,如 Antigravity 与 Deep Research,不论有无可用通道)与没有可用通道的普通模型。公开目录保留当前公开协议承载其调用方法、且已启用通道可以提供的模型;启用 Build 通道时同时包含 Build 独有的可生成模型,channels 列出可调用该模型的通道,见 Build 通道。启用账户的权益都不满足 AccessModes 的模型同样列出,不含 channels。短期冷却和忙碌状态由请求调度处理。
主要请求格式:
| 端点 | 必需字段 | 主要结果 |
|---|---|---|
/v1/chat/completions |
model |
Chat completion 或增量 chunk |
/v1/responses |
model |
Response object 或 response.* 事件 |
/v1/responses/input_tokens |
model 或 previous_response_id |
{"object":"response.input_tokens","input_tokens":<INT>} |
/v1/files |
multipart file、可选 purpose |
OpenAI file object |
/v1/messages |
model |
Anthropic message 或 message 事件 |
:generateContent / :streamGenerateContent |
路径中的模型 | Gemini candidates、usage 与 grounding metadata |
/v1/images/generations |
prompt |
b64_json 或 data URL |
/v1/audio/speech |
model、input |
MP3、Opus、AAC、FLAC、WAV 或 PCM body |
/v1/audio/transcriptions |
multipart file |
文本或转录 JSON |
/v1/videos |
prompt 或 input_reference |
长任务对象,随后轮询并下载内容 |
生成与计数请求需要系统提示或对话内容中的至少一项,只有系统提示时以它作为 user 轮发送。请求以 assistant 轮结尾时,gemini-3.1-pro-preview、gemini-3.1-flash-lite、gemini-3-flash-preview、gemini-omni-1.1-flash、gemini-nano-banana-2.1 与 gemma- 开头的模型原样以 model 轮结尾发送,由模型原生续写。其余模型(包括 -latest 别名与 -build 写代码助手)在 CONTINUATION_REWRITE 打开时改写末尾连续 assistant 轮:CONTINUATION_PROMPT 非空时,这些轮的正文与代码执行内容以 <assistant_prefix> 包裹,连同该提示词写入系统指令;为空时这段正文作为最后一轮 user 发送。改写后模型从前缀之后续写,响应只返回续写部分,末尾未回传结果的函数调用由模型重新生成。CONTINUATION_REWRITE 关闭时所有模型原样发送,Playground 以 400 Requests ending with a model turn are not supported 拒绝的模型返回该错误。各生成入口与计数接口按同一规则转换,countTokens 接受以 model 轮结尾的请求。
四套生成入口共享同一规范请求,输入映射如下:
| 能力 | OpenAI Chat | OpenAI Responses | Anthropic | Gemini |
|---|---|---|---|---|
| system | system / developer messages |
instructions 和 system/developer message items |
system 字符串或 text blocks |
systemInstruction text parts |
| text | 字符串或 text content part | 字符串、message item | 字符串或 text block | Part text |
| image/document | Base64 data URL、file_id |
input_image、input_file |
base64、URL 或 file source | inlineData、fileData |
| audio input | input_audio Base64 |
message content 中的 input_audio |
base64 document source | inlineData |
| video | video_url Base64 data URL、file_id、http(s) URL |
input_video |
base64 source | inlineData、fileData |
| YouTube | video_url / input_video |
input_video |
URL source | fileData.fileUri |
| function call | assistant tool_calls 或旧式 function_call |
function_call item |
tool_use block |
functionCall Part |
| function result | tool message | function_call_output item |
tool_result block |
functionResponse Part |
| structured output | response_format |
text.format |
output_config.format 或 beta output_format |
responseMimeType 与 response schema,或 responseFormat 的 text 项;image 项为图片比例与尺寸 |
| thinking | reasoning_effort、reasoning.effort 或 extra_body.google.thinking_config;include_thoughts 为 false 时不输出思考 |
reasoning.effort;reasoning.summary 决定是否输出思考摘要 |
thinking.budget_tokens、output_config.effort;thinking.type 决定是否输出思考 |
thinkingConfig;includeThoughts 决定是否输出思考 |
Gemini 附件与 predictLongRunning 的图片输入接受 inlineData / inline_data、fileData / file_data、mimeType / mime_type 和 fileUri / file_uri。同一别名对同时出现时,外层优先选择驼峰对象,内层优先选择非空驼峰值。
媒体 Base64 输入接受标准和 URL-safe 字母表、可选的 = 填充,以及 data:<MIME>;base64, 前缀。GIF 内联图片和 OpenAI 视频 input_reference 表单附件提取首帧,按逻辑画布尺寸与帧偏移编码为 PNG 后发送。透明首帧保留透明背景;不透明首帧的未覆盖区域使用全局色表中的背景色。
OpenAI Chat 与 Anthropic 省略转换后没有 parts 的空历史消息;纯空白文本、工具调用、工具结果及媒体保留原有内容。
生成参数映射:
| 参数 | 规则 |
|---|---|
| OpenAI max tokens | max_completion_tokens 优先于 max_tokens |
| Anthropic max tokens | max_tokens 映射 generation config field 4 |
| Gemini max tokens | maxOutputTokens 映射 generation config field 4 |
| temperature / topP / topK / seed | 映射 generation config fields 5 / 6 / 7 / 19 |
| stop sequence | 映射 generation config field 2 |
| stop sequence 命中 | 本地匹配并返回实际命中的序列 |
| structured output | MIME type 映射 field 8,Schema 映射 field 9 |
OpenAI parallel_tool_calls |
false 时本轮最多一个函数调用 |
Responses truncation |
auto 移除最早的完整对话轮次 |
Anthropic thinking |
enabled 写入 budget_tokens;adaptive 使用模型默认思考 |
| Anthropic thinking type | disabled 使用模型最低思考配置 |
- OpenAI Chat 与 Responses 的
parallel_tool_calls省略或为true时允许并行;Responses 同时把该值写入响应元数据 - Responses
truncation:auto按上游权威计数移除最早的完整对话轮次,保留最新轮次与工具调用/结果配对;省略或disabled时保留完整输入 - Anthropic 省略
thinking或thinking.type:"disabled"时不返回思考正文,续接签名以redacted_thinking保持;未知 type 返回400 invalid_request_error - Chat、Responses 与 Gemini 的协议专属参数见各协议小节
POST /v1/chat/completions 请求字段:
| 字段 | 类型与语义 |
|---|---|
model |
必需模型 ID |
messages |
message 数组 |
stream |
boolean |
stream_options.include_usage |
在 finish chunk 后发送 usage-only chunk |
tools |
function、custom 或 Google server tool 数组 |
tool_choice |
省略/auto/none/required、named function 或 custom 对象、allowed_tools |
web_search_options |
对象,开启 Google Search |
temperature、top_p、top_k |
可选采样值 |
max_tokens、max_completion_tokens |
后者优先 |
frequency_penalty、presence_penalty |
不影响生成 |
n |
1–128 |
parallel_tool_calls |
省略/true/false |
logprobs、top_logprobs、logit_bias |
不影响生成 |
stop |
string 或 string array |
response_format |
{type:"text"}、{type:"json_object"} 或 {type:"json_schema",json_schema:{schema}} |
modalities、audio |
["text","audio"] 与 {voice,format},voice 为声音名或 {id},format 为 wav、mp3、flac、opus、aac、pcm16 |
reasoning_effort |
thinking effort |
reasoning.effort |
nested thinking effort |
extra_body.google.thinking_config |
Gemini OpenAI 兼容层的 thinking_level、thinking_budget 与 include_thoughts |
seed |
64 位整数 |
functions、function_call |
旧式函数声明与函数选择 |
allowed_tools的 mode 与工具列表映射为调用模式与允许的函数名,请求只发送列表中的函数与托管工具对应的 Google 工具web_search_options的搜索深度与近似位置写入搜索指令n大于 1 时每个 choice 独立并发生成,带seed时第 i 个 choice 使用seed+i;choices按index排列,各自带finish_reason;usage的输入与缓存命中按一次计,输出、思考与音频 token 为各 choice 之和;任一生成失败时整个请求返回该错误;流式请求在首个 choice 就绪后开始输出,其余 choice 的启动错误以流内错误返回frequency_penalty、presence_penalty、logprobs、top_logprobs与logit_bias接受任意值;非流式响应的choices[].logprobs为nullstop中的空字符串从停止条件中移除reasoning.effort与reasoning_effort映射到同一配置,两者同时提供时以reasoning.effort为准json_schema.schema原样作为responseJsonSchema发送;Chatjson_schema.description与 Responsestext.format.description写入 Schema 顶层description,Schema 自带的 description 接在其后(空一行)modalities含audio,或省略modalities而设置audio时输出音频:请求AUDIO模态与audio.voice声音,format默认wav。非流式响应的message.audio为{id,data,expires_at,transcript},content为null,模型正文写入transcript。流式响应的音频位于delta.audio:pcm16逐块输出{id,data},其他格式在结束时输出一个完整的{id,data,expires_at};正文以{id,transcript}增量输出,pcm16的最后一块为{id,expires_at}。音频回复以 WAV 与 transcript 保存在续接状态中,与 Responses 共用最近 256 个条目;assistant 消息的audio:{id}引用它时,该轮以这段音频与 transcript 发给上游,ID 不存在时返回400 invalid_requestextra_body.google.thinking_config按 GeminithinkingConfig处理:thinking_level优先于reasoning_effort,thinking_budget为 -1 时使用模型默认思考设置,include_thoughts为 false 时不输出reasoning_contentfunctions按 function 工具发送,function_call的none、auto与{name}按tool_choice处理,每轮最多一个调用;带functions的请求以 assistantfunction_call:{name,arguments}返回调用,finish_reason为function_call,流式为delta.function_call。历史中的 assistantfunction_call与function角色消息按函数调用与函数结果发送
message 字段为 role、content、可选 name、tool_call_id、tool_calls、function_call,assistant 另有 refusal 与 audio。system、developer、user 与 assistant 消息的 name 以 <name>: 写在该消息第一段文本前,例如 {"role":"system","name":"example_user","content":"Hi"} 在系统指令中为 example_user: Hi;tool 消息的 name 为函数名。assistant tool call:
{
"id": "call_01",
"type": "function",
"function": {"name":"get_weather","arguments":"{\"city\":\"Taipei\"}"},
"extra_content": {"google":{"thought_signature":"<SIGNATURE>"}}
}content 可以是 string 或 Part 数组。Part 字段:
type |
其他字段 |
|---|---|
text、input_text、output_text |
text |
image_url、input_image |
image_url string 或 {"url":"..."};也可只给 file_id;可选 detail |
video_url、input_video |
video_url string 或 {"url":"..."};也可只给 file_id |
input_file、file |
file_id,或 filename + file_data,filename 为附件给模型的名称;Chat file 的字段位于嵌套 file 对象 |
input_audio |
input_audio.data、input_audio.format |
refusal |
refusal,作为所在消息的文本 |
detail 为 low、high 与 Responses 的 original 时分别设置该 Part 的 MEDIA_RESOLUTION_LOW、MEDIA_RESOLUTION_HIGH、MEDIA_RESOLUTION_ULTRA_HIGH,auto 与省略时使用模型默认分辨率;Chat 的 detail 位于 image_url 对象中。OpenAI image_url / input_image 与 video_url / input_video 值为 data URL 时形成 inline data,值为 YouTube URL 时形成 external media,Gemini Files API 文件 URI 保持文件引用,其他 http(s) URL 由服务端下载后作为内联媒体发送,其他非 data 字符串按已上传 file ID 解析。data URL 接受 Base64 与百分号编码数据,省略 MIME 时按内容判断类型,MIME 参数不发送。同一请求内相同 URL 只下载一次;下载随请求取消,大小上限与内联媒体相同(512 MiB),MIME 取响应 Content-Type,缺失、无法解析或为 octet-stream 时按内容判断;URL 主机或任一重定向目标解析到本机、私网、链路本地、组播或未指定地址时不连接,按下载失败处理;下载失败返回 400,错误信息包含 URL 与原因。file_data 接受 data URL 或 Base64 文件内容,没有声明 MIME 时按 /v1/files 的规则依次按文件内容与 filename 扩展名判断。
function tool 使用 {"type":"function","function":{"name","description","parameters","strict"}}。strict:true 启用参数契约校验。Google tool type 为 web_search、web_search_preview、image_search、url_context、code_interpreter、google_maps。custom tool {"type":"custom","custom":{name,description,format}} 声明为只有字符串参数 input 的函数,grammar 格式的语法与定义写入函数描述;调用以 {"type":"custom","custom":{name,input}} 返回,历史中的 custom 调用以 {"input":<INPUT>} 发送。历史函数调用的 arguments 不是 JSON object 时以 {"_raw":"<原文>"} 发送。
非流式响应:
{
"id": "chatcmpl_...",
"object": "chat.completion",
"created": 0,
"model": "gemini-example",
"provider_model": "gemini-provider-id",
"choices": [{
"index": 0,
"message": {
"role": "assistant",
"content": "...",
"reasoning_content": "...",
"tool_calls": [],
"annotations": []
},
"logprobs": null,
"finish_reason": "stop",
"provider_finish_reason": "provider_19"
}],
"usage": {
"prompt_tokens": 10,
"completion_tokens": 20,
"total_tokens": 30,
"completion_tokens_details": {"reasoning_tokens": 5}
}
}provider_model、provider_finish_reason、reasoning_content、tool_calls、annotations 和 usage 仅在有对应数据时出现。service_tier 为上游用量报告的服务等级:flex 或 priority,其余为 default。annotation 形状为 {"type":"url_citation","url_citation":{"url","title","start_index","end_index"}},start_index、end_index 为 content 中的字符下标;上游没有正文区间的来源两者为 0。
Chat SSE 顺序:
- 每个 choice 一个 role chunk:
delta={"role":"assistant","content":""} - 正文
delta.content、思考delta.reasoning_content、工具delta.tool_calls、媒体或代码渲染delta.content - 各 choice 结束时发送引用
delta.annotations - 随后发送该 choice 的 finish chunk:
finish_reason,可选provider_finish_reason include_usage=true且上游有 usage 时,在全部 choice 结束后发送choices:[]的 usage-only chunkdata: [DONE]
每个普通 chunk 为 {id,object:"chat.completion.chunk",created,model,choices:[{index,delta,finish_reason}],usage?},index 标识所属 choice。响应头已发送后的失败为 data: {"error":{"message","type","code"}}。
POST /v1/responses 请求字段:
| 字段 | 类型与语义 |
|---|---|
model |
必需模型 ID |
input |
string 或 input item 数组 |
instructions |
顶层 system instruction |
stream |
boolean |
tools、tool_choice |
function、custom、namespace(可含 custom)、local_shell/shell/apply_patch 与 Google tools;choice 支持 auto/none/required、named function/custom、allowed_tools、apply_patch/shell 与托管工具类型 |
temperature、top_p、max_output_tokens |
生成参数 |
reasoning |
{"effort":"...","summary":"..."},generate_summary 与 summary 同义 |
text |
`{"format":{"type":"text |
previous_response_id |
当前进程内已保存的前一 Responses 响应 ID,Interactions 资源 ID 视为不存在 |
parallel_tool_calls |
省略/true/false |
truncation |
省略/disabled/auto |
metadata |
string-to-string object |
store |
省略/true/false |
background |
boolean |
include |
reasoning.encrypted_content、web_search_call.action.sources、code_interpreter_call.outputs |
max_tool_calls |
正整数;声明内置工具或 MCP 时以 Make at most <N> built-in tool calls in this response. 追加到本次指令,响应回传该值 |
context_management |
[{"type":"compaction","compact_threshold":<token>}] |
conversation、prompt |
本服务不保存这两类对象,引用它们的请求返回 404 not_found |
- namespace 内的函数以全名编码,输出恢复
namespace与原函数名,不同 namespace 可声明同名函数 store省略或为true时保存当前进程会话节点与输出项;false只返回本次结果,不建立节点,既有续接链保持不变background:true的非流式请求立即返回status:"queued"的响应对象(带Content-Length与Connection: close),生成在服务端继续,开始后保存为in_progress,结束后保存为最终对象;客户端连接关闭不影响生成。该响应不论store取值都会保存,供查询、取消与续传background:true且stream:true时,事件依次为queued状态的response.created与response.queued、response.in_progress、输出项事件与终止事件,全部写入事件记录;客户端断开后生成继续,GET /v1/responses/{id}?stream=true&starting_after=<sequence_number>从该序号之后续传并跟随到结束,不带starting_after时从头回放context_management的 compaction 阈值被超过时(输入 token 按 countTokens 计),先按compaction_trigger的方式压缩当前上下文,再以被压缩部分中的 developer 与 system 消息、保留的条目与 compaction 项作为输入生成;compaction 项排在output首位,流式时在其他输出项之前写出它的output_item.added与output_item.done
input item 字段为 type、id、role、content、call_id、name、namespace、arguments、input、action、operation、status、output、encrypted_content。支持 message、function_call、function_call_output、reasoning item 与下文列出的工具历史项。message content Part:
| type | 字段 |
|---|---|
input_text、output_text |
text |
input_image |
image_url string 或 {url};也可只给 file_id |
input_file |
file_id、file_url,或 filename + file_data,filename 为附件给模型的名称 |
input_audio |
input_audio:{data,format} |
input_video |
video_url string 或 {url};也可只给 file_id |
refusal |
refusal,作为所在消息的文本 |
Responses 的图片、视频与文件 Part 复用上述 data URL、file ID 与 YouTube 规则。
其他 input item 映射:
| item | 映射 |
|---|---|
| system/developer message | 文本进入系统指令,图片与文件移到首个 user 轮 |
custom_tool_call |
函数调用,参数为 {"input":<INPUT>} |
local_shell_call |
local_shell 函数调用,参数为去掉 type 的 action |
shell_call |
shell 函数调用,参数为 action |
apply_patch_call |
apply_patch 函数调用,参数为 operation |
custom_tool_call_output、local_shell_call_output、shell_call_output、apply_patch_call_output |
按 call_id 关联的函数结果 |
computer_call |
computer 函数调用,参数为 action,或 {"actions":[...]} |
web_search_call、code_interpreter_call、file_search_call、mcp_call、mcp_list_tools、mcp_approval_request、tool_search_call、tool_search_output、program、program_output |
assistant 文本摘要 <type> <JSON>;输入含 mcp_approval_response 时 mcp_approval_request 为 mcp__<server_label>__<name> 函数调用,带 approval_request_id 的 mcp_call 并入对应函数结果 |
additional_tools |
tools 并入请求的工具列表 |
configuration_update |
最后一个带 reasoning.effort 的项覆盖请求的推理强度 |
image_generation_call |
assistant 文本摘要与 result 图片 |
computer_call_output |
按 call_id 关联的 computer 函数结果 {"type":"computer_screenshot"},截图作为图片 |
mcp_approval_response |
对应批准请求的函数结果:批准时为服务调用该 MCP 工具得到的 output 与 error,拒绝时为带 reason 的拒绝说明;批准请求取自输入或 previous_response_id 的输出,找不到时返回 400;/v1/responses/input_tokens 与 /v1/responses/compact 不调用工具,批准的函数结果的 output 与 error 均为 null |
item_reference |
当前进程保存的同 ID 输入项或输出项 |
compaction |
摘要 user 轮与原样保留的条目,见下文上下文压缩 |
compaction_trigger |
压缩当前上下文,必须是最后一个输入项,其他位置返回 400 |
文本摘要的 JSON 省略 id、type 与 status。函数结果项缺少 call_id 时使用 id;apply_patch_call_output 的结果为 {"status","output"}。没有 type 与 role、只带 id 的项按 item_reference 展开,找不到同 ID 的项时返回 400。system/developer message 的图片与文件在没有 user 轮时单独组成首个 user 轮。
Responses tool 字段:
| tool type | 字段 |
|---|---|
function |
name、description、parameters、strict;省略 strict 时参数 Schema 的每个对象都设 additionalProperties: false 且全部属性必填即按 strict 校验,否则按非 strict,响应的 tools 回显实际取值 |
web_search、web_search_2025_08_26、web_search_preview、web_search_preview_2025_03_11 |
search_context_size、user_location、filters.allowed_domains、search_content_types |
image_search、url_context、google_maps |
type |
code_interpreter |
container |
custom |
只有字符串参数 input 的函数,grammar 写入描述 |
local_shell |
函数,参数为 command、working_directory、timeout_ms |
shell |
函数,参数为 commands、timeout_ms、max_output_length;environment.skills 的名称、路径与说明写入描述 |
apply_patch |
函数,参数为 type、path、diff |
image_generation |
图片模型按与 POST /v1/images/generations 相同的规则处理 size、quality、output_format 与 output_compression;input_image_mask 见下文 |
computer_use_preview、computer |
名为 computer 的函数;computer_use_preview 的 display_width、display_height 与 environment 写入描述,参数为单个 action,computer 的参数为 actions 列表 |
mcp |
上游 MCP 服务器:server_label、server_url、authorization、headers、allowed_tools(数组或 tool_names),server_description 写入系统指令 |
file_search、tool_search、programmatic_tool_calling |
接受但不声明 |
- web search 工具的
search_context_size、user_location与filters.allowed_domains写入搜索指令,域名限制使用site:查询;上游 grounding query 与 sources 原样返回 search_content_types只含image时只开启图片搜索,同时含text时同时开启网页搜索;图片搜索查询同样输出为web_search_callmcp工具的require_approval省略或为always时全部工具需要批准,为never时全部不需要;为对象时never过滤匹配且always过滤不匹配的工具不需要批准,其余需要批准,过滤的tool_names与read_only同时给出时都要满足。不需要批准的工具由上游在生成中直接调用;需要批准的工具由服务经出口代理读取tools/list,声明为mcp__<server_label>__<name>函数,模型调用时输出mcp_approval_request项(id为mcpr_加调用 ID)并结束本轮;下一轮输入给出mcp_approval_response且approve为 true 时,服务以tools/call调用该工具,结果以带approval_request_id的mcp_call项排在本轮输出首位,客户端回传该mcp_call时不再调用。需要批准的工具按tool_choice展开:为none或指定函数时不读取tools/list,为mcp或allowed_tools时只声明其中列出的服务器与工具,allowed_tools同时列出函数时,声明的 MCP 工具函数也加入允许调用的函数;additional_tools输入项中的mcp工具与tools中的相同。connector_id返回 400;allowed_tools.read_only:true时服务经出口代理以server_url与请求头读取该服务器的tools/list,只允许annotations.readOnlyHint为 true 的工具,同时给出tool_names时取交集,没有允许的工具时不连接该服务器,tools/list失败返回 400 并说明原因;上游的 MCP 调用输出为mcp_call项,output为工具结果文本- namespace 的
description写在其中各函数描述之前 code_interpreter.container为容器 ID 字符串时忽略;为对象时其file_ids作为文件引用附到最后一个 user 轮,没有 user 轮时作为新的 user 轮
image_generation 的 input_image_mask:{image_url} 读取 data URL 或下载 http(s) 图片,{file_id} 读取 /v1/files 上传的文件,按 /v1/images/edits 的 mask 转为 PNG 遮罩,连同同一句说明插在最后一个 user 轮最后一个媒体之后(该轮没有媒体时插在开头),只发给本次生成,不进入续接历史;遮罩无法读取或解码时返回 400。
tool_choice 的 allowed_tools 映射为 mode(auto 或 required)与允许的函数名,请求只发送列表中的函数与托管工具对应的 Google 工具;web_search、web_search_2025_08_26、web_search_preview、web_search_preview_2025_03_11、code_interpreter、url_context、google_maps 与 image_search 映射为 required,本次只允许该工具;computer、computer_use、computer_use_preview 映射为必须调用 computer 函数;mcp 映射为 required,带 name 时只允许该服务器的该工具;file_search、image_generation、programmatic_tool_calling 与 tool_search 映射为 auto。
响应 shell 的字段始终存在:
{
"id": "resp_...",
"object": "response",
"created_at": 0,
"completed_at": null,
"status": "in_progress",
"error": null,
"incomplete_details": null,
"instructions": null,
"metadata": {},
"model": "gemini-example",
"output": [],
"output_text": "",
"parallel_tool_calls": true,
"previous_response_id": null,
"reasoning": null,
"temperature": null,
"text": {"format":{"type":"text"}},
"tool_choice": "auto",
"tools": [],
"top_p": null,
"truncation": "disabled",
"max_output_tokens": null,
"max_tool_calls": null,
"service_tier": "auto",
"background": false,
"usage": null
}完成对象可以增加 provider_model 与 provider_finish_reason。completed_at 在 status 为 completed 时为完成时间的 Unix 秒数,其余为 null;service_tier 在生成前为请求值(省略时为 auto),生成后为上游用量报告的服务等级:flex 或 priority,其余为 default。status 为 completed、incomplete 或 failed;长度终态使用 incomplete_details.reason=max_output_tokens,策略终态使用 content_filter。
output item 联合类型:
| type | 字段 |
|---|---|
reasoning |
id、status、summary:[{type:"summary_text",text}]、可选 encrypted_content;摘要文本只在请求 reasoning.summary(或 generate_summary)为 auto、concise、detailed 时返回 |
message |
id、status、role:"assistant"、content:[{type:"output_text",text,annotations}] |
function_call |
id、status、call_id、name、arguments |
custom_tool_call |
id、status、call_id、name、input,可选 namespace |
local_shell_call |
id、status、call_id、action:{type:"exec",command,env,...} |
shell_call |
id、status、call_id、action:{commands,timeout_ms,max_output_length}、environment:null |
apply_patch_call |
id、status、call_id、operation:{type,path,diff} |
code_interpreter_call |
id、status、code、container_id:"aistudio"、outputs:[{type:"logs",logs}];include 不含 code_interpreter_call.outputs 时 outputs 为 null |
image_generation_call |
id、status、Base64 result |
web_search_call |
id、status、action |
output 按生成顺序排列:相邻的思考并入同一 reasoning 项,相邻的正文并入同一 message 项,被其他输出项隔开的正文分为多个 message 项。请求 include 含 reasoning.encrypted_content 时,函数调用的思考签名写入紧邻其前的 reasoning 项,前一项不是 reasoning 时为单独的 rs_<call_id> reasoning 项。
message 的 url_citation 为 {"type":"url_citation","url","title","start_index","end_index"},按上游正文区间归入所在 message 项,start_index、end_index 为该项文本中的字符下标;上游没有正文区间的来源写入以正文结束的最后一个 message 项,两者为 0。
web_search_call.action 为 {"type":"search","query":"<首个查询>","queries":[...]},上游每个搜索调用步骤在发生处输出一项,queries 为该步骤的查询,grounding 中出现步骤之外的新查询时再新增一项,查询按首次出现去重;请求 include 含 web_search_call.action.sources 时最后一个 search 动作带 sources:[{"type":"url","url":"..."}],来源随末尾的 grounding 到达,按 URI 去重,流式中写在 response.completed 的该项上。GET /v1/responses/{id} 的 include[](也接受 include)与创建时的 include 合并后决定返回的 sources 与 outputs。URL Context 读取的每个网址在读取结果到达时输出一项 web_search_call,action 为 {"type":"open_page","url":"..."},网址按首次出现去重,urlRetrievalStatus 不是 URL_RETRIEVAL_STATUS_SUCCESS 时 status 为 failed,流式中该项没有 response.web_search_call.completed。code_interpreter_call.status 在没有结果时为 incomplete,成功结果为 completed,非 OUTCOME_OK 结果为 failed;stdout 写入 outputs[].logs,失败文本加 stderr: 前缀。流式 output_item.added 使用 in_progress,对应 output_item.done 使用最终状态;流式与非流式的 output 相同,每项 output_item.done 之后才 added 下一项,code_interpreter_call 在执行结果到达时 done。
Responses usage:
{
"input_tokens": 10,
"output_tokens": 20,
"total_tokens": 30,
"input_tokens_details": {"cached_tokens":0,"cache_write_tokens":0},
"output_tokens_details": {"reasoning_tokens":5}
}每个 Responses SSE payload 都包含 type 和从 0 单调递增的 sequence_number:
| 事件 | 事件字段 |
|---|---|
response.created、response.in_progress |
response shell |
response.output_item.added、response.output_item.done |
output_index、item |
response.reasoning_summary_part.added、response.reasoning_summary_part.done |
item_id、output_index、summary_index、part |
response.reasoning_summary_text.delta |
item_id、output_index、summary_index、delta |
response.reasoning_summary_text.done |
上述索引与 text |
response.content_part.added、response.content_part.done |
item_id、output_index、content_index、part |
response.output_text.delta |
item_id、output_index、content_index、delta、logprobs:[] |
response.output_text.done |
上述索引与 text、logprobs:[] |
response.output_text.annotation.added |
item_id、output_index、content_index、annotation_index、annotation |
response.function_call_arguments.delta |
item_id、output_index、delta |
response.function_call_arguments.done |
item_id、output_index、arguments、name |
response.custom_tool_call_input.delta |
item_id、output_index、delta |
response.custom_tool_call_input.done |
item_id、output_index、input |
response.image_generation_call.in_progress、response.image_generation_call.completed |
item_id、output_index |
response.code_interpreter_call.in_progress、response.code_interpreter_call.interpreting、response.code_interpreter_call.completed |
item_id、output_index |
response.code_interpreter_call_code.delta |
item_id、output_index、delta |
response.code_interpreter_call_code.done |
item_id、output_index、code |
response.web_search_call.in_progress、response.web_search_call.searching、response.web_search_call.completed |
item_id、output_index |
response.completed、response.incomplete、response.failed |
完整 response |
声明 web_search 时请求上游返回服务端工具步骤,web_search_call 与正文、代码执行和网址读取按发生顺序输出,正文随到随写。上游在正文后失败时,已产生的 delta 按原顺序位于 response.failed 之前,response.failed 的 output 为已写出的输出项。
上下文压缩:
POST /v1/responses/compact为无状态端点,接受model(必需)、input、instructions、tools与previous_response_id;input的转换、item_reference、媒体与续接链同POST /v1/responses- 压缩先在续接链与输入的条目中确定原样保留部分:从最新条目向前,以完整的模型侧条目组(reasoning、assistant 消息与各类调用,连同其后的工具输出)或 user 消息为单位累计,约 20000 token 内的部分原样保留,最新一组总是保留,切点不落在工具输出上;token 按每 4 字节 1 个估算,消息只计文本、每张图片计 765,其他条目不计
encrypted_content - 原样保留部分之前的条目去掉 developer 与 system 消息后由请求的模型非流式生成摘要,去掉后没有条目时不调用上游、摘要为空:系统指令与工具同请求,
tool_choice为none,末尾追加一个 user 轮,为 OMP 的结构化交接摘要提示词(Goal、Constraints & Preferences、Progress、Key Decisions、Next Steps、Critical Context、Additional Notes);输入已含 compaction 项时,只摘要其原样条目与之后的新条目,旧摘要以<previous-summary>包裹作为首个 user 轮,末尾改用增量摘要提示词;没有需要摘要的条目时不调用上游;摘要的结束原因不是stop时返回错误 - compaction 项为
{"id":"cmp_...","type":"compaction","encrypted_content":"<明文 JSON>"},encrypted_content为{"v":1,"summary":"<摘要>","items":[<原样保留的条目>]},条目保持输入原文,含 reasoning 的encrypted_content思考签名与调用 ID - compact 响应为
{"id":"resp_...","object":"response.compaction","created_at":0,"output":[...],"usage":{...}};output先是原样保留部分之前的 user 消息:从最新向前累计到 64000 token,跨预算的一条只保留首尾文本并在中间写入…N tokens truncated…,跳过以<environment_context>、<user_instructions>、<additional_context>、<skills、<token_budget>、<model_switch>开头的上下文消息;最后是 compaction 项;usage为生成摘要的用量,不调用上游时各项为 0 - 输入中的 compaction 项只展开最后一个:其前的条目保留,与原样条目中 user 消息文本相同的 user 消息各去掉一条,更早的 compaction 项丢弃;之后依次接摘要 user 轮(
Prior model work/tool state available.、MUST build on prior work; NEVER duplicate prior work.与<summary>包裹的摘要)、原样条目与 compaction 项之后的条目;encrypted_content不是本服务生成的 JSON 时返回 400 POST /v1/responses以compaction_trigger结尾时按 compact 的方式压缩,响应output只有一个 compaction 项,output_text为空;流式事件依次为response.created、response.in_progress、response.output_item.added(encrypted_content:"")、response.output_item.done与response.completed,调用上游生成摘要时带 usage;保存的响应不接续前序节点,续接上下文为 compact 输出的条目展开后的内容
POST /v1/messages 请求字段:
| 字段 | 类型与语义 |
|---|---|
model |
必需模型 ID |
messages |
{role,content} 数组,role 为 user、assistant、system |
system |
string 或 text block 数组 |
max_tokens |
正整数,省略时使用模型默认输出上限 |
stop_sequences |
string array |
stream |
boolean |
temperature、top_p、top_k |
生成参数 |
tools、tool_choice |
custom/server tools、Anthropic 定义的客户端工具与 auto/none/any/named tool |
thinking |
{type:"enabled",budget_tokens:<INT>}、{type:"adaptive"} 或 {type:"disabled"},可选 display:"summarized" 或 "omitted" |
output_config |
{effort?:"...",format?:{type:"json_schema",schema}} |
context_management |
{edits:[...]},见下文上下文管理 |
system消息以<system-reminder>包裹并入相邻的用户内容:前一条为 user 时追加在其末尾,否则并入下一条 user 消息、排在其tool_result之后,使函数调用之后紧跟函数结果system消息中的tool_addition与tool_removal块按出现顺序增删声明的工具:tool_reference按name引用tools中的工具(含defer_loading工具,tools中的工具都声明给上游),tool_definition的definition加入工具列表,tool_removal移除同名工具output_config.format的json_schema设置结构化输出,其他 type 返回400 invalid_request_errorthinking.display:"omitted"时 thinking block 的正文为空,签名照常返回
message content 可以是 string 或 block 数组:
| block type | 字段 |
|---|---|
text |
text |
thinking |
thinking、signature |
redacted_thinking |
data |
image、document |
source:{type,media_type,data,url,file_id,content};document 的 title 为附件给模型的名称,context 作为文档之前的文本 |
tool_use |
id、name、object input |
tool_result |
tool_use_id、content、is_error |
server_tool_use、mcp_tool_use |
id、name、input,mcp_tool_use 另有 server_name |
web_search_tool_result |
tool_use_id、content:[{type:"web_search_result",url,title,encrypted_content,page_age}] 或 {type:"web_search_tool_result_error",error_code} |
search_result |
source、title、content |
web_fetch_tool_result |
tool_use_id、content:{type:"web_fetch_result",url,content:<document>} 或错误对象 |
code_execution_tool_result、bash_code_execution_tool_result、text_editor_code_execution_tool_result、tool_search_tool_result、advisor_tool_result、mcp_tool_result |
tool_use_id、content |
compaction |
content、encrypted_content |
container_upload |
file_id |
image / document 的 Base64 source 使用 type:"base64"、media_type、data;URL source 使用 type:"url" 与非空 url,YouTube 链接作为视频引用,其他 http(s) URL 由服务下载为内联媒体,规则与 GenerateContent 的 fileData 相同。document 的 type:"text" source 以 data 作为文本,type:"content" source 按原顺序展开字符串或 content block;type:"file" source 与 container_upload 以 file_id 引用 /v1/files 上传的文件。服务端工具历史块在原位置以文本续接:server_tool_use 与 mcp_tool_use 写为工具名与 input,web_fetch_tool_result 写为 URL 并展开其中的 document,抓取失败时写为错误码,search_result 写为标题、来源与正文,其余工具结果写为 block type 与 content JSON。code_execution_tool_result 的 code_execution_tool_result_error 在 error_code 为 execution_time_exceeded 时回传为超时,其他错误码回传为失败并以错误码作为输出。tool_result.is_error=true 把合法 JSON content 包装为 {"error":<CONTENT>};普通标量或数组结果包装为 {"result":<CONTENT>}。
custom tool 为 {name,description,input_schema},可选 type:"custom"。server tool 字段:
| type | 必需 name |
|---|---|
web_search_* |
web_search |
image_search |
image_search |
web_fetch_* |
web_fetch |
code_execution_* |
code_execution |
url_context |
url_context |
google_maps |
google_maps |
web_search_* 的 allowed_domains、blocked_domains 与 user_location 写入搜索偏好,域名限制使用 site: 与 -site: 查询;web_fetch_* 的 allowed_domains 与 blocked_domains 作为读取 URL 的域名范围(含子域名)写入系统指令;调用次数由上游决定,其余选项不改变上游请求。bash_*、text_editor_*、memory_* 以请求中的 name 声明为函数,描述与参数由服务固定,参数分别为 {command,restart}、{command,path,file_text,old_str,new_str,insert_line,insert_text,view_range}(text_editor_20241022 与 text_editor_20250124 的 command 另含 undo_edit)与再加 old_path、new_path 的 memory 命令,模型调用以 tool_use 返回由客户端执行;computer_20241022、computer_20250124、computer_20251124 同样以 name 声明为函数,说明写明 display_width_px×display_height_px 的屏幕尺寸(缺少时返回 400 invalid_request_error),参数为 action、coordinate、start_coordinate、text,action 取 key、type、mouse_move、left_click、left_click_drag、right_click、middle_click、double_click、screenshot、cursor_position,computer_20250124 起另有 triple_click、left_mouse_down、left_mouse_up、scroll、hold_key、wait 与参数 scroll_direction、scroll_amount、duration、key,enable_zoom:true 时另有 zoom 与参数 region;tool_search_tool_*、advisor_* 与类型名含 toolset 的工具不声明到上游。
请求级 mcp_servers:[{type:"url",name,url,authorization_token?,tool_configuration?:{enabled?,allowed_tools?}}] 作为上游 MCP 服务器,authorization_token 以 Authorization: Bearer 发送,enabled:false 的服务器不发送;mcp_toolset 的 mcp_server_name 必须是其中的服务器,default_config 与 configs 按工具启用情况得出允许列表,默认启用而单独停用部分工具时服务经出口代理读取该服务器的 tools/list,允许全集中未停用的工具,tools/list 失败返回 400 并说明原因。上游的 MCP 调用输出为 mcp_tool_use(server_name、name、input)与 mcp_tool_result(is_error、content)块。
上下文管理 context_management.edits 按数组顺序执行,token 数用内嵌 Gemma 3 分词模型在本地估算:
| edit type | 处理 |
|---|---|
clear_thinking_20251015 |
去掉最近 keep.value 个思考轮之前的思考块 |
clear_tool_uses_20250919 |
超过 trigger 时把较早的工具结果替换为 [cleared] |
compact_20260112 |
超过 trigger.value 时以摘要替换全部历史 |
clear_thinking_20251015:keep为{type:"thinking_turns",value:N}时,最近 N 个带thinking或redacted_thinking的 assistant 轮之前的这两类块从历史中去掉,其思考签名不发给上游;省略keep、"all"与{type:"all"}保留全部clear_tool_uses_20250919:trigger默认{type:"input_tokens",value:100000},tool_uses按历史中的工具调用次数计;超过时保留最近keep.value(默认 3)次调用,更早且不在exclude_tools中的调用,tool_result与mcp_tool_result的 content 替换为[cleared],其余服务端工具结果替换为[cleared]text block;clear_tool_inputs为 true 或包含该工具名时调用的 input 改为{};清理的 token 少于clear_at_least.value时不清理compact_20260112:输入超过trigger.value(默认 150000)时,请求的模型以instructions非流式生成摘要,省略时使用官方文档的摘要提示词,tool_choice为 none;摘要以<summary>包裹时取其中的文本,与 Responses 相同的摘要 user 轮替换全部历史后继续生成。响应 content 首个 block 为{type:"compaction",content:<摘要>,encrypted_content:null},pause_after_compaction:true时只返回该块,stop reason 为compaction- 未知 edit type 与
keep、trigger形状返回400 invalid_request_error - 带
context_management时,非流式响应与流式message_delta输出context_management:{applied_edits:[...]},列出实际清理的编辑及其cleared_tool_uses或cleared_thinking_turns与cleared_input_tokens;带compact_20260112时usage.iterations依次为压缩与生成的{type,input_tokens,output_tokens,cache_creation_input_tokens,cache_read_input_tokens},暂停时只有压缩一项、顶层 input 与 output 为 0 - 输入中最后一个
compaction块之前的全部消息与块被丢弃,其content写为摘要 user 轮,块之后的内容照常续接 count_tokens执行清理编辑、不触发压缩,带context_management时另返回context_management:{original_input_tokens},为清理前的计数
server tool 接受对应 type、name 与任意工具选项(如 Claude Code WebSearch 的 search_profile);带 description 或 input_schema 时返回 400 invalid_request_error。tool choice 接受省略、{"type":"auto"}、{"type":"none"}、{"type":"any"} 与 {"type":"tool","name":"FUNCTION_NAME"}。custom tool 的 cache_control 等客户端提示保留生成能力,strict:true 校验完整返回参数。
非流式响应:
{
"id": "msg_...",
"type": "message",
"role": "assistant",
"model": "gemini-example",
"content": [
{"type":"thinking","thinking":"...","signature":"..."},
{"type":"text","text":"...","citations":null},
{"type":"tool_use","id":"call_01","name":"get_weather","input":{}}
],
"stop_reason": "end_turn",
"stop_sequence": null,
"stop_details": null,
"usage": {"input_tokens":10,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":20,"server_tool_use":null,"service_tier":"standard","inference_geo":null},
"container": null,
"provider_model": "gemini-provider-id",
"provider_finish_reason": "provider_19"
}stop_details、container 与 usage.inference_geo 为 null;usage.server_tool_use 在发生网页搜索或网址读取时为 {web_search_requests,web_fetch_requests},其余为 null;usage.service_tier 在上游用量报告 priority 时为 priority,其余为 standard。text block 带 citations,没有引用时为 null。
content 输出 block 为 text、thinking、redacted_thinking、tool_use、server_tool_use、web_search_tool_result 或 compaction;thinking block 总带 signature,签名不在该 block 上时为空字符串。stop reason 为 end_turn、tool_use、stop_sequence、max_tokens、pause_turn、compaction 或 refusal。POST /v1/messages/count_tokens 接受同一 message/system/tools 输入并返回 {"input_tokens":<INT>};它提供独立计数估算,PDF 等媒体请求的最终用量以生成响应 usage.input_tokens 为准。
Anthropic 响应中的媒体编码为 text block 中的 Markdown 链接,MEDIA_OUTPUT=inline 时为 data URL,url 时为本服务的 /media/<文件名> URL,代码编码为 fenced text。Google Search 的每个去重查询生成一组 server_tool_use 和 web_search_tool_result,结果按 URL 去重,来源集合覆盖本次搜索的全部查询。声明 web_search 时请求上游返回服务端工具步骤,每组搜索块位于对应搜索调用步骤之后;来源随上游末尾的 grounding 到达,流式响应中开头思考之后的块等到 grounding 到达后按发生顺序写出,等待期间发送 ping。usage.server_tool_use.web_search_requests 记录上游报告的去重查询数。grounding 中带正文区间的来源把搜索回答拆成多个 text block:被来源支撑的区间单独成块,citations 为 [{"type":"web_search_result_location","url","title","encrypted_index","cited_text"}],cited_text 为该区间的回答正文,encrypted_index 与 encrypted_content 同样由本服务加密;其余正文的 citations 为 null。流式响应中带引用的块在 content_block_start 之后先以 citations_delta{citation} 逐条给出引用,再写出正文。URL Context 读取的每个网址按首次出现生成一组 server_tool_use(name:"web_fetch"、input:{"url":...})和 web_fetch_tool_result:读取成功时 content 为 {"type":"web_fetch_result","url":...,"retrieved_at":null,"content":{"type":"document","source":{"type":"text","media_type":"text/plain","data":""}}},上游不返回网页正文;URL_RETRIEVAL_STATUS_UNSAFE 为 {"type":"web_fetch_tool_result_error","error_code":"url_not_allowed"},URL_RETRIEVAL_STATUS_ERROR 与 URL_RETRIEVAL_STATUS_PAYWALL 为 url_not_accessible,其余状态为 unavailable;web_fetch_requests 为读取的网址数。其余引用在末尾追加 Sources: Markdown 列表。
搜索来源的 encrypted_content 由本服务生成,保存上游返回的 URL、标题与可用摘要。客户端回传的搜索块以文本续接:查询写为 Web search: <query>,配对结果追加到同一文本,每个来源写标题与 URL,能用当前 PROXY_API_KEY 解开的 encrypted_content 追加摘要;来自 Anthropic 服务或以其他 PROXY_API_KEY 生成的来源只保留标题与 URL。错误结果写为 Web search failed: <error_code>;没有配对调用的结果与没有结果的调用(pause_turn 续接)分别单独成文。该字段用于本服务的多轮会话,和 Anthropic 服务的来源令牌分别使用。
Anthropic SSE:
| 事件 | payload |
|---|---|
message_start |
{type,message:{id,type,role,content:[],model,stop_reason:null,stop_sequence:null,stop_details:null,usage:{input_tokens,cache_creation_input_tokens,cache_read_input_tokens,cache_creation,output_tokens,server_tool_use,service_tier,inference_geo},container:null}} |
ping |
{type:"ping"} |
content_block_start |
{type,index,content_block} |
content_block_delta |
{type,index,delta} |
content_block_stop |
{type,index} |
message_delta |
{type,delta:{stop_reason,stop_sequence,provider_finish_reason?},usage,context_management?} |
message_stop |
{type:"message_stop"} |
error |
{type:"error",error:{type,message}} |
delta 联合类型为 text_delta{text}、citations_delta{citation}、thinking_delta{thinking}、signature_delta{signature}、input_json_delta{partial_json}、compaction_delta{content,encrypted_content}。compaction block 在 message_start 之后以 index 0 输出,content_block_start 的 content 为 null,一个 compaction_delta 带完整摘要。thinking block 的 content_block_start 带 thinking:"" 与 signature:"",signature 在该 block 关闭前以 signature_delta 发送;redacted thinking 使用一个 start/stop block;tool_use 先发送空 input,再通过 input_json_delta 发送完整参数 JSON。搜索块在来源汇总后以完整的 start/stop block 输出,查询计数随最终 message_delta.usage 返回。
POST /v1beta/interactions 与 POST /v1/interactions 接受同一创建请求,通过 x-goog-api-key、Bearer 或 key 查询参数认证。
{
"model": "gemini-3.8-flash-tts",
"input": [{"type":"user_input","content":[{
"type":"text","text":"Have a wonderful day!",
"annotations":[{"type":"speech_metadata","style":"cheerful and friendly"}]
}]}],
"response_format": {"type":"audio","mime_type":"audio/l16","sample_rate":24000},
"generation_config": {"speech_config":[{"voice":"Kore"}]},
"stream": true
}| 字段 | 映射 |
|---|---|
input |
字符串、单个内容块、内容块数组或步骤数组;内容类型为 text、image、audio、video、document |
| 媒体内容 | data(Base64)或 uri,可选 mime_type;图片与视频可选 resolution:low、medium、high、ultra_high;音频可选 sample_rate、channels;文档可选 name 作为附件文件名 |
| 视频处理 | processing:"static"、"agentic" 或 {type:"static",start_offset?,end_offset?,fps?};offset 为带 s 的 Duration 字符串,例如 "2.5s" |
| 输入步骤 | user_input、model_output、thought、function_call、function_result、code_execution_call、code_execution_result 与工具 call/result 步骤;function_call 的 signature 或其前 thought 步骤的 signature 作为该调用的思考签名 |
system_instruction |
当前请求的系统指令 |
generation_config |
temperature、top_p、top_k、max_output_tokens、seed、stop_sequences、thinking_level、thinking_summaries、speech_config、tool_choice、image_config:{aspect_ratio?,image_size?}、transcription_config |
response_format |
单对象或数组:{type:"text",mime_type?,schema?}、JSON Schema 对象、{type:"image",mime_type?,aspect_ratio?,image_size?}、{type:"audio",mime_type?,sample_rate?,bit_rate?,delivery?}、{type:"video",aspect_ratio?,duration?,resolution?} |
response_modalities |
text、image、audio、video 的数组;前三项对应 Gemini 输出模态,video 见 Omni Interaction |
response_mime_type |
text/plain 或 application/json |
safety_settings |
[{type,threshold}],取值为小写的类别与阈值枚举名,如 harassment、block_low_and_above |
| 语音配置 | speech_config:[{voice,language?}] 或 {speakers:[{speaker,voice}],mode?} |
| 语音文本 | 文本块 annotations 中的 {type:"speech_metadata",speaker?,style?} |
| 函数与工具 | tools:[{type:"function",name,description?,parameters?}] 与内置工具;tool_choice 为 auto、any、none、validated 或 {allowed_tools:{mode?,tools}} |
| 内置工具 | {type:"google_search",search_types?}、{type:"google_maps",latitude?,longitude?,enable_widget?}、{type:"computer_use",environment?,excluded_predefined_functions?}、{type:"mcp_server",name,url,headers?,allowed_tools?}、{type:"file_search",file_search_store_names,metadata_filter?,top_k?}、url_context、code_execution |
| 请求设置 | service_tier、labels、cached_content |
agent |
model 为空时作为模型 ID,用于 Deep Research 等代理 |
agent_config |
{type:"antigravity",model?,max_total_tokens?},max_total_tokens 为字符串或数字;{type:"deep-research",thinking_summaries?,visualization?,collaborative_planning?},thinking_summaries 为 auto 或 none,visualization 为 auto 或 off;type 与 agent 的种类不一致或取值不在上述范围时返回 400 INVALID_ARGUMENT |
| 续接 | previous_interaction_id、store |
- 媒体内容的
data与uri二选一,复用 Gemini 文件与内联媒体解析:省略mime_type时内联数据按内容识别类型,无法识别时返回400 INVALID_ARGUMENT;uri为外部 http(s) URL 时由服务下载为内联媒体,规则与 GenerateContent 的fileData相同;本服务 Gemini 文件接口返回的uri作为文件引用 - 函数结果通过
call_id匹配历史调用,没有对应调用时使用自带的name;is_error:true的结果以{"error":<result>}发送上游;code_execution_call与code_execution_result以代码块文本并入模型轮次;google_search、url_context、google_maps、file_search与mcp_server_tool的 call 与 result 步骤作为服务端工具 Part 发送上游,retrieval步骤不发送 processing_call和processing_result保留服务端媒体处理调用的id、对应的call_id与各自的signature,作为模型历史续接;流式响应按step.start、step.delta、step.stop发布,签名位于 delta- 文本
response_format带schema时请求结构化输出,mime_type默认application/json;不带type或type为 JSON Schema 类型的对象直接作为结构化输出 Schema;图片指定mime_type:"image/jpeg"时其他格式的图片输出转为 JPEG response_format中的图片比例与尺寸优先于generation_config.image_config;带response_format时不使用response_mime_type;response_modalities中的其他取值返回400 INVALID_ARGUMENTspeech_config的language不发送上游,多说话人mode为verbatim或conversational;speech_metadata保留说话人与风格google_search.search_types取web_search、enterprise_web_search、image_search,省略时为 web search;google_maps的坐标写入检索位置;computer_use.environment省略时为browser;mcp_server与file_search存在时响应带服务端工具步骤;retrieval不发送上游;tool_choice:"any"要求调用函数,allowed_tools.tools限定可调用的函数transcription_config的timestamp_granularities含word时输出逐词时间,diarization_mode:"speaker"输出说话人,mode:"smart"或{type:"smart"}使用智能转录;转录文本的model_output内容带annotationsservice_tier、labels与 Gemini GenerateContent 的serviceTier、labels相同;cached_content引用显式缓存,缓存不存在或已过期时返回404 NOT_FOUND- MCP 调用输出为
{type:"mcp_server_tool_call",id,name,server_name,arguments},结果为{type:"mcp_server_tool_result",call_id,result},result为 MCP 内容项数组[{type:"text",text}|{type:"image"|"audio",data,mime_type}] - interaction 默认保存;
previous_interaction_id重建前序内容,指向同一 agent 的后台任务时改为以上游 interaction 续接(见后台 Interaction 任务),store:false仅返回本次响应,不能检索或续接;interaction 与 Responses 响应共用最多 256 个保存节点,超出时淘汰最早的节点,服务重启后保留
音频 mime_type 为 audio/wav、audio/l16、audio/mp3、audio/ogg_opus、audio/alaw 或 audio/mulaw,非流式默认 audio/wav,流式默认 audio/l16。TTS 上游为 24 kHz、16-bit 小端、单声道 PCM,Lyria 等返回的 MP3 先解码为 PCM;请求 audio/mp3 且未改采样率、未指定 bit_rate 时原样返回上游 MP3。sample_rate 省略时使用上游采样率,指定时重采样;MP3 取 32、44.1、48 kHz,Ogg Opus 取 8、12、16、24、48 kHz,均为不低于目标采样率的最小值,超出时取最高值。bit_rate 以 bit/s 计,用于 MP3(CBR 32000–320000 取最接近值,默认 192000)与 Opus。输出内容的 mime_type 依次为 audio/wav、audio/l16、audio/mp3、audio/ogg、audio/alaw、audio/mulaw,sample_rate 与 channels 为实际值。上游为 PCM 且不重采样时,audio/l16、audio/alaw、audio/mulaw 逐块输出,其余情况在音频汇总完成后发送一个完整块。请求同时含文本与音频而模型只能生成文本时按文本生成。delivery 取任意值时都内联返回。创建请求在当前连接内执行;非流式 background:true 时先返回 in_progress 的 interaction 并关闭连接,生成在服务内继续,终态可经检索读取。
webhook_config:{uris,user_metadata} 随 background:true 使用,否则返回 400 INVALID_ARGUMENT,uris 为 http 或 https 地址。后台交互结束时服务向每个地址 POST {type,version:"v1",timestamp,data:{id},user_metadata},请求头带 webhook-id 与 webhook-timestamp:type 按终态为 interaction.completed(含 incomplete)、interaction.requires_action、interaction.failed(data 另有 error_code 与 error_message)或 interaction.cancelled;应答不是 2xx 或 10 秒内没有应答时,从 1 秒起按倍数退避(间隔最长 1 小时)重试 24 小时。
非流式响应包含 id、object:"interaction"、model、created、updated、status、steps 与 usage,以 previous_interaction_id 续接时同时带该字段。steps 的 model_output.content 保存文本或媒体,带引用的文本内容含 annotations,每项为 {type:"url_citation",url,title,start_index,end_index},下标为该段文本中的字节位置;音频位于 {type:"audio",data,mime_type,sample_rate,channels};SDK 的 output_audio 与 output_text 从这些步骤读取。正文、图片与函数调用携带的思考签名作为其前 thought 步骤的 signature 输出,按步骤回传时签名回到其后第一个模型 Part。函数调用作为 function_call 步骤返回,状态为 requires_action;正常生成与命中停止序列的状态为 completed,输出限额与内容拦截的状态为 incomplete。usage 包含 total_input_tokens、total_cached_tokens、total_output_tokens、total_thought_tokens、total_tool_use_tokens 与 total_tokens;上游给出模态细分时另有 input_tokens_by_modality、cached_tokens_by_modality、output_tokens_by_modality、tool_use_tokens_by_modality,元素为 {modality,tokens},modality 为小写模态名;使用 Google Search 或 Google Maps 时 grounding_tool_count 按 {type:"google_search"|"google_maps",count} 给出调用次数。
SSE 使用相同的事件名与 JSON event_type:interaction.created → step.start → step.delta → step.stop → interaction.completed。background:true 的流式与后台生成写入事件记录,每个事件带从 1 递增的 event_id;客户端断开后生成继续,GET 带 stream=true 与 last_event_id 从下一个事件继续读取。步骤以 index 对应,引用在其所在文本之后以 {type:"text_annotation_delta",annotations} 增量输出,音频增量为 {type:"audio",data,mime_type,sample_rate,channels}。10 秒无语义事件时发送 : ping,上游错误或缺失终态发送 error 事件并结束;客户端断开会取消上游生成。流开始前使用 Gemini HTTP 错误对象。
GET /v1beta/interactions/{id} 返回创建时的完整 interaction;include_input=true 时 steps 先列出请求输入,字符串与连续的内容块合并为 user_input 步骤;stream=true 时,background:true 创建的 interaction 从其事件记录输出:生成进行中时跟随到 interaction.completed 或 error,结束后输出完整记录;其他 interaction 按创建流的事件格式重放保存的内容。两种输出的每个事件都带递增的 event_id,查询参数 last_event_id 从其后的事件继续,不是正整数时返回 400 INVALID_ARGUMENT。POST /v1beta/interactions/{id}/cancel 返回该 interaction 的终态对象。DELETE /v1beta/interactions/{id} 返回 {},之后检索返回 404 NOT_FOUND,作为 previous_interaction_id 或 Responses 的 previous_response_id 返回 400。/v1 前缀行为相同。
POST /v1/embeddings 请求字段为 model、input,可选 dimensions、encoding_format。input 是字符串或字符串数组,token 数组与空数组返回 400;dimensions 为正整数,写入每条请求的 outputDimensionality;encoding_format 为 float(默认)或 base64,base64 为小端 float32。响应为 {"object":"list","data":[{"object":"embedding","index":0,"embedding":[...]}],"model":"<MODEL>","usage":{"prompt_tokens":N,"total_tokens":N}}。
:embedContent 接受 content、taskType、title、outputDimensionality,返回 {"embedding":{"values":[...]},"usageMetadata"?:{"promptTokenCount"}}。:batchEmbedContents 接受 requests[],每项字段相同并可带与路径一致的 model,返回 {"embeddings":[...],"usageMetadata"?:{"promptTokenCount"}};promptTokenCount 为上游 tokenCount,上游没有时省略。字段同时接受 snake_case;缺 content 或 model 与路径不一致时返回 400 INVALID_ARGUMENT。
三个端点都经 Build 通道调用上游 batchEmbedContents,超过 100 条时按顺序分批并合并结果,上游 tokenCount 计为输入 token。Build 未启用或没有可调用账户时返回 404 model_not_found / NOT_FOUND。
POST /v1beta/models/{model}:generateContent、:streamGenerateContent 与 :countTokens 接受:
{
"contents": [{"role":"user","parts":[{"text":"Hello"}]}],
"systemInstruction": {"role":"user","parts":[{"text":"Be concise"}]},
"generationConfig": {},
"tools": [],
"toolConfig": {},
"safetySettings": [{"category":"HARM_CATEGORY_HARASSMENT","threshold":"BLOCK_ONLY_HIGH"}]
}请求体各层消息字段同时接受 proto 字段名与 lowerCamelCase 名,例如 system_instruction、generation_config.response_mime_type、tools[].function_declarations、tool_config.function_calling_config 和 function_call;同一层两种写法并存时使用驼峰字段。functionCall.args、functionResponse.response、parameters、parametersJsonSchema、responseSchema、responseJsonSchema 与 partMetadata 的取值按原样使用,其中的键名不转换。
Content 字段为 role 与 parts。Part oneof:
| Part | 字段 |
|---|---|
| text/thought | text、可选 thought、thoughtSignature |
| inline data | inlineData:{mimeType,data,displayName?} |
| file data | fileData:{mimeType?,fileUri,displayName} |
| function call | functionCall:{id,name,args} |
| function response | functionResponse:{id,name,response} |
| server tool call | toolCall:{id?,toolType,toolName?,args?} |
| server tool response | toolResponse:{id?,toolType?,response?} |
| executable code | executableCode:{language,code} |
| code result | codeExecutionResult:{outcome,output,error} |
服务端工具步骤的 toolType 为 GOOGLE_SEARCH_WEB、URL_CONTEXT、GOOGLE_MAPS、MEDIA_PROCESSING 或 MCP 调用的 CUSTOM;MCP 调用的 toolName 为 <服务器名>:<工具名>,MCP 结果的 response.call_tool_result_json 为 MCP CallToolResult 的 JSON 文本。媒体 Part 可带 mediaResolution:{level},level 为 MEDIA_RESOLUTION_LOW、MEDIA_RESOLUTION_MEDIUM、MEDIA_RESOLUTION_HIGH 或 MEDIA_RESOLUTION_ULTRA_HIGH;各 Part 分辨率不同或与 generationConfig.mediaResolution 不同时请求经 Build 通道发送,Playground 通道使用所有 Part 共同的分辨率。inlineData.displayName 与 fileData.displayName 作为附件文件名发送,代码执行按该文件名读取附件。
不含数据字段且没有 thoughtSignature 的 Part 不发送;同一 Part 含多个数据字段时返回 400 INVALID_ARGUMENT。fileData.fileUri 为 YouTube 链接时作为外部视频,为本服务 /upload/v1beta/files 返回的文件 URI 或 /v1/files 文件 ID 时作为文件引用,为其他 http(s) URL 时由服务下载为内联媒体;其他 Gemini Files API URI 不下载。外部 URL 在同一请求内只下载一次,上限 512 MiB,MIME 依次取响应 Content-Type、mimeType 与内容识别;主机或任一重定向目标解析到本机、私网、链路本地、组播或未指定地址时不连接,按下载失败处理;下载失败返回带 URL 与原因的 400 INVALID_ARGUMENT。:countTokens 同样先下载外部 URL 再计数。
视频 Part 可设置 mediaProcessing 为 STATIC、AGENTIC 或 MEDIA_PROCESSING_UNSPECIFIED。省略时沿用模型默认处理方式。AGENTIC 使用模型目录的 agentic_video 能力,并返回 toolType:"MEDIA_PROCESSING" 的服务端 toolCall 与 toolResponse;调用标识与 thoughtSignature 随完整模型 Part 一起用于下一轮历史。
静态视频的 videoMetadata 可设置 startOffset、endOffset 与 fps,与该 Part 的视频附件一起参与生成及 token 计数。offset 为非负秒数 Duration 字符串,支持最多九位小数,例如 "2.5s";显式 "0s" 保留起点,终点须晚于起点。FPS 范围为 (0,24],静态参数与 AGENTIC 互斥。例如:
{
"fileData": {"mimeType":"video/*","fileUri":"https://www.youtube.com/watch?v=<VIDEO_ID>"},
"mediaProcessing": "STATIC",
"videoMetadata": {"startOffset":"2s","endOffset":"4s","fps":0.5}
}这些参数与媒体处理历史适用于上游使用 GenerateContent 的模型;使用原生 CreateInteractionStream 或 CreateInteraction 的模型收到这些参数时返回参数错误。
generationConfig 全字段:
| 类别 | 字段 |
|---|---|
| sampling | temperature、topP、topK、frequencyPenalty、presencePenalty、seed |
| media | mediaResolution:MEDIA_RESOLUTION_LOW、MEDIA_RESOLUTION_MEDIUM、MEDIA_RESOLUTION_HIGH |
| output limits | candidateCount、maxOutputTokens、stopSequences |
| log probabilities | responseLogprobs、logprobs |
| structured output | responseMimeType、responseSchema、responseJsonSchema、responseFormat.text |
| modalities | responseModalities |
| image | imageConfig:{aspectRatio,imageSize}、responseFormat.image |
| audio | responseFormat.audio:{mimeType?,sampleRate?,bitRate?,delivery?} |
| thinking | thinkingConfig:{thinkingBudget,thinkingLevel,includeThoughts} |
| transcription | audioTranscriptionConfig:{languageCodes,customVocabulary,adaptationPhrases,wordTimestamp,diarization,languageAuto,languageHints,mode} |
| civic answers | enableEnhancedCivicAnswers |
| speech | speechConfig |
thinkingConfig.includeThoughts 为 true 时输出 thought:true 的思考 Part,省略或为 false 时不输出思考正文;思考签名照常随 Part 返回,thoughtsTokenCount 照常统计。thinkingConfig.thinkingBudget 为 -1(动态思考)时使用模型默认思考设置,与模型名后缀 (-1) 相同。
responseFormat 取单个对象 {text?,image?,audio?} 或这类对象的数组。text.mimeType 取 application/json、text/plain 或 APPLICATION_JSON、TEXT_PLAIN,与 text.schema 一起按 responseMimeType 与 responseJsonSchema 发送;image.aspectRatio 取 ASPECT_RATIO_SIXTEEN_BY_NINE 这类枚举名或 16:9,image.imageSize 取 IMAGE_SIZE_FIVE_TWELVE、IMAGE_SIZE_ONE_K、IMAGE_SIZE_TWO_K、IMAGE_SIZE_FOUR_K 或 512、1K、2K、4K,按 imageConfig 发送;audio 决定输出音频的编码。image.mimeType 只有 IMAGE_JPEG,与上游图片输出相同。image.delivery 或 audio.delivery 为 URI 时,对应的输出图片或音频上传为 Files API 文件,候选 Part 为 {"fileData":{"mimeType","fileUri":"https://generativelanguage.googleapis.com/v1beta/files/<id>"}},文件按 GET /v1beta/files/{id} 查询、按 :download 下载,也可直接作为后续请求的 fileData.fileUri;音频以 URI 交付时流式请求同样在结束时输出一个合并的音频;其他取值内联返回。上传失败时以该错误结束生成。
responseJsonSchema 与 responseFormat.text.schema 原样作为 JSON Schema 使用,additionalProperties、prefixItems、propertyNames、数值枚举与 type:"null" 都保留;含 Playground Schema 无法表达的约束时请求经 Build 通道以 responseFormat.text 发送。responseSchema 按 OpenAPI Schema 子集处理。
responseFormat.audio.mimeType 取 AUDIO_WAV、AUDIO_L16、AUDIO_MP3、AUDIO_OGG_OPUS、AUDIO_ALAW、AUDIO_MULAW,省略时为 AUDIO_WAV,其他取值返回 400 INVALID_ARGUMENT。非流式输出把全部音频合并为一个 inlineData;WAV 为 RIFF WAVE,其他编码的 MIME 带 rate 与 channels 参数,例如 audio/mp3;rate=32000;channels=1。sampleRate 与上游采样率不同时重采样,bitRate 用于 MP3 与 Opus。流式请求中 AUDIO_L16、AUDIO_ALAW、AUDIO_MULAW 在采样率不变时逐块输出,其他格式在结束时输出一个合并的音频块。
audioTranscriptionConfig 的 wordTimestamp 输出逐词时间,diarization 输出说话人,mode:"SMART" 使用智能转录,languageAuto 与 languageHints.languageCodes 设置语言识别。enableEnhancedCivicAnswers 经 Build 通道发送;Playground 通道的非图像请求固定开启该选项。
candidateCount 取省略、0 或 1 至 8;大于 1 时每个候选单独生成,候选 0 沿用请求 ID,候选 i 的请求 ID 为 <id>-<i>,带 seed 时使用 seed+i;任一候选失败时整个请求返回该错误,:streamGenerateContent 在首个候选就绪后开始输出,其余候选的启动错误以流内错误返回;用量的 promptTokenCount 与 cachedContentTokenCount 按一次计,候选输出与思考 token 为各候选之和。frequencyPenalty、presencePenalty、responseLogprobs 与 logprobs 接受任意值,不发送上游,响应不含 logprobs。
responseModalities 接受 TEXT、IMAGE、AUDIO、VIDEO 与 MODALITY_UNSPECIFIED,MODALITY_UNSPECIFIED 不发送,只含该值时按省略处理,VIDEO 按 Omni Interaction 的视频输出格式处理;请求的模态先与模型可生成的模态取交集:TTS 与音乐模型为 AUDIO,图像模型为 IMAGE、TEXT,其他模型为 TEXT;没有交集时保持原样,此时 AUDIO 与其他模态同时出现返回参数错误。图像模型省略模态时发送 [IMAGE,TEXT],仅请求 IMAGE 时发送 [IMAGE];imageConfig 保留显式宽高比与尺寸,支持输出分辨率的模型省略图片配置时使用 1K。
speechConfig.voiceConfig 与 multiSpeakerVoiceConfig 互斥;单声音必须提供 prebuiltVoiceConfig.voiceName,每个多说话人条目必须提供非空 speaker 与 voiceConfig.prebuiltVoiceConfig.voiceName;multiSpeakerVoiceConfig.mode 可选 VERBATIM 或 CONVERSATIONAL。文本 part 的 speechMetadata(或 speech_metadata){speaker,style} 写入 Part field 41。能力码 85 的模型把未带 speaker 的文本按行拆分,以配置中说话人名加冒号开头的行开始新分段,续行并入上一分段,首个说话人行之前的文本不发送;没有匹配行的文本原样发送。旧 TTS 模型把 speechMetadata 写回 speaker: 台词 前缀与 style\n\n 说明段落。audioTranscriptionConfig.mode:"SMART" 与 wordTimestamp 或 diarization 互斥;language code detect 归一为空自动检测。
单声音 speech config:
{"voiceConfig":{"prebuiltVoiceConfig":{"voiceName":"Kore"}}}多说话人:
{
"multiSpeakerVoiceConfig": {
"speakerVoiceConfigs": [{
"speaker": "Speaker A",
"voiceConfig": {"prebuiltVoiceConfig":{"voiceName":"Kore"}}
}]
}
}tool group 字段:
| 工具 | 字段 |
|---|---|
| functions | functionDeclarations:[{name,description,parameters,parametersJsonSchema,response,responseJsonSchema}] |
| search | googleSearch 或 googleSearchRetrieval |
| URL | urlContext |
| code | codeExecution |
| maps | googleMaps:{enableWidget?} |
| image search | imageSearch |
| computer use | computerUse:{environment,excludedPredefinedFunctions?,disabledSafetyPolicies?,enablePromptInjectionDetection?} |
| MCP | mcpServers:[{name,streamableHttpTransport:{url,headers?,timeout?,sseReadTimeout?,terminateOnClose?}}] |
| file search | fileSearch:{fileSearchStoreNames,metadataFilter?,topK?} |
response 与 responseJsonSchema 描述函数返回值,经 Build 通道以 responseJsonSchema 发送,Playground 通道没有对应字段。googleSearch.searchTypes 可以包含 webSearch 与 imageSearch 空对象;未提供或两项均未启用时默认 web search。googleMaps.enableWidget 为 true 时 groundingMetadata 带 googleMapsWidgetContextToken;toolConfig.retrievalConfig:{latLng:{latitude,longitude},languageCode} 为地图与搜索提供位置与语言。computerUse.environment 为 ENVIRONMENT_BROWSER 或省略时两个通道都可使用,其他环境、disabledSafetyPolicies 与 enablePromptInjectionDetection 经 Build 通道发送。MCP 服务器由上游连接并调用,toolConfig.includeServerSideToolInvocations:true 时响应带 toolType:"CUSTOM" 的调用与结果 Part。fileSearch 按原样经 Build 通道发送,上游拒绝时返回上游错误。timeRangeFilter.startTime/endTime 使用 RFC 3339 Nano。googleSearchRetrieval 映射为 web search,dynamicRetrievalConfig 不发送上游。tool choice 位于 toolConfig.functionCallingConfig:{mode,allowedFunctionNames},接受 AUTO、NONE、ANY、VALIDATED 与按 AUTO 处理的 MODE_UNSPECIFIED;allowedFunctionNames 使用已声明函数的子集。
:countTokens 也接受把生成请求放在 generateContentRequest(或 generate_content_request)中的包装形式,按其中的 contents、systemInstruction 与 tools 计数。
systemInstruction 的各文本 Part 作为系统指令的独立分段发送,图片与文件 Part 移到首个 user 轮开头,函数调用与函数结果各以 Gemini API JSON 文本(如 {"functionCall":{"args":{"city":"Paris"},"name":"get_weather"}})作为一个分段。
serviceTier 取 standard、flex、priority,store:false 与 labels 经 Build 通道发送;safetySettings 中的 HARM_CATEGORY_JAILBREAK 同样经 Build 通道发送。Build 通道响应的 usageMetadata.serviceTier 为上游实际使用的等级。
cachedContent 引用本服务 cachedContents 接口创建的显式缓存:缓存的系统指令、内容与工具排在请求之前,请求未设置工具调用方式时沿用缓存的 toolConfig。缓存不存在或已过期时生成、计数与 Interactions 请求返回 404 NOT_FOUND,不发送上游。
:countTokens 返回:
{"totalTokens": 20, "systemInstructionsTokens": {"partTokens": [4]}, "contentTokens": [{"partTokens": [2], "roleTokens": 1}, {"partTokens": [1], "roleTokens": 1}, {"partTokens": [7, 3], "roleTokens": 1}], "promptTokensDetails": [{"modality":"TEXT","tokenCount":20}]}systemInstructionsTokens.partTokens 为系统指令各 Part 的 token 数,没有系统指令时为 {};contentTokens 按请求顺序列出各 content 的 partTokens 与 roleTokens;带工具时 toolTokens 按请求顺序列出各工具,函数声明工具为 {functionDeclarationTokens},其他工具为 {}。promptTokensDetails 为上游给出的模态细分。引用显式缓存时,systemInstructionsTokens、contentTokens 与 toolTokens 只含请求自身的内容,cachedContentTokenCount 与 cacheTokensDetails 为缓存部分的 token 数与模态细分,totalTokens 与 promptTokensDetails 包含缓存部分。Playground 计数只有请求级分辨率,Part 分辨率不同的计数请求与 Playground 目录没有的模型经 Build 通道的 countTokens 计数。
| 方法 | 路径 | 结果 |
|---|---|---|
POST |
/v1beta/cachedContents |
创建,返回 CachedContent |
GET |
/v1beta/cachedContents |
按创建时间从新到旧分页列出,pageSize 默认 10、最大 1000 |
GET |
/v1beta/cachedContents/{id} |
返回 CachedContent |
PATCH |
/v1beta/cachedContents/{id} |
按 updateMask 更新过期时间与显示名称 |
DELETE |
/v1beta/cachedContents/{id} |
删除,返回 {} |
创建请求为 {model,displayName?,systemInstruction?,contents?,tools?,toolConfig?,ttl?|expireTime?},ttl 为正的 Duration 字符串,例如 "600s",两者都省略时存活 1 小时;创建与更新请求同时给出 ttl 与 expireTime 时返回 400 INVALID_ARGUMENT。CachedContent 为 {name:"cachedContents/<id>",model,displayName?,createTime,updateTime,expireTime,usageMetadata:{totalTokenCount}},totalTokenCount 为创建时对缓存内容的计数。PATCH 的查询参数 updateMask 为逗号分隔的字段名,只更新其中列出的字段:ttl、expireTime(也接受 expire_time、expiration)更新过期时间,displayName(也接受 display_name)更新显示名称;列出过期时间而请求没有 ttl 或 expireTime、或列出其他字段时返回 400 INVALID_ARGUMENT;省略 updateMask 时更新请求中出现的这些字段,两者都没有时返回 400 INVALID_ARGUMENT。缓存保存在服务进程内存中,重启后失效;生成请求每次发送缓存的完整内容,promptTokenCount 包含缓存部分;usageMetadata.cachedContentTokenCount 与 cacheTokensDetails、Interactions 的 usage.total_cached_tokens 与 cached_tokens_by_modality 为缓存的 token 数与模态细分,上游隐式缓存命中更多时取上游的值。expireTime 早于当前时间的缓存创建或更新后即过期;读取、更新与删除未知或已过期的资源名返回 403 PERMISSION_DENIED(CachedContent not found (or permission denied)),分页列表的 pageToken 取上一页的 nextPageToken。
非流式生成响应:
{
"candidates": [{
"content": {"parts":[],"role":"model"},
"finishReason": "STOP",
"index": 0,
"finishMessage": "...",
"citationMetadata": {},
"groundingMetadata": {}
}],
"usageMetadata": {
"promptTokenCount": 10,
"candidatesTokenCount": 20,
"totalTokenCount": 35,
"thoughtsTokenCount": 5
},
"modelVersion": "gemini-provider-id",
"responseId": "request-id",
"turnToken": "v1_..."
}modelVersion 为生成所用的模型:Build 通道取上游响应的 modelVersion,以 gemini-flash-latest 等别名请求时为别名当前指向的模型;Playground 通道为目录模型 ID。responseId 为上游响应的 responseId:Build 通道取响应的 responseId,Playground 通道取 turnToken 的 field 2,上游没有给出时为本服务请求 ID。turnToken 为上游响应的轮次令牌,两个通道都输出;Build 通道非流式响应另带上游的 debugInfo,候选结束时带上游的 detailedFinishReason。finishReason 使用 Gemini API 的枚举名,包括 MISSING_THOUGHT_SIGNATURE、MALFORMED_RESPONSE 与 CONTINUATION;Build 通道返回的其他枚举名原样输出,Playground 未知编号输出 OTHER。finishMessage 为上游给出的结束说明,例如上游过滤生成结果时的原因;没有上游说明且结束原因为 OTHER 时写入 AI Studio finish reason <编号>。候选带 safetyRatings:[{category,probability,blocked?}],输入被拦截时 promptFeedback 同样带 safetyRatings。候选没有输出 Part 时省略 content。candidateCount 大于 1 时,candidates 按 index 0 到 n-1 排列,各自携带 finishReason。:streamGenerateContent 按到达顺序输出各候选的增量块,每块只含一个带 index 的候选;最后一块列出全部候选,各自带该候选上游结束帧中的 content、finishReason 与该候选的 groundingMetadata、citationMetadata,并带合计的 usageMetadata。非流式候选同时返回 groundingMetadata 与上游引用的 citationMetadata。
输出 Part 使用与输入相同的 text、thought、thoughtSignature、inlineData、fileData、functionCall、toolCall、toolResponse、executableCode、codeExecutionResult。转录文本可以携带:
{
"text": "Hello.",
"audioTranscription": {
"text": "Hello.",
"speakerLabel": "spk:0",
"words": [{"word":"Hello.","startOffset":"0.200s","endOffset":"0.800s"}]
}
}groundingMetadata 字段为 searchEntryPoint、groundingChunks、groundingSupports、retrievalMetadata、webSearchQueries、googleMapsWidgetContextToken。searchEntryPoint 包含 renderedContent、sdkBlob;groundingChunks 元素的 oneof 为 web:{uri,title,domain?,siteName?,searchResultMapping?}、image:{sourceUri,imageUri,title,domain}、retrievedContext:{uri,title,text} 或 maps:{uri,title,text,placeId,placeAnswerSources?};groundingSupports 元素包含 segment:{partIndex,startIndex,endIndex,text}(值为 0 的下标省略)、groundingChunkIndices、可选 confidenceScores 与图片搜索结果对应的 renderedParts;Build 通道上游给出的 chunk origin、referenceId 与 support origin 原样输出;图片搜索的检索词写入 imageSearchQueries;retrievalMetadata 包含 googleSearchDynamicRetrievalScore。citationMetadata.citationSources 的元素包含 uri、title、startIndex、endIndex 与可选 license。URL Context 读取的网址写入候选的 urlContextMetadata.urlMetadata[],元素为 retrievedUrl 与 urlRetrievalStatus,Build 通道取自上游 urlContextMetadata,Playground 通道取自 URL_CONTEXT 工具结果;groundingMetadata 只在有搜索、检索或地图依据时输出。
非流式结果合并相邻、同类且无签名边界的正文或思考片段。工具、媒体与带转录元数据的 Part 保持独立;独立签名附着于前一未签名 Part,缺少可附着内容时用 {"text":"","thoughtSignature":"..."} 承载。
:streamGenerateContent 带 alt=sse 时使用 SSE;不带时与官方 REST 一样返回 application/json 的 JSON 数组,元素之间以 \r\n,\r\n 分隔,不写保活行。每个内容事件发送一个部分 GenerateContentResponse,包含 responseId、modelVersion、turnToken、该事件所在上游帧的累计 usageMetadata 与一个带 content 的 candidate Part;上游带结束原因的那一帧中的内容 Part(包括只带签名的空文本 Part)不单独成块,与 finishReason、可选 finishMessage、groundingMetadata、citationMetadata 和最终 usageMetadata 一起放在最后一帧。响应头后的错误为 SSE 帧 data: {"error":{"code","message","status"}} 或 JSON 数组中的同形元素。
POST /v1/files 接受 multipart file 与可选 purpose,两者可以按任意顺序到达。文件上限 512 MiB,请求额外允许 1 MiB multipart overhead;普通 scalar part 上限 64 KiB。filename 与非空 file 必需;purpose 省略或为空时为 user_data。Content-Type 为空、无效、不含子类型或为 application/octet-stream 时从文件前缀检测不带参数的 MIME,Ogg 前缀记为 audio/ogg,WAV 前缀记为 audio/wav;前缀无法识别时依次按 FLAC 头、MPEG 音频帧头与扩展名(flac、mp3、mp4、mpeg、mpga、m4a、ogg、wav、webm,其余扩展名查系统 MIME 表)确定。/v1/files 与 /upload/v1beta/files 收到的 GIF 按首帧画在逻辑画布尺寸的白底上,编码为质量 92 的 JPEG 后保存,文件名不变,MIME 为 image/jpeg。
File object:
{
"id": "file_...",
"object": "file",
"bytes": 1234,
"created_at": 0,
"filename": "document.pdf",
"purpose": "assistants",
"status": "processed"
}POST /v1/files 与 GET /v1/files/{id} 返回该对象。GET /v1/files/{id}/content 返回原始 body,并设置 Content-Type、attachment Content-Disposition 和已知时的 Content-Length。DELETE /v1/files/{id} 返回:
{"id":"file_...","object":"file","deleted":true}未知文件返回 404 file_not_found,超过大小限制返回 413 file_too_large。Drive 账户绑定与跨账户复制见“Drive 上传与文件 Part”节。
GET /v1/files 按创建时间从新到旧返回 {"object":"list","data":[File object],"first_id","last_id","has_more"}。order 为 asc 或 desc(默认),after 为上一页最后一个文件 ID,limit 为 1–10000、默认 10000,purpose 只返回该用途的文件。未知的 after 返回空页;limit 越界或 order 无效返回 400。
请求带 anthropic-version,或 anthropic-beta 含 files-api- 时,同一组路径按 Anthropic Files API 返回。文件对象为 {"id","type":"file","filename","mime_type","size_bytes","created_at":"<RFC 3339>","downloadable":true}。上传只需 file 段,用途记为 user_data。删除返回 {"id","type":"file_deleted"}。错误为 Anthropic 错误对象,未知文件为 404 not_found_error。列表按创建时间从新到旧返回 {"data","next_page","first_id","last_id","has_more"}:limit 为 1–1000、默认 20;page 取上一页的 next_page(形如 page_<文件 ID>),也接受 after_id 与 before_id;ids(也接受 ids[] 或逗号分隔)只返回列出的文件且不分页;带 scope_id 时返回空列表。文件 ID 与 OpenAI 文件相同,可用于 Messages 的 {"type":"file","file_id"} source。
POST /upload/v1beta/files 按 X-Goog-Upload-Protocol 或 uploadType 接受 resumable 与 multipart。可续传上传先发送 X-Goog-Upload-Command: start,请求体为可选的 {file:{name?,displayName?,mimeType?}}(接受 display_name 与单引号字符串),X-Goog-Upload-Header-Content-Type 声明类型,响应头 X-Goog-Upload-URL 给出上传地址;分块以 X-Goog-Upload-Command: upload 或 upload, finalize 与 X-Goog-Upload-Offset 发往该地址,偏移与已接收字节数不符时返回 400,query 返回 X-Goog-Upload-Size-Received,cancel 结束上传;地址闲置 1 小时后失效。multipart 请求体由可省略的 JSON 元数据段与文件段组成,multipart/related 与 multipart/form-data 均可。显示名依次取 displayName、文件段的 filename 与 X-Goog-Upload-File-Name,均缺失时为 file;类型依次取文件段 Content-Type、X-Goog-Upload-Header-Content-Type、mimeType,均缺失或为 application/octet-stream 时按内容识别。完成时返回 {file:File} 与 X-Goog-Upload-Status: final。
File 为 {name:"files/<id>",displayName,mimeType,sizeBytes,createTime,updateTime,uri,state:"ACTIVE",source:"UPLOADED",sha256Hash?,videoMetadata?},uri 为 https://generativelanguage.googleapis.com/v1beta/files/<id>,可直接用作 fileData.fileUri 与 Interactions 媒体内容的 uri。sha256Hash 为上传时计算的文件内容 SHA-256 的 Base64;MP4 与 QuickTime 视频带 videoMetadata:{videoDuration},例如 "4s"。GET /v1beta/files/{id} 返回 File,DELETE /v1beta/files/{id} 返回 {},未知文件返回 404 NOT_FOUND。GET /v1beta/files 按创建时间从新到旧返回 {files,nextPageToken?},pageSize 默认 10、最大 100,pageToken 取上一页的 nextPageToken。Gemini 文件与 /v1/files 共用存储、512 MiB 上限与 Drive 账户绑定。
元数据的 file.name 指定文件 ID,形如 files/<id>,<id> 为 1–40 个小写字母、数字或 -,首尾不能为 -;格式无效返回 400 INVALID_ARGUMENT。ID 已属于另一个文件时,multipart 上传与可续传上传的完成请求返回 409 ALREADY_EXISTS,消息为 <id> already exists.,可续传上传的开始请求照常返回上传地址。未指定时由服务分配 ID,分配的 ID 长于 40 个字符。指定的 ID 用于读取、下载、删除与 fileData.fileUri。
POST /v1/audio/transcriptions multipart 字段:
| 字段 | 取值与处理 |
|---|---|
file |
必需非空;audio/*、video/mp4、video/webm;最大 512 MiB;分段 Content-Type 按 POST /v1/files 的规则识别 |
model |
默认 gemini-3.5-transcribe;接受可选 models/ 前缀 |
response_format |
json、text、srt、verbose_json、vtt、diarized_json;默认 json |
language |
语言码;detect 与 auto 映射为空自动检测 |
temperature |
0..2 |
custom_vocabulary |
可重复文本字段或 JSON string array |
word_timestamps、speaker_labels、smart_transcription |
true 或 false |
timestamp_granularities[] |
word 或 segment,可重复;其他取值返回 400 invalid_request |
stream |
true 时以 SSE 返回 |
prompt |
当前 wire 无对应字段,忽略 |
smart_transcription=true 与显式 true 的 word timestamps 或 speaker labels 互斥,custom vocabulary 与 word timestamps 互斥,冲突组合返回 400 invalid_request。每次账户尝试创建临时 Drive file,生成结束、失败或取消后在同账户清理。
text 格式返回 text/plain; charset=utf-8。srt 与 vtt 按 segments 每段生成一条字幕,分别返回 text/plain; charset=utf-8 与 text/vtt; charset=utf-8。srt、vtt、verbose_json 与 diarized_json 在未设置 word_timestamps、smart_transcription 不为 true 且没有 custom_vocabulary 时请求词级时间戳;diarized_json 在未设置 speaker_labels 且 smart_transcription 不为 true 时请求说话人。json 返回 {"text","usage"?},usage 为 {"type":"tokens","input_tokens","output_tokens","total_tokens","input_token_details"?:{"audio_tokens","text_tokens"}},上游没有用量时省略。verbose_json:
{
"task": "transcribe",
"language": "en",
"duration": 1.25,
"text": "Hello",
"segments": [{"id":0,"seek":0,"start":0,"end":1.25,"text":"Hello","tokens":[],"temperature":0,"avg_logprob":0,"compression_ratio":0,"no_speech_prob":0,"speaker":"Speaker 1"}],
"words": [{"word":"Hello","start":0,"end":1.25,"speaker":"Speaker 1"}],
"usage": {"type":"duration","seconds":1.25}
}language 是规范化后的请求语言;detect / auto 时为空并省略。segments 来自 response Part field 23,speaker 在上游给出说话人时出现。words 只在 timestamp_granularities[] 含 word 或 word_timestamps=true 时返回,单词数与 timestamp span 数一致时生成。duration 对 WAV 输入取文件头的时长,其他格式取最后一个词的结束时间与上游 AUDIO 输入 token 数除以 32 两者中的较大值。diarized_json 为 {"task","duration","text","segments":[{"type":"transcript.text.segment","id":"seg_0","start","end","text","speaker"}],"usage"?},usage 与 json 相同。
stream=true 时,上游每段转录正文写出一个 {"type":"transcript.text.delta","delta"} 事件;diarized_json 改为每个分段写出一个 transcript.text.segment 对象;结束时写出 {"type":"transcript.text.done","text","usage"?}。事件流开始前出错按非流式返回错误,开始后出错写出 {"error":{...}} 数据帧。流式开始输出后不再切换账户重试。
POST /v1/audio/translations 接受 file、model、prompt、response_format(json、text、srt、verbose_json、vtt,默认 json)与 temperature(0–2)。服务先按转录规则转录音频,再用文本模型把转录译为英文:model 是转录模型或省略时(默认 gemini-3.5-transcribe),由 gemini-flash-latest 翻译;model 是其他模型时,由 gemini-3.5-transcribe 转录、该模型翻译。srt、vtt 与 verbose_json 请求词级时间戳并逐段翻译,保留每段起止时间;json 与 text 整段翻译。翻译请求用 JSON Schema 要求输出与分段数相同的字符串数组;prompt 作为译文的上下文与风格说明,temperature 作用于翻译。json 返回 {"text"};verbose_json 返回 {"task":"translate","language":"english","duration","text","segments","usage":{"type":"duration","seconds"}},不含 words。转录为空时不调用翻译;译文段数与转录不一致时返回 502 upstream_error。
POST /v1/images/generations:
| 字段 | 取值与处理 |
|---|---|
model |
省略时取公开目录顺序中支持 generateContent 的首个 image_route 模型 |
prompt |
必需 |
n |
默认 1,范围 1–10 |
size |
auto 或 WIDTHxHEIGHT,为输出图片尺寸 |
quality |
auto、low/standard=1K、medium/hd=2K、high/xhigh/max=4K |
output_format |
png(默认)、jpeg(也接受 jpg)或 webp |
output_compression |
0–100,默认 100,为 JPEG 质量 |
response_format |
url 返回 data URL;省略或其他值返回 Base64 b64_json |
stream |
boolean |
safety_identifier、user |
响应回传 safety_identifier,为空时回传 user |
background、moderation、style、partial_images |
没有上游对应项,不影响请求 |
- 每张图片单独生成,按序合并到
data size取模型image_aspect_ratios中比值最接近的宽高比,目录未列出时在 1:1、2:3、3:2、3:4、4:3、4:5、5:4、9:16、16:9、21:9 中选择;分辨率取image_output_resolutions中能覆盖size的最小一档(按与size等面积的正方形边长比较,512、1K、2K、4K 依次为 512、1024、2048、4096),超过全部档位时取最大一档- 模型列出
image_output_resolutions时,quality取其中最接近的分辨率;它高于size对应的分辨率时按quality生成 - 生成的图片从中央取与
size同宽高比的最大区域,缩放为size;生成的图片任一边小于size、或size为auto与省略时保持生成尺寸 - 输出按
output_format编码,WebP 为无损编码 stream:true时以 SSE 返回,每张图片一个image_generation.completed事件
响应为 {"created":<UNIX>,"background":"opaque","data":[{"b64_json":"...","revised_prompt":"..."}],"output_format","quality","size","usage","safety_identifier"?},response_format 为 url 时 data 项为 {"url":"data:<MIME>;base64,...","revised_prompt":"..."}。size 为输出图片的实际宽高;quality 为请求的 low、medium、high、xhigh 或 max,其余按生成分辨率记为 low(512、1K)、medium(2K)或 high(4K);usage 为各张图片上游用量的合计 {input_tokens,input_tokens_details:{text_tokens,image_tokens},output_tokens,output_tokens_details:{text_tokens,image_tokens},total_tokens},图片 token 取上游按模态细分的 IMAGE 项。revised_prompt 只在上游同时返回文本时出现。任一张未返回最终图片时返回 HTTP 502 upstream_error,结束原因不是正常结束时写入错误消息,例如 image_recitation;其他生成错误按该错误返回,不返回部分结果。流式事件为 {"type":"image_generation.completed","b64_json","usage","background","created_at","output_format","quality","safety_identifier"?,"size"},size 为该张图片的实际宽高,usage 为该张图片的上游用量,在全部图片生成后依次发送,不发送 partial image 事件;生成失败时按非流式返回错误。
POST /v1/images/edits 接受 multipart 的 image 或 image[](一个或多个文件)、prompt、mask,以及与图片生成相同的 model、n、size、quality、output_format、output_compression、response_format、stream、safety_identifier、user,响应格式也相同,流式事件类型为 image_edit.completed。输入图片按顺序作为参考图写在提示词之前;分段 Content-Type 缺失或为 application/octet-stream 时按内容识别,GIF 取首帧转为 PNG。mask 中完全透明的像素转为白色、其余为黑色,生成 PNG 遮罩,放在输入图片之后,并附说明“白色为编辑区域、黑色保持不变”。background、input_fidelity、partial_images 没有上游对应项,不影响请求。缺少图片或提示词、遮罩无法解码时返回 400。
POST /v1/audio/speech:
| 字段 | 取值与处理 |
|---|---|
model、input |
必需 |
voice |
默认 Zephyr |
response_format |
默认 mp3;支持 mp3、opus、aac、flac、wav、pcm |
speed |
0.25..4.0 |
instructions |
文本 part 的 speechMetadata.style |
stream_format |
audio(默认)返回音频文件;sse 以 SSE 返回;其他取值返回 400 invalid_request |
speed省略、0或1为正常语速,其他值以Speak at <speed> times the normal speaking rate.追加到语音风格- 旧 TTS 模型以
instructions + "\n\n" + input形成提示
stream_format:"sse" 时,pcm 按上游音频分块逐个写出 {"type":"speech.audio.delta","audio":"<Base64>"},其他格式在生成结束后编码整段音频并写出一个 speech.audio.delta;最后写出 {"type":"speech.audio.done","usage":{"input_tokens","output_tokens","total_tokens"}}。生成出错时写出 {"error":{...}} 数据帧。
上游返回 MP3(Lyria 等)时先解码为 PCM,mp3 原样返回上游数据。pcm 返回 PCM body 与采样参数;上游返回 PCM16 WAV 时先提取音频数据。wav 将 PCM 按有效 rate 与 channels 封装为 16-bit WAV;原生 WAV 保留对应音频格式,多个片段先合并 PCM 数据再封装。mp3 为 MPEG-1 Layer III 192 kbit/s CBR(audio/mpeg,32/44.1/48 kHz),opus 为 Ogg Opus(audio/opus),aac 为 ADTS AAC-LC(audio/aac,44.1/48 kHz),flac 为 16-bit FLAC(audio/flac)。响应设置 Content-Type 与 Content-Length。
旧 TTS 模型的语音请求按官网 wire 在首个文本前写入 ## Transcript:\n,AUDIO-only generation config 不写默认 maxOutputTokens;responseModalities 与 speechConfig 分别写入官网确认的槽位。
Gemini POST /v1beta/models/{model}:predict 以 Imagen 模型生成图片,{model} 为实时目录中带 predict 方法的模型:
{
"instances": [{"prompt": "a red apple"}],
"parameters": {"sampleCount": 1, "aspectRatio": "1:1", "negativePrompt": "blur", "imageSize": "2K", "includeRaiReason": true}
}| 字段 | 取值与处理 |
|---|---|
instances |
一个或多个实例,prompt 为提示词;每个实例按同一组参数依次生成一次 |
sampleCount |
图片数 |
aspectRatio |
宽高比 |
negativePrompt |
反向提示词 |
imageSize |
输出分辨率 |
includeRaiReason |
为 true 时返回被拦下图片的原因 |
响应 predictions[] 按 instances 顺序排列,每项为 bytesBase64Encoded 与 mimeType;某个实例生成出错时返回该错误。被安全策略拦下的图片在 includeRaiReason 为 true 时以 {"raiFilteredReason": "<上游给出的原因>"} 列出,否则省略;全部图片被拦下时响应为 {}。模型不在实时目录或没有 predict 方法时返回 404 NOT_FOUND,上游错误按 Gemini 错误体返回。
OpenAI POST /v1/videos 接受 JSON 或 multipart:
| 字段 | 取值与处理 |
|---|---|
model |
省略时取公开目录顺序中首个视频模型(generateContent 模型列出 video_output_resolutions) |
prompt |
有 input_reference 时可以为空,否则必需 |
seconds |
整数字符串;默认 4;按模型选项取最接近值 |
size |
1280x720、720x1280(默认)、1792x1024、1920x1080、1024x1792、1080x1920 |
input_reference |
JSON 中为 file ID/data URL;multipart 中为文件 |
input_reference文件段的 Content-Type 缺失、无效或为application/octet-stream时按内容识别图片类型
OpenAI video object:
{
"id": "operation-id",
"object": "video",
"model": "gemini-omni-1.1-flash",
"status": "queued",
"progress": 0,
"created_at": 0,
"size": "720x1280",
"seconds": "4",
"prompt": "lake at dawn",
"completed_at": null,
"expires_at": null,
"error": null,
"remixed_from_video_id": null
}prompt 为创建任务时的提示词,completed_at 为结果视频登记时的 Unix 秒数,未完成时为 null;expires_at 与 remixed_from_video_id 为 null,error 在失败时为错误对象,其余为 null。GET /v1/videos/{id} 返回当前对象。完成时 status 为 completed、progress 为 100;服务重启前没有生成完成的任务按本地记录返回 status 为 failed、progress 为 100 的对象,并带 error:{"code":"video_not_found","message":"服务重启前任务没有生成完成"}。GET /v1/videos/{id}/content 接受省略或 variant=video,未完成时返回 409 video_not_ready;成功下载设置媒体 Content-Type、attachment; filename="video.mp4" 和已知的 Content-Length。
GET /v1/videos 从资源绑定列出视频,按创建时间从新到旧返回 {"object":"list","data":[video object],"first_id","last_id","has_more"}。order 为 asc 或 desc(默认),after 为上一页最后一个视频 ID,limit 为 0–100、默认 20。页内每个视频给出与 GET /v1/videos/{id} 相同的对象;读取任务状态失败时返回该错误。DELETE /v1/videos/{id} 先读取任务状态:已完成的删除 Drive 结果文件,并解除结果文件与任务的绑定;失败的只解除任务绑定;都返回 {"id","object":"video.deleted","deleted":true}。未结束的任务返回 409 video_not_ready。未知或已删除的视频在查询、下载与删除时都返回 404 video_not_found。
视频创建成功后按 operation ID 写入以下资源绑定:
{
"kind": "video-operation",
"created_at": "2026-01-01T00:00:00Z",
"video": {
"model": "gemini-omni-1.1-flash",
"seconds": "4",
"size": "720x1280",
"prompt": "lake at dawn",
"completed_at": 1767225900
}
}model、实际发送的 seconds、size、prompt、结果视频登记时间 completed_at 与 UTC created_at 随创建账户持久保存,后续查询从资源绑定恢复;生成服务或进程重新启动后,OpenAI POST 与 GET 仍返回相同字段。size 为宽高比与分辨率换成模型支持的值后实际生成的尺寸:360p 为 640x360 或 360x640,720p 为 1280x720 或 720x1280,1080p 为 1920x1080 或 1080x1920,4k 为 3840x2160 或 2160x3840。公开对象的 created_at 是绑定创建时间的 Unix 秒。
Gemini :predictLongRunning 请求:
{
"instances": [{
"prompt": "...",
"image": {
"inlineData": {"mimeType":"image/jpeg","data":"..."}
}
}],
"parameters": {
"numberOfVideos": 1,
"sampleCount": 1,
"aspectRatio": "16:9",
"durationSeconds": 4,
"resolution": "720p"
}
}instances 有一个或多个,每个实例至少有非空 prompt、image、lastFrame 或 referenceImages 之一;image 必须在 inlineData 与 fileData:{mimeType,fileUri} 中选择一个。numberOfVideos 为 0 时读取 sampleCount,两者均为 0 时默认 1,范围 1–4,为每个实例各生成这些视频;每个视频创建一个任务。durationSeconds 接受 JSON integer 或十进制字符串。duration、aspect ratio 与 resolution 省略时分别为 4、16:9、720p,并换成实时模型 video_durations_seconds、video_aspect_ratios、video_output_resolutions 中最接近的取值(时长按秒数、宽高比按比值对数、分辨率按像素高度,距离相同时取较大值);负数时长返回 400,模型列出对应选项时无法解析的宽高比与分辨率返回 400,未列出时原样发送。创建返回 {"name":"operations/<ID>"},多个视频时 <ID> 为各任务 ID 按实例顺序以 ~ 连接;中途创建失败时停止,已创建的任务照常返回,第一个即失败时返回该错误。Gemini operation 使用同一份持久元数据恢复创建账户;Gemini 响应只包含 name、done 与完成后的 response.generateVideoResponse.generatedSamples。
GET /v1beta/operations/{id} 与 GET /v1beta/models/{model}/operations/{id}:
{
"name": "operations/<ID>",
"done": true,
"response": {
"generateVideoResponse": {
"generatedSamples": [{
"video": {"uri":"http://<HOST>/v1beta/files/<FILE_ID>:download?alt=media","mimeType":"video/mp4"}
}]
}
}
}response 在全部任务 done 时出现,带 "@type":"type.googleapis.com/google.ai.generativelanguage.v1beta.PredictLongRunningResponse",generatedSamples 按创建顺序列出有产物的任务,uri 为各任务结果视频的 Files API 下载地址;无产物时为空。任务生成失败时 operation 带 error:{code,message,status},code 为 google.rpc.Code 数值,例如 RESOURCE_EXHAUSTED 为 8;服务重启前没有生成完成的任务带 error:{"code":5,"message":"服务重启前任务没有生成完成","status":"NOT_FOUND"};查询任务状态失败时返回该错误。
两个入口按模型 ID 或目录别名找到能输出视频的模型(generateContent 模型列出 video_output_resolutions,如 gemini-omni-1.1-flash),在可调用该模型的账户上创建 omni- 开头的任务 ID 并立即返回,服务在后台按 Omni Interaction 生成;模型不输出视频时返回 404:
- 宽高比与分辨率换成模型选项中最接近的取值,时长换成
video_duration_range范围内的秒数 - 按输入核对模型目录的
video_tasks:有参考图时为reference_to_video,只有起始图时为image_to_video,没有图片时为text_to_video,目录没有列出该任务时返回 400;请求带参考图或起始图任务,文字生成视频以及提示词为空、只有图片时与官网一样不带任务;图片在提示词之前,提示词为空时内容只有图片;反向提示词以\n\nNegative prompt: <文本>附加在提示词末尾;尾帧返回 400 - 生成的 MP4 上传到创建账户的 Drive,以官网视频页的文件名绑定为任务结果,查询、下载、列出与删除见上文
- 请求没有指定账户时,生成账户在冷却中或上游返回 401、403、429 与 5xx 时换另一个能运行该模型的账户重新生成,图片输入重新上传到该账户,任务与结果仍属于创建账户;指定账户时以该错误结束
- 生成失败时 Gemini operation 为
done并带error:{code,message,status},OpenAI 对象 status 为failed并带error:{"code":"video_generation_failed","message"} - 服务重启时尚未完成的任务为已结束且没有结果,说明为
服务重启前任务没有生成完成
连接升级后 10 秒内发送 setup:
{
"type": "setup",
"model": "gemini-live-model",
"input_modalities": ["text", "audio", "image"],
"output_modalities": ["audio"],
"tools": [{"name":"get_weather","description":"...","parameters":{"type":"object"}}],
"session_token": ""
}Live input modalities 是 text/audio/image 的非空子集,output 按模型能力确定:普通 Live 模型为 ["audio"];实时翻译模型(能力码 46)要求 output ["audio"] 与 "translation":{"target_language_code":"es","echo_target_language":false},输入音频的原文经 input_transcription、译文经 output_transcription 与 media 返回;实时转录模型(能力码 77)要求 output ["text"],可带 "transcription":{"language_codes":["en"]},转写经 interim_input_transcription(当前累计文本)与 input_transcription(最终文本)返回。两类模型不接受 tools,其他模型不接受 translation 与 transcription。Robotics input/output 必须分别为 ["text"] 与 ["text"],不接受 translation 与 transcription。实时音乐模型 input/output 为 ["text"] 与 ["audio"],不接受 tools、translation 与 transcription。数组不接受空字符串或重复项。
setup 之后的客户端对象统一字段为 type、可选 text、mime_type、Base64 data、tool_responses、weighted_prompts、music_config、playback_control。各帧字段:
| type | 字段 |
|---|---|
text |
text |
audio |
mime_type:"audio/pcm"、data |
image |
mime_type:"image/jpeg"、data |
media_end |
无附加字段 |
tool_response |
tool_responses:[{id,name,content,will_continue?}] |
music_prompts |
weighted_prompts:[{text,weight}] |
music_config |
music_config 对象,字段同 Gemini API LiveMusicGenerationConfig |
playback |
playback_control:"play"|"pause"|"stop"|"reset_context" |
close |
无附加字段 |
text帧要求 setup 声明 text 输入,tool_response帧要求 setup 声明 tools,music_prompts的 text 非空audio与image省略mime_type时分别使用audio/pcm与image/jpegmusic_config的键可用 snake_case 或 camelCase- 实时音乐会话只接受
music_prompts、music_config、playback与close,Live 与 Robotics 会话不接受这三种帧 tool_response批量发送函数结果,保留调用的id与name- setup 的函数声明可带
behavior:NON_BLOCKING的函数在模型继续对话时异步执行;对它的调用回复will_continue: true的中间结果后,同一调用还能继续回复,最后一次回复省略will_continue
tool_response 示例:
{"type":"tool_response","tool_responses":[{"id":"call-1","name":"get_weather","content":{"temperature":26}}]}服务端对象字段全集:
{
"type": "text",
"model": "gemini-live-model",
"text": "...",
"mime_type": "audio/l16;rate=24000",
"data": "<BASE64>",
"transcription": {"text":"...","finished":true,"duration_ms":1000,"language_code":"en"},
"tool_call": {"id":"call-1","name":"get_weather","arguments":{}},
"tool_call_ids": ["call-1"],
"session_token": "...",
"resumable": true,
"raw": {},
"error": "...",
"code": "...",
"retryable": true
}按 type 使用对应字段:session_opened{model}、setup_complete、text{text}、media{mime_type,data}、input_transcription/output_transcription/interim_input_transcription{transcription}、tool_call{tool_call}、tool_call_cancellation{tool_call_ids}、interrupted、generation_complete、turn_complete、session_resumption{session_token,resumable}、usage{raw}、go_away{raw}、provider{raw}、closed、error{error,code,retryable,raw?}。
首帧或后续客户端字段无效时发送 {type:"error",code:"invalid_request",error:"..."}。权益不足、候选账户均在冷却与生成服务已停止时,code 与 HTTP 错误表的 OpenAI 列相同。上游错误保留原始 error 内容。客户端单帧上限 8 MiB,超限发送 WebSocket close code 1009。每次写操作上限 10 秒;会话结束等待读取和发送 goroutine(Go 协程)的上限各 5 秒。
流式端点使用 text/event-stream,每个 SSE frame 以空行结束;Gemini 不带 alt=sse 的请求返回 JSON 数组:
| 协议 | 首事件 | 内容序列 | usage | 终止事件 |
|---|---|---|---|---|
| OpenAI Chat | assistant role chunk | chat completion delta | include_usage=true 时位于 finish chunk 之后 |
data: [DONE] |
| OpenAI Responses | response.created、response.in_progress |
output item / content part / delta / done | 完成 response 的 usage |
response.completed 或 response.incomplete |
| Anthropic | message_start |
content_block_start、delta、content_block_stop |
message_delta.usage |
message_stop |
| Gemini | candidate Part | GenerateContentResponse 增量 |
最后一帧 usageMetadata |
最后一帧 finish reason |
上游语义事件间隔达到 10 秒时,OpenAI 两种协议发送 SSE 注释帧 : ping,Anthropic 发送 ping 事件,Gemini SSE 发送空行,均立即 flush。OpenAI Chat 先发送 assistant role chunk,Responses 先发送 response.created 与 response.in_progress,Anthropic 先发送 message_start;这些起始事件在账户调度期间即可到达客户端。Gemini 的首个帧来自上游语义事件或保活空行。
公开适配规则:
| 规范事件 | OpenAI Chat | Responses | Anthropic | Gemini |
|---|---|---|---|---|
| text | message/content delta | output_text | text block | candidate text Part |
| reasoning | reasoning_content |
reasoning summary,请求设置 reasoning.summary 时输出 |
thinking block,请求启用 thinking 时输出 |
thought Part,includeThoughts 为 true 时输出 |
| function | tool_calls,旧式 functions 请求为 function_call |
function_call item | tool_use block | functionCall Part |
| function result | tool message | function_call_output | tool_result | functionResponse Part |
| code execution | 可读 Markdown | code_interpreter item | text block | executableCode/result Part |
| grounding/citation | annotations | output annotations | text sources | groundingMetadata |
| media | data URL、/media/ URL 或媒体端点 |
output content | content block | inlineData Part |
| usage | prompt/completion/total | input/output/total | input/output | prompt/candidates/thoughts/total |
Responses 媒体使用 image generation item。
OpenAI Chat 使用 Markdown 图片承载生成图片,MEDIA_OUTPUT=inline 时为 data URL,url 时为本服务的 /media/<文件名> URL;客户端把 assistant message.content 回传下一轮时,适配器将其中的 data URL 图片与本服务已保存的媒体 URL 图片恢复为 inline data Part,保留图片多轮上下文。GET /media/<文件名> 返回保存的媒体,不校验 API key,响应带 immutable 缓存头。图片 Base64 支持标准与 URL-safe 字母表、可选填充及 CR/LF 换行;图片前后的文本保持原顺序。
YOUTUBE_LINKS=true 时,用户文本中的 youtu.be/<ID>、youtube.com/watch?v=<ID>、/shorts/<ID>、/live/<ID> 和 /embed/<ID> 会转换为 video/* 外部媒体 part,并从用户 text part 中移除;重复 URL 合并为一个附件。OpenAI video_url/input_video、Anthropic URL source 与 Gemini fileData.fileUri 使用相同的外部媒体编码。
OpenAI Responses 的 previous_response_id 与 Interactions 的 previous_interaction_id 共用最多 256 个响应节点并重建完整 contents,已结束的节点保存在 runtime/states.db,服务重启后仍可续接。Drive 与视频资源绑定持久化到磁盘。
GET /v1/responses/{id} 返回完整响应对象;DELETE /v1/responses/{id} 返回 {"id":"resp_...","object":"response","deleted":true},以它为 previous_response_id 的已保存响应保留完整上下文;POST /v1/responses/{id}/cancel 终止进行中的 background:true 响应并返回保存的 status:"cancelled" 对象,流式事件记录在取消处结束、不带终止事件;已结束的后台响应返回其最终对象,其他响应返回 400。GET 带 stream=true 只用于 background:true 且 stream:true 创建的响应,其他已保存响应返回 400,starting_after 不是非负整数时返回 400。未保存、已淘汰或已删除的 ID 返回 404 not_found。
GET /v1/responses/{id}/input_items 返回 {"object":"list","data":[...],"first_id":...,"last_id":...,"has_more":...},按续接顺序列出前序响应的输入项与输出项及本次输入项。order 为 asc 或 desc(默认),limit 为 1–100(默认 20),after 与 before 取列表中的项 ID,不在列表中时返回 400。字符串输入与字符串 content 展开为 input_text(assistant 为 output_text)内容数组;缺少 ID 的 message 项编号为 msg_<响应 ID>_<序号>,其他项为 item_<响应 ID>_<序号>。
POST /v1/responses/input_tokens 接受 POST /v1/responses 的 input、instructions、tools 与 previous_response_id,经同一转换与前序上下文拼接后调用上游 CountTokens,不发起生成;省略 model 时使用前序响应的模型。
模型、参数、账户与上游错误按下方状态表投影。客户端取消会关闭上游 reader并释放账户租约。
错误对象与状态语义:
Gemini 列中注明状态码的行以该状态码返回;Interactions 路由与不带 alt=sse 的 streamGenerateContent 的错误对象外层为数组。
| 情况 | HTTP | OpenAI | Anthropic | Gemini |
|---|---|---|---|---|
| 参数、Schema、tool choice 无效 | 400 | invalid_request |
invalid_request_error |
INVALID_ARGUMENT |
| 没有符合条件的账户 | 400 | account_required |
invalid_request_error |
INVALID_ARGUMENT |
| 启用账户的权益都不满足模型 AccessModes | 403 | account_required |
permission_error |
PERMISSION_DENIED |
| 支持请求的账户均不可调度 | 503 | account_unavailable |
api_error |
UNAVAILABLE |
| 本地 API key 无效 | 401 | invalid_api_key |
authentication_error |
400 INVALID_ARGUMENT,details 为 API_KEY_INVALID 的 ErrorInfo 与 LocalizedMessage |
| 没有带 API key | 401 | invalid_api_key |
authentication_error |
403 PERMISSION_DENIED |
| 模型或方法不存在 | 404 | model_not_found |
not_found_error |
NOT_FOUND |
| 本地文件不存在 | 404 | file_not_found |
not_found_error |
NOT_FOUND |
输入 token 超过模型上限(上游原文含 The input token count exceeds the maximum number of tokens allowed) |
400 | context_length_exceeded |
invalid_request_error,消息以 prompt is too long: 开头 |
INVALID_ARGUMENT |
| 上游拒绝权限 | 403 | upstream_error |
permission_error |
PERMISSION_DENIED |
| 视频仍在生成 | 409 | video_not_ready |
api_error |
INTERNAL |
| 文件超过 512 MiB | 413 | file_too_large |
request_too_large |
INTERNAL |
上游配额或限流(上游给出重试时长时带 Retry-After,Gemini 错误体带 RetryInfo) |
429 | rate_limit_exceeded |
rate_limit_error |
RESOURCE_EXHAUSTED |
候选账户均在冷却且 1 分钟内不恢复(带 Retry-After,Gemini 错误体带 RetryInfo) |
429 | rate_limit_exceeded |
rate_limit_error |
RESOURCE_EXHAUSTED |
| 上游过载 | 529 | upstream_error |
overloaded_error |
INTERNAL |
| 当前客户端请求被管理端取消 | 503 | request_canceled |
api_error |
UNAVAILABLE |
| 生成服务已停止 | 503 | service_stopped |
api_error |
UNAVAILABLE |
| 生成服务正在启动且模型目录尚未就绪 | 503 | service_starting |
api_error |
UNAVAILABLE |
| 请求期限到期 | 504 | upstream_error |
timeout_error |
DEADLINE_EXCEEDED |
| 传输、Content-Type、解码或缺失终态 | 502 | upstream_error |
api_error |
INTERNAL |
- “没有符合条件的账户”指候选耗尽且没有符合方法与能力的账户
- 权益不满足时错误消息写明模型需要的权益:
1为付费 API key,3为 Google AI Pro 或 Ultra 订阅,4为 Google AI Ultra 订阅 - “支持请求的账户均不可调度”指这些账户都处于需要重新登录、不可用或已停用状态,错误消息逐个列出账户、状态与原因
- 管理端启动生成服务期间到达的公开 API 请求等启动结束再处理;生成服务处于
STOPPED时,生成与计数端点返回service_stopped,错误消息说明在管理页面点击“启动服务”或开启“自动启动生成服务” - OpenAI 错误对象的
type在参数、认证、权限与资源不存在时为invalid_request_error,429 为requests,其余为server_error;param为null - Responses 流中的
response.failed的error.code取官方枚举:429 为rate_limit_exceeded,400 为invalid_prompt,其余为server_error - 错误消息以服务的中文说明开头,上游错误随后附上游方法、HTTP 状态、协议错误码与上游原文,例如
AI Studio GenerateContent 返回 HTTP 429、协议错误码 8: You've reached your usage limit… - 候选账户均在冷却时,消息在最早恢复时间后附上该冷却的类型与触发它的上游错误,例如
每日限额: AI Studio GenerateContent 返回 HTTP 429、协议错误码 8: … limit: 100, model: gemini-3.8-flash … - OpenAI 与 Anthropic 的 5xx 错误消息(含已开始流式响应后的终止事件)在说明前加官方英文开头与冒号:503 为
Service unavailable,504 为Request timed out,529 为Overloaded,其余为Internal server error
上游 RPC 的 HTTP 404 表示传输或上游失败,默认映射为 502;公开 404 对应本地模型目录或本地资源查找失败。客户端自身断开时,访问日志记录 499 并结束响应写入。
错误对象 raw body:
OpenAI Chat / Responses
{
"error": {
"message": "Internal server error: upstream response ended before finish frame",
"type": "server_error",
"param": null,
"code": "upstream_error"
}
}Anthropic
{
"type": "error",
"error": {
"type": "api_error",
"message": "Internal server error: upstream response ended before finish frame"
}
}Gemini
{
"error": {
"code": 502,
"message": "upstream response ended before finish frame",
"status": "INTERNAL"
}
}已开始流式响应后的终止原文:
# OpenAI Chat
data: {"error":{"message":"...","type":"server_error","param":null,"code":"upstream_error"}}
# OpenAI Responses
event: response.failed
data: {"response":{"id":"resp_...","object":"response","status":"failed","error":{"code":"server_error","message":"..."}}}
# Anthropic
event: error
data: {"type":"error","error":{"type":"api_error","message":"..."}}
# Gemini
data: {"error":{"code":502,"message":"...","status":"INTERNAL"}}
MakerSuite 错误解析:
| 来源 | 路径 | 公开结果 |
|---|---|---|
| HTTP status | response status | 保留原状态码 |
| protocol code | $[1][0] |
映射到协议 error code/type/status |
| protocol message | $[1][1] |
写入公开错误的 message |
| 原始形状 | [null,[code,message,...]] |
解析后进入规范错误事件 |
请求生命周期:
| 阶段 | HTTP / SSE 行为 | 资源状态 |
|---|---|---|
| response headers 前失败 | 返回对应 HTTP status 与协议 JSON error | 释放账户槽位 |
| SSE 已开始后失败 | 发送 OpenAI error、response.failed、Anthropic error 或 Gemini error frame |
关闭上游 reader并释放账户槽位 |
| 完成帧 | 输出 finish reason、usage 与协议终止事件 | 合并 Set-Cookie并释放账户槽位 |
| 客户端取消 | 结束上游读取 | 取消请求上下文并释放账户槽位 |
欢迎二次开发,如果对你有帮助,考虑给仓库点一个Star~