claude-api
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseClaude API - Structured Outputs & Error Prevention Guide
Claude API - 结构化输出与错误预防指南
Package: @anthropic-ai/sdk@0.71.2
Breaking Changes: Oct 2025 - Claude 3.5/3.7 models retired, Nov 2025 - Structured outputs beta
Last Updated: 2026-01-09
Package: @anthropic-ai/sdk@0.71.2
重大变更: 2025年10月 - Claude 3.5/3.7模型停用,2025年11月 - 结构化输出进入公测阶段
最后更新: 2026-01-09
What's New in v0.69.0+ (Nov 2025)
v0.69.0+(2025年11月)新特性
Major Features:
主要功能:
1. Structured Outputs (v0.69.0, Nov 14, 2025) - CRITICAL ⭐
1. 结构化输出(v0.69.0,2025年11月14日)- 核心功能 ⭐
Guaranteed JSON schema conformance - Claude's responses strictly follow your JSON schema with two modes.
⚠️ ACCURACY CAVEAT: Structured outputs guarantee format compliance, NOT accuracy. Models can still hallucinate—you get "perfectly formatted incorrect answers." Always validate semantic correctness (see below).
JSON Outputs () - For data extraction and formatting:
output_formattypescript
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: 'Extract contact info: John Doe, john@example.com, 555-1234' }],
betas: ['structured-outputs-2025-11-13'],
output_format: {
type: 'json_schema',
json_schema: {
name: 'Contact',
strict: true,
schema: {
type: 'object',
properties: {
name: { type: 'string' },
email: { type: 'string' },
phone: { type: 'string' }
},
required: ['name', 'email', 'phone'],
additionalProperties: false
}
}
}
});
// Guaranteed valid JSON matching schema
const contact = JSON.parse(message.content[0].text);
console.log(contact.name); // "John Doe"Strict Tool Use () - For validated function parameters:
strict: truetypescript
const message = await anthropic.messages.create({
model: 'claude-sonnet-4-5-20250929',
max_tokens: 1024,
messages: [{ role: 'user', content: 'Get weather for San Francisco' }],
betas: ['structured-outputs-2025-11-13'],
tools: [{
name: 'get_weather',
description: 'Get current weather',
input_schema: {
type: 'object',
properties: {
location: { type: 'string' },
unit: { type: 'string', enum: ['celsius', 'fahrenheit'] }
},
required: ['location'],
additionalProperties: false
},
strict: true // ← Guarantees schema compliance
}]
});Requirements:
- Beta header: (via
structured-outputs-2025-11-13array)betas - Models: Claude Opus 4.5, Claude Sonnet 4.5, Claude Opus 4 (best models only)
- SDK: v0.69.0+ required
Limitations:
- ❌ No recursive schemas
- ❌ No numerical constraints (,
minimum)maximum - ❌ Limited regex support (no backreferences/lookahead)
- ❌ Incompatible with citations and message prefilling
- ⚠️ Grammar compilation adds latency on first request (cached 24hrs)
Performance Characteristics:
- First request: +200-500ms latency for grammar compilation
- Subsequent requests: Normal latency (grammar cached for 24 hours)
- Cache sharing: Only with IDENTICAL schemas (small changes = recompilation)
Pre-warming critical schemas:
typescript
// Pre-compile schemas during server startup
const warmupMessage = await anthropic.messages.create({
model: 'claude-sonnet-4-5-20250929',
max_tokens: 10,
messages: [{ role: 'user', content: 'warmup' }],
betas: ['structured-outputs-2025-11-13'],
output_format: {
type: 'json_schema',
json_schema: YOUR_CRITICAL_SCHEMA
}
});
// Later requests use cached grammarSemantic Validation (CRITICAL):
typescript
const message = await anthropic.messages.create({
model: 'claude-sonnet-4-5-20250929',
messages: [{ role: 'user', content: 'Extract contact: John Doe' }],
betas: ['structured-outputs-2025-11-13'],
output_format: {
type: 'json_schema',
json_schema: contactSchema
}
});
const contact = JSON.parse(message.content[0].text);
// ✅ Format is guaranteed valid
// ❌ Content may be hallucinated
// ALWAYS validate semantic correctness
if (!isValidEmail(contact.email)) {
throw new Error('Hallucinated email detected');
}
if (contact.age < 0 || contact.age > 120) {
throw new Error('Implausible age value');
}When to Use:
- Data extraction from unstructured text
- API response formatting
- Agentic workflows requiring validated tool inputs
- Eliminating JSON parse errors
⚠️ SDK v0.71.1+ Deprecation: Direct property access is deprecated. Check SDK docs for updated API.
.parsed保证JSON Schema一致性 - Claude的响应将严格遵循你定义的JSON Schema,支持两种模式。
⚠️ 准确性说明: 结构化输出仅保证格式合规,不保证内容准确性。模型仍可能产生幻觉——你会得到"格式完全正确但内容错误的答案"。请始终验证语义正确性(见下文)。
JSON输出() - 用于数据提取与格式化:
output_formattypescript
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: 'Extract contact info: John Doe, john@example.com, 555-1234' }],
betas: ['structured-outputs-2025-11-13'],
output_format: {
type: 'json_schema',
json_schema: {
name: 'Contact',
strict: true,
schema: {
type: 'object',
properties: {
name: { type: 'string' },
email: { type: 'string' },
phone: { type: 'string' }
},
required: ['name', 'email', 'phone'],
additionalProperties: false
}
}
}
});
// Guaranteed valid JSON matching schema
const contact = JSON.parse(message.content[0].text);
console.log(contact.name); // "John Doe"严格工具调用() - 用于验证函数参数:
strict: truetypescript
const message = await anthropic.messages.create({
model: 'claude-sonnet-4-5-20250929',
max_tokens: 1024,
messages: [{ role: 'user', content: 'Get weather for San Francisco' }],
betas: ['structured-outputs-2025-11-13'],
tools: [{
name: 'get_weather',
description: 'Get current weather',
input_schema: {
type: 'object',
properties: {
location: { type: 'string' },
unit: { type: 'string', enum: ['celsius', 'fahrenheit'] }
},
required: ['location'],
additionalProperties: false
},
strict: true // ← Guarantees schema compliance
}]
});要求:
- 公测头: (通过
structured-outputs-2025-11-13数组传入)betas - 模型: Claude Opus 4.5、Claude Sonnet 4.5、Claude Opus 4(仅限最优模型)
- SDK: 需v0.69.0及以上版本
限制:
- ❌ 不支持递归Schema
- ❌ 不支持数值约束(、
minimum)maximum - ❌ 正则表达式支持有限(不支持反向引用/正向预查)
- ❌ 与引用标注和消息预填充不兼容
- ⚠️ 首次请求时语法编译会增加延迟(缓存24小时)
性能特点:
- 首次请求: 语法编译增加200-500ms延迟
- 后续请求: 正常延迟(语法缓存24小时)
- 缓存共享: 仅适用于完全相同的Schema(微小改动会触发重新编译)
预加载核心Schema:
typescript
// 在服务器启动时预编译Schema
const warmupMessage = await anthropic.messages.create({
model: 'claude-sonnet-4-5-20250929',
max_tokens: 10,
messages: [{ role: 'user', content: 'warmup' }],
betas: ['structured-outputs-2025-11-13'],
output_format: {
type: 'json_schema',
json_schema: YOUR_CRITICAL_SCHEMA
}
});
// 后续请求将使用缓存的语法语义验证(核心步骤):
typescript
const message = await anthropic.messages.create({
model: 'claude-sonnet-4-5-20250929',
messages: [{ role: 'user', content: 'Extract contact: John Doe' }],
betas: ['structured-outputs-2025-11-13'],
output_format: {
type: 'json_schema',
json_schema: contactSchema
}
});
const contact = JSON.parse(message.content[0].text);
// ✅ 格式保证有效
// ❌ 内容可能存在幻觉
// 始终验证语义正确性
if (!isValidEmail(contact.email)) {
throw new Error('Hallucinated email detected');
}
if (contact.age < 0 || contact.age > 120) {
throw new Error('Implausible age value');
}适用场景:
- 从非结构化文本中提取数据
- API响应格式化
- 需要验证工具输入的Agent工作流
- 消除JSON解析错误
⚠️ SDK v0.71.1+弃用说明: 直接访问属性已被弃用,请查看SDK文档获取更新后的API。
.parsed2. Model Changes (Oct 2025) - BREAKING
2. 模型变更(2025年10月)- 重大变更
Retired (return errors):
- ❌ Claude 3.5 Sonnet (all versions)
- ❌ Claude 3.7 Sonnet - DEPRECATED (Oct 28, 2025)
Active Models (Jan 2026):
| Model | ID | Context | Best For | Cost (per MTok) |
|---|---|---|---|---|
| Claude Opus 4.5 | claude-opus-4-5-20251101 | 200k | Flagship - best reasoning, coding, agents | $5/$25 (in/out) |
| Claude Sonnet 4.5 | claude-sonnet-4-5-20250929 | 200k | Balanced performance | $3/$15 (in/out) |
| Claude Opus 4 | claude-opus-4-20250514 | 200k | High capability | $15/$75 |
| Claude Haiku 4.5 | claude-haiku-4-5-20250929 | 200k | Near-frontier, fast | $1/$5 |
Note: Claude 3.x models (3.5 Sonnet, 3.7 Sonnet, etc.) are deprecated. Use Claude 4.x+ models.
已停用(调用将返回错误):
- ❌ Claude 3.5 Sonnet(所有版本)
- ❌ Claude 3.7 Sonnet - 已弃用(2025年10月28日)
当前可用模型(2026年1月):
| 模型 | ID | 上下文窗口 | 最佳适用场景 | 成本(每百万Token) |
|---|---|---|---|---|
| Claude Opus 4.5 | claude-opus-4-5-20251101 | 200k | 旗舰模型 - 推理、编码、Agent能力最优 | $5/$25(输入/输出) |
| Claude Sonnet 4.5 | claude-sonnet-4-5-20250929 | 200k | 性能均衡 | $3/$15(输入/输出) |
| Claude Opus 4 | claude-opus-4-20250514 | 200k | 高能力模型 | $15/$75 |
| Claude Haiku 4.5 | claude-haiku-4-5-20250929 | 200k | 接近前沿水平,速度快 | $1/$5 |
注意: Claude 3.x系列模型(3.5 Sonnet、3.7 Sonnet等)已被弃用,请使用Claude 4.x及以上版本。
3. Context Management (Oct 28, 2025)
3. 上下文管理(2025年10月28日)
Clear Thinking Blocks - Automatic thinking block cleanup:
typescript
const message = await anthropic.messages.create({
model: 'claude-sonnet-4-5-20250929',
max_tokens: 4096,
messages: [{ role: 'user', content: 'Solve complex problem' }],
betas: ['clear_thinking_20251015']
});
// Thinking blocks automatically managed清晰思维块 - 自动管理思维块:
typescript
const message = await anthropic.messages.create({
model: 'claude-sonnet-4-5-20250929',
max_tokens: 4096,
messages: [{ role: 'user', content: 'Solve complex problem' }],
betas: ['clear_thinking_20251015']
});
// Thinking blocks automatically managed4. Agent Skills API (Oct 16, 2025)
4. Agent技能API(2025年10月16日)
Pre-built skills for Office files (PowerPoint, Excel, Word, PDF):
typescript
const message = await anthropic.messages.create({
model: 'claude-sonnet-4-5-20250929',
max_tokens: 1024,
messages: [{ role: 'user', content: 'Analyze this spreadsheet' }],
betas: ['skills-2025-10-02'],
// Requires code execution tool enabled
});针对Office文件(PowerPoint、Excel、Word、PDF)的预构建技能:
typescript
const message = await anthropic.messages.create({
model: 'claude-sonnet-4-5-20250929',
max_tokens: 1024,
messages: [{ role: 'user', content: 'Analyze this spreadsheet' }],
betas: ['skills-2025-10-02'],
// Requires code execution tool enabled
});Streaming Responses (SSE)
流式响应(SSE)
CRITICAL Error Pattern - Errors occur AFTER initial 200 response:
typescript
const stream = anthropic.messages.stream({
model: 'claude-sonnet-4-5-20250929',
max_tokens: 1024,
messages: [{ role: 'user', content: 'Hello' }],
});
stream
.on('error', (error) => {
// Error can occur AFTER stream starts
console.error('Stream error:', error);
// Implement fallback or retry logic
})
.on('abort', (error) => {
console.warn('Stream aborted:', error);
});Why this matters: Unlike regular HTTP errors, SSE errors happen mid-stream after 200 OK, requiring error event listeners
核心错误模式 - 错误可能在初始200响应后出现:
typescript
const stream = anthropic.messages.stream({
model: 'claude-sonnet-4-5-20250929',
max_tokens: 1024,
messages: [{ role: 'user', content: 'Hello' }],
});
stream
.on('error', (error) => {
// Error can occur AFTER stream starts
console.error('Stream error:', error);
// Implement fallback or retry logic
})
.on('abort', (error) => {
console.warn('Stream aborted:', error);
});重要性: 与常规HTTP错误不同,SSE错误会在200 OK响应后的流传输过程中发生,因此需要监听错误事件
Prompt Caching (⭐ 90% Cost Savings)
提示词缓存(⭐ 节省90%成本)
CRITICAL Rule - MUST be on LAST block:
cache_controltypescript
const message = await anthropic.messages.create({
model: 'claude-sonnet-4-5-20250929',
max_tokens: 1024,
system: [
{
type: 'text',
text: 'System instructions...',
},
{
type: 'text',
text: LARGE_CODEBASE, // 50k tokens
cache_control: { type: 'ephemeral' }, // ← MUST be on LAST block
},
],
messages: [{ role: 'user', content: 'Explain auth module' }],
});
// Monitor cache usage
console.log('Cache reads:', message.usage.cache_read_input_tokens);
console.log('Cache writes:', message.usage.cache_creation_input_tokens);Minimum requirements:
- Claude Sonnet 4.5: 1,024 tokens minimum
- Claude Haiku 4.5: 2,048 tokens minimum
- 5-minute TTL (refreshes on each use)
- Cache shared only with IDENTICAL content
⚠️ AWS Bedrock Limitation: Prompt caching does NOT work for Claude 4 family on AWS Bedrock (works for Claude 3.7 Sonnet only). Use direct Anthropic API for Claude 4 caching support. (GitHub Issue #1347)
核心规则 - 必须放在最后一个块上:
cache_controltypescript
const message = await anthropic.messages.create({
model: 'claude-sonnet-4-5-20250929',
max_tokens: 1024,
system: [
{
type: 'text',
text: 'System instructions...',
},
{
type: 'text',
text: LARGE_CODEBASE, // 50k tokens
cache_control: { type: 'ephemeral' }, // ← MUST be on LAST block
},
],
messages: [{ role: 'user', content: 'Explain auth module' }],
});
// Monitor cache usage
console.log('Cache reads:', message.usage.cache_read_input_tokens);
console.log('Cache writes:', message.usage.cache_creation_input_tokens);最低要求:
- Claude Sonnet 4.5: 最少1024个Token
- Claude Haiku 4.5: 最少2048个Token
- 5分钟TTL(每次使用时刷新)
- 仅完全相同的内容可共享缓存
⚠️ AWS Bedrock限制: AWS Bedrock上的Claude 4系列模型不支持提示词缓存(仅Claude 3.7 Sonnet支持)。如需为Claude 4启用缓存支持,请使用Anthropic直接API。(GitHub Issue #1347)
Tool Use (Function Calling)
工具调用(函数调用)
CRITICAL Patterns:
Strict Tool Use (with structured outputs):
typescript
const message = await anthropic.messages.create({
model: 'claude-sonnet-4-5-20250929',
max_tokens: 1024,
betas: ['structured-outputs-2025-11-13'],
tools: [{
name: 'get_weather',
description: 'Get weather data',
input_schema: {
type: 'object',
properties: {
location: { type: 'string' },
unit: { type: 'string', enum: ['celsius', 'fahrenheit'] }
},
required: ['location'],
additionalProperties: false
},
strict: true // ← Guarantees schema compliance
}],
messages: [{ role: 'user', content: 'Weather in NYC?' }]
});Tool Result Pattern - MUST match:
tool_use_idtypescript
const toolResults = [];
for (const block of response.content) {
if (block.type === 'tool_use') {
const result = await executeToolFunction(block.name, block.input);
toolResults.push({
type: 'tool_result',
tool_use_id: block.id, // ← MUST match tool_use block id
content: JSON.stringify(result),
});
}
}
messages.push({
role: 'user',
content: toolResults,
});Error Handling - Handle tool execution failures:
typescript
try {
const result = await executeToolFunction(block.name, block.input);
toolResults.push({
type: 'tool_result',
tool_use_id: block.id,
content: JSON.stringify(result),
});
} catch (error) {
// Return error to Claude for handling
toolResults.push({
type: 'tool_result',
tool_use_id: block.id,
is_error: true,
content: `Tool execution failed: ${error.message}`,
});
}Content Sanitization - Handle Unicode edge cases:
typescript
// U+2028 (LINE SEPARATOR) and U+2029 (PARAGRAPH SEPARATOR) cause JSON parse failures
function sanitizeToolResult(content: string): string {
return content
.replace(/\u2028/g, '\n') // LINE SEPARATOR → newline
.replace(/\u2029/g, '\n'); // PARAGRAPH SEPARATOR → newline
}
const toolResult = {
type: 'tool_result',
tool_use_id: block.id,
content: sanitizeToolResult(result) // Sanitize before sending
};核心模式:
严格工具调用(结合结构化输出):
typescript
const message = await anthropic.messages.create({
model: 'claude-sonnet-4-5-20250929',
max_tokens: 1024,
betas: ['structured-outputs-2025-11-13'],
tools: [{
name: 'get_weather',
description: 'Get weather data',
input_schema: {
type: 'object',
properties: {
location: { type: 'string' },
unit: { type: 'string', enum: ['celsius', 'fahrenheit'] }
},
required: ['location'],
additionalProperties: false
},
strict: true // ← Guarantees schema compliance
}],
messages: [{ role: 'user', content: 'Weather in NYC?' }]
});工具结果模式 - 必须匹配:
tool_use_idtypescript
const toolResults = [];
for (const block of response.content) {
if (block.type === 'tool_use') {
const result = await executeToolFunction(block.name, block.input);
toolResults.push({
type: 'tool_result',
tool_use_id: block.id, // ← MUST match tool_use block id
content: JSON.stringify(result),
});
}
}
messages.push({
role: 'user',
content: toolResults,
});错误处理 - 处理工具执行失败:
typescript
try {
const result = await executeToolFunction(block.name, block.input);
toolResults.push({
type: 'tool_result',
tool_use_id: block.id,
content: JSON.stringify(result),
});
} catch (error) {
// Return error to Claude for handling
toolResults.push({
type: 'tool_result',
tool_use_id: block.id,
is_error: true,
content: `Tool execution failed: ${error.message}`,
});
}内容清理 - 处理Unicode边缘情况:
typescript
// U+2028 (LINE SEPARATOR) and U+2029 (PARAGRAPH SEPARATOR) cause JSON parse failures
function sanitizeToolResult(content: string): string {
return content
.replace(/\u2028/g, '\n') // LINE SEPARATOR → newline
.replace(/\u2029/g, '\n'); // PARAGRAPH SEPARATOR → newline
}
const toolResult = {
type: 'tool_result',
tool_use_id: block.id,
content: sanitizeToolResult(result) // Sanitize before sending
};Vision (Image Understanding)
视觉能力(图像理解)
CRITICAL Rules:
- Formats: JPEG, PNG, WebP, GIF (non-animated)
- Max size: 5MB per image
- Base64 overhead: ~33% size increase
- Context impact: Images count toward token limit
- Caching: Consider for repeated image analysis
Format validation - Check before encoding:
typescript
const validFormats = ['image/jpeg', 'image/png', 'image/webp', 'image/gif'];
if (!validFormats.includes(mimeType)) {
throw new Error(`Unsupported format: ${mimeType}`);
}核心规则:
- 格式: JPEG、PNG、WebP、GIF(非动画)
- 最大尺寸: 每张图片5MB
- Base64开销: 尺寸增加约33%
- 上下文影响: 图片会占用Token额度
- 缓存: 重复分析图片时可考虑使用缓存
格式验证 - 编码前检查:
typescript
const validFormats = ['image/jpeg', 'image/png', 'image/webp', 'image/gif'];
if (!validFormats.includes(mimeType)) {
throw new Error(`Unsupported format: ${mimeType}`);
}Extended Thinking Mode
扩展思考模式
⚠️ Model Compatibility:
- ❌ Claude 3.7 Sonnet - DEPRECATED (Oct 28, 2025)
- ❌ Claude 3.5 Sonnet - RETIRED (not supported)
- ✅ Claude Opus 4.5 - Extended thinking supported (flagship)
- ✅ Claude Sonnet 4.5 - Extended thinking supported
- ✅ Claude Opus 4 - Extended thinking supported
CRITICAL:
- Thinking blocks are NOT cacheable
- Requires higher (thinking consumes tokens)
max_tokens - Check model before expecting thinking blocks
⚠️ 模型兼容性:
- ❌ Claude 3.7 Sonnet - 已弃用(2025年10月28日)
- ❌ Claude 3.5 Sonnet - 已停用(不支持)
- ✅ Claude Opus 4.5 - 支持扩展思考(旗舰模型)
- ✅ Claude Sonnet 4.5 - 支持扩展思考
- ✅ Claude Opus 4 - 支持扩展思考
核心要点:
- 思维块不可缓存
- 需要更高的(思考过程会消耗Token)
max_tokens - 期望获得思维块前请确认模型支持
Rate Limits
速率限制
CRITICAL Pattern - Respect header with exponential backoff:
retry-aftertypescript
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) {
// CRITICAL: Use retry-after header if present
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');
}Rate limit headers:
- - Total RPM allowed
anthropic-ratelimit-requests-limit - - Remaining requests
anthropic-ratelimit-requests-remaining - - Reset timestamp
anthropic-ratelimit-requests-reset
核心模式 - 遵循头并使用指数退避:
retry-aftertypescript
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) {
// CRITICAL: Use retry-after header if present
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');
}速率限制头:
- - 允许的总请求数/分钟
anthropic-ratelimit-requests-limit - - 剩余请求数
anthropic-ratelimit-requests-remaining - - 重置时间戳
anthropic-ratelimit-requests-reset
Error Handling
错误处理
Common Error Codes:
| Status | Error Type | Cause | Solution |
|---|---|---|---|
| 400 | invalid_request_error | Bad parameters | Validate request body |
| 401 | authentication_error | Invalid API key | Check env variable |
| 403 | permission_error | No access to feature | Check account tier |
| 404 | not_found_error | Invalid endpoint | Check API version |
| 429 | rate_limit_error | Too many requests | Implement retry logic |
| 500 | api_error | Internal error | Retry with backoff |
| 529 | overloaded_error | System overloaded | Retry later |
CRITICAL:
- Streaming errors occur AFTER initial 200 response
- Always implement error event listeners for streams
- Respect header on 429 errors
retry-after - Have fallback strategies for critical operations
常见错误码:
| 状态码 | 错误类型 | 原因 | 解决方案 |
|---|---|---|---|
| 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 | 系统过载 | 稍后重试 |
核心要点:
- 流式错误会在初始200响应后出现
- 始终为流实现错误事件监听器
- 429错误时请遵循头
retry-after - 为核心操作准备回退策略
Known Issues Prevention
已知问题预防
This skill prevents 16 documented issues:
本技能可预防16种已记录的问题:
Issue #1: Rate Limit 429 Errors Without Backoff
问题#1: 未使用退避策略导致的429速率限制错误
Error:
Source: https://docs.claude.com/en/api/errors
Why It Happens: Exceeding RPM, TPM, or daily token limits
Prevention: Implement exponential backoff with header respect
429 Too Many Requests: Number of request tokens has exceeded your per-minute rate limitretry-after错误:
来源: https://docs.claude.com/en/api/errors
原因: 超出请求数/分钟、Token数/分钟或每日Token限制
预防: 实现指数退避策略并遵循头
429 Too Many Requests: Number of request tokens has exceeded your per-minute rate limitretry-afterIssue #2: Streaming SSE Parsing Errors
问题#2: SSE流式传输解析错误
Error: Incomplete chunks, malformed SSE events
Source: Common SDK issue (GitHub #323)
Why It Happens: Network interruptions, improper event parsing
Prevention: Use SDK stream helpers, implement error event listeners
错误: 不完整的块、格式错误的SSE事件
来源: 常见SDK问题(GitHub #323)
原因: 网络中断、事件解析不当
预防: 使用SDK流助手,实现错误事件监听器
Issue #3: Prompt Caching Not Activating
问题#3: 提示词缓存未激活
Error: High costs despite cache_control blocks
Source: https://platform.claude.com/docs/en/build-with-claude/prompt-caching
Why It Happens: placed incorrectly (must be at END)
Prevention: Always place on LAST block of cacheable content
cache_controlcache_control错误: 已添加cache_control块但成本仍居高不下
来源: https://platform.claude.com/docs/en/build-with-claude/prompt-caching
原因: 放置位置错误(必须在最后)
预防: 始终将放在可缓存内容的最后一个块上
cache_controlcache_controlIssue #4: Tool Use Response Format Errors
问题#4: 工具调用响应格式错误
Error:
Source: API validation errors
Why It Happens: Invalid JSON Schema, missing required fields
Prevention: Validate schemas with JSON Schema validator, test thoroughly
invalid_request_error: tools[0].input_schema is invalid错误:
来源: API验证错误
原因: JSON Schema无效、缺少必填字段
预防: 使用JSON Schema验证器验证Schema,充分测试
invalid_request_error: tools[0].input_schema is invalidIssue #5: Vision Image Format Issues
问题#5: 视觉能力图片格式问题
Error:
Source: API documentation
Why It Happens: Incorrect encoding, unsupported formats
Prevention: Validate format (JPEG/PNG/WebP/GIF), proper base64 encoding
invalid_request_error: image source must be base64 or url错误:
来源: API文档
原因: 编码错误、格式不支持
预防: 验证格式(JPEG/PNG/WebP/GIF),正确进行Base64编码
invalid_request_error: image source must be base64 or urlIssue #6: Token Counting Mismatches for Billing
问题#6: 计费Token计数不匹配
Error: Unexpected high costs, context window exceeded
Source: Token counting differences
Why It Happens: Not accounting for special tokens, formatting
Prevention: Use official token counter, monitor usage headers
错误: 成本超出预期、上下文窗口超限
来源: Token计数差异
原因: 未考虑特殊Token、格式影响
预防: 使用官方Token计数器,监控使用头
Issue #7: System Prompt Ordering Issues
问题#7: 系统提示词顺序问题
Error: System prompt ignored or overridden
Source: API behavior
Why It Happens: System prompt placed after messages array
Prevention: ALWAYS place system prompt before messages
错误: 系统提示词被忽略或覆盖
来源: API行为特性
原因: 系统提示词放在messages数组之后
预防: 始终将系统提示词放在messages之前
Issue #8: Context Window Exceeded (200k)
问题#8: 上下文窗口超限(200k)
Error:
Source: Model limits
Why It Happens: Long conversations without pruning
Prevention: Implement message history pruning, use caching
invalid_request_error: messages: too many tokens错误:
来源: 模型限制
原因: 对话过长未进行修剪
预防: 实现消息历史修剪,使用缓存
invalid_request_error: messages: too many tokensIssue #9: Extended Thinking on Wrong Model
问题#9: 在错误的模型上使用扩展思考
Error: No thinking blocks in response
Source: Model capabilities
Why It Happens: Using retired/deprecated models (3.5/3.7 Sonnet)
Prevention: Only use extended thinking with Claude Opus 4.5, Claude Sonnet 4.5, or Claude Opus 4
错误: 响应中无思维块
来源: 模型能力限制
原因: 使用已停用/弃用的模型(3.5/3.7 Sonnet)
预防: 仅在Claude Opus 4.5、Claude Sonnet 4.5或Claude Opus 4上使用扩展思考
Issue #10: API Key Exposure in Client Code
问题#10: 客户端代码中暴露API密钥
Error: CORS errors, security vulnerability
Source: Security best practices
Why It Happens: Making API calls from browser
Prevention: Server-side only, use environment variables
错误: CORS错误、安全漏洞
来源: 安全最佳实践
原因: 在浏览器中直接调用API
预防: 仅在服务端调用,使用环境变量
Issue #11: Rate Limit Tier Confusion
问题#11: 速率限制层级混淆
Error: Lower limits than expected
Source: Account tier system
Why It Happens: Not understanding tier progression
Prevention: Check Console for current tier, auto-scales with usage
错误: 限制低于预期
来源: 账户层级系统
原因: 不了解层级进阶规则
预防: 查看控制台当前层级,使用量会自动触发层级升级
Issue #12: Message Batches Beta Headers Missing
问题#12: 消息批量公测头缺失
Error:
Source: Beta API requirements
Why It Happens: Missing header
Prevention: Include header
invalid_request_error: unknown parameter: batchesanthropic-betaanthropic-beta: message-batches-2024-09-24错误:
来源: 公测API要求
原因: 缺少头
预防: 添加头
invalid_request_error: unknown parameter: batchesanthropic-betaanthropic-beta: message-batches-2024-09-24Issue #13: Stream Errors Not Catchable with .withResponse() (Fixed in v0.71.2)
问题#13: 使用.withResponse()时无法捕获流错误(v0.71.2已修复)
Error: Unhandled promise rejection when using
Source: GitHub Issue #856
Why It Happens: SDK internal error handling prevented user catch blocks from working (pre-v0.71.2)
Prevention: Upgrade to v0.71.2+ or use event listeners instead
messages.stream().withResponse()Fixed in v0.71.2+:
typescript
try {
const stream = await anthropic.messages.stream({
model: 'claude-sonnet-4-5-20250929',
max_tokens: 1024,
messages: [{ role: 'user', content: 'Hello' }]
}).withResponse();
} catch (error) {
// Now properly catchable in v0.71.2+
console.error('Stream error:', error);
}Workaround for pre-v0.71.2:
typescript
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);
});错误: 使用时出现未处理的Promise拒绝
来源: GitHub Issue #856
原因: SDK内部错误处理导致用户捕获块失效(v0.71.2之前版本)
预防: 升级到v0.71.2及以上版本,或使用事件监听器替代
messages.stream().withResponse()v0.71.2及以上版本已修复:
typescript
try {
const stream = await anthropic.messages.stream({
model: 'claude-sonnet-4-5-20250929',
max_tokens: 1024,
messages: [{ role: 'user', content: 'Hello' }]
}).withResponse();
} catch (error) {
// Now properly catchable in v0.71.2+
console.error('Stream error:', error);
}v0.71.2之前版本的解决方法:
typescript
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);
});Issue #14: MCP Tool Connections Cause 2-Minute Timeout
问题#14: MCP工具连接导致2分钟超时
Error: / after ~121 seconds
Source: GitHub Issue #842
Why It Happens: MCP server connection management conflicts with long-running requests, even when MCP tools are not actively used
Prevention: Use direct toolRunner instead of MCP for requests >2 minutes
Connection error499 Client disconnectedSymptoms:
- Request works fine without MCP
- Fails at exactly ~121 seconds with MCP registered
- Dashboard shows: "Client disconnected (code 499)"
- Multiple users confirmed across streaming and non-streaming
Workaround:
typescript
// Don't use MCP for long requests
const message = await anthropic.beta.messages.toolRunner({
model: 'claude-sonnet-4-5-20250929',
max_tokens: 4096,
messages: [{ role: 'user', content: 'Long task >2 min' }],
tools: [customTools] // Direct tool definitions, not MCP
});Note: This is a known limitation with no official fix. Consider architecture changes if long-running requests with tools are required.
错误: / (约121秒后)
来源: GitHub Issue #842
原因: 即使未主动使用MCP工具,MCP服务器连接管理也会与长时间运行的请求冲突
预防: 对于超过2分钟的请求,使用直接toolRunner而非MCP
Connection error499 Client disconnected症状:
- 不使用MCP时请求正常
- 使用MCP注册后,请求在约121秒时失败
- 控制台显示: "Client disconnected (code 499)"
- 流式和非流式请求均有多个用户确认此问题
解决方法:
typescript
// 长时间请求不要使用MCP
const message = await anthropic.beta.messages.toolRunner({
model: 'claude-sonnet-4-5-20250929',
max_tokens: 4096,
messages: [{ role: 'user', content: 'Long task >2 min' }],
tools: [customTools] // 直接定义工具,不使用MCP
});注意: 这是已知限制,暂无官方修复。如果需要长时间运行的工具调用,请考虑架构调整。
Issue #15: Structured Outputs Hallucination Risk
问题#15: 结构化输出幻觉风险
Error: Valid JSON format but incorrect/hallucinated content
Source: Structured Outputs Docs
Why It Happens: Structured outputs guarantee format compliance, NOT accuracy
Prevention: Always validate semantic correctness, not just format
typescript
const message = await anthropic.messages.create({
model: 'claude-sonnet-4-5-20250929',
messages: [{ role: 'user', content: 'Extract contact: John Doe' }],
betas: ['structured-outputs-2025-11-13'],
output_format: {
type: 'json_schema',
json_schema: contactSchema
}
});
const contact = JSON.parse(message.content[0].text);
// ✅ Format is guaranteed valid
// ❌ Content may be hallucinated
// CRITICAL: Validate semantic correctness
if (!isValidEmail(contact.email)) {
throw new Error('Hallucinated email detected');
}
if (contact.age < 0 || contact.age > 120) {
throw new Error('Implausible age value');
}错误: JSON格式有效但内容错误/存在幻觉
来源: 结构化输出文档
原因: 结构化输出仅保证格式合规,不保证内容准确性
预防: 始终验证语义正确性,而非仅验证格式
typescript
const message = await anthropic.messages.create({
model: 'claude-sonnet-4-5-20250929',
messages: [{ role: 'user', content: 'Extract contact: John Doe' }],
betas: ['structured-outputs-2025-11-13'],
output_format: {
type: 'json_schema',
json_schema: contactSchema
}
});
const contact = JSON.parse(message.content[0].text);
// ✅ Format is guaranteed valid
// ❌ Content may be hallucinated
// CRITICAL: Validate semantic correctness
if (!isValidEmail(contact.email)) {
throw new Error('Hallucinated email detected');
}
if (contact.age < 0 || contact.age > 120) {
throw new Error('Implausible age value');
}Issue #16: U+2028 Line Separator in Tool Results (Community-sourced)
问题#16: 工具结果中的U+2028行分隔符(社区发现)
Error: JSON parsing failures or silent errors when tool results contain U+2028
Source: GitHub Issue #882
Why It Happens: U+2028 is valid in JSON but not in JavaScript string literals
Prevention: Sanitize tool results before passing to SDK
typescript
function sanitizeToolResult(content: string): string {
return content
.replace(/\u2028/g, '\n') // LINE SEPARATOR → newline
.replace(/\u2029/g, '\n'); // PARAGRAPH SEPARATOR → newline
}
const toolResult = {
type: 'tool_result',
tool_use_id: block.id,
content: sanitizeToolResult(result)
};错误: 工具结果包含U+2028时出现JSON解析失败或静默错误
来源: GitHub Issue #882
原因: U+2028在JSON中有效,但在JavaScript字符串字面量中无效
预防: 传递给SDK前清理工具结果
typescript
function sanitizeToolResult(content: string): string {
return content
.replace(/\u2028/g, '\n') // LINE SEPARATOR → newline
.replace(/\u2029/g, '\n'); // PARAGRAPH SEPARATOR → newline
}
const toolResult = {
type: 'tool_result',
tool_use_id: block.id,
content: sanitizeToolResult(result)
};Official Documentation
官方文档
- Claude API: https://platform.claude.com/docs/en/api
- Messages API: https://platform.claude.com/docs/en/api/messages
- Structured Outputs: https://platform.claude.com/docs/en/build-with-claude/structured-outputs
- Prompt Caching: https://platform.claude.com/docs/en/build-with-claude/prompt-caching
- Tool Use: https://platform.claude.com/docs/en/build-with-claude/tool-use
- Vision: https://platform.claude.com/docs/en/build-with-claude/vision
- Rate Limits: https://platform.claude.com/docs/en/api/rate-limits
- Errors: https://platform.claude.com/docs/en/api/errors
- TypeScript SDK: https://github.com/anthropics/anthropic-sdk-typescript
- Context7 Library ID: /anthropics/anthropic-sdk-typescript
- Claude API: https://platform.claude.com/docs/en/api
- Messages API: https://platform.claude.com/docs/en/api/messages
- 结构化输出: https://platform.claude.com/docs/en/build-with-claude/structured-outputs
- 提示词缓存: https://platform.claude.com/docs/en/build-with-claude/prompt-caching
- 工具调用: https://platform.claude.com/docs/en/build-with-claude/tool-use
- 视觉能力: https://platform.claude.com/docs/en/build-with-claude/vision
- 速率限制: https://platform.claude.com/docs/en/api/rate-limits
- 错误: https://platform.claude.com/docs/en/api/errors
- TypeScript SDK: https://github.com/anthropics/anthropic-sdk-typescript
- Context7库ID: /anthropics/anthropic-sdk-typescript
Package Versions
包版本
Latest: @anthropic-ai/sdk@0.71.2
json
{
"dependencies": {
"@anthropic-ai/sdk": "^0.71.2"
},
"devDependencies": {
"@types/node": "^20.0.0",
"typescript": "^5.3.0",
"zod": "^3.23.0"
}
}Token Efficiency:
- Without skill: ~8,000 tokens (basic setup, streaming, caching, tools, vision, errors)
- With skill: ~4,200 tokens (knowledge gaps + error prevention + critical patterns)
- Savings: ~48% (~3,800 tokens)
Errors prevented: 16 documented issues with exact solutions
Key value: Structured outputs (v0.69.0+), model deprecations (Oct 2025), prompt caching edge cases, streaming error patterns, rate limit retry logic, MCP timeout workarounds, hallucination validation
Last verified: 2026-01-20 | Skill version: 2.2.0 | Changes: Added 4 new issues from community research: streaming error handling (fixed in v0.71.2), MCP timeout workaround, structured outputs hallucination validation, U+2028 sanitization; expanded structured outputs section with performance characteristics and accuracy caveats; added AWS Bedrock caching limitation
最新版本: @anthropic-ai/sdk@0.71.2
json
{
"dependencies": {
"@anthropic-ai/sdk": "^0.71.2"
},
"devDependencies": {
"@types/node": "^20.0.0",
"typescript": "^5.3.0",
"zod": "^3.23.0"
}
}Token效率:
- 未使用本技能: ~8000个Token(基础设置、流式传输、缓存、工具、视觉、错误处理)
- 使用本技能: ~4200个Token(知识缺口填补 + 错误预防 + 核心模式)
- 节省: ~48%(约3800个Token)
预防的错误: 16种已记录的问题及精确解决方案
核心价值: 结构化输出(v0.69.0+)、模型弃用说明(2025年10月)、提示词缓存边缘情况、流式错误模式、速率限制重试逻辑、MCP超时解决方法、幻觉验证
最后验证: 2026-01-20 | 技能版本: 2.2.0 | 变更: 新增4个社区研究发现的问题:流式错误处理(v0.71.2已修复)、MCP超时解决方法、结构化输出幻觉验证、U+2028清理;扩展了结构化输出部分,增加性能特点和准确性说明;补充AWS Bedrock缓存限制