# SDK 与框架

> Python、Node.js、LangChain、LlamaIndex、Vercel AI SDK 的接法，以及我们没有的那些接口。

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

接口与 OpenAI 兼容，所以**任何能改 base URL 的 OpenAI 客户端都能直接用**。要改的只有两处：

| | 值 |
|---|---|
| base URL | `https://api.scirouter.cn/v1` |
| API Key | 控制台新建的那一把（见「认证与 API Key」） |

下面是常见写法。模型 id 换成你在[模型中心](https://www.scirouter.cn/models)挑好的那个。

## 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="bio/protein-72b",
    messages=[{"role": "user", "content": "这段序列的二级结构倾向？"}],
)
print(resp.choices[0].message.content)

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

拿响应头（报障用的 `X-Request-Id`）和扩展字段：

```python
raw = client.chat.completions.with_raw_response.create(
    model="bio/protein-72b",
    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
```

```ts
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: 'bio/protein-72b',
    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: 'bio/protein-72b',
  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="bio/protein-72b",
    base_url="https://api.scirouter.cn/v1",
    api_key=os.environ["SCIROUTER_API_KEY"],
)
print(llm.invoke("这段序列的二级结构倾向？").content)
```

## LlamaIndex

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

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

llm = OpenAILike(
    model="bio/protein-72b",
    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` 不能省：不写的话它会去调旧的 `/completions` 接口，我们没有这个接口。

## Vercel AI SDK

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

```ts
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('bio/protein-72b'),
  prompt: '这段序列的二级结构倾向？',
})
```

## 图形客户端

各种桌面聊天客户端、IDE 插件里选「OpenAI 兼容」一类的服务商，填 API 地址与 Key 即可。
注意有的客户端要你填到 `/v1` 为止，有的会自己补上 `/v1`——填错会得到 404，换另一种写法再试。

## 没有 SDK 的语言

直接发 HTTP。请求就是「快速开始」里那条 curl：`POST https://api.scirouter.cn/v1/chat/completions`，
`Authorization: Bearer <Key>`，JSON 请求体。流式按 SSE 读，要点见「对话补全」。

## 我们只有这几个接口

`/v1` 下现在是：`GET /models`、`GET /models/{id}`、`POST /chat/completions`、`POST /embeddings`。
旧的 `/completions`、图片、语音、Assistants、Responses 等接口**没有**，调用会得到 404。
框架默认走这些接口时（例如某些版本默认用 Responses API），请把它切到 Chat Completions。

## 重试与超时

- 官方 SDK 默认会对 429 与 5xx 自动重试两次，并遵守 `Retry-After`——这正是我们希望的行为，不用再包一层；
- 推理类模型一次回答可能要几分钟，请把超时设长，或者用流式；
- 哪些错误值得重试、哪些不值得，见「错误码」。
