Anthropic Claude LLM provider
Anthropic Claude provider for Piko's LLM service. It covers completions, streaming, tool/function calling, and structured output.
Overview
This provider implements llm.ProviderPort against the Anthropic Messages API. It serves the current Claude models (Opus, Sonnet, Haiku) and supports synchronous completions, server-sent streaming, native tool use, image input, and structured-output requests. ListModels reports a 200k token context window for the Claude 4 family. The provider does not support frequency or presence penalties, deterministic seed, parallel tool calls, or per-message names, so requests that set those fields ignore them.
The Anthropic Messages API has no dedicated structured-output endpoint. The provider emulates it with a forced synthetic tool call whose schema matches the requested type, then extracts the result from the tool-call arguments. Callers send the same ResponseFormat JSON-schema request used with any other provider and receive a typed response. The translation is invisible.
The Anthropic API requires max_tokens on every request, so the provider exposes DefaultMaxTokens (8192) as a fallback when callers do not set a per-request limit. Without it, requests fail at the API. All public methods on the provider are safe for concurrent use.
The provider is a separate Go module. Add it with go get piko.sh/piko/wdk/llm/llm_provider_anthropic. It is pure Go with no build tags and no CGO, so it runs unchanged in interpreted dev mode (dev-i) and in compiled builds.
Requirements
- An Anthropic API key with permission to call the Messages endpoint. Resolve via
ANTHROPIC_API_KEYor any registered config resolver. - Network egress to
api.anthropic.com(or yourBaseURLoverride if you proxy through a gateway).
Configuration
import (
"os"
"piko.sh/piko/wdk/llm/llm_provider_anthropic"
)
provider, err := llm_provider_anthropic.NewAnthropicProvider(llm_provider_anthropic.Config{
APIKey: os.Getenv("ANTHROPIC_API_KEY"), // required
DefaultModel: "claude-sonnet-4-5-20250929", // optional; package default if empty
DefaultMaxTokens: 8192, // optional; package default if 0
BaseURL: "", // optional; leave empty for the official endpoint
})
if err != nil {
return err
}
Config.Validate() rejects missing API keys at construction time. Config.WithDefaults() populates DefaultModel and DefaultMaxTokens from the package constants when those fields are empty.
Bootstrap
Register the provider through Piko's LLM service. piko.New returns an *SSRServer. Name the default explicitly with WithDefaultLLMProvider. There is no first-registered-wins fallback. When no call to WithDefaultLLMProvider names a default, completion and streaming calls that omit a provider name fail with ErrNoDefaultProvider.
server := piko.New(
piko.WithLLMProvider("anthropic", provider),
piko.WithDefaultLLMProvider("anthropic"),
)
The provider satisfies the standard llm.ProviderPort, so registration needs no custom glue. Once registered it joins the shared LLM service and uses the same request and response path as every other provider. The container configures a cache manager and a budget manager for that service, so caching and budget tracking apply without extra code. Anthropic prompt-cache reads surface through the normal usage accounting as CachedTokens, so cost and cache metrics work for this provider too.
For a multi-provider setup (for example Anthropic for chat, OpenAI for embeddings), register both and pick the default explicitly.
The container registers the provider's Close method for graceful shutdown. On close the provider cancels in-flight streams, drains them within a bounded timeout, and releases idle connections.
Calling the service
With Anthropic set as the default, the LLM service routes completions to it:
resp, err := llmService.Complete(ctx, &llm.CompletionRequest{
Messages: []llm.Message{
{Role: llm.RoleUser, Content: "Summarise this changelog."},
},
})
A structured-output request sets ResponseFormat to a JSON schema. The provider runs the synthetic tool round-trip and returns the JSON in the response content.
See also
Other LLM providers:
- OpenAI, widest model selection, native structured-output API.
- Gemini, cheapest competent option, multimodal-native.
- Mistral, open-weight European provider with strong code models.
- Grok, xAI provider for Grok models.
- Ollama, local inference for offline or privacy-sensitive workloads.
- Voyage, embedding-only specialist.
Framework docs:
- How to use LLMs, embeddings, and RAG, wiring the LLM service end-to-end.
- LLM API reference, every type and method on the LLM service.
External:
- Anthropic API documentation, authoritative reference for models, pricing, and request shape.