Anthropic Provider
Provider Key: anthropic
Overview
The Anthropic provider enables HPD-Agent to use Claude models from Anthropic. Claude excels at complex reasoning, coding tasks, creative writing, and multi-step problem solving with industry-leading context windows.
Key Features:
- Extended Thinking mode - See Claude's reasoning process
- Prompt Caching - Up to 90% cost reduction for repeated contexts
- Function/tool calling with JSON Schema
- Vision support for image analysis
- 200K token context window (Claude 3.5)
- Service tiers for request prioritization
- Streaming support for real-time responses
For detailed API documentation, see:
- AnthropicProviderConfig API Reference - Complete property listing
Quick Start
Minimal Example
using HPD.Agent;
using HPD.Agent.Providers.Anthropic;
// Set API key via environment variable
Environment.SetEnvironmentVariable("ANTHROPIC_API_KEY", "sk-ant-...");
var agent = await new AgentBuilder()
.WithAnthropic(model: "claude-sonnet-4-5-20250929")
.Build();
var response = await agent.RunAsync("What is the capital of France?");
Console.WriteLine(response);Installation
dotnet add package HPD-Agent.Providers.AnthropicDependencies:
Anthropic- Official Anthropic C# SDKMicrosoft.Extensions.AI- AI abstractions
Note: This provider wraps the official Anthropic C# SDK and is not compatible with Native AOT due to SDK limitations (see Native AOT Compatibility).
Configuration
Configuration Patterns
The Anthropic provider supports all three configuration patterns. Choose the one that best fits your needs.
1. Builder Pattern (Fluent API)
Best for: Simple configurations and quick prototyping.
var agent = await new AgentBuilder()
.WithAnthropic(
model: "claude-sonnet-4-5-20250929",
configure: opts =>
{
opts.MaxTokens = 4096;
opts.Temperature = 0.7;
opts.EnablePromptCaching = true;
})
.Build();2. Config Pattern (Data-Driven)
Best for: Serialization, persistence, and configuration files.
C# Config Object:
var config = new AgentConfig
{
Name = "ClaudeAgent",
Provider = new ProviderConfig
{
ProviderKey = "anthropic",
ModelName = "claude-sonnet-4-5-20250929"
}
};
var anthropicOpts = new AnthropicProviderConfig
{
MaxTokens = 4096,
Temperature = 0.7,
EnablePromptCaching = true
};
config.Provider.SetTypedProviderConfig(anthropicOpts);
var agent = await config.BuildAsync();JSON Config File:
{
"Name": "ClaudeAgent",
"Provider": {
"ProviderKey": "anthropic",
"ModelName": "claude-sonnet-4-5-20250929",
"ProviderOptionsJson": "{\"maxTokens\":4096,\"temperature\":0.7,\"enablePromptCaching\":true}"
}
}var agent = await AgentConfig
.BuildFromFileAsync("claude-config.json");3. Builder + Config Pattern (Recommended)
Best for: Production deployments with reusable configuration and runtime customization.
// Define base config once
var config = new AgentConfig
{
Name = "ClaudeAgent",
Provider = new ProviderConfig
{
ProviderKey = "anthropic",
ModelName = "claude-sonnet-4-5-20250929"
}
};
var anthropicOpts = new AnthropicProviderConfig
{
MaxTokens = 4096,
Temperature = 0.7,
EnablePromptCaching = true
};
config.Provider.SetTypedProviderConfig(anthropicOpts);
// Reuse with different runtime customizations
var agent1 = new AgentBuilder(config)
.WithServiceProvider(services)
.WithToolkit<MathToolkit>()
.Build();
var agent2 = new AgentBuilder(config)
.WithServiceProvider(services)
.WithToolkit<FileToolkit>()
.Build();Provider-Specific Options
The AnthropicProviderConfig class provides comprehensive configuration options organized by category:
Core Parameters
configure: opts =>
{
// Maximum tokens to generate (default: 4096)
opts.MaxTokens = 4096;
}Sampling Parameters
configure: opts =>
{
// Sampling temperature (0.0-1.0, default: 1.0)
// Use lower values (0.0-0.3) for analytical tasks
// Use higher values (0.7-1.0) for creative tasks
opts.Temperature = 0.7;
// Top-P nucleus sampling (0.0-1.0)
// You should alter temperature or top_p, but not both
opts.TopP = 0.9;
// Top-K sampling - only sample from top K options
// Removes "long tail" low probability responses
opts.TopK = 40;
// Stop sequences - custom text that stops generation
opts.StopSequences = new List<string> { "STOP", "END" };
}Extended Thinking
configure: opts =>
{
// Enable extended thinking mode with token budget
// Must be >= 1024 and less than max_tokens
// Shows Claude's reasoning process before the final answer
opts.ThinkingBudgetTokens = 4096;
}Extended Thinking allows you to see Claude's internal reasoning process in special thinking content blocks before the final response. This is useful for:
- Complex problem-solving requiring multi-step reasoning
- Debugging Claude's decision-making process
- Educational contexts where reasoning matters
See: Extended Thinking Documentation
Service Tier
configure: opts =>
{
// Service tier for request prioritization
// "auto" (default) - Use priority capacity if available
// "standard_only" - Only use standard capacity
opts.ServiceTier = "auto";
}Service Tiers control request prioritization:
- auto: Automatically uses priority capacity when available, falls back to standard
- standard_only: Uses only standard capacity, potentially slower during high load
See: Service Tiers Documentation
Prompt Caching
configure: opts =>
{
// Enable prompt caching to reduce costs (up to 90% savings)
opts.EnablePromptCaching = true;
// Cache TTL in minutes (1-60, default: 5)
opts.PromptCacheTTLMinutes = 5;
}Prompt Caching dramatically reduces costs and latency by caching frequently used context:
- Ideal for long system prompts, documentation, or code repositories
- Reduces costs by up to 90% for cached tokens
- Reduces latency for repeated contexts
- Cache expires after TTL minutes of inactivity
See: Prompt Caching Documentation
Client Middleware
.WithAnthropic(
model: "claude-sonnet-4-5-20250929",
clientFactory: client => new LoggingChatClient(client, logger))The clientFactory parameter allows you to wrap the chat client with middleware for:
- Logging and telemetry
- Caching and memoization
- Request/response transformation
- Custom error handling
Authentication
Anthropic uses API keys for authentication. The provider supports multiple authentication methods with priority ordering.
Authentication Priority Order
- Explicit API key in
WithAnthropic()method - Environment variable:
ANTHROPIC_API_KEY - Configuration file:
appsettings.jsonunder"anthropic:ApiKey"or"Anthropic:ApiKey"
Method 1: Environment Variable (Recommended for Development)
export ANTHROPIC_API_KEY="sk-ant-..."// Automatically uses ANTHROPIC_API_KEY environment variable
var agent = await new AgentBuilder()
.WithAnthropic(model: "claude-sonnet-4-5-20250929")
.Build();Method 2: Configuration File (Recommended for Production)
appsettings.json:
{
"anthropic": {
"ApiKey": "sk-ant-..."
}
}// Automatically loads from appsettings.json
var agent = await new AgentBuilder()
.WithAnthropic(model: "claude-sonnet-4-5-20250929")
.Build();Method 3: Explicit Parameter (Use with Caution)
var agent = await new AgentBuilder()
.WithAnthropic(
model: "claude-sonnet-4-5-20250929",
apiKey: "sk-ant-...")
.Build();Security Warning: Never hardcode API keys in source code. Use environment variables or configuration files instead.
Obtaining an API Key
- Sign up at console.anthropic.com
- Navigate to API Keys section
- Create a new API key
- Copy the key (starts with
sk-ant-)
API keys are scoped to workspaces and can be rotated or revoked at any time.
Supported Models
Anthropic provides multiple Claude model families optimized for different use cases:
Current Models (Recommended)
| Model ID | Name | Context | Strengths |
|---|---|---|---|
claude-sonnet-4-5-20250929 | Claude 3.5 Sonnet (v2) | 200K | Best balance - intelligence, speed, cost |
claude-opus-4-20250514 | Claude 3 Opus | 200K | Highest intelligence, complex reasoning |
claude-haiku-3-20240307 | Claude 3 Haiku | 200K | Fastest, most economical |
Legacy Models
| Model ID | Context | Notes |
|---|---|---|
claude-3-5-sonnet-20241022 | 200K | Previous Sonnet version |
claude-3-opus-20240229 | 200K | Previous Opus version |
claude-2.1 | 200K | Legacy Claude 2 |
claude-2.0 | 100K | Legacy Claude 2 |
Model Selection Guide
For most use cases: Use claude-sonnet-4-5-20250929
- Best all-around performance
- Excellent at coding, reasoning, and analysis
- Good balance of cost and capability
For maximum intelligence: Use claude-opus-4-20250514
- Best for complex multi-step reasoning
- Excels at nuanced tasks requiring deep understanding
- Higher cost but highest capability
For speed and cost: Use claude-haiku-3-20240307
- Fastest responses
- Most economical
- Great for simple tasks or high-volume applications
For the complete list of models, see:Anthropic Models Documentation
Advanced Features
Extended Thinking Mode
Extended Thinking allows Claude to show its reasoning process before providing the final answer:
var agent = await new AgentBuilder()
.WithAnthropic(
model: "claude-sonnet-4-5-20250929",
configure: opts =>
{
opts.ThinkingBudgetTokens = 4096; // Must be >= 1024
})
.Build();
var response = await agent.RunAsync("Solve this complex math problem...");
// Response includes thinking content blocks showing reasoning stepsBenefits:
- See Claude's step-by-step reasoning
- Debug incorrect responses
- Educational value in showing problem-solving approach
- Improved accuracy on complex tasks
Use Cases:
- Mathematical problem-solving
- Code debugging and optimization
- Multi-step logical reasoning
- Complex decision-making
Prompt Caching
Prompt caching reduces costs and latency by caching large, frequently-used contexts:
var agent = await new AgentBuilder()
.WithAnthropic(
model: "claude-sonnet-4-5-20250929",
configure: opts =>
{
opts.EnablePromptCaching = true;
opts.PromptCacheTTLMinutes = 5; // Cache expires after 5 min of inactivity
})
.Build();
// First call - full cost
var response1 = await agent.RunAsync("Analyze this large document...");
// Subsequent calls within TTL - 90% cost reduction on cached content
var response2 = await agent.RunAsync("What was the main theme?");Benefits:
- Up to 90% cost reduction on cached tokens
- Reduced latency for repeated contexts
- Automatic cache management
Best Practices:
- Use for large system prompts (documentation, code repositories, style guides)
- Cache stable content that doesn't change frequently
- Set appropriate TTL based on usage patterns
Caching Behavior:
- Cache is per-workspace (shared across API keys in the same workspace)
- Cache TTL resets on each access
- Cached content must be at least 1024 tokens
- Maximum 4 cache breakpoints per request
Service Tiers
Control request prioritization with service tiers:
var agent = await new AgentBuilder()
.WithAnthropic(
model: "claude-sonnet-4-5-20250929",
configure: opts =>
{
opts.ServiceTier = "auto"; // or "standard_only"
})
.Build();auto (default):
- Uses priority capacity when available
- Falls back to standard capacity during high load
- No additional cost
- Best for most use cases
standard_only:
- Only uses standard capacity
- May experience slower response times during peak usage
- Guaranteed standard pricing
Custom Endpoint
Override the default Anthropic API endpoint:
var config = new AgentConfig
{
Provider = new ProviderConfig
{
ProviderKey = "anthropic",
ModelName = "claude-sonnet-4-5-20250929",
ApiKey = "sk-ant-...",
Endpoint = "https://custom-proxy.example.com" // Custom endpoint
}
};Use Cases:
- Corporate proxy servers
- Request logging/monitoring proxies
- Anthropic Workbench (local testing)
- Custom rate limiting infrastructure
Error Handling
The Anthropic provider includes intelligent error classification and automatic retry logic.
Error Categories
| Category | HTTP Status | Retry Behavior | Examples |
|---|---|---|---|
| AuthError | 401, 403 | No retry | Invalid API key, workspace access denied |
| RateLimitRetryable | 429 | Exponential backoff | Rate limit exceeded, temporary quota |
| RateLimitTerminal | 429, 400 | No retry | Insufficient credits, quota exceeded |
| ClientError | 400 | No retry | Invalid request, malformed JSON |
| ContextWindow | 400 | No retry | Prompt too long, max context exceeded |
| ServerError | 500-599 | Retry | Internal server error, service unavailable |
| Transient | - | Retry | Network errors, connection timeouts |
Automatic Retry Configuration
The provider automatically retries transient errors with exponential backoff:
var agent = await new AgentBuilder()
.WithAnthropic(model: "claude-sonnet-4-5-20250929")
.WithErrorHandling(config =>
{
config.MaxRetryAttempts = 3; // Default
config.InitialRetryDelay = TimeSpan.FromSeconds(1);
config.MaxRetryDelay = TimeSpan.FromSeconds(60);
config.RetryMultiplier = 2.0; // Exponential backoff
})
.Build();Common Exceptions
Invalid API Key (401)
authentication_error: Invalid API keySolution:
- Verify API key starts with
sk-ant- - Check key is copied correctly (no extra spaces)
- Ensure key hasn't been revoked
Rate Limit Exceeded (429)
rate_limit_error: Number of requests exceeds rate limitSolution:
- Automatically retried with exponential backoff
- Check rate limits in Anthropic Console
- Consider upgrading tier or implementing request throttling
Insufficient Credits (400)
invalid_request_error: credit balance is too lowSolution:
- Add credits in Anthropic Console
- This is a terminal error (not retried)
Context Length Exceeded (400)
invalid_request_error: prompt is too long: X tokens > Y maximumSolution:
- Reduce input size or enable prompt caching for large contexts
- Use Claude 3.5 models (200K context)
- Implement conversation summarization
Invalid JSON Schema (400)
tools.X.custom.input_schema: JSON schema is invalidSolution:
- Ensure tool schemas comply with JSON Schema draft 2020-12
- Common issues: using
additionalProperties: falsewithanyOf, missingtype: "object"for root schema - Validate schemas at jsonschemavalidator.net using draft 2020-12
Note: HPD-Agent includes a schema-fixing wrapper to work around a known bug in the Anthropic SDK v12.x that malforms tool schemas. This is transparent to users.
Network Errors (AnthropicIOException)
Network error: Unable to connect to api.anthropic.comSolution:
- Automatically retried with exponential backoff
- Check internet connectivity
- Verify firewall/proxy settings
Streaming Errors (AnthropicSseException)
SSE parsing error during streamingSolution:
- Automatically retried
- Check network stability
- Consider using non-streaming mode for unreliable connections
Examples
Example 1: Basic Chat with Claude
using HPD.Agent;
using HPD.Agent.Providers.Anthropic;
var agent = await new AgentBuilder()
.WithAnthropic(model: "claude-sonnet-4-5-20250929")
.Build();
var response = await agent.RunAsync("Explain quantum computing in simple terms.");
Console.WriteLine(response);Example 2: Function Calling with Tools
public class WeatherToolkit
{
[Function("Get current weather for a location")]
public string GetWeather(string location)
{
return $"The weather in {location} is sunny, 72°F";
}
[Function("Get 5-day weather forecast")]
public string GetForecast(string location)
{
return $"5-day forecast for {location}: Sunny Mon-Wed, rainy Thu-Fri";
}
}
var agent = await new AgentBuilder()
.WithAnthropic(model: "claude-sonnet-4-5-20250929")
.WithToolkit<WeatherToolkit>()
.Build();
var response = await agent.RunAsync("What's the weather in Seattle and what's the forecast?");
// Claude automatically calls both tools and synthesizes the responseExample 3: Streaming Responses
var agent = await new AgentBuilder()
.WithAnthropic(model: "claude-sonnet-4-5-20250929")
.Build();
Console.Write("Claude: ");
await foreach (var chunk in agent.RunAsync("Write a short story about AI."))
{
Console.Write(chunk);
}
Console.WriteLine();Example 4: Extended Thinking Mode
var agent = await new AgentBuilder()
.WithAnthropic(
model: "claude-sonnet-4-5-20250929",
configure: opts =>
{
opts.ThinkingBudgetTokens = 4096; // Enable thinking mode
})
.Build();
var response = await agent.RunAsync(@"
A farmer needs to cross a river with a fox, a chicken, and a bag of grain.
The boat can only hold the farmer and one other item.
If left alone, the fox will eat the chicken, and the chicken will eat the grain.
How does the farmer get everything across safely?
");
// Response includes thinking blocks showing Claude's reasoning process
Console.WriteLine(response);Example 5: Prompt Caching for Large Contexts
var agent = await new AgentBuilder()
.WithAnthropic(
model: "claude-sonnet-4-5-20250929",
configure: opts =>
{
opts.EnablePromptCaching = true;
opts.PromptCacheTTLMinutes = 10;
})
.Build();
// First call - caches the large documentation
var response1 = await agent.RunAsync(@"
Here is our 50-page API documentation: [large documentation here...]
Question: How do I authenticate?
");
// Subsequent calls - 90% cost reduction on cached documentation
var response2 = await agent.RunAsync(@"
Here is our 50-page API documentation: [same documentation...]
Question: What rate limits apply?
");Example 6: Vision - Image Analysis
var agent = await new AgentBuilder()
.WithAnthropic(model: "claude-sonnet-4-5-20250929")
.Build();
var imageBytes = File.ReadAllBytes("diagram.png");
var imageData = Convert.ToBase64String(imageBytes);
var response = await agent.RunAsync(new[]
{
new ChatMessage
{
Role = ChatRole.User,
Content = new[]
{
new TextContent { Text = "Analyze this architecture diagram:" },
new ImageContent
{
Data = imageData,
MediaType = "image/png"
}
}
}
});
Console.WriteLine(response);Example 7: Multi-Turn Conversation with History
var agent = await new AgentBuilder()
.WithAnthropic(
model: "claude-sonnet-4-5-20250929",
configure: opts =>
{
opts.MaxTokens = 4096;
opts.Temperature = 0.7;
})
.Build();
var history = new List<ChatMessage>();
// Turn 1
history.Add(new ChatMessage
{
Role = ChatRole.User,
Content = "I'm building a REST API"
});
var response1 = await agent.RunAsync(history);
history.Add(new ChatMessage
{
Role = ChatRole.Assistant,
Content = response1
});
// Turn 2 - Claude remembers context
history.Add(new ChatMessage
{
Role = ChatRole.User,
Content = "What authentication should I use?"
});
var response2 = await agent.RunAsync(history);
Console.WriteLine(response2);Example 8: Client Middleware for Logging
public class LoggingChatClient : IChatClient
{
private readonly IChatClient _inner;
private readonly ILogger _logger;
public LoggingChatClient(IChatClient inner, ILogger logger)
{
_inner = inner;
_logger = logger;
}
public async Task<ChatCompletion> CompleteAsync(
IList<ChatMessage> messages,
ChatOptions? options = null,
CancellationToken cancellationToken = default)
{
_logger.LogInformation("Sending request to Claude: {MessageCount} messages", messages.Count);
var start = DateTime.UtcNow;
var result = await _inner.CompleteAsync(messages, options, cancellationToken);
var duration = DateTime.UtcNow - start;
_logger.LogInformation("Received response in {Duration}ms", duration.TotalMilliseconds);
return result;
}
// Implement other IChatClient members...
}
var agent = await new AgentBuilder()
.WithAnthropic(
model: "claude-sonnet-4-5-20250929",
clientFactory: client => new LoggingChatClient(client, logger))
.Build();Troubleshooting
"Anthropic requires an API key"
Problem: Missing API key in configuration.
Solution:
// Option 1: Environment variable
Environment.SetEnvironmentVariable("ANTHROPIC_API_KEY", "sk-ant-...");
// Option 2: Explicit parameter
.WithAnthropic(model: "...", apiKey: "sk-ant-...")
// Option 3: appsettings.json
{
"anthropic": {
"ApiKey": "sk-ant-..."
}
}"authentication_error: Invalid API key"
Problem: API key is incorrect or revoked.
Solution:
- Verify key starts with
sk-ant- - Check for extra spaces or newlines
- Generate new key in Anthropic Console
- Ensure key belongs to correct workspace
"rate_limit_error: Number of requests exceeds rate limit"
Problem: Too many requests in a short time period.
Solution: The provider automatically retries with exponential backoff. If persistent:
- Check rate limits in Anthropic Console
- Implement client-side request throttling
- Consider upgrading to higher tier
"credit balance is too low"
Problem: Insufficient credits in workspace.
Solution:
- Add credits in Anthropic Console
- This is a terminal error (not automatically retried)
- Set up billing alerts to avoid interruption
"prompt is too long: X tokens > Y maximum"
Problem: Input exceeds model's context window.
Solution:
// Option 1: Use prompt caching for large contexts
configure: opts =>
{
opts.EnablePromptCaching = true;
}
// Option 2: Reduce input size
// - Summarize previous conversation turns
// - Remove unnecessary context
// - Split into multiple requests
// Option 3: Use Claude 3.5 (200K context)
.WithAnthropic(model: "claude-sonnet-4-5-20250929")"Thinking budget tokens must be at least 1024"
Problem: ThinkingBudgetTokens set too low.
Solution:
configure: opts =>
{
opts.ThinkingBudgetTokens = 1024; // Minimum
// or
opts.ThinkingBudgetTokens = 4096; // Recommended
}"PromptCacheTTLMinutes must be between 1 and 60"
Problem: Invalid cache TTL value.
Solution:
configure: opts =>
{
opts.PromptCacheTTLMinutes = 5; // Valid: 1-60 minutes
}"JSON schema is invalid"
Problem: Tool schema doesn't comply with JSON Schema draft 2020-12.
Solution:
- HPD-Agent includes an automatic schema-fixing wrapper
- If still encountering issues, validate schemas at jsonschemavalidator.net
- Common issues:
- Using
additionalProperties: falsewithanyOf - Missing
type: "object"for root schema - Incompatible schema keywords
- Using
Connection timeouts
Problem: Requests timing out.
Solution:
// Option 1: Increase agent timeout
.WithErrorHandling(config =>
{
config.RequestTimeout = TimeSpan.FromMinutes(3);
})
// Option 2: Reduce max tokens for faster responses
configure: opts =>
{
opts.MaxTokens = 2048; // Instead of 4096
}
// Option 3: Check network connectivity
// - Verify firewall allows api.anthropic.com
// - Check proxy configuration
// - Test with curl: curl -I https://api.anthropic.com"You should alter temperature or top_p, but not both"
Problem: Both temperature and top_p are set.
Solution: Choose one sampling method:
configure: opts =>
{
// Option 1: Use temperature only
opts.Temperature = 0.7;
opts.TopP = null;
// Option 2: Use top_p only
opts.Temperature = null;
opts.TopP = 0.9;
}Native AOT Compatibility
The Anthropic provider is NOT compatible with Native AOT deployments.
Why Not AOT Compatible?
The official Anthropic C# SDK has AOT compatibility blockers.
Making the SDK AOT compatible would require a complete architectural rewrite.
Alternatives for Native AOT
If you need Native AOT support, use the other providers instead.
HPD-Agent itself is fully Native AOT compatible with comprehensive source generation - only the Anthropic SDK dependency prevents AOT support.
Contributing
If Native AOT support for Anthropic is critical to your use case, consider contributing to the upstream Anthropic SDK to add source generation support.
AnthropicProviderConfig API Reference
Core Parameters
| Property | Type | Default | Description |
|---|---|---|---|
MaxTokens | int | 4096 | Maximum tokens to generate |
Sampling Parameters
| Property | Type | Range | Default | Description |
|---|---|---|---|---|
Temperature | double? | 0.0-1.0 | 1.0 | Randomness in responses (lower = analytical, higher = creative) |
TopP | double? | 0.0-1.0 | - | Nucleus sampling threshold (don't use with Temperature) |
TopK | long? | - | - | Sample from top K options only |
StopSequences | List<string>? | - | - | Custom sequences that stop generation |
Extended Thinking
| Property | Type | Constraint | Description |
|---|---|---|---|
ThinkingBudgetTokens | long? | ≥ 1024 | Token budget for extended thinking mode |
Service Tier
| Property | Type | Values | Default | Description |
|---|---|---|---|---|
ServiceTier | string? | "auto", "standard_only" | - | Request prioritization tier |
Prompt Caching
| Property | Type | Range | Default | Description |
|---|---|---|---|---|
EnablePromptCaching | bool | - | false | Enable prompt caching for cost reduction |
PromptCacheTTLMinutes | int? | 1-60 | 5 | Cache expiration time in minutes |