Appearance
OpenRouter 支持对任意模型启用流式传输(SSE),只需在请求中设置 stream: true。本页说明流式传输的基本用法、SSE 注释处理、通过 AbortController 取消流,以及不同时机的错误处理方式。流式取消功能(立即停止计费)目前支持 OpenAI、Anthropic 等主流提供商,不支持 AWS Bedrock、Groq、Google 等。
OpenRouter API Streaming
OpenRouter 支持对任意模型启用流式传输,方便实时展示模型的生成过程。
基本用法
在请求中设置 stream: true:
typescript
import { OpenRouter } from '@openrouter/sdk';
const openRouter = new OpenRouter({
apiKey: '<OPENROUTER_API_KEY>',
});
const stream = await openRouter.chat.send({
model: 'openai/gpt-4o',
messages: [{ role: 'user', content: '如何建造世界上最高的建筑?' }],
stream: true,
});
for await (const chunk of stream) {
const content = chunk.choices?.[0]?.delta?.content;
if (content) {
process.stdout.write(content);
}
// 最后一个 chunk 包含用量统计
if (chunk.usage) {
console.log('\n用量:', chunk.usage);
}
}SSE 注释
OpenRouter 会偶尔发送 SSE 注释来防止连接超时,格式如下:
: OPENROUTER PROCESSING按照 SSE 规范,这类注释可以安全忽略。你也可以利用它改善 UX,比如在等待时显示加载动画。
每个请求的 X-Generation-Id 响应头中会返回生成 ID,方便调试和追踪。
流式取消
通过 AbortController 可以取消正在进行的流式请求:
typescript
import { OpenRouter } from '@openrouter/sdk';
const openRouter = new OpenRouter({ apiKey: '<OPENROUTER_API_KEY>' });
const controller = new AbortController();
try {
const stream = await openRouter.chat.send({
model: 'openai/gpt-4o',
messages: [{ role: 'user', content: '写一个故事' }],
stream: true,
}, {
signal: controller.signal,
});
for await (const chunk of stream) {
const content = chunk.choices?.[0]?.delta?.content;
if (content) process.stdout.write(content);
}
} catch (error) {
if (error.name === 'AbortError') {
console.log('流已取消');
} else {
throw error;
}
}
// 取消流:
controller.abort();取消流后,支持的提供商会立即停止模型处理并停止计费;不支持的提供商会继续处理并照常收费。
支持流式取消的提供商
支持:OpenAI、Azure、Anthropic、Fireworks、Mancer、Recursal、AnyScale、Lepton、OctoAI、Novita、DeepInfra、Together、Cohere、Hyperbolic、Infermatic、Avian、XAI、Cloudflare、SFCompute、Nineteen、Liquid、Friendli、Chutes、DeepSeek
暂不支持:AWS Bedrock、Groq、Modal、Google、Google AI Studio、Minimax、HuggingFace、Replicate、Perplexity、Mistral、AI21、Featherless、Lynn、Lambda、Reflection、SambaNova、Inflection、ZeroOneAI、AionLabs、Alibaba、Nebius、Kluster、Targon、InferenceNet
流式传输中的错误处理
首个 token 前的错误
返回标准 JSON 错误,带对应 HTTP 状态码(400/401/402/429/502/503)。
已发送部分 token 后的错误
HTTP 状态码已确定(200 OK),错误以 SSE 事件形式返回,finish_reason 为 "error":
typescript
async function streamWithErrorHandling(prompt: string) {
try {
const stream = await openRouter.chat.send({
model: 'openai/gpt-4o',
messages: [{ role: 'user', content: prompt }],
stream: true,
});
for await (const chunk of stream) {
// 检查 chunk 中的错误
if ('error' in chunk) {
console.error(`流错误: ${chunk.error.message}`);
if (chunk.choices?.[0]?.finish_reason === 'error') {
console.log('流因错误终止');
}
return;
}
const content = chunk.choices?.[0]?.delta?.content;
if (content) process.stdout.write(content);
}
} catch (error) {
// 处理首个 token 前的错误
console.error(`错误: ${error.message}`);
}
}常见问题
Q: 哪些 SSE 客户端库兼容 OpenRouter 的流格式?
A: 部分 SSE 客户端不按规范解析非 JSON payload,会在处理注释时抛出异常。建议使用 OpenRouter SDK,或确认你的 SSE 库能正确处理注释行(以 : 开头的行)。
Q: 流式传输和非流式传输的收费方式一样吗?
A: 是的,都按实际的 prompt tokens + completion tokens 收费。取消流时,支持该功能的提供商会在取消点停止计费。
Q: X-Generation-Id 有什么用?
A: 可用于在 OpenRouter Activity 页面追踪单次请求的详细统计,也可通过 /api/v1/generation?id=<ID> 端点查询。