为什么先 curl,再上客户端
“OpenAI 兼容”只说明端点提供 /v1/chat/completions 这类路径——2026-10-07 核验,4Router 与 PackyAPI 的官方端点声明都含 openai /v1/chat/completions——但它不代表模型清单、鉴权头类型、计费口径与你假设一致。客户端报错时你分不清是工具问题还是服务问题;先用最小请求把变量降到三个,之后再接 Cline、Cherry Studio 或 Dify,出问题就能按层定位。
最小验证请求
返回 200 时重点看 usage:这是计费的原始凭据,每百万 token 单价去服务商官方价页核对。注意倍率制站点(4Router、PackyAPI 公开的都是 model_ratio/group_ratio 乘数)的倍率不是单价——结算式核明前不能直接换算引用,核对维度与未知项见我们的成本核对指南。
# 1) 交互式读入密钥:read -s 不回显、不进 shell 历史;sk-... 只是占位写法,
# 真实密钥不要写进命令行、shell 配置文件或任何脚本
read -s API_KEY && export API_KEY
# 2) 最小请求(路径以服务商官方文档为准;带连接/总超时防挂起,max_tokens 限制本次输出)
curl -sS --connect-timeout 10 --max-time 60 \
"https://api.example.com/v1/chat/completions" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"MODEL_ID","messages":[{"role":"user","content":"ping"}],"max_tokens":16}'
# 3) 看计费凭据:返回 JSON 里的 usage.prompt_tokens / usage.completion_tokens
# 可接管道提取: | python3 -c "import json,sys;print(json.load(sys.stdin).get('usage'))"常见返回与含义
401:密钥错误或鉴权头格式不符。404:路径不对——BASE_URL 是否要带 /v1、端点前缀是什么,以服务商文档为准,别猜。400 model not found:模型 ID 不在该站点或该分组。429:限流。若站点开放 GET /v1/models,可先拉一次模型清单核对 ID 拼写,再发对话请求。
有些站点按分组限定协议与模型(如 2026-10-07 核验的 PackyAPI:kimi-k2.5 在 kimi-officially 分组仅 anthropic、kimi-k3 在 kimi-sale 仅 openai-response)。同一个模型 ID 在不同分组下行为不同,验证时把你实际用的令牌分组写进记录。
安全边界
密钥只放服务端或本地环境变量。任何进入浏览器 JS、移动端包、公开仓库的密钥都应视为公开——前端代码里的密钥不是“隐藏”,是“广播”。需要从前端调模型时,走自己的后端代理转发,密钥只存在于服务端。
测试用最小额度、可随时吊销的密钥;请求内容默认可能被服务商记录(日志、排错、审计),密钥、客户隐私、未公开数据不进请求体,确需举例先脱敏。
验收条件
(1) 拿到一次含 model 与 usage 的 200 返回;(2) 用 usage tokens × 官方单价估算的本次成本,与服务商后台账单页一致,误差能归因(缓存命中、阶梯、汇率);(3) 换一个不存在的模型 ID 能得到明确的 4xx,而不是静默路由。三条满足,才能把这个端点交给客户端长期使用。