Overview
Advanced Claude API patterns for production applications. Model defaults: always claude-opus-4-6 unless explicitly overridden. Adaptive thinking, streaming, and agentic loops are the core building blocks.
Model Reference
| Model | ID | Best For |
|-------|-----|----------|
| Claude Opus 4.6 | claude-opus-4-6 | Complex reasoning, production default |
| Claude Sonnet 4.6 | claude-sonnet-4-6 | Cost-efficient, standard tasks |
| Claude Haiku 4.5 | claude-haiku-4-5 | Simple lookups, high throughput |
Never append date suffixes to model IDs. Use the exact strings above.
Adaptive Thinking (claude-opus-4-6)
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic();
const response = await client.messages.create({
model: "claude-opus-4-6",
max_tokens: 16_000,
thinking: { type: "adaptive" }, // Claude decides when/how much to think
messages: [{ role: "user", content: "Design a distributed caching strategy for a SaaS app with 1M users." }],
});
Key rules:
thinking: { type: "adaptive" }— correct for Opus 4.6 and Sonnet 4.6budget_tokens— deprecated, do not usethinking.type: "enabled"withbudget_tokens— only for explicitly requested older models- Opus 4.6 does not support assistant message prefills — use structured outputs instead
Effort Parameter
const response = await client.messages.create({
model: "claude-opus-4-6",
max_tokens: 8_000,
output_config: {
effort: "max", // "low" | "medium" | "high" | "max"
},
messages: [{ role: "user", content: "..." }],
});
max— Opus 4.6 only, deepest reasoninghigh— default (equivalent to omitting)low— for subagents and simple tasks
Streaming (Required for Large Outputs)
Opus 4.6 supports 128K output tokens — must stream for large max_tokens:
const stream = await client.messages.stream({
model: "claude-opus-4-6",
max_tokens: 32_000,
messages: [{ role: "user", content: "Write a complete API spec for..." }],
});
// Stream events
for await (const event of stream) {
if (event.type === "content_block_delta" && event.delta.type === "text_delta") {
process.stdout.write(event.delta.text);
}
}
// Get final complete message
const message = await stream.finalMessage();
Structured Outputs
Use output_config.format (not deprecated output_format):
const response = await client.messages.parse({
model: "claude-opus-4-6",
max_tokens: 4_000,
output_config: {
format: {
type: "json_schema",
json_schema: {
name: "analysis",
schema: {
type: "object",
properties: {
sentiment: { type: "string", enum: ["positive", "negative", "neutral"] },
confidence: { type: "number", minimum: 0, maximum: 1 },
summary: { type: "string" },
},
required: ["sentiment", "confidence", "summary"],
},
},
},
},
messages: [{ role: "user", content: "Analyze this review: ..." }],
});
// Validated response
const analysis = response.content[0];
Manual Agentic Loop
const tools: Anthropic.Tool[] = [
{
name: "search_web",
description: "Search the web for current information",
input_schema: {
type: "object",
properties: { query: { type: "string" } },
required: ["query"],
},
},
];
const messages: Anthropic.MessageParam[] = [
{ role: "user", content: "Research the latest Next.js 16 features." },
];
while (true) {
const response = await client.messages.create({
model: "claude-opus-4-6",
max_tokens: 4_000,
tools,
messages,
});
// Append assistant response
messages.push({ role: "assistant", content: response.content });
if (response.stop_reason === "end_turn") break;
if (response.stop_reason === "tool_use") {
const toolResults: Anthropic.ToolResultBlockParam[] = [];
for (const block of response.content) {
if (block.type === "tool_use") {
const result = await executeToolCall(block.name, block.input);
toolResults.push({
type: "tool_result",
tool_use_id: block.id,
content: JSON.stringify(result),
});
}
}
messages.push({ role: "user", content: toolResults });
}
}
Batches API (50% Cost for Non-Latency-Sensitive Work)
const batch = await client.messages.batches.create({
requests: [
{
custom_id: "classify-0",
params: {
model: "claude-opus-4-6",
max_tokens: 256,
messages: [{ role: "user", content: "Classify: 'Great product!' as positive/negative/neutral" }],
},
},
{
custom_id: "classify-1",
params: {
model: "claude-opus-4-6",
max_tokens: 256,
messages: [{ role: "user", content: "Classify: 'Terrible experience' as positive/negative/neutral" }],
},
},
],
});
console.log(`Batch ID: ${batch.id}`);
// Poll until complete
let batchResult = batch;
while (batchResult.processing_status !== "ended") {
await new Promise(r => setTimeout(r, 10_000));
batchResult = await client.messages.batches.retrieve(batch.id);
}
// Retrieve results
for await (const result of await client.messages.batches.results(batch.id)) {
if (result.result.type === "succeeded") {
console.log(result.custom_id, result.result.message.content[0]);
}
}
Files API (Reuse Documents Across Requests)
// Upload once
const file = await client.files.create({
file: fs.createReadStream("spec.pdf"),
});
const fileId = file.id;
// Reference in multiple requests without re-uploading
const responses = await Promise.all([
client.messages.create({
model: "claude-opus-4-6",
max_tokens: 4_000,
messages: [{
role: "user",
content: [
{ type: "document", source: { type: "file", file_id: fileId } },
{ type: "text", text: "Summarize the architecture section." },
],
}],
}),
client.messages.create({
model: "claude-opus-4-6",
max_tokens: 4_000,
messages: [{
role: "user",
content: [
{ type: "document", source: { type: "file", file_id: fileId } },
{ type: "text", text: "List all the API endpoints mentioned." },
],
}],
}),
]);
RAG Pipeline
Chunk documents (500 tokens, 50-token overlap)
→ Embed with voyage-3
→ Store in pgvector
→ Hybrid search (semantic + BM25 with Reciprocal Rank Fusion)
→ Rerank
→ Augment prompt with top-K context
→ Generate with citations
// Augment prompt with retrieved context
const context = retrievedDocs.map(doc => doc.content).join("\n\n---\n\n");
const response = await client.messages.create({
model: "claude-opus-4-6",
max_tokens: 4_000,
system: `Answer questions using the provided context. Cite sources with [Source N].
Context:
${context}`,
messages: [{ role: "user", content: question }],
});
Compaction (Long Conversations)
// Append response.content (not just text) to preserve compaction blocks
messages.push({ role: "assistant", content: response.content });
// Enable compaction via beta header
const client = new Anthropic({
defaultHeaders: { "anthropic-beta": "compact-2026-01-12" },
});
Compaction automatically summarizes earlier context when approaching the 200K limit.