Chamando Claude do Go com o SDK Oficial
anthropic-sdk-go é o cliente Go oficial para a API de Mensagens do Claude, oferecendo aos serviços Go requisições tipadas, um iterador de streaming e suporte estruturado a tool_use sem chamadas HTTP manuais.
Resumo
anthropic-sdk-go encapsula a mesma API de Mensagens usada por todos os outros SDKs oficiais do Claude, mas construída em torno das convenções do Go: structs tipadas para requisição e resposta, opções funcionais para configuração do cliente e erros retornados como valores em vez de exceções.
Um cliente é um único objeto de longa duração que você constrói uma vez por processo e reutiliza entre as requisições, pois ele contém o transporte HTTP e a chave de API.
As três coisas que a maioria dos serviços Go precisa do Claude são uma chamada simples de requisição/resposta, uma chamada de streaming para saída incremental e um loop tool_use para permitir que o Claude chame funções no seu serviço.
Todos os três ficam na mesma interface client.Messages, diferindo apenas em qual método você chama e como consome o resultado.
Esta página cobre todos os três, na ordem em que a maioria dos serviços Go os adota.
Receita
Cartão de receita de referência rápida - pronto para copiar e colar.
client := anthropic.NewClient(
option.WithAPIKey(os.Getenv("ANTHROPIC_API_KEY")),
)
message, err := client.Messages.New(context.Background(), anthropic.MessageNewParams{
Model: anthropic.ModelClaudeSonnet5,
MaxTokens: 1024,
System: anthropic.String("Você é um assistente conciso."),
Messages: []anthropic.MessageParam{
anthropic.NewUserMessage(anthropic.NewTextBlock("Resuma o scheduler do Go em duas frases.")),
},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(message.Content[0].Text)Quando usar isso:
- Você está construindo um serviço Go (API HTTP, CLI, worker em segundo plano) que precisa de acesso tipado ao Claude.
- Você deseja verificação em tempo de compilação nos campos de requisição em vez de um corpo JSON bruto.
- Você precisa transmitir saída parcial para um cliente ou permitir que o Claude chame funções no seu processo via
tool_use. - Você está consolidando múltiplos clientes HTTP ad hoc em uma dependência compartilhada e tipada.
Exemplo de Trabalho
Um único programa Go que constrói um cliente, envia uma requisição de streaming e imprime tokens à medida que chegam.
package main
import (
"context"
"fmt"
"log"
"os"
"github.com/anthropics/anthropic-sdk-go"
"github.com/anthropics/anthropic-sdk-go/option"
)
func main() {
client := anthropic.NewClient(
option.WithAPIKey(os.Getenv("ANTHROPIC_API_KEY")),
)
ctx := context.Background()
stream := client.Messages.NewStreaming(ctx, anthropic.MessageNewParams{
Model: anthropic.ModelClaudeSonnet5,
MaxTokens: 512,
Messages: []anthropic.MessageParam{
anthropic.NewUserMessage(anthropic.NewTextBlock("Liste três benefícios das goroutines do Go.")),
},
})
message := anthropic.Message{}
for stream.Next() {
event := stream.Current()
if err := message.Accumulate(event); err != nil {
log.Fatal(err)
}
switch delta := event.AsAny().(type) {
case anthropic.ContentBlockDeltaEvent:
if textDelta, ok := delta.Delta.AsAny().(anthropic.TextDelta); ok {
fmt.Print(textDelta.Text)
}
}
}
if err := stream.Err(); err != nil {
log.Fatal(err)
}
fmt.Println()
fmt.Println("motivo da parada:", message.StopReason)
}O que isso demonstra:
client.Messages.NewStreamingretorna um iterador que você controla comstream.Next()estream.Current(), o formato padrão de iterador do Go.message.Accumulateconstrói aMessagefinal e completa à medida que os eventos chegam, para que você obtenha tanto o texto incremental quanto um objeto completo no final.- Deltas de texto chegam como valores
ContentBlockDeltaEventnos quais você usatype switch, correspondendo a como os eventos subjacentes enviados pelo servidor são estruturados. stream.Err()deve ser verificado após o loop terminar, pois uma falha no meio do stream não necessariamente aparece dentro do próprio loop.
Mergulho Profundo
Como Funciona
- O SDK traduz cada struct Go tipada para o mesmo corpo JSON que a API de Mensagens espera; nada sobre o formato da comunicação muda porque você está usando Go.
client.Messages.Newemite uma única requisição HTTP bloqueante e retorna umaMessagetotalmente populada.client.Messages.NewStreamingabre uma conexão de eventos enviados pelo servidor (server-sent events) e expõe cada evento através do iterador; a conexão permanece aberta atémessage_stopou um erro.tool_useé apenas outrostop_reasonna resposta: quando o Claude decide chamar uma ferramenta, oContentda resposta inclui um blocotool_useem vez de (ou ao lado de) texto, eStopReasoné"tool_use".
Uso de Ferramentas em Go
Definir uma ferramenta significa descrever seu esquema de entrada como uma struct tipada, e então verificar a resposta em busca de um bloco tool_use.
type WeatherInput struct {
City string `json:"city"`
}
weatherTool := anthropic.ToolParam{
Name: anthropic.String("get_weather"),
Description: anthropic.String("Obtém o clima atual para uma cidade."),
InputSchema: anthropic.ToolInputSchemaParam{
Type: "object",
Properties: map[string]interface{}{
"city": map[string]string{"type": "string"},
},
Required: []string{"city"},
},
}
message, err := client.Messages.New(ctx, anthropic.MessageNewParams{
Model: anthropic.ModelClaudeSonnet5,
MaxTokens: 512,
Tools: []anthropic.ToolUnionParam{{OfTool: &weatherTool}},
Messages: []anthropic.MessageParam{
anthropic.NewUserMessage(anthropic.NewTextBlock("Qual é o clima em Denver?")),
},
})
if err != nil {
log.Fatal(err)
}
for _, block := range message.Content {
if toolUse, ok := block.AsAny().(anthropic.ToolUseBlock); ok {
var input WeatherInput
if err := json.Unmarshal(toolUse.Input, &input); err != nil {
log.Fatal(err)
}
fmt.Println("Claude quer o clima para:", input.City)
// Execute sua consulta real aqui, depois envie uma mensagem tool_result de volta.
}
}Opções de Configuração do Cliente
| Opção | Propósito |
|---|---|
option.WithAPIKey(key) | Define a chave de API explicitamente em vez de ler ANTHROPIC_API_KEY |
option.WithBaseURL(url) | Aponta o cliente para uma URL base diferente (raro; principalmente para proxies ou testes) |
option.WithHTTPClient(httpClient) | Fornece um *http.Client personalizado, útil para pooling de conexão compartilhado ou timeouts personalizados |
option.WithMaxRetries(n) | Substitui a contagem padrão de retentativas do SDK para falhas transitórias |
Notas do Go
// Reutilize um cliente em todo o seu serviço; é seguro para uso concorrente.
var claudeClient = anthropic.NewClient(
option.WithAPIKey(os.Getenv("ANTHROPIC_API_KEY")),
)
func handleRequest(ctx context.Context, prompt string) (string, error) {
message, err := claudeClient.Messages.New(ctx, anthropic.MessageNewParams{
Model: anthropic.ModelClaudeSonnet5,
MaxTokens: 1024,
Messages: []anthropic.MessageParam{
anthropic.NewUserMessage(anthropic.NewTextBlock(prompt)),
},
})
if err != nil {
return "", fmt.Errorf("falha na requisição claude: %w", err)
}
return message.Content[0].Text, nil
}- O cliente é seguro para compartilhar entre goroutines; construa-o uma vez na inicialização e reutilize-o entre as requisições.
- Sempre passe um
context.Contextpara que os timeouts e cancelamentos de requisição se propaguem corretamente sob carga. - Envolva erros com
%wao retorná-los na pilha de chamadas, para que os chamadores ainda possam usarerrors.Aspara acessar o tipo de erro subjacente do SDK.
Armadilhas
- Construir um novo cliente para cada requisição - criar
anthropic.NewClientdentro de um manipulador de requisição descarta o pooling de conexão e adiciona latência. Correção: construa um cliente na inicialização e reutilize-o. - Ignorar
stream.Err()após o loop - um stream que termina cedo devido a um erro de rede ainda sai do loopfor stream.Next()normalmente. Correção: sempre verifiquestream.Err()após o loop, não apenas dentro dele. - Assumir que
Content[0]é sempre texto - uma resposta comtool_usecoloca umToolUseBlockemContent, não um bloco de texto, e indexar cegamente causa um pânico. Correção: verifique o tipo deblock.AsAny(), ou verifiqueStopReasonantes de lerContent[0].Text. - Esquecer que
MaxTokensé obrigatório - omiti-lo produz um erro de validação no momento da requisição em vez de um padrão sensato. Correção: sempre defina umMaxTokensexplícito dimensionado para sua resposta esperada. - Não passar um contexto cancelável sob carga - usar
context.Background()em todos os lugares significa que uma requisição lenta ou travada não pode ser cancelada por um timeout upstream. Correção: passe umcontext.Contextcom escopo de requisição e um deadline através de cada chamada. - Tratar
tool_usecomo a resposta final - receber um blocotool_usesignifica que o Claude está esperando por umtool_result, não que a tarefa esteja concluída. Correção: execute a ferramenta e, em seguida, envie o resultado de volta em uma chamadaMessages.Newde acompanhamento antes de tratar a conversa como completa.
Alternativas
| Alternativa | Usar Quando | Não Usar Quando |
|---|---|---|
| Camada de compatibilidade OpenAI com um cliente Go no formato OpenAI | Você está migrando rapidamente um serviço Go existente integrado com OpenAI e pode tolerar uma superfície de parâmetros mais restrita | Você precisa de recursos completos da API de Mensagens, como tool_use estendido ou os tipos de bloco de conteúdo mais recentes |
Chamadas net/http brutas para a API de Mensagens | Você precisa de algo sem dependências em um binário mínimo | Você deseja requisições tipadas, retentativas e análise de streaming tratadas para você |
| Um SDK oficial diferente (Java, C#, PHP, Ruby) | Seu serviço não é realmente escrito em Go | Você está especificamente trabalhando em uma base de código Go |
FAQs
Preciso construir um novo cliente para cada requisição?
Não. Construa anthropic.NewClient uma vez na inicialização e reutilize-o entre as requisições; é seguro para uso concorrente.
Como funciona o streaming em anthropic-sdk-go?
client.Messages.NewStreaming retorna um iterador. Chame stream.Next() em um loop, leia stream.Current() para cada evento e verifique stream.Err() após o loop terminar para capturar falhas no meio do stream.
Como sei quando o Claude quer chamar uma ferramenta?
Verifique message.StopReason para "tool_use", depois procure por um ToolUseBlock dentro de message.Content. O bloco carrega o nome da ferramenta e uma entrada codificada em JSON que você desserializa em sua própria struct.
O anthropic-sdk-go tenta novamente requisições falhas automaticamente?
Sim, por padrão ele tenta novamente falhas transitórias como limites de taxa e erros de rede um número limitado de vezes. Você pode substituir a contagem com option.WithMaxRetries(n).
O que acontece se eu esquecer de definir MaxTokens?
A requisição falha na validação, pois MaxTokens não tem um padrão implícito. Sempre defina-o explicitamente para um valor dimensionado para o seu comprimento de resposta esperado.
Posso usar anthropic-sdk-go com um cliente HTTP personalizado?
Sim. Passe option.WithHTTPClient(httpClient) ao construir o cliente para fornecer seu próprio *http.Client, útil para pools de conexão compartilhados ou comportamento de timeout personalizado.
O cliente é seguro para usar de múltiplas goroutines ao mesmo tempo?
Sim, um único anthropic.Client é seguro para uso concorrente, razão pela qual você deve construí-lo uma vez e compartilhá-lo em vez de criar um por requisição.
Como os erros aparecem em Go, em comparação com exceções em outros SDKs?
Erros retornam como um valor error normal do Go de cada método, seguindo a convenção do Go. Não há pânico ou exceção; verifique err != nil após cada chamada da mesma forma que faria para qualquer outra API Go.
Preciso passar context.Background() em todos os lugares?
Apenas em scripts descartáveis. Em um serviço real, passe um context.Context com escopo de requisição e um deadline ou cancelamento, para que uma chamada lenta do Claude possa ser cancelada da mesma forma que qualquer outra chamada downstream seria.
O mesmo cliente pode chamar múltiplos modelos?
Sim. Model é um campo por requisição, não uma configuração em nível de cliente, então um único cliente pode enviar requisições para Claude Fable 5, Claude Opus 4.8, Claude Sonnet 5 ou Claude Haiku 4.5 conforme necessário.
Relacionados
- Noções Básicas de Outros SDKs Oficiais - uma primeira chamada em cada uma das cinco linguagens, incluindo um exemplo mais simples em Go
- Uso Idiomático de Ferramentas em Go, Java, C#, PHP e Ruby - compare este padrão
tool_usecom os outros quatro SDKs - Além de Python e TypeScript: Os Outros SDKs Oficiais do Claude - a visão geral conceitual em que este artigo se baseia
- Construindo um Loop de Uso de Ferramentas Multi-Turno - o loop completo de requisição/tool_result/seguimento, em termos gerais
- Como os Eventos Enviados pelo Servidor Potencializam as Respostas de Streaming do Claude - o protocolo de streaming que este exemplo Go consome
Versões de Stack: Escrito contra a linha de modelos Claude atual em ~junho de 2026 - Claude Fable 5, Claude Opus 4.8, Claude Sonnet 5 (o padrão), e Claude Haiku 4.5 - e os SDKs oficiais atuais para Go, Java, C#, PHP e Ruby. Nomes de modelos, versões de SDK e preços mudam rapidamente - verifique os detalhes atuais em platform.claude.com/docs antes de confiar neles.