跳转到内容

对话

对话功能根据一段对话生成文本。Sakuranbo AI 有两个对话端点。它们运行相同的模型,计费方式也相同,只是请求和响应的格式不同。

  • POST /v1/chat/completions 兼容 OpenAI Chat Completions API。
  • POST /v1/messages 兼容 Anthropic Messages API。

两个端点都需要通过 Authorization: Bearer 发送 API 密钥。详见认证。POST /v1/messages 还接受 x-api-key 请求头中的密钥,Anthropic SDK 就是把密钥放在这个请求头里。

本页的示例使用 sakuranbo/cherrytext-1.0-flash。如需查找文本模型,请调用 GET /v1/models 并带上 task=chat。详见模型 API。非文本模型会返回 404 和 model_not_found。

你可以使用官方的 OpenAI 和 Anthropic SDK。把 SDK 指向 Sakuranbo AI,并提供你的 Sakuranbo AI API 密钥。OpenAI SDK 需要包含 /v1 的基础 URL。Anthropic SDK 会自己添加 /v1/messages,因此它们的基础 URL 不包含 /v1。

OpenAI SDK(TypeScript):

import OpenAI from "openai";
const apiKey = process.env.SAKURANBO_API_KEY;
if (!apiKey) throw new Error("Set the SAKURANBO_API_KEY environment variable.");
const client = new OpenAI({
baseURL: "https://api.sakuranbo.ai/v1",
apiKey,
});
const completion = await client.chat.completions.create({
model: "sakuranbo/cherrytext-1.0-flash",
messages: [
{
role: "system",
content: "You are a concise assistant."
},
{
role: "user",
content: "Summarize the benefits of prepaid API credits in two lines."
}
],
max_tokens: 2048
});
console.log(completion.choices[0]?.message.content);

OpenAI SDK(Python):

import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.sakuranbo.ai/v1",
api_key=os.environ["SAKURANBO_API_KEY"],
)
completion = client.chat.completions.create(
model="sakuranbo/cherrytext-1.0-flash",
messages=[
{
"role": "system",
"content": "You are a concise assistant.",
},
{
"role": "user",
"content": "Summarize the benefits of prepaid API credits in two lines.",
},
],
max_tokens=2048,
)
print(completion.choices[0].message.content)

Anthropic SDK(TypeScript):

import Anthropic from "@anthropic-ai/sdk";
const apiKey = process.env.SAKURANBO_API_KEY;
if (!apiKey) throw new Error("Set the SAKURANBO_API_KEY environment variable.");
// Pass the key as authToken too, so the SDK does not send ANTHROPIC_AUTH_TOKEN from the environment.
const client = new Anthropic({
baseURL: "https://api.sakuranbo.ai",
apiKey,
authToken: apiKey,
});
const message = await client.messages.create({
model: "sakuranbo/cherrytext-1.0-flash",
max_tokens: 2048,
system: "You are a concise assistant.",
messages: [
{
role: "user",
content: "Summarize the benefits of prepaid API credits in two lines."
}
]
});
console.log(message.content);

Anthropic SDK(Python):

import os
import anthropic
api_key = os.environ["SAKURANBO_API_KEY"]
# Pass the key as auth_token too, so the SDK does not send ANTHROPIC_AUTH_TOKEN from the environment.
client = anthropic.Anthropic(
base_url="https://api.sakuranbo.ai",
api_key=api_key,
auth_token=api_key,
)
message = client.messages.create(
model="sakuranbo/cherrytext-1.0-flash",
max_tokens=2048,
system="You are a concise assistant.",
messages=[
{
"role": "user",
"content": "Summarize the benefits of prepaid API credits in two lines.",
},
],
)
print(message.content)

请从你的服务器调用 API。不要把 API 密钥放进在浏览器中运行的代码里。

POST /v1/chat/completions 接收一个 messages 列表,并返回模型的下一条消息。

终端窗口
curl -X POST "https://api.sakuranbo.ai/v1/chat/completions" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $SAKURANBO_API_KEY" \
-d '{
"model": "sakuranbo/cherrytext-1.0-flash",
"messages": [
{
"role": "system",
"content": "You are a concise assistant."
},
{
"role": "user",
"content": "Summarize the benefits of prepaid API credits in two lines."
}
],
"max_tokens": 2048
}'

生成的消息在 choices[0].message 中,usage 包含 token 数量和费用。详见用量与费用。

名称类型必填默认值约束
modelstring是
messagesobject[]是至少 1 项
max_tokensinteger否
max_completion_tokensinteger否
temperaturenumber否0 至 2
top_pnumber否0 至 1
stopstring | string[]否string[]: 最多 4 项
seedinteger否不小于 1
userstring否最多 512 个字符
toolsobject[]否最多 128 项
tool_choicestring | object否string: 可选值:none, auto, required
response_formatobject否
nnumber否可选值:1
streamboolean否
stream_optionsobject | null否

每个模型都设定自己的参数范围和默认值。下表对应示例模型:

名称类型必填默认值约束说明
messagesobject[]是OpenAI Chat Completions 格式的对话消息。
max_tokensinteger否40961 至 131,072生成 token 数的上限,包含模型用于推理的 token。数值过小可能导致在写出回答之前响应就被截断。余额预留按此值计算。
temperaturenumber否10 至 2采样温度。
streamboolean否false以 Server-Sent Events 流式返回 token。

超出范围的 max_tokens 值会返回 400 和 invalid_request。error.details.minimum 和 error.details.maximum 给出上下限。如果请求同时包含 max_tokens 和 max_completion_tokens,则使用 max_completion_tokens。

支持函数工具(tools 和 tool_choice)和 response_format。工具调用会在 choices[0].message.tool_calls 中返回。

消息只能包含文本。其他类型的内容部分(例如图像)会返回 400,error.param 指向该部分。不在字段表中的参数同样会返回 400,error.param 为该参数的名称。

如果 assistant 消息既没有文本也没有 tool_calls 条目,或者 content 数组为空,会返回 400。输出在推理过程中被截断时,可能返回既没有文本也没有工具调用的响应,请不要把这样的响应加入对话历史,并在重试前调高 max_tokens。

POST /v1/messages 接收 Anthropic Messages API 格式的对话。

终端窗口
curl -X POST "https://api.sakuranbo.ai/v1/messages" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $SAKURANBO_API_KEY" \
-d '{
"model": "sakuranbo/cherrytext-1.0-flash",
"max_tokens": 2048,
"system": "You are a concise assistant.",
"messages": [
{
"role": "user",
"content": "Summarize the benefits of prepaid API credits in two lines."
}
]
}'
名称类型必填默认值约束
modelstring是
messagesobject[]是至少 1 项
systemstring | object[]否
max_tokensinteger是
temperaturenumber否0 至 1
top_pnumber否0 至 1
stop_sequencesstring[]否最多 4 项
streamboolean否
toolsobject[]否最多 128 项
tool_choiceobject否

以下几点与 OpenAI 格式不同:

  • max_tokens 为必填。
  • system 是顶层字段。角色为 system 的消息会返回 400。
  • temperature 的可接受范围遵循 Anthropic API,因此与 POST /v1/chat/completions 的范围不同。
  • 不需要 anthropic-version 请求头。如果 SDK 发送了它,服务器会忽略。
  • 消息只能包含文本和工具块。image 块会返回 400。不在字段表中的参数(例如 top_k 或 thinking)同样会返回 400。
  • assistant 消息需要非空字符串的 content,或包含 text 或 tool_use 块的 content 数组。输出在推理过程中被截断时,响应的 content 可能是空数组,把它加入对话历史会返回 400,请调高 max_tokens 后重新发送请求。
  • 所有错误响应体都采用 Anthropic 的格式:type 为 error,详细信息在 error 中,request_id 是顶层字段。这包括 401、404 和 405。

把 stream 设为 true,即可以服务器发送事件的形式接收响应。模型一生成首个 token,就会立即发送给你。

终端窗口
curl -N -X POST "https://api.sakuranbo.ai/v1/chat/completions" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $SAKURANBO_API_KEY" \
-d '{
"model": "sakuranbo/cherrytext-1.0-flash",
"messages": [
{
"role": "system",
"content": "You are a concise assistant."
},
{
"role": "user",
"content": "Summarize the benefits of prepaid API credits in two lines."
}
],
"max_tokens": 2048,
"stream": true,
"stream_options": {
"include_usage": true
}
}'

在 OpenAI 格式中,每个事件是一行 data:,内容为 chat.completion.chunk 对象,choices[].delta 携带新增的文本。流以 data: [DONE] 结束。包含费用的 usage 对象会出现在最后一个 choices 数组为空的数据块中,并且仅当你把 stream_options.include_usage 设为 true 时才会出现。

在 Anthropic 格式中,每个事件有一行 event: 和一行 data:。事件按以下顺序出现:

  1. message_start
  2. 对于每个内容块:content_block_start、一个或多个 content_block_delta 事件,以及 content_block_stop
  3. message_delta,其中有 stop_reason 和 usage(包含费用)
  4. message_stop

Anthropic SDK 只会根据它们已知的字段构建最终消息,因此其中没有 usage.cost。如需读取费用,请读取 message_delta 事件中的 usage。

流开始之前的失败(例如认证或校验错误)会返回带有对应 HTTP 状态码的普通 JSON 错误。流开始之后的失败无法再改变状态码,状态码仍为 200。在 OpenAI 格式中,流会发送一行带有 error 对象的 data:,然后发送 data: [DONE]。在 Anthropic 格式中,流会发送 event: error 事件,且不会再发送 message_stop。

非流式响应在两处报告费用,并在 usage 中给出 token 数量:

  • usage.cost 以 amount_micro_usd 给出 micro USD 金额,并以 amount_usd 给出十进制字符串形式的金额。
  • X-Usage-Cost-Usd 响应头包含同样的 USD 字符串。
  • usage 包含 token 数量。在 OpenAI 格式中是 prompt_tokens、completion_tokens、total_tokens 和 prompt_tokens_details.cached_tokens。在 Anthropic 格式中是 input_tokens、output_tokens 和 cache_read_input_tokens。input_tokens 不包含缓存的 token。

流式响应没有 X-Usage-Cost-Usd 响应头。请改为从最后一个 usage 对象读取费用。

请求运行之前,Sakuranbo AI 会从你的余额中预留一笔金额。它根据输入的大小和 max_tokens 预估这笔金额。请求结束时,会按真实的 token 数量计算费用,其余的预留回到你的余额。在模型一侧失败且尚未生成任何输出的请求不会计费。

  • 由于预留使用 max_tokens,即使请求的真实费用在你的余额之内,它也可能被以 402 拒绝。请把 max_tokens 设为你需要的长度。
  • 如果流在模型开始生成输出之后中断,即使流以错误结束,该请求也会计费。输出包括推理输出,无论是否已送达你都会计费。Anthropic 格式不返回推理输出,因此即使你没有收到任何文本,请求也可能计费。如果最终的 token 数量没有到达,费用会按预估值计算。输入按预留时使用的上限计算,输出按已经生成的输出(包括推理输出和工具调用)的大小计算,因此费用可能高于真实用量,但绝不会超过预留的金额。
  • 如果你在流结束之前关闭连接,请求仍会运行到结束,你需要为生成的全部输出付费。
  • 对话请求不使用 Idempotency-Key。重试的请求是一个新请求,会再次计费。

价格请查看模型目录中的模型页面和定价页面,也可以在运行请求之前用 POST /v1/estimate 计算价格。详见费用预估 API。如需读取余额,请参阅余额与 API 密钥限额。

代码HTTP 状态码类型说明
invalid_request400invalid_request_error请求格式有误或取值超出范围。如果有效取值已知,会列在 details.allowed 中。
unauthorized401authentication_errorAPI 密钥缺失、格式有误、未知、已被吊销或已过期。响应不会说明属于哪一种情况。
balance_insufficient402insufficient_balance可用余额低于该请求需要预留的金额。error.details.limit_source 为 balance。
key_limit_exceeded402insufficient_balance该请求会使 API 密钥超出其支出上限。error.details.limit_source 为 key,error.details.resets_at 说明计数器何时重新开始。
account_suspended403permission_error账户已被停用,图像、视频和对话请求会被拒绝。请联系支持团队。余额、充值、API 密钥和任务仍可使用。
model_not_found404not_found_error目录中不存在该模型 ID。对于不是文本模型的模型,对话端点也会返回此代码。
payload_too_large413invalid_request_error请求体超过了允许的大小。error.details.max_bytes 为大小上限。
rate_limited429rate_limit_error模型提供方正在限制请求。同一地址提交的举报过多时,POST /v1/reports 也会返回该错误代码。请在 Retry-After 响应头给出的时间之后重试。
upstream_error502upstream_error上游提供方返回了错误。
upstream_unavailable503overloaded_error上游提供方暂时容量不足,请稍后重试。

POST /v1/messages 以 Anthropic 的错误格式返回相同的错误代码和 HTTP 状态码。它的 error.type 遵循 Anthropic API,因此可能与“类型”列不同。balance_insufficient 和 key_limit_exceeded 是 billing_error,payload_too_large 是 request_too_large,content_policy_violation 是 invalid_request_error,upstream_error 是 api_error。请根据 error.code 而不是 error.type 判断分支。

对于 429 或 503 响应,请等待 Retry-After 响应头给出的秒数再重试。402 响应带有 error.details.limit_source,其值为 balance 或 key。详见余额与 API 密钥限额。完整的错误代码列表请参阅错误。