接入指南
把任意兼容 OpenAI 接口的客户端指向 https://api.yinchu.net/v1,带上你的 API 密钥即可。 下面每一节都是同一个接口,只是换了不同的客户端。
Claude Code
写进 ~/.claude/settings.json,然后运行 claude:
{
"env": {
"ANTHROPIC_BASE_URL": "https://api.yinchu.net",
"ANTHROPIC_AUTH_TOKEN": "$ENGY_API_KEY",
"ANTHROPIC_MODEL": "glm-5.2",
"ANTHROPIC_DEFAULT_HAIKU_MODEL": "glm-5.2"
}
}URL 后面不要加 /v1;haiku 那一项也要一并设上。
OpenAI API
curl https://api.yinchu.net/v1/chat/completions \
-H "Authorization: Bearer $ENGY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"glm-5.2","messages":[{"role":"user","content":"hello"}]}'from openai import OpenAI
client = OpenAI(base_url="https://api.yinchu.net/v1", api_key="$ENGY_API_KEY")
client.chat.completions.create(model="glm-5.2",
messages=[{"role":"user","content":"hello"}])Cursor
Cursor Settings → Models → API Keys,在 OpenAI API Key 一栏:
OpenAI API Key $ENGY_API_KEY Override OpenAI Base URL https://api.yinchu.net/v1 ← 打开这个开关,然后点 Verify
再到 Models 里 + Add model → miaotui/glm-5.2,启用它,然后在对话框里选中。
Cursor 必须带斜杠。它要求自定义模型写成 厂商/模型 的形式,所以本页 其它地方用的裸 glm-5.2 恰恰是它唯一不接受的写法。加上 miaotui/ 前缀之后,模型列表里的任何 id 都能用。同一个模型、同样的价格; 返回结果里会原样回显你发过来的写法,斜杠后面的 id 仍然必须完全一致。
自定义接入点只作用于 chat / plan 面板;Tab 补全和 Composer 仍然走 Cursor 自己的模型。 请求由 Cursor 的服务器中转,所以在任何机器上都能用。需要 Cursor 付费版:免费版下 任何自定义模型都会显示「Named models unavailable」(免费版只有 Auto,这是 Cursor 的 限制,与本接口无关)。
Codex
写进 ~/.codex/config.toml,然后 export ENGY_API_KEY=… 并运行 codex:
model = "glm-5.2" model_provider = "miaotui" [model_providers.miaotui] name = "miaotui" base_url = "https://api.yinchu.net/v1" env_key = "ENGY_API_KEY" wire_api = "responses"
Hermes
写进 ~/.hermes/config.yaml,然后运行 hermes chat:
model: provider: "custom" default: "glm-5.2" base_url: "https://api.yinchu.net/v1" api_key: "$ENGY_API_KEY"
推理强度
用 OpenAI 的 reasoning_effort 或 OpenRouter 的 reasoning 对象 控制模型思考多久。两种写法在 /v1/chat/completions 上都能用,你也不需要 知道某个模型偏好哪一种。
curl https://api.yinchu.net/v1/chat/completions \
-H "Authorization: Bearer $ENGY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"glm-5.2",
"reasoning_effort":"high",
"messages":[{"role":"user","content":"证明 2 的平方根是无理数。"}]}'OpenRouter 的写法等价:"reasoning": {"effort": "high"}。
档位
接受的取值,从低到高:none、minimal、low、 medium、high、xhigh、max。 none 和 minimal 都表示「不要思考」。
各模型实际收到什么
这一节是真正值得知道的部分:每个模型的 chat template 各说各的方言,同一个词在不同 模型那里含义并不相同。秒推 会把你给的档位翻译成目标模型真正听得懂的值,而不是原样 透传、让 template 自己去猜。比如把 high 直接发给 Qwen3.8,它的 template 会返回 400 —— 秒推 会替你映射成 xhigh。
| 你发送 | GLM | Qwen3.8 | DeepSeek V4 |
|---|---|---|---|
| low | high | low | low |
| medium | high | medium | low |
| high | high | xhigh | high |
| xhigh | max | xhigh | max |
| max | max | xhigh | max |
有两个后果需要提前考虑。GLM 把 low / medium / high 折叠成同一档,所以在 xhigh 以下你实际上只有两个选择。Qwen3.8 的上限就是 xhigh, 而那也是它的默认值,所以对它发 max 不会多要到任何东西。秒推 不认识的 模型走 GLM 的映射。
关闭思考
"reasoning_effort":"none"(或 "minimal",或 "reasoning":{"enabled":false})会去掉 effort 提示,并设置 chat_template_kwargs.enable_thinking = false,这里的每个模型都认这个开关。 如果你自己显式设了 enable_thinking,以你的值为准 —— 秒推 绝不覆盖显式设置。
图片输入
视觉模型通过标准的 OpenAI image_url content part 接收图片,所以任何 已经支持多模态对话的客户端都不用改就能用。哪些模型接受图片是**实时**的集群状态, 不是一张固定名单:定价表里有一列 模态, https://api.yinchu.net/v1/models 也会以 input_modalities 字段报告同样的 信息。给纯文本模型发图片,会在请求被分发之前就返回 400,并指明它不支持 的那种模态。
发送图片
IMG="data:image/png;base64,$(base64 -w0 photo.png)" # macOS: base64 -i photo.png
curl https://api.yinchu.net/v1/chat/completions \
-H "Authorization: Bearer $ENGY_API_KEY" \
-H "Content-Type: application/json" \
-d @- <<JSON
{"model": "kimi-k3",
"messages": [{"role": "user", "content": [
{"type": "text", "text": "这张图里是什么?"},
{"type": "image_url", "image_url": {"url": "$IMG"}}]}]}
JSON文本和图片可以在同一轮里任意混排,也可以跨轮 —— 在 content 列表里放多少个 image_url 都行,不超过下面的限制即可。输出永远是文本。
只能内联,不能给链接
图片必须是 base64 的 data: URI。http(s) URL 会被直接以 400 拒绝,而不是由服务端去抓取。这是刻意的:网关把媒体内联下发给算力 节点,而算力节点跑在出网受限的 GPU 集群上,本来就访问不到大部分公网。再者,代买家 抓取任意 URL 会让整个集群变成一个 SSRF 工具。在边缘给一个明确的错误,好过让节点那边 出一个莫名其妙的故障,所以请你自己把图片下载下来内联进去。
限制
| 限制 | 取值 | 超了会 |
|---|---|---|
| 每个请求的媒体总量 | 解码后 12 MB,所有 part 累加 | 413 |
| 每个请求的媒体 part 数 | 16 | 413 |
| 视频 | 不支持 | 400 |
额度算的是解码后的字节数,所以 base64 编码后大出约三分之一仍然放得下。这个 值定得远低于算力节点控制通道的单帧上限:否则一个超大请求会顺带把那条同时承载心跳的 连接一起打断。
计费上,每个图片 part 会先预留约 1000 个输入 token —— 一张中等尺寸图片的编码器开销。 它只影响预扣的额度;最终结算按模型实际报告的 token 数。
Anthropic 风格的 block
在 Anthropic 兼容接口上,带 base64 source 的 {"type":"image"} block 会被自动转成 OpenAI 的 part 结构,媒体类型 一并带上。url 形式的 source 原样透传,因此同样受上面「只能 data:」 的约束,那边也要内联。
原始提示词与 logprobs
/v1/completions 接收的是原始提示词而不是消息列表:没有 chat template、 没有 system prompt,也没有推理解析器去改写 <think>,模型看到的就是 你发过去的那串字节。用它可以从半句话中间续写,或者给你提供的文本打分。
续写原始提示词
模型会从你的提示词结束的地方接着写:
curl https://api.yinchu.net/v1/completions \
-H "Authorization: Bearer $ENGY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"glm-5.2",
"prompt":"<|user|>\nProve 2 is irrational.\n<|assistant|>\n<think>\n",
"max_tokens":512,"temperature":0}'给一段文本打分
要读取你自己提供的那段文本的对数概率,发送 logprob_start_len:也就是 这段文本开始处的 token 偏移量。响应里会带 token_logprobs 和 token_ids,每个被打分的 token 一项。单次调用最多打分 1024 个 token(当前默认值),前缀长度不限。prompt 请直接传 token id,这样偏移量就是 你自己算出来的那个;并且永远要带 max_tokens=1:
from openai import OpenAI
client = OpenAI(base_url="https://api.yinchu.net/v1", api_key="$ENGY_API_KEY")
ids = tokenizer.encode(prefix + action) # 你自己的 tokenizer
span = len(tokenizer.encode(action)) # 想要打分的 token 数
r = client.completions.create(model="glm-5.2", prompt=ids,
max_tokens=1, temperature=0,
extra_body={"logprob_start_len": len(ids) - span})
lp = r.choices[0].logprobs
print(sum(x for x in lp.token_logprobs if x is not None))显存开销随你打分的 token 数增长,而不是随提示词长度增长 —— 这正是 「在 2 万 token 的前缀上只给一小段打分」可行的原因。但 prefill 该花的时间还是要花: 在生产环境上,64 token 的片段配 14900 token 的前缀,端到端实测 1.2 秒到 4.2 秒, 取决于后端当时还在服务什么。
1024 这个上限是对被打分的片段而言的,前缀不受限,直到上下文窗口用完 为止。1024 能过,1025 会被 400 拒绝并回报它算出来的长度,所以更长的片段要拆成多次 调用,或者联系我们给你的账户调高上限。只要提示词超过这个上限,就传 token id 而不是 字符串:字符串在边缘不会被真正分词,只按长度估算,所以基于字符串的片段会被拒绝, 而不是拿一个可能差出两倍的数字去打分。
给整条提示词打分
echo 会返回提示词里每一个 token 的对数概率。它背后的 logits 张量随提示词 长度增长,直到放不下为止,所以 echo 同样被限制在 1024 个 token,只不过这里是 对整条提示词而言。超过之后请求会被 400 拒绝并指向 logprob_start_len, 而不是发给一个根本处理不了它的后端:
curl https://api.yinchu.net/v1/completions \
-H "Authorization: Bearer $ENGY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"glm-5.2","prompt":"The capital of France is",
"max_tokens":1,"temperature":0,"echo":true,"logprobs":1}'注意事项
打分调用永远要带 max_tokens=1。不带也能成功,但模型会先按自己的默认值 生成一遍:生产环境上是 8192 个 token、约两分钟,全部按输出计费,换来的是和 1 个 token 的调用在一秒内就能拿到的、完全相同的对数概率。
max_tokens 和 logprobs 只要发送就必须至少为 1:两条路径上 传 0 都会被 400 拒绝。而在 echo 路径上漏掉 logprobs 会返回一个正常的 200、却一个对数概率都没有 —— 这是这里唯一一个「看起来成功了」的失败。
logprob_start_len 是从提示词开头算起的绝对偏移量, 所以要给最后 n 个 token 打分,应该发 prompt_tokens - n 而不是 n。发反了会得到一个 400 并附上它算出来的片段长度,通常足够看出问题在哪。
这条路径上 text_offset 返回时是空的,请改用返回的 token_ids 来对齐。
带 max_tokens=1 时,一次打分调用就是 prefill 加一个 token,所以基本按 输入计费。对数概率只有在落到同一个后端的调用之间才具备可比性,所以如果一批实验的 数字要互相比较,请先联系我们把你的账户固定到同一个后端。
Agent API
给 Agent 用的只读接口:查余额、查消费与用量、查模型目录。查看 Agent API 文档。