|$ curl https://forge-ai.dev/api/markdown?path=docs/ai/anthropic
$cat docs/ai-engineering-—-anthropic-claude.md
updated Recently·40 min read·published

AI Engineering — Anthropic Claude

AI EngineeringAPIsIntermediate to Advanced
Introduction

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.

Messages API

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.

messages-api.ts
TypeScript
1// TypeScript SDK setup
2// npm install @anthropic-ai/sdk
3
4import Anthropic from "@anthropic-ai/sdk";
5
6const anthropic = new Anthropic({
7 apiKey: process.env.ANTHROPIC_API_KEY,
8});
9
10// Basic message
11const 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
23console.log(message.content[0].text);
24
25// Response includes usage metadata
26console.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});
messages-api.py
Python
1# Python SDK
2# pip install anthropic
3
4import anthropic
5
6client = anthropic.Anthropic(
7 api_key=os.environ["ANTHROPIC_API_KEY"]
8)
9
10message = 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
19print(message.content[0].text)

info

Claude uses a separate system parameter rather than a system message in the messages array. This is different from OpenAI's API. The max_tokens parameter is required in the Messages API — it limits the output length.
Streaming with Claude

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.

streaming-claude.ts
TypeScript
1// Streaming response
2const 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
11let fullContent = "";
12
13for 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
28console.log("\n--- Complete response ---");
29console.log(fullContent);
🔥

pro tip

Claude's streaming emits different event types. Always check event.type === "content_block_delta" and event.delta.type === "text_delta" for text content. The final message_delta event contains usage metadata and stop reason.
Extended Thinking

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.

thinking-mode.ts
TypeScript
1// Extended thinking mode
2const 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
21for (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

Extended thinking consumes additional tokens (the budget_tokensparameter). Cost increases proportionally to the thinking budget. Start with a modest budget (1024 tokens) and increase only if the model's reasoning quality is insufficient for your task.
Tool Use

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.

tool-use-claude.ts
TypeScript
1// Tool use with Claude
2const 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
33for (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's tool use response contains content blocks of type "tool_use". Unlike OpenAI, Claude can mix text and tool calls in the same response. The tool result must be sent as a "tool_result"content block in a user message. Always include the assistant's full response content in the next turn.
Prompt Caching

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.

prompt-caching.ts
TypeScript
1// Prompt caching for system prompts
2const 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
18console.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
24const 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

Prompt caching can reduce input token costs by up to 90% for repeated system prompts or large context documents. Cache hits are priced lower than cache misses. Cache the system prompt and any static reference material, but not user-specific content that changes per request.
Model Comparison

Claude 3 family offers three models optimized for different use cases: Haiku for speed, Sonnet for balanced performance, and Opus for maximum capability.

ModelStrengthsContextInput Cost (per 1M)Output Cost (per 1M)
Claude 3.5 SonnetBest balance of speed & quality200K$3.00$15.00
Claude 3 OpusHighest capability, deep reasoning200K$15.00$75.00
Claude 3 HaikuFastest, cheapest, simple tasks200K$0.25$1.25

info

Use Claude 3.5 Sonnet as your default model. It offers the best quality-to-cost ratio for most tasks. Reserve Opus for complex reasoning, code generation, and tasks requiring maximum capability. Use Haiku for classification, extraction, and simple chat at high throughput.
Message Batches

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.

message-batches.ts
TypeScript
1// Create a batch of messages
2const 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
27console.log("Batch ID:", batch.id);
28
29// Check batch status
30const status = await anthropic.messages.batches.retrieve(batch.id);
31console.log({
32 status: status.processing_status,
33 created: status.created_at,
34 expires: status.expires_at
35});
36
37// Retrieve results when complete
38const results = await anthropic.messages.batches.results(batch.id);
39for await (const result of results) {
40 console.log(`${result.custom_id}: ${result.result.type}`);
41}
Safety Features

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.

Constitutional AI: Claude follows a constitution of principles rather than simple blocklists
Content filtering: Configurable thresholds for hate, harassment, sexual, and violence categories
Refusal detection: API returns structured refusal reasons for filtered content
Rate limiting: Tiered rate limits with clear upgrade paths for production workloads

best practice

Monitor Claude's stop_reason field in responses. A value of "end_turn" means the model completed normally. "max_tokens" means the response was truncated. "stop_sequence" means a custom stop sequence was triggered. Handle each case appropriately in your application.
$Blueprint — Engineering Documentation·Section ID: AI-ANC-01·Revision: 1.0