Claude API(Anthropic Messages API)指南
阅读目标:看完这篇后,你应该能独立发起一次 Claude Messages 请求,读懂文本、工具和流式响应,并知道它和 OpenAI Chat Completions / Responses 的差异在哪里。
很多人把“Claude API”理解成另一个 OpenAI 兼容接口。这个理解不够准确。Claude 官方 API 的核心是 Anthropic Messages API,endpoint 通常是 /v1/messages;它使用 x-api-key 认证,输入和输出都由有类型的 content block 组成,工具调用、思考内容和流式事件也遵循 Anthropic 自己的协议。
本文以 Anthropic 官方文档为基准,核对日期为 2026-09-08。模型名称、上下文窗口、价格、速率限制、beta header 和部分参数会变化,生产系统应以目标模型对应的 Messages API Reference 和模型发布说明为准。本文重点服务于 AI 应用、Agent、RAG 和企业 API 网关,不试图逐字段覆盖所有管理接口。
一个小场景:查订单,再决定能不能退款
用户说“帮我把刚才那笔订单退了”。Claude 第一轮只能返回一个 tool_use,说明它想查订单或发起退款;真正执行前,应用还要核对登录用户、订单状态、退款金额和是否需要人工审批。工具执行完后,应用把带有 tool_use_id 的 tool_result 放回下一轮 Messages 请求,Claude 才能告诉用户“已受理”还是“需要补充信息”。这个例子提醒我们:模型负责提出下一步,权限和副作用必须留在服务端。
1. 先看懂 Claude API 的接口地图
Anthropic 的开发接口可以先按“模型交互”和“平台资源”分组。不要把 Messages、Token 计数和批处理当成同一个接口的不同参数。
| 类别 | 代表能力 | 解决什么问题 | 常见应用 |
|---|---|---|---|
| 模型消息 | Messages API | 发送多轮消息并获得文本、工具调用或思考内容 | 对话、问答、Agent、信息抽取 |
| Token 计数 | Token Counting API | 在真正生成前估算输入 token 和上下文大小 | 预算、截断、路由、成本估算 |
| 工具调用 | Messages tools | 让模型请求应用执行函数或外部工具 | 搜索、数据库、订单和代码操作 |
| 批处理 | Message Batches API | 以异步任务处理大量相互独立的消息请求 | 离线分类、批量抽取、评测 |
| 文件与多模态输入 | Messages content blocks、Files 能力(按账户开放情况) | 传入图片、PDF、文档或其他支持的内容 | 文档问答、视觉理解、发票和合同抽取 |
| 模型与用量治理 | Models、Usage、Admin 相关接口 | 查询模型、配额、组织和使用情况 | 多租户治理、审计、成本控制 |
1.1 按场景选能力
| 需求 | 优先考虑 | 说明 |
|---|---|---|
| 普通文本问答或 Agent turn | Messages API | Claude 的主模型交互接口 |
| 需要知道输入是否会超上下文 | Token Counting API + 本地 token 预算 | 计数结果用于路由和截断,不能代替生成请求 |
| 需要模型查询天气、数据库或业务服务 | Messages tools | 模型只产生 tool_use,应用负责授权、执行和回传 |
| 大量相互独立的离线请求 | Message Batches API | 用业务 ID 对齐异步结果,不依赖返回顺序 |
| 需要图片、PDF 或图表理解 | Messages 的 image/document content block | 先确认目标模型和账户是否支持该输入类型 |
| 需要长上下文重复调用 | Prompt Caching | 复用稳定前缀的处理结果,不等于答案缓存 |
| 需要更长的推理过程 | Extended Thinking | 允许模型产生思考预算,但要重新评估延迟、成本和输出解析 |
2. 认证、endpoint 和请求基础
2.1 HTTP 认证
Anthropic API 通常使用以下请求头:
x-api-key: $ANTHROPIC_API_KEY
anthropic-version: 2023-06-01
content-type: application/jsonanthropic-version 是 API 版本 header,不是模型版本。部分新能力还需要官方列出的 anthropic-beta header;不要把网上旧示例中的 beta 值永久写死。API key 只应放在服务端、受控 Worker 或安全 CI 环境,不要打包进浏览器、移动端或可下载的 JavaScript。
最小 curl 请求:
curl https://api.anthropic.com/v1/messages \
--header "x-api-key: $ANTHROPIC_API_KEY" \
--header "anthropic-version: 2023-06-01" \
--header "content-type: application/json" \
--data '{
"model": "your-claude-model",
"max_tokens": 256,
"messages": [
{"role": "user", "content": "用一句话解释什么是 RAG。"}
]
}'示例中的模型名只是占位符。生产配置至少要记录模型、API 版本、区域或 provider、system prompt 版本和工具 schema 版本,便于后续回归。
2.2 Python SDK 最小示例
import anthropic
client = anthropic.Anthropic() # 默认读取 ANTHROPIC_API_KEY
message = client.messages.create(
model="your-claude-model",
max_tokens=256,
messages=[
{"role": "user", "content": "用一句话解释什么是 RAG。"},
],
)
for block in message.content:
if block.type == "text":
print(block.text)SDK 返回的对象通常可以通过属性访问,原始 HTTP 响应则是 JSON。不要只读取一个固定位置就假设所有响应都是文本:工具调用、思考和未来新增 block 都可能出现在 content 中。
2.3 错误类别和 request id
生产调用至少要区分:
| 类别 | 常见原因 | 处理方式 |
|---|---|---|
400 | JSON、角色顺序、参数组合或 content block 不合法 | 修复请求,不要盲目重试 |
401 | API key 无效、缺失或环境配置错误 | 检查密钥,不把密钥写日志 |
403 | 项目、模型、区域或能力未授权 | 检查账户和模型访问权限 |
404 | endpoint、模型或资源不存在 | 校验 URL、模型和资源生命周期 |
413 | 输入、文件或请求体过大 | 计数、截断、分片或改用异步流程 |
429 | 速率、并发或配额限制 | 有界退避、限流和队列,不要无限重试 |
5xx | 服务端或依赖暂时异常 | 有界指数退避,记录 request id |
| 网络超时 | 结果可能已在服务端完成 | 读操作可重试;有副作用的工具调用先查询状态 |
Anthropic 会在响应头或 SDK 异常中提供请求标识,应用应把它和自己的 run_id 关联保存。普通日志不应记录 API key、完整敏感 prompt、用户私有文件和未经脱敏的工具结果。
2.4 重试和幂等边界
纯文本生成在请求未产生外部副作用时,通常可以按状态码和退避策略重试。但如果模型已经发出 tool_use,而工具可能创建订单、发邮件、转账或修改文件,重试整个 turn 可能重复执行动作。更稳妥的做法是:
- 为工具调用保存
tool_use_id、业务幂等键和执行状态。 - 工具执行前做权限、参数、审批和幂等检查。
- 网络未知结果时先查询业务状态,再决定是否补偿或回传结果。
- 只有在模型 turn 和工具执行状态都可追踪时,才允许自动重试。
3. Messages API 的请求模型
3.1 最小请求结构
一个普通请求的核心字段如下:
{
"model": "your-claude-model",
"max_tokens": 1024,
"system": "你是一个严谨的企业知识库助手。",
"messages": [
{
"role": "user",
"content": "解释什么是向量检索。"
}
]
}常见字段的职责:
| 字段 | 作用 | 工程注意事项 |
|---|---|---|
model | 选择具体 Claude 模型 | 能力、价格、上下文和速率限制都随模型变化 |
max_tokens | 限制本次最多生成的 token | 必填或受目标模型要求约束;不要把它当作输入上限 |
system | 提供系统指令 | 与 messages 分开;版本化并保持稳定 |
messages | 传入用户与助手消息 | 常见角色为 user、assistant,内容可为字符串或 block 数组 |
temperature | 调整采样随机性 | 结构化抽取和工具参数通常使用较低值 |
top_p、top_k | 截断采样候选 | 通常只调一个采样旋钮,便于解释实验 |
stop_sequences | 指定停止字符串 | 不能替代业务层的完整性校验 |
stream | 是否以 SSE 流式返回 | 流式必须处理事件、断线、取消和最终状态 |
tools | 声明模型可调用的工具 | schema 和执行权限是两件事 |
tool_choice | 约束是否或调用哪个工具 | 具体枚举以目标 API 版本为准 |
metadata | 携带可用于追踪的请求元数据 | 不要放敏感信息或高基数大对象 |
thinking | 配置 Extended Thinking | 会改变响应 block、预算和成本,需单独评估 |
3.2 system 和消息历史
Anthropic Messages API 通常把系统指令放在顶层 system 字段:
{
"system": "回答必须基于提供的证据;证据不足时明确说明。",
"messages": [
{"role": "user", "content": "公司报销上限是多少?"},
{"role": "assistant", "content": "请提供适用的部门或地区。"},
{"role": "user", "content": "华东销售团队。"}
]
}消息历史由应用自己维护。每次请求通常要携带希望模型看到的历史,不应把 API 调用当成自动永久记忆。历史过长时,应用需要做摘要、裁剪、分层存储或重新检索,并记录哪些内容被省略。
Anthropic 对消息角色和顺序有协议约束。常见有效形态是 user 和 assistant 交替出现,工具结果也要放在符合协议的位置。不要把 OpenAI 的 role: tool 消息原样复制过来;Claude 工具结果是 tool_result content block。
3.3 字符串与 content blocks
简单文本可以直接使用字符串:
{"role": "user", "content": "总结下面这段文字:..."}需要混合文本、图片、文档、工具结果或其他类型时,使用数组:
{
"role": "user",
"content": [
{"type": "text", "text": "请识别图片中的表格列名。"},
{
"type": "image",
"source": {
"type": "base64",
"media_type": "image/png",
"data": "..."
}
}
]
}Content block 是 Claude API 的关键抽象。响应中可能出现 text、tool_use、thinking、redacted_thinking 等 block;解析器应按 type 分支处理,遇到未知类型时记录并安全降级,而不是把整个对象强制转成字符串。
3.4 输入 token 计数
当用户问题、历史、RAG 证据和工具定义可能接近上下文上限时,可以先调用 Token Counting API 估算输入 token。它适合用于:
- 在请求前决定是否摘要或截断历史;
- 选择短上下文模型或长上下文模型;
- 估算输入成本和 Prompt Cache 是否值得;
- 在 RAG 中控制最终证据块数量;
- 在批处理前发现异常大请求。
计数结果不是最终生成结果,也不代表所有计费字段。系统仍应读取正式响应中的 usage,并按当前价格表计算成本。
4. 响应模型和文本提取
4.1 普通响应的形状
一个简化的响应可能类似:
{
"id": "msg_...",
"type": "message",
"role": "assistant",
"model": "your-claude-model",
"content": [
{"type": "text", "text": "向量检索是..."}
],
"stop_reason": "end_turn",
"stop_sequence": null,
"usage": {
"input_tokens": 42,
"output_tokens": 28
}
}常见 stop_reason 可能表示自然结束、达到 max_tokens、需要工具调用或其他协议状态。不要只看 HTTP 200 就宣布业务成功:还要检查是否有文本、是否存在未处理的 tool_use、是否因长度截断,以及引用和结构化结果是否通过业务校验。
4.2 安全提取文本
def text_from_message(message) -> str:
parts = []
for block in message.content:
if block.type == "text":
parts.append(block.text)
return "".join(parts)如果启用了 Extended Thinking,思考 block 和文本 block 会同时存在;如果模型请求工具,tool_use block 也会和文本混合。展示层通常只显示允许展示的文本,审计层则保存 block 类型、顺序、usage 和最终状态。
4.3 usage 与成本
至少记录:
input_tokens和output_tokens;- 是否命中 Prompt Cache,以及缓存读取/写入 token(字段随 API 版本变化);
- thinking 预算或相关 usage 字段;
- 模型、区域、请求处理档位和批处理状态;
- 工具调用次数、输入输出大小和外部工具成本。
成本公式应使用当前模型价格,而不是把 input_tokens + output_tokens 乘一个固定单价。Prompt Cache 写入、缓存读取、长上下文、批处理和 Extended Thinking 可能有不同计费规则,具体以 Anthropic 价格文档为准。
5. 多模态输入:图片、PDF 和文档
5.1 图片输入
图片通常作为 image content block,来源可以是 base64 或目标 API 支持的 URL。生产系统需要先校验媒体类型、大小、分辨率、内容安全和用户权限:
{
"role": "user",
"content": [
{
"type": "image",
"source": {
"type": "url",
"url": "https://example.com/diagram.png"
}
},
{"type": "text", "text": "指出图中所有服务之间的调用方向。"}
]
}图片理解不是 OCR、版面解析和事实验证的替代品。合同、票据和表格场景通常需要保存页码、坐标、表格单元格或原始文件 ID,回答时再把定位信息和图片证据一起返回。
5.2 PDF 和文档
目标模型和账户支持文档输入时,可以使用 document block 或官方文档所示的文件引用方式。不同输入方式在大小、缓存、保留时间和计费上可能不同,不能从图片示例推断 PDF 一定支持相同字段。
RAG 系统中更稳妥的做法是:
- 先做文档解析、权限过滤和版本确认。
- 对文本、表格、图片和页码建立可追溯定位。
- 只向模型发送支持当前问题的页面或窗口。
- 把原始文件 ID、版本、页码和 chunk ID 放进应用侧证据对象。
- 在答案中区分模型视觉判断和原文明确写出的事实。
6. Tool Use:Claude 的工具调用闭环
6.1 工具声明
工具通过 tools 声明。典型函数工具包含名称、用途和 JSON Schema:
{
"model": "your-claude-model",
"max_tokens": 512,
"tools": [
{
"name": "search_knowledge_base",
"description": "在当前用户有权限访问的企业知识库中检索证据。",
"input_schema": {
"type": "object",
"properties": {
"query": {"type": "string"},
"top_k": {"type": "integer", "minimum": 1, "maximum": 10}
},
"required": ["query"]
}
}
],
"messages": [
{"role": "user", "content": "查一下差旅报销的住宿标准。"}
]
}Anthropic 的工具 schema 字段是 input_schema,不要直接套用 Chat Completions 中 tools[].function.parameters 的嵌套形状。工具 description 会影响模型决策,应写清适用范围、权限边界、返回内容和不能处理的请求。
6.2 模型返回 tool_use
模型需要工具时,响应的 content 中会出现 tool_use block:
{
"type": "tool_use",
"id": "toolu_...",
"name": "search_knowledge_base",
"input": {
"query": "差旅报销住宿标准",
"top_k": 5
}
}这只是模型生成的调用意图,工具尚未执行。应用必须:
- 校验工具名称和 JSON Schema;
- 根据当前租户、用户、角色和数据版本做授权;
- 限制查询范围、超时、并发、重试和最大循环次数;
- 对写操作执行审批、幂等和审计;
- 对外部网页、用户输入和工具返回内容设置不可信边界。
6.3 把工具结果回传给 Claude
执行完成后,应用把原始 assistant 内容和 tool_result 放进下一轮消息:
{
"messages": [
{
"role": "user",
"content": "查一下差旅报销的住宿标准。"
},
{
"role": "assistant",
"content": [
{
"type": "tool_use",
"id": "toolu_...",
"name": "search_knowledge_base",
"input": {"query": "差旅报销住宿标准", "top_k": 5}
}
]
},
{
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": "toolu_...",
"content": "证据 1:...;来源:制度 v3,第 4 页。"
}
]
}
]
}实际代码应保留上一轮 assistant 的全部 content blocks,不能只保存其中的文本再伪造工具调用。多个 tool_use 可以在同一轮出现,应用可以并行执行相互独立的工具,但要按 tool_use_id 对齐每个结果,并在下一轮保留确定的顺序。
6.4 工具循环的伪代码
messages = [{"role": "user", "content": user_query}]
for _ in range(MAX_TOOL_ROUNDS):
response = client.messages.create(
model=MODEL,
max_tokens=1024,
system=SYSTEM_PROMPT,
tools=TOOLS,
messages=messages,
)
messages.append({"role": "assistant", "content": response.content})
calls = [b for b in response.content if b.type == "tool_use"]
if not calls:
break
results = []
for call in calls:
output = execute_authorized_tool(call.name, call.input)
results.append({
"type": "tool_result",
"tool_use_id": call.id,
"content": output,
})
messages.append({"role": "user", "content": results})循环结束条件不应只依赖模型的 stop_reason。还要处理工具异常、空结果、部分成功、超时、用户取消、预算用尽和达到最大轮数。对 RAG 工具,工具返回证据和 locator,最终答案仍由模型生成并通过引用校验。
6.5 tool_choice 和强制调用
工具选择策略可以让模型自动决定,也可以要求调用某个工具或禁止工具。强制工具适合需要先查数据库、先做身份校验的流程,但会牺牲一部分模型自主判断。不同 API 版本对枚举和字段形状可能有差异,应以 Tool Use 文档为准。
不要用“强制调用工具”代替业务授权。即使模型被要求调用某工具,服务端仍必须检查调用者身份、参数、数据权限、审批状态和调用频率。
7. Structured Outputs 与结构化结果
Claude 可能通过工具 schema、JSON 输出指令或目标模型提供的结构化输出能力返回结构化数据。工程上要区分三层:
- 协议结构:响应是不是合法的 content block,是否出现了预期的 stop reason。
- 语法结构:文本能否解析成 JSON,字段类型是否符合 schema。
- 业务正确性:金额、日期、权限、引用和状态是否符合真实数据及业务规则。
当目标模型支持官方结构化输出能力时,优先使用官方 schema 机制;否则可以让模型通过工具参数返回结构化结果,再由应用侧校验。不要只使用“请输出 JSON”这句提示就把结果直接写入数据库。
例如发票抽取至少需要:
- JSON Schema 类型校验;
- 金额、币种、税率和日期的业务校验;
- 原始页码和字段定位;
- 缺失字段与低置信度处理;
- 重复写入和人工复核边界。
8. Streaming:从 SSE 事件重建响应
8.1 开启流式
with client.messages.stream(
model="your-claude-model",
max_tokens=512,
messages=[{"role": "user", "content": "分三点解释 RAG。"}],
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)SDK 的 text_stream 适合简单文本展示,但生产系统通常还要读取原始事件,才能处理工具、思考、错误和最终 usage。
8.2 常见事件
Anthropic 流式响应通常通过 SSE 发送带类型的事件,常见事件包括:
| 事件 | 作用 |
|---|---|
message_start | 返回消息元数据和初始 usage |
content_block_start | 开始一个文本、工具或思考 block |
content_block_delta | 增量传输文本或工具 JSON 片段 |
content_block_stop | 当前 block 结束 |
message_delta | 更新 stop reason、最终 usage 等消息级字段 |
message_stop | 本次消息事件流结束 |
ping | 保活或连接状态事件 |
error | 流式过程中的错误 |
content_block_delta 的 delta 类型可能包含 text_delta、input_json_delta、thinking_delta 或签名相关字段。工具输入 JSON 可能被拆成多个片段,不能把每个片段当成完整 JSON 立即执行。
8.3 流式解析的正确边界
前端展示层可以增量显示文本;运行时层应同时维护:
事件序列
-> 当前 content block 缓冲
-> 完整工具 input JSON
-> stop_reason 和 usage
-> 最终业务状态客户端断线、代理缓冲、半个 JSON、重复事件和用户取消都必须有处理策略。收到 message_stop 只代表 Anthropic 的事件流结束,不代表工具已经成功执行、数据库已经写入或引用已经通过。
9. Prompt Caching:复用稳定输入前缀
9.1 缓存适合什么
Prompt Caching 适合系统指令、工具定义、稳定背景知识和重复使用的长文档。官方 Prompt Caching 文档说明,缓存通过在请求内容中设置 cache_control 等标记复用前缀处理结果;具体 TTL、模型支持和计费随版本变化。
一个概念上的布局是:
[稳定 system 指令]
[稳定工具定义]
[稳定的公共背景/长文档] <- 缓存断点
----------------------
[本次用户问题]
[本次检索证据]动态内容应放在缓存前缀之后。工具顺序、序列化方式、系统指令和文档版本要稳定,否则命中率会下降。
9.2 缓存不是答案缓存
| 缓存 | 复用什么 | 主要收益 | 主要风险 |
|---|---|---|---|
| Prompt Cache | 稳定输入前缀的计算 | 减少输入处理和首 token 等待 | 前缀变化失效、权限串用 |
| Retrieval Cache | 查询对应的证据 ID | 跳过部分检索 | 数据更新和 ACL 失效 |
| Answer Cache | 完整最终答案 | 直接返回结果 | 过期、越权、问题约束不一致 |
企业系统应把租户、用户权限、权限版本、数据快照、文档版本和安全策略纳入缓存隔离设计。公共且非个性化的文档可以共享前缀;薪资、订单、医疗和刚撤权资料通常需要更严格的键或禁止共享。
9.3 如何验证缓存收益
同时观察:
- cache read/write token 和命中率;
- 输入处理时间、TTFT P50/P95/P99;
- 总输入输出成本;
- 文档更新后的陈旧命中数;
- 权限错误率和答案忠实度。
命中率高但命中旧版本,不能算优化成功。缓存键的正确性和失效传播应纳入发布、删除和权限变更流程。
10. Extended Thinking:思考预算和输出处理
Extended Thinking 允许模型为复杂问题使用额外推理预算。启用方式、预算约束、可见性和模型支持范围会变化,应参考目标模型的 Extended Thinking 文档。常见请求形状类似:
{
"model": "your-thinking-capable-model",
"max_tokens": 4096,
"thinking": {
"type": "enabled",
"budget_tokens": 2048
},
"messages": [
{"role": "user", "content": "比较两套权限模型的迁移风险。"}
]
}工程上要注意:
max_tokens、thinking budget 和可见答案长度共同决定总预算;- 响应可能同时包含 thinking、redacted thinking 和 text block;
- 思考内容不应未经审查直接展示给用户或写入普通业务日志;
- 思考模式可能限制某些采样参数、工具或缓存组合;
- 复杂问题的质量收益要和 TTFT、总延迟、成本一起评估。
不要把 Extended Thinking 当成事实校验。合同、财务和权限问题仍需要检索、工具和业务规则验证。
11. Token、上下文和成本控制
11.1 输入 token 的组成
一次 Messages 请求的输入不只是用户最后一句话:
输入 token
= system 指令
+ 历史 user/assistant 消息
+ 工具名称、description 和 JSON Schema
+ 图片或文档的表示成本
+ RAG 证据
+ 本次用户问题因此只缩短用户问题通常没有意义。RAG 应先做候选召回,再去重、重排、压缩并只注入支持当前答案的证据;Agent 应限制历史、工具数量和重复调用。
11.2 成本估算
请求成本
= 未缓存输入 token × 输入单价
+ 缓存写入/读取 token × 对应单价
+ 输出 token × 输出单价
+ thinking、批处理、长上下文或其他能力费用实际字段和计费方式以当前价格为准。成本看板至少按模型、租户、功能、输入/输出、缓存、工具和失败重试拆分。不要把重试产生的 token 隐藏在平均成本中。
11.3 上下文裁剪顺序
一个可解释的裁剪顺序是:
- 删除已撤权、过期或无权限内容。
- 删除重复的历史和重复召回片段。
- 对长对话做保留事实的摘要。
- 对 RAG 证据按问题相关性和引用覆盖率排序。
- 保留版本、例外、条件和定位信息。
- 最后才按 token 预算截断,并记录被截断的内容。
Token 越少不一定越好。删掉一个例外条件可能让请求更快,但答案更错。
12. OpenAI API 对照与迁移
12.1 核心概念映射
| 关注点 | OpenAI Chat Completions | OpenAI Responses | Anthropic Messages |
|---|---|---|---|
| endpoint | /v1/chat/completions | /v1/responses | /v1/messages |
| 认证 | Authorization: Bearer | Authorization: Bearer | x-api-key + anthropic-version |
| 系统指令 | messages 中 system | instructions 或 input 结构 | 顶层 system |
| 普通输入 | messages | input Items | messages |
| 普通输出 | choices[].message.content | output Items / output_text | content[] 中的 text block |
| 工具声明 | tools[].function | function tool 对象 | tools[] + input_schema |
| 工具调用 | tool_calls | function_call Item | tool_use block |
| 工具结果 | role: tool | function_call_output | tool_result block |
| 流式协议 | delta chunks / [DONE] | typed SSE events | typed SSE events |
| 最大输出字段 | max_completion_tokens 等 | max_output_tokens | max_tokens |
这张表只能作为概念地图,不能当作自动转换规则。即使两个 provider 都声称兼容 OpenAI,工具 schema、流式事件、usage、错误、缓存和数据保留也可能不同。
12.2 从 Chat Completions 迁移到 Messages
迁移通常需要同时改:
- 认证 header、endpoint 和 API 版本。
system从消息数组中拆到顶层字段。- 输入内容从 provider-specific message schema 转成 Claude content blocks。
- 工具声明从嵌套
function.parameters改为input_schema。 - 响应解析从
choices改为contentblock 和stop_reason。 - 工具结果从
role: tool改为带tool_use_id的tool_result。 - 流式解析从 delta chunk 改为 SSE 事件状态机。
- usage、缓存、thinking、错误码和重试策略重新接入观测系统。
不要把 provider 差异都压成一个只有 text 字段的内部模型。至少在网关层保留 text、tool_use、tool_result、thinking、usage、stop_reason 和原始事件等类型信息,业务层再按场景选择需要的抽象。
12.3 统一模型网关的边界
统一网关可以提供:
- 统一租户认证、限流、预算和审计;
- 统一 run、trace、重试、超时和取消;
- provider 能力矩阵和模型路由;
- 文本、工具、流式和 usage 的最小公共接口;
- provider 专属字段的显式扩展位。
不应强行抹平:
- Claude content block 与 OpenAI typed Item 的语义;
tool_use和function_call的 ID、角色和回传方式;- Prompt Cache、thinking、长上下文和多模态计费;
- 错误码、速率限制、数据保留和安全策略。
切换 provider 前,应用应使用同一组文本、工具、多模态、流式、超时和拒答样本做回归,而不是只更换 base_url 或 SDK。
13. 生产工程:超时、限流、观测和安全
13.1 超时和取消
至少区分:
- 连接建立超时;
- 首事件或首 token 超时;
- 单次读取超时;
- 整个 turn 超时;
- 工具执行超时;
- 异步批处理任务超时。
流式请求被用户取消时,要向模型连接、工具执行和下游检索传播取消信号,避免后台继续消耗预算。工具已产生副作用时,取消只代表客户端不再等待,不代表业务动作自动回滚。
13.2 限流和队列
限流至少按模型、API key、租户和请求类型拆分。交互问答、长思考、批处理和多模态请求不应无条件共用一个队列。应监控:
- 请求排队时间和并发数;
- 输入、输出和 thinking token;
- 429 次数与退避时长;
- 流式连接数、取消率和断线率;
- 工具循环轮数与外部调用耗时。
13.3 Trace 和审计字段
一次调用至少可追溯到:
run_id / request_id
tenant_id(脱敏)
provider / model / anthropic-version
system_prompt_version
message_history_version
tools_schema_version
knowledge_base_version
cache_read/write 状态
input/output/thinking token
首事件、首 token、完整响应耗时
stop_reason、错误、重试、取消和最终业务状态日志中应对用户 prompt、图片、文档和工具输出做分级脱敏。不要为了调试把所有原文永久保存;需要审计时,应保存最小必要片段、哈希、locator 和访问策略。
13.4 权限和不可信工具结果
模型看到工具结果,不等于工具结果可信。网页、用户上传文件、数据库文本和第三方 API 都可能包含提示注入或恶意指令。工具执行层应把数据和指令分开,明确哪些字段只能作为事实,不能改变系统规则、权限或工具选择。
在 RAG 中,ACL 必须在检索前或检索服务端执行,不能先把无权 chunk 放进 Claude Prompt 再要求模型忽略。缓存、摘要、工具结果和流式日志也必须遵守同一权限边界。
14. 按问题选择 Claude API 能力
| 观察到的问题 | 优先处理方向 | 不要先做什么 |
|---|---|---|
| 输入经常超上下文 | Token Counting、历史摘要、证据压缩 | 只把 max_tokens 调大 |
| 工具参数经常解析失败 | 收紧 input_schema、校验和重试单个工具 | 让模型自由输出任意 JSON |
| 首 token 慢 | 减少输入、稳定前缀、Prompt Cache、模型队列优化 | 只打开流式显示 |
| 工具循环失控 | 最大轮数、超时、预算和重复调用检测 | 无上限地继续请求 |
| 长文档重复发送 | Prompt Caching 或分层检索 | 直接缓存所有最终答案 |
| 迁移 OpenAI 后行为变化 | 能力矩阵、协议适配和同集回归 | 只替换 SDK 类名 |
| 多模态答案难以审计 | 保存文件 ID、页码、坐标和内容版本 | 只保存模型最终文本 |
| 429 和尾延迟明显 | 按租户/模型限流、队列和退避 | 无限并发重试 |
15. 常见误区
误区一:Claude API 就是 OpenAI API 换了模型名
Messages API 的认证、endpoint、system 字段、content blocks、工具 schema、流式事件和 usage 都有自己的协议。统一网关可以提供公共能力,但不能假设请求和响应可直接互换。
误区二:tool_use 出现就代表工具已经执行
它只是模型的调用意图。应用仍需做参数校验、授权、审批、幂等、执行、审计,并把对应的 tool_result 回传。
误区三:只取 content[0].text 就完成了解析
响应可能包含多个文本 block、工具调用、思考或未来新增类型。应遍历 block,按 type 处理并检查 stop_reason。
误区四:流式输出能降低所有延迟
流式只能让客户端更早看到已经产生的事件,不能消除排队、输入处理、工具执行或模型生成前的等待。还要检查 SSE、代理和客户端是否真的逐事件转发。
误区五:Prompt Cache 命中率高就说明安全且有效
缓存命中还要满足版本、权限、租户和数据新鲜度要求。缓存旧制度或错误租户的内容,速度越快风险越大。
误区六:Extended Thinking 越多越好
思考预算增加可能提高复杂任务质量,也会增加延迟、成本和上下文压力。应按问题类型评测,并对思考 block 的展示、保存和隐私做边界设计。
误区七:让模型输出 JSON 就等于结构化输出
JSON 可解析只说明语法正确,不保证金额、日期、权限、引用和业务状态正确。写库前必须做 schema 和业务校验。
误区八:超时后重试一定安全
如果上一轮已触发外部写操作,重试可能产生重复副作用。应先查询业务状态,使用幂等键和可恢复的执行记录。
误区九:兼容层可以隐藏所有 provider 差异
过度统一通常会丢掉工具、thinking、缓存、流式和错误语义。公共接口应保持最小且稳定,provider 专属能力要显式暴露并有能力矩阵。
16. 面试回答模板
面试中可以这样回答:
Claude 的官方核心接口是 Anthropic Messages API,而不是把 OpenAI 请求原样换一个模型名。请求使用
x-api-key和anthropic-version,系统指令通常放在顶层system,消息内容可以是字符串或有类型的 content blocks。工具调用时模型返回tool_use,应用要做 schema、权限、幂等和超时校验,执行后用带tool_use_id的tool_result开启下一轮;流式则要按 SSE 事件重建 text、tool input、thinking 和最终 usage。生产上我会用 Token Counting 控制上下文,用 Prompt Cache 复用稳定前缀,按问题复杂度决定是否启用 Extended Thinking,并把模型、prompt、工具、缓存、token、stop reason、错误和业务结果放进 trace。迁移 OpenAI 时不会只换 SDK,而是逐项改认证、字段、响应解析、工具循环和回归测试。
最后记住
Messages API 是 Claude 的主交互协议
-> system、messages 和 content blocks 分层建模
-> tool_use 只是意图,应用负责授权、执行和 tool_result
-> 流式按 SSE 事件解析,不能只拼文本
-> Token Counting 控制上下文,Prompt Cache 复用稳定前缀
-> Extended Thinking 要用预算、延迟、成本和隐私一起评估
-> OpenAI 迁移要改协议和回归,不是只改模型名
-> 用 trace、权限、幂等和业务校验把接口接进生产系统Claude API 的学习重点不是记住更多字段,而是理解“模型生成内容、应用执行工具、系统维护状态”三者的边界。只要这条边界清楚,换模型、接 RAG、做多模态或搭统一网关时,具体字段变化都可以通过适配层和回归测试控制。