Anthropic 的 Claude 模型在长文本理解、指令遵循和代码生成上表现突出,但官方文档散落在多个页面,拼出一条完整调用链路要翻不少资料。这篇文章把 Python SDK 的核心用法——发 prompt、用 system 指令控制输出风格、拿结构化 JSON——串成一条可直接跑通的路径。
安装与认证:两步搞定
先装 SDK,再设环境变量,不需要额外注册 OAuth 流程:
pip install anthropic
把你的 API Key 存到环境变量里,避免硬编码泄露:
export ANTHROPIC_API_KEY="sk-ant-xxxxx"
SDK 会自动读取 ANTHROPIC_API_KEY,也可以在代码里手动传入 api_key 参数。前者更适合生产环境,后者方便本地调试时临时切换 Key。
最简对话:一条 prompt 一条回复
下面这段代码是最低可运行示例——发一句用户消息,拿到 Claude 的文本回复:
import anthropic
client = anthropic.Anthropic() # 自动读环境变量
message = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
messages=[
{"role": "user", "content": "用一句话解释什么是向量数据库"}
]
)
print(message.content[0].text)
# 输出类似:向量数据库是一种专门存储和检索高维向量数据的系统,常用于语义搜索和推荐场景。
几个要点:
model字段指定模型版本,claude-sonnet-4-20250514是当前性价比最高的选择;重推理任务可换claude-opus-4-20250514。max_tokens限制回复长度,不设会报错。Claude 不会自动"截断到合理长度",你必须显式声明上限。messages是一个列表,每条消息有role(user或assistant)和content。多轮对话时,把历史消息按顺序塞进去即可。
用 System 指令塑造输出风格
system 参数和 messages 平级,它不占对话轮次,但对每一轮回复都生效。典型用法:限定输出格式、语气、角色。
message = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=2048,
system="你是一名资深后端工程师,回答时只给出可运行的 Python 代码片段,不写解释性文字。代码必须包含类型标注。",
messages=[
{"role": "user", "content": "写一个异步 HTTP GET 函数,带超时和重试"}
]
)
print(message.content[0].text)
输出会是一段带类型标注的 Python 代码,没有多余的"好的,我来帮你……"之类的寒暄。System 指令的约束力很强,但也要注意:
- 过长的 system(超过几千字)会挤占
max_tokens的有效空间,因为模型要"记住"整段指令。 - 如果 system 和用户消息冲突,Claude 通常偏向 system,但极端矛盾下仍可能"叛逃"。关键约束最好在 system 开头用祈使句写清楚。
拿结构化 JSON:让输出可解析
自由文本好读,但下游程序要解析就麻烦了。Claude 支持在 prompt 里要求 JSON 输出,配合 system 指令锁定 schema:
import json
message = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
system="你是一个技术摘要生成器。用户给你一段技术文章,你必须只输出合法 JSON,不要输出任何其他文字。JSON 结构为:{\"title\": string, \"summary\": string, \"tags\": string[]}。",
messages=[
{
"role": "user",
"content": """
Kubernetes 1.30 引入了 Structured Authentication Configuration,
允许管理员用声明式 YAML 配置 OIDC 认证,不再需要修改 API Server 启动参数。
这降低了配置错误风险,也让认证流程可审计。
"""
}
]
)
raw = message.content[0].text
data = json.loads(raw)
print(data["title"]) # Kubernetes 1.30 的声明式认证配置
print(data["tags"]) # ['kubernetes', 'oidc', 'authentication']
实际运行时,json.loads 可能因为 Claude 在 JSON 前后加了换行或注释而报错。两种防御手段:
- system 里加硬约束:
"只输出合法 JSON,不要加注释、不要加 markdown 代码块标记"。 - 代码里做清洗:用正则去掉
```json包裹,或用json.loads的strict=False放松解析。
更稳健的做法是结合两者:
import re
def extract_json(text: str) -> dict:
# 剥掉可能的 markdown 代码块
cleaned = re.sub(r"^```json\s*|\s*```$", "", text, flags=re.MULTILINE)
return json.loads(cleaned.strip())
多轮对话与上下文窗口
Claude 的上下文窗口最大 200K tokens(Opus/Sonnet),多轮对话时把历史塞进 messages:
history = [
{"role": "user", "content": "帮我设计一个 Redis 缓存策略"},
{"role": "assistant", "content": "建议用 cache-aside 模式……"},
{"role": "user", "content": "如果缓存失效时数据库也挂了怎么办?"},
]
message = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
system="你是分布式系统架构师,回答简洁,不超过200字。",
messages=history
)
print(message.content[0].text)
注意 messages 里不能出现 role: system——system 只能通过顶层参数传入。历史太长时,考虑截断早期轮次或做摘要压缩,避免超出 token 限额导致 API 报错。
实用检查清单
上线前逐条过一遍:
| 检查项 | 说明 |
|---|---|
max_tokens 是否设置 |
不设会直接报错;设太小会截断回复 |
| API Key 是否走环境变量 | 硬编码到代码里是安全隐患,CI 环境用 secret 管理 |
| JSON 输出是否做了清洗 | Claude 可能加 markdown 包裹,extract_json 函数兜底 |
| System 指令是否简洁 | 超长 system 挤占输出空间,核心约束放前 200 字 |
| 模型选择是否匹配任务 | 简单提取用 Haiku 省钱,复杂推理用 Opus,通用场景 Sonnet |
| 多轮历史是否做了截断 | 超过上下文窗口会报 overloaded 错误 |
Claude API 的 Python SDK 本身很薄,核心就是 messages.create 一个入口。真正决定效果的是你怎么写 system 指令、怎么设计 prompt 结构、怎么处理输出边界。把上面几段代码跑一遍,改改 system 和 max_tokens,你会很快摸到手感。