主题
Anthropic API 零基础入门完全指南
📚 适用对象:零基础编程学习者
🎯 学习目标:系统掌握 Anthropic Claude API 的核心使用方法
⏱️ 预计学习时间:2-3 小时
📅 更新时间:2025年2月
目录
一、基础认知
1.1 什么是 Anthropic API
通俗解释:
Anthropic 是一家专注于 AI 安全的公司,由前 OpenAI 成员创立。他们开发的 Claude 系列模型以安全性、诚实性和有用性著称。Anthropic API 就是让你能够在自己的程序中调用 Claude 模型的「桥梁」。
技术定义:
Anthropic API 是 Anthropic 公司提供的一套应用程序接口(Application Programming Interface),让开发者可以在自己的程序中调用 Claude 系列大语言模型。
┌─────────────────────────────────────────────────────────────┐
│ Anthropic API 工作原理 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 你的程序 Anthropic API Claude 模型 │
│ ┌─────┐ ┌─────────┐ ┌─────────┐ │
│ │ │ ──请求──▶│ │──处理──▶│ Claude │ │
│ │ App │ │ 云服务器 │ │ Opus │ │
│ │ │ ◀──响应──│ │◀─返回───│ Sonnet │ │
│ └─────┘ └─────────┘ │ Haiku │ │
│ └─────────┘ │
└─────────────────────────────────────────────────────────────┘核心价值:
- ✅ AI 安全性领先(Constitutional AI 技术)
- ✅ 超长上下文窗口(最高 200K tokens)
- ✅ 强大的推理和编码能力
- ✅ 原生工具调用支持
1.2 核心能力一览
| 能力 | 说明 | 典型用途 | 对应接口 |
|---|---|---|---|
| 文本生成 ★ | 根据提示生成文本 | 写作、翻译、总结、代码生成 | Messages API |
| 多轮对话 ★ | 支持上下文的交互式对话 | 聊天机器人、客服、助手 | Messages API |
| 工具调用 ★ | 让模型调用外部工具/函数 | 自动化任务、数据获取 | Messages API + Tools |
| 视觉理解 | 分析和理解图像内容 | 图片描述、OCR、图表分析 | Messages API + Vision |
| 扩展思考 | 显示模型的推理过程 | 复杂问题分析、教育场景 | Messages API + Thinking |
| 批量处理 | 批量异步处理请求 | 大规模数据处理 | Batch API |
💡 新手建议:先从「Messages API」的基础用法开始学习,这是最核心也是最常用的功能。
1.3 主流模型对比
📊 Claude 模型对比表(2025年)
| 模型 | 智能程度 | 速度 | 价格 | 上下文长度 | 推荐场景 |
|---|---|---|---|---|---|
| Claude Opus 4 ★ | ⭐⭐⭐⭐⭐+ | 慢 | 最贵 | 200K | 最复杂的任务、研究分析 |
| Claude Sonnet 4 ★ | ⭐⭐⭐⭐⭐ | 中等 | 中等 | 200K | 平衡性能与成本的首选 |
| Claude Sonnet 3.5 | ⭐⭐⭐⭐⭐ | 快 | 中等 | 200K | 编程、写作、日常任务 |
| Claude Haiku 3.5 | ⭐⭐⭐⭐ | 最快 | 最便宜 | 200K | 高并发、简单任务 |
💰 价格参考(2025年)
| 模型 | 输入价格(每百万Token) | 输出价格(每百万Token) |
|---|---|---|
| Claude Opus 4 | ~$15 | ~$75 |
| Claude Sonnet 4 | ~$3 | ~$15 |
| Claude Sonnet 3.5 | ~$3 | ~$15 |
| Claude Haiku 3.5 | ~$0.25 | ~$1.25 |
⚠️ 价格可能变动,请以官网为准:https://www.anthropic.com/pricing
🔍 什么是上下文长度(Context Length)?
- 200K tokens ≈ 约 150,000 个汉字 ≈ 一本长篇小说
- 这意味着你可以在一次对话中发送大量文档进行分析
1.4 Anthropic vs OpenAI API 对比 ★★★
这是最重要的概念之一,因为很多开发者会从 OpenAI 迁移到 Anthropic:
| 对比项 | OpenAI API | Anthropic API |
|---|---|---|
| 系统提示位置 | 在 messages 数组中,role: "system" | 单独的 system 参数 |
| messages 角色 | system, user, assistant | 只有 user, assistant |
| 必需参数 | model, messages | model, messages, max_tokens |
| 工具定义 | type: "function" + parameters | 直接定义 + input_schema |
| 认证头 | Authorization: Bearer xxx | x-api-key: xxx |
| 流式结束标记 | data: [DONE] | 无 [DONE],通过事件类型判断 |
关键区别示意:
python
# ❌ OpenAI 格式(在 Anthropic 中会报错)
messages = [
{"role": "system", "content": "你是助手"}, # ❌ Anthropic 不支持
{"role": "user", "content": "你好"}
]
# ✅ Anthropic 格式
system = "你是助手" # ✅ 单独的 system 参数
messages = [
{"role": "user", "content": "你好"}
]二、实操步骤
2.1 申请 API Key 完整流程
📋 准备工作
- 邮箱:一个可用的邮箱地址
- 手机号:用于验证
- 支付方式:信用卡(Visa/Mastercard)
📝 申请步骤
步骤 1:注册账号
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1. 访问 https://console.anthropic.com/
2. 点击 "Sign Up" 注册
3. 完成邮箱验证
4. 填写个人信息
步骤 2:添加支付方式
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1. 登录后进入 Settings → Billing
2. 添加信用卡信息
3. 设置消费限额(建议新手设 $10-20)
步骤 3:创建 API Key
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1. 进入 https://console.anthropic.com/settings/keys
2. 点击 "Create Key"
3. 给 Key 起个名字
4. ★ 立即复制并保存!关闭后无法再次查看 ★2.2 Python 环境安装
步骤 1:安装 Anthropic 官方库
bash
# 使用 pip 安装
pip install anthropic
# 如果安装慢,使用国内镜像
pip install anthropic -i https://pypi.tuna.tsinghua.edu.cn/simple步骤 2:配置 API Key
方式一:环境变量(推荐) ★
bash
# Linux / macOS
export ANTHROPIC_API_KEY="sk-ant-你的API密钥"
# Windows PowerShell
$env:ANTHROPIC_API_KEY="sk-ant-你的API密钥"方式二:代码中直接设置(仅测试用)
python
from anthropic import Anthropic
client = Anthropic(api_key="sk-ant-你的API密钥")2.3 最小可行代码 ★
以下是一个可以直接复制运行的最简单示例:
python
"""
Anthropic API 最小可行代码示例
作用:向 Claude 模型发送一条消息,获取回复
"""
# ===== 第一步:导入库 =====
from anthropic import Anthropic
# ===== 第二步:创建客户端 =====
# 会自动读取环境变量 ANTHROPIC_API_KEY
client = Anthropic()
# ===== 第三步:发送请求 =====
message = client.messages.create(
# model: 选择使用的模型
model="claude-sonnet-4-20250514",
# max_tokens: ★ Anthropic 必须指定 ★
max_tokens=1024,
# system: 系统提示词(单独参数,不在 messages 里)
system="你是一个友好的助手,用简洁的中文回答问题。",
# messages: 对话消息列表
# ★ 注意:只能包含 user 和 assistant 角色 ★
messages=[
{
"role": "user",
"content": "你好!请用一句话介绍一下自己。"
}
]
)
# ===== 第四步:获取回复 =====
# message.content[0].text 是 Claude 的回复文本
reply = message.content[0].text
print("Claude 回复:", reply)运行结果示例:
Claude 回复: 你好!我是 Claude,一个由 Anthropic 开发的 AI 助手,随时准备帮你解答问题和完成各种任务。2.4 响应结构解析 ★
当你发送请求后,Anthropic 返回的是一个结构化的响应对象:
python
{
"id": "msg_01XFDUDYJgAACzvnptvVoYEL", # 本次请求的唯一ID
"type": "message", # 对象类型
"role": "assistant", # 角色:AI助手
"model": "claude-sonnet-4-20250514", # 实际使用的模型版本
"content": [ # ★ 内容块列表(可能有多个)
{
"type": "text", # 内容类型
"text": "Claude的回复内容" # ★ 这是你需要的回复文本
}
],
"stop_reason": "end_turn", # 停止原因
"stop_sequence": null, # 触发停止的序列
"usage": { # ★ Token 使用统计
"input_tokens": 25, # 输入 Token 数
"output_tokens": 30 # 输出 Token 数
}
}常用取值方式:
python
# 获取 Claude 回复的文本
reply_text = message.content[0].text
# 获取 Token 使用量
input_tokens = message.usage.input_tokens
output_tokens = message.usage.output_tokens
# 获取停止原因
# "end_turn" = 正常结束
# "max_tokens" = 达到 max_tokens 限制
# "stop_sequence" = 遇到停止序列
# "tool_use" = 模型请求调用工具
stop_reason = message.stop_reason三、核心场景
3.1 简单对话
python
"""
简单对话示例
"""
from anthropic import Anthropic
def chat_once(user_message: str) -> str:
"""发送一条消息,获取 Claude 回复"""
client = Anthropic()
message = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
system="你是一个友好、乐于助人的AI助手。",
messages=[
{"role": "user", "content": user_message}
]
)
return message.content[0].text
if __name__ == "__main__":
question = "Python 和 JavaScript 有什么区别?"
answer = chat_once(question)
print(f"问题: {question}")
print(f"回答: {answer}")3.2 多轮对话实现 ★
多轮对话的关键是保存对话历史:
python
"""
多轮对话机器人 - 支持上下文记忆
"""
from anthropic import Anthropic
class ClaudeBot:
"""
多轮对话机器人类
使用方法:
bot = ClaudeBot()
bot.chat("你好")
bot.chat("我叫小明")
bot.chat("我叫什么名字?") # Claude 能记住你叫小明
"""
def __init__(self, system_prompt: str = None):
self.client = Anthropic()
if system_prompt is None:
system_prompt = """你是一个友好、专业的AI助手。
请遵循以下规则:
1. 用简洁清晰的中文回答
2. 记住用户之前说过的内容"""
self.system_prompt = system_prompt
# ★ 核心:对话历史列表
self.messages = []
def chat(self, user_input: str) -> str:
"""发送消息并获取回复"""
# 1. 将用户消息添加到历史
self.messages.append({
"role": "user",
"content": user_input
})
# 2. 发送请求(包含完整对话历史)
response = self.client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
system=self.system_prompt,
messages=self.messages # ★ 发送完整历史
)
# 3. 获取 Claude 回复
assistant_message = response.content[0].text
# 4. 将 Claude 回复也添加到历史
self.messages.append({
"role": "assistant",
"content": assistant_message
})
return assistant_message
def clear_history(self):
"""清空对话历史"""
self.messages = []
if __name__ == "__main__":
print("=" * 50)
print("Claude 多轮对话机器人")
print("输入 'quit' 退出,输入 'clear' 清空历史")
print("=" * 50)
bot = ClaudeBot()
while True:
user_input = input("\n你: ").strip()
if user_input.lower() == 'quit':
print("再见!")
break
elif user_input.lower() == 'clear':
bot.clear_history()
print("[对话历史已清空]")
continue
elif not user_input:
continue
try:
reply = bot.chat(user_input)
print(f"\nClaude: {reply}")
except Exception as e:
print(f"\n[错误] {e}")3.3 流式输出实现 ★
流式输出让 Claude 的回复像打字一样逐字显示:
python
"""
流式输出示例 - 打字机效果
"""
from anthropic import Anthropic
def chat_stream(user_message: str):
"""流式对话 - 打字机效果"""
client = Anthropic()
print("Claude: ", end="", flush=True)
# ★ 使用 stream() 方法开启流式输出
with client.messages.stream(
model="claude-sonnet-4-20250514",
max_tokens=1024,
system="你是一个友好的助手。",
messages=[
{"role": "user", "content": user_message}
]
) as stream:
full_response = ""
for text in stream.text_stream:
print(text, end="", flush=True)
full_response += text
print() # 换行
return full_response
if __name__ == "__main__":
question = "请用3句话介绍一下人工智能的发展历史。"
print(f"问题: {question}\n")
chat_stream(question)3.4 工具调用(Tool Use) ★★
工具调用是 Claude 的强大功能,让模型可以调用外部函数:
python
"""
工具调用(Tool Use)示例
让 Claude 调用外部函数来完成任务
"""
import json
from anthropic import Anthropic
client = Anthropic()
# 定义工具
tools = [
{
"name": "get_weather",
"description": "获取指定城市的天气信息",
"input_schema": { # ★ Anthropic 使用 input_schema,不是 parameters
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名称,如:北京、上海"
}
},
"required": ["city"]
}
},
{
"name": "write_file",
"description": "将内容写入文件",
"input_schema": {
"type": "object",
"properties": {
"path": {
"type": "string",
"description": "文件路径"
},
"content": {
"type": "string",
"description": "要写入的内容"
}
},
"required": ["path", "content"]
}
}
]
# 模拟工具执行函数
def execute_tool(tool_name: str, tool_input: dict) -> str:
"""执行工具并返回结果"""
if tool_name == "get_weather":
# 模拟天气数据
return json.dumps({
"city": tool_input["city"],
"temperature": "25°C",
"weather": "晴天",
"humidity": "60%"
}, ensure_ascii=False)
elif tool_name == "write_file":
# 模拟写文件
return f"文件 {tool_input['path']} 写入成功"
return "工具未找到"
def chat_with_tools(user_message: str):
"""带工具调用的对话"""
messages = [{"role": "user", "content": user_message}]
# 第一次请求 - 可能会触发工具调用
response = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
tools=tools,
messages=messages
)
print(f"初始响应 stop_reason: {response.stop_reason}")
# 检查是否需要调用工具
while response.stop_reason == "tool_use":
# 收集所有工具调用
tool_results = []
assistant_content = response.content
for block in assistant_content:
if block.type == "tool_use":
tool_name = block.name
tool_input = block.input
tool_use_id = block.id
print(f"\n[调用工具] {tool_name}")
print(f"[工具参数] {json.dumps(tool_input, ensure_ascii=False)}")
# 执行工具
result = execute_tool(tool_name, tool_input)
print(f"[工具结果] {result}")
tool_results.append({
"type": "tool_result",
"tool_use_id": tool_use_id,
"content": result
})
# 将 assistant 消息和工具结果添加到历史
messages.append({"role": "assistant", "content": assistant_content})
messages.append({"role": "user", "content": tool_results})
# 继续对话
response = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
tools=tools,
messages=messages
)
# 获取最终回复
final_text = ""
for block in response.content:
if hasattr(block, "text"):
final_text += block.text
return final_text
if __name__ == "__main__":
# 测试天气查询
result = chat_with_tools("北京今天天气怎么样?")
print(f"\n[最终回复] {result}")3.5 视觉能力(Vision)
Claude 可以理解和分析图像:
python
"""
视觉能力示例 - 图片分析
"""
import base64
from anthropic import Anthropic
client = Anthropic()
def analyze_image(image_path: str, question: str) -> str:
"""分析图片并回答问题"""
# 读取图片并转为 base64
with open(image_path, "rb") as f:
image_data = base64.standard_b64encode(f.read()).decode("utf-8")
# 根据文件扩展名确定 media_type
if image_path.endswith(".png"):
media_type = "image/png"
elif image_path.endswith(".gif"):
media_type = "image/gif"
elif image_path.endswith(".webp"):
media_type = "image/webp"
else:
media_type = "image/jpeg"
message = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
messages=[
{
"role": "user",
"content": [
{
"type": "image",
"source": {
"type": "base64",
"media_type": media_type,
"data": image_data
}
},
{
"type": "text",
"text": question
}
]
}
]
)
return message.content[0].text
# 也支持 URL 方式
def analyze_image_url(image_url: str, question: str) -> str:
"""通过 URL 分析图片"""
message = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
messages=[
{
"role": "user",
"content": [
{
"type": "image",
"source": {
"type": "url",
"url": image_url
}
},
{
"type": "text",
"text": question
}
]
}
]
)
return message.content[0].text四、Messages API 完整参数手册 ★★★
4.1 接口基本信息
┌─────────────────────────────────────────────────────────────────────────┐
│ Messages API 接口概览 │
├─────────────────────────────────────────────────────────────────────────┤
│ 接口地址: POST https://api.anthropic.com/v1/messages │
│ │
│ 请求头: │
│ ├── x-api-key: YOUR_API_KEY # ★ Anthropic 使用 x-api-key │
│ ├── anthropic-version: 2023-06-01 # API 版本(必须指定) │
│ ├── Content-Type: application/json │
│ └── anthropic-beta: xxx # 可选,启用 Beta 功能 │
│ │
│ 超时设置: │
│ • Claude 3.7 Sonnet / Claude 4 模型:推荐 60 分钟超时 │
│ • 其他模型:推荐 10-30 分钟超时 │
└─────────────────────────────────────────────────────────────────────────┘SDK 与直接请求对比:
python
# ===== 方式一:使用 SDK(推荐)=====
from anthropic import Anthropic
client = Anthropic() # 自动读取 ANTHROPIC_API_KEY 环境变量
response = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
messages=[{"role": "user", "content": "你好"}]
)
# ===== 方式二:直接 HTTP 请求 =====
import requests
headers = {
"x-api-key": "sk-ant-xxx",
"anthropic-version": "2023-06-01",
"Content-Type": "application/json"
}
payload = {
"model": "claude-sonnet-4-20250514",
"max_tokens": 1024,
"messages": [{"role": "user", "content": "你好"}]
}
response = requests.post(
"https://api.anthropic.com/v1/messages",
headers=headers,
json=payload
)4.2 请求参数详解 ★★★
📋 完整请求参数一览表
| 参数名 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| model | string | ✅ | - | 模型标识符 |
| messages | array | ✅ | - | 对话消息列表 |
| max_tokens | integer | ✅ | - | 最大输出 Token 数 |
| system | string/array | ❌ | - | 系统提示词 |
| temperature | number | ❌ | 1.0 | 随机性控制 (0-1) |
| top_p | number | ❌ | - | 核采样参数 |
| top_k | integer | ❌ | - | Top-K 采样 |
| stop_sequences | array | ❌ | - | 停止序列 |
| stream | boolean | ❌ | false | 是否流式输出 |
| tools | array | ❌ | - | 工具定义列表 |
| tool_choice | object | ❌ | auto | 工具调用策略 |
| thinking | object | ❌ | - | 扩展思考配置 |
| metadata | object | ❌ | - | 请求元数据 |
一、必填参数详解
1. model(模型标识符)★
| 字段 | 说明 |
|---|---|
| 类型 | string |
| 必填 | ✅ 是 |
| 说明 | 指定要使用的 Claude 模型版本 |
可用模型列表(2025年):
| 模型标识符 | 说明 | 特点 |
|---|---|---|
claude-opus-4-20250514 | Claude Opus 4 | 最强大,复杂任务首选 |
claude-sonnet-4-20250514 | Claude Sonnet 4 | 平衡性能与成本 |
claude-3-5-sonnet-20241022 | Claude 3.5 Sonnet | 编程和日常任务 |
claude-3-5-haiku-20241022 | Claude 3.5 Haiku | 快速响应,成本最低 |
claude-3-opus-20240229 | Claude 3 Opus | 旧版高端模型 |
claude-3-sonnet-20240229 | Claude 3 Sonnet | 旧版平衡模型 |
claude-3-haiku-20240307 | Claude 3 Haiku | 旧版快速模型 |
python
# 示例
model = "claude-sonnet-4-20250514"2. messages(消息列表)★★★
| 字段 | 说明 |
|---|---|
| 类型 | array of message objects |
| 必填 | ✅ 是 |
| 说明 | 对话历史,交替包含 user 和 assistant 消息 |
核心规则:
┌─────────────────────────────────────────────────────────────┐
│ messages 核心规则 │
├─────────────────────────────────────────────────────────────┤
│ 1. 只支持两种角色: "user" 和 "assistant" │
│ 2. 第一条消息必须是 "user" 角色 │
│ 3. 消息必须交替出现(user → assistant → user → ...) │
│ 4. 连续相同角色的消息会被自动合并 │
│ 5. 最后一条如果是 "assistant",Claude 会继续补全 │
└─────────────────────────────────────────────────────────────┘Message 对象结构:
| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
| role | string | ✅ | 消息角色:"user" 或 "assistant" |
| content | string 或 array | ✅ | 消息内容 |
content 字段的多种格式:
python
# ===== 格式 1: 简单字符串 =====
{"role": "user", "content": "你好,请介绍一下自己"}
# ===== 格式 2: 内容块数组(支持多模态)=====
{
"role": "user",
"content": [
{"type": "text", "text": "这张图片里有什么?"},
{
"type": "image",
"source": {
"type": "base64",
"media_type": "image/jpeg",
"data": "/9j/4AAQSkZJRgABAQEASABIAAD..."
}
}
]
}
# ===== 格式 3: 工具结果返回 =====
{
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": "toolu_01A09q90qw90lq917835lgs",
"content": "北京今天晴天,温度25°C"
}
]
}内容块类型(Content Block Types):
| type 值 | 说明 | 使用场景 |
|---|---|---|
text | 文本内容 | 普通对话 |
image | 图片内容 | 视觉分析 |
tool_use | 工具调用请求 | Claude 发起工具调用 |
tool_result | 工具执行结果 | 返回工具执行结果给 Claude |
图片内容块详解:
python
{
"type": "image",
"source": {
# 方式 1: Base64 编码
"type": "base64",
"media_type": "image/jpeg", # 支持: image/jpeg, image/png, image/gif, image/webp
"data": "base64编码的图片数据..."
# 方式 2: URL(部分模型支持)
# "type": "url",
# "url": "https://example.com/image.jpg"
}
}多轮对话示例:
python
messages = [
# 第 1 轮
{"role": "user", "content": "你好,我叫小明"},
{"role": "assistant", "content": "你好小明!很高兴认识你。有什么可以帮助你的吗?"},
# 第 2 轮
{"role": "user", "content": "我想学习 Python 编程"},
{"role": "assistant", "content": "Python 是一门非常适合初学者的编程语言..."},
# 第 3 轮(当前问题)
{"role": "user", "content": "能给我推荐一些学习资源吗?"}
]预填充(Prefill)技巧:
python
# 如果最后一条消息是 assistant 角色,Claude 会从该位置继续生成
messages = [
{"role": "user", "content": "用 JSON 格式列出三种水果"},
{"role": "assistant", "content": "{"} # 预填充,强制 JSON 格式开头
]
# Claude 会继续输出: "fruits": ["苹果", "香蕉", "橙子"]}3. max_tokens(最大输出 Token)★
| 字段 | 说明 |
|---|---|
| 类型 | integer |
| 必填 | ✅ 是(Anthropic 必须指定,与 OpenAI 不同) |
| 范围 | 1 ~ 模型最大值 |
| 说明 | 限制 Claude 生成的最大 Token 数量 |
各模型最大输出限制:
| 模型 | 最大输出 Tokens | 上下文窗口 |
|---|---|---|
| Claude Opus 4 | 32,000 | 200K |
| Claude Sonnet 4 | 16,000 | 200K |
| Claude 3.5 Sonnet | 8,192 | 200K |
| Claude 3.5 Haiku | 8,192 | 200K |
python
# 示例:根据任务类型设置合适的 max_tokens
max_tokens_config = {
"简单问答": 500,
"代码生成": 2000,
"长文写作": 4000,
"复杂分析": 8000
}二、可选参数 - 系统提示
system(系统提示词)★★
| 字段 | 说明 |
|---|---|
| 类型 | string 或 array |
| 必填 | ❌ 否 |
| 说明 | 设定 Claude 的角色、行为和背景信息 |
⚠️ 关键区别:Anthropic vs OpenAI
python
# ❌ OpenAI 格式(在 Anthropic 不适用)
messages = [
{"role": "system", "content": "你是助手"}, # ❌ Anthropic 不支持
{"role": "user", "content": "你好"}
]
# ✅ Anthropic 格式
system = "你是助手" # 单独的 system 参数
messages = [
{"role": "user", "content": "你好"}
]system 的两种格式:
python
# 格式 1: 简单字符串
system = "你是一个专业的翻译助手,精通中英双语。请始终用友好的语气回复。"
# 格式 2: 内容块数组(支持缓存控制)
system = [
{
"type": "text",
"text": "你是一个专业的翻译助手。",
"cache_control": {"type": "ephemeral"} # 启用提示缓存
},
{
"type": "text",
"text": "以下是翻译规范文档...(很长的文档内容)"
}
]三、可选参数 - 输出控制类
temperature(温度/随机性)
| 字段 | 说明 |
|---|---|
| 类型 | number |
| 范围 | 0.0 ~ 1.0 |
| 默认值 | 1.0 |
| 说明 | 控制输出的随机性和创造性 |
┌─────────────────────────────────────────────────────────────┐
│ temperature 参数效果对比 │
├─────────────────────────────────────────────────────────────┤
│ │
│ temperature=0.0 ───────────────────────── temperature=1.0 │
│ │ │ │
│ 确定性高 随机性高 │
│ 输出一致 输出多样 │
│ │
│ 推荐场景: │
│ • 0.0-0.3: 代码生成、数据提取、事实问答 │
│ • 0.4-0.7: 通用对话、翻译、总结 │
│ • 0.8-1.0: 创意写作、头脑风暴、故事创作 │
│ │
└─────────────────────────────────────────────────────────────┘top_p(核采样)
| 字段 | 说明 |
|---|---|
| 类型 | number |
| 范围 | 0.0 ~ 1.0 |
| 说明 | 仅从累积概率达到 top_p 的 token 中采样 |
python
# top_p=0.9 表示只考虑累积概率前 90% 的 token
# 建议:temperature 和 top_p 只调整其中一个,不要同时修改top_k(Top-K 采样)
| 字段 | 说明 |
|---|---|
| 类型 | integer |
| 范围 | 正整数 |
| 说明 | 仅从概率最高的 K 个 token 中采样 |
python
# top_k=50 表示只考虑概率最高的 50 个 tokenstop_sequences(停止序列)
| 字段 | 说明 |
|---|---|
| 类型 | array of strings |
| 最大数量 | 4 个 |
| 说明 | 当生成的文本包含任一停止序列时,立即停止生成 |
python
# 示例:生成 JSON 时,遇到 } 就停止
stop_sequences = ["}", "\n\n"]
# 示例:代码生成时,遇到函数结束就停止
stop_sequences = ["\ndef ", "\nclass ", "```"]四、可选参数 - 流式输出
stream(流式输出开关)
| 字段 | 说明 |
|---|---|
| 类型 | boolean |
| 默认值 | false |
| 说明 | 是否启用 Server-Sent Events (SSE) 流式输出 |
python
# 非流式(等待完整响应)
response = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
messages=[{"role": "user", "content": "你好"}],
stream=False # 默认值
)
# 流式(实时返回)
with client.messages.stream(
model="claude-sonnet-4-20250514",
max_tokens=1024,
messages=[{"role": "user", "content": "你好"}]
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)五、可选参数 - 工具调用类 ★★
tools(工具定义列表)
| 字段 | 说明 |
|---|---|
| 类型 | array of tool objects |
| 说明 | 定义 Claude 可以调用的工具/函数 |
Tool 对象结构:
| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
| name | string | ✅ | 工具名称(唯一标识) |
| description | string | ✅ | 工具功能描述 |
| input_schema | object | ✅ | 输入参数的 JSON Schema |
⚠️ 关键区别:Anthropic vs OpenAI
python
# ❌ OpenAI 格式
tools = [{
"type": "function",
"function": {
"name": "get_weather",
"description": "获取天气",
"parameters": {...} # OpenAI 使用 parameters
}
}]
# ✅ Anthropic 格式
tools = [{
"name": "get_weather", # 直接定义,无需包装
"description": "获取天气",
"input_schema": {...} # ★ 使用 input_schema
}]完整工具定义示例:
python
tools = [
{
"name": "get_weather",
"description": "获取指定城市的实时天气信息,包括温度、湿度、天气状况等",
"input_schema": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名称,如:北京、上海、广州"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "温度单位,默认摄氏度"
}
},
"required": ["city"]
}
},
{
"name": "search_web",
"description": "搜索互联网获取最新信息",
"input_schema": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "搜索关键词"
},
"max_results": {
"type": "integer",
"description": "最大返回结果数",
"default": 5
}
},
"required": ["query"]
}
}
]tool_choice(工具调用策略)
| 字段 | 说明 |
|---|---|
| 类型 | object |
| 默认值 | {"type": "auto"} |
| 说明 | 控制 Claude 何时以及如何调用工具 |
可选值:
| tool_choice 值 | 说明 |
|---|---|
{"type": "auto"} | Claude 自动决定是否调用工具(默认) |
{"type": "any"} | 必须调用工具列表中的某一个 |
{"type": "tool", "name": "xxx"} | 强制调用指定的工具 |
{"type": "none"} | 禁止调用任何工具(Beta) |
python
# 示例:强制调用特定工具
response = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
tools=tools,
tool_choice={"type": "tool", "name": "get_weather"}, # 强制调用 get_weather
messages=[{"role": "user", "content": "北京天气怎么样?"}]
)六、可选参数 - 高级功能类
thinking(扩展思考)
| 字段 | 说明 |
|---|---|
| 类型 | object |
| 支持模型 | Claude 3.5 Sonnet 及以上 |
| 说明 | 启用后 Claude 会显示推理过程 |
python
thinking = {
"type": "enabled",
"budget_tokens": 2048 # 思考过程的最大 token 数(最小 1024)
}
response = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=4096,
thinking=thinking,
messages=[{"role": "user", "content": "计算 123 × 456 的结果,并解释计算过程"}]
)metadata(请求元数据)
| 字段 | 说明 |
|---|---|
| 类型 | object |
| 说明 | 请求的附加元数据,用于跟踪和日志 |
python
metadata = {
"user_id": "user_123" # 终端用户标识,用于监控和滥用检测
}📝 完整请求示例
python
"""
Anthropic Messages API 完整请求示例
包含所有主要参数的使用
"""
from anthropic import Anthropic
client = Anthropic()
response = client.messages.create(
# ===== 必填参数 =====
model="claude-sonnet-4-20250514",
max_tokens=2048,
messages=[
{"role": "user", "content": "请帮我分析这段代码的问题"},
{"role": "assistant", "content": "好的,请提供代码内容。"},
{"role": "user", "content": "def add(a, b): return a + b"}
],
# ===== 系统提示 =====
system="你是一个资深的代码审查专家,擅长发现代码中的问题和改进点。",
# ===== 输出控制 =====
temperature=0.3, # 低温度,更确定的输出
# top_p=0.9, # 二选一
stop_sequences=["\n\n---"],
# ===== 工具调用 =====
tools=[
{
"name": "run_code",
"description": "执行 Python 代码并返回结果",
"input_schema": {
"type": "object",
"properties": {
"code": {"type": "string", "description": "要执行的代码"}
},
"required": ["code"]
}
}
],
tool_choice={"type": "auto"},
# ===== 元数据 =====
metadata={"user_id": "developer_001"}
)
print(response.content[0].text)4.3 响应参数详解 ★★★
📋 完整响应结构
python
{
"id": "msg_01XFDUDYJgAACzvnptvVoYEL",
"type": "message",
"role": "assistant",
"model": "claude-sonnet-4-20250514",
"content": [
{
"type": "text",
"text": "Claude 的回复内容..."
}
],
"stop_reason": "end_turn",
"stop_sequence": null,
"usage": {
"input_tokens": 25,
"output_tokens": 150,
"cache_creation_input_tokens": 0,
"cache_read_input_tokens": 0
}
}响应字段详解
| 字段 | 类型 | 说明 |
|---|---|---|
| id | string | 消息的唯一标识符,格式:msg_xxxxxx |
| type | string | 对象类型,固定为 "message" |
| role | string | 响应角色,固定为 "assistant" |
| model | string | 实际使用的模型版本 |
| content | array | 内容块数组(核心字段) |
| stop_reason | string | 生成停止的原因 |
| stop_sequence | string/null | 触发停止的具体序列 |
| usage | object | Token 使用统计 |
content 数组详解 ★★
content 是一个数组,可能包含多种类型的内容块:
1. TextBlock(文本块)
python
{
"type": "text",
"text": "Claude 的文本回复内容..."
}| 属性 | 类型 | 说明 |
|---|---|---|
| type | string | 固定为 "text" |
| text | string | 文本内容 |
2. ToolUseBlock(工具调用块)★
当 Claude 决定调用工具时返回:
python
{
"type": "tool_use",
"id": "toolu_01A09q90qw90lq917835lgs",
"name": "get_weather",
"input": {
"city": "北京",
"unit": "celsius"
}
}| 属性 | 类型 | 说明 |
|---|---|---|
| type | string | 固定为 "tool_use" |
| id | string | 工具调用的唯一 ID(返回结果时需要) |
| name | string | 被调用的工具名称 |
| input | object | 工具的输入参数 |
3. ThinkingBlock(思考块)
启用 thinking 参数时返回:
python
{
"type": "thinking",
"thinking": "让我一步步分析这个问题...\n首先,..."
}| 属性 | 类型 | 说明 |
|---|---|---|
| type | string | 固定为 "thinking" |
| thinking | string | Claude 的推理过程文本 |
4. RedactedThinkingBlock(已编辑的思考块)
某些情况下思考内容可能被编辑:
python
{
"type": "redacted_thinking",
"data": "[Thinking content redacted]"
}stop_reason 取值说明 ★
| 值 | 说明 | 后续处理 |
|---|---|---|
| end_turn | Claude 自然结束,认为回复完整 | 直接使用回复 |
| max_tokens | 达到 max_tokens 限制被截断 | 增加 max_tokens 或分段请求 |
| stop_sequence | 遇到 stop_sequences 中的序列 | 根据业务逻辑处理 |
| tool_use | Claude 请求调用工具 | 执行工具,返回结果,继续对话 |
| end_turn (with tool_use) | 多工具调用完成 | 检查 content 中的所有 tool_use |
判断逻辑示例:
python
if response.stop_reason == "end_turn":
# 正常结束,获取文本
text = response.content[0].text
elif response.stop_reason == "tool_use":
# 需要执行工具
for block in response.content:
if block.type == "tool_use":
tool_name = block.name
tool_input = block.input
tool_id = block.id
# 执行工具并返回结果...
elif response.stop_reason == "max_tokens":
# 被截断,可能需要继续请求
print("警告:回复被截断,考虑增加 max_tokens")usage 对象详解
| 字段 | 类型 | 说明 |
|---|---|---|
| input_tokens | integer | 输入(prompt + history)消耗的 Token |
| output_tokens | integer | 输出(生成内容)消耗的 Token |
| cache_creation_input_tokens | integer | 创建缓存使用的 Token(启用缓存时) |
| cache_read_input_tokens | integer | 从缓存读取的 Token(命中缓存时) |
费用计算公式:
费用 = input_tokens × 输入单价 + output_tokens × 输出单价
# 示例(Claude Sonnet 4):
# 输入:$3 / 1M tokens = $0.000003 / token
# 输出:$15 / 1M tokens = $0.000015 / token
input_tokens = 1000
output_tokens = 500
cost = 1000 × 0.000003 + 500 × 0.000015 = $0.01054.4 流式响应详解 ★★★
当 stream=true 时,响应以 Server-Sent Events (SSE) 格式返回。
SSE 格式说明
┌─────────────────────────────────────────────────────────────┐
│ Server-Sent Events (SSE) 格式 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 每个事件由两行组成: │
│ event: <事件类型> │
│ data: <JSON 数据> │
│ │
│ 事件之间用空行分隔 │
│ │
│ ⚠️ 与 OpenAI 不同:Anthropic 没有 "data: [DONE]" 结束标记 │
│ 而是通过 message_stop 事件表示结束 │
│ │
└─────────────────────────────────────────────────────────────┘事件类型详解
| 事件类型 | 说明 | 携带数据 |
|---|---|---|
message_start | 消息开始 | 完整 message 对象(不含 content) |
content_block_start | 内容块开始 | index + content_block 初始结构 |
content_block_delta | 内容块增量 | index + delta 增量数据 |
content_block_stop | 内容块结束 | index |
message_delta | 消息增量 | stop_reason + usage |
message_stop | 消息结束 | 无 |
ping | 心跳 | 用于保持连接 |
error | 错误 | 错误信息 |
各事件结构详解
1. message_start 事件
json
{
"type": "message_start",
"message": {
"id": "msg_01XFDUDYJgAACzvnptvVoYEL",
"type": "message",
"role": "assistant",
"content": [],
"model": "claude-sonnet-4-20250514",
"stop_reason": null,
"stop_sequence": null,
"usage": {
"input_tokens": 25,
"output_tokens": 1
}
}
}2. content_block_start 事件
文本块开始:
json
{
"type": "content_block_start",
"index": 0,
"content_block": {
"type": "text",
"text": ""
}
}工具调用块开始:
json
{
"type": "content_block_start",
"index": 0,
"content_block": {
"type": "tool_use",
"id": "toolu_01A09q90qw90lq917835lgs",
"name": "get_weather",
"input": {}
}
}思考块开始:
json
{
"type": "content_block_start",
"index": 0,
"content_block": {
"type": "thinking",
"thinking": ""
}
}3. content_block_delta 事件
文本增量:
json
{
"type": "content_block_delta",
"index": 0,
"delta": {
"type": "text_delta",
"text": "你好"
}
}工具输入增量(流式传输工具参数):
json
{
"type": "content_block_delta",
"index": 0,
"delta": {
"type": "input_json_delta",
"partial_json": "{\"city\":"
}
}思考内容增量:
json
{
"type": "content_block_delta",
"index": 0,
"delta": {
"type": "thinking_delta",
"thinking": "让我分析一下..."
}
}4. content_block_stop 事件
json
{
"type": "content_block_stop",
"index": 0
}5. message_delta 事件
json
{
"type": "message_delta",
"delta": {
"stop_reason": "end_turn",
"stop_sequence": null
},
"usage": {
"output_tokens": 150
}
}6. message_stop 事件
json
{
"type": "message_stop"
}7. error 事件
json
{
"type": "error",
"error": {
"type": "overloaded_error",
"message": "Overloaded"
}
}流式响应完整示例
event: message_start
data: {"type":"message_start","message":{"id":"msg_xxx","type":"message","role":"assistant","content":[],"model":"claude-sonnet-4-20250514","stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":25,"output_tokens":1}}}
event: content_block_start
data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}}
event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"你"}}
event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"好"}}
event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"!"}}
event: content_block_stop
data: {"type":"content_block_stop","index":0}
event: message_delta
data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"output_tokens":5}}
event: message_stop
data: {"type":"message_stop"}流式工具调用示例
当 Claude 调用工具时,流式响应的结构:
event: message_start
data: {"type":"message_start","message":{...}}
event: content_block_start
data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}}
event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"我来帮你查询北京的天气。"}}
event: content_block_stop
data: {"type":"content_block_stop","index":0}
event: content_block_start
data: {"type":"content_block_start","index":1,"content_block":{"type":"tool_use","id":"toolu_xxx","name":"get_weather","input":{}}}
event: content_block_delta
data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"{\"city\":"}}
event: content_block_delta
data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"\"北京\"}"}}
event: content_block_stop
data: {"type":"content_block_stop","index":1}
event: message_delta
data: {"type":"message_delta","delta":{"stop_reason":"tool_use","stop_sequence":null},"usage":{"output_tokens":50}}
event: message_stop
data: {"type":"message_stop"}delta 类型汇总
| delta.type | 说明 | 对应内容块 |
|---|---|---|
text_delta | 文本增量 | TextBlock |
input_json_delta | 工具输入 JSON 增量 | ToolUseBlock |
thinking_delta | 思考内容增量 | ThinkingBlock |
完整流式处理代码(SDK 版本)
python
"""
使用 Anthropic SDK 处理流式响应
"""
from anthropic import Anthropic
def stream_with_sdk(user_message: str):
"""使用 SDK 的流式对话"""
client = Anthropic()
# 方式 1: 简单的文本流
print("方式1 - 文本流:")
with client.messages.stream(
model="claude-sonnet-4-20250514",
max_tokens=1024,
messages=[{"role": "user", "content": user_message}]
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)
print("\n")
# 方式 2: 处理完整事件
print("方式2 - 完整事件:")
with client.messages.stream(
model="claude-sonnet-4-20250514",
max_tokens=1024,
messages=[{"role": "user", "content": user_message}]
) as stream:
for event in stream:
print(f"事件类型: {event.type}")
if event.type == "content_block_delta":
if hasattr(event.delta, "text"):
print(f" 文本: {event.delta.text}")
elif event.type == "message_delta":
print(f" 停止原因: {event.delta.stop_reason}")
# 方式 3: 获取最终完整消息
print("\n方式3 - 最终消息:")
with client.messages.stream(
model="claude-sonnet-4-20250514",
max_tokens=1024,
messages=[{"role": "user", "content": user_message}]
) as stream:
# 消费流并获取最终消息
response = stream.get_final_message()
print(f"完整回复: {response.content[0].text}")
print(f"Token 使用: {response.usage}")
if __name__ == "__main__":
stream_with_sdk("用一句话介绍人工智能")完整流式处理代码(HTTP 版本)
python
"""
完整的流式响应处理示例
使用 httpx 直接调用 API
"""
import json
import httpx
def stream_chat(user_message: str, api_key: str):
"""流式对话,手动解析 SSE"""
url = "https://api.anthropic.com/v1/messages"
headers = {
"x-api-key": api_key,
"anthropic-version": "2023-06-01",
"Content-Type": "application/json"
}
payload = {
"model": "claude-sonnet-4-20250514",
"max_tokens": 1024,
"stream": True,
"messages": [
{"role": "user", "content": user_message}
]
}
# 用于收集完整响应
content = ""
tool_uses = {}
current_tool_id = None
current_tool_name = None
current_tool_input = ""
with httpx.Client(timeout=60.0) as client:
with client.stream('POST', url, headers=headers, json=payload) as response:
if response.status_code != 200:
print(f"Error: {response.read().decode()}")
return
for line in response.iter_lines():
if not line:
continue
# 解析 SSE 格式
if line.startswith("event:"):
event_type = line[6:].strip()
continue
if line.startswith("data:"):
data_str = line[5:].strip()
try:
event = json.loads(data_str)
except json.JSONDecodeError:
continue
event_type = event.get("type")
# 处理不同事件类型
if event_type == "content_block_start":
block = event.get("content_block", {})
if block.get("type") == "tool_use":
current_tool_id = block.get("id")
current_tool_name = block.get("name")
current_tool_input = ""
print(f"\n[工具调用开始] {current_tool_name}")
elif block.get("type") == "text":
print("\n[文本开始] ", end="")
elif event_type == "content_block_delta":
delta = event.get("delta", {})
delta_type = delta.get("type")
if delta_type == "text_delta":
text = delta.get("text", "")
content += text
print(text, end="", flush=True)
elif delta_type == "input_json_delta":
partial = delta.get("partial_json", "")
current_tool_input += partial
elif event_type == "content_block_stop":
if current_tool_id:
tool_uses[current_tool_id] = {
"name": current_tool_name,
"input": current_tool_input
}
print(f"\n[工具参数] {current_tool_input}")
current_tool_id = None
elif event_type == "message_delta":
delta = event.get("delta", {})
stop_reason = delta.get("stop_reason")
if stop_reason:
print(f"\n\n[停止原因] {stop_reason}")
usage = event.get("usage", {})
if usage:
print(f"[输出 Token] {usage.get('output_tokens', 0)}")
elif event_type == "message_stop":
print("[消息结束]")
return {"content": content, "tool_uses": tool_uses}
if __name__ == "__main__":
result = stream_chat("你好,请介绍一下自己", "sk-ant-xxx")五、避坑指南
5.1 常见错误及解决
错误 1:缺少 max_tokens
python
# ❌ 错误:没有指定 max_tokens(Anthropic 必须指定)
message = client.messages.create(
model="claude-sonnet-4-20250514",
messages=[{"role": "user", "content": "你好"}]
)
# ✅ 正确
message = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024, # ★ 必须指定
messages=[{"role": "user", "content": "你好"}]
)错误 2:在 messages 中使用 system 角色
python
# ❌ 错误:Anthropic 不支持 messages 中的 system 角色
messages = [
{"role": "system", "content": "你是助手"}, # ❌ 会报错
{"role": "user", "content": "你好"}
]
# ✅ 正确:使用单独的 system 参数
message = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
system="你是助手", # ✅ 单独参数
messages=[
{"role": "user", "content": "你好"}
]
)错误 3:messages 第一条不是 user
python
# ❌ 错误:第一条消息必须是 user
messages = [
{"role": "assistant", "content": "我是助手"}, # ❌ 不能以 assistant 开头
{"role": "user", "content": "你好"}
]
# ✅ 正确:必须以 user 开头
messages = [
{"role": "user", "content": "你好"},
{"role": "assistant", "content": "你好!有什么可以帮你的?"},
{"role": "user", "content": "介绍一下自己"}
]错误 4:工具定义格式错误
python
# ❌ 错误:使用 OpenAI 的工具格式
tools = [{
"type": "function",
"function": {
"name": "get_weather",
"parameters": {...}
}
}]
# ✅ 正确:使用 Anthropic 的工具格式
tools = [{
"name": "get_weather",
"description": "获取天气",
"input_schema": {...} # 使用 input_schema
}]错误 5:认证头错误
python
# ❌ 错误:使用 OpenAI 风格的认证头
headers = {
"Authorization": "Bearer sk-ant-xxx" # ❌ Anthropic 不使用这种格式
}
# ✅ 正确:使用 x-api-key
headers = {
"x-api-key": "sk-ant-xxx",
"anthropic-version": "2023-06-01"
}5.2 API Key 安全
python
# ❌ 错误:硬编码 Key
client = Anthropic(api_key="sk-ant-xxx")
# ✅ 正确:使用环境变量
import os
client = Anthropic() # 自动读取 ANTHROPIC_API_KEY
# 或
client = Anthropic(api_key=os.getenv("ANTHROPIC_API_KEY"))六、速记清单
🚀 30秒速记
Anthropic Claude API 核心要点
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1. 必填参数(3个)
├── model: 模型名称
├── messages: 对话内容(只有 user/assistant)
└── max_tokens: 最大输出长度 ★ 必须指定 ★
2. System 提示
└── 单独的 system 参数,不在 messages 里
3. 工具调用
├── 使用 input_schema(不是 parameters)
└── 无需 type: "function" 包装
4. 认证方式
└── x-api-key 头(不是 Bearer token)
5. 流式响应
└── 通过事件类型判断(无 [DONE] 标记)📋 API 参数速查
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
model | string | ✅ | 模型名称 |
messages | array | ✅ | 对话消息列表 |
max_tokens | int | ✅ | 最大输出 Token 数 |
system | string | ❌ | 系统提示词 |
temperature | float | ❌ | 随机度 0-1 |
stream | bool | ❌ | 是否流式输出 |
tools | array | ❌ | 工具定义列表 |
tool_choice | object | ❌ | 工具调用策略 |
📝 Anthropic vs OpenAI 快速对照
| 功能 | OpenAI | Anthropic |
|---|---|---|
| 系统提示 | messages 中 role: system | 单独 system 参数 |
| max_tokens | 可选 | 必填 |
| 工具参数 | parameters | input_schema |
| 工具包装 | type: function + function: {} | 直接定义 |
| 认证头 | Authorization: Bearer | x-api-key |
| 流式结束 | data: [DONE] | message_stop 事件 |
七、学习资源
📚 官方资源
| 资源 | 链接 | 说明 |
|---|---|---|
| Anthropic 官方文档 | https://docs.anthropic.com | 最权威的参考 |
| API 参考手册 | https://docs.anthropic.com/claude/reference | 详细 API 规范 |
| Cookbook 示例 | https://github.com/anthropics/anthropic-cookbook | 实战代码集 |
| Claude 控制台 | https://console.anthropic.com | 在线管理和测试 |
📖 学习路径
入门(1-2天)
├── 1. 注册账号,获取 API Key
├── 2. 运行最小代码示例
└── 3. 实现简单对话
进阶(3-7天)
├── 1. 理解流式输出
├── 2. 掌握工具调用(Tool Use)
├── 3. 学习视觉能力
└── 4. 了解扩展思考
高级(1-2周)
├── 1. 构建复杂的 Agent
├── 2. 优化性能和成本
├── 3. 实现缓存和批处理
└── 4. 生产环境部署附录:完整代码模板
🔧 通用对话模板
python
"""
Anthropic Claude API 通用对话模板
可以直接复制使用
"""
import os
from anthropic import Anthropic
def create_client() -> Anthropic:
"""创建 Claude 客户端"""
if not os.getenv("ANTHROPIC_API_KEY"):
raise ValueError(
"请设置 ANTHROPIC_API_KEY 环境变量\n"
"Linux/Mac: export ANTHROPIC_API_KEY='sk-ant-xxx'\n"
"Windows: set ANTHROPIC_API_KEY=sk-ant-xxx"
)
return Anthropic()
def chat(
client: Anthropic,
messages: list,
model: str = "claude-sonnet-4-20250514",
max_tokens: int = 1024,
system: str = None,
**kwargs
) -> str:
"""
发送聊天请求
参数:
client: Anthropic 客户端
messages: 消息列表
model: 模型名称
max_tokens: 最大输出 Token
system: 系统提示词
**kwargs: 其他参数(temperature, tools 等)
"""
params = {
"model": model,
"max_tokens": max_tokens,
"messages": messages,
**kwargs
}
if system:
params["system"] = system
response = client.messages.create(**params)
return response.content[0].text
if __name__ == "__main__":
client = create_client()
messages = [
{"role": "user", "content": "你好!"}
]
reply = chat(client, messages, system="你是一个有帮助的助手。")
print(reply)🔧 流式对话模板
python
"""
Anthropic Claude API 流式对话模板
"""
from anthropic import Anthropic
def stream_chat(user_message: str, system: str = None):
"""流式对话"""
client = Anthropic()
params = {
"model": "claude-sonnet-4-20250514",
"max_tokens": 1024,
"messages": [{"role": "user", "content": user_message}]
}
if system:
params["system"] = system
with client.messages.stream(**params) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)
print()
if __name__ == "__main__":
stream_chat("讲一个简短的笑话", system="你是一个幽默的助手")🔧 带工具调用的完整模板
python
"""
Anthropic Claude API 工具调用完整模板
"""
import json
from anthropic import Anthropic
def chat_with_tools(
user_message: str,
tools: list,
tool_executor: callable,
system: str = None,
max_turns: int = 10
) -> str:
"""
带工具调用的对话
参数:
user_message: 用户消息
tools: 工具定义列表
tool_executor: 工具执行函数 (name, input) -> result
system: 系统提示词
max_turns: 最大对话轮数
"""
client = Anthropic()
messages = [{"role": "user", "content": user_message}]
for _ in range(max_turns):
params = {
"model": "claude-sonnet-4-20250514",
"max_tokens": 4096,
"tools": tools,
"messages": messages
}
if system:
params["system"] = system
response = client.messages.create(**params)
# 如果不需要调用工具,返回结果
if response.stop_reason != "tool_use":
return "".join(
block.text for block in response.content
if hasattr(block, "text")
)
# 处理工具调用
tool_results = []
for block in response.content:
if block.type == "tool_use":
result = tool_executor(block.name, block.input)
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": str(result)
})
# 添加 assistant 消息和工具结果
messages.append({"role": "assistant", "content": response.content})
messages.append({"role": "user", "content": tool_results})
return "达到最大对话轮数限制"
# 使用示例
if __name__ == "__main__":
tools = [{
"name": "calculate",
"description": "执行数学计算",
"input_schema": {
"type": "object",
"properties": {
"expression": {"type": "string", "description": "数学表达式"}
},
"required": ["expression"]
}
}]
def executor(name, input_data):
if name == "calculate":
return eval(input_data["expression"])
return "未知工具"
result = chat_with_tools(
"计算 (123 + 456) * 789 的结果",
tools,
executor
)
print(result)📝 文档版本:v1.0
📅 更新日期:2025年2月
🔗 参考来源:https://docs.anthropic.com/
补充1
Anthropic 流式响应(SSE)的本质是:按「内容块」拆分,每个内容块遵循「启动→增量更新→结束」的生命周期,不同类型的内容块(文本/工具调用/图片)对应不同的载体字段。
一、流式响应的基础格式规则
1. 传输层格式(SSE 通用规则)
所有响应行都遵循:
text
data: <JSON字符串> # 核心数据行
# 空行分隔不同事件(可选)
data: [DONE] # 整个流式响应结束的标识(最后一行)- 必须过滤空行、非
data:开头的行; - 解析时需先去掉前缀
data:,再将剩余字符串转为 JSON; [DONE]是传输层结束标识,无 JSON 结构,仅用于关闭流。
2. 数据层核心字段(所有 JSON 都包含)
| 字段名 | 必选/可选 | 含义 | 取值范围 |
|---|---|---|---|
type | 必选 | 事件类型(核心分类) | content_block_start/content_block_delta/content_block_end/message_stop/error |
index | 必选(除message_stop/error) | 内容块的序号(从0开始) | 整数,如0、1、2 |
二、三大核心事件类型的详细规则
Anthropic 把流式响应拆分为「内容块启动→内容块增量→内容块结束→全局结束」四个阶段,前三个阶段针对单个内容块,最后一个是全局收尾。
1. 阶段1:content_block_start(内容块启动)
- 作用:宣告「一个新的内容块开始生成」,携带该内容块的完整初始属性(如类型、工具调用ID等);
- 格式固定规则:json
{ "type": "content_block_start", "content_block": { // 该内容块的完整初始属性(核心载体) "type": "<内容块类型>", // text/tool_use/image(核心) // 以下字段根据content_block.type不同而变化 "text": "<初始文本>" | "", // type=text时,通常为空(文本在delta阶段返回) "id": "<工具调用ID>", // type=tool_use时必选 "name": "<工具名>", // type=tool_use时必选 "input": {<工具参数>}, // type=tool_use时必选 "source": {<图片源信息>} // type=image时必选 }, "index": <整数> // 内容块序号 } - 关键特点:
content_block是这个阶段的唯一内容载体;- 无论内容块是文本/工具调用/图片,启动阶段都会一次性返回该内容块的「静态属性」(如工具调用的名称、参数,图片的源信息);
- 文本类型的内容块,
content_block.text通常为空(文本内容在delta阶段逐字返回)。
2. 阶段2:content_block_delta(内容块增量)
- 作用:向已启动的内容块「追加增量内容」(如文本逐字返回、图片细节补充);
- 格式固定规则:json
{ "type": "content_block_delta", "delta": { // 增量内容载体(核心) "type": "<增量类型>", // text_delta/tool_use_delta/image_delta // 以下字段根据delta.type不同而变化 "text": "<新增文本片段>", // type=text_delta时必选(如"北京的天气是") "input": {<新增工具参数>} // type=tool_use_delta时可选(极少用) }, "index": <整数> // 与启动阶段的index一致,标识属于哪个内容块 } - 关键特点:
delta是这个阶段的唯一内容载体;- 仅「可增量更新」的内容块会有这个阶段(文本最常见,工具调用几乎没有,图片极少);
- 文本增量是逐字/逐词返回的,需拼接所有
delta.text得到完整文本。
3. 阶段3:content_block_end(内容块结束)
- 作用:宣告「某个内容块的生成已完成」,无额外内容,仅做标识;
- 格式固定规则:json
{ "type": "content_block_end", "index": <整数> // 与启动/增量阶段的index一致 } - 关键特点:无内容载体字段(无content_block/delta),仅标识结束。
4. 全局收尾:message_stop(整个响应结束)
- 作用:所有内容块都生成完成后,返回全局统计信息(如token消耗);
- 格式固定规则:json
{ "type": "message_stop", "stop_reason": "<结束原因>", // end_turn/tool_use/max_tokens等 "usage": { // 必选,token消耗统计 "input_tokens": <整数>, "output_tokens": <整数> } } - 关键特点:无index字段,是整个响应的最后一个有效JSON行(之后是
data: [DONE])。
5. 异常场景:error(错误返回)
- 作用:请求/响应过程中出现错误时返回;
- 格式固定规则:json
{ "type": "error", "error": { "type": "<错误类型>", // invalid_request/rate_limit等 "message": "<错误描述>" } }
三、不同类型内容块的完整流程示例
示例1:纯文本内容块(最常见)
text
# 启动:宣告文本内容块开始(index=0)
data: {"type":"content_block_start","content_block":{"type":"text","text":""},"index":0}
# 增量1:追加文本片段(index=0)
data: {"type":"content_block_delta","delta":{"type":"text_delta","text":"你好,"}, "index":0}
# 增量2:继续追加(index=0)
data: {"type":"content_block_delta","delta":{"type":"text_delta","text":"我是Claude。"}, "index":0}
# 结束:文本内容块完成(index=0)
data: {"type":"content_block_end","index":0}
# 全局结束:返回统计信息
data: {"type":"message_stop","stop_reason":"end_turn","usage":{"input_tokens":10,"output_tokens":8}}
# 传输层结束
data: [DONE]- 拼接所有
delta.text得到完整文本:你好,我是Claude。
示例2:工具调用内容块(无增量)
text
# 启动:宣告工具调用内容块开始(index=1)
data: {"type":"content_block_start","content_block":{"type":"tool_use","id":"toolu_012345","name":"get_weather","input":{"city":"北京"}},"index":1}
# 结束:工具调用内容块完成(无增量阶段)
data: {"type":"content_block_end","index":1}
# 全局结束
data: {"type":"message_stop","stop_reason":"tool_use","usage":{"input_tokens":50,"output_tokens":20}}
data: [DONE]- 工具调用内容块几乎没有delta阶段,所有信息都在
content_block_start的content_block里; stop_reason为tool_use,表示响应因触发工具调用而暂停,需你返回工具结果后继续。
示例3:混合内容块(文本+工具调用)
text
# 第一个内容块:文本(思考过程)
data: {"type":"content_block_start","content_block":{"type":"text","text":""},"index":0}
data: {"type":"content_block_delta","delta":{"type":"text_delta","text":"我需要调用天气工具查询北京的天气。"},"index":0}
data: {"type":"content_block_end","index":0}
# 第二个内容块:工具调用
data: {"type":"content_block_start","content_block":{"type":"tool_use","id":"toolu_012345","name":"get_weather","input":{"city":"北京"}},"index":1}
data: {"type":"content_block_end","index":1}
# 全局结束
data: {"type":"message_stop","stop_reason":"tool_use","usage":{"input_tokens":60,"output_tokens":30}}
data: [DONE]四、核心规则总结(避坑关键)
1. 内容块与生命周期的对应规则
| 内容块类型 | 是否有start阶段 | 是否有delta阶段 | 是否有end阶段 |
|---|---|---|---|
| text(文本) | 必选 | 必选(逐字返回) | 必选 |
| tool_use(工具调用) | 必选 | 几乎无(参数固定) | 必选 |
| image(图片) | 必选 | 极少(仅细节补充) | 必选 |
2. 载体字段的对应规则
| 事件类型 | 核心载体字段 | 用途 |
|---|---|---|
| content_block_start | content_block | 存储内容块的初始/完整属性 |
| content_block_delta | delta | 存储内容块的增量内容 |
| content_block_end | 无 | 仅标识结束 |
| message_stop | usage/stop_reason | 全局统计与结束原因 |
3. 解析逻辑的核心步骤
- 逐行读取SSE响应,过滤空行和非
data:开头的行; - 去掉
data:前缀,若剩余内容是[DONE]则停止解析; - 解析JSON,根据
type字段分阶段处理:content_block_start:记录index和content_block的属性(如工具调用的名称/参数);content_block_delta:根据index拼接delta.text(文本);content_block_end:标记对应index的内容块完成;message_stop:记录token消耗,准备关闭流;
- 同一
index的start→delta→end属于同一个内容块,需关联处理。
总结
- Anthropic 流式响应的核心是「按内容块拆分,每个内容块走启动-增量-结束流程」;
content_block_start用content_block存初始属性,content_block_delta用delta存增量内容,是两类不同阶段的载体;- 文本内容块重点拼接
delta.text,工具调用内容块重点提取content_block_start里的name和input。