---
title: "OpenAI SDK"
description: "用 OpenAI 官方 SDK（Python 与 TypeScript）调用 pirouter，只需改 base URL 和 API key，Chat Completions 与 Responses 两个接口都能用。本页说明怎么安装、配置、验证，以及常见报错怎么处理。"
canonical: "https://pirouter.ai/zh/docs/integrations/openai-sdk"
last-updated: "2026-10-17"
lang: "zh"
source: "content/docs/zh/integrations/openai-sdk.mdx"
---

# OpenAI SDK

用 OpenAI 官方 SDK（Python 与 TypeScript）调用 pirouter，只需改 base URL 和 API key，Chat Completions 与 Responses 两个接口都能用。本页说明怎么安装、配置、验证，以及常见报错怎么处理。

OpenAI 官方 SDK 不需要插件就能调用 pirouter：创建客户端时把 base URL 换成 pirouter 的地址，把 key 换成 pirouter 的 key，其余代码不用改。

## 前提

- 一把 pirouter API key。还没有的话，按[快速开始](https://pirouter.ai/zh/docs/quickstart.md)创建一个，并存进环境变量：

```bash
export PIROUTER_API_KEY="sk-pi-..."
```

- Python 3.10 及以上，或 Node.js 22 及以上。
- 安装 SDK：

Python:

```bash
pip install openai
```

TypeScript:

```bash
pnpm add openai
```

TypeScript 示例用了顶层 `await`，把文件存成 `.mjs`，或者在 `package.json` 里设 `"type": "module"`。

## 配置

创建客户端时传两项：`base_url`（TypeScript 是 `baseURL`）填 `https://api.pirouter.ai/v1`，`api_key`（TypeScript 是 `apiKey`）填你的 pirouter key。SDK 把 key 放在 `Authorization: Bearer` 请求头里发出，网关从这个头读 key。

模型 ID 写 `vendor/model` 全名。能用哪些模型，见[模型与协议](https://pirouter.ai/zh/docs/models.md#每个模型接受哪些协议)的协议表里 OpenAI 一列：除生图模型外，别家的模型也能通过 OpenAI 协议调用。

### Chat Completions

Python:

```python
import os
from openai import OpenAI

client = OpenAI(
    base_url="https://api.pirouter.ai/v1",
    api_key=os.environ["PIROUTER_API_KEY"],
)

completion = client.chat.completions.create(
    model="openai/gpt-6-sol",
    messages=[{"role": "user", "content": "Hello!"}],
)
print(completion.choices[0].message.content)
```

TypeScript:

```ts
import OpenAI from 'openai'

const client = new OpenAI({
  baseURL: 'https://api.pirouter.ai/v1',
  apiKey: process.env.PIROUTER_API_KEY,
})

const completion = await client.chat.completions.create({
  model: 'openai/gpt-6-sol',
  messages: [{ role: 'user', content: 'Hello!' }],
})
console.log(completion.choices[0].message.content)
```

### Responses

Python:

```python
import os
from openai import OpenAI

client = OpenAI(
    base_url="https://api.pirouter.ai/v1",
    api_key=os.environ["PIROUTER_API_KEY"],
)

response = client.responses.create(
    model="openai/gpt-6-sol",
    input="Hello!",
)
print(response.output_text)
```

TypeScript:

```ts
import OpenAI from 'openai'

const client = new OpenAI({
  baseURL: 'https://api.pirouter.ai/v1',
  apiKey: process.env.PIROUTER_API_KEY,
})

const response = await client.responses.create({
  model: 'openai/gpt-6-sol',
  input: 'Hello!',
})
console.log(response.output_text)
```

两个接口网关都提供：`POST /v1/chat/completions` 和 `POST /v1/responses`。

### 用环境变量

不传参数创建客户端时，SDK 读 `OPENAI_BASE_URL` 和 `OPENAI_API_KEY` 两个环境变量。设置一次，代码里写 `OpenAI()` 即可：

`~/.zshrc`:

```bash
export OPENAI_BASE_URL="https://api.pirouter.ai/v1"
export OPENAI_API_KEY="$PIROUTER_API_KEY"
```

### 流式输出

Chat Completions 加 `stream=True`（TypeScript 是 `stream: true`），然后逐块读 `choices[0].delta.content`：

Python:

```python
import os
from openai import OpenAI

client = OpenAI(
    base_url="https://api.pirouter.ai/v1",
    api_key=os.environ["PIROUTER_API_KEY"],
)

stream = client.chat.completions.create(
    model="openai/gpt-6-sol",
    messages=[{"role": "user", "content": "Hello!"}],
    stream=True,
)
for chunk in stream:
    if chunk.choices and chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="", flush=True)
print()
```

TypeScript:

```ts
import OpenAI from 'openai'

const client = new OpenAI({
  baseURL: 'https://api.pirouter.ai/v1',
  apiKey: process.env.PIROUTER_API_KEY,
})

const stream = await client.chat.completions.create({
  model: 'openai/gpt-6-sol',
  messages: [{ role: 'user', content: 'Hello!' }],
  stream: true,
})
for await (const chunk of stream) {
  process.stdout.write(chunk.choices[0]?.delta?.content ?? '')
}
console.log()
```

Responses 同样加 `stream`，文字在 `response.output_text.delta` 事件里：

Python:

```python
import os
from openai import OpenAI

client = OpenAI(
    base_url="https://api.pirouter.ai/v1",
    api_key=os.environ["PIROUTER_API_KEY"],
)

stream = client.responses.create(
    model="openai/gpt-6-sol",
    input="Hello!",
    stream=True,
)
for event in stream:
    if event.type == "response.output_text.delta":
        print(event.delta, end="", flush=True)
print()
```

TypeScript:

```ts
import OpenAI from 'openai'

const client = new OpenAI({
  baseURL: 'https://api.pirouter.ai/v1',
  apiKey: process.env.PIROUTER_API_KEY,
})

const stream = await client.responses.create({
  model: 'openai/gpt-6-sol',
  input: 'Hello!',
  stream: true,
})
for await (const event of stream) {
  if (event.type === 'response.output_text.delta') process.stdout.write(event.delta)
}
console.log()
```

你应该看到回复一段一段地打印出来。

## 验证

把上面 Chat Completions 的示例存成 `main.py` 或 `main.mjs`，然后运行：

Python:

```bash
python main.py
```

TypeScript:

```bash
node main.mjs
```

你应该看到模型的一句回复。

打开控制台的 **日志**，请求发出后几秒，这次请求出现在列表里，**端点** 一栏是 `/v1/chat/completions`。每个响应都带 `X-Pi-Trace-Id` 响应头，它和日志详情里的 **Trace ID** 是同一个值。

## 排障

### 401 invalid\_api\_key

返回 `401`，错误码 `invalid_api_key`，`message` 是 "You didn't provide an API key. Provide it in an Authorization header using Bearer auth (Authorization: Bearer YOUR\_KEY)."：请求没带上 key，或者带的不是以 `sk-pi-` 开头的 pirouter key。

确认运行代码的那个终端里设置了 `PIROUTER_API_KEY`。用环境变量写法时，`OPENAI_API_KEY` 要设成 pirouter 的 key，而不是 OpenAI 的。其他鉴权失败见[鉴权与 API key](https://pirouter.ai/zh/docs/authentication.md#鉴权失败时的返回)。

### 400 model is required

返回 `400`，错误码 `invalid_request`，`message` 是 `model is required`：base URL 多半填成了 `https://api.pirouter.ai`，漏了 `/v1`。这时请求的路径不是网关提供的端点，网关从中取不到模型。把 base URL 改成 `https://api.pirouter.ai/v1`。

### 422 validation\_failed

返回 `422`，错误码 `validation_failed`，`message` 以 "This model is not served on the endpoint you called." 开头：这个模型不在你调用的端点上提供，例如用生图模型调 Chat Completions。`message` 后半句列出它提供的端点；换一个端点，或者换一个在 OpenAI 协议下提供文本生成的模型。

## 目前没有验证的用法

- 网关只提供 Responses 的创建接口 `POST /v1/responses`。读取、删除、取消某个 response 的接口（如 `GET /v1/responses/{id}`）目前没有，调用返回 `400` 和 `model is required`。
- `client.embeddings` 用的 `POST /v1/embeddings` 目前没有，调用同样返回 `400`。
