用 Python 调用 Claude API:从发消息到拿结构化 JSON

2026-05-20 17 预计阅读时间:1 分钟
来源:realpython.com AI 摘要 原文链接

免责声明:本文为 AI 摘要整理,建议结合原文阅读。摘要可能省略上下文、版本差异或边界条件,不作为官方说明。

预计阅读时间:8 分钟

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 是一个列表,每条消息有 roleuserassistant)和 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 前后加了换行或注释而报错。两种防御手段:

  1. system 里加硬约束"只输出合法 JSON,不要加注释、不要加 markdown 代码块标记"
  2. 代码里做清洗:用正则去掉 ```json 包裹,或用 json.loadsstrict=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,你会很快摸到手感。


相关推荐