Anthropic Messages
现有的 Anthropic SDK 代码改个 base URL 就能半价调用 Claude。流式输出、扩展思考、工具调用、提示缓存和 token 计数照常可用。
如果你的代码已经用 Anthropic SDK 调 Claude,迁移到 Half Off Dev 只需改两项配置:base URL 设为 https://halfoff.dev,密钥换成 Half Off Dev 的密钥。POST /v1/messages 和 POST /v1/messages/count_tokens 的行为与 Anthropic 的定义一致,请求体原样转发,因此每个字段都以 Anthropic API 文档为准。所有 token 都按官方标价的一半计费。
让 SDK 指向 Half Off Dev#
Anthropic SDK 把密钥放在 x-api-key 里;用 Authorization: Bearer 发送也可以。
curl https://halfoff.dev/v1/messages \
-H "x-api-key: $HALFOFF_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{
"model": "claude-sonnet-5.5",
"max_tokens": 1024,
"messages": [{"role": "user", "content": "给一个代码评审机器人起三个名字。"}]
}'使用默认客户端的代码甚至不用改:SDK 会从环境变量读取 ANTHROPIC_BASE_URL 和 ANTHROPIC_API_KEY,执行 export ANTHROPIC_BASE_URL=https://halfoff.dev 并设好密钥即可。
目前可用的 Claude 模型包括 claude-fable-5.1、claude-opus-5.5、claude-sonnet-5.5、claude-haiku-5.5,以及更早的版本。完整列表和价格以 GET /v1/models 为准。
边生成边接收#
设置 stream: true,或使用 SDK 的流式辅助方法。事件顺序与 Anthropic 一致:message_start、content_block_start、content_block_delta、content_block_stop、message_delta、message_stop。
with client.messages.stream(
model="claude-sonnet-5.5",
max_tokens=2048,
messages=[{"role": "user", "content": "为一个修复 bug 的小版本写一段简短的发布说明。"}],
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)
final = stream.get_final_message()
print("\n", final.usage)第一个 token 出现之前,网关会先把流扣在自己这边;这段时间里渠道出错,会由另一个渠道接手,你完全察觉不到。细节见流式输出。
让 Claude 调用你的函数#
用 JSON Schema 的 input_schema 描述每个函数。响应里出现 stop_reason: "tool_use" 时,执行对应函数,再用 tool_result 块把结果发回去。
tools = [{
"name": "convert_currency",
"description": "在两种货币之间换算金额。",
"input_schema": {
"type": "object",
"properties": {
"amount": {"type": "number"},
"from_currency": {"type": "string"},
"to_currency": {"type": "string"},
},
"required": ["amount", "from_currency", "to_currency"],
},
}]
messages = [{"role": "user", "content": "250 欧元能换多少日元?"}]
response = client.messages.create(
model="claude-sonnet-5.5", max_tokens=1024, tools=tools, messages=messages,
)
if response.stop_reason == "tool_use":
call = next(b for b in response.content if b.type == "tool_use")
result = {"converted": 40125.0, "currency": call.input["to_currency"]} # 这里换成你的实现
messages += [
{"role": "assistant", "content": response.content},
{"role": "user", "content": [
{"type": "tool_result", "tool_use_id": call.id, "content": str(result)},
]},
]
response = client.messages.create(
model="claude-sonnet-5.5", max_tokens=1024, tools=tools, messages=messages,
)
print(response.content[0].text)tool_choice、strict 等其他选项原样转发,用法见 Anthropic 的工具调用指南。
开启扩展思考#
按 Anthropic 对所调用模型的规定发送 thinking 和 output_config。新模型采用自适应思考,配合 effort 档位;Claude 4.5 及更早的模型使用固定的 budget_tokens。各模型的规则见 Anthropic 思考指南。
reply = client.messages.create(
model="claude-opus-5.5",
max_tokens=16000,
thinking={"type": "adaptive", "display": "summarized"},
output_config={"effort": "high"},
messages=[{"role": "user", "content": "火车 09:40 出发、14:05 到达,全程多少分钟?"}],
)
for block in reply.content:
if block.type == "thinking":
print("推理:", block.thinking)
elif block.type == "text":
print("结果:", block.text)思考内容计入 usage.output_tokens,按(减半后的)输出单价计费。在工具调用之后继续对话时,请把 thinking 块原封不动地传回。
缓存每次重复发送的前缀#
在每次请求都不变的那部分内容里,给最后一个块加上 cache_control。第一次请求写入缓存,之后以相同前缀开头的请求按远低于输入单价的价格读取缓存。
response = client.messages.create(
model="claude-sonnet-5.5",
max_tokens=1024,
system=[{
"type": "text",
"text": STYLE_GUIDE,
"cache_control": {"type": "ephemeral"},
}],
messages=[{"role": "user", "content": "按规范改写这个标题:'第三季度数据出炉'"}],
)
u = response.usage
print(u.cache_creation_input_tokens, u.cache_read_input_tokens, u.input_tokens)以 claude-sonnet-5.5 为例,你实际支付的每百万 token 价格:未缓存输入 $1.00,缓存写入 $1.25,缓存读取 $0.05。前缀短于模型的最小长度时不会被缓存,两个缓存字段都返回 0。网关会把每个对话送回持有其缓存的渠道,完整说明见提示缓存。
发送前先数 token#
POST /v1/messages/count_tokens 接受与消息请求相同的请求体(不含 max_tokens),返回 input_tokens。它不收费,余额为零时也能用。
curl https://halfoff.dev/v1/messages/count_tokens \
-H "x-api-key: $HALFOFF_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{"model": "claude-sonnet-5.5",
"messages": [{"role": "user", "content": "这段提示词有多长?"}]}'估算值,不是账单
计数适合用来对照上下文窗口检查提示词长度,或做预算。实际扣费永远以模型响应里的 usage 为准。
Claude Code#
Claude Code 使用的就是这套 API。设置 ANTHROPIC_BASE_URL=https://halfoff.dev,把密钥填进 ANTHROPIC_AUTH_TOKEN;每个会话都会固定在同一个渠道上,缓存始终有效。包括模型设置在内的完整步骤见 Claude Code。
请求头#
| 请求头 | 行为 |
|---|---|
x-api-key 或 Authorization: Bearer | 你的 Half Off Dev 密钥,必填。 |
anthropic-version | 转发;不填时默认为 2023-06-01。 |
anthropic-beta | 原样转发。 |
x-halfoff-group | 可选。为本次请求指定渠道分组;密钥已绑定分组时无效。 |
x-session-id | 可选。把多个请求标记为同一个对话,用于缓存感知路由。请求体里的 metadata.user_id 效果相同。 |
其他请求头一律不转发。错误沿用 Anthropic 的格式 {"type": "error", "error": {"type": "...", "message": "..."}},错误码见错误。