---
title: "Gemini 协议"
description: "pirouter 上接受 Gemini 协议的模型可以用 Google GenAI SDK 或 REST 调用，请求体按 Google 官方格式写；和直连 Google 不同的是 key 必须放在 Authorization 请求头里，只带 x-goog-api-key 会返回 401。"
canonical: "https://pirouter.ai/zh/docs/api/gemini"
last-updated: "2026-10-17"
lang: "zh"
source: "content/docs/zh/api/gemini.mdx"
---

# Gemini 协议

pirouter 上接受 Gemini 协议的模型可以用 Google GenAI SDK 或 REST 调用，请求体按 Google 官方格式写；和直连 Google 不同的是 key 必须放在 Authorization 请求头里，只带 x-goog-api-key 会返回 401。

用 Google GenAI SDK 或 REST 调用 pirouter，改三项：base URL 填 `https://api.pirouter.ai`，key 换成 pirouter 的 API key 并放进 `Authorization: Bearer` 请求头，路径里的模型 ID 写成 `vendor/model`。请求体按 Google 官方格式写。

## 用 REST 调用

Gemini 协议有两个端点：

| 端点                                                  | 用途       |
| --------------------------------------------------- | -------- |
| `POST /v1beta/models/{model}:generateContent`       | 一次返回整个回复 |
| `POST /v1beta/models/{model}:streamGenerateContent` | 流式返回     |

模型 ID 写在路径里，写完整的 `vendor/model`，中间的斜杠原样保留，例如 `/v1beta/models/google/gemini-4-argon:generateContent`。pirouter 不会替你补厂商前缀。

cURL:

```bash
curl "https://api.pirouter.ai/v1beta/models/google/gemini-4-argon:generateContent" \
  -H "Authorization: Bearer $PIROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contents": [{ "parts": [{ "text": "Hello!" }] }]
  }'
```

Python:

```python
import os
from google import genai
from google.genai import types

client = genai.Client(
    api_key=os.environ["PIROUTER_API_KEY"],
    http_options=types.HttpOptions(
        base_url="https://api.pirouter.ai",
        headers={"Authorization": f"Bearer {os.environ['PIROUTER_API_KEY']}"},
    ),
)

response = client.models.generate_content(
    model="google/gemini-4-argon",
    contents="Hello!",
)
print(response.text)
```

TypeScript:

```ts
import { GoogleGenAI } from '@google/genai'

const ai = new GoogleGenAI({
  apiKey: process.env.PIROUTER_API_KEY,
  httpOptions: {
    baseUrl: 'https://api.pirouter.ai',
    headers: { Authorization: `Bearer ${process.env.PIROUTER_API_KEY}` },
  },
})

const response = await ai.models.generateContent({
  model: 'google/gemini-4-argon',
  contents: 'Hello!',
})
console.log(response.text)
```

成功时返回一个 JSON 响应，回复在 `candidates[0].content.parts[0].text` 里。控制台的 **日志** 里能找到这次请求。

要流式输出，把 `generateContent` 换成 `streamGenerateContent`。请求体不变，不需要 `stream` 字段：

```bash
curl -N "https://api.pirouter.ai/v1beta/models/google/gemini-4-argon:streamGenerateContent" \
  -H "Authorization: Bearer $PIROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contents": [{ "parts": [{ "text": "Hello!" }] }]
  }'
```

返回的是一行行 `data: ` 事件，每个事件在 `candidates` 里带一段回复。最后一个事件带 `finishReason` 和 `usageMetadata`，之后没有单独的结束标记。带不带 `?alt=sse`，返回的都是这样的事件流。

请求体原样转发给 provider，只去掉 `provider` 这类路由字段。

## 用 Google GenAI SDK

创建客户端时改两处：

1. base URL 填 `https://api.pirouter.ai`。不要设 API 版本，SDK 默认会拼上 `/v1beta`。
2. 在 `http_options`（TypeScript 是 `httpOptions`）的 `headers` 里加 `Authorization: Bearer` 请求头。SDK 的 `api_key` 参数照常传。

上面 Python 和 TypeScript 两个 Tab 就是这样写的。

## 只带 x-goog-api-key 时返回 401

pirouter 不读 `x-goog-api-key`，也不读查询参数 `?key=`，转发前还会删掉这两处的值。照 Google 的 REST 示例只带 `x-goog-api-key`：

```bash
curl "https://api.pirouter.ai/v1beta/models/google/gemini-4-argon:generateContent" \
  -H "x-goog-api-key: $PIROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contents": [{ "parts": [{ "text": "Hello!" }] }]
  }'
```

返回 `401`：

```json
{
  "error": {
    "message": "You didn't provide an API key. Provide it in an Authorization header using Bearer auth (Authorization: Bearer YOUR_KEY).",
    "type": "invalid_request_error",
    "code": "invalid_api_key"
  }
}
```

加上 `Authorization: Bearer` 就能通过；SDK 默认带上的 `x-goog-api-key` 不用去掉。网关读哪些请求头见[在请求里带上 key](https://pirouter.ai/zh/docs/authentication.md#在请求里带上-key)。

## 哪些模型能用

Google 的 Gemini 系列接受 Gemini 协议，包括几个图像生成模型。要确认一个模型，看 `GET /v1/models/{vendor}/{model}/endpoints` 返回的 `protocols` 里有没有 `gemini`，或者在[模型列表](https://pirouter.ai/zh/models)里看每个模型的协议。

Gemini 协议没有单独的图像生成端点：图像模型同样调用 `generateContent`，生成的图像在回复的 `inlineData` 里。写法见[生成与编辑图像](https://pirouter.ai/zh/docs/guides/images.md)。

## 与 Google 官方行为的差异

| 方面                  | pirouter 的行为                                                                                                                                 |
| ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| 鉴权                  | 不读 `x-goog-api-key` 和 `?key=`，见[只带 x-goog-api-key 时返回 401](https://pirouter.ai/zh/docs/api/gemini.md#只带-x-goog-api-key-时返回-401)              |
| 响应里的 `modelVersion` | 改写为 pirouter 的模型 ID（`vendor/model`）。provider 自己报的名字在响应头 `X-Pi-Upstream-Model` 里                                                              |
| provider 的请求 ID     | 部分 provider 不返回请求 ID，这时响应没有 `X-Pi-Upstream-Request-Id`                                                                                       |
| 错误体                 | pirouter 自己的错误是 `{"error": {"message", "type", "code"}}`，`code` 是字符串错误码，见[错误码](https://pirouter.ai/zh/docs/api/errors.md)。provider 返回的错误原样转发 |
| 故障切换                | provider 在返回第一个字节之前失败时，pirouter 换到下一个 provider，见[故障切换](https://pirouter.ai/zh/docs/guides/routing.md#故障切换)                                   |

## 目前没有的能力

下面这些 Gemini 方法 pirouter 目前没有：

- `countTokens`。调用 `POST /v1beta/models/{model}:countTokens` 返回 `400` `invalid_request`，`message` 是 `model is required`，意思是 pirouter 不提供这个方法，见 [`invalid_request`](https://pirouter.ai/zh/docs/api/errors.md#invalid_request)。
- `embedContent` 等其他方法。

## 下一步

- [生成内容](https://pirouter.ai/zh/docs/api/generate-content.md): generateContent 端点的全部参数与响应。
- [鉴权与 API key](https://pirouter.ai/zh/docs/authentication.md): key 放在哪个请求头，怎么创建和吊销。
