上周接了个私活,甲方要求做一个代码审查工具——用户贴代码进去,AI给出优化建议和重构方案。说实话这种需求用Claude来做确实顺手,Claude Opus 4.6在代码生成质量上处于目前第一梯队,尤其是长上下文理解和代码输出稳定性,比手写靠谱多了。
用Claude API写代码,核心就三步:拿到API Key、选对调用方式、把System Prompt调好。下面把自己踩过的坑和最终跑通的3种方案全部摊开讲,代码直接复制就能跑。
先说结论
| 方案 | 适用场景 | 上手难度 | 推荐度 |
|---|---|---|---|
| OpenAI SDK兼容调用 | 已有OpenAI代码想切模型 | ⭐ | ⭐⭐⭐⭐⭐ |
| Anthropic官方SDK | 需要用Claude独有特性 | ⭐⭐ | ⭐⭐⭐⭐ |
| HTTP直接请求 | 轻量级脚本/非Python项目 | ⭐⭐⭐ | ⭐⭐⭐ |
我最终选了方案一,改一行base_url就能在GPT-5和Claude Opus 4.6之间来回切,省心。
环境准备
Python 3.9+,装两个包就够了:
bash
pip install openai anthropic
方案一:OpenAI SDK兼容调用(最推荐)
这是我日常用得最多的方式。原因很简单:项目里本来就有一堆OpenAI的调用代码,不想为了换个模型把半个项目重写一遍。
python
from openai import OpenAI
client = OpenAI(
api_key="your-key",
base_url="https://4sapi.com/v1" # 接入层接口,一个Key调Claude/GPT/Gemini
)
def code_review(code_snippet: str) -> str:
"""让Claude做代码审查"""
response = client.chat.completions.create(
model="claude-sonnet-4-20250514",
messages=[
{
"role": "system",
"content": (
"你是一个资深代码审查员。针对用户提交的代码,你需要:\n"
"1. 指出潜在bug和安全隐患\n"
"2. 给出性能优化建议\n"
"3. 提供重构后的完整代码\n"
"回复用中文,代码块标注语言类型。"
)
},
{
"role": "user",
"content": f"请审查以下代码:\n```python\n{code_snippet}\n```"
}
],
temperature=0.3,
max_tokens=4096,
stream=True # 流式输出,体验好很多
)
result = ""
for chunk in response:
if chunk.choices[0].delta.content:
content = chunk.choices[0].delta.content
print(content, end="", flush=True)
result += content
print()
return result
# 测试一段有问题的代码
test_code = """
import sqlite3
def get_user(username):
conn = sqlite3.connect('users.db')
cursor = conn.cursor()
query = f"SELECT * FROM users WHERE name = '{username}'"
cursor.execute(query)
result = cursor.fetchone()
return result
"""
review = code_review(test_code)
实测下来,Claude精准揪出了SQL注入漏洞、连接没关闭、没有错误处理这三个问题,还给了参数化查询 + context manager的重构版本。响应时间大概1.2秒首token,流式输出体验很顺滑。
方案二:Anthropic官方SDK
需要用到Claude的独有能力(比如超长上下文、extended thinking)时,官方SDK更合适。
python
import anthropic
client = anthropic.Anthropic(api_key="your-anthropic-key")
def generate_code(task_description: str) -> str:
"""让Claude根据需求描述生成代码"""
message = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=4096,
messages=[
{
"role": "user",
"content": (
f"请根据以下需求生成Python代码,要求:\n"
f"1. 代码可直接运行\n"
f"2. 包含类型注解\n"
f"3. 包含docstring\n"
f"4. 包含简单的单元测试\n\n"
f"需求:{task_description}"
)
}
]
)
return message.content[0].text
# 让Claude写一个LRU缓存
result = generate_code("实现一个线程安全的LRU缓存,支持TTL过期")
print(result)
好处是API参数和官方文档完全一致,没有兼容性问题。缺点是只能调Claude,想换GPT-5或Gemini 3就得改代码。
方案三:HTTP直接请求
写轻量脚本不想装SDK,直接requests怼:
python
import requests
import json
def claude_code_gen(prompt: str) -> str:
"""纯HTTP调用Claude生成代码"""
headers = {
"Authorization": "Bearer your-key",
"Content-Type": "application/json"
}
payload = {
"model": "claude-sonnet-4-20250514",
"messages": [
{
"role": "system",
"content": "你是一个Python专家,生成的代码要求生产级质量。"
},
{"role": "user", "content": prompt}
],
"temperature": 0.2,
"max_tokens": 4096
}
response = requests.post(
"https://4sapi.com/v1/chat/completions",
headers=headers,
json=payload,
timeout=60
)
if response.status_code == 200:
return response.json()["choices"][0]["message"]["content"]
else:
raise Exception(f"API错误: {response.status_code} - {response.text}")
# 测试
code = claude_code_gen("写一个FastAPI的文件上传接口,支持多文件、大小限制、类型校验")
print(code)
非Python项目里这个方案特别有用,Node.js / Go / Rust直接发HTTP就行,不用找第三方SDK。
调用链路示意
text
你的代码 ──▶ OpenAI SDK / HTTP ──▶ 接入层服务 ──┬── Claude Opus 4.6
├── Claude Sonnet 4.6
├── GPT-5
└── Gemini 3
◀── 流式响应 ──┘
用接入层接口的好处就是这个——同一套代码,换个model参数就能切模型。我做那个代码审查工具时,就用这个方式做了个A/B测试,发现Claude Opus 4.6在代码理解上确实比其他模型强一截。
踩坑记录
坑1:System Prompt太长导致代码质量下降
一开始把所有要求塞进system prompt里,足足2000字。结果Claude生成的代码又臭又长,像在凑字数。后来把system prompt精简到200字以内,代码质量立刻上来了。
教训: system prompt要简洁,具体需求放user message里。
坑2:temperature设太高,代码跑不通
默认temperature=1.0写代码简直是灾难,生成的变量名天马行空,逻辑也经常跑偏。最后固定用0.2-0.3,稳定多了。创意性需求(比如取名、写注释)可以开到0.5。
坑3:流式输出没处理好,丢了最后几个token
用stream的时候,一定要处理最后一个chunk的finish_reason。之前有个bug,循环里只判断了delta.content是否存在,最后一个chunk的content是None,直接被跳过,导致代码块的```结尾偶尔丢失。
坑4:Claude的Anthropic SDK不支持system字段放messages里
用方案二的官方SDK,system prompt要用system参数单独传,不能像OpenAI那样放在messages数组里。这个坑排了半小时,报错信息还特别不明显。
python
# ❌ 错的
messages=[{"role": "system", "content": "..."}]
# ✅ 对的
message = client.messages.create(
model="claude-sonnet-4-20250514",
system="你是一个代码专家", # system单独传
messages=[{"role": "user", "content": "..."}],
max_tokens=4096
)
用方案一的OpenAI兼容接口就没这个问题,system放messages里没事,接入层会自动帮你转换格式。
进阶技巧:让Claude写更好代码的Prompt模板
跟Claude交流写代码,摸索出一套好用的prompt结构:
python
CODING_SYSTEM_PROMPT = """你是一个资深全栈工程师。
生成代码遵循以下原则:
- 类型安全,使用类型注解
- 错误处理完善,不要用裸except
- 函数职责单一,不超过30行
- 变量命名语义化
直接输出代码,不需要解释。"""
# 用户消息模板
USER_TEMPLATE = """
## 任务
{task}
## 技术栈
{tech_stack}
## 约束
{constraints}
## 输入输出示例
{examples}
"""
把需求结构化之后,Claude生成的代码质量和一致性都会提升很多,亲测有效。
小结
三种方案各有适用场景:想省事切模型用方案一(OpenAI兼容),想用Claude全部特性用方案二(官方SDK),轻量级场景用方案三(HTTP)。我个人90%的场景都在用方案一,通过接入层服务统一管理模型调用,一个API Key可以覆盖Claude Opus 4.6、GPT-5、Gemini 3等主流模型,改一行base_url就能切换,省去了管理多个API Key和维护不同SDK的麻烦。
最近Claude Code那边还出了51万行代码泄露的事,搞得挺热闹。不过单纯用API调Claude写代码这件事本身很稳,关键在于prompt写得好不好。多花时间调prompt,比纠结用哪个模型有用多了。