阶跃星辰 API 怎么接:OpenAI 兼容形态

2026-08-25

数据截至 2026-08,价格与限额以各官网为准。本文只讲计费与接入机制,不列具体价格数字。

阶跃星辰的接入路径可以一句话说完:官方文档写明「兼容 OpenAI 的 API 规范」,所以你继续用 OpenAI 的 SDK,只把 api_key 换成阶跃的密钥、把 base_url 指到 https://api.stepfun.com/v1、把模型名换成阶跃的模型名,就完成了迁移。真正会绊住人的不是这三行改动,而是三件容易被忽略的事:官方列出的兼容接口是一份有明确边界的清单,不在清单里的能力不能按 OpenAI 的路子去猜;请求和返回里都多出了 OpenAI 侧没有的字段,尤其是推理相关的字段有两套命名;以及 429 和 503 这两个状态码在阶跃这边各自对应两种完全不同的原因,不看错误标识就会把限流当成欠费去处理。

三行改动:key、base_url、模型名

官方的迁移指南把改动范围压得很窄。Python SDK 这边,原来的客户端初始化只传 api_key,迁移后需要把 api_key 换成阶跃星辰的 API Key,并新增 base_url 设置为 https://api.stepfun.com/v1,然后在具体的模型设置中改成阶跃的模型即可。

from openai import OpenAI

client = OpenAI(api_key="STEP_API_KEY", base_url="https://api.stepfun.com/v1")

completion = client.chat.completions.create(
    model="step-3.7-flash",
    messages=[{"role": "user", "content": "你好"}],
)
print(completion)

TypeScript SDK 的改法一样,只是参数名按 SDK 自身的习惯写成 apiKeybaseURL。用 curl 直连时,请求地址是 POST https://api.stepfun.com/v1/chat/completions,认证走 Authorization: Bearer 头。

密钥从哪来?官方快速开始里写的是在开放平台「账号管理」子菜单的「接口密钥」页面获取。如果你是加入了组织、用项目下的 API Key 调用,官方文档特别说明了一点:项目下 API Key 的使用方式与个人 API Key 一致,不需要额外传递组织或项目标识——也就是说代码不用为「个人还是组织」分叉,差别只体现在费用从谁的账户扣、以及后面会讲到的额度报错上。密钥怎么管理、怎么轮换,可以参考站内这篇通用的 API Key 安全管理

兼容清单是白名单,别拿它当「全兼容」

这是我认为最值得先看的一节。官方文档在「API 兼容」小节里明确列出了与 OpenAI 兼容的接口:Chat Completion、上传文件、获取文件列表、获取文件信息、获取文件内容、删除文件、获取模型列表、查询单个模型信息、生成图片。

换句话说,这是一份可枚举的清单,不是「OpenAI 有的我都有」。清单里的接口你可以直接用 OpenAI SDK 的对应方法去调,比如查模型就是 GET https://api.stepfun.com/v1/models,SDK 里对应 client.models.list()。清单之外的能力——阶跃自己也提供音频、向量库、Realtime 之类的接口——官方是放在自家 API 参考里单独描述的,不在这份 OpenAI 兼容清单内。迁移时如果你原来的代码用到了 OpenAI 侧某个不在清单里的方法,就得去阶跃的接口文档里找对应形态,而不是假设它能透明跑通。换厂商时该逐项核对哪些东西,站内有一份 换厂商迁移清单 可以对照着走。

LangChain 的参数名和 SDK 不是一套

官方对 LangChain 单独给了迁移说明,因为参数名不一样,直接照抄 SDK 的写法会传不进去。

Python 的 LangChain 里,要改的是 ChatOpenAI 初始化时的 openai_api_keyopenai_api_basemodel_name 三个参数——注意 base 的参数名是 openai_api_base 而不是 base_url

LangChain.js 那边又是另一套。官方的说法是修改 ChatOpenAI 初始化时的 modelNameopenAIApiKeybasePath 即可切换,但要留意官方示例里这三个参数并不在同一处:modelNameopenAIApiKey 写在第一个参数对象里,basePath 单独写在第二个配置对象里,ChatOpenAI 是按两个对象接收的。所以最省事的做法是照抄官方示例的对象结构,而不是把三个参数拍平成一层去传。如果你手里有一层自己封装的配置读取逻辑,迁移时要专门确认 basePath 最终落在了第二个对象里。位置写错会出现什么现象,官方文档里没有找到相关说明,别靠猜——改完直接发一个最小请求,拿返回体里的 model 字段核对一下是不是阶跃的模型名,这比读代码猜配置有没有生效要快。

请求参数里,OpenAI 没有的那几个

Chat Completions 的参数表里,messagestoolsmax_tokenstemperaturetop_pnstreamstopfrequency_penaltyresponse_format 这些都是熟面孔,行为按官方文档描述与 OpenAI 侧对齐。真正需要你专门看一眼的是下面这几个。

reasoning_effort 控制模型的推理深度。官方写明:支持三档推理强度的模型可选值为 lowmediumhigh,值越高模型会进行更深入的思考,但响应时间可能更长。注意「支持三档」是有限定的,官方同时提到有的模型只兼容其中两档,所以别把三档当成所有模型的通用取值。

reasoning_format 决定推理内容用哪个字段名返回。官方给的可选项是 generaldeepseek-style:默认的 generalreasoning 字段返回结果,设置为 deepseek-style 时可以用 DeepSeek 兼容的 reasoning_content 字段获取推理内容。如果你的下游代码原本是按 DeepSeek 的字段名解析的,这个参数就是省事的开关。

response_formattype 官方列了三个取值:textjson_objectjson_schema。设为 json_object 就是开启 JSON Mode;设为 json_schema 时必须同时给 json_schema 对象,里面 nameschema 是必填,strict 可选,开启严格模式后模型输出将严格遵循所定义的 schema。官方在 JSON Mode 的使用建议里还补了一句实操要求:除了设参数,还要在 System Prompt 里放上你期望的 JSON 结构与说明,并推荐用 JSON Schema 的结构描述来帮助模型理解。

多模态输入这块,用户消息的 content 可以是普通文本字符串,也可以是 multipart 消息列表。图片消息的 type 固定为 image_urlurl 支持图片地址或 base64 编码,官方限定的格式是 jpg/jpeg、png、webp 和静态 gif,且仅支持 http 和 https 协议。图片还有个 detail 参数可选 lowhighhigh 按原图分辨率理解,在大图、OCR、极端长宽比等场景表现更好,token 随图片大小变化;low 会把图片缩放到固定尺寸、更省 token。视频消息用 video_url,官方对格式、体积和时长都有限制,具体数值以官方文档为准。

至于 temperaturetop_pmax_tokens 这几个有默认值的参数,官方文档都标了各自的默认行为(max_tokens 默认不作限制、由模型自动决定),但默认值属于会随版本调整的东西——如果你的业务原本依赖 OpenAI 侧的默认行为,迁移时最好显式写死,别指望两边默认值一致。具体默认值以官方文档当前版本为准。

返回体里多出来的字段

非流式返回的骨架和 OpenAI 一样:idobject(此模式下总为 chat.completion)、modelcreatedchoicesusage。差异在细节里。

message 下面除了 rolecontent,还可能有 reasoningreasoning_content。官方对这两个字段的描述是:它们一同返回且内容一致,后者是 DeepSeek 兼容的字段名,且都仅在 step 推理模型下返回。这句「仅在推理模型下返回」很关键——解析代码不要无条件取这两个字段。

usage 里除了三个 token 计数,还有两个可选的细分对象:prompt_tokens_details 下的 cached_tokens 表示提示信息中命中缓存的 token 数量,completion_tokens_details 下的 reasoning_tokens 表示推理思考过程消耗的 token 数量。这两个字段是你做成本归因时最直接的依据:推理档位调高会体现在 reasoning_tokens 上,Prompt 前缀稳不稳定会体现在 cached_tokens 上。官方在 Prompt 缓存文档里也是这么定位的——判断自己有没有命中缓存,就看返回的 usage 里有没有缓存 token 字段以及它的值。

流式返回时,object 变成 chat.completion.chunkmessage 变成 deltareasoningreasoning_content 同样出现在 delta 里,末尾以 data: [DONE] 收束。

429 和 503,各有两种含义

这一段值得单独记住,理由不是我的经验判断,而是官方自己在错误码文档里专门补了一句提醒:有两种额度相关的情况,错误码与速率限制相同,请以错误标识区分。文档愿意为这件事单独加一句话,说明只看状态码是分不清的。

先说 503。官方的错误码表里,503 的原因写的是「目前服务器负载过高」。但快速开始那页还写了另一种触发场景:官方为每个请求设定了时间限制,如果在这个时间限制内请求没有完成,系统不会继续等待,而是立即终止该请求并返回状态码为 503 的错误响应。具体时长以官方文档为准。所以看到 503,先分清是「服务端忙」还是「你这个请求跑太久被掐了」。对前一种,官方在错误码表里给的解决方案就是稍候重试您的请求;异常处理那页讲得更细一点,说 HTTP 500/503/504 表明是阶跃星辰的服务端出现的问题,遇到 5XX 错误时可以稍等重试,如多次重试后依然无法解决,则可以联系官方定位。对后一种,官方只写了触发条件是请求在时间限制内没有完成、系统会立即终止并返回 503,并没有给出对应的处理建议——按这个触发条件反推,你能动的只有单次请求的规模:把输入裁短、把 max_tokens 压小、把一次大任务拆成几次小调用,让单次请求落在时间限制之内。这两种情况混在同一个状态码里,官方文档也没有给出从响应本身区分它们的字段,所以要分清只能靠你自己在客户端留证据:把每次请求从发出到收到 503 的耗时记进日志,再对照官方文档写的那个时间限制看落在哪一侧。这件事得在接入时就做,等线上出问题再补,你手上就只有一个光秃秃的 503。

再说 429。常规含义是速率限制:请求频率超过限制就直接返回 429。但官方另有一张「组织额度相关错误码」表,明确写了「其中两种情况的错误码与速率限制相同,请以错误标识区分」——使用企业套餐的项目密钥调用时,project_credit_limit_exceeded 表示项目达到当期 Credit 上限,member_project_credit_limit_exceeded 表示成员在该项目内达到当期 Credit 上限,这两个都是 429。而余额不足是 402,错误标识 insufficient_credit

这意味着一个很实际的后果:如果你的重试逻辑是「收到 429 就退避重试」,那么在额度打满的场景下,你会一直重试到天荒地老也不会成功,因为官方给这两条的解决方案写的是由主账号调高上限、或者等待下月 1 号重置,而不是等一会儿再来。正确做法是把错误标识读出来,标识属于额度类的直接停机告警,只有真正的速率限制才走退避。退避策略本身怎么写,站内 429 的通用处理 讲得比这里细。

其余错误码官方也给了对照:400 是请求参数格式不正确,列出的可能原因包括图片无法下载、图片数量超过限制、该模型不支持视频输入、模型不存在或无权限、参数值不合法;401 是认证无效;404 是请求路径不正确;451 是请求内容或响应内容未审核通过,需要修改请求信息后重试;500 是服务端问题。

finish_reason 要处理几种

接口参考里,finish_reason 列出的可选值是 stop(正常结束)、length(达到 max_tokens 上限)和 tool_calls(模型发起工具调用)。而「异常事件处理建议」那页在讲模型层面的异常时,除了这三种还写了 content_filter:表示模型虽然按预定计划结束生成,但未通过安全审核,官方建议前置添加安全审核能力,让用户更早感知输入的问题。

两处文档的枚举范围不完全一致,稳妥的写法是四种都处理,并给未知取值留一条兜底分支。官方也特别提醒了流式场景:流式请求可能会在生成过程中因为模型输出原因结束,所以要对每一个 chunk 返回的 finish_reason 做判断,而不是只看最后一块。

Step Plan 是另一条通道

如果你看到 step_plan 这个路径不要以为写错了。官方在 Chat Completions 页面有一条注记:Step Plan 场景请使用 POST https://api.stepfun.com/step_plan/v1/chat/completions,和常规的 /v1 不是同一个入口。

官方还专门列了这条通道下的字段差异:model 仅接受 step-router-v1,其他名称会返回 HTTP 400 并带 request_params_invalidmax_tokens 有单独的上限(数值以官方文档为准);messages 中的图像与文档输入不支持,使用会返回 unsupported_content_typetools 中的 web_search 同样不支持,报同一个错误标识。

这几条限制值得抄进你的代码注释里——尤其是「图像输入不支持」这条,如果你的应用在两条通道之间做切换,多模态消息切到 Step Plan 通道后,官方写明会返回 unsupported_content_type,而不是自动降级成纯文本继续跑。也就是说这条错误你是能在响应里明确看到的,前提是你的切换逻辑没有把错误吞掉。

最后:报障时该带什么

阶跃的故障排查指南把「联系支持时要提供什么」写得很具体,这在真出问题时能省掉一轮来回。用 Chat API、文生图、图生图、图片编辑、音频生成、复刻音色、音频转写这些接口时,需要提供两样东西:响应头 Header 中的 X-Trace-Id 字段,以及生成结果中的 id。Realtime API 则要提供 session.createdsession.updated 里的 session.id;流式生成音频接口要提供任一事件中的 session_id

所以接入时顺手做一件事:把响应头里的 X-Trace-Id 和返回体的 id 一起落到你的日志里。等到线上出现一次说不清的异常再回头补,那次的现场就已经没了。至于跨厂商的兼容端点该怎么统一抽象,站内 OpenAI 兼容端点 那篇讲的是通用形态,和这篇的具体形态正好互补。

单价和限额一律以官方定价页与官方文档为准,本文不列具体数字——这些恰恰是最容易过期、也最不该从二手文章里抄的部分。

想系统学会用 AI?报名体系课或加入会员,照着学、照着用。