# OpenAI Chat Completions `POST /v1/chat/completions` 覆盖面最广的入口——网关上几乎每个文本模型都能从这里调。开源项目、老框架、只认 「OpenAI 兼容」四个字的客户端,填这个准没错。 代价是它把所有模型压成同一套形状:Claude 的 thinking 块、Gemini 的 `imageConfig`、 Responses 的跨轮推理状态,走到这里都会被抹平。**模型有原生入口就优先用原生的**, 对照表见[模型与入口](https://docs.vibeapi.cn/zh/docs/models)。 ## 基本调用 **建议用官方 SDK 而不是自己拼 HTTP**——SSE 解析、工具参数分片拼接、超时与重试都由它处理,能避开大部分常见问题。安装与环境变量配置见[快速开始](https://docs.vibeapi.cn/zh/docs/quickstart)。 ```bash curl -N -X POST "https://www.vibeapi.cn/v1/chat/completions" \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "gpt-6-astra", "messages": [ {"role": "system", "content": "你是一个简洁的助手。"}, {"role": "user", "content": "用一句话解释什么是幂等。"} ], "stream": true }' ``` ```python from openai import OpenAI client = OpenAI(base_url="https://www.vibeapi.cn/v1", api_key="YOUR_API_KEY") stream = client.chat.completions.create( model="gpt-6-astra", messages=[ {"role": "system", "content": "你是一个简洁的助手。"}, {"role": "user", "content": "用一句话解释什么是幂等。"}, ], stream=True, ) for chunk in stream: delta = chunk.choices[0].delta.content if delta: print(delta, end="", flush=True) ``` ```javascript import OpenAI from "openai"; const client = new OpenAI({ baseURL: "https://www.vibeapi.cn/v1", apiKey: "YOUR_API_KEY", }); const stream = await client.chat.completions.create({ model: "gpt-6-astra", messages: [ { role: "system", content: "你是一个简洁的助手。" }, { role: "user", content: "用一句话解释什么是幂等。" }, ], stream: true, }); for await (const chunk of stream) { const delta = chunk.choices[0]?.delta?.content; if (delta) process.stdout.write(delta); } ``` ## 认证 `Authorization: Bearer `,`base_url` 为 `https://www.vibeapi.cn/v1`。 OpenAI 官方 SDK 只需要换这一个值。 ## 流式要求 请求超时上限 **120 秒**。非流式请求在生成完成前没有数据下行,单次生成超过这个时间就会 被中断,表现为「调用超时」。**这是本网关最常见的报错原因。** 短输出的非流式请求正常可用;长输出与推理型模型容易触发上限。**耗时无法预判,生产 环境建议默认开启流式**,需要完整文本时在客户端拼接 `delta`。 ## 请求参数 参数名、类型与语义对齐 [OpenAI Chat Completions API](https://developers.openai.com/api/reference/resources/chat)。每个参数先给官方定义,再以「网关」标注本网关的实测行为。 GPT 系模型的请求体不经改写,整个参数面照单转发;标注含义:**支持**=有可观测证据生效;**接受**=正常受理、效果取决于模型本身;**实测不生效**=返回 200 但没有对应效果;**无效**=本网关不提供这项能力。 ### 必填 用于生成响应的模型 ID。可用模型见[模型与入口](https://docs.vibeapi.cn/zh/docs/models),或调 `GET /v1/models` 取当前 key 能用的那份。 到目前为止的对话消息列表。每项含 `role`(`developer` / `system` / `user` / `assistant` / `tool`)与 `content`; 支持的模态取决于模型,多模态模型的 `content` 可为数组,混排 `{"type": "text"}` 与 `{"type": "image_url"}`。 ### 输出控制 为 `true` 时以 server-sent events 边生成边返回。 **网关。** 单次请求上限 120 秒,推理模型建议设为 `true`,见[流式要求](#流式要求)。 流式选项,仅在 `stream: true` 时设置。`{"include_usage": true}` 让最后一个 chunk 带上 `usage`,否则流式模式下拿不到 token 统计。 本次补全可生成的 token 上限,**包含可见输出与不可见的推理 token**。推理模型请用它而不是 `max_tokens`。 **网关。** 设得很小时 `finish_reason` 仍可能是 `stop` 而不是 `length`,不要用 `finish_reason` 判断是否被截断,以实际内容为准。 可生成的 token 上限。官方已弃用,由 `max_completion_tokens` 取代,且与推理模型不兼容;保留仅为兼容旧客户端。 为每条输入生成多少个候选回复;按所有候选的总 token 计费。 **网关 · 实测不生效。** 需要多个结果请并发多次调用。 最多 4 个停止序列,命中即停止生成,返回文本不含该序列。最新的推理模型不支持。**接受。** 指定模型必须输出的格式。`{"type": "json_schema", "json_schema": {...}}` 启用结构化输出,保证输出符合你给的 JSON Schema;`{"type": "json_object"}` 只保证是合法 JSON,需在提示里要求模型输出 JSON。 **网关 · 支持。** 两种写法都实测可用。 约束回复的详略:`low` / `medium` / `high`。较新的模型才支持。**接受。** 预测输出(Predicted Outputs):把已知的大部分内容作为静态预测传入,命中时降低延迟。**接受。** ### 采样 采样温度,`0`–`2`。越高越随机,越低越集中;一般只调它或 `top_p` 之一。 **网关。** 部分推理模型忽略它或只接受默认值,取决于模型。 核采样,替代温度:只考虑累计概率达到 `top_p` 的那部分 token,`0.1` 即只看前 10% 概率质量。 `-2.0`–`2.0`。正值按 token 已出现的频次惩罚,降低逐字重复的概率。**接受。** `-2.0`–`2.0`。正值按 token 是否已出现惩罚,提高谈论新话题的概率。**接受。** 按 token ID 调整其出现概率,取值 `-100`–`100`,在采样前加到 logits 上。**接受**,效果取决于模型。 是否返回输出 token 的对数概率。 **网关 · 实测不生效。** 返回 200 但响应里没有 `logprobs` 字段。 每个位置返回最可能的 `0`–`20` 个 token 及其对数概率,需同时开 `logprobs`。 **网关 · 实测不生效。** 同 `logprobs`。 指定后系统尽力确定性采样,相同 `seed` 与参数的重复请求应返回相同结果;不保证确定性,可用响应里的 `system_fingerprint` 监控后端变化。 **网关 · 支持。** 同一种子连续两次请求输出完全一致;模型版本变化后不保证跨时间一致。 约束推理模型的推理投入:`none` / `minimal` / `low` / `medium` / `high` / `xhigh` / `max`。降低投入可加快响应、减少推理 token;不是每个推理模型都支持全部取值,默认值随模型而异。 ### 工具调用 模型可以调用的工具列表,可以是函数工具或自定义工具。 **网关。** GPT 系工具调用语义完整;从本端点调 Claude / Gemini 属于协议转换,只保证基本的函数调用。 控制模型是否调用工具:`none` 不调用只生成消息;`auto` 由模型决定;`required` 必须调用至少一个;`{"type": "function", "function": {"name": "..."}}` 指定某个函数。 是否允许一轮内并行调用多个工具。**接受。** 已弃用,由 `tools` 取代。仅为兼容旧客户端保留。 已弃用,由 `tool_choice` 取代。 内置联网搜索工具的选项:`search_context_size`(`low` / `medium` / `high`)与 `user_location`。 **网关。** 取决于该模型当前是否开放该能力,不保证可用。 ### 缓存、标识与其他 用于把相似请求路由到同一缓存,提高提示缓存命中率;取代 `user` 字段的缓存用途。 **网关 · 支持。** 相同前缀的第二次请求 `usage` 里能读到命中的缓存 token,`auto` 与官方满血两类 key 都可用。相同前缀带同一个 key 更容易命中,直接影响成本。 提示缓存选项,`gpt-5.6` 及以后支持:`mode: "explicit"` 关闭隐式缓存断点,`ttl` 目前只支持 `30m`。**接受。** 已弃用,改用 `prompt_cache_options.ttl`。设为 `24h` 延长缓存保留。**接受。** 是否在服务端保存本次对话,供蒸馏与评测产品使用。**接受。** 最多 16 对键值,键 ≤ 64 字符、值 ≤ 512 字符,随对象存储、可供查询。**接受。** 终端用户的稳定标识,正被 `safety_identifier` 与 `prompt_cache_key` 取代。**接受。** 帮助识别可能违反使用政策的终端用户的稳定标识,≤ 64 字符,建议用用户名或邮箱的哈希。**接受。** 处理类型:`auto` / `default` / `flex` / `priority` 等。 **网关。** 由网关自行路由,该字段无意义。 对输入与输出运行内容审核的配置(`model`、`policy`)。**接受。** 期望的输出类型,如 `["text"]` 或 `["text", "audio"]`。**接受。** 音频输出参数,`modalities` 含 `audio` 时必填。 **网关 · 无效。** 不提供音频输出模型。 ## 响应字段 非流式返回一个 `chat.completion` 对象: ```json { "id": "chatcmpl-...", "object": "chat.completion", "created": 1788960000, "model": "gpt-6-astra", "choices": [ { "index": 0, "message": { "role": "assistant", "content": "同一个操作执行多次和执行一次效果相同。", "tool_calls": null }, "finish_reason": "stop", "logprobs": null } ], "usage": { "prompt_tokens": 32, "completion_tokens": 18, "total_tokens": 50, "completion_tokens_details": { "reasoning_tokens": 0 } } } ``` 本次补全的 id。 正文。工具调用时可能为 `null`,内容在 `tool_calls` 里。 模型请求调用的工具及其参数(参数是 JSON 字符串,需自行解析)。 `stop` 正常结束 · `length` 撞到输出上限 · `tool_calls` 等待工具结果 · `content_filter` 被审核拦截。 不可见的推理 token 数。**它计费但不出现在正文里**,推理模型上对账要看这个。 ## 流式事件 SSE,每个事件是一个 `chat.completion.chunk`,增量在 `choices[0].delta`, 以 `data: [DONE]` 收尾: ``` data: {"object":"chat.completion.chunk","choices":[{"index":0,"delta":{"role":"assistant"}}]} data: {"object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":"同一个"}}]} data: {"object":"chat.completion.chunk","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]} data: [DONE] ``` 只有一种 chunk 类型,按 `delta` 里出现的字段分辨内容:`content` 是正文增量, `tool_calls` 是工具调用参数的增量片段(要按 `index` 累积拼接)。 带了 `stream_options.include_usage` 时,最后一个 chunk 会额外带 `usage`。 ## 参数改写规则 | 模型 | 触发条件 | 网关的动作 | | -------- | ------------------------------- | ------------------------------------------------------------------------------- | | `grok-*` | `tools` 里含 `web_search` 类型的内置工具 | 移除该工具,其余工具保留(xAI 的 Chat 接口不支持内置搜索,带上会 422;联网请用 [Responses](https://docs.vibeapi.cn/zh/docs/grok#联网搜索)) | | `grok-*` | `reasoning.effort` 为 `none` | 改写为 `low` | Claude 系模型也有一组改写规则(`thinking`、`temperature`、`top_p`),见 [Messages](https://docs.vibeapi.cn/zh/docs/messages) 页——从本页调用 Claude 时同样适用。 ## 分组差异 key 分两类:**`auto`**(可调用除 `claude-opus-5-5`、`claude-fable-5`、`claude-fable-5-1` 外的全部模型)和 **`Claude 官方满血版`**。 **对 GPT 系模型,两类 key 实测没有差异**——提示缓存与内置工具在两边都可用。 差异只出现在 Claude 系模型上,见 [Messages](https://docs.vibeapi.cn/zh/docs/messages) 页。 ## 国产模型兼容度 网关上的国产模型(glm / kimi / qwen / deepseek / MiniMax)两套协议都能调通, 工具调用也都可用,但对 `max_tokens`、停止序列、结构化输出的遵循程度**逐个模型不同**, 同一模型在 Chat 协议和另一套协议上还可能表现不同。逐项实测结果见 [模型与入口](https://docs.vibeapi.cn/zh/docs/models)。 其中 `deepseek-v4-pro` 与 `kimi-k3` 不执行 `max_tokens`,且仍将结束原因报为已截断。 使用这两个模型时,以 `usage` 中的实际 token 数对账。 ## 真实响应示例 下面是从生产网关真实抓取、脱敏后的请求与响应,可以直接对照你自己的返回体。 模型决定调用工具时,`content` 为 `null`,内容在 `tool_calls` 里: 流式的 SSE 增量(中间事件已省略): ### 国产模型的真实响应 以下为各国产模型在 Chat 协议上的真实调用与响应,逐条折叠。 ## 能力边界 * **不等价于原生协议。** Claude 模型从这里调 thinking 块会丢,Gemini 的生图参数会丢。 调用成功不代表功能完整。 * **`n` 不保证生效。** 需要多个结果请并发多次调用。 * **不提供音频模型**,`audio` / `modalities: ["audio"]` 无效。 * **不是所有官方端点都有。** `/v1/assistants`、`/v1/batches`、`/v1/fine_tuning` 不在提供范围内。 ## 在线调试 填入你自己的 API Key 即可直接发起请求,参数表与响应结构由接口定义生成。 ## 官方文档 本页只写与本网关有关的部分,参数语义的权威定义以官方为准: * [OpenAI · Chat Completions](https://developers.openai.com/api/reference/chat-completions/overview) * [OpenAI · 文本生成指南](https://developers.openai.com/api/docs/guides/text) # Gemini 图像生成 `POST /v1beta/models/{model}:generateContent` Gemini 系图像模型走 Gemini 原生协议。**生图请务必用这个端点**——走 Chat 兼容协议也能出图, 但 `imageConfig`(`aspectRatio` 画幅、`imageSize` 分辨率)会在协议转换中整个丢掉,只能拿到默认尺寸。 文本对话见 [Gemini generateContent](https://docs.vibeapi.cn/zh/docs/gemini);GPT 生图见 [GPT 图像 · Image API](https://docs.vibeapi.cn/zh/docs/images) 与 [GPT 图像 · Responses](https://docs.vibeapi.cn/zh/docs/images-responses),Grok 见 [Grok 图像](https://docs.vibeapi.cn/zh/docs/grok-images)。 ## 基本调用 **建议用官方 SDK**(Python `google-genai`、Node.js `@google/genai`),`base_url` 填不带 `/v1` 的根地址。 ```bash curl -s -X POST \ "https://www.vibeapi.cn/v1beta/models/gemini-3.1-flash-image:generateContent" \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -d '{ "contents": [{"parts": [{"text": "一只可爱的猫咪在阳光下打盹"}]}], "generationConfig": { "responseModalities": ["IMAGE"], "imageConfig": {"aspectRatio": "16:9", "imageSize": "1K"} } }' -o response.json # 提取图片 jq -r '.candidates[0].content.parts[0].inlineData.data' response.json | base64 -d > output.png ``` ```python from google import genai from google.genai import types client = genai.Client( api_key="YOUR_API_KEY", http_options=types.HttpOptions(base_url="https://www.vibeapi.cn"), ) response = client.models.generate_content( model="gemini-3.1-flash-image", contents="一只可爱的猫咪在阳光下打盹", config=types.GenerateContentConfig( response_modalities=["IMAGE"], image_config=types.ImageConfig(aspect_ratio="16:9", image_size="1K"), ), ) for part in response.parts: if part.inline_data is not None: part.as_image().save("cat.png") break ``` ```javascript import { GoogleGenAI } from "@google/genai"; import fs from "fs"; const ai = new GoogleGenAI({ apiKey: "YOUR_API_KEY", httpOptions: { baseUrl: "https://www.vibeapi.cn" }, }); const response = await ai.models.generateContent({ model: "gemini-3.1-flash-image", contents: "一只可爱的猫咪在阳光下打盹", config: { responseModalities: ["IMAGE"], imageConfig: { aspectRatio: "16:9", imageSize: "1K" }, }, }); for (const part of response.candidates[0].content.parts) { if (part.inlineData) { fs.writeFileSync("cat.png", Buffer.from(part.inlineData.data, "base64")); break; } } ``` 以下内容均来自对本网关的真实调用,最后验证:2026-08-10。 ## 可用模型 超时建议:512px / 1K 约 80 秒,2K 约 200 秒,4K 约 350 秒。 | 模型 | 适用场景 | 特点 | | ---------------------------- | --------- | ------------------------------ | | `gemini-3-pro-image-preview` | 专业素材、复杂指令 | 高级推理、搜索接地、最高 4K、最多 14 张参考图 | | `gemini-3.1-flash-image` | 日常生成、批量任务 | 性价比高、支持 512px-4K、思考等级控制、图片搜索接地 | ## 请求格式 ```json { "contents": [ { "parts": [ { "text": "你的提示词" } ] } ], "generationConfig": { "responseModalities": ["IMAGE"], "imageConfig": { "aspectRatio": "16:9", "imageSize": "1K" } } } ``` ### generationConfig 参数 | 参数 | 类型 | 说明 | | ------------------------- | ---------- | ------------------------------------------------ | | `responseModalities` | `string[]` | `["IMAGE"]` 仅图片;`["TEXT", "IMAGE"]` 图文混合(默认) | | `imageConfig.aspectRatio` | `string` | 宽高比,见下方支持列表 | | `imageConfig.imageSize` | `string` | 分辨率档位:`512px`(仅 flash)、`1K`、`2K`、`4K`。**必须大写 K** | ### 支持的宽高比 全部 14 种,两个模型均已验证通过: `1:1` `1:4` `1:8` `2:3` `3:2` `3:4` `4:1` `4:3` `4:5` `5:4` `8:1` `9:16` `16:9` `21:9` ## 响应格式 ```json { "candidates": [ { "content": { "role": "model", "parts": [ { "inlineData": { "mimeType": "image/png", "data": "" } } ] }, "finishReason": "STOP" } ], "usageMetadata": { "promptTokenCount": 10, "candidatesTokenCount": 1120, "totalTokenCount": 1130 } } ``` 图片在 `candidates[0].content.parts[].inlineData` 中,base64 编码。 当 `responseModalities` 包含 `"TEXT"` 时,parts 中可能同时包含 `text` 和 `inlineData`。 ## 分辨率参考表 ### gemini-3.1-flash-image | 宽高比 | 512px | 1K | 2K | 4K | | ---- | -------- | --------- | --------- | ---------- | | 1:1 | 512×512 | 1024×1024 | 2048×2048 | 4096×4096 | | 1:4 | 256×1024 | 512×2064 | 1024×4128 | 2048×8256 | | 1:8 | 176×1456 | 352×2928 | 704×5856 | 1408×11712 | | 2:3 | 416×624 | 848×1264 | 1696×2528 | 3392×5056 | | 3:2 | 624×416 | 1264×848 | 2528×1696 | 5056×3392 | | 3:4 | 448×592 | 896×1200 | 1792×2400 | 3584×4800 | | 4:1 | 1024×256 | 2064×512 | 4128×1024 | 8256×2048 | | 4:3 | 592×448 | 1200×896 | 2400×1792 | 4800×3584 | | 4:5 | 464×576 | 928×1152 | 1856×2304 | 3712×4608 | | 5:4 | 576×464 | 1152×928 | 2304×1856 | 4608×3712 | | 8:1 | 1456×176 | 2928×352 | 5856×704 | 11712×1408 | | 9:16 | 384×688 | 768×1376 | 1536×2752 | 3072×5504 | | 16:9 | 688×384 | 1376×768 | 2752×1536 | 5504×3072 | | 21:9 | 784×336 | 1584×672 | 3168×1344 | 6336×2688 | > 512px 档位仅 flash 模型支持。 ### gemini-3-pro-image-preview 支持 `1K`、`2K`、`4K`,不支持 `512px`。分辨率与 flash 的 1K/2K/4K 一致。 ### 耗时参考 | 档位 | 典型耗时 | | ----- | -------- | | 512px | 10-17s | | 1K | 13-40s | | 2K | 40-170s | | 4K | 120-310s | ## 图片编辑 原图与文字指令一起放进 `contents`,即为编辑;SDK 直接传 PIL Image,REST 用 `inline_data` 传 base64。 只改局部时,在指令里明确说清保留什么: ```python from PIL import Image response = client.models.generate_content( model="gemini-3.1-flash-image", contents=[Image.open("cat.png"), "给这只猫戴上一顶圣诞帽"], config=types.GenerateContentConfig( response_modalities=["IMAGE"], image_config=types.ImageConfig(aspect_ratio="1:1", image_size="1K"), ), ) for part in response.parts: if part.inline_data is not None: part.as_image().save("cat_hat.png") break ``` 同一写法覆盖三类常见任务,只换指令: | 任务 | 指令示例 | | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | | 局部重绘(语义遮盖) | `Change only the background to a snowy winter scene. Keep the cat exactly the same.` | | 风格迁移 | `Transform this photograph into the style of Van Gogh's Starry Night. Preserve the composition but render with swirling, impasto brushstrokes.` | | 多图合成 | `contents` 里放多张图 + 指令:`让第二张图中的人穿上第一张图中的蓝色连衣裙,生成一张专业电商照片` | REST 写法(多图合成): ```bash curl -s -X POST \ "https://www.vibeapi.cn/v1beta/models/gemini-3.1-flash-image:generateContent" \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -d '{ "contents": [{"parts": [ {"text": "让第二张图中的人穿上第一张图中的蓝色连衣裙,生成一张专业电商照片"}, {"inline_data": {"mime_type": "image/png", "data": ""}}, {"inline_data": {"mime_type": "image/png", "data": ""}} ]}], "generationConfig": { "responseModalities": ["IMAGE"], "imageConfig": {"aspectRatio": "3:4", "imageSize": "2K"} } }' ``` ## 多轮迭代 把上一轮模型返回的完整 `parts`(含 `inlineData` 与 `thoughtSignature`)以 `role: "model"` 原样放回 `contents`,再追加新指令: ```python history = [{"role": "user", "parts": [{"text": "画一只橘猫坐在窗台上"}]}] r1 = client.models.generate_content(model="gemini-3.1-flash-image", contents=history, config=types.GenerateContentConfig(response_modalities=["TEXT", "IMAGE"])) history.append(r1.candidates[0].content) # 模型回复原样入史 history.append({"role": "user", "parts": [{"text": "把背景改成下雨天"}]}) r2 = client.models.generate_content(model="gemini-3.1-flash-image", contents=history, config=types.GenerateContentConfig(response_modalities=["TEXT", "IMAGE"])) ``` ## 高级功能 ### Google 搜索接地 基于实时搜索数据生成图片(如天气、新闻、股票)。在请求中添加 `tools` 字段: ```json { "contents": [{"parts": [{"text": "可视化旧金山今天的天气预报"}]}], "tools": [{"google_search": {}}], "generationConfig": { "responseModalities": ["TEXT", "IMAGE"], "imageConfig": {"aspectRatio": "16:9"} } } ``` 响应中会额外返回 `groundingMetadata`,包含 `webSearchQueries`(搜索词)和 `groundingChunks`(来源链接)。 Flash 还额外支持图片搜索接地,可用网络图片作为视觉参考: ```json "tools": [{"google_search": {"search_types": {"web_search": {}, "image_search": {}}}}] ``` ### 思考模式 Pro 模型默认启用思考模式,会先生成构思草图再输出最终图片。响应中 `part.thought == true` 的为思考过程,可跳过。 Flash 模型支持控制思考等级(`minimal` 默认 或 `high`),通过 `generationConfig.thinkingConfig` 设置: ```json { "contents": [{"parts": [{"text": "A futuristic city inside a glass bottle floating in space"}]}], "generationConfig": { "responseModalities": ["IMAGE"], "imageConfig": {"aspectRatio": "1:1", "imageSize": "1K"}, "thinkingConfig": { "thinkingLevel": "high", "includeThoughts": true } } } ``` `high` 模式下响应 parts 会包含多种类型: | part 类型 | 说明 | | -------------------------------- | ---------- | | `thought == true` + `text` | 思考文本(推理过程) | | `thought == true` + `inlineData` | 构思草图(临时图片) | | `inlineData`(无 thought) | 最终输出图片 | 提取最终图片时跳过 thought parts: ```python for part in response.candidates[0].content.parts: if getattr(part, "thought", False): continue # 跳过思考过程 if part.get("inlineData"): # 这是最终图片 save(part["inlineData"]) ``` > 无论 `includeThoughts` 设为 true 还是 false,思考 token 都会计费。`high` 模式会消耗更多 token 但图片质量更高。 ### 多张参考图片 Pro 支持最多 6 张对象图 + 5 张人物图(共 14 张);Flash 支持最多 10 张对象图 + 4 张人物图。 ## 能力边界 1. **imageSize 大小写**:必须用大写 `K`(`1K`、`2K`、`4K`),小写 `1k` 会被拒绝 2. **512px 仅 flash**:Pro 模型不支持 512px 档位 3. **超时**:4K 分辨率生成可能需要 2-5 分钟,务必设置足够的超时 4. **Token 消耗**:512px 约 747 token,1K 约 1120 token,4K 约 2000 token 5. **默认行为**:不传 `imageConfig` 时,默认输出约 1408×768(接近 16:9 的 1K) 6. **图片格式**:响应中 `mimeType` 通常为 `image/png`,偶尔为 `image/jpeg` 7. **SynthID 水印**:所有生成图片均包含 SynthID 数字水印 8. **推荐语言**:英语、中文、日语、韩语、法语、德语、西班牙语等 ## 在线调试 填入你自己的 API Key 即可直接发起请求,参数表与响应结构由接口定义生成。 ## 官方文档 * [Gemini API · 图像生成](https://ai.google.dev/gemini-api/docs/image-generation) * [Gemini API · generateContent](https://ai.google.dev/api/generate-content) # Gemini generateContent `POST /v1beta/models/{model}:generateContent` · 流式 `POST /v1beta/models/{model}:streamGenerateContent` Gemini 系模型的原生协议。**Gemini 模型请优先用这个端点**——它是唯一能拿到 `thinkingConfig`(思考)与 `imageConfig`(生图的比例与分辨率)的路径。从 [Chat Completions](https://docs.vibeapi.cn/zh/docs/chat) 调 Gemini 也能通,但那是网关做的协议转换,这两组参数 都会在转换中丢失。 注意模型名出现在**路径里**,不在请求体里。 ## 基本调用 **建议用官方 SDK**(Python `google-genai`、Node.js `@google/genai`),SSE 解析与重试由它处理。 ```bash curl -N -X POST "https://www.vibeapi.cn/v1beta/models/gemini-3.8-flash:streamGenerateContent" \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -d '{ "contents": [{"role": "user", "parts": [{"text": "用一句话解释什么是幂等。"}]}], "generationConfig": {"maxOutputTokens": 512} }' ``` ```python from google import genai from google.genai import types client = genai.Client( api_key="YOUR_API_KEY", http_options=types.HttpOptions(base_url="https://www.vibeapi.cn"), ) for chunk in client.models.generate_content_stream( model="gemini-3.8-flash", contents="用一句话解释什么是幂等。", config=types.GenerateContentConfig(max_output_tokens=512), ): if chunk.text: print(chunk.text, end="", flush=True) ``` ```javascript import { GoogleGenAI } from "@google/genai"; const ai = new GoogleGenAI({ apiKey: "YOUR_API_KEY", httpOptions: { baseUrl: "https://www.vibeapi.cn" }, }); const stream = await ai.models.generateContentStream({ model: "gemini-3.8-flash", contents: "用一句话解释什么是幂等。", config: { maxOutputTokens: 512 }, }); for await (const chunk of stream) { if (chunk.text) process.stdout.write(chunk.text); } ``` ## 认证 `Authorization: Bearer `,base 是 `https://www.vibeapi.cn`(**不带 `/v1`**, Gemini 的路径前缀是 `/v1beta`)。 ## 流式要求 请求超时上限 **120 秒**。`:generateContent` 在生成完成前没有数据下行,单次生成超过这个 时间会被中断。短输出不受影响;开启 thinking 的型号要等整段思考结束才返回,容易触发 上限。**建议默认用 `:streamGenerateContent`**,将各 chunk 的 `candidates[0].content.parts[].text` 拼接成完整文本。 ## 与另外两套协议的差异 Gemini 的请求结构与 OpenAI / Anthropic 均不同,以下三处差异最大: **模型名在 URL 路径里**,请求体里没有 `model` 字段。换模型要换 URL。 **对话叫 `contents` 不叫 `messages`**,角色是 `user` 和 **`model`**(不是 `assistant`), 每条消息的内容是 `parts` 数组(文本、图片、函数调用各是一个 part)。 **采样参数包在 `generationConfig` 里**,不是顶层字段;而 `tools`、`safetySettings`、 `systemInstruction` 是顶层的。 | | Chat Completions | Messages | generateContent | | ----- | ----------------------- | ---------------- | ---------------------------------- | | 模型名 | 请求体 `model` | 请求体 `model` | **URL 路径** | | 对话 | `messages` | `messages` | `contents` | | 助手角色名 | `assistant` | `assistant` | **`model`** | | 系统提示 | `system` 角色 | 顶层 `system` | 顶层 `systemInstruction` | | 输出上限 | `max_completion_tokens` | `max_tokens`(必填) | `generationConfig.maxOutputTokens` | | 流式 | `stream: true` | `stream: true` | **换端点** `:streamGenerateContent` | ## 请求体顶层字段 对话数组。每项含 `role`(`user` / `model`)与 `parts` 数组。`parts` 里可以混排 `{"text": ...}`、`{"inlineData": {"mimeType", "data"}}`(内联 base64 图片)、 `{"functionCall": ...}`、`{"functionResponse": ...}`。 系统指引,形状与一条 `contents` 相同(含 `parts`)。 工具定义。既包括你自己的 `functionDeclarations`,也包括内置工具(如 `googleSearch`、`codeExecution`)。**内置工具不保证可用**,也不保证与官方一致。 工具调用模式,`functionCallingConfig.mode` 取 `AUTO` / `ANY` / `NONE` / `VALIDATED`。 按类别设置安全阈值。**接受**,实际拦截强度取决于模型。 引用服务端缓存的内容。**依赖服务端存储,本网关不保证可用。** 自定义标签。**接受**。 ## generationConfig 输出上限。**思考 token 也算在内**,带 thinking 的型号要留足空间。 随机度。 核采样阈值。 只从概率最高的 K 个 token 里采样。 生成几个候选。**实测只能为 1**——传 2 会被 400 拒绝,提示当前模型只允许一个候选。 需要多个结果请并发多次调用。生图同样不支持这个参数。 停止序列。**支持**——实测命中后正常截断,`finishReason` 为 `STOP`。 采样种子。**实测不生效**——固定种子 + `temperature: 0` 连续三次请求输出仍不相同; 不带种子的对照组同样不确定。需要可复现结果时,请改用 OpenAI 系模型 ([Chat](https://docs.vibeapi.cn/zh/docs/chat) 页的 `seed` 实测可复现)。 按是否出现过惩罚重复。**接受**。 按出现频次惩罚重复。**接受**。 返回多少个候选 token 的概率。**实测不可用**,见下面的 `responseLogprobs`。 是否返回对数概率。**实测不可用**——本网关会以 400 拒绝,提示对数概率不支持流式模式。 响应 MIME 类型,如 `application/json`。配合 `responseSchema` 做结构化输出。 用 Gemini 自己的 schema 方言约束输出结构,需配合 `responseMimeType: "application/json"`。**支持**——实测返回符合 schema 的纯 JSON。 注意 `maxOutputTokens` 要给足:部分型号(实测 `gemini-3-pro`)会在 JSON 前先输出一句 前言,前言同样计入输出预算。预算不足时只会拿到那句前言,并以 `finishReason: "MAX_TOKENS"` 结束——**看起来像 schema 没生效,实际是被截断了**。 解析前检查 `finishReason` 比直接 `JSON.parse` 更可靠。 用标准 JSON Schema 约束输出结构,与 `responseSchema` 二选一。 期望的输出模态,如 `["TEXT"]`、`["TEXT","IMAGE"]`。**生图模型必须带 `IMAGE`。** 思考配置。`thinkingLevel` 控制思考深度,`includeThoughts: true` 让思考内容随响应返回。 **本网关实测可用**:返回的 `parts` 里带 `thought: true` 标记的就是思考内容, `usageMetadata.thoughtsTokenCount` 是思考消耗的 token。 生图配置,`aspectRatio` 比例、`imageSize` 分辨率(`1K` / `2K` / `4K` 等,**每个模型支持 的档位不同**)。**这组参数只在原生端点有**,走 Chat 兼容协议会整个丢掉。 输入媒体的处理分辨率,影响图片/视频输入的 token 消耗。**接受**。 语音合成配置。**本网关不提供语音模型**,无效。 音频输入的时间戳。**本网关不提供音频输入**,无效。 音频转写配置。同上,无效。 Google 侧的模型路由配置。**本网关自行路由,这个字段没有意义。** 模型选择配置。同上,没有意义。 公民类问题的增强回答。**接受**。 Model Armor 防护配置,属于 Vertex 侧能力。**接受**,多数情况无效。 SDK 里还有 `httpOptions`、`abortSignal`、`automaticFunctionCalling` 等字段, 它们是**客户端行为**,不会出现在 HTTP 请求体里。 ## 响应字段 ```json { "candidates": [ { "content": { "role": "model", "parts": [{ "text": "同一个操作执行多次和执行一次效果相同。" }] }, "finishReason": "STOP" } ], "usageMetadata": { "promptTokenCount": 12, "candidatesTokenCount": 18, "thoughtsTokenCount": 0, "totalTokenCount": 30 } } ``` 产出的 part 数组,**类型是混排的**。带 `thought: true` 的是思考内容,带 `inlineData` 的是生成的图片,带 `functionCall` 的是工具调用。 **取正文要过滤掉 `thought` 的那些**,直接拼所有 `text` 会把思考内容混进正文。 `STOP` 正常结束 · `MAX_TOKENS` 撞到上限 · `SAFETY` 被安全策略拦截 · `RECITATION` 疑似复述。 思考消耗的 token。**计费但不出现在正文里**,对账要看这个。 输入被安全策略拦截时的说明。此时 `candidates` 可能为空——**要处理这种情况**, 否则会在取 `candidates[0]` 时崩掉。 ## 流式 流式换端点,不是加参数:`:streamGenerateContent`。返回 SSE,每个 chunk 的形状与 非流式响应相同,只是 `parts` 里是增量文本,`usageMetadata` 在最后的 chunk 上。 ## 真实响应示例 以下为真实调用与响应,逐条折叠。带 `thought: true` 的 part 是思考内容; 最后两条分别是结构化输出与不受支持参数的实际返回,可用于对照你自己的解析与错误处理。 ## 能力边界 * **只保证文本与图像**。语音合成、音频输入、实时(Live)接口不在提供范围内, 对应参数无效。 * **服务端缓存(`cachedContent`)不保证可用。** * **内置工具不保证可用**,也不保证与官方一致。 * **走 Chat 兼容协议会丢掉 `thinkingConfig` 与 `imageConfig`**,生图务必用原生端点。 ## 在线调试 填入你自己的 API Key 即可直接发起请求,参数表与响应结构由接口定义生成。 ## 官方文档 本页只写与本网关有关的部分,参数语义的权威定义以官方为准: * [Gemini API · 生成内容](https://ai.google.dev/gemini-api/docs/text-generation) * [Gemini API · 思考](https://ai.google.dev/gemini-api/docs/thinking) * [Gemini API · 图像生成](https://ai.google.dev/gemini-api/docs/image-generation) # 在 Claude Code 里用 Grok(旧方法,已归档) 现在不需要 CC Switch 和本地路由了。运行一条命令,Claude Code 的 `/model` 菜单里就会出现这把 key 能用的 Grok 模型,直接选就行: ```bash npx --registry=https://registry.npmmirror.com @vibeapi/cli@latest setup --key sk-xxx ``` 详见 [Claude Code(VibeCLI)](https://docs.vibeapi.cn/zh/docs/coding-tools/claude-code)。下面的旧方法只留给已经按它配好、暂时不想换的用户参考。 Claude Code 只认 Anthropic 协议,而 Grok 走的是 OpenAI 兼容协议, 两边对不上——所以要用 \*\*CC Switch 的「本地路由」\*\*在本机做一次协议转换。 配置一次即可,之后在 Claude Code 里就是直接用 `grok-4.6`。 下面四步照着截图填即可,标注的红框和序号就是要动的地方。 **「本地路由」是必开项,不是可选项。** API 格式选了 `OpenAI Chat Completions` 的供应商,卡片上会挂一个 \*\*「需要路由」\*\*标记;只要路由没开,这个供应商就是不可用状态—— 这是最常见的「配好了却用不了」的原因。 ## 新增供应商 打开 CC Switch,顶部先切到 **Claude 那一栏**(① 处的图标), 再点右上角的 **+**(②)新增一个供应商。 CC Switch 主界面:切到 Claude 栏,点右上角加号新增供应商 ① 顶部切到 Claude 图标那一栏 ② 右上角 + 新增供应商。配好后卡片长这样,注意名称旁边的「需要路由」标记 ## 填写供应商信息 按下图逐项填,五个红框是关键: | 字段 | 填什么 | | --------- | -------------------------------------------------- | | 供应商名称 | 自己认得就行,例如 `VibeAPI Grok` | | 官网链接 | `https://www.vibeapi.cn` | | ① API Key | 在 VibeAPI 用 **`auto` 或 `default` 令牌分组**生成的 key | | ② 请求地址 | `https://www.vibeapi.cn/v1` **结尾不要带斜杠** | | ③ API 格式 | **OpenAI Chat Completions(需开启路由)** | | 认证字段 | `ANTHROPIC_AUTH_TOKEN`(默认,不用改) | | ④ 模型映射 | Sonnet / Opus / Fable / Haiku **四行全部填 `grok-4.6`** | | ⑤ 默认兜底模型 | 同样填 `grok-4.6` | CC Switch 编辑供应商表单:API Key、请求地址、API 格式、模型映射、默认兜底模型 编辑供应商页面。①API Key ②请求地址填到 `/v1` ③API 格式选「需开启路由」那项 ④四个模型角色全填 grok-4.6 ⑤默认兜底模型也填 grok-4.6,填完点右下角保存 **为什么四行都填 `grok-4.6`。** Claude Code 会按 Sonnet / Opus / Haiku 这些角色分别发请求(后台小任务通常走 Haiku)。 映射不填满的话,这些请求会把原始 Claude 模型名透传给上游, 上游没有这个模型就直接报错。**默认兜底模型同理,别留空。** ## 打开本地路由 回到主界面,进 **设置 → 路由**,第一项就是**本地路由**,点开它。 CC Switch 设置页的路由标签页,第一项是本地路由 设置 → 路由 → 本地路由(控制路由服务开关、查看状态与端口信息) ## 打开总开关和 Claude 开关 展开后有两个开关要打开:**路由总开关**,以及「路由启用」里的 **Claude**。状态显示**运行中**就算好了。 本地路由展开后的开关:路由总开关与 Claude 路由开关均已打开 两个红箭头就是要打开的:右上「路由总开关」、下方「路由启用 · Claude」。服务地址默认 `http://127.0.0.1:15721`,改地址或端口后要重启路由服务才生效 **最后一步**:回主界面把这个供应商切成「使用中」, **重开一个 Claude Code 会话**(旧会话读的还是旧配置), `/model` 菜单里就能看到 `grok-4.6` 了。 还是不通,按顺序查三样:路由是不是「运行中」、请求地址是不是 `https://www.vibeapi.cn/v1`(无尾斜杠)、令牌分组是不是 `auto` / `default`。 # Grok 图像 `POST /v1/images/generations` · `POST /v1/images/edits` 模型 `grok-imagine-image-2.0`,按张计费;上一代 `grok-imagine-image-quality` 同端点、同价、仍在线(官方定于 2026-11-02 退役)。 图生图不换模型:把生图模型送到 `/v1/images/edits` 就是改图。最后验证:2026-09-12。 ## 基本调用 ```bash curl https://www.vibeapi.cn/v1/images/generations \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "grok-imagine-image-2.0", "prompt": "a red apple on a wooden table, photo", "n": 1 }' ``` ```python from openai import OpenAI client = OpenAI(base_url="https://www.vibeapi.cn/v1", api_key="YOUR_API_KEY") result = client.images.generate( model="grok-imagine-image-2.0", prompt="a red apple on a wooden table, photo", n=1, ) item = result.data[0] print(item.url or "b64_json") # 临时链接,生成后立即下载落盘 ``` ```javascript import OpenAI from "openai"; const client = new OpenAI({ baseURL: "https://www.vibeapi.cn/v1", apiKey: "YOUR_API_KEY" }); const result = await client.images.generate({ model: "grok-imagine-image-2.0", prompt: "a red apple on a wooden table, photo", n: 1, }); const item = result.data[0]; console.log(item.url ?? "b64_json"); // 临时链接,生成后立即下载落盘 ``` 响应: ```json { "data": [{"url": "https://.../....jpeg", "mime_type": "image/jpeg"}], "usage": {"cost_in_usd_ticks": 600000000} } ``` 图片 URL 是临时地址,请在生成后立即下载落盘,不要直接交给终端用户或作为长期地址存储。 ## 请求参数 | 参数 | 支持 | 取值 / 说明 | | ----------------- | -- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `prompt` | ✅ | 必填 | | `n` | ✅ | `1`–`10`,超出返回 400;按张计费 | | `aspect_ratio` | ⚠️ | 官方取值 `1:1`、`16:9` / `9:16`、`4:3` / `3:4`、`3:2` / `2:3`、`2:1` / `1:2`、`19.5:9` / `9:19.5`、`20:9` / `9:20`、`21:9`、`5:2`、`auto`。**2.0 在本网关不生效**,固定 1248×832;上一代生效 | | `resolution` | ⚠️ | 官方 `1k`(默认)/ `2k`。**2.0 在本网关不生效** | | `quality` | ⚠️ | 官方仅 2.0 支持,`low` / `medium` / `auto`(默认;生成按 `low`、编辑按 `medium` 服务,按实际档计费)。本网关传 `medium` 或 `high` 都返回 200,尺寸不变,是否影响计费未验证 | | `response_format` | ✅ | `url`(默认)或 `b64_json` | | `seed` | ✅ | 固定随机种子 | | `size` | ⚠️ | 不报错但无效,改用 `aspect_ratio` | ## 画幅 `grok-imagine-image-2.0` 在本网关上**只出 1248 × 832 一种尺寸**:`aspect_ratio` 七种取值、`resolution: 2k`、`quality` 逐一试过, 既不报错也不生效。这与 xAI 官方文档(2.0 支持全部画幅与 2K)不一致,属本网关当前表现。 | `aspect_ratio` | `grok-imagine-image-2.0` | `grok-imagine-image-quality` | | ---------------------- | ------------------------ | ---------------------------- | | `1:1` | 1248 × 832 | 1024 × 1024 | | `16:9` | 1248 × 832 | 1280 × 720 | | `9:16` | 1248 × 832 | 864 × 1152 | | `4:3` | 1248 × 832 | 1152 × 864 | | `3:2` | 1248 × 832 | 1248 × 832 | | `2:3` / `3:4` / `21:9` | 1248 × 832 | — | 需要竖图、方图或任何非 3:2 画幅,用 `grok-imagine-image-quality`。它退役后由 2.0 以 `quality: low` 接管——如果届时 2.0 仍不认画幅,竖图就没有替代方案了。 上一代的尺寸口径也会变(`9:16` 曾返回 720 × 1280,现为 864 × 1152),**不要把尺寸写死在代码里**,以返回图片的实际宽高为准。 ## 出图耗时 同一句提示词、同样单张:`grok-imagine-image-2.0` **36–64 秒**,`grok-imagine-image-quality` 约 **5 秒**。 批量出图、或接在用户交互链路上的场景,按这个差距估算超时与并发。 ## 图生图 ```bash curl https://www.vibeapi.cn/v1/images/edits \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "grok-imagine-image-2.0", "prompt": "change the apple color to bright green, keep everything else identical", "image": {"type": "image_url", "url": "https://example.com/apple.jpg"} }' ``` **只收 JSON body。** OpenAI SDK 的 `images.edit()` 走 multipart 表单上传,打到本网关会 502 (`分组 auto 下模型 grok-imagine-image-2.0 的可用渠道不存在`)。改图请自行 POST JSON,图片走 URL 或 base64 内联。 `image` 字段接受四种写法,都能正常出图、计费一致: ```json "image": {"type": "image_url", "url": "https://example.com/apple.jpg"} // 文档写法 "image": {"url": "https://example.com/apple.jpg"} // 省略 type "image": "https://example.com/apple.jpg" // 直接给字符串 "image": {"type": "image_url", "url": "data:image/jpeg;base64,...."} // base64 内联 ``` 官方还支持一次最多 5 张源图(输出画幅默认跟随第一张,可用 `aspect_ratio` 覆盖)和 Files API 的 `file_id`;本网关输出仍固定 1248 × 832。 计费与文生图同档,按张;耗时 2.0 约 36–58 秒,上一代约 5 秒。 ### 一致性 当前的改图更像「重画」而不是「编辑」:同一张红苹果原图、`keep everything else identical`,两代模型六次输出全部是按提示词重新绘制的新场景—— 苹果确实变绿了,但桌面、背景、道具、构图都换了。 对一致性有硬要求的链路(换色、局部替换、批量套版),**先用自己的图跑一遍再上线**。 把必须保留的元素直接写进提示词(背景、材质、机位、光线)比只写「保留其余部分」更有效;如果目标是「同一主体动起来」, [视频](https://docs.vibeapi.cn/zh/docs/grok-videos)接口的 `image`(锁首帧)与 `reference_images` 反而更接近「保留原图」的语义。 ## 在线调试 填入你自己的 API Key 即可直接发起请求,参数表与响应结构由接口定义生成。 模型填 `grok-imagine-image-2.0`,`aspect_ratio` 等 Grok 专有参数可在请求体里手动加。改图接口只收 JSON,通用调试器走 multipart,不适用,请直接用上文的 curl。 ## 官方文档 * [xAI · Image Generation](https://docs.x.ai/developers/model-capabilities/images/generation) · [Image Editing](https://docs.x.ai/developers/model-capabilities/images/editing) · [Multi-Image Editing](https://docs.x.ai/developers/model-capabilities/images/multi-image-editing) # Grok 视频 `POST /v1/videos/generations` · `POST /v1/videos/edits` · `POST /v1/videos/extensions` 异步两段式:提交拿到任务 ID → 轮询状态 → 取片。生成用 `grok-imagine-video-1.5`,编辑与延长用不带版本号的 `grok-imagine-video`。 按秒计费,见 [Grok 对话](https://docs.vibeapi.cn/zh/docs/grok#计费方式)。最后验证:2026-09-12。 ## 基本调用 ```bash # 1. 提交 curl https://www.vibeapi.cn/v1/videos/generations \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "grok-imagine-video-1.5", "prompt": "a blue ball rolling slowly on a white floor", "duration": 6, "resolution": "720p", "aspect_ratio": "16:9" }' # 2. 轮询(每 5–6 秒一次) curl "https://www.vibeapi.cn/v1/videos/$TASK_ID" -H "Authorization: Bearer $API_KEY" # 3. 取片 curl -L "https://www.vibeapi.cn/v1/videos/$TASK_ID/content" \ -H "Authorization: Bearer $API_KEY" -o out.mp4 ``` ```python import time, requests BASE = "https://www.vibeapi.cn/v1" H = {"Authorization": "Bearer YOUR_API_KEY"} task = requests.post(f"{BASE}/videos/generations", headers=H, json={ "model": "grok-imagine-video-1.5", "prompt": "a blue ball rolling slowly on a white floor", "duration": 6, "resolution": "720p", "aspect_ratio": "16:9", }).json() while True: s = requests.get(f"{BASE}/videos/{task['id']}", headers=H).json() if s["status"] in ("completed", "failed"): break time.sleep(5) if s["status"] == "completed": mp4 = requests.get(f"{BASE}/videos/{task['id']}/content", headers=H).content open("out.mp4", "wb").write(mp4) # 视频会被回收,生成后立即落盘 ``` ```javascript import fs from "fs"; const BASE = "https://www.vibeapi.cn/v1"; const H = { Authorization: "Bearer YOUR_API_KEY", "Content-Type": "application/json" }; const sleep = (ms) => new Promise((r) => setTimeout(r, ms)); const task = await (await fetch(`${BASE}/videos/generations`, { method: "POST", headers: H, body: JSON.stringify({ model: "grok-imagine-video-1.5", prompt: "a blue ball rolling slowly on a white floor", duration: 6, resolution: "720p", aspect_ratio: "16:9", }), })).json(); let s; while (true) { s = await (await fetch(`${BASE}/videos/${task.id}`, { headers: H })).json(); if (s.status === "completed" || s.status === "failed") break; await sleep(5000); } if (s.status === "completed") { const mp4 = Buffer.from(await (await fetch(`${BASE}/videos/${task.id}/content`, { headers: H })).arrayBuffer()); fs.writeFileSync("out.mp4", mp4); // 视频会被回收,生成后立即落盘 } ``` ## 提交、轮询与取片 提交返回任务对象: ```json {"id": "task_xxx", "request_id": "task_xxx", "object": "video", "status": "queued"} ``` 轮询 `GET /v1/videos/{id}`,`status` 取值 `queued` → `in_progress` → `completed` / `failed` (本网关统一成这套;xAI 原生是 `pending` / `done` / `expired` / `failed`)。建议每 5–6 秒查一次,2 秒视频约 20–30 秒完成,6 秒约 40 秒。 ```json { "id": "task_xxx", "status": "completed", "progress": 100, "seconds": "6", "metadata": {"url": "https://www.vibeapi.cn/v1/videos/task_xxx/content"} } ``` 取片 `GET /v1/videos/{id}/content`,返回 `video/mp4` 文件流,需带同一个 `Authorization` 头。 **视频不长期保存,请务必下载落盘。** `/content` 是实时代理,每次请求都从上游拉取转发,平台只存任务元数据; 上游会回收文件,数小时后再取可能返回 `Video request not found`,此时任务状态仍是 `completed` 但内容已取不回。 ## 请求参数 | 参数 | 支持 | 取值 / 说明 | | ------------------ | -- | ------------------------------------------------------------------------------ | | `prompt` | ✅ | 文生视频必填;带 `image` / `reference_images` / `last_frame` 时可省略 | | `duration` | ✅ | `1`–`15` 秒,超出返回 400;`seconds` 是等价别名 | | `resolution` | ✅ | `480p`(默认)/ `720p` / `1080p`(1.5 的文生、图生支持 1080p;参考图生视频上限 720p) | | `aspect_ratio` | ✅ | `1:1`、`16:9`(默认)/ `9:16`、`4:3` / `3:4`、`3:2` / `2:3`;图生视频默认跟随输入图 | | `image` | ✅ | 图生视频:`{"url": "..."}`,锁定首帧 | | `reference_images` | ✅ | 参考图,支持多张,见下文 | | `last_frame` | — | 仅 1.5:锁定末帧;与 `image` 同传即首尾帧插值。未实测 | | `generate_audio` | — | 默认 `true`(成片带音轨),`false` 出静音视频。未实测 | | `reference_audios` | ⚠️ | 官方已开放预置音色,最多 3 个 `{"voice_id": "eve"}`,提示词用 `` 引用;自定义音频仍限受信任伙伴。本网关未验证 | | `size` | ⚠️ | 无效,静默忽略;改用 `resolution` | 费用 = 每秒单价 × 实际输出秒数 × 分组倍率。按实际产出秒数结算,生成失败或超时全额退款;分辨率不影响单价。 ## 多图生成视频 `image` 与 `reference_images` 都能传图,语义不同: ```text // image:锁定首帧,视频从这张图开始运动 {"prompt": "make it spin", "image": {"url": "https://..."}} // reference_images:引导内容与风格,不锁首帧,用 引用 {"prompt": " slowly rotating", "reference_images": [{"url": "https://..."}]} ``` 多图有三种写法,都能正常出片;提示词里用 `` `` 指代对应图片: ```json // 写法一 · reference_images(推荐,与单图一致) { "model": "grok-imagine-video-1.5", "prompt": " and together, slow pan", "reference_images": [{"url": "https://..."}, {"url": "https://..."}], "duration": 4 } // 写法二 · image_urls(字符串数组) {"prompt": "...", "image_urls": ["https://...", "https://..."]} // 写法三 · frame_images(按帧引导) {"prompt": "...", "frame_images": ["https://...", "https://..."]} ``` **每张图必须可公网直接获取。** 许多站点禁止外链引用,会失败并返回 `Failed to download the provided image ... the image host returned HTTP status 400`;用自有对象存储,或用生图接口返回的图片 URL。 ## 视频编辑与延长 与生成共用同一套异步流程。**模型都用不带版本号的 `grok-imagine-video`**,`-1.5` 在这两个接口上返回 400。 | 写法 | 模型 | 结果 | | ------------------------------------------------------ | -------------------------------------- | -------------------------------------------------------- | | `POST /v1/videos/edits` + `video` | `grok-imagine-video` | ✅ 成片与源片等长(官方端点) | | `POST /v1/videos/edits` + `video` | `grok-imagine-video-1.5` | ❌ 400 `Video editing is not supported for this model.` | | `POST /v1/videos/generations` + `video`(旧写法) | `grok-imagine-video-1.5`,不传 `duration` | ✅ 但成片时长翻倍(4 秒变 8 秒) | | `POST /v1/videos/extensions` + `video` + `duration: 3` | `grok-imagine-video` | ✅ 成片 7 秒 = 4 + 3 | | `POST /v1/videos/extensions` | `grok-imagine-video-1.5` | ❌ 400 `Video extension is not supported for this model.` | ### 编辑 ```bash curl https://www.vibeapi.cn/v1/videos/edits \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "grok-imagine-video", "prompt": "Add a small blue ribbon tied around the apple", "video": {"url": "https://.../source.mp4"} }' ``` 编辑不接受 `duration` / `aspect_ratio` / `resolution`,输出继承源片,分辨率上限 720p、时长上限 8.7 秒。 `video.url` 可以是公网直链、`data:video/mp4;base64,...` 或 Files API 的 `file_id`。 旧写法 `/v1/videos/generations` + `video` 仍能提交,但用 1.5 且不传 `duration` 时成片翻倍、计费也翻倍;不建议再用。 ### 延长 ```bash curl https://www.vibeapi.cn/v1/videos/extensions \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "grok-imagine-video", "prompt": "The camera slowly zooms out revealing the whole table", "duration": 4, "video": {"url": "https://.../source.mp4"} }' ``` `duration` **只是延长部分的秒数**:4 秒源片 + `duration: 3` = 7 秒成片,轮询响应里的 `seconds` 也只报延长部分。 编辑、延长各自产出的视频重新按秒计费。 ## 已知限制(截至 2026-09-21) | 限制 | 说明 | 怎么办 | | ---------------------------------- | --------------------------------------------------------------------- | --------------------------------------- | | **10 秒以上不稳定** | `grok-imagine-video-1.5` 请求 15 秒时经常丢件或 400 / 404,失败全额退款 | 对外按 **≤ 10 秒** 设计;要更长先出 10 秒再走[延长](#延长) | | **大文件取片** | 720p 10 秒约 15–20 MB,上游回源只有几十 KB/s,早期版本曾在 60 秒处截断成残片(2026-09-15 已修) | 下载超时按 3 分钟设,校验文件能完整播放再入库 | | **视频不长期保存** | 上游数小时后回收,`/content` 返回 `Video request not found`,任务状态仍是 `completed` | 完成后立即下载 | | **编辑 / 延长只认 `grok-imagine-video`** | `-1.5` 在 `/edits`、`/extensions` 上 400;旧写法不传 `duration` 成片与计费翻倍 | 见[视频编辑与延长](#视频编辑与延长) | | **参数错误返回慢** | 上游拒绝的参数(如不支持的组合)网关会换线重试,可能十几秒后才收到 500 | 先按本页参数表自检,`size` 一类无效参数直接别传 | | **未实测项** | `generate_audio` / `last_frame` / `reference_audios` 预置音色官方已开放,本网关未验证 | 用之前先小样本试 | ## 商业方向样片 所有底图都是用 `gpt-image-2.5-sunburst` 出的(横版 2560×1440、竖版 1440×2560), 再作为首帧 / 参考图交给本页模型,提示词只写运镜与动态。成片保留原始音轨。 Grok 出片最快(1–2 分钟),8–10 秒最稳,适合竖版信息流广告快速出多版;15 秒目前不稳定。 ## 官方文档 * [xAI · Video Generation](https://docs.x.ai/developers/model-capabilities/video/generation) · [Image-to-Video](https://docs.x.ai/developers/model-capabilities/video/image-to-video) · [Reference-to-Video](https://docs.x.ai/developers/model-capabilities/video/reference-to-video) · [Video Editing](https://docs.x.ai/developers/model-capabilities/video/editing) · [Video Extension](https://docs.x.ai/developers/model-capabilities/video/extension) # Grok 对话 `POST /v1/chat/completions` · `POST /v1/responses` xAI 的 Grok 系列在本网关上覆盖对话、图像、视频三类能力,共 7 个模型 ID,全部走 OpenAI 兼容协议: `base_url` 填 `https://www.vibeapi.cn/v1`,`openai` SDK 直接用。**它的参数支持与 OpenAI 系差别不小**: `stop`、`presence_penalty`、`frequency_penalty`、`n`、`logprobs` 传了都返回 200,但都不生效。本页讲对话与全系列共用的模型、计费、错误; 生图见 [Grok 图像](https://docs.vibeapi.cn/zh/docs/grok-images),视频见 [Grok 视频](https://docs.vibeapi.cn/zh/docs/grok-videos),在 Claude Code 里使用,用 [VibeCLI 一条命令配好](https://docs.vibeapi.cn/zh/docs/coding-tools/claude-code),`/model` 里直接选 Grok。 本页结论来自对本网关的真实调用,并对照 [docs.x.ai](https://docs.x.ai) 逐条核对;与官方口径不一致之处均标注「实测」。最后验证:2026-10-13(联网搜索)、2026-09-23(其余)。 ## 基本调用 ```bash curl -N https://www.vibeapi.cn/v1/chat/completions \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "grok-4.7", "messages": [{"role": "user", "content": "用一句话解释量子纠缠"}], "stream": true }' ``` ```python from openai import OpenAI client = OpenAI(base_url="https://www.vibeapi.cn/v1", api_key="YOUR_API_KEY") stream = client.chat.completions.create( model="grok-4.7", messages=[{"role": "user", "content": "用一句话解释量子纠缠"}], stream=True, ) for chunk in stream: print(chunk.choices[0].delta.content or "", end="", flush=True) ``` ```javascript import OpenAI from "openai"; const client = new OpenAI({ baseURL: "https://www.vibeapi.cn/v1", apiKey: "YOUR_API_KEY" }); const stream = await client.chat.completions.create({ model: "grok-4.7", messages: [{ role: "user", content: "用一句话解释量子纠缠" }], stream: true, }); for await (const chunk of stream) { process.stdout.write(chunk.choices[0]?.delta?.content ?? ""); } ``` ## 模型 | 模型 | 能力 | 端点 | 计费 | | ---------------------------- | ------------------------------ | --------------------------------------------- | ------------------- | | `grok-4.7` | 对话 / 推理,最新一代 | `/v1/chat/completions` · `/v1/responses` | 按 token,两档,与 4.6 同价 | | `grok-4.6` | 对话 / 推理 | 同上 | 按 token,两档 | | `grok-4.5` | 对话 / 推理,上上代 | 同上 | 按 token,两档,与 4.6 同价 | | `grok-imagine-image-2.0` | 文生图 + 图生图,当前主力 | `/v1/images/generations` · `/v1/images/edits` | 按张 | | `grok-imagine-image-quality` | 文生图 + 图生图,上一代 | 同上 | 按张 | | `grok-imagine-video-1.5` | 文生 / 图生 / 参考图生视频 | `/v1/videos/generations` | **按秒** | | `grok-imagine-video` | **视频编辑 + 视频延长**(这两个接口只接受这个模型名) | `/v1/videos/edits` · `/v1/videos/extensions` | **按秒** | `grok-imagine-image-quality` 官方定于 **2026-11-02 退役**,之后这个模型名由 2.0 以 `quality: low` 接管,请求与响应形状不变。 它目前是唯一能指定画幅的 Grok 图像模型,依赖竖图 / 方图的链路要提前打算,见[图像](https://docs.vibeapi.cn/zh/docs/grok-images#画幅)。 ## 计费方式 单价随分组倍率变动,一律以[价格页](https://www.vibeapi.cn/pricing)为准;这里只讲计费方式,也就是写代码时会影响费用的那几件事。 **对话按 token,分两档。** 单次请求的输入达到 **200K token** 时进入第二档,输入、输出、缓存读取单价全部翻倍。 `grok-4.7`、`grok-4.6`、`grok-4.5` 三个定价相同,包括这条分档规则。4.6 与 4.5 都能吃下超长上下文(实测 210K 输入正常返回), 越界的是费用档位,不是上下文长度——把长文档一次性塞进 prompt 之前先算一遍账,能拆到 200K 以内就拆。 **图像按张。** `n` 张就是 `n` 份费用。图生图复用生图模型,价格与文生图同档。 **联网搜索按次。** 走 Responses 入口时,`web_search` 按实际搜索次数计费,每千次 5 美元;`x_search` 按抓取的 X 帖子(每千条 5 美元)和用户资料(每千份 10 美元)计。都要乘分组倍率,调用日志里写明次数与费用。模型没有真的去搜就不收这部分。 **视频按秒,不是按次。** 价格页给的是每秒单价,一条 6 秒视频要乘 6;按实际产出秒数结算,生成失败或超时全额退款。 编辑、延长各自产出的视频重新计费。 ## 新旧两代怎么选 | 场景 | 选谁 | 原因 | | ----------- | ---------------------------- | --------------------------------------------------------------------------------- | | 长时 Agent、编码 | `grok-4.7` | 与 4.6 同价,参数支持一致(2026-09-23 逐项复测);每次请求多带约 1,000 个隐藏输入 token,见[推理 token](#推理-token) | | 短问答、高频小请求 | `grok-4.6` | 隐藏输入约 210 token,单次成本低于 4.7;与 4.5 同价同参数,没有留在 4.5 的理由 | | 横图、默认画幅 | `grok-imagine-image-2.0` | 固定输出 1248×832 | | 竖图、方图、指定画幅 | `grok-imagine-image-quality` | 2.0 在本网关不认 `aspect_ratio`,只有它能指定画幅;注意 11-02 退役 | | 批量出图、对延迟敏感 | `grok-imagine-image-quality` | 单张约 5 秒;2.0 约 40–60 秒 | ## 请求参数 | 参数 | 支持 | 说明 | | ---------------------------------------- | -- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | | `messages` | ✅ | 必填 | | `max_tokens` | ✅ | 只约束可见回复,推理 token 另算:设 20 时实得 20 个可见 token + 96 个推理 token | | `temperature` / `top_p` | ✅ | | | `n` | ⚠️ | 返回 200,但只回 1 个 choice(4.5 / 4.6 / 4.7 相同;2026-09-12 时 `n=2` 还能返回 2 个)。要多个候选请并发多次 | | `seed` | ✅ | 接受,但推理模型不保证复现,见下文 | | `stream` | ✅ | SSE 流式 | | `tools` / `tool_choice` | ✅ | 标准 Function Calling。Chat 接口不支持 xAI 的内置搜索(带上 `web_search` / `x_search` 会返回 422),网关会移除 `web_search`;要联网请走 [Responses 入口](#联网搜索) | | `response_format` | ✅ | `{"type": "json_object"}` 可用 | | `reasoning_effort` | ✅ | `low` / `medium` / `high`(默认)/ `xhigh`,四档均可用(4.6 实测 reasoning\_tokens 约 99 / 161 / 157 / 212);`none` 返回 200 但推理照常(仍有约 200 个 reasoning\_tokens),推理不可关闭 | | `logprobs` / `top_logprobs` | ⚠️ | 返回 200 但字段为 null,**静默忽略** | | `stop` | ⚠️ | 返回 200,**静默忽略**:停止词照常出现在输出里 | | `presence_penalty` / `frequency_penalty` | ⚠️ | 返回 200,从响应上看不出是否生效,按不生效处理 | **`stop` 不再报错,但也不生效。** 2026-09-12 时这三个参数传了直接 400;2026-09-23 复测 4.5 / 4.6 / 4.7 都改成返回 200、 输出不受约束。依赖停止序列截断的逻辑,要改成在客户端截断。 多轮对话建议带上 `prompt_cache_key`(Responses)或请求头 `x-grok-conv-id`(Chat),把同一会话路由到同一台服务器以稳定命中缓存; 否则常按全价输入计费。 ## Responses 入口 xAI 官方把 Responses API 列为首选入口,本网关可用: ```bash curl https://www.vibeapi.cn/v1/responses \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "grok-4.7", "input": [{"role": "user", "content": "How do stars form?"}], "reasoning": {"effort": "high"} }' ``` | | `/v1/chat/completions` | `/v1/responses` | | ---- | ---------------------- | --------------------------- | | 会话状态 | 无状态,每次重发全部历史 | 官方支持服务端保存 | | 多轮 | 自行拼接 `messages` | 官方支持 `previous_response_id` | | 推理档位 | `reasoning_effort` | `reasoning.effort` | 本网关返回 `store: false`,即服务端留存未开启,多轮对话仍需自行携带历史(xAI 官方默认 `store: true` 保存 30 天,这是网关侧差异)。 ### 联网搜索 Responses 入口支持 xAI 的两个服务端搜索工具,由 xAI 服务端执行,结果直接写进回答: * `web_search`:网页搜索。回复的 `output` 里每搜一次有一个 `web_search_call` 条目。 * `x_search`:搜 X(Twitter)上的帖子和用户资料。 ```bash curl https://www.vibeapi.cn/v1/responses \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "grok-4.7", "input": "联网搜一条今天的科技新闻,一句话,带出处", "tools": [{"type": "web_search"}] }' ``` * OpenAI 规范里 `web_search` 的 `external_web_access`、`search_context_size` 两个字段 xAI 不支持,网关转发前会删掉,工具本身保留。Codex 默认会带 `external_web_access`,所以 Codex 接 Grok 可以直接联网。 * `user_location`、`filters`(如 `allowed_domains`)可用。 * 旧写法 `web_search_preview` 不报错,但不会真的执行搜索,请用 `web_search`。 * Chat 接口(`/v1/chat/completions`)不支持这两个工具。 * 费用见上文[计费方式](#计费方式)。 ## 推理 token 三个对话模型都是推理模型,`usage` 里会有推理消耗: ```json "usage": { "prompt_tokens": 212, "completion_tokens": 65, "completion_tokens_details": { "reasoning_tokens": 63 }, "prompt_tokens_details": { "cached_tokens": 128 } } ``` 上例一句「回复 PONG」实际消耗 65 个输出 token,其中 **63 个是推理 token**,可见回复只占 2 个。 按可见回复长度估算成本会严重偏低,请以 `usage` 为准;`reasoning_effort: "low"` 能明显压低这部分开销。 固定 `seed` 与 `temperature=0` 连续调用,推理 token 数与措辞仍会波动(同一句提示词四次分别 282 / 286 / 311 / 294)。 推理模型不保证确定性复现,需要稳定输出的场景请在应用层处理。 **隐藏输入 token。** 上例只发了一句话,`prompt_tokens` 却是 212——每次请求都带着一段看不见的系统提示。 `grok-4.7` 的这部分更大:发一句 `hi`,`prompt_tokens` 是 1,243,其中 1,152 命中缓存(按缓存读取单价计费)。 估算成本时把这段固定开销算进去,高频短请求用 4.6 更省。 ## 真实响应示例 最后一条是传了 `stop` 的真实响应:返回 200,回复末尾仍是停止词「。」。 ## 容量抖动 Grok 图片 / 视频的号池容量有限,突发并发会失败,而且失败表现与「参数不被支持」很像,容易误判: 同时提交 8 个视频任务,提交全部返回 200,生成阶段整批 `failed`;相同参数单发或并发 ≤ 2 时全部成功。 失败信息也很笼统(`upstream returned error` / `no eligible account`)。 视频提交并发控制在 2 以内,失败用指数退避重试 3–5 次,不要因单次失败就判定某参数不可用。 ## 错误速查 | 现象 | 原因 | 处理 | | --------------------------------------------------------------------------------------------------------- | --------------------------------------------------- | -------------------------------------------- | | 设了 `stop`,输出没在停止词处截断 | Grok 静默忽略 `stop` | 在客户端截断 | | `n=2` 只拿到 1 个 choice | Grok 现在不执行 `n` | 并发多次请求 | | `reasoning_effort: none` 仍有 reasoning\_tokens | 推理不可关闭 | 用 `low` 压低开销 | | 400 `seconds must be between 1 and 15` | 视频时长越界 | 调整至 1–15 | | 400 `The number of images to generate (n) must be between 1 and 10 inclusive` | 生图数量越界 | 调整至 1–10 | | 非流式请求返回空的 `text/event-stream`,正文只有 `data: [DONE]` | 上游抖动,一次性空响应 | 直接重试 | | 生图 `aspect_ratio` / `resolution` / `quality` 设了不生效 | `grok-imagine-image-2.0` 在本网关不认这些参数 | 指定画幅用 `grok-imagine-image-quality`(11-02 退役) | | 视频 `failed` 但参数无误 | 容量抖动 | 退避重试 | | 视频 `failed` + `image_download_error` | 参考图无法公网直接获取 | 换可直接引用的图床 | | 改图 502 `可用渠道不存在` | 用了 multipart/form-data 上传图片 | 改成 JSON body,图片走 URL 或 base64 内联 | | `/content` 502 或 `Video request not found`,任务却是 `completed` | 视频已被回收 | 无法找回,需重新生成;今后生成完立即下载落盘 | | 400 `Video editing is not supported for this model.` / `Video extension is not supported for this model.` | 编辑或延长接口传了 `grok-imagine-video-1.5` | 换成不带版本号的 `grok-imagine-video` | | 视频编辑后时长翻倍(4 秒变 8 秒) | 走了旧写法 `/generations` + `video` 且用 1.5 不传 `duration` | 改用 `/v1/videos/edits` + `grok-imagine-video` | ## 迁移 OpenAI 代码的检查清单 * `stop` / `presence_penalty` / `frequency_penalty` / `n` / `logprobs` 传了不报错也不生效,依赖它们的逻辑改到客户端 * `reasoning_effort` 用 `low` / `medium` / `high` / `xhigh`;`none` 不报错,但关不掉推理 * 预算按 `usage` 里的 `reasoning_tokens` 与 `prompt_tokens` 重新估算——推理 token 和隐藏系统提示都可能远超可见内容 * 生图把 `size` 换成 `aspect_ratio`;用 2.0 时不要依赖画幅,固定 1248×832 * 改图改成 JSON body,不要用 SDK 的 multipart `images.edit()` * 视频把 `size` 换成 `resolution`,改成异步轮询,生成完立即下载 * 视频编辑走 `/v1/videos/edits`、延长走 `/v1/videos/extensions`,模型都写 `grok-imagine-video` ## 能力边界 * `stop`、`presence_penalty`、`frequency_penalty`、`n`、`logprobs` 返回 200 但不生效。 * 推理不可关闭,`reasoning_effort: none` 返回 200 但照常推理。 * Chat 接口不支持内置搜索,`web_search` 会被网关移除;联网请用 Responses 的 `web_search` / `x_search`(按次计费)。 * Responses 的服务端留存未开,`store` 恒为 `false`,多轮仍需自带历史。 * `grok-imagine-image-2.0` 不认 `aspect_ratio` / `resolution` / `quality`,只出 1248×832。 * `size` 在图像与视频接口里都被静默忽略,改用 `aspect_ratio` / `resolution`。 * 视频文件会被回收,生成完成后立即下载落盘,之后 `/content` 可能取不到。 * `grok-imagine-edit` 已下线,代码里还有这个模型名的请移除。 ## 在线调试 填入你自己的 API Key 即可直接发起请求,参数表与响应结构由接口定义生成。 模型填 `grok-4.7` 或 `grok-4.6`。 ### Chat Completions ### Responses ## 官方文档 * [xAI · Grok 4.6](https://docs.x.ai/developers/grok-4-6) · [Reasoning](https://docs.x.ai/developers/model-capabilities/text/reasoning) · [Models](https://docs.x.ai/developers/models) · [Pricing](https://docs.x.ai/developers/pricing) · [Release Notes](https://docs.x.ai/developers/release-notes) # 图像生成概览 图像生成分散在三个端点上,先确认你要的模型走哪一个: | 模型 | 端点 | 页面 | | --------------------------------------------------------------------------------------------- | --------------------------------------------- | ----------------------------------------------- | | `gpt-image-2` · `gpt-image-2.5-flare` · `gpt-image-2.5-sunburst` | `/v1/images/generations` · `/v1/images/edits` | [GPT 图像 · Image API](https://docs.vibeapi.cn/zh/docs/images) | | `gpt-6-astra` + `image_generation` 工具 | `/v1/responses` | [GPT 图像 · Responses](https://docs.vibeapi.cn/zh/docs/images-responses) | | `gemini-3-pro-image` · `gemini-3.1-flash-image` · `gemini-3.1-flash-lite-image`(含 `-preview`) | `/v1beta/models/{model}:generateContent` | [Gemini 图像生成](https://docs.vibeapi.cn/zh/docs/gemini-images) | | `grok-imagine-image-2.0` · `grok-imagine-image-quality` | `/v1/images/generations` · `/v1/images/edits` | [Grok 图像](https://docs.vibeapi.cn/zh/docs/grok-images) | | `wan3.0-image-*` | `/v1/videos`(图生视频,不是出图) | [万相 3.0](https://docs.vibeapi.cn/zh/docs/videos-wan) | ## GPT 的两套入口 | | Image API | Responses | | ------------------ | -------------------------------------- | --------------------------------- | | 调用模型 | `gpt-image-2` / `gpt-image-2.5-*`,直接指定 | `gpt-6-astra` 内部调度,无法指定 | | `size` / `quality` | 按请求执行,4K + high 精确返回 | 被改写:要 4K/high 实得 1536×1024/medium | | 耗时 | 4K + high 约 45–57 秒 | 40–170 秒 | | 多轮编辑 / 自动优化提示词 | 无 | 有 | **默认用 Image API**;只在需要对话式多轮编辑时用 Responses。Image API 上三个模型的差别(`n`、透明背景、耗时)见[怎么选](https://docs.vibeapi.cn/zh/docs/images#三个-gpt-图像模型怎么选)。 ## 三条通用约束 * **图片返回有两种形态。** Image API 的 `data[0]` 可能是 `b64_json`(内联)也可能是 `url`(临时链接,尽快下载),`response_format` 不决定形态,两种都要处理。 * **Gemini 生图必须走原生端点。** 走 Chat 兼容协议能出图,但 `imageConfig`(画幅、分辨率)会在协议转换中丢掉。 * **Grok 2.0 画幅固定 1248×832。** 需要竖图用 `grok-imagine-image-quality`,它 2026-11-02 退役。 ## 实测样图 各页附真实调用产出的样图:GPT 六主题 4K(东方水墨、仙侠、工笔重彩、空间站、巨构城市、戴森云)在 [Image API 页](https://docs.vibeapi.cn/zh/docs/images#实测4k-最高画质), Responses 降级对照在 [Responses 页](https://docs.vibeapi.cn/zh/docs/images-responses#与-image-api-的差异)。缩略图点击可放大。 # GPT 图像 · Responses `POST /v1/responses` GPT 图像的第二套入口:主线模型 `gpt-6-astra` 理解意图、自动优化提示词,再调度 `image_generation` 工具出图,SSE 流式回传、心跳保活。 它的价值在**对话式多轮编辑**和自动 `revised_prompt`;但它无法指定图像模型,`size` / `quality` 会被改写——要 4K/high 实得 1536×1024/medium。 **默认生图请用 [Image API](https://docs.vibeapi.cn/zh/docs/images)**,那边按请求精确返回 4K。 本页结论来自对本网关的真实调用,最后验证:2026-09-12。 ## 基本调用 请求发出后约 3\~4 秒即开始回传事件,读流式响应时客户端超时建议设到 300 秒以上。 ```bash curl -N -sS "https://www.vibeapi.cn/v1/responses" \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "gpt-6-astra", "input": "一只灰色虎斑猫抱着戴橙色围巾的水獭,温暖的童书插画风格", "stream": true, "tools": [{"type": "image_generation"}] }' ``` ```python from openai import OpenAI import base64 client = OpenAI(base_url="https://www.vibeapi.cn/v1", api_key="YOUR_API_KEY") stream = client.responses.create( model="gpt-6-astra", input="一只灰色虎斑猫抱着戴橙色围巾的水獭,温暖的童书插画风格", tools=[{"type": "image_generation"}], stream=True, ) for event in stream: if event.type == "response.image_generation_call.partial_image": with open("out.png", "wb") as f: f.write(base64.b64decode(event.partial_image_b64)) print("已生成 out.png") ``` ```javascript import OpenAI from "openai"; import fs from "fs"; const client = new OpenAI({ baseURL: "https://www.vibeapi.cn/v1", apiKey: "YOUR_API_KEY", }); const stream = await client.responses.create({ model: "gpt-6-astra", input: "一只灰色虎斑猫抱着戴橙色围巾的水獭,温暖的童书插画风格", tools: [{ type: "image_generation" }], stream: true, }); for await (const event of stream) { if (event.type === "response.image_generation_call.partial_image") { fs.writeFileSync("out.png", Buffer.from(event.partial_image_b64, "base64")); } } ``` 图片数据位于 `response.image_generation_call.partial_image` 事件的 `partial_image_b64` 字段(base64 编码)。完整事件序列见[流式事件序列](#流式事件序列)。 实测输出(约 30 秒): ## 与 Image API 的差异 | | Responses(本页) | Image API | | ------------------ | -------------------------------------- | -------------------------------------- | | 调用模型 | `gpt-6-astra`,内部调度图像模型,无法指定 | `gpt-image-2` / `gpt-image-2.5-*`,直接指定 | | `size` / `quality` | 被改写:要 4K/high 实得 1536×1024/medium | 按请求执行 | | 耗时 | 40–170 秒 | 4K + high 约 45–57 秒 | | 提示词优化 | 自动,返回 `revised_prompt` | 无 | | 多轮编辑 | 支持,上下文携带图片 | 不支持 | | 参考图 | URL / base64 / `file_id`;URL 由上游主动下载 | multipart 文件上传 | | 返回 | SSE 事件里的 base64;非流式在 `output[].result` | `data[0].b64_json` 或 `url` | | 流式 | 支持,心跳保活,大图不中断 | 同步返回 | 实测:同样请求 `3840x2160` + `high`,三个主题都被降到 1536×1024 / medium: | 主题 | 耗时 | 实返 size / quality | | ---- | ------- | ---------------------- | | 东方水墨 | 40.2 s | `1536x1024` / `medium` | | 工笔重彩 | 166.7 s | `1536x1024` / `medium` | | 仙侠 | 171.4 s | `1536x1024` / `medium` | ## 请求结构 ``` POST https://www.vibeapi.cn/v1/responses Authorization: Bearer Content-Type: application/json ``` 顶层请求字段: | 字段 | 类型 | 必填 | 默认 | 说明 | | ---------------------- | --------------- | ----- | ------- | ------------------------------------------------------------------------------------------------ | | `model` | string | 是 | — | 主线模型,生成图片固定使用 `gpt-6-astra` | | `input` | string \| array | 是 | — | 用户输入。字符串表示纯文本;数组表示多模态(文本 + 图片)。详见 [input 字段详解](#input-字段) | | `tools` | array | 是(生图) | — | 内置工具列表,生成图片须包含 `{"type":"image_generation"}`。详见 [image\_generation 工具参数](#image_generation-工具参数) | | `stream` | boolean | 否 | `false` | `true` 启用 SSE 流式(推荐);`false` 一次性返回完整 JSON | | `instructions` | string | 否 | — | 系统级指令。可选,不传也能正常生成 | | `previous_response_id` | string | 否 | — | 关联上一次响应以实现多轮。本网关不支持,见[多轮编辑](#多轮编辑与参考图输入) | 最小请求(字符串形式的 `input`): ```json { "model": "gpt-6-astra", "input": "a red apple on a wooden table", "stream": true, "tools": [{ "type": "image_generation" }] } ``` 完整请求(数组形式的 `input` + 全参数工具): ```json { "model": "gpt-6-astra", "instructions": "You are a helpful image generation assistant.", "input": [ { "role": "user", "content": [{ "type": "input_text", "text": "Draw a watercolor winter landscape" }] } ], "stream": true, "tools": [ { "type": "image_generation", "quality": "high", "size": "1536x1024", "output_format": "webp", "output_compression": 50, "moderation": "low", "partial_images": 2 } ] } ``` ### `input` 字段 `input` 有两种写法,本网关均已对齐 OpenAI 协议: 写法一,字符串(最简,纯文本生成): ```json "input": "a red apple on a wooden table" ``` 写法二,数组(多模态,文本 + 参考图,编辑与 Vision 必用): ```json "input": [ { "role": "user", "content": [ { "type": "input_text", "text": "把这张图改成水彩风格" }, { "type": "input_image", "image_url": "https://.../photo.jpg" } ] } ] ``` `content` 数组中每个 part 的类型: | part 类型 | 字段 | 说明 | | ------------- | ------------------- | ------------------------------------------------- | | `input_text` | `text`(string) | 文本指令 | | `input_image` | `image_url`(string) | 参考图:公网 URL,或 `data:image/...;base64,...` data URI | | `input_image` | `file_id`(string) | 参考图:经 Files API 上传后得到的文件 ID | | `input_image` | `detail`(string) | 仅图片理解时使用,控制理解精度,见 [Vision 图片理解](#vision-图片理解) | 一个 `content` 数组可包含多个 `input_image`(多参考图)。三种参考图写法的完整示例见 [多轮编辑与参考图输入](#多轮编辑与参考图输入)。 ### `image_generation` 工具参数 生成能力通过 `tools` 数组中的 `image_generation` 对象配置。逐字段说明如下: | 字段 | 类型 | 取值 | 默认 | 说明 | | -------------------- | ------ | ----------------------------------------- | ------ | -------------------------------------------- | | `type` | string | `"image_generation"` | — | 必填,固定值,声明启用生成工具 | | `quality` | string | `low` / `medium` / `high` / `auto` | `auto` | 渲染质量。`low` 最快(草稿、缩略图),`high` 最精细(耗时最长) | | `size` | string | 同 [Image API](https://docs.vibeapi.cn/zh/docs/images#输出定制) 的尺寸约束 | `auto` | 期望尺寸;本网关会改写,以响应实际尺寸为准 | | `output_format` | string | `png` / `jpeg` / `webp` | `png` | 输出格式。Responses 工具遵循该参数(实测 `webp` 返回真正的 WebP) | | `output_compression` | number | `0`–`100` | — | 压缩级别(仅 `jpeg` / `webp`)。`50` 表示压缩 50% | | `moderation` | string | `auto` / `low` | `auto` | 内容审核强度,`low` 更宽松 | | `action` | string | `auto` / `generate` / `edit` | `auto` | 强制生成或编辑,详见下文与 [多轮编辑与参考图输入](#多轮编辑与参考图输入) | | `partial_images` | number | `0`–`3` | — | 流式过程中下发的中间预览帧数。`0` 表示只下发最终图 | | `input_image_mask` | object | `{"file_id": "..."}` | — | 蒙版编辑,蒙版区域被重绘,详见 [多轮编辑与参考图输入](#多轮编辑与参考图输入) | 逐字段示例: `quality`——三档质量(其余参数固定): ```json { "type": "image_generation", "quality": "low" } // 快,草稿 { "type": "image_generation", "quality": "high" } // 慢,成片 ``` `output_format` + `output_compression`——输出 WebP 并压缩 50%: ```json { "type": "image_generation", "output_format": "webp", "output_compression": 50 } ``` `moderation`——放宽审核: ```json { "type": "image_generation", "moderation": "low" } ``` `action`——强制行为(默认 `auto` 由模型自行决定生成还是编辑): ```json { "type": "image_generation", "action": "generate" } // 总是新建图片 { "type": "image_generation", "action": "edit" } // 强制编辑上下文中的图片;无图则报错 ``` `partial_images`——流式下发 2 帧中间预览: ```json { "type": "image_generation", "partial_images": 2 } ``` 全参数组合的真实请求与响应见[流式事件序列](#流式事件序列);`size` / `quality` 在本页会被改写,见[与 Image API 的差异](#与-image-api-的差异)。 ## 流式与非流式 | | 流式 `stream:true`(推荐) | 非流式 `stream:false` | | --------- | --------------------------------------- | ------------------------------------------- | | 返回 | SSE 事件流,逐帧回传 | 一次性完整 JSON | | 取图 | `partial_image` 事件的 `partial_image_b64` | `output[]` 中 `image_generation_call.result` | | 首字节 | 3\~4 秒 | 渲染完成后才返回 | | 大图 / high | 心跳保活,不中断 | 存在 `504` 风险 | | 实测耗时 | — | 约 80\~140 秒(medium 1K) | > 读流式响应时,客户端超时建议设到 300 秒以上:大图渲染常要好几分钟,默认的短超时(比如 60 秒)会把请求自己掐断,反而拿不到图。 非流式真实响应结构(`gpt-6-astra` + medium,`result` 已截断): ```json { "id": "resp_0bb33694b11513cf016a3d4bb1d4a0819b918d29bc82aa4358", "object": "response", "status": "completed", "model": "gpt-6-astra", "output": [ { "id": "ig_0bb33694b11513cf016a3d4bbb4b54819b9ba7731790d4d87d", "type": "image_generation_call", "status": "generating", "action": "generate", "background": "opaque", "output_format": "png", "quality": "medium", "result": "iVBORw0KGgoAAAANSU...<3493728 字节 base64>", "revised_prompt": "Oil painting still life...<407 字符>", "size": "1400x1123" }, { "type": "message", "role": "assistant", "content": [{ "type": "output_text", "text": "" }] } ], "reasoning": { "effort": "medium" }, "service_tier": "default", "store": false } ``` 非流式取图代码: ```python resp = client.responses.create( model="gpt-6-astra", input="An oil painting still life of fruit and wine, Rembrandt lighting", tools=[{"type": "image_generation", "quality": "medium"}], ) for item in resp.output: if item.type == "image_generation_call": with open("out.png", "wb") as f: f.write(base64.b64decode(item.result)) print("revised_prompt:", item.revised_prompt) print("实际尺寸:", item.size) # 实际尺寸由上游裁定,与请求不同 ``` ### 流式事件序列 完整 SSE 事件类型(实测自全参数流式请求): | 事件 `type` | 关键字段 | 含义 | | ------------------------------------------------------------------------ | ------------------------------------------------------------------------------------- | ---------------------------- | | `response.created` | `response.id` | 请求创建,获得 response id | | `response.in_progress` | — | 开始处理 | | `response.output_item.added` | `item.id`(`ig_…`)、`output_index` | 新建一个 image\_generation\_call | | `response.image_generation_call.in_progress` | `item_id` | 图片生成中 | | `response.image_generation_call.generating` | `item_id` | 正在渲染 | | `response.image_generation_call.partial_image` | `partial_image_b64`、`partial_image_index`、`output_index`、`background`、`output_format` | 图片数据(中间帧或最终帧) | | `keepalive` | `sequence_number` | 心跳,长时间渲染时出现,用于保持连接 | | `response.output_item.done` | `item.revised_prompt` | image\_generation\_call 完成 | | `response.content_part.added` / `output_text.done` / `content_part.done` | — | 附带的文本消息(生成图片时通常为空串) | | `response.completed` | `response.output[]` | 完成,包含最终 output 数组 | 真实事件流(`partial_image_b64` 已截断): ``` data: {"type":"response.created","response":{"id":"resp_04a3…","status":"in_progress"}} data: {"type":"response.in_progress","response":{...}} data: {"type":"response.output_item.added","item":{"id":"ig_04a3…","type":"image_generation_call","status":"in_progress"},"output_index":0,"sequence_number":2} data: {"type":"response.image_generation_call.in_progress","item_id":"ig_04a3…","output_index":0,"sequence_number":3} data: {"type":"response.image_generation_call.generating","item_id":"ig_04a3…","output_index":0,"sequence_number":4} data: {"type":"response.image_generation_call.partial_image","background":"opaque","item_id":"ig_04a3…","output_format":"webp","output_index":0,"partial_image_b64":"iVBORw0KGgo…<460KB>"} data: {"type":"keepalive","sequence_number":6} data: {"type":"response.image_generation_call.partial_image","background":"opaque","output_format":"webp","output_index":0,"partial_image_b64":"UklGRpzTAwB…<380KB>"} data: {"type":"response.output_item.done","item":{"id":"ig_04a3…","type":"image_generation_call","status":"generating","action":"generate","output_format":"webp","quality":"high","revised_prompt":"…","size":"1024x1536"}} data: {"type":"response.output_item.added","item":{"id":"msg_04a3…","type":"message","role":"assistant","content":[]},"output_index":1} data: {"type":"response.content_part.added", ...} data: {"type":"response.output_text.done","text":""} data: {"type":"response.content_part.done", ...} data: {"type":"response.output_item.done","item":{"id":"msg_04a3…","type":"message","status":"completed"}} data: {"type":"response.completed","response":{"id":"resp_04a3…","status":"completed","output":[…]}} ``` 要点: * 图片数据位于 `partial_image` 事件的 `partial_image_b64`;`partial_image_index` 标记第几帧(从 0 起),`output_index` 标记第几张图(多图时用于区分,见 [一次生成多张](#一次生成多张))。 * 最终图为最后一个 `partial_image`,或 `response.completed` 中 `response.output[].result`。 * `partial_image` 事件附带 `background` 与 `output_format`(实测 `webp` 生效)。 ## revised\_prompt 用 Responses 生成图片时,`gpt-6-astra` 会自动优化提示词以提升出图质量,优化后的文本在 `revised_prompt`: * 流式:`response.output_item.done` 事件的 `item.revised_prompt` * 非流式:`output[].revised_prompt` 实测:输入 `"Draw a serene winter landscape with a river made entirely of white owl feathers winding through snow-dusted pines..."`,被优化为: ```text A serene winter landscape in delicate watercolor style: a winding river made entirely of overlapping white owl feathers flowing through snow-dusted pine trees, under a pale dawn sky with soft pink and blue washes. Fine ink linework defines the pines, feather barbs, snowy banks, and distant hills. Peaceful, airy composition, gentle mist, subtle shadows on snow, elegant natural fantasy illustration. ``` ## 多轮编辑与参考图输入 把参考图通过 `input_image` 传进去,即可编辑或参考生成。共三种写法: 写法一,URL(公网可直接下载): ```json { "type": "input_image", "image_url": "https://your-bucket.example.com/photo.jpg" } ``` 写法二,base64 data URI: ```python import base64 b64 = base64.b64encode(open("photo.jpg", "rb").read).decode part = {"type": "input_image", "image_url": f"data:image/jpeg;base64,{b64}"} ``` 写法三,file\_id(经 Files API 上传): ```python def create_file(path): return client.files.create(file=open(path, "rb"), purpose="vision").id fid = create_file("photo.jpg") part = {"type": "input_image", "file_id": fid} ``` 注意:用 URL 时,模型服务器会主动去拉这个地址,所以它必须对**上游取图网络**可达。浏览器或 VibeAPI 网关本机能得到 HTTP 200,并不代表模型服务器一定能下载。 参考图 URL 可达性实测: | 参考图输入 | 结果 | 耗时 / 现象 | | --------------------- | ----------- | ---------------------------------------------------------------- | | 腾讯 COS 公网 URL | 失败 | 约 20 秒返回 `400 Unable to download content ... before the timeout` | | 同对象的 EdgeOne CDN URL | 失败 | 约 20 秒返回相同 `400` | | GitHub 公共图片 URL | 成功 | 约 24 秒完成 | | 图片内联为 base64 data URI | 通过 URL 下载阶段 | 不再出现下载超时;后续仍可能遇到独立的上游负载错误 | 因此,腾讯 COS / EdgeOne CDN、带鉴权或可达性不确定的参考图不要直接传 URL,优先使用 base64 data URI 或 `file_id`。这类 `400` 表示上游取图失败,不能据此判断 COS 对象本身损坏或未公开。 `action` 参数控制生成还是编辑:`auto`(默认,模型自行决定)、`generate`(强制新建)、`edit`(强制编辑,上下文无图则报错)。 蒙版编辑(`input_image_mask`):原图作为 `input_image`、蒙版作为 `input_image_mask`,蒙版的透明区域会被重绘。 ```python img_id = create_file("sunlit_lounge.png") mask_id = create_file("mask.png") # 透明区即重绘区,须包含 alpha 通道 resp = client.responses.create( model="gpt-6-astra", input=[{"role": "user", "content": [ {"type": "input_text", "text": "在泳池里加一只火烈鸟"}, {"type": "input_image", "file_id": img_id}, ]}], tools=[{"type": "image_generation", "quality": "high", "input_image_mask": {"file_id": mask_id}}], ) ``` 参考图编辑实测: ### 多轮:把上一轮的图传进下一轮 OpenAI 官方 Responses API 支持用 `previous_response_id` 关联多轮编辑,本网关不支持:传入后流式连接被中断,客户端报 `ChunkedEncodingError: Response ended prematurely`。 替代方案:将上一轮的图片作为 `input_image` 显式传入下一轮,即可实现多轮编辑: ```python # 第一轮:生成 r1_b64 = generate_and_get_b64("一只灰色虎斑猫抱着戴橙色围巾的水獭,童书插画风格") # 第二轮:将第一轮的图作为参考图传入,继续编辑 stream = client.responses.create( model="gpt-6-astra", input=[{"role": "user", "content": [ {"type": "input_text", "text": "现在把它变成写实摄影风格,浅景深"}, {"type": "input_image", "image_url": f"data:image/png;base64,{r1_b64}"}, ]}], tools=[{"type": "image_generation"}], stream=True, ) ``` ## 一次生成多张 `n` 在 Responses 工具中无效。如需多张,请在提示词中写明「生成 N 张」,模型会多次调用 `image_generation` 工具,每张对应一个递增的 `output_index`。 ```python stream = client.responses.create( model="gpt-6-astra", instructions="You are a helpful image generation assistant. Generate ALL images the user requests.", input="Generate 3 separate images: 1) a solid purple star, 2) a solid blue square, 3) a solid green triangle, each centered on white.", tools=[{"type": "image_generation", "quality": "low"}], stream=True, ) finals = {} for event in stream: if event.type == "response.image_generation_call.partial_image": finals[event.output_index] = event.partial_image_b64 # 按 output_index 分组 for idx, b64 in finals.items: with open(f"out_{idx}.png", "wb") as f: f.write(base64.b64decode(b64)) print(f"共 {len(finals)} 张") # 实测 3 张 ``` 实测(3 张,事件流中出现 3 个 `image_generation_call`,`output_index` 为 0 / 1 / 2): ## Vision 图片理解 `gpt-6-astra` 能理解图片:识别物体、颜色、纹理,也能读出图里的文字。做图片理解只需传 `input_image`、不带 `image_generation` 工具即可。两个入口: | 入口 | 端点 | 输出 | | ---------------- | ---------------------- | ------------------------------- | | Responses | `/v1/responses` | 文本(`output_text`),可同时生成图片 | | Chat Completions | `/v1/chat/completions` | 文本(`choices[].message.content`) | ### Responses 方式 ```python resp = client.responses.create( model="gpt-6-astra", input=[{"role": "user", "content": [ {"type": "input_text", "text": "请用中文详细描述这张图片:主要物体、颜色、风格、氛围。"}, {"type": "input_image", "image_url": "https://your-bucket.example.com/product.png", "detail": "high"}, ]}], ) print(resp.output_text) ``` 实测输出(护目镜产品图,`detail=high`,节选): > 这张图片展示的是一副运动防护眼镜 / 护目镜式眼镜……镜框前部为方形圆角设计,左右两侧带有透明的防护结构……右侧镜片上可见 "YUANMU" 字样。颜色以黑色、透明白、灰色为主……风格偏向产品摄影 / 电商展示图…… 模型准确识别了产品类型、结构、配色、镜片上的英文字样与拍摄风格(`usage` 约为输入 930、输出 624 token)。 ### Chat Completions 方式 ```python resp = client.chat.completions.create( model="gpt-6-astra", messages=[{"role": "user", "content": [ {"type": "text", "text": "Describe this image: main objects, color palette, mood."}, {"type": "image_url", "image_url": {"url": "https://.../photo.jpg", "detail": "low"}}, ]}], ) print(resp.choices[0].message.content) ``` 两个入口的图片字段写法不同:Responses 使用 `input_image` 加 `image_url`(字符串);Chat 使用 `image_url` 加 `image_url.url`(对象)。 ### 参考图的三种写法 和生成一样,图片理解也支持 URL、base64、file\_id 三种写法(见 [多轮编辑与参考图输入](#多轮编辑与参考图输入))。一个请求可包含多张图片(`content` 数组中放置多个 `input_image`)。 ### detail 精度参数 | `detail` | 说明 | | ---------- | --------------------------------------------------- | | `low` | 模型仅接收 512×512 低清版本,速度快、成本低,适用于细节不重要的场景 | | `high` | 标准高保真,最多 2500 个图块或 2048px 长边 | | `original` | 适用于大图、密集或空间敏感场景(`gpt-5.4` 及以后),最多 10000 个图块或 6000px | | `auto` | 自动选择;在 `gpt-6-astra` 上等价于 `original`(不传时也是该行为) | ### 输入图要求与局限 * 支持格式:PNG、JPEG、WEBP、非动画 GIF * 限制:单次请求不超过 512MB、最多 1500 张图片;无水印或 logo、无 NSFW 内容、清晰可辨;CAPTCHA 会被系统拦截 * 已知局限:对非拉丁文字(如日文、韩文)的理解可能不佳;小字、旋转或倒置、精确空间定位、物体计数等场景容易出错;不适用于医学影像判读 ## 多语言文字渲染 `gpt-image-2` 的一项突出能力是在图片中渲染多语言文字(中、英、日、韩等),错字率低,而这正是许多其它图像模型的短板。 下例用一条提示词要求四种语言同框,并明确列出每种语言的确切文字: ```text A festive vertical New Year greeting poster. Render the SAME greeting in four languages on four separate, clearly legible lines: Chinese '新年快乐', English 'Happy New Year', Japanese 'あけましておめでとう', Korean '새해 복 많이 받으세요'. Warm red and gold palette, hanging paper lanterns, gold foil accents, elegant typography. ``` 两条路径均成功,四种语言的文字全部正确无误: 提示词建议: * 逐语言写出确切文字并用引号括住(如 `Chinese '新年快乐'`),避免让模型自行翻译 * 加入 `clearly legible` 或 `separate lines` 等要求,提升可读性与排版 * 文字不宜过多过密,大段文字或极小字号仍可能出错 ## 错误处理 | 状态 / code | 场景 | 应对 | | ------------------------------------------------------- | ------------------------- | ---------------------------------------------------- | | `400 Unable to download content ... before the timeout` | 上游无法下载参考图 URL | 改用 base64 data URI 或 `file_id`;不要只以本机 HTTP 200 判断可达性 | | `ChunkedEncodingError` / 连接中断 | 传了 `previous_response_id` | 改用「带图进入下一轮」 | | `moderation_blocked` | 提示词或图片被内容审核拦截 | 修改提示词或输入图后重试 | | `429` | 触发限流 | 指数退避后重试 | | `401` / `403` | 鉴权失败或无模型权限 | 检查 `API_KEY` 与 `gpt-6-astra` 权限 | ### 内容审核拦截(moderation\_blocked) 所有提示词与生成图片都会经过内容审核。被拦截时返回如下结构(可能包含 `moderation_details`): ```json { "error": { "type": "image_generation_user_error", "code": "moderation_blocked", "moderation_details": { "moderation_stage": "input", "categories": ["harassment"] } } } ``` * `moderation_stage`:`input`(提示词或输入图被拦)、`output`(生成图被拦)、`unknown` * `categories`:粗粒度标签,例如 `harassment`、`self-harm`、`sexual`、`violence` * 可通过 `moderation:"low"`(见 [image\_generation 工具参数](#image_generation-工具参数) / [输出定制](https://docs.vibeapi.cn/zh/docs/images#输出定制))放宽审核 ```python import openai try: client.images.generate(model="gpt-image-2", prompt="...") except openai.BadRequestError as e: if e.code == "moderation_blocked": details = (e.body or {}).get("moderation_details", {}) print("拦截阶段:", details.get("moderation_stage"), "类别:", details.get("categories")) # 提示用户修改后重试;此类用户错误不应自动重试 else: raise ``` ### 重试策略 * 可重试:`429`、`5xx`(瞬时故障),建议指数退避 * 不可重试:`moderation_blocked` 等用户错误,必须修改提示词或输入后再发,重复发送无意义 ## 与 OpenAI 官方的差异 | 能力 | OpenAI 官方 | 本网关 | | | ------------------------------------ | --------------- | -------------------------------------- | :-: | | 流式 / 非流式生成 | 支持 | 事件序列完整 | √ | | 多图(提示词触发) | 支持 | 返回多个 `image_generation_call` | √ | | 参考图编辑(base64 / `file_id`) | 支持 | 成功 | √ | | 参考图编辑(URL) | 支持公网 URL | GitHub 等直链成功;腾讯 COS / EdgeOne URL 下载超时 | ✗ | | `revised_prompt` | 有 | 一致返回 | √ | | 工具 `output_format` | 遵循 | `webp` 生效 | √ | | `size` / `quality` | 视为约束 | 被改写,要 4K/high 实得 1536×1024/medium | ✗ | | 指定图像模型 | 工具 `model` 字段 | 被忽略,不存在的模型名照样出图 | ✗ | | `previous_response_id` | 支持 | 不支持,连接中断 | ✗ | | Vision 理解(Responses + Chat,`detail`) | 支持 | 成功 | √ | | `background:transparent` | gpt-image-2 不支持 | 忽略并输出不透明 | √ | ## 参数速查 ``` type* "image_generation" quality low | medium | high | auto (本网关会改写,以响应为准) size 1024x1024 | 1536x1024 | 1024x1536 | … | auto (同上) output_format png | jpeg | webp output_compression 0–100 (jpeg / webp) moderation auto | low action auto | generate | edit partial_images 0–3 input_image_mask { "file_id": "..." } ``` ## 在线调试 填入你自己的 API Key 即可直接发起请求,参数表与响应结构由接口定义生成。 模型填 `gpt-6-astra`,`tools` 里加 `{"type": "image_generation"}`。 ## 官方文档 * [OpenAI · 图像生成](https://developers.openai.com/api/docs/guides/image-generation) * [OpenAI · Responses](https://developers.openai.com/api/reference/resources/responses/methods/create) # GPT 图像 · Image API `POST /v1/images/generations` · `POST /v1/images/edits` GPT 图像有两套入口,**这一套是默认入口**:直接指定图像模型一次性生成或编辑,`size` / `quality` 按请求执行, 4K + `high` 约 1–2 分钟返回。另一套是 [Responses](https://docs.vibeapi.cn/zh/docs/images-responses)——`gpt-6-astra` 调度 `image_generation` 工具做对话式多轮编辑, 但它拿不到高分辨率与高质量档位,只在需要多轮对话时使用。 协议与 OpenAI Image API 兼容,`openai` SDK 把 `base_url` 换成 `https://www.vibeapi.cn/v1` 即可。 本页结论来自对本网关的真实调用,最后验证 2026-10-13(实测记录小节标注各自的日期)。 ## 基本调用 ```bash curl -X POST "https://www.vibeapi.cn/v1/images/generations" \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "gpt-image-2", "prompt": "a red apple on a wooden table, studio lighting", "quality": "medium", "size": "1024x1024", "response_format": "b64_json" }' ``` ```python from openai import OpenAI import base64, urllib.request client = OpenAI(base_url="https://www.vibeapi.cn/v1", api_key="YOUR_API_KEY") result = client.images.generate( model="gpt-image-2", prompt="a red apple on a wooden table, studio lighting", quality="medium", size="1024x1024", ) item = result.data[0] if item.b64_json: image_bytes = base64.b64decode(item.b64_json) else: image_bytes = urllib.request.urlopen(item.url, timeout=60).read() open("apple.png", "wb").write(image_bytes) ``` ```javascript import OpenAI from "openai"; import fs from "fs"; const client = new OpenAI({ baseURL: "https://www.vibeapi.cn/v1", apiKey: "YOUR_API_KEY" }); const result = await client.images.generate({ model: "gpt-image-2", prompt: "a red apple on a wooden table, studio lighting", quality: "medium", size: "1024x1024", }); const item = result.data[0]; const imageBytes = item.b64_json ? Buffer.from(item.b64_json, "base64") : Buffer.from(await (await fetch(item.url)).arrayBuffer()); ``` ## 网关上的图像模型 图像生成分散在三个端点上,先确认你要的模型走哪一个: | 模型 | 端点 | 文档 | | --------------------------------------------------------------------------------------------- | --------------------------------------------- | ------------------------------------- | | `gpt-image-2` · `gpt-image-2.5-flare` · `gpt-image-2.5-sunburst` | `/v1/images/generations` · `/v1/images/edits` | 本页 | | `gemini-3-pro-image` · `gemini-3.1-flash-image` · `gemini-3.1-flash-lite-image`(含 `-preview`) | `/v1beta/models/{model}:generateContent` | [Gemini 图像生成](https://docs.vibeapi.cn/zh/docs/gemini-images) | | `grok-imagine-image-2.0` · `grok-imagine-image-quality` | `/v1/images/generations` · `/v1/images/edits` | [Grok 图像](https://docs.vibeapi.cn/zh/docs/grok-images) | | `wan3.0-image-*` | `/v1/videos`(图生视频,不是出图) | [视频生成](https://docs.vibeapi.cn/zh/docs/videos) | Gemini 的生图必须走原生端点:走 Chat 兼容协议能出图,但 `imageConfig`(画幅、分辨率)会在协议转换中丢掉。 `wan3.0-image-*` 名字里带 image,指的是「图生视频」,它走视频接口。 ## 三个 GPT 图像模型怎么选 `gpt-image-2`、`gpt-image-2.5-flare`、`gpt-image-2.5-sunburst` 的请求与响应格式完全相同,换 `model` 即可。 `gpt-image-2.5-1k` 已下线,代码里还有这个模型名的请换成 flare 或 sunburst。三者的差别(2.5 系列 2026-09-23 实测): | | `gpt-image-2` | `gpt-image-2.5-flare` | `gpt-image-2.5-sunburst` | | --------------------------- | --------------------- | ----------------------------- | ------------------------ | | `n` | 固定 1 张,按 1 张计费;要多张请并发 | **生效**,`n=2` 返回 2 张,按实际返回张数计费 | 同 flare | | `background: "transparent"` | 不支持,忽略该参数,输出不透明图 | **生效**,PNG 带 alpha 通道 | 同 flare | | 4K(`3840x2160`)+ `high` 耗时 | 约 1–2 分钟 | 约 40 秒 | 约 40–55 秒 | | `1024x1024` + `low` 耗时 | 约 20–50 秒 | 约 15–20 秒 | 约 15–20 秒 | | 计费 | 按张 | 按张,单价高于 `gpt-image-2` | 与 flare 同价 | 本网关通过多种渠道提供 GPT 图像。张数、尺寸校验、透明背景、响应字段和错误格式由网关统一,与本页一致; 耗时和 `usage` 里的 token 数会随调度到的渠道不同而变化,计费按张,与 `usage` 无关。 响应顶层的 `quality` 是实际执行的档位,个别情况下可能低于请求的档位(例如请求 `high` 返回 `medium`),以响应为准。 三个模型都按请求的 `size` 精确返回(2.5 实测 `1024x1024`、`1024x1536`、`3840x2160`),`quality` 按档回显, edits(multipart 参考图)同样可用,`low` 档约 18–25 秒。本轮 2.5 的 `data[0]` 都是 `url`,仍要按下文同时处理两种形态。 单价以[价格页](https://www.vibeapi.cn/pricing)为准。画质与文字渲染三者之间还没有做系统对比,同一提示词的样图见[实测](#实测gpt-image-25)。 要透明背景或一次多张,选 2.5;要和已有 `gpt-image-2` 产物保持一致,留在 2;2.5 两个里 flare 在这一轮更快。 ## 与 Responses 怎么选 | | Image API(本页) | Responses | | ------------------ | --------------------------------------------- | --------------------------------------- | | 端点 | `/v1/images/generations`、`/v1/images/edits` | `/v1/responses` + `image_generation` 工具 | | 调用模型 | `gpt-image-2` / `gpt-image-2.5-*`,直接指定 | `gpt-6-astra`,内部调度图像模型,无法指定 | | `size` / `quality` | 按请求执行,4K + high 精确返回 | 被改写:要 4K/high 实得 1536×1024/medium | | 耗时 | 4K + high 约 45–57 秒 | 40–170 秒 | | 提示词优化 | 无 | 自动,返回 `revised_prompt` | | 多轮编辑 | 不支持,每次独立 | 支持,上下文携带图片 | | 参考图 | multipart 文件上传 | URL / base64 / `file_id` | | 返回 | `data[0].b64_json` **或** `data[0].url`,两种都要处理 | SSE 事件里的 base64 | 要高分辨率、高画质、准确尺寸,用本页;要对话式多轮,用 Responses。 ## generations 全部请求字段: | 字段 | 类型 | 必填 | 默认 | 说明 | | --------------------------- | ------- | -- | -------- | -------------------------------------------------------------------------------------- | | `model` | string | 是 | — | `gpt-image-2` / `gpt-image-2.5-flare` / `gpt-image-2.5-sunburst` | | `prompt` | string | 是 | — | 图片描述文本 | | `size` | string | 否 | `auto` | 见[输出定制](#输出定制);`3840x2160` / `2160x3840` 精确返回;不合规返回 400 | | `quality` | string | 否 | `auto` | `low` / `medium` / `high` / `auto`,按档执行 | | `output_format` | string | 否 | `png` | `png` / `jpeg` / `webp`;以响应顶层字段和文件 MIME 为准 | | `output_compression` | integer | 否 | — | `0`–`100`,仅 `jpeg` / `webp` | | `response_format` | string | 否 | — | `b64_json` / `url`;**不决定响应形态**,见下文 | | `moderation` | string | 否 | `auto` | `auto` / `low` | | `background` | string | 否 | `opaque` | `opaque` / `auto` / `transparent`;`transparent` 只有 2.5 系列生效,`gpt-image-2` 忽略该参数、输出不透明图 | | `n` | integer | 否 | `1` | 2.5 系列生效、按实际返回张数计费;`gpt-image-2` 固定 1 张,多张请并发 | | `stream` / `partial_images` | — | 否 | — | 不要依赖;同步调用即可 | ### 响应有两种形态 同一个端点,`data[0]` 里可能是 `b64_json`(内联 base64),也可能是 `url`(临时下载链接,有时效,拿到后尽快下载)。 `response_format` 传了也不保证——generations 传 `b64_json` 通常拿到内联数据,edits 传相同值仍可能返回 `url`。**生产代码必须两种都处理:** ```python import base64, urllib.request item = result.data[0] data = (base64.b64decode(item.b64_json) if item.b64_json else urllib.request.urlopen(item.url, timeout=60).read()) open(f"out.{result.output_format or 'png'}", "wb").write(data) ``` ```bash if jq -e '.data[0].b64_json' response.json >/dev/null; then jq -r '.data[0].b64_json' response.json | base64 --decode > out.png else curl -L "$(jq -r '.data[0].url' response.json)" -o out.png fi ``` 响应顶层一定带 `size` / `quality` / `output_format`,它们是实际值,请读它们并校验下载后文件的真实 MIME: ```json { "created": 1789190861, "data": [{ "url": "https://..." }], "output_format": "png", "quality": "high", "size": "3840x2160", "model": "gpt-image-2", "usage": { "input_tokens": 234, "output_tokens": 13342, "total_tokens": 13576 } } ``` ## edits ``` POST /v1/images/edits (multipart/form-data) ``` 两类场景:用一张或多张参考图生成新图;配合蒙版重绘指定区域。表单字段与 generations 相同,另加: | 字段 | 类型 | 说明 | | --------- | -------- | ----------------------------------------- | | `image[]` | file,可多个 | 参考图。多张时重复 `image[]` | | `mask` | file | 蒙版,可选。须含 alpha 通道,透明区即重绘区,与原图同尺寸、不超过 50MB | 多参考图: ```python result = client.images.edit( model="gpt-image-2", image=[open("ref1.png", "rb"), open("ref2.jpg", "rb"), open("ref3.jpg", "rb")], prompt="Combine the subjects into a single flat-lay collage on white marble, studio lighting", quality="medium", ) ``` ```bash curl -X POST "https://www.vibeapi.cn/v1/images/edits" \ -H "Authorization: Bearer $API_KEY" \ -F "model=gpt-image-2" \ -F "image[]=@ref1.png" -F "image[]=@ref2.jpg" -F "image[]=@ref3.jpg" \ -F "prompt=Combine the subjects into a single flat-lay collage on white marble" \ -F "quality=high" -F "size=3840x2160" > response.json ``` 蒙版编辑: ```python result = client.images.edit( model="gpt-image-2", image=open("base.png", "rb"), mask=open("mask.png", "rb"), # 透明区即要重绘的区域 prompt="In the masked area, add a blooming cherry blossom tree", quality="low", ) ``` 多张参考图时蒙版作用于第一张。蒙版是提示性的:模型以它为引导,不保证严格贴合形状。 edits 对整体风格和构图的保持很强,对局部小对象的加入偏保守——要求「加两只鹤」这类小元素可能不出现,先用自己的图试一次。 ## 输出定制 **`size`** 官方约束:最大边不超过 `3840px`,两边均为 `16` 的倍数;长短边比不超过 `3:1`;总像素在 `655,360` \~ `8,294,400` 之间。 常用 `1024x1024`、`1536x1024`、`1024x1536`、`2048x2048`、`3840x2160`、`2160x3840`、`auto`。 `3840x2160` 与 `2160x3840` 均精确返回;仍建议读响应顶层的 `size` 做校验。 不符合上述规则的尺寸直接返回 400(`code` 为 `invalid_request`,消息里说明不满足哪一条,例如 `invalid size "4096x4096": the longer side must be at most 3840`),不会被改成别的尺寸出图。 **`quality`** `low` / `medium` / `high` / `auto`。以响应顶层的 `quality` 为准;`usage.output_tokens` 随渠道不同而不同,不要用它判断档位。 **`output_format`** `png` / `jpeg` / `webp`,配合 `output_compression`(`0`–`100`,仅 jpeg / webp)。始终以响应顶层 `output_format` 和下载文件的 MIME 为准。 **`background`** `gpt-image-2` 不支持透明背景,传 `transparent` 时网关会去掉这个参数、照常输出不透明图片(不报错);2.5 系列会返回带 alpha 通道的 PNG (下图用棋盘格垫底显示透明区域): **`n`** 2.5 系列生效,`n=2` 返回两张、按实际返回张数计费。`gpt-image-2` 固定 1 张,传多少都按 1 张执行和计费:多张请并发多次调用, 或用 [Responses](https://docs.vibeapi.cn/zh/docs/images-responses#一次生成多张) 在提示词里要求多张。 ## 实测:4K 最高画质 以下是 2026-09-12 的实测记录,耗时与 `output_tokens` 会随调度到的渠道变化。`quality=high`,`size` 取官方上限 `3840x2160` / `2160x3840`,六个主题并发 6 路: | 主题 | 请求 size | 耗时 | 实返 size / quality | `data[0]` | `output_tokens` | | ----- | ----------- | ------ | -------------------- | --------- | --------------- | | 东方水墨 | `3840x2160` | 52.0 s | `3840x2160` / `high` | `url` | 13,342 | | 仙侠 | `2160x3840` | 56.7 s | `2160x3840` / `high` | `url` | 13,342 | | 工笔重彩 | `3840x2160` | 54.1 s | `3840x2160` / `high` | `url` | 13,342 | | 环形空间站 | `2160x3840` | 47.6 s | `2160x3840` / `high` | `url` | 13,342 | | 巨构城市 | `3840x2160` | 54.1 s | `3840x2160` / `high` | `url` | 13,342 | | 戴森云 | `2160x3840` | 45.2 s | `2160x3840` / `high` | `url` | 13,342 | 六张全部按请求尺寸返回真实 4K PNG(9–17 MB),无一超时。 同一批用 `edits` 做参考图编辑(把水墨图缩到 1920×1080 作为 `image[]`,`size=3840x2160`、`quality=high`):50 秒返回精确 4K,构图与笔触完全保留。 其他尺寸与质量档的耗时:`low` 小图约 20–25 秒,`medium` 1K 约 80–140 秒,参考图编辑约 50–100 秒。质量越高、图片越大,耗时越长。 ## 实测:gpt-image-2.5 以下是 2026-09-23 的实测记录。同一个水墨提示词,`size=3840x2160`、`quality=high`,两个模型各一张: | 模型 | 耗时 | 实返 size / quality | `data[0]` | `output_tokens` | 文件 | | ------------------------ | ------ | -------------------- | --------- | --------------- | ----------- | | `gpt-image-2.5-flare` | 38.4 s | `3840x2160` / `high` | `url` | 3,336 | PNG 14.6 MB | | `gpt-image-2.5-sunburst` | 54.2 s | `3840x2160` / `high` | `url` | 3,336 | PNG 13.1 MB | ## 错误处理 | 状态 / code | 场景 | 应对 | | ---------------------------- | --------------------------- | ------------------------- | | `400` · `moderation_blocked` | 提示词或图片被内容审核拦截(各渠道统一为这个错误码) | 修改提示词或输入图后重试;不要自动重试 | | `400` · `invalid_request` | `size` 不符合[输出定制](#输出定制)里的规则 | 按规则改尺寸 | | `504` | 同步渲染超时,极少见 | 重试或降一档 `quality` | | `429` | 触发限流 | 指数退避后重试 | | `401` / `403` | 鉴权失败或无模型权限 | 检查 `API_KEY` 与所用图像模型的分组权限 | 审核拦截的响应结构与处理代码见 [Responses 页](https://docs.vibeapi.cn/zh/docs/images-responses#内容审核拦截moderation_blocked),两套入口相同。 ## 参数速查 ``` model* gpt-image-2 | gpt-image-2.5-flare | gpt-image-2.5-sunburst prompt* 文本描述 size 1024x1024 | 1536x1024 | 1024x1536 | 2048x2048 | 3840x2160 | 2160x3840 | auto (须符合输出定制里的规则,否则 400) quality low | medium | high | auto output_format png | jpeg | webp output_compression 0–100 (jpeg / webp) response_format b64_json | url (不决定响应形态,两种都要处理) moderation auto | low background opaque | auto | transparent (transparent 仅 2.5 生效;gpt-image-2 忽略) n 2.5 生效、按实际张数计费;gpt-image-2 固定 1 张 image[] edits:一张或多张参考图(multipart) mask edits:alpha 蒙版,透明区即重绘区 ``` ## 在线调试 填入你自己的 API Key 即可直接发起请求,参数表与响应结构由接口定义生成。 ### 生成图像(OpenAI 格式) ### 编辑图像(OpenAI 格式) ## 官方文档 * [OpenAI · 图像生成](https://developers.openai.com/api/docs/guides/image-generation) # 文档 import { Card, Cards } from 'fumadocs-ui/components/card'; 网关地址 `https://www.vibeapi.cn/v1`,所有请求带 `Authorization: Bearer `。一把 key 可调用 GPT、Claude、Gemini、Grok 与国产模型。 ## 先读这一条 请求超时上限 **120 秒**。非流式请求在生成完成前没有任何数据下行,单次生成一旦超过这个时间,连接会被中断。 短输出不受影响;长输出与推理型模型容易触发。**生产环境建议默认开启流式**,这是本网关最常见的报错原因。 ## 文本对话 按模型家族选它的原生协议,功能最全;跨协议调用是网关翻译的,只保证消息、流式和基本工具调用。总览见[文本对话概览](https://docs.vibeapi.cn/zh/docs/text)。 ## 图像生成 哪个模型走哪个端点、GPT 两套入口怎么选,见[图像生成概览](https://docs.vibeapi.cn/zh/docs/images-overview)。 ## 视频生成 异步接口:提交拿到 `task_id`,轮询到 `completed`,再取片;不受 120 秒约束。 ## 其他 ## 不想写代码?直接用产品 同一套模型与网关,做成了两个开箱即用的应用,用 VibeAPI 账号登录即可: ## 这份文档怎么写 * **官方 SDK,只换 base URL。** 参数名、类型与语义对齐三家官方参考,每个参数先给官方定义,再以「网关」标注本网关的实测行为。 * **写的都是实测。** 参数逐项标注「支持 / 接受 / 实测不生效 / 无效」,每个端点附真实抓取并脱敏的请求与响应,样图和样片都是真实调用产出。 * **返回 200 不等于参数生效。** 网关会为部分模型改写参数,`auto` 类 key 上的 Claude 会静默忽略一批约束;各页的「参数改写规则」「分组差异」写明了判断方法。 # Claude Messages `POST /v1/messages` Claude 系模型的原生协议。**Claude 模型请优先用这个端点**——它是唯一能完整拿到 thinking 块的路径。从 [Chat Completions](https://docs.vibeapi.cn/zh/docs/chat) 调 Claude 也能通,但那是网关做的 协议转换,thinking 会在转换中丢失,工具调用只保核心字段。 网关上还有一批国产模型也走这个端点接入(glm、kimi、qwen、deepseek 等), 具体见[模型与入口](https://docs.vibeapi.cn/zh/docs/models)。 ## 基本调用 **建议用官方 SDK 而不是自己拼 HTTP**——SSE 解析、工具参数分片拼接、超时与重试都由它处理,能避开大部分常见问题。安装与环境变量配置见[快速开始](https://docs.vibeapi.cn/zh/docs/quickstart)。 ```bash curl -N -X POST "https://www.vibeapi.cn/v1/messages" \ -H "Authorization: Bearer $API_KEY" \ -H "anthropic-version: 2023-06-01" \ -H "Content-Type: application/json" \ -d '{ "model": "claude-opus-5", "max_tokens": 1024, "system": "你是一个简洁的助手。", "messages": [ {"role": "user", "content": "用一句话解释什么是幂等。"} ], "stream": true }' ``` ```python import anthropic client = anthropic.Anthropic( base_url="https://www.vibeapi.cn", api_key="YOUR_API_KEY", ) with client.messages.stream( model="claude-opus-5", max_tokens=1024, system="你是一个简洁的助手。", messages=[{"role": "user", "content": "用一句话解释什么是幂等。"}], ) as stream: for text in stream.text_stream: print(text, end="", flush=True) ``` ```javascript import Anthropic from "@anthropic-ai/sdk"; const client = new Anthropic({ baseURL: "https://www.vibeapi.cn", apiKey: "YOUR_API_KEY", }); const stream = await client.messages.create({ model: "claude-opus-5", max_tokens: 1024, system: "你是一个简洁的助手。", messages: [{ role: "user", content: "用一句话解释什么是幂等。" }], stream: true, }); for await (const event of stream) { if (event.type === "content_block_delta" && event.delta.type === "text_delta") { process.stdout.write(event.delta.text); } } ``` ## 认证 ``` Authorization: Bearer anthropic-version: 2023-06-01 Content-Type: application/json ``` `base_url` 是 `https://www.vibeapi.cn`——注意 Messages 的完整路径是 `/v1/messages`, Anthropic 官方 SDK 填 base URL 时通常**不带** `/v1`。 ## 流式要求 请求超时上限 **120 秒**。非流式请求在生成完成前没有数据下行,单次生成超过这个时间会被 中断。短输出不受影响;推理型号要等整段思考结束才返回首字节,容易触发上限。 官方 SDK 也有同类保护:`max_tokens` 给得很大时会要求走流式,以避免 HTTP 超时。 **建议默认开启流式**,需要完整文本时在客户端拼接 `text_delta`。 ## 与 Chat 的差异 以下三处差异较大: **`max_tokens` 是必填的**,不像 Chat 可以省略。忘了带直接 400。 **系统提示是顶层的 `system` 字段**,不是 `messages` 里的一个角色。`messages` 只放 `user` 和 `assistant`,而且需要交替出现。 **响应是内容块数组,不是一个字符串。** `content` 里每项有自己的 `type`——`text`、 `thinking`、`tool_use` 各是一种块。取正文要过滤 `type == "text"`。 | | Chat Completions | Messages | | ---- | -------------------------------- | ------------------- | | 系统提示 | `messages` 里的 `system` 角色 | 顶层 `system` 字段 | | 输出上限 | `max_completion_tokens`,可省略 | `max_tokens`,**必填** | | 产出位置 | `choices[0].message.content` 字符串 | `content` 内容块数组 | | 结束原因 | `finish_reason` | `stop_reason` | | 停止序列 | `stop` | `stop_sequences` | ## 请求参数 参数名、类型与语义对齐 [Anthropic Messages API](https://platform.claude.com/docs/en/api/messages)。每个参数先给官方定义,再以「网关」标注本网关的实测行为; 标了「分组敏感」的参数在 `auto` 类 key 上会被静默忽略(返回 200,不报错),详见[分组差异](#分组差异)。 ### 必填 为提示词补全的模型。可用模型见[模型与入口](https://docs.vibeapi.cn/zh/docs/models)。 停止生成前允许产出的最大 token 数。模型可能在达到上限之前就停止,该参数只规定绝对上限;不同模型的最大取值不同。 设为 `0` 可只预热[提示缓存](https://platform.claude.com/docs/en/build-with-claude/prompt-caching#pre-warming-the-cache)而不生成。 思考模型的思考预算计入这个上限。 **网关 · 分组敏感,影响费用。** 官方满血 key 精确执行(要 16 就返回 16,`stop_reason` 为 `max_tokens`); `auto` key 不执行这个上限,要 16 实际产出 145\~159,`stop_reason` 仍为 `end_turn`。用 `auto` 时以 `usage.output_tokens` 对账。 输入消息。模型按 `user` 与 `assistant` 轮次交替工作:请求里给出此前的轮次,模型生成下一条 `Message`; 连续的同角色轮次会合并成一轮。每条消息是 `{role, content}`,`content` 可以是字符串,也可以是内容块数组(文本、图片、文档、工具结果混排)。 若最后一条是 `assistant`,响应会直接从它的内容接着往下写,可用来约束回复的开头。 ### 系统提示与输出 系统提示,用于给模型提供上下文与指令,例如设定目标或角色。给数组时每项是一个 `text` 块,可逐块附加 `cache_control`。 是否以 server-sent events 增量返回响应。 **网关。** 单次请求上限 120 秒,思考模型建议设为 `true`,见[流式要求](#流式要求)。 自定义停止序列。模型正常结束时 `stop_reason` 为 `end_turn`;命中自定义序列时 `stop_reason` 为 `stop_sequence`,`stop_sequence` 字段回显命中的那一条。 **网关 · 分组敏感。** 官方满血 key 生效;`auto` key 忽略它,输出照常跑完,`stop_reason` 仍是 `end_turn`。 输出配置。`effort` 取 `low` / `medium` / `high` / `xhigh` / `max`,控制模型投入的算力;`format` 为 `{"type": "json_schema", "schema": {...}}` 时约束输出为该结构,见[结构化输出](https://platform.claude.com/docs/en/build-with-claude/structured-outputs)。 **网关 · 分组敏感。** 官方满血 key 返回纯 JSON;`auto` key 退化成普通文本,返回带 ` ``` ` 包裹的代码块,直接 `json.loads` 会失败。 schema 里 `type: object` 须显式带 `additionalProperties`,否则 400——该校验只在官方满血 key 上执行。 ### 思考 扩展思考配置。开启后响应里包含 `thinking` 内容块,展示模型给出最终答案前的思考过程。 三种写法:`{"type": "adaptive"}` 由模型自行决定思考深度;`{"type": "enabled", "budget_tokens": N}` 指定思考预算,须 ≥ 1024 且小于 `max_tokens`;`{"type": "disabled"}` 关闭。 `display` 可设 `omitted`,思考内容不返回但保留签名以维持多轮连续性。 不同代次的模型接受的写法不同:Claude 4.7 及以后只接受 `adaptive`,显式 `enabled` + `budget_tokens` 会被拒绝;旧型号相反。 跨型号的代码不要写死一种。 **网关。** 对新型号传 `enabled` 会被改写为 `adaptive` 并删掉 `budget_tokens`,请求成功但预算不生效,见[参数改写规则](#参数改写规则)。 `claude-opus-5-5` 上传 `disabled` 多数情况会 400,见同一节。`auto` key 上 `claude-sonnet-5` 不返回 thinking 块,见[分组差异](#分组差异)。 ### 工具调用 模型可以使用的工具定义。每个工具包含 `name`、`description` 和描述参数的 `input_schema`;模型决定调用时返回 `tool_use` 内容块, 你执行后以 `tool_result` 内容块回传。也可以放服务端执行的内置工具(如 `web_search_20250305`)。 **网关 · 分组敏感。** 自定义工具在两类 key 上都完整;服务端内置工具在 `auto` key 上不保证,见[分组差异](#分组差异)。 模型如何使用提供的工具:`{"type": "auto"}` 自行决定;`{"type": "any"}` 必须用某个工具;`{"type": "tool", "name": "..."}` 指定工具;`{"type": "none"}` 不用。 `auto` / `any` 可加 `disable_parallel_tool_use: true`,让模型最多只发起一次工具调用。 注意与 Chat Completions 不同,这里是对象不是字符串。 ### 缓存 提示缓存标记。顶层 `cache_control` 自动作用于请求里最后一个可缓存块;也可以在 `system`、`messages`、`tools` 的内容块上逐个设置 `{"type": "ephemeral"}`。 把稳定不变的前缀(长系统提示、工具定义、文档)标为可缓存,后续命中时 `usage` 里出现 `cache_read_input_tokens`。 **网关 · 分组敏感。** `auto` key 上不生效,`usage` 里不会出现缓存字段;官方满血 key 正常。 ### 采样 三个采样参数官方已标记为弃用:晚于 Claude Opus 4.6 发布的模型只接受 `temperature: 1.0` 与 `top_p ≥ 0.99`,不接受 `top_k`,其他取值返回 400。 注入响应的随机程度,`0.0`–`1.0`。分析类、选择题类任务取值靠近 `0.0`,创作类靠近 `1.0`;即使为 `0.0` 结果也不完全确定。 **网关。** 新型号上不等于 `1.0` 的值会被删除,见[参数改写规则](#参数改写规则)。 核采样:按概率降序累计,达到 `top_p` 即截断。仅建议高级用法使用,与 `temperature` 通常只调其一。 **网关。** 新型号上小于 `0.99` 的值会被删除。 每个 token 只从概率最高的 K 个候选里采样,用于去掉低概率的长尾。仅建议高级用法使用;Chat Completions 没有这个参数。 **网关。** `claude-fable-5` / `claude-fable-5-1` 上会被删除。 ### 标识与其他 请求元数据。`user_id` 为终端用户的外部标识,应是 uuid、哈希等不透明值,不要放姓名、邮箱、电话。 `auto` / `standard_only`,选择优先容量还是标准容量。 **网关。** 由网关自行路由,该字段无意义。 代码执行容器的复用标识。 **网关。** 不提供代码执行工具,无效。 推理处理的地理区域。 **网关。** 不保证生效。 ## 响应字段 ```json { "id": "msg_...", "type": "message", "role": "assistant", "model": "claude-opus-5", "content": [ { "type": "text", "text": "同一个操作执行多次和执行一次效果相同。" } ], "stop_reason": "end_turn", "stop_sequence": null, "usage": { "input_tokens": 24, "output_tokens": 17 } } ``` 内容块数组,**类型是混排的**。开了思考的模型会在前面多出 `{"type":"thinking"}` 块, 用工具时会有 `{"type":"tool_use"}` 块。**直接取 `content[0]` 在这些情况下会拿到思考内容 或工具调用,不是正文**——务必按 `type` 过滤。 `end_turn` 自然结束 · `max_tokens` 撞到输出上限 · `stop_sequence` 命中停止序列 · `tool_use` 等待工具结果。 命中的是哪一条停止序列,未命中为 `null`。 `input_tokens` / `output_tokens`。用了提示缓存时还会有缓存读写的 token 统计, 对账时要一并看。 ## 流式事件 整体以 `message_start` 开始、`message_stop` 结束;中间每个内容块有自己的 `content_block_start` → 若干 `content_block_delta` → `content_block_stop`, 块之间用 `index` 区分。 ``` event: content_block_delta data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"同一个"}} event: content_block_delta data: {"type":"content_block_delta","index":0,"delta":{"type":"thinking_delta","thinking":"先确认定义…"}} ``` 增量在 `delta` 里,`delta.type` 决定它属于哪种块: 正文增量。**绝大多数情况只需要认这一种。** 思考增量。 工具调用参数的增量 JSON 片段,需自己累积拼接成完整 JSON 再解析。 顶层字段的变更,`stop_reason` 和最终的 `usage` 从这里来。 用工具时事件之间可能出现明显停顿,因为参数是攒够一组键值才发出来的,这是正常现象。 ## 参数改写规则 这几个型号只接受自适应思考,显式思考预算在官方那里会直接 400。与其把这个错误丢给你, 网关在转发前将这类参数改写为等价的合法形式,请求因此成功,但原始取值不生效。 下表列出改写发生的条件。 | 触发条件 | 网关的动作 | | ----------------------------------------------------------------------------------------------------------- | ------------------------------------------- | | `thinking.type` 为 `enabled` | 改写为 `adaptive`,并删除 `thinking.budget_tokens` | | `temperature` **不等于** `1.0` | 删除该字段(`1.0` 保留) | | `top_p` **小于** `0.99` | 删除该字段(`≥ 0.99` 保留) | | `claude-fable-5` / `claude-fable-5-1`:总是 | 删除 `top_k` | | `claude-fable-5` / `claude-fable-5-1`:`thinking.type` 为 `disabled` | 删除整个 `thinking` | | `claude-opus-5` / `claude-opus-5-5`:`thinking.type` 为 `disabled` 且 `output_config.effort` 为 `xhigh` / `max` | 改写 `thinking.type` 为 `adaptive` | 适用型号:`claude-opus-5-5`、`claude-opus-5`、`claude-sonnet-5`、`claude-opus-4-8`、`claude-opus-4-7`、 `claude-fable-5`、`claude-fable-5-1`。 **`claude-opus-5-5` 不接受关闭思考。** `thinking.type: "disabled"` 只有在 `effort` 为 `xhigh` / `max` 时会被改写,其余情况(不传 `effort`,或 `low` / `medium` / `high`)网关原样转发,返回 400: `"***.***.disabled" is not supported for this model. Use "***.***.adaptive" and "output_config.effort" to control thinking behavior.` (`***.***` 是网关对 `thinking.type` 的打码。)不想要思考就不传 `thinking`,把 `output_config.effort` 调到 `low`—— 实测简单问题这样不返回 thinking 块。`claude-opus-5` 上 `disabled` 仍可直接用。2026-09-23 实测。 **最要紧的一条是 `thinking`。** 你传 `{"type": "enabled", "budget_tokens": 4096}` 会拿到 200,但 `budget_tokens` 已经被丢掉了,思考长度由模型自己决定。要控制思考成本, 用 `max_tokens` 留出的空间去间接约束,别依赖 `budget_tokens`。 这几个型号只接受 `temperature = 1.0` 与 `top_p >= 0.99`(Anthropic 对晚于 Opus 4.6 发布的模型的兼容边界),其他取值上游会直接 400。网关把不合规的值删掉,请求因此成功—— 但**你设置的自定义 `temperature` / `top_p` 在这些型号上不会生效**。`claude-opus-4-6`、 `claude-sonnet-4-6`、`claude-haiku-4-5` 等旧型号不套用此规则,采样参数原样透传。 ## 分组差异 key 分两类:**`auto`**(可调用除 `claude-opus-5-5`、`claude-fable-5`、`claude-fable-5-1` 外的全部模型)和 **`Claude 官方满血版`**。Claude 系模型 在这两类上有实测差异,**全部返回 200,没有任何报错或警告**: | 能力 | `auto` | `Claude 官方满血版` | | ----------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | | 提示缓存 `cache_control` | **不可用**,`usage` 里不返回缓存字段 | 返回 `cache_creation_input_tokens` / `cache_read_input_tokens` | | 服务端执行的内置工具 | 不保证,响应形状可能不符合官方约定 | 正常 | | `thinking`(`claude-sonnet-5`) | **不返回 thinking 块**,显式要求也不返回 | 返回 | | `thinking`(`claude-opus-5`) | 返回,但输出(含思考)明显更短 | 完整 | | `max_tokens` 上限 | **不执行**,要求 16 实际产出 145\~159 | 精确执行,`stop_reason` 为 `max_tokens` | | `stop_sequences` | **被忽略**,输出照常跑完 | 生效,`stop_reason` 为 `stop_sequence` | | `output_config` 结构化输出 | 退化成 markdown 代码块 | 返回纯 JSON | | 可用模型 | 不含 `claude-opus-5-5` / `claude-fable-5` / `claude-fable-5-1` | 含 | 以上差异在 `auto` 上均表现为静默忽略:请求返回 200,响应内容正常,设置的约束不生效。 常规对话与代码生成用 `auto` 即可。**只要你的代码依赖参数被真正执行——限制输出长度、 停止序列、结构化输出、提示缓存、服务端工具、`claude-sonnet-5` 的 thinking——就必须换 官方满血 key,改参数没有用。** **一把 key 可以多选分组。** 在控制台给 key 选多个分组后,请求按从左到右的顺序尝试:当前分组没有 这个模型的可用渠道,就换下一个;`auto` 在它所在的位置展开;计费按实际命中的分组结算。两种常见排法: * **`auto` → `Claude 官方满血版`**:只有 `auto` 调不到的 `claude-opus-5-5`、`claude-fable-5`、 `claude-fable-5-1` 会落到满血版,其余请求照旧走 `auto`。 * **`Claude 官方满血版` → `auto`**:Claude 请求全部先走满血版,拿到上表右列的完整行为,也按满血版的 倍率计费;其他模型走 `auto`。 多选分组的 key 报错时,信息里显示的分组可能仍是 `auto`,这不代表请求只走了 `auto`。 ## 如何验证生效 **不要用 HTTP 状态码判断**,上面两类情况都返回 200。看响应体: * **思考是否生效** —— `content` 数组里有没有 `{"type": "thinking"}` 块。 * **缓存是否生效** —— `usage` 里有没有 `cache_creation_input_tokens` / `cache_read_input_tokens`。没有这两个字段就是没生效,不管你怎么标 `cache_control`。 * **参数有没有被改写** —— 把可疑参数换一个明显不同的值再发一次,看输出是否真的变化。 两次没差异,多半是它没被送到模型那里。 ## 国产模型兼容度 网关上的国产模型(glm / kimi / qwen / deepseek / MiniMax)两套协议都能调通, 工具调用也都可用,但对 `max_tokens`、停止序列、结构化输出的遵循程度**逐个模型不同**, 同一模型在 Messages 协议和另一套协议上还可能表现不同。逐项实测结果见 [模型与入口](https://docs.vibeapi.cn/zh/docs/models)。 其中 `deepseek-v4-pro` 与 `kimi-k3` 不执行 `max_tokens`,且仍将结束原因报为已截断。 使用这两个模型时,以 `usage` 中的实际 token 数对账。 ## 真实响应示例 下面是从生产网关真实抓取、脱敏后的响应。注意 `content` 是内容块数组: 模型决定调用工具时,会多出一个 `tool_use` 块: 流式的事件序列(中间事件已省略): ### 国产模型的真实响应 以下为各国产模型在 Messages 协议上的真实调用与响应。注意 `kimi-k3` 会返回 `thinking` 块,`usage.output_tokens_details.thinking_tokens` 是其消耗。 ## 能力边界 * **只保证核心能力**:消息、流式、thinking、基本的工具调用。批处理、文件上传、 代码执行容器这些端点不在提供范围内。 * **`thinking` 的写法不能跨代次通用**,写死一种会在另一代次上 400。 * **`container` / `inference_geo` / `service_tier` 无效**,见参数表。 * **非流式不适合推理型号。** ## 在线调试 填入你自己的 API Key 即可直接发起请求,参数表与响应结构由接口定义生成。 ## 官方文档 本页只写与本网关有关的部分,参数语义的权威定义以官方为准: * [Anthropic · Messages](https://platform.claude.com/docs/en/api/messages) * [Anthropic · 流式](https://platform.claude.com/docs/en/build-with-claude/streaming) * [Anthropic · 思考](https://platform.claude.com/docs/en/build-with-claude/thinking) # 模型与入口 网关地址 `https://www.vibeapi.cn/v1`,所有请求带 `Authorization: Bearer `。 ## 列出模型 `GET /v1/models` 返回当前 key 可调用的全部模型,模型名与下方矩阵一致。 ```bash curl "https://www.vibeapi.cn/v1/models" \ -H "Authorization: Bearer $API_KEY" ``` ```python from openai import OpenAI client = OpenAI(base_url="https://www.vibeapi.cn/v1", api_key="YOUR_API_KEY") for m in client.models.list(): print(m.id) ``` ```javascript import OpenAI from "openai"; const client = new OpenAI({ baseURL: "https://www.vibeapi.cn/v1", apiKey: "YOUR_API_KEY" }); for await (const m of client.models.list()) { console.log(m.id); } ``` ## 流式与超时 请求超时上限是 **120 秒**。非流式请求在生成完成前没有任何数据下行,单次生成一旦超过这个 时间,连接会被中断,表现为「调用超时」。 短输出的非流式请求正常可用,通常几秒即返回。会触发上限的是长输出与推理型模型—— 它们要等整段推理和生成结束才返回首字节。**由于单次生成耗时无法预先判断,生产环境 建议默认开启流式**:流式从第一个事件起就有数据下行,连接不会闲置到触发超时。 需要一次性拿到完整结果时,请在客户端聚合流式事件,而不是改回非流式。 ## 标注含义 下面每个模型最多有三行,含义是固定的: 这个模型的原生入口,功能最全、字段保真最好。没有特殊理由就用它。 可以调通,但会损失一些东西——具体差在哪写在模型下面的说明里。 你用 A 协议发,网关翻译成 B 协议后再发出。**只保证核心功能**:消息、流式、基本的 工具调用。协议特有的字段(比如 Claude 的 thinking 块、Gemini 的 imageConfig)会在 翻译中丢失。调用成功不代表功能等价。 标着 **ⓘ 以实测为准** 的模型,它们的原生协议逐个模型而异,结论是实测出来的,日期是 最后一次验证的时间。没有这个标记的(OpenAI、Anthropic、Google 三家)是确定性的, 不随时间变化。 ## 两类静默失效 **一、你的 key 分组会影响能力。** key 分 `auto`(可调用除 `claude-opus-5-5`、`claude-fable-5`、`claude-fable-5-1` 外的全部模型)和 `Claude 官方满血版` 两类。Claude 系模型在这两类上,提示缓存、服务端工具和 thinking 的实际可用性**是不同的**;GPT 系实测没有差异。一把 key 可以多选分组:想保留 `auto` 又要用这三个模型, 在 `auto` 后面加选 `Claude 官方满血版`。详见 [Messages · 分组差异](https://docs.vibeapi.cn/zh/docs/messages#分组差异)。 **二、网关会为部分模型过滤或改写参数**,比如 Claude 的 `thinking.budget_tokens` 会被丢掉、Grok 在 Chat 接口上的内置 `web_search` 会被移除。规则写在各自的调用页 ([Messages](https://docs.vibeapi.cn/zh/docs/messages) · [Chat](https://docs.vibeapi.cn/zh/docs/chat) · [Responses](https://docs.vibeapi.cn/zh/docs/responses))。 两件事都返回 200,只看状态码发现不了。 ## 国产模型的协议兼容度 国产模型两套协议都能调通,但**对参数的遵循程度参差不齐**。 下面是逐项实测结果(`auto` key,最后验证 2026-09-09): | | glm-5.3 | kimi-k3 | qwen3.8-max | deepseek-v4-pro | MiniMax-M3 | | -------------------------- | --------------- | --------- | ----------- | --------------- | ---------- | | 基本调用(两协议) | ✅ | ✅ | ✅ | ✅ | ✅ | | **工具调用**(两协议) | ✅ | ✅ | ✅ | ✅ | ✅ | | `max_tokens` 是否执行 | ✅ 精确 | ❌ **不执行** | ✅ 精确 | ❌ **严重不执行** | ✅ 精确 | | `stop`(Chat 协议) | ❌ | ✅ | ❌ | ✅ | ❌ | | `stop_sequences`(Messages) | ❌ | ✅ | ✅ | ✅ | ❌ | | `json_object` 结构化输出 | ❌ 带 markdown 包裹 | ✅ | ✅ | ✅ | ✅ | 三条要点: **一、工具调用全部可用。** 五个模型在 Chat 和 Messages 两个协议上都能正确返回 `tool_calls` / `tool_use`。做 agent 类应用可以放心用。 **二、`max_tokens` 在两个模型上不执行,而且结束字段会误导你。** `deepseek-v4-pro` 要求 16 token,实际产出 **1465**(Chat)/ **964**(Messages); `kimi-k3` 要求 16,实际产出 81 / 75。这两个模型同时将 `finish_reason` 报为 `length`、 `stop_reason` 报为 `max_tokens`,与实际不符。 > 不要用 `max_tokens` 估算成本上限,也不要依据 `finish_reason` 判断是否截断。 > 使用这两个模型时,以 `usage` 中的实际 token 数对账。 **三、`stop` / `stop_sequences` 看模型,而且同一模型在两个协议上可能不同。** `qwen3.8-max` 在 Messages 协议上生效、在 Chat 协议上不生效。依赖停止序列的逻辑, 请先在你要用的那个协议上实测一次,不要跨协议套用结论。 `glm-5.3` 的 `json_object` 会返回带 ` ``` ` 包裹的代码块,解析前要先剥离。 ## 在线调试 填入你自己的 API Key 即可直接发起请求,参数表与响应结构由接口定义生成。 # 快速开始 VibeAPI 兼容 OpenAI、Anthropic、Google 三家的官方协议,**官方 SDK 只需要换一个 base URL**。一把 key 可调用 GPT、Claude、Gemini、Grok 与国产模型。 只是想在 Claude Code、Codex 这类编码工具里用,不写代码?看[编码工具(VibeCLI)](https://docs.vibeapi.cn/zh/docs/coding-tools):一条命令装工具,一条命令配 key。 ## 获取 key 与地址 | | | | -------------------------------- | ------------------------------------------------------------- | | Base URL(OpenAI SDK / 直接调 HTTP) | `https://www.vibeapi.cn/v1` | | Base URL(Anthropic / Google SDK) | `https://www.vibeapi.cn`,SDK 自己拼 `/v1/messages`、`/v1beta/...` | | 认证 | 请求头 `Authorization: Bearer ` | | 可用模型 | `GET /v1/models`,或看[模型与入口](https://docs.vibeapi.cn/zh/docs/models) | `/v1` 只属于 OpenAI 协议这一族的路径。Anthropic SDK 与 Google `google-genai` SDK 填 base URL 时**不带** `/v1`,写 `https://www.vibeapi.cn` 即可,SDK 会自己拼上 `/v1/messages` 或 `/v1beta/...`;直接调 Gemini 原生 HTTP 时也是 `/v1beta/...`,不是 `/v1`。 ## 使用官方 SDK SDK 处理了以下几类容易出错的细节: 手写的 SSE 解析器几乎都会在这几处翻车:一个事件跨越多个 TCP 包、`data:` 出现多行、 注释行(以 `:` 开头)、以及最后的 `[DONE]` 哨兵。SDK 的迭代器直接给你解析好的事件对象。 流式下函数参数是**分片下发**的,要按 `index` 累积拼成完整 JSON 才能解析。 自己写很容易在多个并行工具调用时串行错位。 SDK 自带合理的超时默认值和对 429 / 5xx 的指数退避重试。裸 `requests.post` 不设超时, 一次网络抖动就是一个挂死的请求。 参数名写错、该用 `max_completion_tokens` 却用了 `max_tokens`、Messages 忘了必填的 `max_tokens`——这些在有类型提示的 SDK 里当场就能发现,不用等线上报 400。 安装: ```bash pip install openai # Responses / Chat / 图像 / Grok pip install anthropic # Claude Messages pip install google-genai # Gemini ``` ```bash npm install openai # Responses / Chat / 图像 / Grok npm install @anthropic-ai/sdk # Claude Messages npm install @google/genai # Gemini ``` ## 发第一个请求 ```python from openai import OpenAI client = OpenAI(base_url="https://www.vibeapi.cn/v1", api_key="YOUR_API_KEY") stream = client.responses.create( model="gpt-6-astra", input="用一句话解释什么是幂等。", stream=True, ) for event in stream: if event.type == "response.output_text.delta": print(event.delta, end="", flush=True) ``` ```javascript import OpenAI from "openai"; const client = new OpenAI({ baseURL: "https://www.vibeapi.cn/v1", apiKey: "YOUR_API_KEY", }); const stream = await client.responses.create({ model: "gpt-6-astra", input: "用一句话解释什么是幂等。", stream: true, }); for await (const event of stream) { if (event.type === "response.output_text.delta") process.stdout.write(event.delta); } ``` ```bash curl -N -X POST "https://www.vibeapi.cn/v1/responses" \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -d '{"model":"gpt-6-astra","input":"用一句话解释什么是幂等。","stream":true}' ``` 用环境变量更省事,两家 SDK 都认: ```bash # OpenAI SDK export OPENAI_BASE_URL="https://www.vibeapi.cn/v1" export OPENAI_API_KEY="sk-..." # Anthropic SDK export ANTHROPIC_BASE_URL="https://www.vibeapi.cn" export ANTHROPIC_API_KEY="sk-..." ``` 设好之后 `OpenAI()` / `Anthropic()` 不传参数就能直接用。 ## 开启流式 **请求超时上限是 120 秒。** 非流式请求在生成完成前没有任何数据下行,单次生成一旦超过 这个时间,连接会被中断,表现为「调用超时」。 短输出的非流式请求正常可用;长输出与推理型模型容易触发上限。该超时为硬约束, 无法通过配置放宽,而单次生成耗时又无法预先判断,**因此生产环境建议默认开启流式**。 需要一次性获得完整结果时,请在客户端聚合流式事件。两家 SDK 均提供了聚合接口: OpenAI SDK 的 `stream.get_final_response()`、Anthropic SDK 的 `stream.get_final_message()`。 ## 选择端点 按模型家族选它的原生协议,功能最全;跨协议调用是网关翻译的,只保证消息、流式和基本工具调用。 | 你要做的事 | 端点 | SDK | | -------------------------- | ------------------------------------------------------------------------------------------------- | ----------------------------------- | | GPT 系对话(`gpt-*`、`codex-*`) | [OpenAI Responses](https://docs.vibeapi.cn/zh/docs/responses),推荐 | `openai` | | Claude 系对话(`claude-*`) | [Claude Messages](https://docs.vibeapi.cn/zh/docs/messages) | `anthropic` | | Gemini 系对话(`gemini-*`) | [Gemini generateContent](https://docs.vibeapi.cn/zh/docs/gemini) | `google-genai` | | Grok 对话与国产模型 | [OpenAI Chat Completions](https://docs.vibeapi.cn/zh/docs/chat) / [Grok 对话](https://docs.vibeapi.cn/zh/docs/grok) | `openai` | | 生图 | [GPT 图像](https://docs.vibeapi.cn/zh/docs/images) · [Gemini 图像](https://docs.vibeapi.cn/zh/docs/gemini-images) · [Grok 图像](https://docs.vibeapi.cn/zh/docs/grok-images) | `openai` / `google-genai` | | 生视频 | [视频生成](https://docs.vibeapi.cn/zh/docs/videos)(万相 / Seedance / MiniMax)· [Grok 视频](https://docs.vibeapi.cn/zh/docs/grok-videos) | 直接 HTTP | | 判断而不是生成(路由 / 分类 / 打分) | [TypeSafe 判断型模型](https://docs.vibeapi.cn/zh/docs/typesafe) | `typesafe-sdk` / `@typesafe-ai/sdk` | 拿不准就查[模型与入口](https://docs.vibeapi.cn/zh/docs/models),那里逐个模型写明了推荐入口、可用入口,以及哪些是网关转换出来的。 ## 给 AI 编程代理装 Skill 本站打包成了一个 Skill。装进代理之后,涉及 VibeAPI 的任务里它会自动读:该走哪套协议、 为什么建议流式、网关会改写哪些参数、两类 key 的差异,以及每个参数的实测结果。内容与本站同源,随站点构建更新。 把这句话发给你的代理,它自己会装: ```text 帮我安装这个 Skill:https://docs.vibeapi.cn/vibeapi-skill.zip ``` 想手动装:解压得到 `vibeapi/`(`SKILL.md`、`references/`、`VERSION`、`scripts/update.sh`),放进代理的 skills 目录。 `SKILL.md` 是一份带 frontmatter 的普通 Markdown,不支持 Agent Skills 规范的工具, 把它贴进 `AGENTS.md` 或系统提示也能用,`references/` 下的文件按需附上。 **装一次,之后自己更新。** 每个 Skill 包都带版本号(内容截至日期 + 内容哈希,写在 `SKILL.md` 与 `VERSION` 里)。 `SKILL.md` 让代理每次会话开始时运行一次 `scripts/update.sh`:它读线上清单 [`vibeapi-skill.json`](https://docs.vibeapi.cn/vibeapi-skill.json),版本不同就下载新包、校验 sha256 后覆盖, 并删掉线上已下线的参考页。更新不了(离线、目录只读)时,代理会用 `date` 核对日期,内容超过 14 天就改读线上页面、 以 `GET /v1/models` 为准。想手动检查:`sh vibeapi/scripts/update.sh --check`。 ## 官方文档 我们只写与本网关有关的部分。参数语义的权威定义仍以官方为准: * [OpenAI API Reference](https://developers.openai.com/api/reference/overview) · [Responses](https://developers.openai.com/api/reference/resources/responses/methods/create) · [迁移到 Responses](https://developers.openai.com/api/docs/guides/migrate-to-responses) * [Anthropic Messages API](https://platform.claude.com/docs/en/api/messages) · [流式](https://platform.claude.com/docs/en/build-with-claude/streaming) * [Gemini API · generateContent](https://ai.google.dev/api/generate-content) * [xAI · API 文档](https://docs.x.ai/) # OpenAI Responses `POST /v1/responses` OpenAI 对新项目推荐这个端点而不是 Chat Completions,Chat 仍受支持但不再是首选。 公开理由集中在几点:推理模型上表现更好、提示缓存命中率显著更高(因而更便宜)、 可用 `previous_response_id` 跨轮保留推理与工具上下文、内置工具只在这一侧提供。 **在 VibeAPI 上,GPT 系模型的推荐入口就是这里。** 走这个端点的模型见 [模型与入口](https://docs.vibeapi.cn/zh/docs/models);Claude 系请去 [Messages](https://docs.vibeapi.cn/zh/docs/messages)。 ## 基本调用 **建议用官方 SDK 而不是自己拼 HTTP**——SSE 解析、工具参数分片拼接、超时与重试都由它处理,能避开大部分常见问题。安装与环境变量配置见[快速开始](https://docs.vibeapi.cn/zh/docs/quickstart)。 ```bash curl -N -X POST "https://www.vibeapi.cn/v1/responses" \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "gpt-6-astra", "instructions": "你是一个简洁的助手。", "input": "用一句话解释什么是幂等。", "stream": true }' ``` ```python from openai import OpenAI client = OpenAI(base_url="https://www.vibeapi.cn/v1", api_key="YOUR_API_KEY") stream = client.responses.create( model="gpt-6-astra", instructions="你是一个简洁的助手。", input="用一句话解释什么是幂等。", stream=True, ) for event in stream: if event.type == "response.output_text.delta": print(event.delta, end="", flush=True) ``` ```javascript import OpenAI from "openai"; const client = new OpenAI({ baseURL: "https://www.vibeapi.cn/v1", apiKey: "YOUR_API_KEY", }); const stream = await client.responses.create({ model: "gpt-6-astra", instructions: "你是一个简洁的助手。", input: "用一句话解释什么是幂等。", stream: true, }); for await (const event of stream) { if (event.type === "response.output_text.delta") process.stdout.write(event.delta); } ``` ## 认证 `Authorization: Bearer `,`base_url` 为 `https://www.vibeapi.cn/v1`。 官方 SDK 换掉 `base_url` 即可。 ## 流式要求 请求超时上限 **120 秒**。非流式请求在生成完成前没有数据下行,单次生成超过这个时间会被 中断。短输出不受影响;推理模型要等整段推理结束才返回首字节,容易触发上限。 **建议默认开启流式**,需要完整文本时在客户端聚合 `response.output_text.delta`。 ## 与 Chat 的差异 从 Chat 迁过来最容易卡在这里,先看懂再往下写代码。 Chat 的输入输出都是 **Message** 数组;Responses 用 **Item**。Item 是联合类型, `message` 只是其中一种,`function_call`、`function_call_output`、`reasoning` 各是独立的 一种——不再像 Chat 那样把多种含义塞进同一个对象。 响应形状也跟着变:Chat 返回 `choices` 数组、每项裹一个 `message`;Responses 返回一个 带自己 `id` 的 `response` 对象,产出在 `output` 数组里。Chat 用 `n` 一次要多个结果的 能力在这里去掉了,一次只有一个生成结果。 | | Chat Completions | Responses | | ---- | ---------------------------- | --------------------------- | | 输入单位 | `messages`(Message) | `input`(Item,也可直接给字符串) | | 系统指引 | `messages` 里的 `system` 角色 | `instructions` | | 产出位置 | `choices[0].message.content` | `output` 数组 / `output_text` | | 输出上限 | `max_completion_tokens` | `max_output_tokens` | | 多轮 | 自己把历史拼回 `messages` | `previous_response_id` | | 推理强度 | `reasoning_effort` | `reasoning.effort` | ## 请求参数 参数名、类型与语义对齐 [OpenAI Responses API](https://developers.openai.com/api/reference/resources/responses/methods/create)。每个参数先给官方定义,再以「网关」标注本网关的实测行为。 GPT 系模型的请求体不经改写,整个参数面照单转发;标注含义:**支持**=有可观测证据生效;**接受**=正常受理、效果取决于模型本身;**无效**=本网关不提供这项能力。 ### 核心 用于生成响应的模型 ID。走这个端点的模型见[模型与入口](https://docs.vibeapi.cn/zh/docs/models)。 给模型的文本、图片或文件输入。单轮问答直接给字符串;多轮、带工具结果或多模态时给 Item 数组。 插入模型上下文的系统(或 developer)消息。与 `previous_response_id` 同用时,上一轮的 `instructions` 不会带到下一轮,便于在多轮间替换指令——需要每轮都带。 ### 多轮与状态 上一次响应的唯一 ID,用于构建多轮对话:推理与工具上下文跨轮保留。不能与 `conversation` 同用。 **网关 · 支持。** 这是相对 Chat Completions 最实际的收益。 本次响应所属的会话:会话里的 Item 会前置到本次输入,本次的输入输出也会自动追加进会话。 **网关。** 依赖服务端存储,不保证可用。 是否保存生成的响应,供之后通过 API 取回;用 `previous_response_id` 串多轮时需要为 `true`。 要求响应额外带回的数据,如 `reasoning.encrypted_content`、`message.output_text.logprobs`、内置工具调用的中间产物。**接受。** 上下文管理配置,目前只有 `compaction`:达到 `compact_threshold` 个 token 时触发压缩。**接受。** ### 输出控制 为 `true` 时以 server-sent events 边生成边返回。 **网关。** 单次请求上限 120 秒,推理模型建议设为 `true`,见[流式要求](#流式要求)。 流式选项,仅在 `stream: true` 时设置(如 `include_obfuscation`)。**接受。** 本次响应可生成的 token 上限,**包含可见输出与推理 token**。不够时返回 `status: "incomplete"`、`incomplete_details.reason` 为 `max_output_tokens`,且可能一个可见字符都没产出就已计费。给推理模型留足空间。 文本响应的配置:纯文本或结构化 JSON。结构化输出写在 `{"format": {"type": "json_schema", ...}}`;能否严格遵守取决于模型。 `auto` 时输入超出上下文窗口会从对话开头丢弃 Item 以适配;`disabled` 时超出即报 400。**接受。** 以后台任务方式运行响应,之后轮询取结果。 **网关 · 无效。** 不提供后台任务接口。 ### 推理 推理模型的配置。`effort` 约束推理投入(`none` / `minimal` / `low` / `medium` / `high` / `xhigh` / `max`,支持的取值与默认值随模型而异);`summary` 要求返回推理摘要(`auto` / `concise` / `detailed`)。 **网关 · 实测(2026-09-23)。** `gpt-6-astra` 只接受 `low` 到 `max`,传 `none` 或 `minimal` 返回 400 `Unsupported value: 'none' is not supported with the 'gpt-6-astra' model`(`minimal` 被当成 `none` 处理); `gpt-6-sol` / `gpt-6-luna` 七档都接受,`minimal` 在响应里回显为 `none`。 ### 工具调用 模型可调用的工具数组:内置工具(联网搜索、文件检索、代码解释器、图像生成、远程 MCP 等)、函数工具、自定义工具。用 `tool_choice` 指定使用方式。 **网关。** 函数工具完整;内置工具不保证可用,也不保证与官方一致。 **联网搜索按次计费。** `web_search` 与 `web_search_preview` 按实际搜索次数(`output` 里的 `web_search_call` 条目)计费:GPT 系每千次 10 美元(gpt-4o、gpt-4.1 系列用 `web_search_preview` 时 25 美元),Grok 每千次 5 美元,乘分组倍率;声明了工具但模型没有搜索不收费。Grok 的 `x_search` 按抓取的帖子与用户资料计,见 [Grok · 联网搜索](https://docs.vibeapi.cn/zh/docs/grok#联网搜索)。调用日志里写明次数与费用。 模型如何选择工具:`none` / `auto` / `required`,或指定某个函数、某类内置工具。 是否允许模型并行执行工具调用。**接受。** 一次响应内内置工具调用的总次数上限,跨所有内置工具计数,超出的调用被忽略。**接受。** ### 提示缓存 引用服务端保存的提示模板及其变量(`id`、`version`、`variables`)。 **网关。** 依赖服务端存储,不保证可用。 用于把相似请求路由到同一缓存,提高提示缓存命中率;取代 `user` 字段的缓存用途。 **网关 · 支持。** 相同前缀的请求 `usage.input_tokens_details.cached_tokens` 能读到命中量,`auto` 与官方满血两类 key 都可用。Responses 相对 Chat 的省钱优势主要来自缓存,值得用起来。 提示缓存选项,`gpt-5.6` 及以后支持:`mode: "explicit"` 关闭隐式断点,`ttl` 目前只支持 `30m`。**接受。** 已弃用,改用 `prompt_cache_options.ttl`。设为 `24h` 延长缓存保留。**接受。** ### 采样与标识 采样温度,`0`–`2`。越高越随机,越低越集中;一般只调它或 `top_p` 之一。 **网关。** 部分推理模型忽略它或只接受默认值,取决于模型。 核采样,替代温度:只考虑累计概率达到 `top_p` 的那部分 token。 每个位置返回最可能的 `0`–`20` 个 token 及其对数概率,需在 `include` 里加 `message.output_text.logprobs`。**接受。** 最多 16 对键值,键 ≤ 64 字符、值 ≤ 512 字符,随对象存储、可供查询。**接受。** 帮助识别可能违反使用政策的终端用户的稳定标识,≤ 64 字符,建议用用户名或邮箱的哈希。**接受。** 终端用户的稳定标识,正被 `safety_identifier` 与 `prompt_cache_key` 取代。**接受。** 处理类型:`auto` / `default` / `flex` / `priority` 等。 **网关。** 由网关自行路由,该字段无意义。 对输入与输出运行内容审核的配置(`model`、`policy`)。**接受。** ## 响应字段 ```json { "id": "resp_...", "object": "response", "status": "completed", "model": "gpt-6-astra", "output": [ { "type": "reasoning", "id": "rs_...", "summary": [] }, { "type": "message", "id": "msg_...", "role": "assistant", "content": [{ "type": "output_text", "text": "同一个操作执行多次和执行一次效果相同。" }] } ], "usage": { "input_tokens": 32, "output_tokens": 18, "output_tokens_details": { "reasoning_tokens": 0 }, "total_tokens": 50 } } ``` 本次响应的 id,多轮时作为下一轮的 `previous_response_id`。 `completed` / `incomplete` / `in_progress` / `failed`。 `status` 为 `incomplete` 时的原因,最常见是 `max_output_tokens`。 产出的 Item 数组。**类型是混排的**——`reasoning`、`message`、`function_call` 都可能出现, 取正文务必按 `type` 过滤,不要直接取 `output[0]`。 官方 SDK 提供的便捷字段,把所有 `output_text` 片段拼好。裸 HTTP 调用时没有这个字段, 需要自己从 `output` 里取。 不可见的推理 token 数,**计费但不出现在正文里**。推理模型上对账要看这个。 ## 流式事件 事件是有类型的,按 `type` 分发,不像 Chat 那样只有一种 chunk: ``` event: response.created data: {"type":"response.created","response":{"id":"resp_...","status":"in_progress"}} event: response.output_text.delta data: {"type":"response.output_text.delta","delta":"同一个"} event: response.completed data: {"type":"response.completed","response":{"id":"resp_...","status":"completed"}} ``` 常见事件类型: 响应已创建,此时能拿到 `id`。 新增一个输出 Item(一条消息、一次函数调用、一段推理)。 正文增量。**只认这一种就够取全文了。** 函数调用参数的增量 JSON 片段,需自行累积拼接。 推理摘要增量,需在 `include` 里要求才会出现。 结束,带完整的 `response` 对象与 `usage`。 异常结束。**要处理这两种,否则失败会表现为「流断了但没报错」。** ## 参数改写规则 | 模型 | 触发条件 | 网关的动作 | | -------- | ----------------------------------------------------------------------- | --------------------- | | `grok-*` | `tools` 里的 `web_search` 带 `external_web_access` 或 `search_context_size` | 删掉这两个字段(xAI 不支持),工具保留 | | `grok-*` | `reasoning.effort` 为 `none` | 改写为 `low` | Claude 系模型也有一组改写规则(`thinking`、`temperature`、`top_p`),见 [Messages](https://docs.vibeapi.cn/zh/docs/messages) 页——从本页调用 Claude 时同样适用。 ## 分组差异 key 分两类:**`auto`**(可调用除 `claude-opus-5-5`、`claude-fable-5`、`claude-fable-5-1` 外的全部模型)和 **`Claude 官方满血版`**。 **对 GPT 系模型,两类 key 实测没有差异**——提示缓存与内置工具在两边都可用。 差异只出现在 Claude 系模型上,见 [Messages](https://docs.vibeapi.cn/zh/docs/messages) 页。 ## 真实响应示例 下面是从生产网关真实抓取、脱敏后的流式响应(中间的增量事件已省略): 非流式的完整响应对象: ## 能力边界 * **Claude 与 Gemini 系没有这个端点。** 原生入口分别是 [Messages](https://docs.vibeapi.cn/zh/docs/messages) 和 Gemini 的 `generateContent`。 * **服务端存储类字段不保证可用**:`conversation`、`prompt`、`background` 依赖官方的 服务端状态,本网关不提供对应的管理接口。 * **内置工具不保证可用**,也不保证与官方一致。 * **`reasoning_tokens` 不可用于对账。** 实测中这个字段多数情况下返回 `0`,即使 `reasoning.effort` 设为 `high`。它反映的是该字段是否被上报,不代表模型没有推理, 所以不要拿它核算推理成本。 * **非流式不适合推理模型。** ## 在线调试 填入你自己的 API Key 即可直接发起请求,参数表与响应结构由接口定义生成。 ## 官方文档 本页只写与本网关有关的部分,参数语义的权威定义以官方为准: * [OpenAI · Responses Create](https://developers.openai.com/api/reference/resources/responses/methods/create) * [OpenAI · 迁移到 Responses](https://developers.openai.com/api/docs/guides/migrate-to-responses) * [OpenAI · 推理模型](https://developers.openai.com/api/docs/guides/reasoning) # 文本对话概览 网关地址 `https://www.vibeapi.cn/v1`,`Authorization: Bearer `。文本对话有四套原生协议,按模型家族选它自己的那一套,功能最全; 跨协议调用是网关翻译的,只保证消息、流式和基本工具调用,协议特有字段(Claude 的 thinking 块、Gemini 的 thoughtSignature)会在翻译中丢失。 ## 协议怎么选 | 模型家族 | 端点 | 页面 | SDK | | ------------------------------------------ | --------------------------------------------- | ----------------------------------------------------- | ---------------------- | | GPT / Codex(`gpt-*`、`codex-*`) | `POST /v1/responses` | [OpenAI Responses](https://docs.vibeapi.cn/zh/docs/responses),推荐 | `openai` | | 同上,或任何模型的兼容调用 | `POST /v1/chat/completions` | [OpenAI Chat Completions](https://docs.vibeapi.cn/zh/docs/chat) | `openai` | | Claude(`claude-*`) | `POST /v1/messages` | [Claude Messages](https://docs.vibeapi.cn/zh/docs/messages) | `anthropic` | | Gemini(`gemini-*`) | `POST /v1beta/models/{model}:generateContent` | [Gemini generateContent](https://docs.vibeapi.cn/zh/docs/gemini) | `google-genai` | | Grok(`grok-*`) | `/v1/chat/completions` 或 `/v1/responses` | [Grok 对话](https://docs.vibeapi.cn/zh/docs/grok) | `openai` | | 国产(glm / kimi / qwen / deepseek / MiniMax) | `/v1/chat/completions` 或 `/v1/messages` | [Chat](https://docs.vibeapi.cn/zh/docs/chat) / [Messages](https://docs.vibeapi.cn/zh/docs/messages) | `openai` / `anthropic` | 逐个模型的推荐入口、可用入口与最后验证日期见[模型与入口](https://docs.vibeapi.cn/zh/docs/models)。 ## 建议默认流式 请求超时上限 **120 秒**。非流式请求在生成完成前没有任何数据下行,单次生成一旦超过这个时间,连接会被中断。 短输出不受影响;推理型号要等整段思考结束才返回首字节,容易触发。**生产环境建议默认开启流式**,需要完整文本时在客户端聚合 (OpenAI SDK `stream.get_final_response()`、Anthropic SDK `stream.get_final_message()`)。 ## 返回 200 不等于参数生效 两类情况都返回 200,只看状态码发现不了: **key 分组。** key 分 `auto`(可调用除 `claude-opus-5-5`、`claude-fable-5`、`claude-fable-5-1` 外的全部模型)和 `Claude 官方满血版` 两类。GPT 系在两类上实测没有差异; Claude 系在 `auto` 上会静默忽略提示缓存、`max_tokens`、`stop_sequences`、结构化输出,`claude-sonnet-5` 不返回 thinking 块。 依赖这些约束的代码必须用官方满血 key。详见 [Claude Messages · 分组差异](https://docs.vibeapi.cn/zh/docs/messages#分组差异)。 **网关改写。** 对部分模型,网关会在转发前删除或改写参数:Claude 新型号的 `temperature` / `top_p` / `top_k` 与 `thinking.budget_tokens`, Grok 在 Chat 接口上的内置 `web_search` 工具、Responses 上 `web_search` 的两个上游不支持的字段,以及 `reasoning.effort: none`。规则写在各页的「参数改写规则」小节。 判断依据是响应体——thinking 块在不在、`usage` 里有没有缓存字段、输出长度是否真的受 `max_tokens` 约束。 ## 国产模型 glm / kimi / qwen / deepseek / MiniMax 两套协议都能调通,工具调用全部可用;`max_tokens`、停止序列、结构化输出的遵循程度逐模型不同, `deepseek-v4-pro` 与 `kimi-k3` 不执行 `max_tokens` 却仍把结束原因报为已截断。逐项实测见[模型与入口 · 国产模型的协议兼容度](https://docs.vibeapi.cn/zh/docs/models#国产模型的协议兼容度)。 ## 各页的固定结构 每个协议页按同一骨架组织:基本调用(curl / Python / Node.js)→ 认证与流式要求 → 请求参数(先官方定义,再「网关」实测标注)→ 响应字段与流式事件 → 参数改写规则与分组差异 → 真实响应示例 → 能力边界 → 在线调试 → 官方文档。 # TypeSafe 判断型模型 `POST /v1/systemone` TypeSafe 的 **System One** 模型(当前是 **Jev**,模型名 `jev-latest`)和对话模型不是一类东西: 你给它一份 **state**(要评估的内容)和若干个带类型的 **questions**,它对每个问题返回一个 **概率**,不返回文字。三种问题类型——**Noul**(是 / 否的概率)、**Choice**(在你定义的选项里选一个, 附完整概率分布)、**Score**(在你定义的有序档位上按概率加权打分)——覆盖了路由、分类、打分、抽取、 校验这一类「代码里需要一小块常识判断」的场景。它快(本网关实测单次 1 秒左右)、便宜、输出可直接进 `if`。 本页讲在本网关上怎么调:地址、请求响应结构、三种原语怎么选、confidence 怎么用、计费与限制、错误。 概念与更多模式以 [TypeSafe 官方文档](https://docs.typesafe.ai/) 为准。最后验证:2026-09-19。 ## 给 AI 编程代理装 Skill TypeSafe 官方给 Claude Code 等代理写了一份 skill,教代理怎么把「提示词 + 解析文本」改成结构化判断、 三种原语怎么选、怎么组合与验证。我们把它完整译成中文,加上了本网关的差异(端点、令牌、按次计费、不支持 `models.list()`), 并附上 API 参考、模型页的中文版和本页的 Markdown 版。 把这句话发给你的代理,它自己会装: ```text 帮我安装这个 Skill:https://docs.vibeapi.cn/typesafe-skill.zip ``` 想手动装:解压得到 `typesafe/`(`SKILL.md`、`references/`、`VERSION`、`scripts/update.sh`),放进代理的 skills 目录。 它和主 skill 一样会自己检查更新,机制见[快速开始](https://docs.vibeapi.cn/zh/docs/quickstart#agent-skill)。 装了[VibeAPI 主 skill](https://docs.vibeapi.cn/zh/docs/quickstart#agent-skill) 的代理,也能从它的 `references/typesafe.md` 读到本页。 ## 与官方的差异 官方 SDK 和文档里的代码**只改两处**就能用:`base_url` 指到本网关,`api_key` 换成 VibeAPI 的令牌。 | | 官方 | 本网关 | | --------------- | ------------------------------------------- | ---------------------------------------------------------- | | 端点 | `https://api.typesafe.ai/v1/systemone` | `https://www.vibeapi.cn/v1/systemone` | | 认证 | TypeSafe 的 key | `Authorization: Bearer `,任意分组 | | 模型 | `jev-latest` / `jev-preview` / `jev-1.13.0` | 只开放 **`jev-latest`**(三者当前指向同一个模型) | | 计费 | 按输入 token | **按次**:一次请求一个价,与 state 长度、问题数量、返回 token 无关 | | `models.list()` | 返回 TypeSafe 形状 | **不支持**——本网关 `/v1/models` 是 OpenAI 形状,SDK 会报响应校验错误;模型名直接写死 | | 请求校验 | 上游 422 | 网关先做一层结构校验返回 400,再由上游做语义校验(422 逐条透出) | ## 基本调用 ```bash curl https://www.vibeapi.cn/v1/systemone \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "jev-latest", "state": "Help! My payouts have been failing for 3 days.", "questions": { "is_urgent": {"type": "noul", "instructions": "Does this convey urgency?"}, "department": {"type": "choice", "instructions": "Which team should handle this?", "criteria": {"billing": "Payments, invoicing, refunds", "technical": "Bugs, outages, integrations", "sales": "Pricing, upgrades, new accounts"}}, "frustration": {"type": "score", "instructions": "How frustrated is the customer?", "criteria": ["Calm", "Frustrated", "Very angry"]} } }' ``` ```python # pip install typesafe-sdk from typesafe_sdk import TypeSafeClient, Choice, Noul, Score client = TypeSafeClient(api_key="YOUR_API_KEY", base_url="https://www.vibeapi.cn") response = client.system_one( model="jev-latest", state={"document": "Help! My payouts have been failing for 3 days."}, questions={ "is_urgent": Noul(instructions="Does this convey urgency?"), "department": Choice( instructions="Which team should handle this?", criteria={"billing": "Payments, invoicing, refunds", "technical": "Bugs, outages, integrations", "sales": "Pricing, upgrades, new accounts"}, ), "frustration": Score( instructions="How frustrated is the customer?", criteria=["Calm", "Frustrated", "Very angry"], ), }, ) print(response.model) # 实际应答版本,如 jev-1.13.0 print(response.answers["is_urgent"].noul) # 0.95 dept = response.answers["department"] print(dept.choice, dept.confidence, dept.probabilities) print(response.answers["frustration"].score) # 1.05,落在 Frustrated 附近 ``` ```javascript // npm install @typesafe-ai/sdk (Node.js 20+) import { TypeSafeClient, noul, choice, score } from "@typesafe-ai/sdk"; const client = new TypeSafeClient({ apiKey: "YOUR_API_KEY", baseURL: "https://www.vibeapi.cn" }); const response = await client.systemOne({ model: "jev-latest", state: { document: "Help! My payouts have been failing for 3 days." }, questions: { is_urgent: noul("Does this convey urgency?"), department: choice("Which team should handle this?", { billing: "Payments, invoicing, refunds", technical: "Bugs, outages, integrations", sales: "Pricing, upgrades, new accounts", }), frustration: score("How frustrated is the customer?", ["Calm", "Frustrated", "Very angry"]), }, }); console.log(response.answers.is_urgent.noul); // 0.95 console.log(response.answers.department.choice); // "billing" console.log(response.answers.frustration.score); // 1.05 ``` 上面这次请求在本网关的真实响应(2026-09-19): ```json { "model": "jev-1.13.0", "answers": { "is_urgent": { "type": "noul", "noul": 0.95 }, "department": { "type": "choice", "choice": "billing", "confidence": 0.82, "probabilities": { "billing": 0.88, "technical": 0.12, "sales": 0.0 } }, "frustration": { "type": "score", "score": 1.05, "confidence": 0.93, "legend": { "0": "Calm", "1": "Frustrated", "2": "Very angry" }, "probabilities": { "0": 0.0, "1": 0.95, "2": 0.05 } } }, "usage": { "input_tokens": 395, "output_tokens": 73 } } ``` 三个问题、一次请求、一次计费。SDK 也支持环境变量:`TYPESAFE_API_KEY` 填 VibeAPI 令牌, `TYPESAFE_BASE_URL=https://www.vibeapi.cn`,`TYPESAFE_DEFAULT_MODEL=jev-latest`,然后 `TypeSafeClient()` 不传参。 ## 请求结构 固定写 `jev-latest`。这是别名,始终指向 Jev 当前稳定版;响应的 `model` 字段会报告实际应答的版本号(如 `jev-1.13.0`), 把它记进日志,方便日后对比。 要评估的内容。一段文字传字符串;有多个部分(消息、订单、策略)传**带名字字段的对象**,让每部分含义清楚、关系明确; 一串消息或记录传数组。同一次请求里所有问题看到的是同一份 state,各自独立评估。 **只接受文本。** 图片、音频、视频要先自己转成文字或结构化字段再放进来。英文是主要训练语言、准确率最高; 中文能处理但官方自述「不同等」,中文场景先用自己的数据测一轮,路由时多看 confidence。 问题映射,key 由你定,答案在同一个 key 下返回。**key 不会发给模型**,问题的完整含义要写在 `instructions` 里。 本网关要求至少 1 条、至多 256 条。 ### 三种问题 每个问题都有 `type` 和 `instructions`,`criteria` 的形状因类型而异。 `instructions` 写一个是 / 否问题;`criteria` 可选,`{"true": "是的含义", "false": "否的含义"}`。 返回 `noul`:0(否)到 1(是)的概率。**没有 confidence**——接近 0.5 表示「是」「否」概率相近,不是「中等程度」。 多个标签可能同时成立时,每个标签一个 noul,不要用 choice 单选。 `criteria` **必填**,是 `{选项: 说明}` 的对象,说明可为 `null`,至少一个选项。 返回 `choice`(概率最高的选项)、`probabilities`(每个选项的概率,总和为 1)、`confidence`。 可能什么都不匹配时,自己加一个 `"other"` / `"none"` 选项——模型选不出你没给的值。 `criteria` **必填**,是有序的档位描述数组,**至少两档**,每一档要描述一个具体、独立成立的情形。 返回 `score`(按概率加权的位置,可落在两档之间,如 1.6)、`legend`(档位编号 → 描述)、`probabilities`(每档概率)、`confidence`。 要给一批条目做分级排序,就给每个条目一个可比较的 score。 `instructions` 和 `criteria` 的值都接受字符串、对象或数组:简单问题用字符串;需要定义、对比、排除项或示例时用结构化写法。 引用 state 里的嵌套字段用反引号包路径,例如 `` `ticket.messages[0].text` ``。 ## 响应结构 实际执行评估的模型版本号。 每个问题一个答案,`type` 与问题一致。各类型的字段见上一节。 `input_tokens` / `output_tokens`。原样透传,**不参与本网关计费**,可用来观察 state 有多长。 ## 用 confidence 分流 Choice 和 Score 的 `confidence`(0–1)是把 `probabilities` 的集中程度压成的一个数:分布集中在一个选项上就高,摊开就低。 它衡量的是「模型对这一题有多确定」,不是整条业务流程的正确性,也不是「可以执行」的许可。一个常用起点是分三段: ```python action = response.answers["action"] if action.confidence < 0.5: route_to_human() # 模型真的不确定,别猜 elif action.choice == "check_balance": show_balance() # 低风险动作,错了可恢复,直接做 elif action.choice == "approve_transfer": if action.confidence > 0.9: confirm_then_execute() # 高风险 + 高确定:带确认执行 else: ask_user_to_confirm() # 高风险 + 中等确定:先核实 ``` 阈值随风险走:同一套系统里,只读操作和破坏性操作用不同的门槛。数字要在你自己的数据上试出来,从保守开始。 几个都可接受的备选项也会把概率摊开——对无害的偏好选择,低 confidence 不一定作废。 ## 一次问多个问题 一次请求评估一份 state、回答任意多个问题,问题之间并行、互不可见。**本网关按次计费,多问不加钱**, 所以把能一起问的都放进同一次请求,包括「如果是 A 分支,那 X 是多少」这类推测性问题—— 把前提写进问题里,由代码只消费命中的分支。只有当前一个答案是取证据、构造新 state 或决定下一步选项的前提时, 才值得发第二次请求。 上限:一次请求 64k token(state + 全部问题),其中 state + 单个最长问题不超过 32k;问题数不超过 256。 ## 计费与限制 | 项 | 值 | | --- | ---------------------------------------------------------------------------------------------------------- | | 计费 | **按次**,`jev-latest` 每次请求一个固定价,见[价格页](https://www.vibeapi.cn/pricing)。与 state 长度、问题数、token 数无关;`usage` 只是信息 | | 失败 | 400 / 401 / 422 / 429 / 5xx **不计费** | | 上下文 | 64k token / 请求;state + 最长问题 ≤ 32k | | 问题数 | 1–256 条 / 请求 | | 输入 | 仅文本;英文最佳,中文可用但先测 | | 超时 | 非流式、单次实测约 1 秒,不受对话模型 120 秒流式建议的影响 | | 限流 | 按令牌 / 模型限流,超限 429;上游过载 529。用官方 SDK 自带退避重试,直接调 HTTP 自己做指数退避 | ## 错误速查 | 状态 | 现象 | 先查 | | ----------------------------------------- | -------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | | 400 | `question "q": score criteria must contain at least two levels` 之类 | 网关本地校验:`state` / `model` / `questions` 必填;`type` 只认 `noul` / `choice` / `score`;`choice` 的 `criteria` 非空对象;`score` 至少两档;问题 ≤ 256 条 | | 401 | `Invalid token` | 用的是 VibeAPI 的 sk- 令牌吗(不是 TypeSafe 的 key);Anthropic / OpenAI SDK 那种带 `/v1` 的 base\_url 在这里**不要带** | | 422 | `questions/q/choice/instructions/str: Input should be a valid string; ...` | 上游校验:字段类型不对(如 `instructions` 传了数字、`criteria` 的值不是字符串)。路径用 `/` 分隔指到出错的字段 | | 429 / 529 | 限流 / 上游过载 | 退避重试 | | SDK 报 `Invalid response data at 'models'` | 调了 `models.list()` | 本网关不支持这个方法,模型名写死 `jev-latest` | | 503 `No available channel for model ...` | 模型名写错 | 只有 `jev-latest` | ## 官方文档 概念、更多模式与 cookbook 以官方为准,Mintlify 站在路径后加 `.md` 可拿 Markdown: * [文档索引](https://docs.typesafe.ai/llms.txt) · [System One 是什么](https://docs.typesafe.ai/concepts/system-one) · [如何用 TypeSafe 构建](https://docs.typesafe.ai/concepts/how-to-build-with-system-one) * [State](https://docs.typesafe.ai/concepts/state) · [原语](https://docs.typesafe.ai/primitives):[Choice](https://docs.typesafe.ai/primitives/choice) / [Noul](https://docs.typesafe.ai/primitives/noul) / [Score](https://docs.typesafe.ai/primitives/score) · [Confidence](https://docs.typesafe.ai/confidence) * [HTTP API](https://docs.typesafe.ai/api) · [Python SDK](https://docs.typesafe.ai/sdk/python) · [JavaScript SDK](https://docs.typesafe.ai/sdk/javascript) * 模式:[推测性扇出](https://docs.typesafe.ai/patterns/fan-out) · [复合打分](https://docs.typesafe.ai/patterns/composite-scoring) · [用例地图](https://docs.typesafe.ai/concepts/use-case-map) # MiniMax H3 `POST /v1/videos`,`model` 为 `MiniMax-H3`。按秒计费,见[视频生成](https://docs.vibeapi.cn/zh/docs/videos#模型与计费)。本页结论来自对本网关的真实调用,最后验证:2026-10-26。 ## 基本调用 ```bash # 1. 提交 curl https://www.vibeapi.cn/v1/videos \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "MiniMax-H3", "prompt": "日出时分的海面,镜头极缓慢推进,电影级布光", "seconds": "5", "aspect_ratio": "16:9" }' # 2. 轮询(每 10~15 秒一次) curl "https://www.vibeapi.cn/v1/videos/$TASK_ID" -H "Authorization: Bearer $API_KEY" # 3. 取片 curl -L "https://www.vibeapi.cn/v1/videos/$TASK_ID/content" \ -H "Authorization: Bearer $API_KEY" -o output.mp4 ``` ```python import time, requests BASE = "https://www.vibeapi.cn/v1" H = {"Authorization": "Bearer YOUR_API_KEY"} task = requests.post(f"{BASE}/videos", headers=H, json={ "model": "MiniMax-H3", "prompt": "日出时分的海面,镜头极缓慢推进,电影级布光", "seconds": "5", "aspect_ratio": "16:9", }).json() while True: s = requests.get(f"{BASE}/videos/{task['id']}", headers=H).json() if s["status"] in ("completed", "failed"): break time.sleep(12) if s["status"] == "completed": url = s.get("metadata", {}).get("url") or f"{BASE}/videos/{task['id']}/content" open("output.mp4", "wb").write(requests.get(url, headers=H).content) ``` ```javascript import fs from "fs"; const BASE = "https://www.vibeapi.cn/v1"; const H = { Authorization: "Bearer YOUR_API_KEY", "Content-Type": "application/json" }; const sleep = (ms) => new Promise((r) => setTimeout(r, ms)); const task = await (await fetch(`${BASE}/videos`, { method: "POST", headers: H, body: JSON.stringify({ model: "MiniMax-H3", prompt: "日出时分的海面,镜头极缓慢推进,电影级布光", seconds: "5", aspect_ratio: "16:9", }), })).json(); let s; while (true) { s = await (await fetch(`${BASE}/videos/${task.id}`, { headers: H })).json(); if (s.status === "completed" || s.status === "failed") break; await sleep(12_000); } if (s.status === "completed") { const url = s.metadata?.url ?? `${BASE}/videos/${task.id}/content`; fs.writeFileSync("output.mp4", Buffer.from(await (await fetch(url, { headers: H })).arrayBuffer())); } ``` 按秒计费,固定 768P,整数 1–15 秒。特点是**参考素材的种类最全**:图、视频、音频三类 可以同时给,提示词里用 `` `