Construindo sistemas de IA multiagentes com a estrutura de agentes da Microsoft
Introdução
Entramos na era dos sistemas de IA multiagentes. Em vez de uma única IA monolítica cuidar de tudo, a indústria está migrando para agentes especializados que colaboram para resolver problemas complexos – como uma equipe bem organizada de especialistas. Um agente pesquisa, outro analisa, um terceiro escreve e um coordenador mantém todos no caminho certo.
Se você trabalhou com grandes modelos de linguagem, provavelmente atingiu o limite do que um único prompt pode fazer. As janelas de contexto ficam cheias, as instruções ficam confusas e a qualidade diminui. As arquiteturas multiagentes resolvem isso decompondo tarefas complexas em responsabilidades específicas, onde cada agente é especialista em uma coisa.
O Agent Framework da Microsoft, parte do ecossistema mais amplo do Kernel Semântico, oferece aos desenvolvedores .NET um kit de ferramentas de primeira classe para construir exatamente esses tipos de sistemas. Nesta postagem, iremos do zero a um pipeline multiagente totalmente funcional, abordando os principais conceitos, padrões de orquestração e código prático de que você precisa para começar.
O que é o Agent Framework da Microsoft?
O Agent Framework é a resposta da Microsoft para construir, orquestrar e implantar agentes de IA e sistemas multiagentes em .NET. Ele acompanha – e se integra profundamente – o Kernel Semântico, que tem sido o SDK de código aberto da Microsoft para orquestração de IA desde 2023.
Pense desta forma: o Kernel Semântico fornece os primitivos (kernels, plug-ins, memória, planejadores), enquanto o Estrutura do Agente fornece abstrações de nível superior projetadas especificamente para comunicação e coordenação entre agentes.
A estrutura dá suporte a vários provedores de modelos, incluindo Azure OpenAI, OpenAI e modelos hospedados no Azure AI Foundry. Seu design é independente de modelo, mas está profundamente integrado ao ecossistema do Azure, o que o torna particularmente atraente para cenários empresariais.
Os principais recursos incluem:
- Vários tipos de agentes:
ChatCompletionAgent,OpenAIAssistantAgenteAzureAIAgentpara diferentes back-ends - Padrões de orquestração: fluxos de trabalho sequenciais, simultâneos, de transferência e de bate-papo em grupo
- Ecossistema de plug-ins: Estenda agentes com funções C# nativas, especificações OpenAPI e ferramentas Model Context Protocol (MCP)
- Gerenciamento de conversas: threading integrado, gerenciamento de histórico e estratégias de encerramento
- Observabilidade: Integração com OpenTelemetry para rastrear interações de agentes
Conceitos-chave
Antes de escrevermos qualquer código, vamos estabelecer o vocabulário. O Agent Framework gira em torno de algumas abstrações básicas.
Agentes
Um agente é uma entidade apoiada por um modelo de IA, configurado com instruções específicas (um prompt do sistema), um nome e, opcionalmente, um conjunto de plug-ins ou ferramentas. Cada agente é um especialista – você define o que ele sabe, o que pode fazer e como deve se comportar.
ChatCompletionAgenteO tipo de agente mais direto. Ele envolve um ponto final de conclusão de chat (Azure OpenAI, OpenAI, etc.) e mantém uma conversa. Não há monitoração de estado entre invocações — você fornece o histórico e ele responde. Isso o torna leve e fácil de raciocinar.
ChatCompletionAgent agent = new()
{
Name = "Reviewer",
Instructions = "You are a senior code reviewer. Analyze the provided code for bugs, security issues, and style violations. Be concise and actionable.",
Kernel = kernel
};
OpenAIAAssistantAgente
Este tipo de agente aproveita a API OpenAI Assistants, que fornece estado de conversação no lado do servidor, manipulação de arquivos e interpretação de código. É mais pesado, mas oferece threads persistentes e ferramentas integradas, como interpretador de código e pesquisa de arquivos.
OpenAIAssistantAgent agent = await OpenAIAssistantAgent.CreateAsync(
clientProvider: clientProvider,
definition: new OpenAIAssistantDefinition("gpt-4o")
{
Name = "DataAnalyst",
Instructions = "You analyze datasets and produce statistical summaries."
}
);
AgentGroupChat
Este é o orquestrador. AgentGroupChat gerencia conversas múltiplas entre vários agentes, controlando quem fala em seguida, quando a conversa termina e como o histórico é compartilhado. É onde acontece a mágica da colaboração multiagente.
Padrões de orquestração
A estrutura oferece suporte a quatro padrões principais de orquestração, cada um adequado para problemas diferentes.
Sequencial
Os agentes executam um após o outro em uma ordem definida. A saída do Agente A alimenta o Agente B, cuja saída alimenta o Agente C. Isso é ideal para pipelines: rascunho → revisão → edição → publicação.
// Conceptual flow
var draft = await writerAgent.InvokeAsync("Write a blog post about .NET 9");
var reviewed = await reviewerAgent.InvokeAsync($"Review this: {draft}");
var edited = await editorAgent.InvokeAsync($"Edit based on feedback: {reviewed}");
Simultâneo
Vários agentes trabalham na mesma entrada simultaneamente. Você distribui o trabalho e depois agrega os resultados. Ótimo para obter perspectivas diversas – como ter três revisores analisando a mesma solicitação pull.
Transferência
Um agente decide transferir o controle para outro agente com base no contexto da conversa. Isso imita o funcionamento de uma equipe de atendimento ao cliente: o agente da linha de frente lida com dúvidas básicas e encaminha para especialistas quando necessário.
Bate-papo em grupo
Vários agentes participam de uma conversa aberta, revezando-se com base em uma estratégia de seleção. A classe AgentGroupChat implementa esse padrão com lógica configurável de tomada de turno e terminação.
Construindo seu primeiro agente
Vamos ser práticos. Veja como construir seu primeiro agente passo a passo.
Pré-requisitos
Você precisará de:
- SDK do .NET 9
- Um recurso Azure OpenAI com um modelo implantado (por exemplo,
gpt-4o) - Visual Studio ou VS Code
Configurando o Projeto
Crie um novo aplicativo de console e instale os pacotes necessários:
dotnet new console -n AgentDemo
cd AgentDemo
dotnet add package Microsoft.SemanticKernel --prerelease
dotnet add package Microsoft.SemanticKernel.Agents.Core --prerelease
dotnet add package Azure.AI.OpenAI
dotnet add package Azure.Identity
Criando um Agente Simples
Primeiro, configure o kernel com a configuração do Azure OpenAI:
using Azure.Identity;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Agents;
using Microsoft.SemanticKernel.ChatCompletion;
var builder = Kernel.CreateBuilder();
builder.AddAzureOpenAIChatCompletion(
deploymentName: "gpt-4o",
endpoint: "https://your-resource.openai.azure.com/",
credentials: new DefaultAzureCredential()
);
Kernel kernel = builder.Build();
Agora crie um agente e invoque-o:
ChatCompletionAgent agent = new()
{
Name = "TechWriter",
Instructions = """
You are a technical writer specializing in software documentation.
Write clear, concise content aimed at experienced developers.
Use code examples when appropriate.
Always structure your output with headings and bullet points.
""",
Kernel = kernel
};
ChatHistory history = new();
history.AddUserMessage("Explain dependency injection in .NET in 200 words.");
await foreach (ChatMessageContent response in agent.InvokeAsync(history))
{
Console.WriteLine(response.Content);
}
É isso. Você tem um agente trabalhando. Mas o verdadeiro poder surge quando os agentes trabalham juntos.
Orquestração Multiagente com AgentGroupChat
Vamos criar algo mais interessante: um bate-papo em grupo onde vários agentes colaboram. A classe AgentGroupChat gerencia o fluxo da conversa, incluindo quem fala em seguida e quando parar.
Definindo os Agentes
Criaremos três agentes: um redator, um revisor e um editor.
ChatCompletionAgent writer = new()
{
Name = "Writer",
Instructions = """
You are a content writer. When given a topic, produce a well-structured
draft. Focus on clarity and technical accuracy.
When you receive feedback from the Reviewer, incorporate it into a
revised draft.
""",
Kernel = kernel
};
ChatCompletionAgent reviewer = new()
{
Name = "Reviewer",
Instructions = """
You are a content reviewer. Analyze drafts for technical accuracy,
clarity, and completeness. Provide specific, actionable feedback.
Do NOT rewrite the content — only provide feedback.
When the content meets your standards, respond with: APPROVED
""",
Kernel = kernel
};
ChatCompletionAgent editor = new()
{
Name = "Editor",
Instructions = """
You are an editor. Once content is approved by the Reviewer,
polish it for grammar, tone, and formatting.
Output only the final polished version.
When you have produced the final version, respond with: COMPLETE
""",
Kernel = kernel
};
Configurando o bate-papo em grupo
O AgentGroupChat precisa de duas configurações principais: uma estratégia de seleção (quem fala a seguir) e uma estratégia de rescisão (quando parar).
AgentGroupChat chat = new(writer, reviewer, editor)
{
ExecutionSettings = new()
{
SelectionStrategy = new SequentialSelectionStrategy(),
TerminationStrategy = new ApprovalTerminationStrategy()
{
Agents = [editor],
MaximumIterations = 12
}
}
};
Estratégia de rescisão personalizadaA estratégia de encerramento define quando a conversa termina. Aqui está um personalizado que procura a palavra-chave “COMPLETE”:
class ApprovalTerminationStrategy : TerminationStrategy
{
protected override Task<bool> ShouldAgentTerminateAsync(
Agent agent,
IReadOnlyList<ChatMessageContent> history,
CancellationToken cancellationToken = default)
{
bool isComplete = history
.Last()
.Content?
.Contains("COMPLETE", StringComparison.OrdinalIgnoreCase) ?? false;
return Task.FromResult(isComplete);
}
}
Conduzindo a conversa
Inicie a conversa com uma mensagem do usuário e deixe os agentes colaborarem:
chat.AddChatMessage(
new ChatMessageContent(AuthorRole.User,
"Write a 300-word technical overview of gRPC vs REST for microservices.")
);
await foreach (ChatMessageContent message in chat.InvokeAsync())
{
Console.WriteLine($"[{message.AuthorName}]: {message.Content}");
Console.WriteLine("---");
}
O fluxo será mais ou menos assim:
- Escritor produz um rascunho
- Revisor fornece feedback
- Escritor revisa com base no feedback
- Revisor diz “APROVADO”
- Editor dá um polimento e diz “COMPLETO”
- A conversa termina
Esse vaivém continua automaticamente até que a condição de encerramento seja atendida ou MaximumIterations seja alcançado.
Plug-ins e ferramentas
Os agentes tornam-se verdadeiramente poderosos quando podem interagir com sistemas externos. O Agent Framework oferece suporte a três mecanismos principais de extensão.
Funções nativas (plugins do kernel)
Você pode conceder aos agentes acesso a métodos C# como ferramentas. O agente chamará essas funções quando determinar que são necessárias:
public class ContentToolsPlugin
{
[KernelFunction("word_count")]
[Description("Counts the number of words in the provided text.")]
public int WordCount([Description("The text to count words in")] string text)
{
return text.Split(' ', StringSplitOptions.RemoveEmptyEntries).Length;
}
[KernelFunction("check_readability")]
[Description("Calculates a readability score for the given text.")]
public string CheckReadability([Description("The text to analyze")] string text)
{
var words = text.Split(' ', StringSplitOptions.RemoveEmptyEntries).Length;
var sentences = text.Split(['.', '!', '?'], StringSplitOptions.RemoveEmptyEntries).Length;
if (sentences == 0) return "Unable to calculate — no sentences found.";
double avgWordsPerSentence = (double)words / sentences;
return avgWordsPerSentence switch
{
< 15 => $"Easy to read (avg {avgWordsPerSentence:F1} words/sentence)",
< 25 => $"Moderate difficulty (avg {avgWordsPerSentence:F1} words/sentence)",
_ => $"Difficult to read (avg {avgWordsPerSentence:F1} words/sentence). Consider shorter sentences."
};
}
}
Registre o plugin no kernel antes de criar o agente:
kernel.Plugins.AddFromType<ContentToolsPlugin>();
ChatCompletionAgent analyst = new()
{
Name = "ContentAnalyst",
Instructions = "Analyze content using available tools. Report word count and readability.",
Kernel = kernel,
Arguments = new KernelArguments(
new PromptExecutionSettings
{
FunctionChoiceBehavior = FunctionChoiceBehavior.Auto()
})
};
Protocolo de Contexto do Modelo (MCP)
MCP é um padrão aberto para conectar modelos de IA a ferramentas e fontes de dados externas. O Agent Framework oferece suporte a MCP, o que significa que seus agentes podem usar ferramentas expostas por qualquer servidor compatível com MCP. Isso abre as portas para sistemas de arquivos, bancos de dados, APIs e muito mais — tudo por meio de uma interface padronizada.
// Example: Adding an MCP server for file operations
kernel.Plugins.AddFromMcpServer("filesystem",
new Uri("http://localhost:3000/mcp"));
Isso é particularmente interessante porque significa que seus agentes não estão limitados ao que você cria — eles podem aproveitar um ecossistema de ferramentas MCP que outros desenvolvem e compartilham.
Exemplo do mundo real: pipeline de revisão de conteúdo
Vamos juntar tudo com um cenário prático. Imagine que você está construindo uma ferramenta interna que automatiza a revisão de conteúdo para uma equipe de documentação. O pipeline tem quatro etapas:
- Pesquisador — Reúne informações técnicas relevantes
- Escritor — Produz um rascunho baseado em pesquisas
- Revisor — Verifica a precisão e integridade
- Editor — Formata e prepara o resultado final
Aqui está uma implementação condensada:
using Azure.Identity;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Agents;
using Microsoft.SemanticKernel.ChatCompletion;
// Build the kernel
var builder = Kernel.CreateBuilder();
builder.AddAzureOpenAIChatCompletion(
deploymentName: "gpt-4o",
endpoint: "https://your-resource.openai.azure.com/",
credentials: new DefaultAzureCredential()
);
Kernel kernel = builder.Build();
// Define specialized agents
ChatCompletionAgent researcher = new()
{
Name = "Researcher",
Instructions = """
You are a technical researcher. Given a topic, identify the key
concepts, recent developments, and important details that should
be covered. Output a structured research brief.
""",
Kernel = kernel
};
ChatCompletionAgent writer = new()
{
Name = "Writer",
Instructions = """
You are a technical writer. Using the research brief provided,
write a comprehensive, well-structured article. Include code
examples where relevant. Target audience: experienced developers.
""",
Kernel = kernel
};
ChatCompletionAgent reviewer = new()
{
Name = "Reviewer",
Instructions = """
You are a senior technical reviewer. Check the article for:
- Technical accuracy
- Completeness relative to the research brief
- Code correctness
- Clarity and structure
If everything looks good, respond with APPROVED.
Otherwise, provide specific feedback for revision.
""",
Kernel = kernel
};
ChatCompletionAgent publisher = new()
{
Name = "Publisher",
Instructions = """
You are a content publisher. Once the article is approved,
format it with proper markdown, add a summary at the top,
and ensure consistent formatting throughout.
End your response with COMPLETE.
""",
Kernel = kernel
};
// Configure the group chat
AgentGroupChat chat = new(researcher, writer, reviewer, publisher)
{
ExecutionSettings = new()
{
SelectionStrategy = new SequentialSelectionStrategy(),
TerminationStrategy = new ApprovalTerminationStrategy()
{
Agents = [publisher],
MaximumIterations = 15
}
}
};
// Start the pipeline
chat.AddChatMessage(new ChatMessageContent(
AuthorRole.User,
"Create a technical article about implementing health checks in ASP.NET Core microservices."
));
await foreach (ChatMessageContent message in chat.InvokeAsync())
{
Console.ForegroundColor = message.AuthorName switch
{
"Researcher" => ConsoleColor.Cyan,
"Writer" => ConsoleColor.Green,
"Reviewer" => ConsoleColor.Yellow,
"Publisher" => ConsoleColor.Magenta,
_ => ConsoleColor.White
};
Console.WriteLine($"\n{'='new string('=', 60)}");
Console.WriteLine($"[{message.AuthorName}]");
Console.WriteLine(new string('=', 60));
Console.WriteLine(message.Content);
}
Console.ResetColor();
Esse pipeline produz um artigo totalmente pesquisado, escrito, revisado e formatado – tudo por meio da colaboração do agente. Cada agente se concentra no que faz de melhor e o AgentGroupChat coordena o fluxo de trabalho.
Melhores práticas
Depois de construir vários sistemas multiagentes, aqui estão os padrões e práticas que considero mais valiosos.
Tratamento de erros
Sempre defina MaximumIterations em sua estratégia de rescisão. Sem ele, os agentes podem entrar em ciclos infinitos — especialmente quando um revisor continua encontrando problemas e um redator continua revisando sem melhorar.
TerminationStrategy = new ApprovalTerminationStrategy()
{
MaximumIterations = 12 // Safety net
}
Envolva as invocações do seu agente em blocos try-catch. Limites de taxa de API, problemas de rede e erros de modelo são realidades dos sistemas de produção:
try
{
await foreach (var message in chat.InvokeAsync(cancellationToken))
{
// Process messages
}
}
catch (HttpOperationException ex) when (ex.StatusCode == System.Net.HttpStatusCode.TooManyRequests)
{
// Implement retry with exponential backoff
await Task.Delay(TimeSpan.FromSeconds(30), cancellationToken);
}
ObservabilidadeO Agent Framework se integra ao OpenTelemetry, o que significa que você pode rastrear cada interação do agente, chamada de ferramenta e uso de token. Isso é essencial para depurar fluxos de trabalho multiagentes, onde nem sempre é óbvio qual agente causou o problema.
Configure a telemetria básica adicionando os pacotes de telemetria do Kernel Semântico e configurando seu exportador preferido (Application Insights, Jaeger, etc.):
builder.Services.AddOpenTelemetry()
.WithTracing(tracing =>
{
tracing.AddSource("Microsoft.SemanticKernel*");
tracing.AddOtlpExporter();
});
Gerenciamento de Custos
Os sistemas multiagentes multiplicam seus custos de API: cada turno de agente é uma chamada de API, e os bate-papos em grupo podem gerar muitos turnos. Algumas estratégias para manter os custos sob controle:
- Use modelos mais baratos para agentes mais simples: Nem todo agente precisa do GPT-4o. Um revisor pode funcionar bem com um modelo menor, enquanto apenas o redator precisa do rebatedor pesado.
- Limitar histórico: use
ReducedHistoryCountnas configurações de execução para limitar a quantidade de contexto de conversa que cada agente recebe. - Definir limites rígidos de iteração: Evite conversas descontroladas com valores
MaximumIterationsrazoáveis. - Cache quando possível: se um agente realizar a mesma pesquisa repetidamente, armazene em cache os resultados em um plugin.
Design do Agente
- Mantenha o foco nas instruções: cada agente deve ter uma responsabilidade única e clara. Instruções amplas levam a um desempenho medíocre em todas as tarefas.
- Seja explícito sobre o formato de saída: diga aos agentes exatamente como estruturar suas respostas. Isso torna a análise downstream confiável.
- Use palavras-chave de rescisão: defina sinais claros (como “APROVADO” ou “CONCLUÍDO”) que os agentes usam para indicar que terminaram. Isso torna as estratégias de rescisão simples e previsíveis.
Conclusão
Os sistemas de IA multiagentes representam uma mudança fundamental na forma como construímos aplicações inteligentes. Em vez de lutar com um único prompt para lidar com tudo, podemos decompor os problemas em funções especializadas e permitir que os agentes colaborem.
O Agent Framework da Microsoft torna isso prático para desenvolvedores .NET. As abstrações são claras – agentes, chats em grupo, estratégias de seleção e rescisão – e se compõem naturalmente. Combinado com o ecossistema de plug-ins do Kernel Semântico e a hospedagem de modelos do Azure, você tem uma pilha completa para criar sistemas multiagentes de nível de produção.
A estrutura ainda está evoluindo (muitos pacotes estão em versão prévia), mas os padrões principais são sólidos e a direção é clara. Se você estiver criando aplicativos com tecnologia de IA em .NET, agora é a hora de começar a experimentar arquiteturas multiagentes.
Comece aos poucos: crie dois agentes que colaborem em uma tarefa simples. Depois de ver a melhoria da qualidade em relação às abordagens de agente único, você desejará decompor tudo em equipes de agentes.
Boa codificação!