Documentation
¶
Overview ¶
Package anthropic implements the Anthropic (Claude) llms.Model with options for API key, model selection, and custom HTTP client or AWS config when used via Bedrock (see NewBedrock in this package).
Example
mdl, err := anthropic.New(
anthropic.WithToken(os.Getenv("ANTHROPIC_API_KEY")),
anthropic.WithModel("claude-3-5-sonnet-20240620"),
)
_ = mdl; _ = err
The models an account can call are listed with NewModelLister, which needs no model name, or with LLM.ListModels.
Example (AdvancedConfiguration) ¶
Example_advancedConfiguration demonstrates various configuration options
package main
import (
"context"
"fmt"
"log"
"github.com/effective-security/gogentic/pkg/llms"
"github.com/effective-security/gogentic/pkg/llms/anthropic"
)
func main() {
llm, err := anthropic.New(
anthropic.WithModel("claude-3-5-sonnet-20241022"),
anthropic.WithBaseURL("https://api.anthropic.com"),
// anthropic.WithHTTPClient(&http.Client{Timeout: 30 * time.Second}),
// anthropic.WithAnthropicBetaHeader("beta-feature-1"),
)
if err != nil {
log.Fatal(err)
}
messages := []llms.Message{
llms.MessageFromTextParts(llms.RoleSystem, "You are a creative writer."),
llms.MessageFromTextParts(llms.RoleHuman, "Write a very short story about a robot learning to paint."),
}
resp, err := llm.GenerateContent(context.Background(), messages,
llms.WithTemperature(0.8), // Higher creativity
llms.WithMaxTokens(300), // Limit response length
llms.WithTopP(0.9), // Nucleus sampling
llms.WithStopWords([]string{"END"}), // Stop if this sequence appears
)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Generated story:\n%s\n", resp.Choices[0].Content)
// Access generation metadata
info := resp.Choices[0].Usage
if info.InputTokens > 0 {
fmt.Printf("Input tokens used: %v\n", info.InputTokens)
}
if info.OutputTokens > 0 {
fmt.Printf("Output tokens used: %v\n", info.OutputTokens)
}
if info.TotalTokens > 0 {
fmt.Printf("Total tokens used: %v\n", info.TotalTokens)
}
}
Output:
Example (BasicUsage) ¶
Example_basicUsage demonstrates basic text generation
package main
import (
"context"
"fmt"
"log"
"github.com/effective-security/gogentic/pkg/llms"
"github.com/effective-security/gogentic/pkg/llms/anthropic"
)
func main() {
// Initialize the client
llm, err := anthropic.New(
anthropic.WithToken("your-api-key"), // or set ANTHROPIC_API_KEY env var
anthropic.WithModel("claude-3-5-sonnet-20241022"),
)
if err != nil {
log.Fatal(err)
}
// Create a simple message
messages := []llms.Message{
llms.MessageFromTextParts(llms.RoleHuman, "Hello, how are you?"),
}
// Generate content
resp, err := llm.GenerateContent(context.Background(), messages)
if err != nil {
log.Fatal(err)
}
fmt.Println(resp.Choices[0].Content)
}
Output:
Example (ConversationWithSystem) ¶
Example_conversationWithSystem demonstrates system messages and multi-turn conversation
package main
import (
"context"
"fmt"
"log"
"github.com/effective-security/gogentic/pkg/llms"
"github.com/effective-security/gogentic/pkg/llms/anthropic"
)
func main() {
llm, err := anthropic.New(
anthropic.WithModel("claude-3-5-sonnet-20241022"),
)
if err != nil {
log.Fatal(err)
}
messages := []llms.Message{
llms.MessageFromTextParts(llms.RoleSystem, "You are a helpful math tutor. Always explain your reasoning step by step."),
llms.MessageFromTextParts(llms.RoleHuman, "What is 25 * 4?"),
llms.MessageFromTextParts(llms.RoleAI, "Let me solve this step by step:\n25 × 4 = 100\n\nThis is because 25 × 4 is the same as 25 × 4 = (20 + 5) × 4 = 20 × 4 + 5 × 4 = 80 + 20 = 100."),
llms.MessageFromTextParts(llms.RoleHuman, "Now what about 25 * 8?"),
}
resp, err := llm.GenerateContent(context.Background(), messages)
if err != nil {
log.Fatal(err)
}
fmt.Println(resp.Choices[0].Content)
}
Output:
Example (DifferentModels) ¶
Example_differentModels demonstrates using different Claude models
package main
import (
"context"
"fmt"
"log"
"github.com/effective-security/gogentic/pkg/llms"
"github.com/effective-security/gogentic/pkg/llms/anthropic"
)
func main() {
models := []string{
"claude-3-5-haiku-20241022", // Fast and cost-effective
"claude-3-5-sonnet-20241022", // Balanced performance
"claude-3-opus-20240229", // Most capable for complex tasks
}
message := "Explain quantum computing in one sentence."
for _, model := range models {
llm, err := anthropic.New(
anthropic.WithModel(model),
)
if err != nil {
log.Printf("Failed to initialize %s: %v", model, err)
continue
}
messages := []llms.Message{
llms.MessageFromTextParts(llms.RoleHuman, message),
}
resp, err := llm.GenerateContent(context.Background(), messages,
llms.WithMaxTokens(100),
)
if err != nil {
log.Printf("Error with %s: %v", model, err)
continue
}
fmt.Printf("%s: %s\n\n", model, resp.Choices[0].Content)
}
}
Output:
Example (ErrorHandling) ¶
Example_errorHandling demonstrates proper error handling
package main
import (
"context"
"fmt"
"github.com/effective-security/gogentic/pkg/llms"
"github.com/effective-security/gogentic/pkg/llms/anthropic"
)
func main() {
// Example with invalid configuration to show error handling
llm, err := anthropic.New(
anthropic.WithToken("invalid-token"),
anthropic.WithModel("claude-3-5-sonnet-20241022"),
)
if err != nil {
fmt.Printf("Configuration error: %v\n", err)
return
}
messages := []llms.Message{
llms.MessageFromTextParts(llms.RoleHuman, "Hello"),
}
resp, err := llm.GenerateContent(context.Background(), messages)
if err != nil {
// Handle different types of errors
switch {
case contains(err.Error(), "authentication_error"):
fmt.Println("Authentication failed: check your API key")
case contains(err.Error(), "rate_limit_error"):
fmt.Println("Rate limit exceeded: please wait and retry")
case contains(err.Error(), "invalid_request_error"):
fmt.Println("Invalid request: check your parameters")
default:
fmt.Printf("Other error: %v\n", err)
}
return
}
fmt.Printf("Success: %s\n", resp.Choices[0].Content)
}
// Helper function for error handling example
func contains(s, substr string) bool {
return len(s) >= len(substr) && s[:len(substr)] == substr
}
Output:
Example (MultimodalWithImage) ¶
Example_multimodalWithImage demonstrates image analysis
package main
import (
"context"
"fmt"
"log"
"os"
"github.com/effective-security/gogentic/pkg/llms"
"github.com/effective-security/gogentic/pkg/llms/anthropic"
)
func main() {
llm, err := anthropic.New(
anthropic.WithModel("claude-3-5-sonnet-20241022"),
)
if err != nil {
log.Fatal(err)
}
// Read an image file (you would replace this with actual image data)
imageData, err := os.ReadFile("example.jpg")
if err != nil {
// For this example, we'll use a placeholder
imageData = []byte("placeholder-image-data")
}
messages := []llms.Message{
{
Role: llms.RoleHuman,
Parts: []llms.ContentPart{
llms.TextPart("What do you see in this image? Please describe it in detail."),
llms.BinaryPart("image/jpeg", imageData),
},
},
}
resp, err := llm.GenerateContent(context.Background(), messages,
llms.WithMaxTokens(500),
)
if err != nil {
log.Fatal(err)
}
fmt.Println(resp.Choices[0].Content)
}
Output:
Example (StreamingResponse) ¶
Example_streamingResponse demonstrates real-time streaming
package main
import (
"context"
"fmt"
"log"
"github.com/effective-security/gogentic/pkg/llms"
"github.com/effective-security/gogentic/pkg/llms/anthropic"
)
func main() {
llm, err := anthropic.New(
anthropic.WithModel("claude-3-5-sonnet-20241022"),
)
if err != nil {
log.Fatal(err)
}
messages := []llms.Message{
llms.MessageFromTextParts(llms.RoleHuman, "Write a short poem about programming"),
}
fmt.Print("Streaming response: ")
resp, err := llm.GenerateContent(context.Background(), messages,
llms.WithStreamingFunc(func(ctx context.Context, chunk []byte) error {
fmt.Print(string(chunk)) // Print each chunk as it arrives
return nil
}),
llms.WithMaxTokens(200),
)
if err != nil {
log.Fatal(err)
}
fmt.Printf("\n\nFinal response: %s\n", resp.Choices[0].Content)
}
Output:
Example (ToolCalling) ¶
Example_toolCalling demonstrates tool/function calling
package main
import (
"context"
"fmt"
"log"
"reflect"
"github.com/effective-security/gogentic/pkg/llms"
"github.com/effective-security/gogentic/pkg/llms/anthropic"
"github.com/effective-security/gogentic/pkg/schema"
)
func main() {
llm, err := anthropic.New(
anthropic.WithModel("claude-3-5-sonnet-20241022"),
)
if err != nil {
log.Fatal(err)
}
// Define function parameters
type WeatherParams struct {
Location string `json:"location" description:"The city and state, e.g. San Francisco, CA"`
Unit string `json:"unit" description:"Temperature unit" enum:"celsius,fahrenheit"`
}
// Create schema for function parameters
schema, err := schema.New(reflect.TypeOf(WeatherParams{}))
if err != nil {
log.Fatal(err)
}
// Define available functions
tools := []llms.Tool{
{
Type: "function",
Function: &llms.FunctionDefinition{
Name: "get_weather",
Description: "Get current weather information for a location",
Parameters: schema.Parameters,
},
},
}
messages := []llms.Message{
llms.MessageFromTextParts(llms.RoleHuman, "What's the weather like in Tokyo, Japan?"),
}
// Make the request with functions
resp, err := llm.GenerateContent(context.Background(), messages,
llms.WithTools(tools),
)
if err != nil {
log.Fatal(err)
}
// Check if the model wants to call a function
if len(resp.Choices[0].ToolCalls) > 0 {
toolCall := resp.Choices[0].ToolCalls[0]
fmt.Printf("Function call requested:\n")
fmt.Printf(" Function: %s\n", toolCall.FunctionCall.Name)
fmt.Printf(" Arguments: %s\n", toolCall.FunctionCall.Arguments)
// Simulate function execution (you would implement the actual function here)
functionResult := "Temperature: 22°C, Condition: Partly cloudy, Humidity: 65%"
// Continue the conversation with the function result
messages = append(messages, llms.Message{
Role: llms.RoleAI,
Parts: []llms.ContentPart{
llms.ToolCall{
ID: toolCall.ID,
FunctionCall: toolCall.FunctionCall,
},
},
})
messages = append(messages, llms.Message{
Role: llms.RoleTool,
Parts: []llms.ContentPart{
llms.ToolCallResponse{
ToolCallID: toolCall.ID,
Content: functionResult,
},
},
})
// Get the final response
finalResp, err := llm.GenerateContent(context.Background(), messages)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Final response: %s\n", finalResp.Choices[0].Content)
} else {
fmt.Printf("Direct response: %s\n", resp.Choices[0].Content)
}
}
Output:
Index ¶
- Constants
- Variables
- func GenerateMessagesContent(ctx context.Context, o *LLM, messages []llms.Message, opts *llms.CallOptions) (*llms.ContentResponse, error)
- func GenerateStreamingContent(ctx context.Context, o *LLM, params anthropic.MessageNewParams, ...) (*llms.ContentResponse, error)
- func HandleAIMessage(msg llms.Message) (anthropic.MessageParam, error)
- func HandleHumanMessage(msg llms.Message) (anthropic.MessageParam, error)
- func HandleSystemMessage(msg llms.Message) (string, error)
- func HandleToolMessage(msg llms.Message) (anthropic.MessageParam, error)
- func NewModelLister(opts ...Option) (llms.ModelLister, error)
- func ProcessMessages(messages []llms.Message) ([]anthropic.MessageParam, string, error)
- func ToTools(tools []llms.Tool, model string) ([]anthropic.ToolUnionParam, error)
- type LLM
- func (o *LLM) GenerateContent(ctx context.Context, messages []llms.Message, options ...llms.CallOption) (*llms.ContentResponse, error)
- func (o *LLM) GetName() string
- func (o *LLM) GetProviderType() llms.ProviderType
- func (o *LLM) Infer(ctx context.Context, r llms.InferenceRequest) (*llms.InferenceResponse, error)
- func (o *LLM) ListModels(ctx context.Context) ([]llms.ModelInfo, error)
- func (o *LLM) ValidateInference(r llms.InferenceRequest) error
- type Option
- func WithAWSConfig(cfg *aws.Config) Option
- func WithAnthropicBetaHeader(value string) Option
- func WithBaseURL(baseURL string) Option
- func WithEffortPolicy(policy llms.EffortPolicy) Option
- func WithHTTPClient(client option.HTTPClient) Option
- func WithModel(model string) Option
- func WithToken(token string) Option
- type Options
Examples ¶
Constants ¶
const ( RoleUser = "user" RoleAssistant = "assistant" RoleSystem = "system" // DefaultMaxTokens is the max_tokens sent when a call sets none. It is // the 8192-token output limit of Claude 3.5 Sonnet, so that model and // every later one accept it. Claude 3 Haiku and Opus, which are // deprecated, stop at 4096 tokens and reject it: pass llms.WithMaxTokens // for them. DefaultMaxTokens = 8 * 1024 // DefaultBaseURL is the endpoint of the Anthropic API. DefaultBaseURL = "https://api.anthropic.com" )
const (
TokenEnvVarName = "ANTHROPIC_API_KEY" //nolint:gosec
)
Variables ¶
var ( ErrEmptyResponse = errors.New("anthropic: no response") ErrMissingToken = errors.New("anthropic: missing API key, set it in the ANTHROPIC_API_KEY environment variable") ErrUnexpectedResponseLength = errors.New("anthropic: unexpected length of response") ErrInvalidContentType = errors.New("anthropic: invalid content type") ErrUnsupportedMessageType = errors.New("anthropic: unsupported message type") ErrUnsupportedContentType = errors.New("anthropic: unsupported content type") )
Functions ¶
func GenerateMessagesContent ¶ added in v0.10.58
func GenerateMessagesContent(ctx context.Context, o *LLM, messages []llms.Message, opts *llms.CallOptions) (*llms.ContentResponse, error)
GenerateMessagesContent generates content using the Anthropic API with processed messages.
This function handles the core logic for generating content, including:
- Message processing and conversion to Anthropic format
- Tool definition handling
- Parameter setup (temperature, max tokens, etc.)
- Streaming and non-streaming responses
The function processes input messages to separate system prompts from conversation messages, converts tools to the Anthropic format, and handles both streaming and non-streaming responses.
func GenerateStreamingContent ¶ added in v0.10.58
func GenerateStreamingContent(ctx context.Context, o *LLM, params anthropic.MessageNewParams, streamingFunc func(context.Context, []byte) error, requestOpts ...option.RequestOption) (*llms.ContentResponse, error)
GenerateStreamingContent handles streaming responses from the Anthropic API.
This function establishes a streaming connection to the Anthropic API and processes real-time response chunks. It handles:
- Text content streaming (delta updates)
- Tool call streaming (partial JSON assembly)
- Usage statistics collection
- Error handling for streaming failures
The streaming function is called for each text chunk received, allowing for real-time display or processing of the generated content.
func HandleAIMessage ¶ added in v0.10.58
func HandleAIMessage(msg llms.Message) (anthropic.MessageParam, error)
HandleAIMessage converts AI assistant messages to Anthropic assistant message format.
This function handles AI/assistant messages and converts them to the Anthropic assistant message format. It supports:
- Text responses from the assistant
- Tool calls with function names and JSON arguments
- Mixed content (text + tool calls)
Tool call arguments are validated as proper JSON before conversion.
func HandleHumanMessage ¶ added in v0.10.58
func HandleHumanMessage(msg llms.Message) (anthropic.MessageParam, error)
HandleHumanMessage converts human messages to Anthropic user message format.
This function handles human/user messages and converts them to the Anthropic user message format. It supports:
- Text content
- Image content (PNG, JPEG, GIF, WebP)
- Base64 encoding for binary content
- Multiple content parts in a single message
Images are automatically base64-encoded and formatted for the Anthropic API.
func HandleSystemMessage ¶ added in v0.10.58
HandleSystemMessage extracts text content from system messages.
System messages in Anthropic are handled separately from conversation messages and are passed as a distinct system parameter. This function validates that the system message contains only text content and returns it as a string.
func HandleToolMessage ¶ added in v0.10.58
func HandleToolMessage(msg llms.Message) (anthropic.MessageParam, error)
HandleToolMessage converts tool response messages to Anthropic user message format.
This function handles tool call response messages and converts them to the Anthropic user message format with tool result content. Tool responses in Anthropic are sent as user messages containing tool result blocks.
The function validates that the message contains only tool call response content and formats it appropriately for the API.
func NewModelLister ¶ added in v1.0.173
func NewModelLister(opts ...Option) (llms.ModelLister, error)
NewModelLister returns a client that lists the models of an Anthropic account. It takes the options of New, and needs a token but no model name. The Bedrock endpoint has no model list: with WithAWSConfig it returns llms.ErrModelListNotSupported.
func ProcessMessages ¶ added in v0.10.58
ProcessMessages converts generic message content to Anthropic SDK message parameters.
This function processes an array of message content and converts them to the format expected by the Anthropic API. It handles:
- System message extraction (returned as separate system prompt)
- Human message conversion (text and image content)
- AI message conversion (text and tool calls)
- Tool message conversion (tool call responses)
- Error handling for unsupported message types
Returns the converted messages, extracted system prompt, and any error encountered.
func ToTools ¶ added in v0.10.58
ToTools converts LLM tool definitions to Anthropic SDK tool parameters.
This function transforms the generic llms.Tool format into the specific anthropic.ToolUnionParam format required by the Anthropic SDK. It handles:
- Function definition conversion
- JSON schema property mapping from orderedmap to regular map
- Required parameter specification
- Tool description formatting
- Model-aware web_fetch: legacy models (e.g. claude-sonnet-4-0) get WebFetchTool20250910Param, newer models get WebFetchTool20260209Param.
Returns nil if no tools are provided, which is handled gracefully by the API. Returns an error wrapping llms.ErrMissingFunctionDefinition for a tool other than web_search that has no function definition. A function without Parameters takes an empty object.
Types ¶
type LLM ¶
func New ¶
New creates a new Anthropic LLM client using the official Anthropic SDK.
This function initializes an Anthropic client with the provided options. If no token is provided via options, it will attempt to read the API key from the ANTHROPIC_API_KEY environment variable.
Required configuration:
- API token (via WithToken option or ANTHROPIC_API_KEY env var)
- Model (via WithModel option)
Example usage:
llm, err := anthropic.New(
anthropic.WithToken("your-api-key"),
anthropic.WithModel("claude-3-5-sonnet-20241022"),
)
if err != nil {
log.Fatal(err)
}
// Generate content
resp, err := llm.GenerateContent(ctx, messages)
func NewBedrock ¶ added in v0.16.114
func (*LLM) GenerateContent ¶
func (o *LLM) GenerateContent(ctx context.Context, messages []llms.Message, options ...llms.CallOption) (*llms.ContentResponse, error)
GenerateContent implements the Model interface.
This method generates content using the Anthropic API. It supports:
- Text and image inputs (multimodal)
- Tool/function calling
- Streaming responses
- Custom parameters (temperature, max tokens, etc.)
Example usage:
messages := []llms.MessageContent{
{
Role: llms.ChatMessageTypeHuman,
Parts: []llms.ContentPart{llms.TextPart("Hello, how are you?")},
},
}
resp, err := llm.GenerateContent(ctx, messages,
llms.WithTemperature(0.7),
llms.WithMaxTokens(1000),
)
func (*LLM) GetProviderType ¶ added in v0.10.54
func (o *LLM) GetProviderType() llms.ProviderType
GetProviderType implements the Model interface.
func (*LLM) Infer ¶ added in v0.21.160
func (o *LLM) Infer(ctx context.Context, r llms.InferenceRequest) (*llms.InferenceResponse, error)
Infer uses the existing Anthropic SDK client with lossless schemas, thinking passthrough and no retries.
func (*LLM) ListModels ¶ added in v1.0.173
ListModels implements llms.ModelLister. It returns the models of the account in every lifecycle stage, newest first, each with the model line as its Family and the effort levels the API reports for it.
A client built with NewBedrock returns llms.ErrModelListNotSupported: the Bedrock runtime endpoint has no model list.
func (*LLM) ValidateInference ¶ added in v0.21.160
func (o *LLM) ValidateInference(r llms.InferenceRequest) error
ValidateInference rejects nonportable Anthropic request controls.
type Option ¶
type Option func(*Options)
func WithAWSConfig ¶ added in v0.19.148
WithAWSConfig passes the AWS config to the client.
func WithAnthropicBetaHeader ¶
WithAnthropicBetaHeader adds the Anthropic Beta header to support extended options.
func WithBaseURL ¶
WithBaseUrl passes the Anthropic base URL to the client. If not set, the default base URL is used.
func WithEffortPolicy ¶ added in v1.0.173
func WithEffortPolicy(policy llms.EffortPolicy) Option
WithEffortPolicy sets the reasoning effort used when a call requests none, and the highest effort any call may use. Each call still sends the nearest level its model accepts. Legacy GenerateContent only; the portable Infer path is unaffected.
func WithHTTPClient ¶
func WithHTTPClient(client option.HTTPClient) Option
WithHTTPClient allows setting a custom HTTP client. If not set, the default value is http.DefaultClient.
type Options ¶ added in v0.10.58
type Options struct {
Token string
Model string
BaseURL string
HttpClient option.HTTPClient
// If supplied, the 'anthropic-beta' header will be added to the request with the given value.
AnthropicBetaHeader string
// AWSCfg is used with Bedrock
AWSCfg *aws.Config
// Effort is the reasoning effort default and ceiling for every call.
Effort llms.EffortPolicy
}