Uso Idiomático de Ferramentas em Go, Java, C#, PHP e Ruby
O uso de ferramentas (tool_use) é o mesmo protocolo em todos os lugares onde o Claude é executado, mas definir um esquema de ferramenta e ler o resultado de volta é diferente em cada idioma. Esta página compara essa sintaxe em todos os cinco SDKs oficiais além de Python e TypeScript.
Como Usar Esta Lista
- Leia a entrada para o seu idioma primeiro, depois percorra as outras para reconhecer o padrão ao ler exemplos entre idiomas.
- Cada exemplo define a mesma ferramenta (uma função
get_weatherque recebe uma stringcity), para que a comparação seja direta. - O protocolo de comunicação - o que o Claude realmente envia e espera de volta - é idêntico em todos os cinco; apenas a sintaxe da linguagem hospedeira muda.
- Combine isso com o loop geral de uso de ferramentas (
tool_use) (requisição, blocotool_use, executar a ferramenta, enviartool_result) se você ainda não viu esse fluxo antes.
Go: Esquemas Baseados em Structs
Go descreve o esquema de entrada de uma ferramenta como uma struct tipada mais um ToolInputSchemaParam explícito, e lê os resultados alternando o tipo dos blocos de conteúdo.
type WeatherInput struct {
City string `json:"city"`
}
weatherTool := anthropic.ToolParam{
Name: anthropic.String("get_weather"),
Description: anthropic.String("Get the current weather for a city."),
InputSchema: anthropic.ToolInputSchemaParam{
Type: "object",
Properties: map[string]interface{}{
"city": map[string]string{"type": "string"},
},
Required: []string{"city"},
},
}
for _, block := range message.Content {
if toolUse, ok := block.AsAny().(anthropic.ToolUseBlock); ok {
var input WeatherInput
json.Unmarshal(toolUse.Input, &input)
}
}- O esquema é construído a partir das tags
jsonde uma struct Go mais um mapaPropertiesexplícito; Go não tem reflexão de JSON Schema integrada, então você escreve ambos manualmente. - Ler um resultado significa alternar o tipo de
block.AsAny()para encontrar umToolUseBlock, entãojson.Unmarshal-ing seus bytes brutos deInputem sua própria struct tipada. - Este é o mais verboso dos cinco, em troca de verificação de campo em tempo de compilação no destino do unmarshal.
Java: Esquemas com Padrão Builder
Java expressa o mesmo esquema através de seu padrão builder e lê os resultados inspecionando objetos de bloco de conteúdo tipados.
Tool weatherTool = Tool.builder()
.name("get_weather")
.description("Get the current weather for a city.")
.inputSchema(Tool.InputSchema.builder()
.properties(JsonValue.from(Map.of(
"city", Map.of("type", "string")
)))
.putAdditionalProperty("required", JsonValue.from(List.of("city")))
.build())
.build();
for (ContentBlock block : message.content()) {
if (block.isToolUse()) {
ToolUseBlock toolUse = block.asToolUse();
String city = toolUse.input().asObject().get("city").asString().get();
}
}Tool.builder()espelha a convenção de builder fluente que Java usa em todos os outros lugares no SDK, incluindo a própria requisição de mensagem.- As propriedades do esquema de entrada são construídas como um
Mapencapsulado emJsonValue, já que Java não tem sintaxe nativa de literal JSON. - Ler um resultado significa verificar
block.isToolUse()antes de chamarblock.asToolUse(), então navegar pelo JSON como uma árvore genérica em vez de desserializar automaticamente para um POJO.
C#: Objetos de Requisição Tipados
C# define o esquema como um objeto tipado e lê os resultados através de correspondência de padrões em tipos de bloco de conteúdo.
var weatherTool = new Tool
{
Name = "get_weather",
Description = "Get the current weather for a city.",
InputSchema = new
{
type = "object",
properties = new { city = new { type = "string" } },
required = new[] { "city" }
}
};
foreach (var block in response.Content)
{
if (block is ToolUseContent toolUse)
{
var city = toolUse.Input["city"].ToString();
}
}InputSchemaé frequentemente construído como um objeto anônimo serializado para JSON, já que C# não tem um tipo JSON Schema de primeira classe no SDK.- O tratamento de resultados usa o operador
isde correspondência de padrões do C# para verificar o tipo de tempo de execução do bloco, o equivalente C# do switch de tipo do Go ou da verificaçãoisToolUse()do Java. toolUse.Inputé tipicamente uma estrutura semelhante a um dicionário que você indexa por chave, mais próximo da abordagem de PHP e Ruby do que do padrão estrito de desmarshal para struct do Go.
PHP: Arrays Associativos
PHP não tem tipagem em tempo de compilação para isso, então tanto o esquema quanto o resultado são arrays associativos simples.
$weatherTool = [
'name' => 'get_weather',
'description' => 'Get the current weather for a city.',
'input_schema' => [
'type' => 'object',
'properties' => [
'city' => ['type' => 'string'],
],
'required' => ['city'],
],
];
foreach ($response->content as $block) {
if ($block->type === 'tool_use') {
$city = $block->input['city'];
}
}- O esquema da ferramenta é escrito como um array associativo aninhado que espelha diretamente a forma do JSON Schema, chave por chave.
- O tratamento de resultados verifica
$block->type === 'tool_use'e então indexa$block->inputcomo um array normal, já que PHP não desmarshal para classes tipadas por padrão. - Esta é a menos cerimoniosa das cinco: sem builders, sem structs, apenas arrays que espelham o formato de comunicação quase literalmente.
Ruby: Hashes
A abordagem do Ruby espelha a do PHP, usando hashes com chaves de símbolo em vez de arrays associativos.
weather_tool = {
name: "get_weather",
description: "Get the current weather for a city.",
input_schema: {
type: "object",
properties: {
city: { type: "string" }
},
required: ["city"]
}
}
response.content.each do |block|
if block.type == "tool_use"
city = block.input["city"]
end
end- O hash do esquema usa chaves de símbolo (
city:) em vez de chaves de string, o que é idiomático em Ruby, mas ainda assim serializa para o mesmo JSON Schema que a API de Mensagens espera. - O tratamento de resultados verifica
block.type == "tool_use"e lêblock.inputcomo um hash, a mesma forma que o PHP produz de seu array associativo. - Ruby e PHP são a dupla mais próxima aqui: ambos pulam a tipagem estática inteiramente e deixam a forma do hash/array fazer o trabalho.
Comparando as Cinco em Resumo
| Idioma | Forma do Esquema | Acesso ao Resultado | Tipagem |
|---|---|---|---|
| Go | Struct + ToolInputSchemaParam explícito | Alternância de tipo para ToolUseBlock, então json.Unmarshal | Estática, mais verbosa |
| Java | Padrão Builder (Tool.builder()) | block.isToolUse() então block.asToolUse() | Estática, com muito uso de builder |
| C# | Objeto tipado / objeto anônimo | Correspondência de padrão com is ToolUseContent | Estática, mais leve que Go/Java |
| PHP | Array associativo | Verificar type === 'tool_use', indexar array | Dinâmica |
| Ruby | Hash com chaves de símbolo | Verificar type == "tool_use", indexar hash | Dinâmica |
Tratando o Resultado: A Forma Compartilhada
Independentemente do idioma, todo SDK espera o mesmo próximo passo depois de ler um bloco tool_use: executar a ferramenta e, em seguida, enviar uma mensagem tool_result de volta para o Claude referenciando o ID do tool_use.
resultMessage := anthropic.NewUserMessage(
anthropic.NewToolResultBlock(toolUse.ID, weatherJSON, false),
)- O bloco
tool_resultsempre carrega o ID do blocotool_useoriginal, para que o Claude possa associar o resultado à chamada que fez. - Este requisito de correspondência de ID é idêntico em todos os cinco SDKs; apenas a sintaxe para construir o bloco de resultado difere.
- Pular esta etapa, ou enviar um
tool_resultcom um ID incompatível, produz uma requisição que a API de Mensagens rejeita da mesma forma em todos os idiomas.
FAQs
O protocolo tool_use é realmente diferente entre esses cinco SDKs?
Não. O protocolo de comunicação, o que o Claude envia como um bloco tool_use e espera de volta como um tool_result, é idêntico em todos os cinco. Apenas a sintaxe da linguagem hospedeira para construir o esquema e ler o resultado difere.
Qual SDK tem menos código repetitivo para definir uma ferramenta?
PHP e Ruby, já que ambos usam arrays associativos ou hashes que mapeiam quase diretamente para o JSON Schema que a API espera, sem cerimônia de builder ou struct.
Qual SDK oferece mais segurança em tempo de compilação para entradas de ferramentas?
Go, já que json.Unmarshal tem como alvo uma struct Go real com campos tipados, capturando incompatibilidades de forma em tempo de compilação no lado do consumidor (embora a definição do esquema em si ainda seja escrita manualmente).
Preciso usar um builder em Java, ou posso construir um Tool diretamente?
O padrão builder é o ponto de entrada idiomático do SDK e o que a maioria dos exemplos usa, correspondendo a como Java constrói requisições de mensagem em geral.
Como o C# sabe qual tipo de bloco de conteúdo recebeu?
Através do operador is de correspondência de padrões do C#, verificando se um bloco de conteúdo is ToolUseContent antes de acessar campos específicos da ferramenta.
O PHP e o Ruby validam o input_schema antes de enviá-lo?
Não, nenhum dos idiomas faz validação JSON Schema no lado do cliente. Ambos enviam o array ou hash como está; um esquema malformado só é capturado quando a API de Mensagens rejeita a requisição.
O que todos os SDKs precisam para enviar um tool_result de volta para o Claude?
- O ID do bloco
tool_useoriginal - A saída da ferramenta, serializada como o conteúdo do resultado
- Um sinalizador indicando se a chamada da ferramenta foi um erro, em SDKs que expõem um
Posso misturar definições de ferramentas escritas em diferentes idiomas na mesma conversa?
Não diretamente. Cada serviço que fala com o Claude define e executa suas próprias ferramentas localmente; se dois serviços em diferentes idiomas expõem ferramentas, isso geralmente são duas integrações separadas, não uma definição compartilhada.
A verbosidade do Go aqui significa que é a escolha errada para serviços com muitas ferramentas?
Não necessariamente. A verbosidade extra oferece verificação em tempo de compilação no destino do unmarshal, o que muitas equipes preferem para serviços com muitas ferramentas e contratos de entrada rigorosos.
Onde devo procurar se quiser o loop completo de requisição/resposta, não apenas a sintaxe do esquema?
Veja o artigo do loop geral de tool_use na seção de tool-use-function-calling e o tutorial específico para Go nesta seção para um exemplo completo e executável.
Relacionados
- Chamando Claude do Go com o SDK Oficial - um exemplo completo e executável de
tool_useem Go com a requisição de acompanhamento incluída - Noções Básicas de Outros SDKs Oficiais - primeiras chamadas em cada um dos cinco idiomas antes de adicionar ferramentas
- Além de Python e TypeScript: Os Outros SDKs Oficiais do Claude - por que esses SDKs divergem idiomaticamente, apesar de compartilharem um protocolo
- Construindo um Loop de Uso de Ferramentas Multi-Turno - o fluxo agnóstico de linguagem de requisição/
tool_result/seguimento - Definindo Esquemas de Ferramentas com Nome, Descrição e Esquema de Entrada - a forma JSON Schema que a sintaxe de cada idioma produz em última análise
Versões de Stack: Escrito contra a linha de modelos Claude atual em aproximadamente 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.