AI Engineering — Anthropic Claude
Anthropic's Claude API provides access to the Claude family of models (Claude 3.5 Sonnet, Claude 3 Opus, Claude 3 Haiku). Claude excels at nuanced reasoning, safety-aware responses, long-context tasks (200K token context window), and structured tool use.
The Messages API is the primary interface, supporting streaming, tool use, image inputs, extended thinking, and prompt caching. Claude's constitution-based training makes it particularly suitable for applications requiring careful content moderation and safety.
The Messages API is the primary way to interact with Claude. It accepts a list of messages (alternating user and assistant roles) and returns a response. Claude uses a system parameter (separate from messages) for system prompts.
| 1 | // TypeScript SDK setup |
| 2 | // npm install @anthropic-ai/sdk |
| 3 | |
| 4 | import Anthropic from "@anthropic-ai/sdk"; |
| 5 | |
| 6 | const anthropic = new Anthropic({ |
| 7 | apiKey: process.env.ANTHROPIC_API_KEY, |
| 8 | }); |
| 9 | |
| 10 | // Basic message |
| 11 | const message = await anthropic.messages.create({ |
| 12 | model: "claude-3-5-sonnet-20241022", |
| 13 | max_tokens: 1024, |
| 14 | system: "You are a helpful assistant. Be concise.", |
| 15 | messages: [ |
| 16 | { |
| 17 | role: "user", |
| 18 | content: "What is the capital of Japan?" |
| 19 | } |
| 20 | ] |
| 21 | }); |
| 22 | |
| 23 | console.log(message.content[0].text); |
| 24 | |
| 25 | // Response includes usage metadata |
| 26 | console.log({ |
| 27 | input_tokens: message.usage.input_tokens, |
| 28 | output_tokens: message.usage.output_tokens, |
| 29 | stop_reason: message.stop_reason, |
| 30 | model: message.model |
| 31 | }); |
| 1 | # Python SDK |
| 2 | # pip install anthropic |
| 3 | |
| 4 | import anthropic |
| 5 | |
| 6 | client = anthropic.Anthropic( |
| 7 | api_key=os.environ["ANTHROPIC_API_KEY"] |
| 8 | ) |
| 9 | |
| 10 | message = client.messages.create( |
| 11 | model="claude-3-5-sonnet-20241022", |
| 12 | max_tokens=1024, |
| 13 | system="You are a helpful assistant.", |
| 14 | messages=[ |
| 15 | {"role": "user", "content": "What is the capital of Japan?"} |
| 16 | ] |
| 17 | ) |
| 18 | |
| 19 | print(message.content[0].text) |
info
Claude supports streaming via Server-Sent Events. The SDK provides stream parameter that returns an async iterable of events. Each event type signals different stages: message start, content block delta, and message stop.
| 1 | // Streaming response |
| 2 | const stream = await anthropic.messages.create({ |
| 3 | model: "claude-3-5-sonnet-20241022", |
| 4 | max_tokens: 1024, |
| 5 | messages: [ |
| 6 | { role: "user", content: "Explain quantum computing simply." } |
| 7 | ], |
| 8 | stream: true |
| 9 | }); |
| 10 | |
| 11 | let fullContent = ""; |
| 12 | |
| 13 | for await (const event of stream) { |
| 14 | if (event.type === "content_block_delta" && |
| 15 | event.delta.type === "text_delta") { |
| 16 | fullContent += event.delta.text; |
| 17 | process.stdout.write(event.delta.text); |
| 18 | } |
| 19 | |
| 20 | if (event.type === "message_delta") { |
| 21 | console.log("\n\nUsage:", { |
| 22 | output_tokens: event.usage?.output_tokens, |
| 23 | stop_reason: event.delta?.stop_reason |
| 24 | }); |
| 25 | } |
| 26 | } |
| 27 | |
| 28 | console.log("\n--- Complete response ---"); |
| 29 | console.log(fullContent); |
pro tip
Claude supports extended thinking — the model can show its step-by-step reasoning before producing a final answer. This improves performance on complex math, logic, and coding tasks by allowing the model to "think" in a structured way.
| 1 | // Extended thinking mode |
| 2 | const response = await anthropic.messages.create({ |
| 3 | model: "claude-3-5-sonnet-20241022", |
| 4 | max_tokens: 4096, |
| 5 | thinking: { |
| 6 | type: "enabled", |
| 7 | budget_tokens: 2048 // Allocate tokens for thinking |
| 8 | }, |
| 9 | messages: [ |
| 10 | { |
| 11 | role: "user", |
| 12 | content: "Solve: A train leaves station A at 60 mph. " + |
| 13 | "Another train leaves station B at 80 mph. " + |
| 14 | "Stations are 280 miles apart. " + |
| 15 | "When do they meet?" |
| 16 | } |
| 17 | ] |
| 18 | }); |
| 19 | |
| 20 | // Response contains both thinking and text blocks |
| 21 | for (const block of response.content) { |
| 22 | if (block.type === "thinking") { |
| 23 | console.log("Thinking:", block.thinking); |
| 24 | } |
| 25 | if (block.type === "text") { |
| 26 | console.log("Answer:", block.text); |
| 27 | } |
| 28 | } |
warning
Claude supports tool use similar to OpenAI but with a slightly different API. Tools are defined with JSON Schema, and Claude returns tool use content blocks. Claude can handle parallel tool calls and multi-turn tool interactions.
| 1 | // Tool use with Claude |
| 2 | const response = await anthropic.messages.create({ |
| 3 | model: "claude-3-5-sonnet-20241022", |
| 4 | max_tokens: 1024, |
| 5 | system: "You have access to tools. Use them when needed.", |
| 6 | messages: [ |
| 7 | { role: "user", content: "What's the weather in London?" } |
| 8 | ], |
| 9 | tools: [ |
| 10 | { |
| 11 | name: "get_weather", |
| 12 | description: "Get current weather for a location.", |
| 13 | input_schema: { |
| 14 | type: "object", |
| 15 | properties: { |
| 16 | location: { |
| 17 | type: "string", |
| 18 | description: "City name, e.g. 'London, UK'" |
| 19 | }, |
| 20 | units: { |
| 21 | type: "string", |
| 22 | enum: ["celsius", "fahrenheit"], |
| 23 | default: "celsius" |
| 24 | } |
| 25 | }, |
| 26 | required: ["location"] |
| 27 | } |
| 28 | } |
| 29 | ] |
| 30 | }); |
| 31 | |
| 32 | // Check for tool use blocks |
| 33 | for (const block of response.content) { |
| 34 | if (block.type === "tool_use") { |
| 35 | console.log(`Tool: ${block.name}`); |
| 36 | console.log(`Input: ${JSON.stringify(block.input)}`); |
| 37 | |
| 38 | const result = await executeTool(block.name, block.input); |
| 39 | |
| 40 | // Send result back |
| 41 | const followUp = await anthropic.messages.create({ |
| 42 | model: "claude-3-5-sonnet-20241022", |
| 43 | max_tokens: 1024, |
| 44 | messages: [ |
| 45 | { role: "user", content: "What's the weather in London?" }, |
| 46 | { role: "assistant", content: response.content }, |
| 47 | { |
| 48 | role: "user", |
| 49 | content: [ |
| 50 | { |
| 51 | type: "tool_result", |
| 52 | tool_use_id: block.id, |
| 53 | content: JSON.stringify(result) |
| 54 | } |
| 55 | ] |
| 56 | } |
| 57 | ] |
| 58 | }); |
| 59 | |
| 60 | console.log(followUp.content[0].text); |
| 61 | } |
| 62 | } |
best practice
Claude supports prompt caching to reduce latency and cost for repeated system prompts or large context prefixes. Mark cacheable content with the cache_control parameter. Cached content is stored for 5 minutes and reused across requests.
| 1 | // Prompt caching for system prompts |
| 2 | const response = await anthropic.messages.create({ |
| 3 | model: "claude-3-5-sonnet-20241022", |
| 4 | max_tokens: 1024, |
| 5 | system: [ |
| 6 | { |
| 7 | type: "text", |
| 8 | text: longSystemPrompt, // Large system prompt |
| 9 | cache_control: { type: "ephemeral" } |
| 10 | } |
| 11 | ], |
| 12 | messages: [ |
| 13 | { role: "user", content: "Query about the documentation..." } |
| 14 | ] |
| 15 | }); |
| 16 | |
| 17 | // Check cache metrics |
| 18 | console.log({ |
| 19 | cache_creation: response.usage?.cache_creation_input_tokens, |
| 20 | cache_read: response.usage?.cache_read_input_tokens |
| 21 | }); |
| 22 | |
| 23 | // Caching large documents |
| 24 | const response2 = await anthropic.messages.create({ |
| 25 | model: "claude-3-5-sonnet-20241022", |
| 26 | max_tokens: 1024, |
| 27 | messages: [ |
| 28 | { |
| 29 | role: "user", |
| 30 | content: [ |
| 31 | { |
| 32 | type: "text", |
| 33 | text: largeDocument, // e.g., entire codebase |
| 34 | cache_control: { type: "ephemeral" } |
| 35 | }, |
| 36 | { |
| 37 | type: "text", |
| 38 | text: "Summarize this document." |
| 39 | } |
| 40 | ] |
| 41 | } |
| 42 | ] |
| 43 | }); |
pro tip
Claude 3 family offers three models optimized for different use cases: Haiku for speed, Sonnet for balanced performance, and Opus for maximum capability.
| Model | Strengths | Context | Input Cost (per 1M) | Output Cost (per 1M) |
|---|---|---|---|---|
| Claude 3.5 Sonnet | Best balance of speed & quality | 200K | $3.00 | $15.00 |
| Claude 3 Opus | Highest capability, deep reasoning | 200K | $15.00 | $75.00 |
| Claude 3 Haiku | Fastest, cheapest, simple tasks | 200K | $0.25 | $1.25 |
info
The Message Batches API enables asynchronous processing of multiple requests at 50% discount. Messages are processed within 24 hours, making this ideal for bulk classification, data enrichment, and offline processing.
| 1 | // Create a batch of messages |
| 2 | const batch = await anthropic.messages.batches.create({ |
| 3 | requests: [ |
| 4 | { |
| 5 | custom_id: "req-001", |
| 6 | params: { |
| 7 | model: "claude-3-haiku-20240307", |
| 8 | max_tokens: 256, |
| 9 | messages: [ |
| 10 | { role: "user", content: "Classify: Great product!" } |
| 11 | ] |
| 12 | } |
| 13 | }, |
| 14 | { |
| 15 | custom_id: "req-002", |
| 16 | params: { |
| 17 | model: "claude-3-haiku-20240307", |
| 18 | max_tokens: 256, |
| 19 | messages: [ |
| 20 | { role: "user", content: "Classify: Terrible service." } |
| 21 | ] |
| 22 | } |
| 23 | } |
| 24 | ] |
| 25 | }); |
| 26 | |
| 27 | console.log("Batch ID:", batch.id); |
| 28 | |
| 29 | // Check batch status |
| 30 | const status = await anthropic.messages.batches.retrieve(batch.id); |
| 31 | console.log({ |
| 32 | status: status.processing_status, |
| 33 | created: status.created_at, |
| 34 | expires: status.expires_at |
| 35 | }); |
| 36 | |
| 37 | // Retrieve results when complete |
| 38 | const results = await anthropic.messages.batches.results(batch.id); |
| 39 | for await (const result of results) { |
| 40 | console.log(`${result.custom_id}: ${result.result.type}`); |
| 41 | } |
Claude includes built-in safety features: content filtering, harm category detection, and the ability to set safety thresholds via the anthropic_versionheader. Claude's constitutional AI approach makes refusals more nuanced than keyword-based filtering.
best practice