.NET - Construindo Agentes com Claude Agent SDK
   Aprenda como criar agentes autônomos de IA em C# utilizando o Claude Agent SDK da Anthropic, o runtime agêntico do Claude Code, execução em loop de ferramentas, políticas de segurança, permissões e MCP no ecossistema .NET.

A maioria das aplicações baseadas em LLM começa com uma arquitetura enganosamente simples:



Essa arquitetura funciona surpreendentemente bem — até que a aplicação precisa, de fato, fazer alguma coisa.

No momento em que um sistema de IA precisa inspecionar arquivos, executar comandos, chamar APIs, modificar código-fonte, lembrar o que já fez, recuperar-se de falhas ou decidir qual ferramenta usar em seguida, a arquitetura muda completamente.

Você não está mais construindo um chatbot. Você está construindo um agente.

E é exatamente aqui que o Claude Agent SDK se torna interessante.

O Claude Agent SDK é a interface programática da Anthropic projetada para permitir a criação de aplicações baseadas nas mesmas capacidades agênticas que alimentam o Claude Code. Em vez de você implementar manualmente todo o loop de execução de ferramentas (tool-use loop), o SDK fornece à sua aplicação acesso a um runtime agêntico que pode raciocinar, invocar ferramentas, inspecionar resultados, continuar trabalhando e realizar streaming do seu progresso em tempo real.

Este artigo explica o que realmente é o Claude Agent SDK, como ele difere do SDK padrão da Anthropic, como funciona o loop agêntico e como construir agentes úteis no ecossistema .NET com C#.

 

1. O Problema de Chamar um LLM Diretamente

Suponha que você queira construir um assistente de programação. Com uma API tradicional de LLM (como o SDK padrão de mensagens), você faria algo como:

var response = await anthropicClient.Messages.CreateAsync(new MessageParameters
{
    Model = "claude-3-7-sonnet-20250219",
    Messages = [
        new Message { Role = "user", Content = "Encontre o bug neste projeto" }
    ]
});

O modelo pode explicar textualmente o que ele acha que é o problema. No entanto, ele não consegue necessariamente:
- Inspecionar seu repositório local;
- Abrir os arquivos de código relevantes;
- Buscar por referências e declarações;
- Executar testes (dotnet test);
- Modificar um arquivo no disco;
- Rodar os testes novamente;
- Analisar as falhas de compilação ou de teste;
- Corrigir a implementação;
- Validar e verificar o reparo.

Você teria que construir toda essa camada de orquestração por conta própria. Conceitualmente, sua aplicação se tornaria:



E então você precisaria gerenciar manualmente: esquemas JSON de ferramentas (tool schemas), execução e tratamento de resultados de ferramentas, múltiplos turnos de conversa (multi-turn loops), tratamento de erros e exceções, políticas de permissão e segurança, streaming de eventos e saídas, estado de sessão e gerenciamento de contexto, cancelamentos, tentativas (retries) e sub-agentes especializados.

É exatamente aqui que os frameworks e SDKs agênticos se tornam valiosos.

2. O que é o Claude Agent SDK?

O Claude Agent SDK é um SDK oficial da Anthropic voltado para a construção programática de agentes capazes de utilizar as funcionalidades agênticas do Claude.

A distinção essencial é que ele não é simplesmente outro invólucro (wrapper) em torno da API de Mensagens do Claude.

A Anthropic também disponibiliza o SDK padrão do Claude:
- No Python: f
rom anthropic import Anthropic (via pip install anthropic)
- No ecossistema .NET: via pacote NuGet Anthropic
(dotnet add package Anthropic)

Esse SDK convencional concede acesso direto e de baixo nível à API do Claude. O Agent SDK, por outro lado, fornece um runtime orientado a agentes.

Instalação no Ecossistema .NET:

Para utilizar o Claude Agent SDK na plataforma .NET (.NET 8 ou superior), o pacote e o ambiente são configurados da seguinte forma:

1. Instalação do pacote NuGet no seu projeto:
 
dotnet add package ClaudeAgentSdk   ou
dotnet add package ClaudeAgentSdk --prerelease

(Ou via Gerenciador de Pacotes do Visual Studio: Install-Package ClaudeAgentSdk)

2. Pré-requisito do Runtime (Claude Code CLI):
Assim como a biblioteca empacota ou interage com a engine do Claude Code, o runtime necessita do utilitário de linha de comando instalado no ambiente de desenvolvimento:
 
npm install -g @anthropic-ai/claude-code

3. Configuração da Chave de API:
 
# Windows (PowerShell)
$env:ANTHROPIC_API_KEY = "sua-chave-api-aqui"

# Linux / macOS
export ANTHROPIC_API_KEY="sua-chave-api-aqui"

A distinção arquitetural pode ser compreendida da seguinte forma :



O segundo modelo é muito mais próximo do que significa construir um agente autônomo real.

3. O Ciclo Agêntico (The Agent Loop)

O conceito mais importante para entender é o loop do agente. Um agente não é simplesmente prompt → resposta. Ele funciona segundo o fluxo iterativo:



Esse loop é o que transforma um modelo tradicional em um sistema agêntico.

Por exemplo: “Encontre o motivo pelo qual os testes estão falhando e corrija o problema.”

O agente pode decidir autonomamente:
1. Inspecionar a estrutura do projeto;
2. Localizar a pasta e arquivos de testes;
3. Ler os arquivos-fonte relevantes;
4. Executar a suíte de testes (dotnet test);
5. Analisar o log de falhas;
6. Modificar a implementação no código-fonte;
7. Executar os testes novamente;
8. Analisar o novo resultado;
9. Repetir o processo, se necessário;
10. Reportar a conclusão e o resumo da correção.

O ponto interessante é que você não precisa programar rigidamente essa sequência passo a passo: o agente determina dinamicamente qual ação deve acontecer em seguida.

4. Seu Primeiro Agente Claude em C#

Um exemplo mínimo em .NET usando C# é conciso:

using ClaudeAgentSdk;
Console.WriteLine("Meu primeiro Agente usando Claude Agent SDK\n");
Console.WriteLine("Pressione qualquer tecla para iniciar...\n");
Console.ReadKey();
try
{
 // O método QueryAsync retorna um IAsyncEnumerable<AgentMessage>
 await foreach (var message in ClaudeAgent.QueryAsync("Explique o que este projeto faz."))
 {
     Console.WriteLine(message);
 }
}
catch (ArgumentException ex) when (ex.Message.Contains("rate_limit_event"))
{
    Console.ForegroundColor = ConsoleColor.Yellow;
    Console.WriteLine("\n[Aviso]: Limite de requisições atingido na API da Anthropic ou chave sem créditos.");
    Console.ResetColor();
}
catch (Exception ex)
{
    Console.ForegroundColor = ConsoleColor.Red;
    Console.WriteLine($"\n[Erro]: {ex.Message}");
    Console.ResetColor();
}

O método
QueryAsync() do SDK é assíncrono e expõe um iterador assíncrono (IAsyncEnumerable). Isso significa que você não fica bloqueado aguardando uma única resposta monolítica: você pode consumir a saída do agente progressivamente à medida que ele avança na execução.

5. Lendo Mensagens do Assistente de Forma Estruturada

Em uma aplicação de produção, normalmente você não deseja imprimir todos os objetos internos na saída bruta. Você pode inspecionar os tipos de mensagens fortemente tipadas expostas pelo SDK:

using ClaudeAgentSdk;

try
{
        await foreach (var message in ClaudeAgent.QueryAsync("Explique este projeto."))
        {
            if (message is AssistantMessage assistantMessage)
            {
                foreach (var block in assistantMessage.Content)
                {
                    if (block is TextBlock textBlock)
                    {
                        Console.WriteLine(textBlock.Text);
                    }
                }
            }
        }
}
catch (ArgumentException ex) when (ex.Message.Contains("rate_limit_event"))
{
    Console.ForegroundColor = ConsoleColor.Yellow;
    Console.WriteLine("\n[Aviso]: Limite de requisições atingido na API da Anthropic ou chave sem créditos.");
    Console.ResetColor();
}
catch (Exception ex)
{
    Console.ForegroundColor = ConsoleColor.Red;
    Console.WriteLine($"\n[Erro]: {ex.Message}");
    Console.ResetColor();
}

O SDK expõe tipos de mensagens e blocos estruturados como AssistantMessage, ResultMessage, TextBlock e ToolUseBlock.

Isso é fundamental porque a saída de um agente não é puramente textual; o fluxo de stream pode conter diferentes naturezas de eventos:

AssistantMessage├── TextBlock
├── ToolUseBlock
└── ToolResultBlock

Essa modelagem fornece à sua aplicação ampla visibilidade sobre o que o agente está realizando internamente.

6. Concedendo Ferramentas ao Agente

É aqui que o SDK se torna muito mais poderoso: ele permite expor ao agente o mesmo conjunto de ferramentas utilitárias nativas do Claude Code.

using ClaudeAgentSdk;

var options = new ClaudeAgentOptions
{
    AllowedTools = new List<string> { "Read", "Write", "Bash" }
};

await foreach (var message in ClaudeAgent.QueryAsync(
    "Inspecione o projeto e crie um arquivo hello.txt.", 
    options))
{
    Console.WriteLine(message);
}

A documentação do SDK descreve ferramentas nativas prontas para uso, como Read (leitura), Write (escrita), Edit (edição pontual) e Bash (terminal).

Agora o modelo não apenas descreve teoricamente o que deveria ser feito; ele pode efetivamente executar a operação no disco e no sistema operacional.

Essa é a mudança de paradigma fundamental:
- Aplicação LLM Tradicional: “Aqui está a sugestão de como você poderia corrigir o arquivo.”
- Aplicação com Agente: “Eu inspecionei o arquivo, alterei a implementação no código e validei o resultado.”

7. Permissões de Ferramentas Importam

Conceder ferramentas a um agente é extremamente poderoso, mas pode ser perigoso se feito sem critério.

Considere: AllowedTools = ["Read", "Write", "Bash"]


O agente passa a ter permissão para executar ações que causam efeitos reais no sistema. É por essa razão que o SDK disponibiliza mecanismos de controle de permissão:

var options = new ClaudeAgentOptions
{
    AllowedTools = new List<string> { "Read", "Write", "Bash" },
    PermissionMode = PermissionMode.AcceptEdits
};

Um detalhe importante: AllowedTools funciona como um mecanismo de aprovação automática prévia, e não apenas como exclusão de ferramentas do escopo do agente. Ferramentas não aprovadas previamente na lista ainda podem passar pelos fluxos de autorização configurados. O SDK também suporta DisallowedTools para bloqueio explícito de ferramentas específicas.

Você deve enxergar ferramentas como capacidades operacionais com fronteiras explícitas:

Agente
├── Ler arquivos
├── Modificar arquivos
├── Executar comandos de console
├── Invocar ferramentas externas
└── Acessar recursos customizados da aplicação

Cada capacidade deve possuir um limite de segurança deliberado.

8. O Diretório de Trabalho (Working Directory)

Agentes precisam de contexto e, no caso de um agente de desenvolvimento, esse contexto geralmente é o repositório ou a solução .sln.

O SDK permite especificar o diretório de trabalho:

var options = new ClaudeAgentOptions
{
    Cwd = @"C:\Projetos\MeuProjetoDotNet" // ou "/path/to/project"
};

Com isso, todas as operações do agente passam a ser relativas ao ambiente daquele projeto.

Embora pareça uma simples configuração, seu impacto arquitetural é enorme: em vez de você ler todo o repositório e injetar gigabytes de texto no prompt do modelo, o agente inspeciona o ambiente sob demanda:

- LLM Tradicional: Repositório → Ler tudo → Colocar tudo no prompt → LLM

- Agente: Repositório → Agente decide o que precisa → (Ler arquivo A / Buscar símbolos / Ler arquivo B / Rodar teste)

O agente coleta progressivamente apenas as informações necessárias para resolver a tarefa.

9. Prompts de Sistema (System Prompts)

Você também pode guiar e restringir o comportamento operacional do agente:

var options = new ClaudeAgentOptions
{
    SystemPrompt = """
        Você é um Engenheiro de Software Sênior em C#/.NET.
        - Prefira alterações pequenas, modulares e de fácil manutenção.
        - Nunca altere arquivos não relacionados ao escopo.
        - Execute os testes relevantes após realizar qualquer modificação.
        - Ao final, explique claramente o que foi alterado.
        """,
    MaxTurns = 20
};

O suporte a configurações como SystemPrompt e MaxTurns (limite máximo de iterações do loop) permite que agentes em produção operem sob regras claras de conduta: Compreenda primeiro. Modifique em seguida. Teste logo após. Explique por último.

10. QueryAsync() vs ClaudeSdkClient

Uma decisão de design importante é escolher entre o método direto
ClaudeAgent.QueryAsync() e o cliente interativo ClaudeSdkClient.

Para tarefas diretas de execução pontual:
await foreach (var message in ClaudeAgent.QueryAsync(...)) { ... } geralmente é o suficiente.

Já para aplicações que necessitam de conversação bidirecional contínua e interativa, utiliza-se o cliente completo ClaudeSdkClient:

var options = new ClaudeAgentOptions { MaxTurns = 50 };
await using var client = new ClaudeSdkClient(options);
await client.ConnectAsync();

// Primeira instrução
await client.QueryAsync("Crie uma Web API em ASP.NET Core");
await foreach (var msg in client.ReceiveResponseAsync())
{
    // Processa a resposta inicial...
}

// Interação contínua mantendo o mesmo contexto de sessão
await client.QueryAsync("Agora adicione autenticação JWT a ela");
await foreach (var msg in client.ReceiveResponseAsync())
{
    // Processa a evolução do agente...
}

O ClaudeSdkClient oferece suporte a conversas bidirecionais, streaming, interrupções em tempo de execução, envio dinâmico de mensagens, ferramentas customizadas e interceptadores (
hooks).

O modelo mental é:

- QueryAsync(): Uma tarefa única → Agente → Resultado.

- ClaudeSdkClient: Aplicação ↔ Agente ↔ Ferramentas ↔ Aplicação (adequado para experiências interativas de longa duração).

11. Agentes como Orquestradores de Ferramentas

É aqui que a arquitetura agêntica supera a simples chamada de funções isoladas (function calling).

Suponha um agente de atendimento com acesso a: ConsultarCliente
, BuscarPedidos, ConsultarBaseConhecimento, AbrirChamado e EmitirReembolso.

Você não precisa escrever árvores condicionais manuais no seu código C#:

// Abordagem antiga e rígida
if (intencao == "cliente") ConsultarCliente();
  else if (intencao == "pedido") BuscarPedidos();
    else if (intencao == "reembolso") EmitirReembolso();

Em vez disso, o agente determina dinamicamente o encadeamento adequado:

Usuário: "Meu pedido veio danificado. Posso solicitar o reembolso?"
│
▼
Agente
├──► ConsultarCliente()
├──► BuscarPedidos()
├──► Inspecionar dados da entrega
├──► EmitirReembolso()
└──► Responder detalhadamente ao usuário

A lógica de orquestração move-se do fluxo rígido da sua aplicação para o próprio runtime do agente.

12. Hooks: Controlando o Ciclo de Vida do Agente

Aplicações corporativas precisam de uma camada intermediária de governança situada entre o Agente e a Ferramenta, com objetivos como:
- Auditar todas as invocações de ferramentas;
- Rejeitar comandos perigosos;
- Registrar telemetria e custos;
- Validar e sanitizar parâmetros de entrada;
- Interceptar falhas e emitir alertas.

O SDK expõe eventos de ciclo de vida como
PreToolUse, PostToolUse, PostToolUseFailure e UserPromptSubmit:


Se o agente tentar executar rm -rf / ou um comando destrutivo no terminal, o hook PreToolUse pode inspecionar e bloquear a operação antes que ela chegue ao sistema operacional. O modelo deixa de ser a sua única linha de defesa.

13. O Agente Não é a sua Barreira de Segurança

Este ponto merece destaque: um LLM nunca deve ser tratado como um mecanismo de segurança.

Se um agente tem permissão para deletar dados, enviar e-mails, publicar código em produção, emitir estornos financeiros ou executar scripts de console, sua aplicação necessita de autorização explícita e governança estruturada na infraestrutura:



O agente decide o que deseja fazer; a sua infraestrutura decide se ele tem permissão para executar.

14. Sistemas Multi-Agente (Multi-Agent Systems)

Quando se tem um agente funcional, é comum a tentação de criar múltiplos agentes especializados (Supervisor, Pesquisador, Programador, Revisor).

O Claude Agent SDK oferece suporte programático a subagentes e gerenciamento de sessões. Contudo, há uma lição importante: Não crie sistemas multi-agente apenas porque você pode.

Arquiteturas com múltiplos agentes introduzem mais chamadas ao modelo, janelas adicionais de contexto, maior latência, estados complexos, dificuldade de depuração e risco de decisões contraditórias.

Um único agente sólido com boas ferramentas, instruções claras e políticas seguras costuma ser muito mais eficiente que cinco agentes mal coordenados. Comece simples e introduza especializações apenas quando houver justificativa arquitetural clara.

15. Claude Agent SDK vs Anthropic SDK

Recurso Anthropic SDK (Padrão) Claude Agent SDK
Objetivo Principal Chamar diretamente a API do Claude Construir agentes autônomos
Abstração Cliente HTTP / Mensagens de baixo nível Agent Runtime completo de alto nível
Loop de Ferramentas Você implementa e gerencia o loop manualmente O Runtime gerencia a execução de ponta a ponta
Operações com Arquivos Você precisa criar as funções e handlers Ferramentas no estilo Claude Code já embutidas
Execução de Terminal Você precisa implementar o executor Suportado nativamente via ferramenta Bash
Streaming Stream direto de respostas da API Stream estruturado de eventos e ações do agente
Ferramentas Customizadas Definições JSON de ferramentas via API Integração com MCP e ferramentas locais de SDK
Permissões Controladas manualmente pela aplicação Políticas de permissão embutidas e Hooks
Sessões Interativas Gerenciamento manual no nível de API Suporte de primeira classe via ClaudeSdkClient
Melhor Indicado Para Aplicações tradicionais de LLM / Prompts simples Aplicações e assistentes agênticos autônomos

16. Exemplo Prático: Um Agente de Correção de Código em C#

Vamos juntar todos os blocos em um exemplo real:

using ClaudeAgentSdk;
using Microsoft.Extensions.Options;

Console.WriteLine("Pressione qualquer tecla para iniciar...\n");
Console.ReadKey();
var options = new ClaudeAgentOptions
{
    Cwd = @"./MeuProjetoDotNet",
    AllowedTools = new List<string>
    {
        "Read",
        "Edit",
        "Bash"
    },
    PermissionMode = PermissionMode.AcceptEdits,
    MaxTurns = 20,
    SystemPrompt = """
        Você é um Engenheiro de Software Sênior especialista em C# e .NET.
        - Investigue e compreenda o problema antes de modificar qualquer código.
        - Modifique apenas os arquivos estritamente relacionados à falha.
        - Execute 'dotnet test' após aplicar as alterações.
        - Não mascare falhas de testes.
        Ao final, forneça uma explicação clara:
          1. O que causou o erro.
          2. O que foi modificado.
          3. Quais testes foram executados.
          4. Se todos os testes passaram com sucesso.
        """
};
var prompt = """
    Investigue as falhas nos testes de autenticação
    neste repositório e corrija a causa raiz do problema.
    """;
try
{
    await foreach (var message in ClaudeAgent.QueryAsync(prompt, options))
    {
        if (message is AssistantMessage assistantMsg)
        {
            foreach (var block in assistantMsg.Content)
            {
                if (block is TextBlock textBlock)
                {
                    Console.WriteLine(textBlock.Text);
                }
            }
        }
    }
}
catch (ArgumentException ex) when (ex.Message.Contains("rate_limit_event"))
{
    Console.ForegroundColor = ConsoleColor.Yellow;
    Console.WriteLine(
        "\n[Aviso]: Limite de requisições atingido na API da Anthropic ou chave sem créditos.");
    Console.ResetColor();
}
catch (Exception ex)
{
    Console.ForegroundColor = ConsoleColor.Red;
    Console.WriteLine($"\n[Erro]: {ex.Message}");
    Console.ResetColor();
} 

Observe o que não precisamos escrever:
- Nenhum loop while (true) manual;
- Nenhuma deserialização ou invocação manual de ferramentas
(tool_call());
- Nenhuma cadeia de if (tool == ...);
- Nenhum controle de reenvio de resultados de ferramentas para a API.

O runtime do agente cuida de toda a interação iterativa de forma transparente.

18. O que Realmente Caracteriza um Agente?

É fácil rotular qualquer aplicação que consuma uma LLM como "agente", mas isso não a torna um:

- Sistema A (Aplicação Tradicional de LLM):
  Prompt → Claude → Resposta

- Sistema B (Sistema Agêntico):
  Objetivo → Claude → Inspeciona ambiente → Ferramenta → Resultado → Claude → Outra ferramenta → ... → Resultado Final

A característica definidora não é apenas "fazer várias chamadas à API", mas a capacidade de selecionar ações autonomamente com base no estado intermediário e nas observações do ambiente:



19. Onde o Claude Agent SDK se Posiciona na Arquitetura de IA



 A interface (Produto / UI) capta a solicitação e a encaminha para a Lógica da Aplicação. O Agent Runtime orquestra o fluxo, gerenciando Tools, interceptadores (Hooks) e o estado (Sessões).

O modelo Claude atua como o motor de raciocínio, processando o contexto e decidindo as ações necessárias.

Por fim, as ferramentas interagem com os Sistemas Externos (APIs, bancos de dados e arquivos) para consultar ou persistir dados.

O Claude Agent SDK ocupa prioritariamente a camada de Agent Runtime, fornecendo a ponte robusta entre o modelo fundacional e o seu ambiente de software.

Conclusão

O Claude Agent SDK representa uma mudança conceitual na forma como desenvolvemos software com inteligência artificial:

Passamos anos construindo programas onde o ser humano define todo o fluxo de trabalho detalhado e a máquina apenas o executa. Com o software agêntico, caminhamos para sistemas onde o ser humano define o objetivo, e o software determina dinamicamente as etapas necessárias para alcançá-lo.

Isso não torna a engenharia de software tradicional obsoleta; torna a boa engenharia ainda mais indispensável. Quando o software ganha autonomia para decidir ações, a pergunta mais importante deixa de ser apenas “o modelo é capaz de fazer?” e passa a ser:

“O que o agente tem permissão para fazer, como ele deve fazer e como garantimos que ele fez a coisa certa ?”

E estamos conversados..

"A minha língua falará da tua palavra, pois todos os teus mandamentos são justiça."
Salmos 119:172

Referências:


José Carlos Macoratti