API 基础教程 共 6 章 · Anthropic 官方课程中文精译
原文 GitHub →
第 1 章

Getting Started with the Claude SDK

本章介绍如何安装 Anthropic SDK、获取 API Key 并发送第一条消息。完成本章后,你将拥有一个可运行的 Claude 开发环境。

安装 SDK

Anthropic Python SDK 要求 Python 3.7.1 或更高版本。可通过以下命令安装:

%pip install anthropic
# 命令行安装:pip install anthropic

获取 API Key

向 Claude API 发送请求需要进行身份验证,你需要一个 API Key。获取步骤:

  1. 访问 console.anthropic.com 注册 Anthropic 账户
  2. 登录后进入 API 设置页面(右上角点击头像)
  3. 点击"Create Key",创建并复制你的 API Key
⚠ 安全提示

不要将 API Key 硬编码到代码中。推荐将其存储在 .env 文件中并通过 python-dotenv 加载:

# .env 文件内容
ANTHROPIC_API_KEY=put-your-api-key-here
# 安装 dotenv 包
%pip install python-dotenv

# 在代码中加载
from dotenv import load_dotenv
import os

load_dotenv()
my_api_key = os.getenv("ANTHROPIC_API_KEY")

发送第一条消息

安装好 SDK 并加载好 API Key 之后,你可以创建 Anthropic 客户端对象并发送第一条消息:

from anthropic import Anthropic

# SDK 会自动查找 ANTHROPIC_API_KEY 环境变量
client = Anthropic()

our_first_message = client.messages.create(
    model="claude-3-haiku-20240307",
    max_tokens=1000,
    messages=[
        {"role": "user", "content": "Hi there! Please write me a haiku about a pet chicken"}
    ]
)

print(our_first_message.content[0].text)
💡 提示

你不需要手动传入 api_key 参数。SDK 会自动从环境变量 ANTHROPIC_API_KEY 中读取,直接 client = Anthropic() 即可。

练习

发送你的第一条消息

新建一个 Python 脚本或 Notebook,完成以下步骤:

  1. 导入所需包
  2. 加载你的 Anthropic API Key
  3. 让 Claude 讲一个笑话,并打印结果

第 2 章

Working with Messages

本章深入讲解 Messages API 格式、响应对象结构,以及如何构建多轮对话聊天机器人。

消息格式

messages 参数是一个消息字典列表,每个字典代表对话中的一条消息。每条消息必须包含以下字段:

response = client.messages.create(
    model="claude-3-haiku-20240307",
    max_tokens=1000,
    messages=[
        {"role": "user", "content": "What flavors are used in Dr. Pepper?"}
    ]
)
print(response)
💡 注意

Messages 格式支持保留完整对话历史,但很多场景不需要多轮历史,每次传入单条用户消息即可。

小测验:每条消息中两个必填的字段是什么?

  • a) "sender" 和 "text"
  • b) "role" 和 "content"
  • c) "user" 和 "assistant"
  • d) "input" 和 "output"
查看答案

正确答案是 b。每条消息必须包含 "role""content"

解析响应对象

API 返回一个 Message 对象,其主要属性如下:

属性说明
content模型生成的内容列表(TextBlock 等)
id唯一标识符
model处理请求的模型名称
stop_reason模型停止生成的原因(end_turn / max_tokens 等)
usageToken 用量统计(input_tokens / output_tokens)
# 获取文本内容
print(response.content[0].text)

# 查看停止原因
print(response.stop_reason)   # 'end_turn' 或 'max_tokens'

# 查看 token 用量
print(response.usage.input_tokens, response.usage.output_tokens)

常见错误

使用 messages 列表时常见的两类错误:

错误 1:以 assistant 消息开头

消息列表必须以 user 消息开头,否则会报错。

错误 2:角色未交替出现

消息列表中 user 和 assistant 的角色必须交替出现,不能连续出现相同角色。

# 错误示例 1:以 assistant 开头
messages=[{"role": "assistant", "content": "Hello!"}]   # ❌

# 错误示例 2:assistant 连续出现
messages=[
    {"role": "user", "content": "Hey!"},
    {"role": "assistant", "content": "Hi!"},
    {"role": "assistant", "content": "How can I help??"}  # ❌
]

预填充(Prefill)

你可以在 messages 中提供 assistant 消息,让 Claude 从该位置继续生成,从而精确控制输出格式,这称为"预填充"(Putting words in Claude's mouth):

response = client.messages.create(
    model="claude-3-haiku-20240307",
    max_tokens=500,
    messages=[
        {"role": "user", "content": "Generate a beautiful haiku"},
        {"role": "assistant", "content": "calming mountain air"}  # 预填充
    ]
)
# 拼接预填充内容
print("calming mountain air" + response.content[0].text)

Few-Shot 提示

对话历史是提供 few-shot 示例最自然的方式。通过提供几个示例对,可以引导 Claude 输出特定格式:

# Few-shot 情感分析示例
response = client.messages.create(
    model="claude-3-haiku-20240307",
    max_tokens=100,
    messages=[
        {"role": "user", "content": "Analyze sentiment: 'I love this!'"},
        {"role": "assistant", "content": "Positive"},
        {"role": "user", "content": "Analyze sentiment: 'This is terrible.'"},
        {"role": "assistant", "content": "Negative"},
        {"role": "user", "content": "Analyze sentiment: 'It's okay, I guess.'"}
    ]
)
print(response.content[0].text)   # 输出: Neutral

构建多轮聊天机器人

多轮对话的核心是维护一个消息列表,每次将用户输入追加到列表中,再把 Claude 的回复也追加进去:

conversation_history = []

def chat(user_message):
    conversation_history.append({"role": "user", "content": user_message})
    response = client.messages.create(
        model="claude-3-haiku-20240307",
        max_tokens=1000,
        messages=conversation_history
    )
    assistant_message = response.content[0].text
    conversation_history.append({"role": "assistant", "content": assistant_message})
    return assistant_message

# 开始聊天
print(chat("Hello! Tell me a fun fact."))
print(chat("Tell me another one related to the first."))
练习

实现 translate 函数

编写一个 translate(word, language) 函数,使用 Claude 将单词翻译到指定语言。函数应只返回翻译后的单词,不含其他内容。


第 3 章

Claude Models

本章介绍 Claude 模型家族,比较各模型的速度与能力,并提供选型建议。

Claude 模型家族

Anthropic 提供多个 Claude 模型,在速度、能力和成本之间有不同的权衡。选择模型时需要考虑三个维度:

参考 官方模型对比表 查看最新模型列表。当前主要模型系列:

模型特点适用场景
Claude 3.5 Sonnet高智能,高速复杂推理、代码生成
Claude 3 Opus最高智能需要最强推理能力的任务
Claude 3 Sonnet平衡性能与成本通用任务
Claude 3 Haiku最快最便宜简单任务、高吞吐场景

速度对比

import time

def compare_model_speeds():
    models = [
        "claude-3-5-sonnet-20240620",
        "claude-3-opus-20240229",
        "claude-3-sonnet-20240229",
        "claude-3-haiku-20240307"
    ]
    task = "Explain the concept of photosynthesis in a concise paragraph."

    for model in models:
        start = time.time()
        response = client.messages.create(
            model=model,
            max_tokens=200,
            messages=[{"role": "user", "content": task}]
        )
        elapsed = time.time() - start
        print(f"{model}: {elapsed:.2f}s | {response.usage.output_tokens} tokens")

compare_model_speeds()

选型建议

💡 推荐策略

从 Haiku 开始:先用最快最便宜的 Haiku 完成原型,建立评估基准;如果 Haiku 无法满足质量要求,再升级到 Sonnet;对极少数需要最强推理的任务,才考虑 Opus。

关键原则:切勿在不测试的情况下就假设"更大的模型一定更好"。很多任务 Haiku 的效果与 Opus 相差无几,而速度快 10 倍以上。

练习

模型对比实验

设计一个对比实验:用相同的提示词分别调用 Haiku 和 Sonnet,比较生成质量与响应时间,并记录 usage.output_tokens


第 4 章

Model Parameters

本章介绍控制模型输出的核心参数:max_tokens、temperature、stop_sequences 和 system prompt。

max_tokens

每次 API 请求都需要三个必填参数:modelmax_tokensmessages

max_tokens 设置 Claude 最多可以生成的 Token 数量上限。需要理解两点:

# max_tokens 设置过低会导致截断
truncated = client.messages.create(
    model="claude-3-haiku-20240307",
    max_tokens=10,
    messages=[{"role": "user", "content": "Write me a poem"}]
)
print(truncated.content[0].text)   # 只有 10 个 token,诗句被截断
print(truncated.stop_reason)       # 'max_tokens'

# 合理的 max_tokens
full = client.messages.create(
    model="claude-3-haiku-20240307",
    max_tokens=500,
    messages=[{"role": "user", "content": "Write me a poem"}]
)
print(full.stop_reason)            # 'end_turn'

什么是 Token?

大型语言模型不以完整词语为单位处理文本,而是以更小的片段(Token)进行思考。大约 1 Token ≈ 0.75 个英文单词,中文每个汉字通常是 1-2 个 Token。

可以使用 Anthropic 的 Token 计数工具 来了解文本的 Token 数量。

Stop Sequences

stop_sequences 是一个字符串列表,当 Claude 生成的内容包含其中任何一个字符串时,会立即停止生成(该字符串本身不会出现在输出中):

response = client.messages.create(
    model="claude-3-haiku-20240307",
    max_tokens=500,
    stop_sequences=["END"],
    messages=[
        {"role": "user", "content": "List 5 colors, then write END."}
    ]
)
print(response.content[0].text)
print(response.stop_reason)   # 'stop_sequence'

Temperature

temperature 参数控制模型输出的随机性,取值范围 01(可延伸到更高):

效果适用场景
0完全确定性,每次输出相同数据提取、分类、代码生成
0.5适度创意(默认值)通用问答、摘要
1.0+高度随机,更有创意创意写作、头脑风暴
# 确定性输出(提取/分类任务)
response = client.messages.create(
    model="claude-3-haiku-20240307",
    max_tokens=200,
    temperature=0,
    messages=[{"role": "user", "content": "Extract the city name from: 'I live in Shanghai'"}]
)

# 创意写作
response = client.messages.create(
    model="claude-3-haiku-20240307",
    max_tokens=500,
    temperature=1.0,
    messages=[{"role": "user", "content": "Write me a creative short story opening"}]
)

System Prompt

System Prompt(系统提示)是一段在对话开始前向 Claude 提供的指令,用于设定 Claude 的角色、约束行为或提供上下文。通过 system 参数传入:

response = client.messages.create(
    model="claude-3-haiku-20240307",
    max_tokens=500,
    system="You are a helpful assistant that always responds in rhyme.",
    messages=[{"role": "user", "content": "What is the capital of France?"}]
)
print(response.content[0].text)
# Claude 会用押韵的方式回答!
💡 System Prompt 最佳实践
  • 用于设定角色和行为约束
  • 可以提供领域知识或工具描述
  • 不需要在每次对话中重复,只需在 system 参数中设置一次
练习

参数实验室

设计一个实验,用相同的创意写作提示词,分别测试 temperature = 0、0.5、1.0 的输出差异,并观察 stop_reason 和 token 用量的变化。


第 5 章

Streaming

本章介绍流式响应(Streaming)的工作原理、事件类型、首 Token 时间(TTFT)以及 SDK 提供的流式辅助工具。

什么是流式响应?

默认情况下,Claude 生成完整响应后才一次性返回。流式响应(Streaming)让你可以在生成过程中实时接收 Token,就像 claude.ai 界面的逐字显示效果一样。

使用流式响应的两大好处:

基础流式请求

使用 client.messages.stream() 作为上下文管理器来启用流式输出:

with client.messages.stream(
    model="claude-3-haiku-20240307",
    max_tokens=1000,
    messages=[{"role": "user", "content": "Tell me a story about a robot."}]
) as stream:
    for text in stream.text_stream:
        print(text, end="", flush=True)
print()  # 换行

流式事件类型

流式 API 会产生多种事件,完整的事件序列如下:

事件类型说明
message_start消息开始,包含 id、model 等元信息
content_block_start内容块开始
content_block_delta文本增量(实际内容)
content_block_stop内容块结束
message_delta消息级别的更新(stop_reason、usage 等)
message_stop消息结束
# 监听所有流式事件
with client.messages.stream(
    model="claude-3-haiku-20240307",
    max_tokens=300,
    messages=[{"role": "user", "content": "Hi!"}]
) as stream:
    for event in stream:
        print(event.type)

首 Token 时间(TTFT)

TTFT(Time to First Token)是从发送请求到收到第一个 Token 的时间,是衡量用户感知延迟的关键指标。流式模式可以让你在 TTFT 后立即开始渲染内容:

import time

start = time.time()
first_token_time = None

with client.messages.stream(
    model="claude-3-haiku-20240307",
    max_tokens=500,
    messages=[{"role": "user", "content": "Write a paragraph about the ocean."}]
) as stream:
    for text in stream.text_stream:
        if first_token_time is None:
            first_token_time = time.time()
            print(f"TTFT: {first_token_time - start:.3f}s")
        print(text, end="", flush=True)

print(f"\nTotal time: {time.time() - start:.3f}s")

流式辅助方法

SDK 的流式管理器提供了多个辅助方法:

# 获取完整消息(等待完成后返回)
with client.messages.stream(...) as stream:
    final_message = stream.get_final_message()
    print(final_message.usage)

# 使用事件处理器
class MyHandler(anthropic.MessageStreamManager):
    def on_text(self, text):
        print(text, end="", flush=True)
    def on_message(self, message):
        print(f"\nUsage: {message.usage}")
练习

实现流式聊天界面

基于上一章的聊天机器人,将其改造为流式版本。要求:逐字输出 Claude 的回复,并在回复完成后显示用时和 token 数量。


第 6 章

Vision Prompting

本章介绍 Claude 的视觉能力,包括如何发送图片、图文混合提示、多图输入及视觉提示技巧。

视觉能力概览

Claude 3 及以上系列模型具备视觉理解能力,支持:

图片内容块格式

发送图片时,需要使用"内容块"(content block)格式,将图片编码为 Base64 并放入消息列表:

import base64

# 读取并编码图片
with open("image.png", "rb") as f:
    binary_data = f.read()

base64_string = base64.standard_b64encode(binary_data).decode("utf-8")

# 构建包含图片的消息
messages = [
    {
        "role": "user",
        "content": [
            {
                "type": "image",
                "source": {
                    "type": "base64",
                    "media_type": "image/png",
                    "data": base64_string,
                },
            }
        ]
    }
]

仅图片提示

可以只发送图片而不附带文字,Claude 会自动描述图片内容:

response = client.messages.create(
    model="claude-3-5-sonnet-20240620",
    max_tokens=1024,
    messages=messages   # 只包含图片块的消息
)
print(response.content[0].text)

图文混合提示

更常见的用法是将图片和文字问题一起发送:

messages = [
    {
        "role": "user",
        "content": [
            {
                "type": "image",
                "source": {
                    "type": "base64",
                    "media_type": "image/png",
                    "data": base64_string,
                },
            },
            {
                "type": "text",
                "text": "What is shown in this image? Please describe it in detail."
            }
        ]
    }
]

response = client.messages.create(
    model="claude-3-5-sonnet-20240620",
    max_tokens=1024,
    messages=messages
)
print(response.content[0].text)

通过 URL 发送图片

除了 Base64,也可以直接传入公开可访问的图片 URL:

messages = [
    {
        "role": "user",
        "content": [
            {
                "type": "image",
                "source": {
                    "type": "url",
                    "url": "https://upload.wikimedia.org/wikipedia/commons/thumb/2/2f/Eiffel_Tower.jpg/400px-Eiffel_Tower.jpg",
                },
            },
            {"type": "text", "text": "What landmark is this?"}
        ]
    }
]

多图输入

在同一条消息中可以包含多个图片块,Claude 可以跨图比较和推理:

# 辅助函数:生成图片内容块
def create_image_block(image_path):
    import mimetypes
    with open(image_path, "rb") as f:
        data = base64.standard_b64encode(f.read()).decode("utf-8")
    media_type = mimetypes.guess_type(image_path)[0] or "image/jpeg"
    return {
        "type": "image",
        "source": {"type": "base64", "media_type": media_type, "data": data}
    }

messages = [
    {
        "role": "user",
        "content": [
            create_image_block("chart1.png"),
            create_image_block("chart2.png"),
            {"type": "text", "text": "Compare these two charts and identify the key differences."}
        ]
    }
]

视觉提示技巧

💡 提高视觉理解准确率
  • 要具体:不要只说"描述这张图",而是"描述图中右上角的内容"
  • 提供示例:用 few-shot 格式给出几个示例图文对,引导 Claude 输出格式
  • 指定格式:明确要求 Claude 以列表、表格或 JSON 格式输出分析结果
练习

构建图片分析助手

编写一个函数 analyze_image(image_path, question),接受一张图片路径和一个问题,使用 Claude 分析图片并回答问题。额外挑战:支持多图比较。