Claude API 教程:从拿到 Key 到流式输出(完整可跑代码)
接入 Claude API 并不复杂,核心就四件事:拿到 Key、发第一条请求、处理流式返回、把错误码接住。下面这份代码是我实际跑通的版本,你照着改一个 Key 就能用。
一、拿到 Key 并确认两个头
在 Anthropic 控制台创建一个 API Key,然后记住两件事:鉴权头是 x-api-key,不是常见的 Authorization: Bearer;还要带 anthropic-version 头,当前用 2023-06-01。漏掉第二个头,服务端会直接报错。
import httpx
API_KEY = "sk-ant-xxx" # 换成你的
HEADERS = {
"x-api-key": API_KEY,
"anthropic-version": "2023-06-01",
"content-type": "application/json",
}
resp = httpx.post(
"https://api.anthropic.com/v1/messages",
headers=HEADERS,
json={
"model": "claude-sonnet-4-20250514",
"max_tokens": 512,
"messages": [{"role": "user", "content": "用一句话介绍你自己"}],
},
timeout=60,
)
print(resp.status_code)
print(resp.json()) 
二、最简单的对话请求
messages 数组就是整个会话历史,你只需要往里追加。注意系统提示词是单独字段 system,不要塞进 messages 里冒充用户消息。返回体的 content 是数组,文本在 content[0].text。
r = resp.json()
print(r["content"][0]["text"])
print("用量:", r["usage"]) 三、流式输出:真正的长回答体验
流式模式用来解决"回答太长、用户等得发慌"的问题。把 stream: true 打开,用 SSE 逐块接收。这里最容易踩的坑是:事件类型不同,数据结构也不同,别把 content_block_delta 当成完整消息。
with httpx.stream(
"POST",
"https://api.anthropic.com/v1/messages",
headers=HEADERS,
json={
"model": "claude-sonnet-4-20250514",
"max_tokens": 1024,
"stream": True,
"messages": [{"role": "user", "content": "写一段 200 字的产品介绍"}],
},
timeout=120,
) as resp:
buffer = ""
for line in resp.iter_lines():
if not line or not line.startswith("data:"):
continue
import json as j
ev = j.loads(line[6:])
if ev.get("type") == "content_block_delta":
delta = ev.get("delta", {}).get("text", "")
buffer += delta
print(delta, end="", flush=True)
print()
print("完整输出长度:", len(buffer)) 四、错误码:先接住再谈体验
四个码最常见:401 是 Key 错或没带 version 头;429 是限流,等 retry-after 再试;529 是服务过载,退避重试;400 通常是 messages 格式不对。别把所有错误都弹给用户,429/529 应该静默重试,400/401 应该直接报配置问题。
def call_claude(messages, max_tokens=512, stream=False):
try:
resp = httpx.post(
"https://api.anthropic.com/v1/messages",
headers=HEADERS,
json={"model": "claude-sonnet-4-20250514", "max_tokens": max_tokens,
"stream": stream, "messages": messages},
timeout=120,
)
if resp.status_code == 200:
return resp.json()
if resp.status_code in (429, 529):
return {"retryable": True, "status": resp.status_code}
return {"retryable": False, "status": resp.status_code, "body": resp.text[:200]}
except Exception as e:
return {"retryable": True, "error": str(e)} 五、几个容易忽略的点
max_tokens 只算输出不算输入,别按整段话估算。多轮对话记得把历史完整传回去,模型不记得上一轮的事。想控制成本就把 system 提示词写短,它在每次请求里都会重复计费。如果做的是国内产品、直接连官方域名延迟高,走国内中转聚合平台(如 bigmodel.org 这类统一入口)通常更稳,还能一个 Key 管多家模型。

