# SDK 与框架

> OpenAI 与 Anthropic SDK、常用框架及图形客户端的接入方式，接口清单与重试、超时策略。

来源：https://www.scirouter.cn/docs/sdks · 更新于 2026-10-24

接口与 OpenAI 兼容，可修改 base URL 的 OpenAI 客户端均可直接使用，只需修改两项配置：

| 配置项 | 取值 |
|---|---|
| base URL | `https://api.scirouter.cn/v1` |
| API Key | 在 SciRouter 控制台创建的 Key（以 `sk-sr-` 开头，见[认证与 API Key](https://www.scirouter.cn/docs/authentication)），不能使用 OpenAI 的 Key |

示例中的 `YOUR_MODEL_ID` 为占位，替换为在[模型中心](https://www.scirouter.cn/models)选定的模型 id。Anthropic SDK 的接入见 [Anthropic SDK 与 Claude Code](#anthropic-sdk-与-claude-code)；Claude Code、Codex、Cursor 等编程工具的配置见[编程工具概览](https://www.scirouter.cn/docs/coding-tools)。

## Python（openai）

```bash
pip install openai
```

```python
import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["SCIROUTER_API_KEY"],
    base_url="https://api.scirouter.cn/v1",
)

# 非流式
resp = client.chat.completions.create(
    model="YOUR_MODEL_ID",
    messages=[{"role": "user", "content": "这段序列的二级结构倾向？"}],
)
print(resp.choices[0].message.content)

# 流式
stream = client.chat.completions.create(
    model="YOUR_MODEL_ID",
    messages=[{"role": "user", "content": "这段序列的二级结构倾向？"}],
    stream=True,
)
for chunk in stream:
    # 末尾的 scirouter 扩展分片与 include_usage 的用量分片 choices 为空，取值前先判断
    if chunk.choices and chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="", flush=True)
```

读取响应头 `X-Request-Id`（用于报障）与 `scirouter` 扩展字段：

```python
raw = client.chat.completions.with_raw_response.create(
    model="YOUR_MODEL_ID",
    messages=[{"role": "user", "content": "…"}],
)
print(raw.headers.get("X-Request-Id"))
resp = raw.parse()
print(resp.model_dump().get("scirouter"))
```

## Node.js / TypeScript（openai）

```bash
npm install openai
```

```typescript
import OpenAI from 'openai'

const client = new OpenAI({
  apiKey: process.env.SCIROUTER_API_KEY,
  baseURL: 'https://api.scirouter.cn/v1',
})

// 非流式，同时读取响应头
const { data, response } = await client.chat.completions
  .create({
    model: 'YOUR_MODEL_ID',
    messages: [{ role: 'user', content: '这段序列的二级结构倾向？' }],
  })
  .withResponse()
console.log(data.choices[0].message.content, response.headers.get('x-request-id'))

// 流式
const stream = await client.chat.completions.create({
  model: 'YOUR_MODEL_ID',
  messages: [{ role: 'user', content: '这段序列的二级结构倾向？' }],
  stream: true,
})
for await (const chunk of stream) {
  process.stdout.write(chunk.choices[0]?.delta?.content ?? '')
}
```

> 注意：不要在浏览器中使用上述代码，否则 Key 会暴露给所有访问者。前端页面应通过调用方自己的后端转发请求。

## LangChain（Python）

```bash
pip install langchain-openai
```

```python
import os
from langchain_openai import ChatOpenAI

llm = ChatOpenAI(
    model="YOUR_MODEL_ID",
    base_url="https://api.scirouter.cn/v1",
    api_key=os.environ["SCIROUTER_API_KEY"],
)
print(llm.invoke("这段序列的二级结构倾向？").content)
```

- `with_structured_output()` 默认发送 `json_schema` 并带 `strict: true`。模型支持原生结构化输出时原样传递；不支持时由平台模拟（强制工具或提示），响应头 `X-SciRouter-Param-Actions` 中出现 `emulated=response_format`，见[参数如何被处理](https://www.scirouter.cn/docs/params)。
- `ChatAnthropic`（接 `/v1/messages`，base URL 不带 `/v1`）获取结构化输出时默认使用强制工具。模型不支持强制工具时，平台降为 `auto` 并在提示中要求调用工具，结果尽力而为。
- LangChain 默认不发送 `stream_options.include_usage`，不影响用量统计：平台向上游始终请求用量，流式响应末尾仍返回 `usage`。

## LlamaIndex

```bash
pip install llama-index-llms-openai-like
```

```python
import os
from llama_index.llms.openai_like import OpenAILike

llm = OpenAILike(
    model="YOUR_MODEL_ID",
    api_base="https://api.scirouter.cn/v1",
    api_key=os.environ["SCIROUTER_API_KEY"],
    is_chat_model=True,
)
print(llm.complete("这段序列的二级结构倾向？"))
```

`is_chat_model=True` 不能省略。省略时 LlamaIndex 调用旧的 `/completions` 接口，平台不提供该接口。

## Vercel AI SDK

```bash
npm install ai @ai-sdk/openai-compatible
```

```typescript
import { createOpenAICompatible } from '@ai-sdk/openai-compatible'
import { generateText } from 'ai'

const scirouter = createOpenAICompatible({
  name: 'scirouter',
  baseURL: 'https://api.scirouter.cn/v1',
  apiKey: process.env.SCIROUTER_API_KEY,
})

const { text } = await generateText({
  model: scirouter('YOUR_MODEL_ID'),
  prompt: '这段序列的二级结构倾向？',
})
```

AI SDK 会重试流中无法识别的错误码，因此平台流内错误帧的 `code` 只使用原厂可识别的值（`rate_limit_exceeded`、`server_error` 等），平台码放在 `scirouter_code`，见[错误码](https://www.scirouter.cn/docs/errors)「流式响应中的错误」。

## Anthropic SDK 与 Claude Code

`/v1/messages` 为 Anthropic Messages 格式，Anthropic SDK（Python 的 `anthropic`、TypeScript 的 `@anthropic-ai/sdk`）与 Claude Code 可直接使用。这些客户端会自行拼接 `/v1`，**base URL 为 `https://api.scirouter.cn`，不带 `/v1`**。SDK 的完整写法见 [Messages（Anthropic 格式）](https://www.scirouter.cn/docs/messages)，Claude Code 的配置见 [Claude Code](https://www.scirouter.cn/docs/claude-code)。

## OpenAI Responses 与 Codex CLI

`/v1/responses` 为 OpenAI Responses 格式。新版 OpenAI SDK 的 `client.responses.create` / `stream` / `parse` 与 Codex CLI（`wire_api = "responses"`）可直接使用，base URL 与对话补全相同（带 `/v1`）。

平台不保存状态：`store` 只接受 `false`，不支持 `previous_response_id`。完整写法见 [Responses（OpenAI Responses 格式）](https://www.scirouter.cn/docs/responses)，Codex 的 `config.toml` 见 [Codex](https://www.scirouter.cn/docs/codex)。

## 图形客户端与 IDE 插件

Claude Code、Codex、OpenCode、Kilo CLI、Kilo Code、Cursor 与 CC Switch 各有一页配置说明，见[编程工具概览](https://www.scirouter.cn/docs/coding-tools)。其他桌面聊天客户端与 IDE 插件按服务商类型填写：

| 服务商类型 | API 地址 | Key |
|---|---|---|
| 「OpenAI 兼容」类 | `https://api.scirouter.cn/v1` | SciRouter 的 Key |
| 「Anthropic」类 | `https://api.scirouter.cn`（不带 `/v1`） | SciRouter 的 Key |

两类服务商均填写 SciRouter 的 Key，不填写厂商的 Key。部分客户端要求地址填到 `/v1` 为止，部分客户端会自动补上 `/v1`；填错时返回 404，改用另一种写法。

| 客户端 | 配置 |
|---|---|
| Cline、Continue | 选择 OpenAI 兼容的服务商，base URL 填 `https://api.scirouter.cn/v1`，模型填平台的模型 id |
| Dify | 选择「OpenAI-API-compatible」供应商，填写同样两项 |

Cursor、Cline、Continue 按 `error.code` 的原厂值识别错误（上下文超长为 `context_length_exceeded`，参数不支持为 `unsupported_parameter`），平台的错误体使用相同的值，见[错误码](https://www.scirouter.cn/docs/errors)「上游语义错误」。

Cursor、Cline、Continue、Dify 均不读取 `error.param` 自动调整参数。参数能否传到线路上由网关统一处理：提示类参数去掉并留痕，契约类参数翻译或模拟，见[参数如何被处理](https://www.scirouter.cn/docs/params)。

## 直接调用 HTTP

没有 SDK 的语言直接发送 HTTP 请求，与[快速开始](https://www.scirouter.cn/docs/quickstart)中的 curl 相同：`POST https://api.scirouter.cn/v1/chat/completions`，请求头 `Authorization: Bearer <Key>`，JSON 请求体。流式响应按 SSE 读取，要点见[对话补全](https://www.scirouter.cn/docs/chat-completions)。

## 接口清单

`/v1` 下提供以下接口：

| 接口 | 文档 |
|---|---|
| `GET /models`、`GET /models/{id}` | [模型列表](https://www.scirouter.cn/docs/models) |
| `POST /chat/completions` | [对话补全](https://www.scirouter.cn/docs/chat-completions) |
| `POST /embeddings` | [向量](https://www.scirouter.cn/docs/embeddings) |
| `POST /images/generations`、`POST /images/edits`、`POST /images/variations` | [图片](https://www.scirouter.cn/docs/images) |
| `POST /responses` | [Responses（OpenAI Responses 格式）](https://www.scirouter.cn/docs/responses) |
| `POST /messages`、`POST /messages/count_tokens` | [Messages（Anthropic 格式）](https://www.scirouter.cn/docs/messages) |

- 平台不提供旧的 `/completions`、语音、Assistants，以及 Responses 中按 id 读取、删除、取消已保存响应的接口（平台不保存响应），调用返回 404。
- `model` 必须是具体的模型 id，平台不提供 `auto` 这类虚拟模型。
- `/v1` 之外另有 MCP 端点 `https://api.scirouter.cn/mcp`（使用同一个 Key），供调用方的 agent 使用平台的检索与读库工具，见 [MCP 与托管工具](https://www.scirouter.cn/docs/mcp)。

## 重试与超时

官方 SDK 默认对连接错误、408、409、429 与 5xx 自动重试两次，并参考 `Retry-After`。SDK 不读取 `error.code`，因此以下错误也会被重试：

- `key_quota_exceeded`、`project_budget_exceeded` 等重试无效的 429；
- 不带 `Retry-After` 的 503（`details.reason` 为 `tools_unsupported` 等）。

这些请求在预扣之前被拒绝，不扣费，只增加几秒等待。需要精确控制时，将 `max_retries` 设为 0，按[错误码](https://www.scirouter.cn/docs/errors)自行分支。

**非流式请求最长等待约 270 秒，回答耗时可能超过该时长时使用流式。** 非流式请求在生成完成前连接上没有任何数据；平台最多等待整个响应约 270 秒，超时返回 504 `upstream_timeout`（`details.timeout` 为 `response`），不计费。该时长短于接入层（CDN）等待源站应答的 300 秒，因此客户端收到的是 JSON 错误体，不是 CDN 的 524。推理类模型单次回答可能需要数分钟，此类请求使用流式；流式响应带 `: ping` 心跳，不受该限制。

客户端超时应长于模型的正常耗时；非流式请求的超时设为 300 秒以上无效。

三个上游语义错误（上下文超长、参数不支持、内容审核）返回 400，SDK 不重试。它们的 `error.code` 为原厂兼容值（`context_length_exceeded` 等），平台码在 `error.scirouter_code`。各错误是否值得重试见[错误码](https://www.scirouter.cn/docs/errors)。
