Anthropic 格式
POST /v1/messages 接受 Anthropic Messages 格式的请求,并以相同格式作答,可流式也可非流式。可配合 Anthropic SDK 以及基于它构建的工具(如 Claude Code)使用:设置 base URL,使用你的 Shannon API 密钥,并指定一个 Shannon 模型 id。
POST https://api.shannon-ai.com/v1/messages
将 Anthropic SDK 指向 Shannon 的 base URL。SDK 会添加 /v1/messages,并在 x-api-key 请求头中发送你的密钥。
import anthropic
client = anthropic.Anthropic(
api_key="YOUR_API_KEY",
base_url="https://api.shannon-ai.com",
)
message = client.messages.create(
model="shannon-3",
max_tokens=1024,
messages=[{"role": "user", "content": "Say hello in one sentence."}],
)
for block in message.content:
if block.type == "text":
print(block.text) import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic({
apiKey: "YOUR_API_KEY",
baseURL: "https://api.shannon-ai.com",
});
const message = await client.messages.create({
model: "shannon-3",
max_tokens: 1024,
messages: [{ role: "user", content: "Say hello in one sentence." }],
});
for (const block of message.content) {
if (block.type === "text") console.log(block.text);
} curl https://api.shannon-ai.com/v1/messages \
-H "x-api-key: YOUR_API_KEY" \
-H "content-type: application/json" \
-d '{
"model": "shannon-3",
"max_tokens": 1024,
"messages": [{"role": "user", "content": "Say hello in one sentence."}]
}' 回复是一条消息,其 content 是块的列表。请按 type 查找块:模型进行了推理时,第一个块是 thinking,文本在其后。
{
"id": "msg_5f0c1e7a9b3d4c62a8e1f07d2b46c9a3",
"type": "message",
"role": "assistant",
"model": "shannon-3",
"content": [
{
"type": "thinking",
"thinking": "The user wants a greeting in one sentence. Keep it short and friendly."
},
{
"type": "text",
"text": "Hello, it is good to meet you."
}
],
"stop_reason": "end_turn",
"usage": {
"input_tokens": 1184,
"output_tokens": 46
}
} 请求头
| 请求头 | 值 | 说明 |
|---|---|---|
x-api-key | YOUR_API_KEY | 你的 API 密钥。也可以用 Authorization: Bearer YOUR_API_KEY 代替。 |
content-type | application/json | 必填。 |
anthropic-version | 2023-06-01 | 接受,非必需。Anthropic SDK 会发送 2023-06-01;无论取何值,回复格式都相同。 |
anthropic-beta | 接受,非必需。 | |
x-request-id | 可选。你自己的请求 id。它会原样出现在回复中;若不提供,回复会带一个 12 位十六进制字符的 id。 |
请求字段
只有 messages 是必需的。适用模型 一列列出了字段会改变回复的模型。托管开源权重模型即模型列表中的十二个 id;Shannon 3 系列为 shannon-3、shannon-3-pro、shannon-3.1 和 shannon-3.1-pro。 模型与定价
| 字段 | 类型 | 默认值 | 说明 | 适用模型 |
|---|---|---|---|---|
model | string | shannon-1.6-lite | 模型列表中的 Shannon 模型 id。每个请求都要发送。匹配不区分大小写。任何其他名称都会返回 400 unknown model,因此发送自己模型名称的工具必须改为 Shannon id。 | 所有模型 |
messages | array | 必填。 对话内容,按从旧到新排列,角色为 user 和 assistant。参见下文的消息与内容块。 | 所有模型 | |
system | string | array | 给模型的指令:字符串,或文本块数组。参见下文的系统提示词。 | 托管开源权重模型、shannon-1.6-*、shannon-2-*、shannon-coder-1 | |
max_tokens | integer | 4096 | 回复的上限,以 tokens 计。在此端点上可选;Anthropic SDK 始终会发送它。1 至 65,536 范围之外的值会被调整到该范围内。它同时也是请求运行期间从你的余额中预留的数量。 | 托管开源权重模型、shannon-1.6-lite、shannon-1.6-pro、shannon-coder-1 |
stream | boolean | false | true 会以 server-sent events 形式发送回复。参见下文的流式传输。 | 所有模型 |
temperature | number | 采样温度。在托管开源权重模型上,取值保持在 0 到 2 之间。 | 托管开源权重模型、shannon-1.6-lite、shannon-1.6-pro、shannon-coder-1 | |
top_p | number | 核采样。 | 托管开源权重模型 | |
stop_sequences | array | 最多 4 个字符串。答案会在第一个出现的字符串之前结束。stop_reason 仍为 end_turn。 | 托管开源权重模型 | |
tools | array | 模型可以调用的工具,每个工具形如 {"name", "description", "input_schema"}。参见下文的工具。 | 所有模型 | |
tool_choice | object | {"type": "auto"} 由模型决定,{"type": "any"} 强制其调用某个工具,{"type": "tool", "name": "…"} 强制其调用指定工具。 | 托管开源权重模型 | |
thinking | object | 模型回答前的推理量。参见下文的思考。 | 托管开源权重模型 | |
web_search | boolean | false | Shannon 对该格式的扩展:true 让模型在回答前先搜索网页。 | shannon-1.6-*、shannon-2-*、Shannon 3 系列 |
未提供 max_tokens 时,值为 4,096;在 shannon-coder-1 上为 65,536。
块上的 metadata、top_k、service_tier 和 cache_control 标记会被接受,以便现有客户端代码无需修改即可运行。它们不会改变回复;托管开源权重模型上的 prompt 缓存是自动的。
要获得符合 schema 的 JSON 答案,在 Chat Completions 上使用 response_format,在 Responses 上使用 text.format。 结构化输出
带系统提示词和思考的请求
此请求发送了系统提示词、思考预算、温度和一个停止序列。它使用托管开源权重模型,这些参数都会生效。
import anthropic
client = anthropic.Anthropic(
api_key="YOUR_API_KEY",
base_url="https://api.shannon-ai.com",
)
message = client.messages.create(
model="DeepSeek-V4-Flash-0731-W4A16-AUTOROUND-REAP",
max_tokens=4096,
system="You are a physics teacher. Answer in two sentences.",
thinking={"type": "enabled", "budget_tokens": 2048},
temperature=0.3,
stop_sequences=["\n\n"],
messages=[{"role": "user", "content": "Why is the sky blue?"}],
)
for block in message.content:
if block.type == "thinking":
print("reasoning:", block.thinking)
elif block.type == "text":
print("answer:", block.text)
print(message.usage) import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic({
apiKey: "YOUR_API_KEY",
baseURL: "https://api.shannon-ai.com",
});
const message = await client.messages.create({
model: "DeepSeek-V4-Flash-0731-W4A16-AUTOROUND-REAP",
max_tokens: 4096,
system: "You are a physics teacher. Answer in two sentences.",
thinking: { type: "enabled", budget_tokens: 2048 },
temperature: 0.3,
stop_sequences: ["\n\n"],
messages: [{ role: "user", content: "Why is the sky blue?" }],
});
for (const block of message.content) {
if (block.type === "thinking") console.log("reasoning:", block.thinking);
if (block.type === "text") console.log("answer:", block.text);
}
console.log(message.usage); curl https://api.shannon-ai.com/v1/messages \
-H "x-api-key: YOUR_API_KEY" \
-H "content-type: application/json" \
-d '{
"model": "DeepSeek-V4-Flash-0731-W4A16-AUTOROUND-REAP",
"max_tokens": 4096,
"system": "You are a physics teacher. Answer in two sentences.",
"thinking": {"type": "enabled", "budget_tokens": 2048},
"temperature": 0.3,
"stop_sequences": ["\n\n"],
"messages": [{"role": "user", "content": "Why is the sky blue?"}]
}' 在托管开源权重模型上,usage 会把从 prompt 缓存读取的 tokens 与其他输入 tokens 分开报告。
{
"usage": {
"input_tokens": 31,
"cache_read_input_tokens": 0,
"cache_creation_input_tokens": 0,
"output_tokens": 62
}
} 系统提示词
system 是字符串,或形如 [{"type": "text", "text": "…"}] 的文本块数组。各块的文本以换行符连接。
托管开源权重模型、shannon-1.6-lite、shannon-1.6-pro、shannon-2-lite、shannon-2-pro 和 shannon-coder-1 会应用它。使用 Shannon 3 系列 id 时,请把必须遵守的指令放进用户消息。
消息与内容块
每条消息包含 role(user 或 assistant)和 content。content 是字符串,或由块组成的数组。
| 块 | 说明 | 可用于 |
|---|---|---|
{"type": "text", "text": "…"} | 文本。 | 所有模型 |
{"type": "image", "source": {"type": "base64", "media_type": "image/png", "data": "…"}}{"type": "image", "source": {"type": "url", "url": "…"}} | user 消息中的图片,以 base64 或 URL 形式提供。 | Shannon 3 系列、shannon-1.6-lite、shannon-1.6-pro,以及列出图片输入的托管开源权重模型 |
{"type": "document", "source": {"type": "base64", "media_type": "application/pdf", "data": "…"}} | user 消息中的文档(PDF、Word、PowerPoint 或 Excel),以 base64 或 URL 形式提供。 | Shannon 3 系列 |
{"type": "tool_use", "id": "toolu_…", "name": "…", "input": {…}} | 位于 assistant 消息中:模型在先前回复中发起的工具调用。 | 所有模型 |
{"type": "tool_result", "tool_use_id": "toolu_…", "content": "…"} | 位于 user 消息中:该调用的结果。content 是字符串,或文本块列表。 | 所有模型 |
你可以把先前回复的 content 原样发回:text 和 tool_use 块会被读取,thinking 块会被跳过。
在 Shannon 档位上,图片和文档从最后一条 user 消息中读取。大小和限制另有专页说明。 图片与文件
思考
托管开源权重模型会把 thinking 映射为推理强度。不带该字段时,强度为高。
| 形式 | budget_tokens | 效果 |
|---|---|---|
{"type": "disabled"} | 不推理。回复中没有 thinking 块。 | |
{"type": "enabled", "budget_tokens": 2048} | ≤ 2,048 | 低强度。 |
{"type": "enabled", "budget_tokens": 8192} | ≤ 8,192 | 中等强度。 |
{"type": "enabled", "budget_tokens": 16000} | > 8,192 | 高强度。 |
会推理的模型会把推理内容以 {"type": "thinking", "thinking": "…"} 块的形式返回,位于文本之前。会推理的 Shannon 档位同样会发送。
各档强度在专页中说明。 推理强度
工具
工具是由你的代码运行的函数。用 name、description 和 input_schema 描述每个工具。当模型需要工具时,回复包含 tool_use 块,且 stop_reason 为 tool_use。
tools 中的工具定义:
[
{
"name": "get_weather",
"description": "Current weather for a city.",
"input_schema": {
"type": "object",
"properties": {
"city": {
"type": "string"
}
},
"required": [
"city"
]
}
}
] 调用该工具的回复的 content:
[
{
"type": "text",
"text": ""
},
{
"type": "tool_use",
"id": "toolu_3d9a7c1e5b2f4a60c8e1d7f09b24a6c5",
"name": "get_weather",
"input": {
"city": "Paris"
}
}
] 运行工具,然后再次发送请求,并在 messages 中加入该调用和一个 tool_result 块:
[
{
"role": "user",
"content": "What is the weather in Paris?"
},
{
"role": "assistant",
"content": [
{
"type": "tool_use",
"id": "toolu_3d9a7c1e5b2f4a60c8e1d7f09b24a6c5",
"name": "get_weather",
"input": {
"city": "Paris"
}
}
]
},
{
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": "toolu_3d9a7c1e5b2f4a60c8e1d7f09b24a6c5",
"content": "{\"temperature_c\": 18, \"sky\": \"cloudy\"}"
}
]
}
] tool_choice
| 形式 | 效果 | 适用模型 |
|---|---|---|
{"type": "auto"} | 由模型决定是否调用工具。这是默认值。 | 所有模型 |
{"type": "any"} | 模型必须调用其中一个工具。 | 托管开源权重模型 |
{"type": "tool", "name": "…"} | 模型必须调用指定名称的工具。 | 托管开源权重模型 |
只有带 input_schema 的工具才会被读取。在此端点上,网页搜索不是工具:请设置 web_search 字段。
工具循环在专页中有完整说明。 函数调用
回复
| 字段 | 类型 | 说明 | 发送方 |
|---|---|---|---|
id | string | msg_ 后接 32 位十六进制字符。 | 所有模型 |
type | string | 始终为 message。 | 所有模型 |
role | string | 始终为 assistant。 | 所有模型 |
model | string | 作答模型的规范 id。 | 所有模型 |
content | array | 回复的各个块,按此顺序排列:模型进行了推理时先是 thinking,然后是 text,之后每个工具调用对应一个 tool_use。 | 所有模型 |
stop_reason | string | 回复结束的原因。见下方的取值。 | 所有模型 |
usage | object | input_tokens 和 output_tokens。 | 所有模型 |
sources | array | 仅出现在带 web_search: true 且搜索找到了结果的请求中:交给模型的结果,每条包含 index、title 和 url。答案中的 [1] 就是 index 为 1 的条目。在流式输出中,它随 message_delta 事件到达。 | shannon-1.6-*、shannon-2-*、Shannon 3 系列 |
usage.cache_read_input_tokens | integer | cache_read_input_tokens 是 prompt 中从缓存读取的部分;input_tokens 是其余部分。cache_creation_input_tokens 始终为 0。 | 托管开源权重模型 |
回复块
| 块 | 说明 |
|---|---|
{"type": "thinking", "thinking": "…"} | 模型的推理过程。没有 signature 成员。 |
{"type": "text", "text": "…"} | 答案文本。当回复是工具调用时,它可能为空。 |
{"type": "tool_use", "id": "toolu_…", "name": "…", "input": {…}} | 工具调用。input 是 JSON 对象。请用相同的 id 把结果发回。 |
stop_reason
| stop_reason | 说明 | 发送方 |
|---|---|---|
end_turn | 模型完成了回答,或出现了你的某个 stop_sequences。 | 所有模型 |
tool_use | 回复包含一个或多个工具调用。 | 所有模型 |
max_tokens | 回复在输出上限处被截断。 | Shannon 3 系列、shannon-1.6-lite、shannon-1.6-pro、shannon-coder-1,仅限流式传输 |
流式传输
将 stream 设为 true 即可使用 server-sent events。每个帧包含一行带事件名称的 event:,以及一行带 JSON 对象的 data:,该对象在 type 中重复事件名称。Anthropic SDK 的流式辅助工具会替你读取这些事件:
import anthropic
client = anthropic.Anthropic(
api_key="YOUR_API_KEY",
base_url="https://api.shannon-ai.com",
)
with client.messages.stream(
model="shannon-3",
max_tokens=1024,
messages=[{"role": "user", "content": "Explain server-sent events in three sentences."}],
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)
message = stream.get_final_message()
print()
print(message.stop_reason, message.usage) import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic({
apiKey: "YOUR_API_KEY",
baseURL: "https://api.shannon-ai.com",
});
const stream = client.messages.stream({
model: "shannon-3",
max_tokens: 1024,
messages: [{ role: "user", content: "Explain server-sent events in three sentences." }],
});
stream.on("text", (text) => process.stdout.write(text));
const message = await stream.finalMessage();
console.log("\n", message.stop_reason, message.usage); curl -N https://api.shannon-ai.com/v1/messages \
-H "x-api-key: YOUR_API_KEY" \
-H "content-type: application/json" \
-d '{
"model": "shannon-3",
"max_tokens": 1024,
"stream": true,
"messages": [{"role": "user", "content": "Explain server-sent events in three sentences."}]
}' 事件按到达顺序如下:
| 事件 | 数据 | 时机 |
|---|---|---|
message_start | message | 始终最先到来。message 包含 id、角色、模型、空的 content,以及从零开始的 usage。 |
content_block_start | index, content_block | 一个块打开。content_block 是空的 text 或 thinking 块,或是带有 id 和 name 的 tool_use 块。 |
content_block_delta | index, delta {"type": "thinking_delta", "thinking"} | 对于 thinking 块:推理的一段。 |
content_block_delta | index, delta {"type": "text_delta", "text"} | 对于 text 块:答案的一段。 |
content_block_delta | index, delta {"type": "input_json_delta", "partial_json"} | 对于 tool_use 块:工具调用的参数,在一个 delta 中完整给出。 |
content_block_stop | index | 此 index 对应的块已完成。 |
message_delta | delta {stop_reason, stop_sequence}, usage | 回复的结尾:delta.stop_reason 以及该请求的 usage。 |
message_stop | 始终最后到来。 |
块按打开的顺序以 index 编号,且前一个块完成后下一个块才会打开。请按类型而不是编号来读取每个块:流可能先打开一个空的 text 块,再打开 thinking 块,并在之后的 text 块中送出答案。
event: message_start
data: {"type":"message_start","message":{"id":"msg_5f0c…","type":"message","role":"assistant","model":"shannon-3","content":[],"usage":{"input_tokens":0,"output_tokens":0}}}
event: content_block_start
data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}}
event: content_block_stop
data: {"type":"content_block_stop","index":0}
event: content_block_start
data: {"type":"content_block_start","index":1,"content_block":{"type":"thinking","thinking":""}}
event: content_block_delta
data: {"type":"content_block_delta","index":1,"delta":{"type":"thinking_delta","thinking":"Three sentences: what it is, how it is framed, why it is used."}}
event: ping
data: {"type": "ping"}
event: content_block_stop
data: {"type":"content_block_stop","index":1}
event: content_block_start
data: {"type":"content_block_start","index":2,"content_block":{"type":"text","text":""}}
event: content_block_delta
data: {"type":"content_block_delta","index":2,"delta":{"type":"text_delta","text":"Server-sent events let a server push text over one HTTP reply."}}
event: content_block_stop
data: {"type":"content_block_stop","index":2}
event: message_delta
data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"input_tokens":1190,"output_tokens":84}}
event: message_stop
data: {"type":"message_stop"} 保活
| 发送方 | 说明 |
|---|---|
Shannon 3 系列、shannon-1.6-lite、shannon-1.6-pro、shannon-coder-1 | ping 事件,数据为 {"type": "ping"},每 15 秒一次。 |
| 托管开源权重模型 | 注释行 : keepalive,模型工作期间每 15 秒一次。 |
失败的流
流开始后的失败会以 error 事件给出,其响应体与错误回复相同:{"type": "error", "error": {"type", "message"}}。结束事件 message_delta 和 message_stop 仍会随后到来。请将该回复视为失败,并重新发送请求。
错误
错误使用 Anthropic 错误响应体:type 为 error,error 对象包含 type 和 message。下表列出此端点最常返回的错误。完整列表及重试建议见专页。 错误处理
{
"type": "error",
"error": {
"type": "invalid_request_error",
"message": "unknown model: no-such-model"
}
} | 状态 | 类型 | 消息 | 时机 |
|---|---|---|---|
401 | authentication_error | Missing authenticationInvalid API key | 未发送 API 密钥,或密钥未知或已被撤销。 |
400 | invalid_request_error | unknown model: <id> | model 不是 Shannon 模型 id。 |
400 | invalid_request_error | No user message provided | Shannon 档位:请求既没有用户文本,也没有 tools。 |
400 | invalid_request_error | <id> does not accept image input | 向不支持图片输入的托管开源权重模型发送了图片。 |
422 | invalid_request_error | Failed to deserialize the JSON body into the target type: … | 缺少 messages,或某个字段的 JSON 类型有误。 |
429 | rate_limit_error | Quota exceeded. Upgrade your plan at shannon-ai.com/plan | max_tokens 大于你余额的剩余量。 |
429 | rate_limit_error | Too many requests. Retry in <n>s. | 限流保护:你的账户在一分钟内发送了超过 120 个请求。 |
429 | rate_limit_error | Shannon Coder call quota reached. Upgrade your plan at shannon-ai.com/plan | shannon-coder-1:你的计划在当前 4 小时窗口内的 Shannon Coder 调用次数已用完。 |
500 | server_error | The model backend failed to answer. Please retry. | 模型未生成回复。请重新发送请求。 |
502 | api_error | The model backend failed to answer. Please retry. | 模型未生成回复。请重新发送请求。 |
计算 tokens
POST /v1/messages/count_tokens 接受与消息请求相同的请求体(model、system、messages、tools),并返回 {"input_tokens": n}:即该请求将被计费的输入 tokens 数。它适用于托管开源权重模型,免费,且不计入限流保护。
import anthropic
client = anthropic.Anthropic(
api_key="YOUR_API_KEY",
base_url="https://api.shannon-ai.com",
)
count = client.messages.count_tokens(
model="DeepSeek-V4-Flash-0731-W4A16-AUTOROUND-REAP",
system="You are a physics teacher. Answer in two sentences.",
messages=[{"role": "user", "content": "Why is the sky blue?"}],
)
print(count.input_tokens) import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic({
apiKey: "YOUR_API_KEY",
baseURL: "https://api.shannon-ai.com",
});
const count = await client.messages.countTokens({
model: "DeepSeek-V4-Flash-0731-W4A16-AUTOROUND-REAP",
system: "You are a physics teacher. Answer in two sentences.",
messages: [{ role: "user", content: "Why is the sky blue?" }],
});
console.log(count.input_tokens); curl https://api.shannon-ai.com/v1/messages/count_tokens \
-H "x-api-key: YOUR_API_KEY" \
-H "content-type: application/json" \
-d '{
"model": "DeepSeek-V4-Flash-0731-W4A16-AUTOROUND-REAP",
"system": "You are a physics teacher. Answer in two sentences.",
"messages": [{"role": "user", "content": "Why is the sky blue?"}]
}'
# {"input_tokens": 31} 计数有专门的页面,包含纯文本端点和限制。 Token 计数