Skip to main content

Anthropic Provider

Anthropic provides the Claude family of models, known for their helpfulness, honesty, and harmlessness. Claude excels at analysis, coding, creative writing, and extended conversations with industry-leading context windows.

Setup​

Installation​

The Anthropic provider is included in the Go-AI SDK:

import (
"github.com/digitallysavvy/go-ai/pkg/ai"
"github.com/digitallysavvy/go-ai/pkg/providers/anthropic"
)

Configuration​

provider := anthropic.New(anthropic.Config{
APIKey: os.Getenv("ANTHROPIC_API_KEY"),
})

model, err := provider.LanguageModel("claude-sonnet-4-5")
if err != nil {
log.Fatal(err)
}

Get API Key​

  1. Sign up at console.anthropic.com
  2. Navigate to API Keys section
  3. Create new API key
  4. Set environment variable:
export ANTHROPIC_API_KEY=sk-ant-...

Claude Platform on AWS​

Use pkg/providers/anthropicaws when calling Claude Platform through AWS. The provider reuses the Anthropic language model, Files API, Skills API, and Anthropic tool factories, but signs requests for AWS or sends the Anthropic AWS API key headers.

API Key Authentication​

provider, err := anthropicaws.New(anthropicaws.Config{
Region: os.Getenv("AWS_REGION"),
WorkspaceID: os.Getenv("ANTHROPIC_AWS_WORKSPACE_ID"),
APIKey: os.Getenv("ANTHROPIC_AWS_API_KEY"),
})
if err != nil {
log.Fatal(err)
}

model, err := provider.LanguageModel(anthropic.ClaudeOpus4_8)

SigV4 Authentication​

When APIKey and ANTHROPIC_AWS_API_KEY are empty, the provider signs POST requests with SigV4. Credentials may come from Config, environment variables, or CredentialProvider.

provider, err := anthropicaws.New(anthropicaws.Config{
Region: os.Getenv("AWS_REGION"),
WorkspaceID: os.Getenv("ANTHROPIC_AWS_WORKSPACE_ID"),
AccessKeyID: os.Getenv("AWS_ACCESS_KEY_ID"),
SecretAccessKey: os.Getenv("AWS_SECRET_ACCESS_KEY"),
SessionToken: os.Getenv("AWS_SESSION_TOKEN"),
})

The default base URL is https://aws-external-anthropic.{region}.api.aws/v1. WorkspaceID is required and is sent as anthropic-workspace-id.

Available Models​

Claude 4.7/4.6/4.5 Series (Latest)​

Model IDContextInput PriceOutput PriceBest For
claude-opus-4-7200KTBATBALatest Opus reasoning and coding
claude-opus-4-6200KTBATBAComplex tasks, fast mode
claude-sonnet-4-6200KTBATBABalanced performance and capability
claude-opus-4-5200K$15.00/1M$75.00/1MMost capable, complex tasks
claude-sonnet-4-5200K$3.00/1M$15.00/1MBest balance of speed & quality
claude-haiku-4-5200K$0.80/1M$4.00/1MFast, cost-effective

Claude 4 Series​

Model IDContextInput PriceOutput PriceBest For
claude-opus-4200K$15.00/1M$75.00/1MComplex analysis
claude-sonnet-4200K$3.00/1M$15.00/1MGeneral purpose
claude-haiku-4200K$0.25/1M$1.25/1MHigh-volume tasks

Claude 3.5 Series (Previous Generation)​

Model IDContextInput PriceOutput PriceBest For
claude-3-5-sonnet-20241022200K$3.00/1M$15.00/1MLatest 3.5 with tool use
claude-3-5-haiku-20241022200K$0.80/1M$4.00/1MFast responses

Claude 3 Series (Legacy)​

Model IDContextInput PriceOutput PriceBest For
claude-3-opus-20240229200K$15.00/1M$75.00/1MLegacy flagship
claude-3-sonnet-20240229200K$3.00/1M$15.00/1MLegacy balanced
claude-3-haiku-20240307200K$0.25/1M$1.25/1MLegacy fast

Provider-Specific Features​

Inference Region​

Set InferenceGeo on Anthropic model options to forward the TypeScript SDK inferenceGeo provider option as inference_geo. Supported values are "us" and "global".

anthropic.ClaudeFable5 is available for Claude Fable 5. ModelOptions.Fallbacks forwards Anthropic's server-side fallback configuration and enables the server-side-fallback-2026-06-01 beta header. Fallback response blocks are consumed like the TypeScript provider and are not returned as content; fallback activity is visible through the raw usage iterations metadata.

model := anthropic.NewLanguageModel(provider, anthropic.ClaudeOpus4_7, &anthropic.ModelOptions{
InferenceGeo: "us",
})

Anthropic JSON schema serialization sanitizes unsupported validation keywords before sending requests, matching the TypeScript provider behavior. This keeps structured output/tool schemas compatible with Anthropic without requiring callers to manually strip incompatible fields.

Extended Context (200K tokens)​

Claude models support up to 200K token context windows:

// Process entire codebases or documents
largeDocument := readLargeFile("document.txt") // up to 200K tokens

result, err := ai.GenerateText(ctx, ai.GenerateTextOptions{
Model: model,
Prompt: fmt.Sprintf("Analyze this document and provide insights:\n\n%s", largeDocument),
})

Vision Capabilities​

Claude 4.5 and 3.5 models support image understanding:

// Read image
imageData, err := os.ReadFile("chart.png")
if err != nil {
log.Fatal(err)
}

result, err := ai.GenerateText(ctx, ai.GenerateTextOptions{
Model: model,
Messages: []types.Message{
{
Role: types.RoleUser,
Content: []types.ContentPart{
types.TextContent{Text: "Analyze this chart"},
types.FileContent{
Data: imageData,
MediaType: "image/png",
},
},
},
},
})

Tool Use (Function Calling)​

Claude excels at tool use with precise parameter extraction:

searchTool := types.Tool{
Name: "search_database",
Description: "Search the customer database",
Parameters: map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"query": map[string]interface{}{
"type": "string",
"description": "Search query",
},
"filters": map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"status": map[string]interface{}{
"type": "string",
"enum": []string{"active", "inactive"},
},
"created_after": map[string]string{
"type": "string",
},
},
},
},
"required": []string{"query"},
},
}

result, err := ai.GenerateText(ctx, ai.GenerateTextOptions{
Model: model,
Prompt: "Find all active customers who signed up in 2024",
Tools: []types.Tool{searchTool},
StopWhen: []ai.StopCondition{ai.IsStepCount(5)},
})

for _, call := range result.ToolCalls {
fmt.Printf("Tool: %s\nArgs: %v\n", call.ToolName, call.Arguments)
}

Prompt Caching​

Reduce costs by caching frequently used prompt segments:

// Cache system prompt and context
result, err := ai.GenerateText(ctx, ai.GenerateTextOptions{
Model: model,
System: "You are an expert Go programmer...",
Messages: []types.Message{
{
Role: types.RoleUser,
Content: []types.ContentPart{
types.TextContent{Text: "Review this code: " + largeCodebase},
},
},
{
Role: types.RoleUser,
Content: []types.ContentPart{
types.TextContent{Text: "How can I improve error handling?"},
},
},
},
ProviderOptions: map[string]interface{}{
"anthropic": anthropic.ModelOptions{AutomaticCaching: true},
},
})

// Subsequent requests with same cached content cost significantly less

Pricing with caching:

  • Cache write: $3.75/1M tokens (1.25x normal)
  • Cache read: $0.30/1M tokens (0.1x normal)
  • Cached content valid for 5 minutes

Thinking (Extended Reasoning)​

Claude 4.5 supports extended thinking for complex problems:

thinkingModel, err := provider.LanguageModelWithOptions("claude-sonnet-4-5", &anthropic.ModelOptions{
Thinking: &anthropic.ThinkingConfig{Type: anthropic.ThinkingTypeAdaptive},
})
if err != nil {
log.Fatal(err)
}

result, err := ai.GenerateText(ctx, ai.GenerateTextOptions{
Model: thinkingModel,
Prompt: "Solve this complex optimization problem...",
})

// Response includes thinking process as ordered reasoning content parts
for _, part := range result.Content {
if reasoning, ok := part.(types.ReasoningContent); ok {
fmt.Println("Claude's reasoning:", reasoning.Text)
}
}
fmt.Println("Final answer:", result.Text)

When streaming (ai.StreamText) extended thinking together with tool calls across multiple steps, each thinking block's cryptographic signature streams as its own signature_delta event, after the block's text deltas. The provider carries it through as the reasoning content part's Signature, so a later step's request replays the thinking block with its signature intact (required for Anthropic to accept the replayed block) instead of dropping it.

Between-Tools Thinking (Claude Sonnet 5.5)​

anthropic.ClaudeSonnet5_5 rejects thinking.type "disabled" and budget-based thinking, and adds anthropic.ThinkingTypeBetweenTools, its lowest thinking setting: no upfront thinking, but short progress notes between tool calls stream back as summarized thinking blocks. It's only accepted at "low", "medium", and "high" effort — "xhigh"/"max" is lowered to "high" with a warning. Reasoning: types.ReasoningNone and ThinkingConfig{Type: anthropic.ThinkingTypeDisabled} both map to between_tools automatically for this model, with a warning in the latter case.

model, err := provider.LanguageModelWithOptions(anthropic.ClaudeSonnet5_5, &anthropic.ModelOptions{
Thinking: &anthropic.ThinkingConfig{Type: anthropic.ThinkingTypeBetweenTools},
Effort: anthropic.EffortMedium,
})

Context Management (Beta)​

Automatically manage conversation history to prevent context window overflows. Claude can intelligently clear old tool calls, thinking blocks, or compact entire conversations:

import "github.com/digitallysavvy/go-ai/pkg/providers/anthropic"

// Create model with context management
model, err := provider.LanguageModelWithOptions("claude-sonnet-4-5", &anthropic.ModelOptions{
ContextManagement: &anthropic.ContextManagement{
Edits: []anthropic.ContextManagementEdit{
// Clear old tool calls after 10,000 input tokens
anthropic.NewClearToolUsesEdit().
WithInputTokensTrigger(10000).
WithKeepToolUses(3),

// Clear thinking blocks, keeping last 2 turns
anthropic.NewClearThinkingEdit().
WithKeepRecentTurns(2),

// Compact conversation at 50,000 tokens
anthropic.NewCompactEdit().
WithTrigger(50000),
},
},
})

// Use in long conversations - context automatically managed
result, err := ai.GenerateText(ctx, ai.GenerateTextOptions{
Model: model,
Messages: longConversation,
})

// Check if context management was applied
if result.ContextManagement != nil {
cmr := result.ContextManagement.(*anthropic.ContextManagementResponse)
for _, edit := range cmr.AppliedEdits {
switch e := edit.(type) {
case *anthropic.AppliedClearToolUsesEdit:
fmt.Printf("Cleared %d tool uses, freed %d tokens\n",
e.ClearedToolUses, e.ClearedInputTokens)
case *anthropic.AppliedClearThinkingEdit:
fmt.Printf("Cleared %d thinking turns, freed %d tokens\n",
e.ClearedThinkingTurns, e.ClearedInputTokens)
case *anthropic.AppliedCompactEdit:
fmt.Println("Conversation compacted")
}
}
}

Available Edit Types:

  1. ClearToolUses - Removes old tool call details

    • Configure trigger thresholds (token count or tool use count)
    • Keep recent tool uses
    • Exclude specific tools
    • Control minimum tokens to clear
  2. ClearThinking - Removes extended thinking blocks

    • Keep all thinking or specify number of recent turns
    • Preserves final conclusions
  3. Compact - Summarizes entire conversation

    • Most aggressive space-saving
    • Optional pause after compaction
    • Custom compaction instructions

Beta Headers Required:

  • context-management-2025-06-27 for clear_tool_uses and clear_thinking
  • compact-2026-01-12 for compact edits (Headers are automatically added by the SDK)

Streaming​

Stream responses for real-time output:

stream, err := ai.StreamText(ctx, ai.StreamTextOptions{Model: model, Prompt: "Write a detailed essay about AI safety"})
if err != nil {
log.Fatal(err)
}
defer stream.Close()

for chunk := range stream.Chunks() {
fmt.Print(chunk.Text)
}

if stream.Err() != nil {
log.Fatal(stream.Err())
}

Examples​

Basic Text Generation​

package main

import (
"context"
"fmt"
"log"
"os"

"github.com/digitallysavvy/go-ai/pkg/ai"
"github.com/digitallysavvy/go-ai/pkg/providers/anthropic"
)

func main() {
ctx := context.Background()
provider := anthropic.New(anthropic.Config{
APIKey: os.Getenv("ANTHROPIC_API_KEY"),
})

model, err := provider.LanguageModel("claude-sonnet-4-5")
if err != nil {
log.Fatal(err)
}

result, err := ai.GenerateText(ctx, ai.GenerateTextOptions{
Model: model,
Prompt: "Explain the Go concurrency model with examples",
})
if err != nil {
log.Fatal(err)
}

fmt.Println(result.Text)
fmt.Printf("\nTokens - Input: %d, Output: %d\n",
result.Usage.GetInputTokens(),
result.Usage.GetOutputTokens())
}

Multi-Turn Conversation​

messages := []types.Message{
{
Role: types.RoleUser,
Content: []types.ContentPart{
types.TextContent{Text: "Review this function:\n\n" + code},
},
},
}

result, err := ai.GenerateText(ctx, ai.GenerateTextOptions{
Model: model,
System: "You are a helpful code review assistant",
Messages: messages,
})
if err != nil {
log.Fatal(err)
}

fmt.Println("Review:", result.Text)

// Continue conversation
messages = append(messages,
types.Message{
Role: types.RoleAssistant,
Content: []types.ContentPart{
types.TextContent{Text: result.Text},
},
},
types.Message{
Role: types.RoleUser,
Content: []types.ContentPart{
types.TextContent{Text: "Can you suggest specific improvements?"},
},
},
)

result, err = ai.GenerateText(ctx, ai.GenerateTextOptions{
Model: model,
System: "You are a helpful code review assistant",
Messages: messages,
})

Document Analysis with Vision​

// Analyze a PDF page rendered as image
imageData, err := os.ReadFile("invoice.png")
if err != nil {
log.Fatal(err)
}

result, err := ai.GenerateText(ctx, ai.GenerateTextOptions{
Model: model,
Messages: []types.Message{
{
Role: types.RoleUser,
Content: []types.ContentPart{
types.TextContent{Text: "Extract all line items from this invoice with prices"},
types.FileContent{
Data: imageData,
MediaType: "image/png",
},
},
},
},
ResponseFormat: &provider.ResponseFormat{Type: "json_object"},
})

fmt.Println("Extracted data:", result.Text)

Code Generation with Tool Use​

fileReadTool := types.Tool{
Name: "read_file",
Description: "Read contents of a file",
Parameters: map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"path": map[string]string{
"type": "string",
"description": "File path",
},
},
"required": []string{"path"},
},
}

fileWriteTool := types.Tool{
Name: "write_file",
Description: "Write content to a file",
Parameters: map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"path": map[string]string{"type": "string"},
"content": map[string]string{"type": "string"},
},
"required": []string{"path", "content"},
},
}

result, err := ai.GenerateText(ctx, ai.GenerateTextOptions{
Model: model,
Prompt: "Read main.go, add error handling, and save the improved version",
Tools: []types.Tool{fileReadTool, fileWriteTool},
StopWhen: []ai.StopCondition{ai.IsStepCount(5)},
})

// Process tool calls
for _, call := range result.ToolCalls {
switch call.ToolName {
case "read_file":
// Execute file read
case "write_file":
// Execute file write
}
}

Large Document Processing with Caching​

// Load large codebase
codebase := loadCodebase("./src") // ~100K tokens

messages := []types.Message{
{
Role: types.RoleUser,
Content: []types.ContentPart{
types.TextContent{Text: "Here is the codebase:\n\n" + codebase}, // Cached
},
},
}

// First query - caches codebase
result, err := ai.GenerateText(ctx, ai.GenerateTextOptions{
Model: model,
System: "You are an expert code reviewer",
Messages: append(messages, types.Message{
Role: types.RoleUser,
Content: []types.ContentPart{
types.TextContent{Text: "List all exported functions"},
},
}),
ProviderOptions: map[string]interface{}{
"anthropic": anthropic.ModelOptions{AutomaticCaching: true},
},
})

// Second query - uses cached codebase (90% cost reduction)
result, err = ai.GenerateText(ctx, ai.GenerateTextOptions{
Model: model,
System: "You are an expert code reviewer",
Messages: append(messages, types.Message{
Role: types.RoleUser,
Content: []types.ContentPart{
types.TextContent{Text: "Find potential security issues"},
},
}),
ProviderOptions: map[string]interface{}{
"anthropic": anthropic.ModelOptions{AutomaticCaching: true},
},
})

Advanced Configuration​

Custom HTTP Client​

provider := anthropic.New(anthropic.Config{
APIKey: os.Getenv("ANTHROPIC_API_KEY"),
HTTPClient: &http.Client{
Timeout: time.Minute * 5,
Transport: &http.Transport{
MaxIdleConns: 100,
MaxIdleConnsPerHost: 10,
IdleConnTimeout: 90 * time.Second,
},
},
})

Custom Base URL​

Breaking change: the default base URL now includes /v1 (TS parity). A bare https://api.anthropic.com is normalized automatically, but a custom BaseURL (proxy, test server) must include /v1 itself.

provider := anthropic.New(anthropic.Config{
APIKey: os.Getenv("ANTHROPIC_API_KEY"),
BaseURL: "https://your-proxy.com/v1",
})

Beta Features​

Most beta headers (prompt caching, extended thinking, context management, and so on) are added automatically based on the ModelOptions you set. To send an additional anthropic-beta flag that isn't covered by a dedicated option, set AnthropicBeta on ModelOptions:

provider := anthropic.New(anthropic.Config{
APIKey: os.Getenv("ANTHROPIC_API_KEY"),
})

model, err := provider.LanguageModelWithOptions("claude-sonnet-4-5", &anthropic.ModelOptions{
AnthropicBeta: []string{"some-other-beta-flag"},
})

Error Handling​

Common Errors​

result, err := ai.GenerateText(ctx, ai.GenerateTextOptions{
Model: model,
Prompt: prompt,
})
if err != nil {
var providerErr *providererrors.ProviderError
if errors.As(err, &providerErr) {
switch providerErr.ErrorCode {
case "invalid_request_error":
log.Printf("Invalid request: %s", providerErr.Message)
case "authentication_error":
log.Fatal("Invalid API key")
case "permission_error":
log.Fatal("Permission denied")
case "not_found_error":
log.Fatal("Model not found")
case "rate_limit_error":
log.Printf("Rate limited: %s", providerErr.Message)
time.Sleep(time.Second * 5)
case "overloaded_error":
log.Println("Service overloaded, retrying...")
time.Sleep(time.Second * 10)
default:
log.Printf("Anthropic error: %s", providerErr.Message)
}
}
return nil, err
}

Retry with Exponential Backoff​

func generateWithRetry(ctx context.Context, model provider.LanguageModel, prompt string) (*ai.GenerateTextResult, error) {
maxRetries := 5
baseDelay := time.Second

for attempt := 0; attempt < maxRetries; attempt++ {
result, err := ai.GenerateText(ctx, ai.GenerateTextOptions{
Model: model,
Prompt: prompt,
})
if err == nil {
return result, nil
}

var providerErr *providererrors.ProviderError
if errors.As(err, &providerErr) {
if providerErr.ErrorCode == "rate_limit_error" || providerErr.ErrorCode == "overloaded_error" {
delay := baseDelay * time.Duration(math.Pow(2, float64(attempt)))
log.Printf("Attempt %d failed, waiting %v", attempt+1, delay)
time.Sleep(delay)
continue
}
}

return nil, err
}

return nil, fmt.Errorf("max retries exceeded")
}

Best Practices​

  1. Model Selection

    • Use claude-sonnet-4-5 for best balance of quality and speed
    • Use claude-opus-4-5 for most complex tasks requiring deep analysis
    • Use claude-haiku-4-5 for high-volume, latency-sensitive applications
  2. Prompt Engineering

    • Be specific and detailed in instructions
    • Use XML tags for clear structure: <document>, <context>, <instruction>
    • Provide examples when possible
    • Place most important information at the start or end
  3. Cost Optimization

    • Enable prompt caching for repeated context (large documents, system prompts)
    • Use Haiku for simple tasks
    • Monitor token usage with result.Usage
    • Cache responses on your side for identical queries
  4. Context Management

    • Take advantage of 200K context window
    • Include full context rather than summarizing
    • Use structured formats (JSON, XML) for large data
  5. Tool Use

    • Provide clear, detailed tool descriptions
    • Use precise parameter schemas
    • Handle tool results in follow-up messages
    • Chain multiple tool calls for complex workflows

Rate Limits & Pricing​

Rate Limits (Standard Tier)​

ModelRPMTPMRPD
Claude Opus 4.55040,0001,000
Claude Sonnet 4.55040,0001,000
Claude Haiku 4.55050,0001,000

RPM = Requests per minute, TPM = Tokens per minute (input), RPD = Requests per day

Higher tiers available with increased limits.

Token Counting​

// Estimate tokens (approximate: 1 token ≈ 4 characters)
func estimateTokens(text string) int {
return len(text) / 4
}

// Calculate cost
func calculateCost(usage types.Usage, model string) float64 {
rates := map[string][2]float64{
"claude-opus-4-5": {15.00 / 1_000_000, 75.00 / 1_000_000},
"claude-sonnet-4-5": {3.00 / 1_000_000, 15.00 / 1_000_000},
"claude-haiku-4-5": {0.80 / 1_000_000, 4.00 / 1_000_000},
}

rate := rates[model]
inputCost := float64(usage.GetInputTokens()) * rate[0]
outputCost := float64(usage.GetOutputTokens()) * rate[1]

return inputCost + outputCost
}

Batch API​

Anthropic implements the batch API (Message Batches) used by ai.ExperimentalStartBatch / ExperimentalGetBatchStatus / ExperimentalGetBatchResults — process large volumes at a discount with async turnaround instead of ai.GenerateText per request:

started, err := ai.ExperimentalStartBatch(ctx, ai.StartBatchOptions{
Provider: provider, // an *anthropic.Provider (implements provider.BatchProvider)
Requests: []ai.BatchRequest{
{Text: &ai.BatchTextRequest{
ID: "req-1",
Model: "claude-sonnet-4-6",
Prompt: "Summarize the Go concurrency model.",
}},
},
})
if err != nil {
log.Fatal(err)
}

status, err := ai.ExperimentalGetBatchStatus(ctx, ai.GetBatchStatusOptions{
Provider: provider,
Batch: started.BatchReference,
})

Forwarding Code-Execution Containers Across Steps​

anthropic.ForwardContainerIDFromLastStep(steps) builds ProviderOptions that reuse the code-execution container from the most recent step that had one, so a multi-step agent loop doesn't pay to spin up a fresh sandbox on every step. Use it from PrepareStep:

// tools includes anthropicTools.CodeExecution20260120() — see
// docs/providers/anthropic-advanced-features.md#code-execution-tool-2026-01-20
// for the full code execution tool setup.
result, err := ai.GenerateText(ctx, ai.GenerateTextOptions{
Model: model,
Prompt: "Run some Python to analyze this data, then summarize.",
Tools: tools,
StopWhen: []ai.StopCondition{ai.IsStepCount(5)},
PrepareStep: func(ctx context.Context, step ai.PrepareStepOptions) ai.PrepareStepOptions {
if opts := anthropic.ForwardContainerIDFromLastStep(step.Steps); opts != nil {
step.ProviderOptions = opts
}
return step
},
})

Pruned Programmatic Tool History​

If history is pruned between steps (e.g. to control context size) and that removes a code-execution source call (code_execution_20250825/code_execution_20260120) while a dependent tool call still references it via caller, the provider now omits that dangling caller metadata — rather than sending it as-is and having Anthropic reject the request with "source tool ... not found" — and returns one warning per affected tool call. The call, its result, ordering, and cache controls are otherwise unchanged; a caller that still resolves to an emitted server_tool_use block, or that is in an active continuation not yet followed by a new user message, is left untouched.

Finish Reasons​

result.FinishReason and result.RawFinishReason (and their StreamChunk equivalents) report Anthropic's raw stop_reason alongside the normalized value. Since this release, three additional raw reasons map to non-"other" finish reasons, matching TS:

Anthropic stop_reasonFinishReason
end_turn, stop_sequencestop
pause_turnstop
refusalcontent-filter
model_context_window_exceededlength
max_tokenslength
tool_usetool-calls

RawFinishReason always carries Anthropic's original string (e.g. "pause_turn"), so you can distinguish these cases from a plain end_turn even though they share the same normalized FinishReason.

Workflow Serialization​

Anthropic language models can cross a workflow boundary with providerutils.SerializeModel / DeserializeModel. See Provider Serialization for the mechanism. Anthropic has no embedding, image, speech, transcription, or video models, so there is nothing else to serialize.

See Also​

May 2026 parity updates​

Claude Opus 4.7​

Use anthropic.ClaudeOpus4_7 for Claude Opus 4.7. The provider maps top-level Reasoning to Anthropic thinking settings and supports x-high effort on the newest Opus models.

p := anthropic.New(anthropic.Config{APIKey: os.Getenv("ANTHROPIC_API_KEY")})
model, err := p.LanguageModel(anthropic.ClaudeOpus4_7)

Inference geography and task budget​

ModelOptions includes InferenceGeo and TaskBudget, matching the TypeScript provider options.

remaining := 12000
model, err := p.LanguageModelWithOptions(anthropic.ClaudeOpus4_7, &anthropic.ModelOptions{
InferenceGeo: "us",
TaskBudget: &anthropic.TaskBudget{
Type: "tokens",
Total: 32000,
Remaining: &remaining,
},
})

Schema and beta header behavior​

The provider sanitizes unsupported JSON Schema validation properties before sending tools or structured output requests to Anthropic. The obsolete fine-grained tool streaming beta header is no longer injected.