|
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. |


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" }
]
});
|

from
anthropic import Anthropic
(via pip install anthropic)dotnet
add package Anthropic)
dotnet add package ClaudeAgentSdk ou
dotnet add package ClaudeAgentSdk --prerelease
|
Install-Package
ClaudeAgentSdk)
npm install -g @anthropic-ai/claude-code
|
# Windows (PowerShell) $env:ANTHROPIC_API_KEY = "sua-chave-api-aqui" # Linux / macOS export ANTHROPIC_API_KEY="sua-chave-api-aqui" |

prompt → resposta.
Ele funciona segundo o fluxo iterativo:
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();
}
|
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.
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(); } |
AssistantMessage, ResultMessage, TextBlock e
ToolUseBlock.
AssistantMessage │ ├── TextBlock ├── ToolUseBlock └── ToolResultBlock |
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);
}
|
AllowedTools = ["Read", "Write",
"Bash"]
var options = new ClaudeAgentOptions
{
AllowedTools = new List<string> { "Read", "Write", "Bash" },
PermissionMode = PermissionMode.AcceptEdits
};
|
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.
var options = new ClaudeAgentOptions
{
Cwd = @"C:\Projetos\MeuProjetoDotNet" // ou "/path/to/project"
};
|
Repositório
→ Ler tudo → Colocar tudo no prompt → LLM
Repositório → Agente
decide o que precisa → (Ler arquivo A / Buscar símbolos / Ler arquivo B / Rodar
teste)
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
};
|
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.
ClaudeAgent.QueryAsync() e o cliente interativo
ClaudeSdkClient.await foreach (var message in
ClaudeAgent.QueryAsync(...)) { ... } geralmente é o suficiente.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...
}
|
ClaudeSdkClient oferece suporte a conversas bidirecionais,
streaming, interrupções em tempo de execução, envio dinâmico de mensagens,
ferramentas customizadas e interceptadores (hooks).
ConsultarCliente,
BuscarPedidos,
ConsultarBaseConhecimento,
AbrirChamado
e EmitirReembolso.
// Abordagem antiga e rígida
if (intencao == "cliente") ConsultarCliente();
else if (intencao == "pedido") BuscarPedidos();
else if (intencao == "reembolso") EmitirReembolso();
|
Usuário: "Meu pedido veio danificado. Posso solicitar o reembolso?" │ ▼ Agente ├──► ConsultarCliente() ├──► BuscarPedidos() ├──► Inspecionar dados da entrega ├──► EmitirReembolso() └──► Responder detalhadamente ao usuário |
PreToolUse,
PostToolUse,
PostToolUseFailure
e UserPromptSubmit:
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.
| 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 |
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(); } |
while
(true) manual;tool_call());
if (tool == ...);Prompt → Claude → RespostaObjetivo → Claude → Inspeciona ambiente →
Ferramenta → Resultado → Claude → Outra ferramenta → ... → Resultado Final

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: