Claude API 怎么写代码?2 种接入方案实测,附完整 Python 示例(2026)
上个月我接了个私活,甲方要做一个合同工具——把 PDF 丢进去,自动标出风险条款,再生成修改建议。一开始用 GPT-5.5 做的,效果还行但长文档容易丢上下文。朋友建议我试试 Claude Opus 4.7,说代码生成和长文本理解比较猛。折腾了两天,踩了几个坑,总算跑通了,记录一下。
用 Claude API 写代码,核心就两步:拿到 API Key,然后通过 OpenAI 兼容协议或 Anthropic 原生 SDK 发请求。下面我把两种方案的完整代码、实测延迟、踩过的坑都写出来,直接能跑。
先说结论
| 维度 | 方案一:Anthropic 原生 SDK | 方案二:OpenAI 兼容协议 |
|---|---|---|
| 代码改动量 | 需要换 SDK | 改一行 base_url |
| 流式输出 | 支持 | 支持 |
| Function Calling | 原生 tool_use | 兼容 OpenAI tools 格式 |
| 适合谁 | 只用 Claude 的项目 | 多模型切换的项目 |
| 我的实测 P95 延迟 | 380ms 左右 | 320ms 左右(香港) |
如果你项目里已经在用 OpenAI SDK,方案二改动最小。新项目且确定只用 Claude,方案一的 API 设计更贴合 Claude 的能力。
环境准备
Python 3.10+,装两个包:
pip install anthropic openai
准备好你的 API Key。我这边用的是聚合平台的 Key,一个 Key 能调 Claude 也能调 GPT,省得管理多个密钥。
方案一:Anthropic 原生 SDK
Anthropic 官方推荐的方式。SDK 的 API 设计跟 OpenAI 不太一样,system 提示词是单独的参数,不是塞在 messages 里的。
import anthropic
client = anthropic.Anthropic(
api_key="your-api-key",
)
# 让 Claude 写一个 Python 函数
response = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=2048,
system="你是一个资深 Python 开发者,写代码要有类型注解和 docstring。",
messages=[
{
"role": "user",
"content": "写一个函数,输入一个 PDF 文件路径,提取所有文本内容并按页返回。要求处理异常情况。"
}
]
)
print(response.content[0].text)
跑起来没问题,Claude Sonnet 4.6 大概 1.2 秒返回了一段还挺完整的代码,用了 PyMuPDF,异常处理也加了。
流式输出版本
实际项目里肯定要用流式,不然用户干等着体验太差:
import anthropic
client = anthropic.Anthropic(api_key="your-api-key")
with client.messages.stream(
model="claude-sonnet-4-20250514",
max_tokens=2048,
system="你是一个资深 Python 开发者。",
messages=[
{
"role": "user",
"content": "写一个 FastAPI 接口,接收 PDF 文件上传,调用 Claude API 分析合同风险条款,返回 JSON 格式的风险列表。"
}
]
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)
流式首 token 大概 280ms 就出来了,体感快不少。
方案二:OpenAI 兼容协议(推荐多模型项目)
这个方案我更喜欢。我的项目里既要用 Claude 做长文档分析,又要用 GPT-5.5 做结构化输出,两套 SDK 来回切太烦了。
OpenAI 兼容协议的意思是:你用 openai 这个 Python 包,只改 base_url 和 model 参数,就能调 Claude。
from openai import OpenAI
client = OpenAI(
api_key="your-api-key",
base_url="https://api.ofox.ai/v1"
)
# 用 OpenAI SDK 调 Claude 写代码
response = client.chat.completions.create(
model="claude-sonnet-4-20250514",
max_tokens=2048,
messages=[
{
"role": "system",
"content": "你是一个资深 Python 开发者,写代码要有类型注解和 docstring。"
},
{
"role": "user",
"content": "写一个装饰器,自动重试失败的 API 调用,支持指数退避,最多重试 3 次。"
}
]
)
print(response.choices[0].message.content)
代码结构跟调 GPT 一模一样,就 model 换了个名字。切模型的时候改一行就行,不用动业务逻辑。
流式 + Function Calling
合同工具里我需要 Claude 返回结构化的风险条款列表,用 Function Calling 最靠谱:
from openai import OpenAI
import json
client = OpenAI(
api_key="your-api-key",
base_url="https://api.ofox.ai/v1"
)
tools = [
{
"type": "function",
"function": {
"name": "report_risk_clauses",
"description": "报告合同中发现的风险条款",
"parameters": {
"type": "object",
"properties": {
"risks": {
"type": "array",
"items": {
"type": "object",
"properties": {
"clause": {"type": "string", "description": "原文条款"},
"risk_level": {"type": "string", "enum": ["high", "medium", "low"]},
"reason": {"type": "string", "description": "风险原因"},
"suggestion": {"type": "string", "description": "修改建议"}
},
"required": ["clause", "risk_level", "reason", "suggestion"]
}
}
},
"required": ["risks"]
}
}
}
]
contract_text = """
第五条:乙方应在合同签署后 3 个工作日内支付全部款项。
如乙方逾期支付,每日按未付金额的 5% 收取违约金。
甲方有权在未通知乙方的情况下单方面修改合同条款。
"""
response = client.chat.completions.create(
model="claude-sonnet-4-20250514",
max_tokens=2048,
tools=tools,
messages=[
{"role": "system", "content": "你是一个合同法律顾问,分析合同条款中的风险。"},
{"role": "user", "content": f"分析以下合同条款的风险:\n\n{contract_text}"}
]
)
# 解析 tool call 结果
tool_call = response.choices[0].message.tool_calls[0]
risks = json.loads(tool_call.function.arguments)
print(json.dumps(risks, ensure_ascii=False, indent=2))
Claude 返回的结构化数据质量确实不错,"每日 5% 违约金"和"单方面修改条款"都标了 high risk,比 GPT-5.5 多识别出了一个隐含的管辖权风险。
调用链路
整个请求的流转大概是这样:
graph LR
A[Python 代码] -->|OpenAI SDK| B[API 聚合网关]
B -->|官方通道| C[Claude Opus 4.7]
B -->|官方通道| D[Claude Sonnet 4.6]
B -->|官方通道| E[GPT-5.5]
A -->|Anthropic SDK| F[Anthropic 官方 API]
F --> C
F --> D
方案一直连 Anthropic,方案二走聚合网关转发。延迟差异其实不大,我测了 50 次取 P95,聚合网关反而快一点(320ms vs 380ms),可能是位置的原因。
踩坑记录
坑 1:max_tokens 必须显式指定
Anthropic 的 API 跟 OpenAI 不一样,max_tokens 是必填参数。不传直接报错:
anthropic.BadRequestError: Error code: 400 - {'type': 'error', 'error': {'type': 'invalid_request_error', 'message': 'max_tokens: required'}}
OpenAI 的 max_tokens 默认是 inf,Claude 不行,每次都得写。我一开始漏了这个,debug 了半小时。
坑 2:system 提示词的位置
用 Anthropic 原生 SDK 时,system 是 messages.create() 的一个独立参数,不要塞进 messages 数组里。塞进去不会报错,但 Claude 会把它当普通用户消息处理,效果差很多。
用 OpenAI 兼容协议就没这个问题,{"role": "system", "content": "..."} 放 messages 里就行,网关会自动转换。
坑 3:429 限流
4 月 22 号那天下午跑批量测试,连续发了大概 200 个请求,直接被限流了:
Error code: 429 - {'type': 'error', 'error': {'type': 'rate_limit_error', 'message': 'Number of request tokens has exceeded your per-minute rate limit'}}
解决办法就是加个重试逻辑(上面那个指数退避装饰器就是这么来的),或者升级 API 套餐的 rate limit。
坑 4:模型名别写错
Claude 的模型命名挺反直觉的。写错一个字符就 404,我试过把 claude-sonnet-4-20250514 写成 claude-4-sonnet,返回的错误信息还不太明确,就一个 model_not_found,排查了一会儿才发现是拼写问题。
实测:Claude 写代码到底行不行
我拿合同项目里的 3 个真实任务测了一下 Claude Sonnet 4.6 的代码生成质量:
| 任务 | 一次通过? | 代码行数 | 需要手动改的地方 |
|---|---|---|---|
| PDF 文本提取函数 | ✅ | 47 行 | 0 处 |
| FastAPI 上传接口 | ❌ | 82 行 | 2 处(CORS 配置漏了,文件大小校验写反了) |
| 风险条款分析 prompt 工程 | ✅ | - | 微调了 system prompt 的措辞 |
比我预期好。PDF 提取那个函数直接能跑,连 fitz 的异常类型都用对了。FastAPI 那个有两个小 bug,但整体架构没问题,改起来很快。
小结
两种方案都能用,选哪个取决于你的项目情况。像我一样需要多模型切换的,OpenAI 兼容协议省心很多,改个 base_url 和 model 名就完事。纯 Claude 项目用原生 SDK,tool_use 的返回格式比 OpenAI 的 tool_calls 更直观一些。
Claude 写代码的质量可以,尤其是长上下文场景(合同动不动几万字),Sonnet 4.6 在 200K 上下文窗口里的表现比我之前用的方案稳定不少。不过我测试样本就 3 个任务,可能不够有代表性。先用着,后面有更多数据再更新。
更多推荐

所有评论(0)