关于 claude-api
claude-api 是 Anthropic Messages API 的开发参考技能,面向在 Node.js 或直接 HTTP 请求中构建 Claude 应用的开发者。内容涵盖流式响应、提示词缓存、工具调用、图像理解和扩展思考等用法。
主要功能
- 01Messages API 请求与多轮对话
- 02SSE 流式响应
- 03提示词缓存
- 04工具调用流程
- 05图像理解
- 06扩展思考模式
适用场景
- 01在应用中实现 Claude 对话
- 02逐段显示模型生成内容
- 03为重复上下文配置提示词缓存
- 04结合工具或图像处理复杂请求
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ jackspace/ claudeskillz --skill claude-api安装后在 Claude Code 中输入/claude-api确认已加载。
附带文件README.mdSKILL.json
详细介绍
Claude API(Anthropic Messages API)
状态:已可投入生产 最后更新:2025-10-25 依赖项:无(独立 API 技能) 最新版本:@anthropic-ai/[email protected]
快速入门(5 分钟)
1. 获取 API 密钥
# Sign up at https://console.anthropic.com/
# Navigate to API Keys section
# Create new key and save securely
export ANTHROPIC_API_KEY="sk-ant-..."
重要原因:
- 所有请求都需要 API 密钥
- 妥善保管(切勿提交到 git)
- 使用环境变量
2. 安装 SDK(Node.js)
npm install @anthropic-ai/sdk
import Anthropic from '@anthropic-ai/sdk';
const anthropic = new Anthropic({
apiKey: process.env.ANTHROPIC_API_KEY,
});
const message = await anthropic.messages.create({
model: 'claude-sonnet-4-5-20250929',
max_tokens: 1024,
messages: [{ role: 'user', content: 'Hello, Claude!' }],
});
console.log(message.content[0].text);
至关重要:
- 始终在服务端使用(切勿在客户端代码中公开 API 密钥)
- 设置
max_tokens(必需参数) - 模型名称带有版本号(使用最新稳定版)
3. 或使用直接 API(Cloudflare Workers)
// No SDK needed - use fetch()
const response = await fetch('https://api.anthropic.com/v1/messages', {
method: 'POST',
headers: {
'x-api-key': env.ANTHROPIC_API_KEY,
'anthropic-version': '2023-06-01',
'content-type': 'application/json',
},
body: JSON.stringify({
model: 'claude-sonnet-4-5-20250929',
max_tokens: 1024,
messages: [{ role: 'user', content: 'Hello!' }],
}),
});
const data = await response.json();
Claude API 完整参考
目录
核心 API(Messages API)
可用模型(2025 年 10 月)
| 模型 | ID | 上下文 | 最适合用途 | 费用(每 MTok) |
|---|---|---|---|---|
| Claude Sonnet 4.5 | claude-sonnet-4-5-20250929 | 200k tokens | 性能均衡 | $3/$15(输入/输出) |
| Claude 3.7 Sonnet | claude-3-7-sonnet-20250228 | 2M tokens | 扩展思考 | $3/$15 |
| Claude Opus 4 | claude-opus-4-20250514 | 200k tokens | 能力最强 | $15/$75 |
| Claude 3.5 Haiku | claude-3-5-haiku-20241022 | 200k tokens | 快速且经济 | $1/$5 |
创建基本消息
import Anthropic from '@anthropic-ai/sdk';
const anthropic = new Anthropic({
apiKey: process.env.ANTHROPIC_API_KEY,
});
const message = await anthropic.messages.create({
model: 'claude-sonnet-4-5-20250929',
max_tokens: 1024,
messages: [
{ role: 'user', content: 'Explain quantum computing in simple terms' }
],
});
console.log(message.content[0].text);
多轮对话
const messages = [
{ role: 'user', content: 'What is the capital of France?' },
{ role: 'assistant', content: 'The capital of France is Paris.' },
{ role: 'user', content: 'What is its population?' },
];
const message = await anthropic.messages.create({
model: 'claude-sonnet-4-5-20250929',
max_tokens: 1024,
messages,
});
系统提示词
const message = await anthropic.messages.create({
model: 'claude-sonnet-4-5-20250929',
max_tokens: 1024,
system: 'You are a helpful Python coding assistant. Always provide type hints and docstrings.',
messages: [
{ role: 'user', content: 'Write a function to sort a list' }
],
});
至关重要:
- 系统提示词必须放在消息数组之前
- 系统提示词会设定整个对话的行为
- 长度可以为 1-10k tokens(会占用上下文窗口)
流式响应(SSE)
使用 SDK 流辅助工具
const stream = anthropic.messages.stream({
model: 'claude-sonnet-4-5-20250929',
max_tokens: 1024,
messages: [{ role: 'user', content: 'Write a short story' }],
});
// Method 1: Event listeners
stream
.on('text', (text) => {
process.stdout.write(text);
})
.on('message', (message) => {
console.log('\n\nFinal message:', message);
})
.on('error', (error) => {
console.error('Stream error:', error);
});
// Wait for completion
await stream.finalMessage();
手动迭代流
const stream = await anthropic.messages.create({
model: 'claude-sonnet-4-5-20250929',
max_tokens: 1024,
messages: [{ role: 'user', content: 'Explain AI' }],
stream: true,
});
for await (const event of stream) {
if (event.type === 'content_block_delta' && event.delta.type === 'text_delta') {
process.stdout.write(event.delta.text);
}
}
流事件类型
| 事件 | 触发时机 | 使用场景 |
|---|---|---|
message_start | 消息开始 | 初始化 UI |
content_block_start | 新内容块开始 | 跟踪内容块 |
content_block_delta | 收到文本片段 | 显示文本 |
content_block_stop | 内容块完成 | 格式化内容块 |
message_delta | 元数据更新 | 更新停止原因 |
message_stop | 消息完成 | 完成 UI |
Cloudflare Workers 流式处理
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const response = await fetch('https://api.anthropic.com/v1/messages', {
method: 'POST',
headers: {
'x-api-key': env.ANTHROPIC_API_KEY,
'anthropic-version': '2023-06-01',
'content-type': 'application/json',
},
body: JSON.stringify({
model: 'claude-sonnet-4-5-20250929',
max_tokens: 1024,
messages: [{ role: 'user', content: 'Hello!' }],
stream: true,
}),
});
// Return SSE stream directly
return new Response(response.body, {
headers: {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
},
});
},
};
至关重要:
- 初始 200 响应发出后仍可能发生错误
- 始终实现错误事件处理程序
- 使用
stream.abort()取消 - 设置正确的 Content-Type 标头
提示词缓存(⭐ 节省 90% 费用)
概述
提示词缓存允许你缓存频繁使用的上下文(系统提示词、文档、代码库),从而:
- 降低 90% 的费用(缓存读取费用为输入 tokens 价格的 10%)
- 降低 85% 的延迟(缩短首个 token 的生成时间)
- 缓存有效期:5 分钟(默认)或 1 小时(可配置)
最低要求
- Claude 3.5 Sonnet:至少 1,024 tokens
- Claude 3.5 Haiku:至少 2,048 tokens
基本提示词缓存
const message = await anthropic.messages.create({
model: 'claude-sonnet-4-5-20250929',
max_tokens: 1024,
system: [
{
type: 'text',
text: 'You are an AI assistant analyzing the following codebase...',
},
{
type: 'text',
text: LARGE_CODEBASE_CONTENT, // 50k tokens
cache_control: { type: 'ephemeral' },
},
],
messages: [
{ role: 'user', content: 'Explain the auth module' }
],
});
// Check cache usage
console.log('Cache read tokens:', message.usage.cache_read_input_tokens);
console.log('Cache creation tokens:', message.usage.cache_creation_input_tokens);
在消息中缓存
const message = await anthropic.messages.create({
model: 'claude-sonnet-4-5-20250929',
max_tokens: 1024,
messages: [
{
role: 'user',
content: [
{
type: 'text',
text: 'Analyze this documentation:',
},
{
type: 'text',
text: LONG_DOCUMENTATION, // 20k tokens
cache_control: { type: 'ephemeral' },
},
{
type: 'text',
text: 'What are the main API endpoints?',
},
],
},
],
});
多轮缓存(聊天机器人模式)
// First request - creates cache
const message1 = await anthropic.messages.create({
model: 'claude-sonnet-4-5-20250929',
max_tokens: 1024,
system: [
{
type: 'text',
text: SYSTEM_INSTRUCTIONS,
cache_control: { type: 'ephemeral' },
},
],
messages: [
{ role: 'user', content: 'Hello!' }
],
});
// Second request - hits cache (within 5 minutes)
const message2 = await anthropic.messages.create({
model: 'claude-sonnet-4-5-20250929',
max_tokens: 1024,
system: [
{
type: 'text',
text: SYSTEM_INSTRUCTIONS, // Same content = cache hit
cache_control: { type: 'ephemeral' },
},
],
messages: [
{ role: 'user', content: 'Hello!' },
{ role: 'assistant', content: message1.content[0].text },
{ role: 'user', content: 'Tell me a joke' },
],
});
费用对比
Without Caching:
- 100k input tokens = 100k × $3/MTok = $0.30
With Caching (after first request):
- Cache write: 100k × $3.75/MTok = $0.375 (first request)
- Cache read: 100k × $0.30/MTok = $0.03 (subsequent requests)
- Savings: 90% per request after first
至关重要:
cache_control必须放在可缓存内容的最后一个块上- 内容完全相同的请求之间会共享缓存
- 监控
cache_creation_input_tokens与cache_read_input_tokens - 每次使用都会刷新 5 分钟的 TTL
工具使用(函数调用)
基本工具定义
const tools = [
{
name: 'get_weather',
description: 'Get the current weather in a given location',
input_schema: {
type: 'object',
properties: {
location: {
type: 'string',
description: 'City name, e.g. San Francisco, CA',
},
unit: {
type: 'string',
enum: ['celsius', 'fahrenheit'],
description: 'Temperature unit',
},
},
required: ['location'],
},
},
];
const message = await anthropic.messages.create({
model: 'claude-sonnet-4-5-20250929',
max_tokens: 1024,
tools,
messages: [{ role: 'user', content: 'What is the weather in NYC?' }],
});
if (message.stop_reason === 'tool_use') {
const toolUse = message.content.find(block => block.type === 'tool_use');
console.log('Claude wants to use:', toolUse.name);
console.log('With parameters:', toolUse.input);
}
工具执行循环
async function chatWithTools(userMessage: string) {
const messages = [{ role: 'user', content: userMessage }];
while (true) {
const response = await anthropic.messages.create({
model: 'claude-sonnet-4-5-20250929',
max_tokens: 1024,
tools,
messages,
});
// Add assistant response
messages.push({
role: 'assistant',
content: response.content,
});
// Check if tools need to be executed
if (response.stop_reason === 'tool_use') {
const toolResults = [];
for (const block of response.content) {
if (block.type === 'tool_use') {
// Execute tool
const result = await executeToolFunction(block.name, block.input);
toolResults.push({
type: 'tool_result',
tool_use_id: block.id,
content: JSON.stringify(result),
});
}
}
// Add tool results
messages.push({
role: 'user',
content: toolResults,
});
} else {
// Final response
return response.content.find(block => block.type === 'text')?.text;
}
}
}
Beta 工具运行器(SDK 助手)
import { betaZodTool } from '@anthropic-ai/sdk/helpers/zod';
import { z } from 'zod';
const weatherTool = betaZodTool({
name: 'get_weather',
inputSchema: z.object({
location: z.string(),
unit: z.enum(['celsius', 'fahrenheit']).optional(),
}),
description: 'Get the current weather in a given location',
run: async (input) => {
// Execute actual API call
const weather = await fetchWeatherAPI(input.location, input.unit);
return `The weather in ${input.location} is ${weather.temp}°${input.unit || 'F'}`;
},
});
const finalMessage = await anthropic.beta.messages.toolRunner({
model: 'claude-sonnet-4-5-20250929',
max_tokens: 1000,
messages: [{ role: 'user', content: 'What is the weather in San Francisco?' }],
tools: [weatherTool],
});
console.log(finalMessage.content[0].text);
关键:
- 工具架构必须是有效的 JSON Schema
tool_use_id必须与tool_result中的值匹配- 妥善处理工具执行错误
- 设置合理的
max_iterations以防止循环
视觉(图像理解)
支持的图像格式
- 格式:JPEG、PNG、WebP、GIF(非动画)
- 最大大小:每张图像 5MB
- 输入方式:Base64 编码、URL(如果可访问)
单张图像
import fs from 'fs';
const imageData = fs.readFileSync('./photo.jpg', 'base64');
const message = await anthropic.messages.create({
model: 'claude-sonnet-4-5-20250929',
max_tokens: 1024,
messages: [
{
role: 'user',
content: [
{
type: 'image',
source: {
type: 'base64',
media_type: 'image/jpeg',
data: imageData,
},
},
{
type: 'text',
text: 'What is in this image?',
},
],
},
],
});
多张图像
const message = await anthropic.messages.create({
model: 'claude-sonnet-4-5-20250929',
max_tokens: 1024,
messages: [
{
role: 'user',
content: [
{
type: 'text',
text: 'Compare these two images:',
},
{
type: 'image',
source: {
type: 'base64',
media_type: 'image/jpeg',
data: image1Data,
},
},
{
type: 'image',
source: {
type: 'base64',
media_type: 'image/png',
data: image2Data,
},
},
{
type: 'text',
text: 'What are the differences?',
},
],
},
],
});
使用工具进行视觉分析
const message = await anthropic.messages.create({
model: 'claude-sonnet-4-5-20250929',
max_tokens: 1024,
tools: [searchTool, saveTool],
messages: [
{
role: 'user',
content: [
{
type: 'image',
source: {
type: 'base64',
media_type: 'image/jpeg',
data: productImage,
},
},
{
type: 'text',
text: 'Search for similar products and save the top 3 results',
},
],
},
],
});
关键:
- 图像会占用上下文窗口
- Base64 编码会增加大小(约 33% 的额外开销)
- 编码前验证图像格式
- 对重复的图像分析考虑使用缓存
扩展思考模式
⚠️ 模型可用性
扩展思考仅适用于:
- Claude 3.7 Sonnet(
claude-3-7-sonnet-20250228) - Claude 4 模型(Opus 4、Sonnet 4)
不适用于 Claude 3.5 Sonnet
工作原理
扩展思考允许 Claude 在回复前“出声思考”,展示其推理过程。适用于:
- 复杂的 STEM 问题(物理、数学)
- 软件调试与架构设计
- 法律分析与财务建模
- 多步骤推理任务
基本用法
// Only works with Claude 3.7 Sonnet or Claude 4
const message = await anthropic.messages.create({
model: 'claude-3-7-sonnet-20250228', // NOT claude-sonnet-4-5
max_tokens: 4096, // Higher token limit for thinking
messages: [
{
role: 'user',
content: 'Solve this physics problem: A ball is thrown upward with velocity 20 m/s. How high does it go?'
}
],
});
// Response includes thinking blocks
for (const block of message.content) {
if (block.type === 'thinking') {
console.log('Claude is thinking:', block.text);
} else if (block.type === 'text') {
console.log('Final answer:', block.text);
}
}
思考与常规回复
Regular Response:
"The ball reaches a height of approximately 20.4 meters."
With Extended Thinking:
[Thinking block]: "I need to use kinematic equations. The relevant formula is v² = u² + 2as, where v=0 at max height, u=20 m/s, a=-9.8 m/s². Solving: 0 = 400 - 19.6s, so s = 400/19.6 = 20.4m"
[Text block]: "The ball reaches a height of approximately 20.4 meters."
关键:
- 预期使用扩展思考前,检查模型名称
- 需要更高的
max_tokens(思考会消耗令牌) - 思考块无法缓存
- 仅在需要深入推理时使用(成本更高)
速率限制
了解速率限制
Claude API 使用令牌桶算法:
- 容量持续补充(而非按固定间隔补充)
- 分为三种类型:每分钟请求数(RPM)、每分钟令牌数(TPM)、每日令牌数
速率限制等级
| 等级 | 条件 | 限制示例 |
|---|---|---|
| Tier 1 | 新账户 | 50 RPM、40k TPM |
| Tier 2 | 消费 $10 | 1000 RPM、100k TPM |
| Tier 3 | 消费 $50 | 2000 RPM、200k TPM |
| Tier 4 | 消费 $500 | 4000 RPM、400k TPM |
限制因模型而异。请在 Console 中查看确切限制。
处理 429 错误
async function makeRequestWithRetry(
requestFn: () => Promise<any>,
maxRetries = 3,
baseDelay = 1000
): Promise<any> {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
return await requestFn();
} catch (error) {
if (error.status === 429) {
const retryAfter = error.response?.headers?.['retry-after'];
const delay = retryAfter
? parseInt(retryAfter) * 1000
: baseDelay * Math.pow(2, attempt);
console.warn(`Rate limited. Retrying in ${delay}ms...`);
await new Promise(resolve => setTimeout(resolve, delay));
} else {
throw error;
}
}
}
throw new Error('Max retries exceeded');
}
// Usage
const message = await makeRequestWithRetry(() =>
anthropic.messages.create({
model: 'claude-sonnet-4-5-20250929',
max_tokens: 1024,
messages: [{ role: 'user', content: 'Hello' }],
})
);
检查速率限制标头
const response = await fetch('https://api.anthropic.com/v1/messages', {
// ... request config
});
console.log('Limit:', response.headers.get('anthropic-ratelimit-requests-limit'));
console.log('Remaining:', response.headers.get('anthropic-ratelimit-requests-remaining'));
console.log('Reset:', response.headers.get('anthropic-ratelimit-requests-reset'));
关键:
- 始终遵循
retry-after标头 - 实施指数退避
- 在 Console 中监控使用情况
- 处理大量请求时,考虑使用批处理
错误处理
常见错误代码
| 状态码 | 错误类型 | 原因 | 解决方案 |
|---|---|---|---|
| 400 | invalid_request_error | 参数错误 | 验证请求正文 |
| 401 | authentication_error | API 密钥无效 | 检查环境变量 |
| 403 | permission_error | 无权使用此功能 | 检查账户等级 |
| 404 | not_found_error | 端点无效 | 检查 API 版本 |
| 429 | rate_limit_error | 请求过多 | 实施重试逻辑 |
| 500 | api_error | 内部错误 | 退避后重试 |
| 529 | overloaded_error | 系统过载 | 稍后重试 |
全面的错误处理程序
import Anthropic from '@anthropic-ai/sdk';
async function safeAPICall(request: Anthropic.MessageCreateParams) {
try {
return await anthropic.messages.create(request);
} catch (error) {
if (error instanceof Anthropic.APIError) {
console.error('API Error:', error.status, error.message);
switch (error.status) {
case 400:
console.error('Invalid request:', error.error);
throw new Error('Request validation failed');
case 401:
console.error('Authentication failed. Check API key.');
throw new Error('Invalid credentials');
case 429:
console.warn('Rate limited. Implement retry logic.');
// Implement retry (see Rate Limits section)
break;
case 500:
case 529:
console.warn('Service unavailable. Retrying...');
// Implement retry with exponential backoff
break;
default:
console.error('Unexpected error:', error);
throw error;
}
} else {
console.error('Non-API error:', error);
throw error;
}
}
}
流式传输错误处理
const stream = anthropic.messages.stream({
model: 'claude-sonnet-4-5-20250929',
max_tokens: 1024,
messages: [{ role: 'user', content: 'Hello' }],
});
stream
.on('error', (error) => {
console.error('Stream error:', error);
// Error can occur AFTER initial 200 response
// Implement fallback or retry logic
})
.on('abort', (error) => {
console.warn('Stream aborted:', error);
})
.on('end', () => {
console.log('Stream ended successfully');
});
关键:
- SSE 流中的错误会在 200 响应之后发生
- 始终实现错误事件监听器
- 记录带上下文的错误以便调试
- 为关键操作准备备用策略
平台集成
Cloudflare Workers
export interface Env {
ANTHROPIC_API_KEY: string;
}
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const { messages } = await request.json();
const response = await fetch('https://api.anthropic.com/v1/messages', {
method: 'POST',
headers: {
'x-api-key': env.ANTHROPIC_API_KEY,
'anthropic-version': '2023-06-01',
'content-type': 'application/json',
},
body: JSON.stringify({
model: 'claude-sonnet-4-5-20250929',
max_tokens: 1024,
messages,
}),
});
return new Response(await response.text(), {
headers: { 'Content-Type': 'application/json' },
});
},
};
Next.js API 路由(App Router)
// app/api/chat/route.ts
import Anthropic from '@anthropic-ai/sdk';
import { NextRequest } from 'next/server';
const anthropic = new Anthropic({
apiKey: process.env.ANTHROPIC_API_KEY,
});
export async function POST(request: NextRequest) {
try {
const { messages } = await request.json();
const stream = anthropic.messages.stream({
model: 'claude-sonnet-4-5-20250929',
max_tokens: 1024,
messages,
});
// Return stream to client
return new Response(
new ReadableStream({
async start(controller) {
for await (const event of stream) {
if (event.type === 'content_block_delta' && event.delta.type === 'text_delta') {
controller.enqueue(new TextEncoder().encode(event.delta.text));
}
}
controller.close();
},
}),
{
headers: {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
},
}
);
} catch (error) {
console.error('Chat error:', error);
return new Response(JSON.stringify({ error: 'Internal error' }), {
status: 500,
});
}
}
Next.js API 路由(Pages Router)
// pages/api/chat.ts
import type { NextApiRequest, NextApiResponse } from 'next';
import Anthropic from '@anthropic-ai/sdk';
const anthropic = new Anthropic({
apiKey: process.env.ANTHROPIC_API_KEY,
});
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
if (req.method !== 'POST') {
return res.status(405).json({ error: 'Method not allowed' });
}
try {
const { messages } = req.body;
const message = await anthropic.messages.create({
model: 'claude-sonnet-4-5-20250929',
max_tokens: 1024,
messages,
});
res.status(200).json(message);
} catch (error) {
console.error('API error:', error);
res.status(500).json({ error: 'Internal server error' });
}
}
关键规则
务必做到
✅ 将 API 密钥存储在环境变量中(切勿硬编码)
✅ 设置 max_tokens 参数(必需)
✅ 使用最新的稳定模型 ID(定期查看文档)
✅ 为所有 API 调用实现错误处理
✅ 通过指数退避遵循速率限制
✅ 将 cache_control 放在可缓存内容的末尾
✅ 严格验证工具输入架构
✅ 处理流式传输错误(可能在 200 响应后发生)
✅ 监控令牌用量(输入 + 输出 + 缓存)
✅ 仅在服务端使用(切勿在客户端公开密钥)
切勿执行
❌ 在客户端代码中暴露 API key(存在安全风险)
❌ 在 429 错误时忽略 retry-after 标头
❌ 在 Claude 3.5 Sonnet 上使用 extended thinking(不支持)
❌ 缓存低于最低令牌阈值(1024/2048)的内容
❌ 将 system prompt 放在 messages 数组之后(必须放在最前面)
❌ 收到初始 200 响应后就认定流式传输成功
❌ 未经验证就将用户输入直接发送到 API
❌ 忘记处理工具执行错误
❌ 未裁剪消息就超出上下文窗口
❌ 使用过时的模型 ID(例如 claude-2.1)
已知问题预防
此技能可预防 12 个已记录的问题:
问题 #1:速率限制 429 错误且未进行退避
错误:429 Too Many Requests: Number of request tokens has exceeded your per-minute rate limit
来源:https://docs.claude.com/en/api/errors
原因:超出 RPM、TPM 或每日令牌限额
预防措施:实现指数退避,并遵循 retry-after 标头
问题 #2:流式 SSE 解析错误
错误:数据块不完整、SSE 事件格式错误 来源:常见 SDK 问题(GitHub #323) 原因:网络中断、事件解析不当 预防措施:使用 SDK 流式辅助工具,并实现错误事件监听器
问题 #3:提示词缓存未生效
错误:尽管设置了 cache_control 块,费用仍然很高
来源:https://docs.claude.com/en/docs/build-with-claude/prompt-caching
原因:cache_control 放置位置不正确(必须放在末尾)
预防措施:始终将 cache_control 放在可缓存内容的最后一个块上
问题 #4:工具使用响应格式错误
错误:invalid_request_error: tools[0].input_schema is invalid
来源:API 验证错误
原因:JSON Schema 无效、缺少必填字段
预防措施:使用 JSON Schema 验证器检查架构,并进行全面测试
问题 #5:视觉图像格式问题
错误:invalid_request_error: image source must be base64 or url
来源:API 文档
原因:编码不正确、格式不受支持
预防措施:验证格式(JPEG/PNG/WebP/GIF),并确保 base64 编码正确
问题 #6:计费令牌计数不匹配
错误:费用意外偏高、超出上下文窗口 来源:令牌计数差异 原因:未将特殊令牌和格式纳入计算 预防措施:使用官方令牌计数器,并监控用量标头
问题 #7:System prompt 顺序问题
错误:system prompt 被忽略或覆盖 来源:API 行为 原因:system prompt 放在 messages 数组之后 预防措施:务必将 system prompt 放在 messages 之前
问题 #8:超出上下文窗口(200k)
错误:invalid_request_error: messages: too many tokens
来源:模型限制
原因:长对话未裁剪
预防措施:实现消息历史裁剪,并使用缓存
问题 #9:在错误的模型上使用 Extended Thinking
错误:响应中没有思考块 来源:模型能力 原因:使用了 Claude 3.5 Sonnet,而不是 3.7/4 预防措施:仅在 Claude 3.7 Sonnet 或 Claude 4 上使用 extended thinking
问题 #10:客户端代码中暴露 API key
错误:CORS 错误、安全漏洞 来源:安全最佳实践 原因:从浏览器发起 API 调用 预防措施:仅在服务端调用,并使用环境变量
问题 #11:混淆速率限制层级
错误:限制低于预期 来源:账户层级系统 原因:不了解层级递进机制 预防措施:在 Console 中检查当前层级;层级会随用量自动提升
问题 #12:消息批次缺少 Beta 标头
错误:invalid_request_error: unknown parameter: batches
来源:Beta API 要求
原因:缺少 anthropic-beta 标头
预防措施:添加 anthropic-beta: message-batches-2024-09-24 标头
依赖项
必需(如果使用 SDK):
- @anthropic-ai/[email protected]+ - 官方 TypeScript SDK
可选(用于增强功能):
- [email protected]+ - 使用 betaZodTool 定义类型安全的工具架构
- @types/[email protected]+ - Node.js 的 TypeScript 类型
平台特定依赖:
- Cloudflare Workers:无(使用 fetch API)
- Next.js:[email protected]+ 或 15.x.x
- Node.js:v18.0.0+(用于原生 fetch)
官方文档
- Claude API:https://docs.claude.com/en/api
- Messages API:https://docs.claude.com/en/api/messages
- 提示词缓存:https://docs.claude.com/en/docs/build-with-claude/prompt-caching
- 工具使用:https://docs.claude.com/en/docs/build-with-claude/tool-use
- 视觉:https://docs.claude.com/en/docs/build-with-claude/vision
- 速率限制:https://docs.claude.com/en/api/rate-limits
- 错误:https://docs.claude.com/en/api/errors
- TypeScript SDK:https://github.com/anthropics/anthropic-sdk-typescript
- Context7 库 ID:/anthropics/anthropic-sdk-typescript
软件包版本(已于 2025-10-25 验证)
{
"dependencies": {
"@anthropic-ai/sdk": "^0.67.0"
},
"devDependencies": {
"@types/node": "^20.0.0",
"typescript": "^5.3.0",
"zod": "^3.23.0"
}
}
生产环境示例
此技能基于 Anthropic 官方文档和 SDK 模式:
- 在线示例:Anthropic Cookbook (https://github.com/anthropics/anthropic-cookbook)
- 验证:✅ 已使用 SDK 0.67.0 测试所有模式
- 成本优化:已验证提示词缓存可节省 90% 成本
- 平台支持:已测试 Cloudflare Workers、Next.js、Node.js
故障排除
问题:429 速率限制错误持续出现
解决方案:在 Console 中检查当前等级,实施适当的退避策略,并考虑批处理
问题:提示词缓存不起作用
解决方案:确保内容不少于 1024 个 token,将 cache_control 放在末尾,并检查使用情况标头
问题:工具使用循环永不结束
解决方案:设置 max_iterations,添加超时,并验证工具响应
问题:流式响应在中途截断
解决方案:增加 max_tokens,检查网络稳定性,并实现重新连接逻辑
问题:未显示扩展思考
解决方案:确认使用的是 Claude 3.7 Sonnet 或 Claude 4(而非 3.5 Sonnet)
问题:图像 token 使用量过高
解决方案:编码前压缩图像,对重复图像使用缓存
完整设置清单
- 已从 Console 获取 API 密钥(https://console.anthropic.com/)
- 已将 API 密钥存储在环境变量中
- 已安装 SDK (@anthropic-ai/[email protected]+) 或已准备好 fetch API
- 已实现错误处理(try/catch、错误事件)
- 已使用指数退避处理速率限制
- 已处理流式响应错误(错误事件监听器)
- 已监控 token 使用量(输入 + 输出 + 缓存)
- 仅在服务端调用(不在客户端调用 API)
- 使用最新的模型 ID (claude-sonnet-4-5-20250929)
- 已配置提示词缓存(如果使用长上下文)
- 已验证工具架构(如果使用函数调用)
- 已在正确的模型(3.7/4)上验证扩展思考
有疑问或遇到问题?
- 查看 references/top-errors.md,了解常见问题
- 检查设置流程中的所有步骤
- 查看官方文档:https://docs.claude.com/en/api
- 确保 API 密钥在 Console 中具有正确的权限
Token 效率:与手动集成 API 相比,节省约 62%(估算) 错误预防:100%(已预防全部 12 个已记录的问题) 开发时间:使用模板需 5 分钟,手动开发则需 2 小时以上