常见问题
为什么这次扣费比预估多?
先看响应里的 usage 和 lokospace_billing,不要只看请求参数。常见原因有六类:
| 现象 | 原因 | 怎么核对 |
|---|---|---|
| 文本费用高于按输出字数估算 | 输入 token 也算钱,系统提示、工具定义、历史消息都算输入 | 看 usage.prompt_tokens 或 usage.input_tokens |
| 输出费用比预期高 | 模型有 completion_ratio,输出 token 可能按输入价的倍数计费 | 看模型计费详情里的 completion_ratio |
| 首次调用更贵 | 缓存写入按 cacheWriteRatio 计费,常见配置是 1.5 倍 | 看 usage.cache_write_tokens |
| 多张图片费用翻倍 | per_unit 按张数乘,n 不是 1 就按 n 倍 | 看请求里的 n 和返回的 creditsUsed |
视频比 duration 略贵 | 计费秒数向上取整,且不低于 min_billing_seconds | 看模型详情的按秒价和最短计费秒数 |
| 重试后出现第二笔 | 换了新的幂等键,平台会当成新请求 | 对比两次的 request_id |
max_tokens 是上限,不是实际输出量。实际扣费按上游返回的用量算。余额不够时,网关还可能把输出上限下调到可支付范围,这会让结果变短,但不会让单价变高。
如果仍然对不上,拿 request_id 查积分流水。流水里能看到扣费额和扣费后余额。
缓存命中率为什么不高?
缓存命中不是配置了就有。它至少取决于三件事:模型是否支持缓存、这次请求的前缀是否和上次一致、上游这次有没有返回缓存用量。
先确认这个模型有没有开启缓存计费。只有 model_pricing.pricing_basis.cacheBilling 为 true 时,cacheReadRatio 和 cacheWriteRatio 才生效;否则一律按 1 倍,等于没有缓存折扣。
再看响应:
usage.cached_tokens大于 0,说明这次确实命中了。usage.cache_write_tokens大于 0,说明这次写入了缓存。lokospace_billing.metering.cacheReadTokens和cacheWriteTokens是网关归一化后的值。
想提高命中率,把稳定的内容放前面:系统提示、工具定义、固定知识库放在前缀,时间戳、随机 ID、每次都变的用户信息放后面。前缀一变,缓存就容易失效。
缓存写入本身可能按 1.5 倍计费。只调用一次的长前缀,写入缓存不一定划算;同一段前缀反复使用时才有意义。平台不承诺任何命中率。
模型列表里有,为什么调不通?
/models 返回的是当前账号可售的全部模型,不等于每个入口都接受它。图片、视频、音频有各自的专用接口,不能拿文本入口去调。
按错误码判断:
| 错误码 | 实际原因 | 处理 |
|---|---|---|
403 MODEL_ACCESS_DENIED | 账号或团队没有这个模型的权限 | 换模型或让管理员开通 |
400 MODEL_PROTOCOL_MISMATCH | 用了模型不支持的协议 | 换文本入口,或改用对应类型的接口 |
400 MEDIA_MODEL_MODE_UNSUPPORTED | 视频模型不支持图生视频或当前模式 | 去掉 image_url,或换支持该模式的模型 |
404 MEDIA_MODEL_NOT_FOUND | 模型不存在、停用,或类型用错 | 到 /images/models 或 /videos/models 确认真实 id |
402 INSUFFICIENT_CREDITS | 余额不够 | 充值或缩小请求 |
503 MODEL_PRICING_MISSING | 这个模型没有按 Token 定价,通常是图片/视频模型被拿来当文本调 | 换对应类型的接口 |
503 CHANNEL_CREDENTIAL_MISSING | 渠道没有可用凭证 | 稍后重试或联系支持 |
另外确认 model 用的是列表里的 id,不是显示名。别名有时能用,但排障时先用精确 id。
流式输出中断了,会不会重复扣费?
分两种情况。
还没收到任何内容帧就断了:这次没有产生可用输出,通常不会扣费。可以用同一个 Idempotency-Key 重试,平台会按同一个请求处理。
已经收到部分内容后断了:网关会把这次请求标记为账单待核对,不会立刻再扣一笔,也不会按整单退款。保留 x-lokospace-request-id 或 lokospace_billing.requestId,先对账,不要直接换新幂等键重发。
平台在等待首帧时会发 SSE 心跳注释,避免长连接被中间层误判为空闲。客户端要把以 : 开头的行当成注释忽略,不要当业务数据。
如果中断频繁,先检查客户端和服务端之间的代理超时、缓冲区设置,以及客户端自己的读超时。不要用 30 秒以内的读超时去接长回答。
视频任务一直 queued 怎么办?
queued 表示任务已受理,但还没拿到可用的上游任务 ID,或上游还没开始处理。它不是失败。
正确做法是用创建时返回的 id 轮询:
GET /videos/generations/<id>
不要重新 POST,也不要用新的幂等键再建一个任务。
当前实现:
- 后台默认每 10 秒查一次,最多 30 分钟。
- 只有当前 Node 进程存活时,后台轮询才会继续。
- 服务重启后,后台轮询会停;你再调用一次
GET /videos/generations/:id,才会继续查询和触发退款。 - 任务创建超过 2 小时仍未完成,查询时会返回
failed并退款。 - 如果一直不查询,服务重启后它可能一直显示
queued,不会自动退款。
如果超过 2 小时还是 queued,先 GET 一次;仍然不对,就带任务 ID 和 request_id 找支持。
密钥怎么创建、撤销?能建几个?
在 LokoSpace 客户端「个人中心 → API 接入」创建。对应管理接口在 /api/api-keys,但密钥本身不能管理密钥,管理密钥要用登录态。
| 项目 | 规则 |
|---|---|
| 最多未撤销密钥 | 10 个 |
| 有效期 | 创建后 365 天 |
| 完整明文 | 只在创建时返回一次,之后只存哈希和前缀 |
| 撤销 | 立即失效,不能恢复 |
| 密钥权限 | 与账号共享余额、模型权限和企业上下文,不是独立子账号 |
泄露后先撤销,再重建。撤销不会退回已经产生的费用。
能不能直接用现成 SDK?
可以。文本入口兼容 Chat Completions 协议。用现成 SDK 时,把两个配置项改掉:
| SDK 配置 | 填什么 |
|---|---|
base_url | https://sheverai.com/8811c8/api/llm/v1 |
api_key | 你的 sk-loko- 密钥 |
模型名用 GET /models 返回的 id。流式用标准的 stream: true。图片、视频、音频不走 Chat Completions,要用各自的接口。
网关也提供 Messages 协议入口 POST /messages。有些 SDK 会自动在 base 后面拼 /v1,如果你的 base 已经带了 /v1,就会拼成 /v1/v1/messages。按 SDK 的实际拼接规则把 base 调到不重复的层级,不要同时改 base 和路径。
目前用兼容 Chat Completions 的 SDK 即可,不需要 LokoSpace 专属 SDK。先用 curl 打通,再接 SDK,排障会简单很多。
并发为什么上不去?
因为并发不是按你的 API Key 单独分的。模型并发按“渠道 + 模型”全局计数,所有账号共享。
常见原因:
| 现象 | 原因 | 处理 |
|---|---|---|
429 RATE_LIMITED | 入口每小时 120 次或每天 1000 次用完 | 按 Retry-After 退避;确认出口 IP 是否和别的服务共用 |
502 CHANNEL_POOL_BUSY | 模型并发满了,排队超过 90 秒 | 把客户端并发降到 2 到 4,再逐步加 |
502 CHANNEL_POOL_EXHAUSTED | 渠道没有未尝试的可用凭证 | 稍后重试或联系支持 |
| 请求很慢但不报错 | 在排队,不是没受理 | 看总耗时;接近 90 秒就会转成 502 |
模型详情里没有公开的并发数字。max_concurrency 为 null 只表示不额外限制,不代表上游无限容量;单个渠道凭证还有自己的并发上限。
实际调优时,一次只加一点并发,观察 429、CHANNEL_POOL_BUSY 和 P95 延迟。不要直接把客户端并发开到几十。
失败会不会退款?
文本和音频文件转写是后结算,失败通常不发生扣款,所以不是“退款”,而是“没有结算”。图片和视频是先扣费再调用,失败会全额退回。实时语音按会话分段预扣,结束时多退少补。
| 场景 | 结果 |
|---|---|
| 402 余额不足 | 不扣费,不调上游 |
| 400、401、403、404 | 不扣费 |
| 文本在上游返回内容前失败 | 不扣费 |
| 文本流式已输出后中断 | 暂不结算,进入账单待核对;不会重复扣费 |
| 图片失败或超时 | 全额退款,按蓝/黄积分原路退回 |
| 视频提交失败、生成失败或超时 | 全额退款 |
| 音频转写失败 | 不扣费 |
| 相同幂等键重复提交 | 不重复扣费 |
图片 n > 1 是整笔成功或整笔退款,不会只退失败的那几张。b64_json 结果不缓存,同一幂等键完成后重试会返回 409 MEDIA_RESULT_NOT_CACHED,不会再次扣费,但需要换新幂等键才能重新生成。
余额在哪里看?
三个地方:
- 客户端「个人中心 → 积分」,能看余额和流水。
- 登录态调用
GET /api/credits/balance,返回蓝积分、黄积分、冻结积分等字段。 - 正常扣费的响应里,
lokospace_billing.balanceAfter是本次扣费后的余额;幂等重放时可能为null。
可用积分按 蓝积分 + 黄积分 - 冻结黄积分 计算。充值比例是 1 元 = 100 积分。
如果你用 sk-loko- 密钥调 API,余额接口不适用。用登录态查,或者直接看每次响应里的 balanceAfter。