Generate Content
Google Gemini 原生内容生成接口,支持文本、图片、音频、视频多模态输入。
POST /v1beta/models/{model}:generateContent
请求示例
- Curl
- Python
- TypeScript
- Java
- Go
- PHP
- Ruby
- C#
curl https://gw.opentoken.io/v1beta/models/gemini-3.1-flash-image:generateContent \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPEN_TOKEN_KEY" \
-d '{
"contents": [{"parts": [{"text": "什么是机器学习?用简单的话解释。"}]}],
"generationConfig": {"temperature": 0.7, "maxOutputTokens": 10000}
}'
import os
import requests
response = requests.post(
"https://gw.opentoken.io/v1beta/models/gemini-3.1-flash-image:generateContent",
headers={
"Authorization": f"Bearer {os.environ['OPEN_TOKEN_KEY']}",
"Content-Type": "application/json",
},
json={
"contents": [{"parts": [{"text": "什么是机器学习?用简单的话解释。"}]}],
"generationConfig": {"temperature": 0.7, "maxOutputTokens": 10000},
},
)
response.raise_for_status()
print(response.json()["candidates"][0]["content"]["parts"][0]["text"])
const apiKey = process.env.OPEN_TOKEN_KEY;
if (!apiKey) {
throw new Error("OPEN_TOKEN_KEY is not set");
}
const response = await fetch(
"https://gw.opentoken.io/v1beta/models/gemini-3.1-flash-image:generateContent",
{
method: "POST",
headers: {
Authorization: `Bearer ${apiKey}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
contents: [{ parts: [{ text: "什么是机器学习?用简单的话解释。" }] }],
generationConfig: { temperature: 0.7, maxOutputTokens: 10000 },
}),
}
);
if (!response.ok) {
throw new Error(`Request failed: ${response.status} ${response.statusText}`);
}
const data = await response.json();
console.log(data.candidates[0].content.parts[0].text);
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class GenerateContent {
public static void main(String[] args) throws Exception {
String apiKey = System.getenv("OPEN_TOKEN_KEY");
if (apiKey == null || apiKey.isBlank()) {
throw new IllegalStateException("OPEN_TOKEN_KEY is not set");
}
String json = "{"
+ "\"contents\":[{\"parts\":[{\"text\":\"什么是机器学习?用简单的话解释。\"}]}],"
+ "\"generationConfig\":{\"temperature\":0.7,\"maxOutputTokens\":10000}"
+ "}";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://gw.opentoken.io/v1beta/models/gemini-3.1-flash-image:generateContent"))
.header("Authorization", "Bearer " + apiKey)
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(json))
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() < 200 || response.statusCode() >= 300) {
throw new IllegalStateException("Request failed: " + response.statusCode() + " " + response.body());
}
System.out.println(response.body());
}
}
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
)
func main() {
apiKey := os.Getenv("OPEN_TOKEN_KEY")
if apiKey == "" {
panic("OPEN_TOKEN_KEY is not set")
}
payload := map[string]interface{}{
"contents": []map[string]interface{}{
{"parts": []map[string]string{
{"text": "什么是机器学习?用简单的话解释。"},
}},
},
"generationConfig": map[string]interface{}{
"temperature": 0.7,
"maxOutputTokens": 10000,
},
}
jsonBody, err := json.Marshal(payload)
if err != nil {
panic(err)
}
request, err := http.NewRequest(
http.MethodPost,
"https://gw.opentoken.io/v1beta/models/gemini-3.1-flash-image:generateContent",
bytes.NewReader(jsonBody),
)
if err != nil {
panic(err)
}
request.Header.Set("Authorization", "Bearer "+apiKey)
request.Header.Set("Content-Type", "application/json")
response, err := http.DefaultClient.Do(request)
if err != nil {
panic(err)
}
defer response.Body.Close()
if response.StatusCode < 200 || response.StatusCode >= 300 {
body, _ := io.ReadAll(response.Body)
panic(fmt.Sprintf("request failed: %s: %s", response.Status, body))
}
body, err := io.ReadAll(response.Body)
if err != nil {
panic(err)
}
fmt.Println(string(body))
}
<?php
$apiKey = getenv('OPEN_TOKEN_KEY');
if (!$apiKey) {
throw new RuntimeException('OPEN_TOKEN_KEY is not set');
}
$ch = curl_init('https://gw.opentoken.io/v1beta/models/gemini-3.1-flash-image:generateContent');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'contents' => [['parts' => [['text' => '什么是机器学习?用简单的话解释。']]]],
'generationConfig' => ['temperature' => 0.7, 'maxOutputTokens' => 10000],
], JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR),
]);
$body = curl_exec($ch);
if ($body === false) {
throw new RuntimeException(curl_error($ch));
}
$statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($statusCode < 200 || $statusCode >= 300) {
throw new RuntimeException("Request failed: $statusCode $body");
}
$data = json_decode($body, true, 512, JSON_THROW_ON_ERROR);
echo $data['candidates'][0]['content']['parts'][0]['text'], PHP_EOL;
require 'json'
require 'net/http'
require 'uri'
api_key = ENV.fetch('OPEN_TOKEN_KEY')
uri = URI('https://gw.opentoken.io/v1beta/models/gemini-3.1-flash-image:generateContent')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri.request_uri)
request['Authorization'] = "Bearer #{api_key}"
request['Content-Type'] = 'application/json'
request.body = {
contents: [{ parts: [{ text: '什么是机器学习?用简单的话解释。' }] }],
generationConfig: { temperature: 0.7, maxOutputTokens: 10000 },
}.to_json
response = http.request(request)
unless response.is_a?(Net::HTTPSuccess)
raise "Request failed: #{response.code} #{response.body}"
end
data = JSON.parse(response.body)
puts data['candidates'][0]['content']['parts'][0]['text']
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
var apiKey = Environment.GetEnvironmentVariable("OPEN_TOKEN_KEY");
if (string.IsNullOrWhiteSpace(apiKey))
{
throw new InvalidOperationException("OPEN_TOKEN_KEY is not set");
}
using var client = new HttpClient();
using var request = new HttpRequestMessage(
HttpMethod.Post,
"https://gw.opentoken.io/v1beta/models/gemini-3.1-flash-image:generateContent");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", apiKey);
request.Content = new StringContent(JsonSerializer.Serialize(new
{
contents = new[]
{
new { parts = new[] { new { text = "什么是机器学习?用简单的话解释。" } } },
},
generationConfig = new { temperature = 0.7, maxOutputTokens = 10000 },
}), Encoding.UTF8, "application/json");
using var response = await client.SendAsync(request);
var body = await response.Content.ReadAsStringAsync();
response.EnsureSuccessStatusCode();
Console.WriteLine(body);
请求参数
| 参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
| contents | array | 是 | 对话内容列表;模型名不写在请求体中,而是写在 URL 的 {model} 位置。 |
| contents[].role | string | 否 | 内容角色,用户输入通常为 user。 |
| contents[].parts | array | 是 | 内容片段,可包含 text、inlineData、fileData 等对象。 |
| contents[].parts[].inlineData | object | 否 | 内联媒体数据,格式为 {"mimeType":"image/png","data":"<BASE64>"}。 |
| generationConfig | object | 否 | 生成配置,可设置 temperature、topP、topK、maxOutputTokens 等。 |
| generationConfig.responseModalities | array | 图片生成时建议显式填写 | 期望的输出类型。本页图片生成示例使用 ["TEXT", "IMAGE"],具体可用模态以所选模型能力为准。 |
| generationConfig.imageConfig | object | 否 | 图片输出配置,仅对支持图片生成的模型有效。 |
| generationConfig.imageConfig.aspectRatio | string | 否 | 请求的图片比 例,例如 16:9;可用值以当前模型能力为准。 |
| generationConfig.imageConfig.imageSize | string | 否 | 请求的图片尺寸档位,例如 1K、2K 或 4K;可用值以当前模型能力为准。 |
| safetySettings | array | 否 | 安全过滤设置 |
| tools | array | 否 | 工具/函数调用定义 |
gemini-3.1-flash-image 图像理解
curl https://gw.opentoken.io/v1beta/models/gemini-3.1-flash-image:generateContent \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPEN_TOKEN_KEY" \
-d '{
"contents": [
{
"parts": [
{
"text": "描述这张图片中的内容。"
},
{
"inlineData": {
"mimeType": "image/jpeg",
"data": "<BASE64_IMAGE_DATA>"
}
}
]
}
],
"generationConfig": {
"temperature": 0.7,
"maxOutputTokens": 10000
}
}'
将 <BASE64_IMAGE_DATA> 替换为图片文件的 Base64 编码内容。
例如 macOS 下可以执行:
base64 -i ~/Downloads/original.jpeg | tr -d '\n'
然后将输出结果复制到 data 字段中。
注意:
data字段只填写纯 Base64 内容;- 不要包含
data:image/jpeg;base64,前缀; - 不要填写图片路径,例如
/Users/xxx/original.jpeg; - 不要保留示例里的省略号
...; mimeType需要和图片真实格式一致,例如image/jpeg、image/png。
gemini-3.1-flash-image-preview 文本生成图片
curl "https://gw.opentoken.io/v1beta/models/gemini-3.1-flash-image-preview:generateContent" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPEN_TOKEN_KEY" \
-d '{
"contents": [
{
"role": "user",
"parts": [
{
"text": "生成一张未来感城市夜景海报,蓝紫色霓虹灯光,电影感构图。"
}
]
}
],
"generationConfig": {
"responseModalities": ["TEXT", "IMAGE"],
"imageConfig": {
"aspectRatio": "16:9",
"imageSize": "2K"
}
}
}'
gemini-3.1-flash-image-preview 参考图编辑
curl "https://gw.opentoken.io/v1beta/models/gemini-3.1-flash-image-preview:generateContent" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPEN_TOKEN_KEY" \
-d '{
"contents": [
{
"role": "user",
"parts": [
{
"text": "保留参考图中的主体和构图,将背景改为蓝紫色霓虹城市夜景。"
},
{
"inlineData": {
"mimeType": "image/jpeg",
"data": "<BASE64_REFERENCE_IMAGE>"
}
}
]
}
],
"generationConfig": {
"responseModalities": ["TEXT", "IMAGE"],
"imageConfig": {
"aspectRatio": "16:9",
"imageSize": "2K"
}
}
}'
gemini-3-pro-image-preview 文本生成图片
curl "https://gw.opentoken.io/v1beta/models/gemini-3-pro-image-preview:generateContent" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPEN_TOKEN_KEY" \
-d '{
"contents": [
{
"role": "user",
"parts": [
{
"text": "生成一张高细节商业海报,玻璃质感香水瓶,棚拍灯光,黑色背景。"
}
]
}
],
"generationConfig": {
"responseModalities": ["TEXT", "IMAGE"],
"imageConfig": {
"aspectRatio": "16:9",
"imageSize": "4K"
}
}
}'
gemini-3-pro-image-preview 参考图编辑
curl "https://gw.opentoken.io/v1beta/models/gemini-3-pro-image-preview:generateContent" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPEN_TOKEN_KEY" \
-d '{
"contents": [
{
"role": "user",
"parts": [
{
"text": "保留参考图中的产品外形和标签,将场景改为黑色高级感棚拍背景,增加轮廓光。"
},
{
"inlineData": {
"mimeType": "image/jpeg",
"data": "<BASE64_REFERENCE_IMAGE>"
}
}
]
}
],
"generationConfig": {
"responseModalities": ["TEXT", "IMAGE"],
"imageConfig": {
"aspectRatio": "16:9",
"imageSize": "4K"
}
}
}'
imageSize 是 Gemini 原生接口的图片尺寸档位。示例中 gemini-3.1-flash-image-preview 使用 2K,gemini-3-pro-image-preview 使用 4K。
响应结构
文本响应
{
"candidates": [{
"content": {
"parts": [{"text": "机器学 习是人工智能的一个分支..."}],
"role": "model"
},
"finishReason": "STOP"
}],
"usageMetadata": {
"promptTokenCount": 10,
"candidatesTokenCount": 25,
"totalTokenCount": 35
}
}
Gemini 图片模型响应
gemini-3.1-flash-image-preview 和 gemini-3-pro-image-preview 均按下面的 Gemini 原生结构返回。parts 是一个数组,可能包含文本、图片,或同时包含两者。图片通常位于 candidates[].content.parts[].inlineData:
{
"candidates": [
{
"content": {
"role": "model",
"parts": [
{
"inlineData": {
"mimeType": "image/jpeg",
"data": "<BASE64_GENERATED_IMAGE>"
}
}
]
},
"finishReason": "STOP"
}
]
}
响应可能只有图片,也可能包含文本。不要假设 parts[0] 的类型或顺序,应遍历 parts,分别检查 text 和 inlineData。图片格式以 inlineData.mimeType 为参考;如需严格校验,应在 Base64 解码后检查文件头。
结果校验与排错
HTTP 200 只表示这次 HTTP 调用成功返回,不能单独证明每个请求字段都已生效,也不能代替对生成结果的检查。图片生成请求完成后至少检查:
candidates是否存在且非空;candidates[].content.parts[]中是否存在inlineData.data;inlineData.mimeType是否为预期的图片类型;finishReason、promptFeedback和安全拦截信息是否异常;- Base64 解码后的图片像素尺寸是否符合预期。
如果响应中只有 text、没有 inlineData,优先检查模型是否支持图片输出,以及 responseModalities 和 imageConfig 是否使用了本页规定的 camelCase 写法。如果参考图未生效,同时检查 inlineData.data 是否为完整 Base64,且 mimeType 是否与图片真实格式一致。