claude-api by jezweb/claude-skills
npx skills add https://github.com/jezweb/claude-skills --skill claude-api包 : @anthropic-ai/sdk@0.71.2 重大变更 : 2025年10月 - Claude 3.5/3.7 模型停用,2025年11月 - 结构化输出功能进入测试版 最后更新 : 2026-01-09
主要特性:
保证 JSON 模式一致性 - Claude 的响应严格遵循您的 JSON 模式,提供两种模式。
⚠️ 准确性警告 : 结构化输出保证格式合规性,而非准确性。模型仍可能产生幻觉——您会得到"格式完美但内容错误的答案"。务必验证语义正确性(见下文)。
JSON 输出 (output_format) - 用于数据提取和格式化:
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
}
}
}
});
// 保证是符合模式的有效 JSON
const contact = JSON.parse(message.content[0].text);
console.log(contact.name); // "John Doe"
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
严格工具使用 (strict: true) - 用于验证函数参数:
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 // ← 保证模式合规性
}]
});
要求:
structured-outputs-2025-11-13 (通过 betas 数组)限制:
minimum, maximum)性能特征:
预热关键模式:
// 在服务器启动期间预编译模式
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
}
});
// 后续请求使用缓存的语法
语义验证 (关键):
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('检测到幻觉生成的邮箱');
}
if (contact.age < 0 || contact.age > 120) {
throw new Error('不合理的年龄值');
}
使用场景:
⚠️ SDK v0.71.1+ 弃用 : 直接访问 .parsed 属性已被弃用。请查阅 SDK 文档了解更新的 API。
已停用 (返回错误):
活跃模型 (2026年1月):
| 模型 | ID | 上下文 | 最佳用途 | 成本 (每 MTok) |
|---|---|---|---|---|
| Claude Opus 4.5 | claude-opus-4-5-20251101 | 200k | 旗舰 - 最佳推理、编码、智能体 | $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+ 模型。
清理思考块 - 自动清理思考块:
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']
});
// 思考块自动管理
用于 Office 文件 (PowerPoint, Excel, Word, PDF) 的预构建技能:
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'],
// 需要启用代码执行工具
});
关键错误模式 - 错误发生在初始 200 响应之后:
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('流错误:', error);
// 实施回退或重试逻辑
})
.on('abort', (error) => {
console.warn('流已中止:', error);
});
为何重要 : 与常规 HTTP 错误不同,SSE 错误发生在 200 OK 之后的中途,需要错误事件监听器
关键规则 - cache_control 必须在最后一个块上:
const message = await anthropic.messages.create({
model: 'claude-sonnet-4-5-20250929',
max_tokens: 1024,
system: [
{
type: 'text',
text: '系统指令...',
},
{
type: 'text',
text: LARGE_CODEBASE, // 50k tokens
cache_control: { type: 'ephemeral' }, // ← 必须在最后一个块上
},
],
messages: [{ role: 'user', content: 'Explain auth module' }],
});
// 监控缓存使用情况
console.log('缓存读取:', message.usage.cache_read_input_tokens);
console.log('缓存写入:', message.usage.cache_creation_input_tokens);
最低要求:
⚠️ AWS Bedrock 限制 : 提示缓存不适用于 AWS Bedrock 上的 Claude 4 系列 (仅适用于 Claude 3.7 Sonnet)。对于 Claude 4 缓存支持,请使用直接的 Anthropic API。(GitHub Issue #1347)
关键模式:
严格工具使用 (配合结构化输出):
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 // ← 保证模式合规性
}],
messages: [{ role: 'user', content: 'Weather in NYC?' }]
});
工具结果模式 - tool_use_id 必须匹配:
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, // ← 必须匹配 tool_use 块 id
content: JSON.stringify(result),
});
}
}
messages.push({
role: 'user',
content: toolResults,
});
错误处理 - 处理工具执行失败:
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) {
// 将错误返回给 Claude 处理
toolResults.push({
type: 'tool_result',
tool_use_id: block.id,
is_error: true,
content: `Tool execution failed: ${error.message}`,
});
}
内容清理 - 处理 Unicode 边缘情况:
// U+2028 (行分隔符) 和 U+2029 (段落分隔符) 会导致 JSON 解析失败
function sanitizeToolResult(content: string): string {
return content
.replace(/\u2028/g, '\n') // 行分隔符 → 换行符
.replace(/\u2029/g, '\n'); // 段落分隔符 → 换行符
}
const toolResult = {
type: 'tool_result',
tool_use_id: block.id,
content: sanitizeToolResult(result) // 发送前清理
};
关键规则:
格式验证 - 编码前检查:
const validFormats = ['image/jpeg', 'image/png', 'image/webp', 'image/gif'];
if (!validFormats.includes(mimeType)) {
throw new Error(`Unsupported format: ${mimeType}`);
}
⚠️ 模型兼容性:
关键:
max_tokens (思考消耗 tokens)关键模式 - 使用指数退避尊重 retry-after 头:
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) {
// 关键: 如果存在则使用 retry-after 头
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 - 允许的总 RPManthropic-ratelimit-requests-remaining - 剩余请求数anthropic-ratelimit-requests-reset - 重置时间戳常见错误代码:
| 状态 | 错误类型 | 原因 | 解决方案 |
|---|---|---|---|
| 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 | 系统过载 | 稍后重试 |
关键:
retry-after 头此技能预防 16 个已记录的问题:
错误 : 429 Too Many Requests: Number of request tokens has exceeded your per-minute rate limit 来源 : https://docs.claude.com/en/api/errors 发生原因 : 超过 RPM、TPM 或每日 token 限制 预防 : 实施指数退避并尊重 retry-after 头
错误 : 不完整的块、格式错误的 SSE 事件 来源 : 常见 SDK 问题 (GitHub #323) 发生原因 : 网络中断、事件解析不当 预防 : 使用 SDK 流辅助工具,实现错误事件监听器
错误 : 尽管有 cache_control 块,成本仍然很高 来源 : https://platform.claude.com/docs/en/build-with-claude/prompt-caching 发生原因 : cache_control 放置不正确 (必须在末尾) 预防 : 始终将 cache_control 放在可缓存内容的最后一个块上
错误 : invalid_request_error: tools[0].input_schema is invalid 来源 : API 验证错误 发生原因 : 无效的 JSON 模式,缺少必填字段 预防 : 使用 JSON 模式验证器验证模式,彻底测试
错误 : invalid_request_error: image source must be base64 or url 来源 : API 文档 发生原因 : 编码不正确,格式不支持 预防 : 验证格式 (JPEG/PNG/WebP/GIF),正确进行 base64 编码
错误 : 意外的高成本,超出上下文窗口 来源 : token 计数差异 发生原因 : 未考虑特殊 tokens、格式化 预防 : 使用官方 token 计数器,监控使用情况头
错误 : 系统提示被忽略或覆盖 来源 : API 行为 发生原因 : 系统提示放在 messages 数组之后 预防 : 始终将系统提示放在 messages 之前
错误 : invalid_request_error: messages: too many tokens 来源 : 模型限制 发生原因 : 长对话未修剪 预防 : 实施消息历史修剪,使用缓存
错误 : 响应中没有思考块 来源 : 模型能力 发生原因 : 使用已停用/弃用的模型 (3.5/3.7 Sonnet) 预防 : 仅将扩展思考与 Claude Opus 4.5、Claude Sonnet 4.5 或 Claude Opus 4 一起使用
错误 : CORS 错误,安全漏洞 来源 : 安全最佳实践 发生原因 : 从浏览器调用 API 预防 : 仅限服务器端,使用环境变量
错误 : 限制低于预期 来源 : 账户层级系统 发生原因 : 不理解层级进展 预防 : 在控制台检查当前层级,随使用自动扩展
错误 : invalid_request_error: unknown parameter: batches 来源 : 测试版 API 要求 发生原因 : 缺少 anthropic-beta 头 预防 : 包含 anthropic-beta: message-batches-2024-09-24 头
错误 : 使用 messages.stream().withResponse() 时未处理的 Promise 拒绝 来源 : GitHub Issue #856 发生原因 : SDK 内部错误处理阻止了用户 catch 块工作 (v0.71.2 之前) 预防 : 升级到 v0.71.2+ 或改用事件监听器
已在 v0.71.2+ 修复 :
try {
const stream = await anthropic.messages.stream({
model: 'claude-sonnet-4-5-20250929',
max_tokens: 1024,
messages: [{ role: 'user', content: 'Hello' }]
}).withResponse();
} catch (error) {
// 现在在 v0.71.2+ 中可正确捕获
console.error('流错误:', error);
}
v0.71.2 之前的变通方法 :
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('流错误:', error);
});
错误 : 约 121 秒后出现 Connection error / 499 Client disconnected 来源 : GitHub Issue #842 发生原因 : MCP 服务器连接管理与长时间运行的请求冲突,即使 MCP 工具未被主动使用 预防 : 对于超过 2 分钟的请求,使用直接的 toolRunner 而非 MCP
症状 :
变通方法 :
// 对于长时间请求不要使用 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
});
注意 : 这是一个已知限制,没有官方修复。如果需要使用工具进行长时间运行的请求,请考虑架构变更。
错误 : JSON 格式有效但内容不正确/产生幻觉 来源 : 结构化输出文档 发生原因 : 结构化输出保证格式合规性,而非准确性 预防 : 始终验证语义正确性,而不仅仅是格式
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('检测到幻觉生成的邮箱');
}
if (contact.age < 0 || contact.age > 120) {
throw new Error('不合理的年龄值');
}
错误 : 当工具结果包含 U+2028 时,JSON 解析失败或静默错误 来源 : GitHub Issue #882 发生原因 : U+2028 在 JSON 中有效,但在 JavaScript 字符串字面量中无效 预防 : 在传递给 SDK 之前清理工具结果
function sanitizeToolResult(content: string): string {
return content
.replace(/\u2028/g, '\n') // 行分隔符 → 换行符
.replace(/\u2029/g, '\n'); // 段落分隔符 → 换行符
}
const toolResult = {
type: 'tool_result',
tool_use_id: block.id,
content: sanitizeToolResult(result)
};
最新 : @anthropic-ai/sdk@0.71.2
{
"dependencies": {
"@anthropic-ai/sdk": "^0.71.2"
},
"devDependencies": {
"@types/node": "^20.0.0",
"typescript": "^5.3.0",
"zod": "^3.23.0"
}
}
Token 效率 :
预防的错误 : 16 个已记录的问题,附带确切解决方案 关键价值 : 结构化输出 (v0.69.0+)、模型弃用 (2025年10月)、提示缓存边缘情况、流式错误模式、速率限制重试逻辑、MCP 超时变通方法、幻觉验证
最后验证 : 2026-01-20 | 技能版本 : 2.2.0 | 变更 : 根据社区研究新增 4 个问题: 流式错误处理 (已在 v0.71.2 修复)、MCP 超时变通方法、结构化输出幻觉验证、U+2028 清理;扩展了结构化输出部分,包含性能特征和准确性警告;添加了 AWS Bedrock 缓存限制
每周安装数
325
仓库
GitHub 星标数
643
首次出现
2026年1月20日
安全审计
安装于
claude-code275
opencode217
gemini-cli217
cursor208
antigravity198
codex190
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
Major Features:
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 (output_format) - For data extraction and formatting:
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 (strict: true) - For validated function parameters:
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:
structured-outputs-2025-11-13 (via betas array)Limitations:
minimum, maximum)Performance Characteristics:
Pre-warming critical schemas:
// 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 grammar
Semantic Validation (CRITICAL):
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:
⚠️ SDK v0.71.1+ Deprecation : Direct .parsed property access is deprecated. Check SDK docs for updated API.
Retired (return errors):
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.
Clear Thinking Blocks - Automatic thinking block cleanup:
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
Pre-built skills for Office files (PowerPoint, Excel, Word, PDF):
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
});
📚 Docs : https://platform.claude.com/docs/en/build-with-claude/structured-outputs
CRITICAL Error Pattern - Errors occur AFTER initial 200 response:
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
CRITICAL Rule - cache_control MUST be on LAST block:
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:
⚠️ 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)
CRITICAL Patterns:
Strict Tool Use (with structured outputs):
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 - tool_use_id MUST match:
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:
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:
// 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
};
CRITICAL Rules:
Format validation - Check before encoding:
const validFormats = ['image/jpeg', 'image/png', 'image/webp', 'image/gif'];
if (!validFormats.includes(mimeType)) {
throw new Error(`Unsupported format: ${mimeType}`);
}
⚠️ Model Compatibility:
CRITICAL:
max_tokens (thinking consumes tokens)CRITICAL Pattern - Respect retry-after header with exponential backoff:
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:
anthropic-ratelimit-requests-limit - Total RPM allowedanthropic-ratelimit-requests-remaining - Remaining requestsanthropic-ratelimit-requests-reset - Reset timestampCommon 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:
retry-after header on 429 errorsThis skill prevents 16 documented issues:
Error : 429 Too Many Requests: Number of request tokens has exceeded your per-minute rate limit Source : https://docs.claude.com/en/api/errors Why It Happens : Exceeding RPM, TPM, or daily token limits Prevention : Implement exponential backoff with retry-after header respect
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
Error : High costs despite cache_control blocks Source : https://platform.claude.com/docs/en/build-with-claude/prompt-caching Why It Happens : cache_control placed incorrectly (must be at END) Prevention : Always place cache_control on LAST block of cacheable content
Error : invalid_request_error: tools[0].input_schema is invalid Source : API validation errors Why It Happens : Invalid JSON Schema, missing required fields Prevention : Validate schemas with JSON Schema validator, test thoroughly
Error : invalid_request_error: image source must be base64 or url Source : API documentation Why It Happens : Incorrect encoding, unsupported formats Prevention : Validate format (JPEG/PNG/WebP/GIF), proper base64 encoding
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
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
Error : invalid_request_error: messages: too many tokens Source : Model limits Why It Happens : Long conversations without pruning Prevention : Implement message history pruning, use caching
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
Error : CORS errors, security vulnerability Source : Security best practices Why It Happens : Making API calls from browser Prevention : Server-side only, use environment variables
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
Error : invalid_request_error: unknown parameter: batches Source : Beta API requirements Why It Happens : Missing anthropic-beta header Prevention : Include anthropic-beta: message-batches-2024-09-24 header
Error : Unhandled promise rejection when using messages.stream().withResponse() 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
Fixed in v0.71.2+ :
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 :
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 : Connection error / 499 Client disconnected 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
Symptoms :
Workaround :
// 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.
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
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');
}
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
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)
};
Latest : @anthropic-ai/sdk@0.71.2
{
"dependencies": {
"@anthropic-ai/sdk": "^0.71.2"
},
"devDependencies": {
"@types/node": "^20.0.0",
"typescript": "^5.3.0",
"zod": "^3.23.0"
}
}
Token Efficiency :
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
Weekly Installs
325
Repository
GitHub Stars
643
First Seen
Jan 20, 2026
Security Audits
Gen Agent Trust HubFailSocketPassSnykWarn
Installed on
claude-code275
opencode217
gemini-cli217
cursor208
antigravity198
codex190
agent-browser 浏览器自动化工具 - Vercel Labs 命令行网页操作与测试
140,500 周安装