Creación de sistemas de IA multiagente con el marco de agentes de Microsoft
Introducción
Hemos entrado en la era de los sistemas de IA multiagente. En lugar de una única IA monolítica que se encargue de todo, la industria está avanzando hacia agentes especializados que colaboran para resolver problemas complejos, muy parecidos a un equipo de expertos bien organizado. Un agente investiga, otro analiza, un tercero escribe y un coordinador mantiene a todos al día.
Si ha trabajado con modelos de lenguaje grandes, probablemente haya llegado al límite de lo que puede hacer un solo mensaje. Las ventanas contextuales se llenan, las instrucciones se confunden y la calidad se degrada. Las arquitecturas multiagente resuelven esto descomponiendo tareas complejas en responsabilidades enfocadas, donde cada agente es un experto en una cosa.
Agent Framework de Microsoft, parte del ecosistema más amplio de Semantic Kernel, ofrece a los desarrolladores de .NET un conjunto de herramientas de primera clase para construir exactamente este tipo de sistemas. En esta publicación, pasaremos de cero a una canalización multiagente completamente funcional, cubriendo los conceptos centrales, los patrones de orquestación y el código práctico que necesita para comenzar.
¿Qué es el marco de agentes de Microsoft?
Agent Framework es la respuesta de Microsoft para crear, orquestar e implementar agentes de IA y sistemas multiagente en .NET. Se ubica junto al Semantic Kernel, que ha sido el SDK de código abierto de Microsoft para la orquestación de IA desde 2023, y se integra profundamente con él.
Piénselo de esta manera: Semantic Kernel le brinda las primitivas (kernels, complementos, memoria, planificadores), mientras que Agent Framework le brinda abstracciones de nivel superior diseñadas específicamente para la comunicación y coordinación de agente a agente.
El marco admite múltiples proveedores de modelos, incluidos Azure OpenAI, OpenAI y modelos alojados en Azure AI Foundry. Su diseño es independiente del modelo pero está profundamente integrado con el ecosistema de Azure, lo que lo hace particularmente atractivo para escenarios empresariales.
Las capacidades clave incluyen:
- Múltiples tipos de agentes:
ChatCompletionAgent,OpenAIAssistantAgentyAzureAIAgentpara diferentes backends - Patrones de orquestación: flujos de trabajo secuenciales, simultáneos, de transferencia y de chat grupal
- Ecosistema de complementos: amplíe los agentes con funciones nativas de C#, especificaciones de OpenAPI y herramientas de protocolo de contexto de modelo (MCP).
- Gestión de conversaciones: estrategias integradas de subprocesamiento, gestión de historial y terminación
- Observabilidad: integración con OpenTelemetry para rastrear interacciones de agentes
Conceptos clave
Antes de escribir cualquier código, establezcamos el vocabulario. El Agent Framework gira en torno a algunas abstracciones centrales.
Agentes
Un agente es una entidad respaldada por un modelo de IA, configurada con instrucciones específicas (un mensaje del sistema), un nombre y, opcionalmente, un conjunto de complementos o herramientas. Cada agente es un especialista: usted define lo que sabe, lo que puede hacer y cómo debe comportarse.
Agente de finalización de chatEl tipo de agente más sencillo. Incluye un punto final de finalización de chat (Azure OpenAI, OpenAI, etc.) y mantiene una conversación. No tiene estado entre invocaciones: usted proporciona el historial y responde. Esto lo hace liviano y fácil de razonar.
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
};
Agente Asistente de OpenAIA
Este tipo de agente aprovecha la API de OpenAI Assistants, que proporciona estado de conversación del lado del servidor, manejo de archivos e interpretación de código. Es más pesado pero le brinda subprocesos persistentes y herramientas integradas como intérprete de código y búsqueda de archivos.
OpenAIAssistantAgent agent = await OpenAIAssistantAgent.CreateAsync(
clientProvider: clientProvider,
definition: new OpenAIAssistantDefinition("gpt-4o")
{
Name = "DataAnalyst",
Instructions = "You analyze datasets and produce statistical summaries."
}
);
Chat en grupo de agentes
Este es el orquestador. AgentGroupChat administra conversaciones de varios turnos entre múltiples agentes, controlando quién habla a continuación, cuándo termina la conversación y cómo se comparte el historial. Aquí es donde ocurre la magia de la colaboración entre múltiples agentes.
Patrones de orquestación
El marco admite cuatro patrones de orquestación principales, cada uno de ellos adecuado para diferentes problemas.
Secuencial
Los agentes se ejecutan uno tras otro en un orden definido. La salida del Agente A alimenta al Agente B, cuya salida alimenta al Agente C. Esto es ideal para canalizaciones: borrador → revisar → editar → publicar.
// 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}");
Concurrente
Varios agentes trabajan en la misma entrada simultáneamente. Distribuyes el trabajo y luego agregas los resultados. Excelente para obtener diversas perspectivas, como que tres revisores observen la misma solicitud de extracción.
Traspaso
Un agente decide transferir el control a otro agente según el contexto de la conversación. Esto imita cómo funciona un equipo de servicio al cliente: el agente de primera línea maneja consultas básicas y las deriva a especialistas cuando es necesario.
Chat grupal
Varios agentes participan en una conversación abierta, turnándose según una estrategia de selección. La clase AgentGroupChat implementa este patrón con lógica configurable de toma de turnos y terminación.
Construyendo su primer agente
Seamos prácticos. A continuación le mostramos cómo crear su primer agente paso a paso.
Requisitos previos
Necesitarás:
- SDK .NET 9
- Un recurso de Azure OpenAI con un modelo implementado (por ejemplo,
gpt-4o) - Visual Studio o código VS
Configuración del proyecto
Cree una nueva aplicación de consola e instale los paquetes necesarios:
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
Creando un agente simple
Primero, configure el kernel con su configuración de 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();
Ahora crea un agente e invocalo:
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);
}
Eso es todo. Tienes un agente de trabajo. Pero el verdadero poder surge cuando los agentes trabajan juntos.
Orquestación multiagente con AgentGroupChat
Construyamos algo más interesante: un chat grupal donde colaboran varios agentes. La clase AgentGroupChat administra el flujo de la conversación, incluido quién habla a continuación y cuándo detenerse.
Definición de los agentes
Crearemos tres agentes: un escritor, un revisor y un 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
};
Configurar el chat grupal
El AgentGroupChat necesita dos configuraciones clave: una estrategia de selección (quién habla a continuación) y una estrategia de terminación (cuándo detenerse).
AgentGroupChat chat = new(writer, reviewer, editor)
{
ExecutionSettings = new()
{
SelectionStrategy = new SequentialSelectionStrategy(),
TerminationStrategy = new ApprovalTerminationStrategy()
{
Agents = [editor],
MaximumIterations = 12
}
}
};
Estrategia de terminación personalizadaLa estrategia de terminación define cuándo termina la conversación. Aquí hay uno personalizado que busca la palabra clave “COMPLETO”:
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);
}
}
Ejecutar la conversación
Inicie la conversación con un mensaje de usuario y deje que los agentes colaboren:
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("---");
}
El flujo se verá así:
- El escritor produce un borrador
- El revisor proporciona comentarios
- El escritor revisa según los comentarios
- El revisor dice “APROBADO”
- Editor pule y dice “COMPLETO”
- La conversación termina
Este ida y vuelta continúa automáticamente hasta que se cumple la condición de terminación o se alcanza MaximumIterations.
Complementos y herramientas
Los agentes se vuelven verdaderamente poderosos cuando pueden interactuar con sistemas externos. Agent Framework admite tres mecanismos de extensión principales.
Funciones nativas (complementos del kernel)
Puede dar a los agentes acceso a métodos de C# como herramientas. El agente llamará a estas funciones cuando determine que son necesarias:
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 el complemento en el kernel antes de crear el 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 modelo (MCP)
MCP es un estándar abierto para conectar modelos de IA a herramientas y fuentes de datos externas. Agent Framework es compatible con MCP, lo que significa que sus agentes pueden usar herramientas expuestas por cualquier servidor compatible con MCP. Esto abre la puerta a sistemas de archivos, bases de datos, API y más, todo a través de una interfaz estandarizada.
// Example: Adding an MCP server for file operations
kernel.Plugins.AddFromMcpServer("filesystem",
new Uri("http://localhost:3000/mcp"));
Esto es particularmente interesante porque significa que sus agentes no están limitados a lo que usted crea: pueden aprovechar un ecosistema de herramientas MCP que otros desarrollan y comparten.
Ejemplo del mundo real: canal de revisión de contenido
Juntemos todo con un escenario práctico. Imagine que está creando una herramienta interna que automatiza la revisión de contenido para un equipo de documentación. El oleoducto tiene cuatro etapas:
- Investigador: recopila información técnica relevante
- Escritor: produce un borrador basado en una investigación.
- Revisor: verifica la precisión y la integridad
- Editor: formatea y prepara el resultado final.
Aquí hay una implementación 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();
Este canal produce un artículo completamente investigado, escrito, revisado y formateado, todo ello a través de la colaboración de los agentes. Cada agente se centra en lo que mejor sabe hacer y el AgentGroupChat coordina el flujo de trabajo.
Mejores prácticas
Después de construir varios sistemas multiagente, estos son los patrones y prácticas que he encontrado más valiosos.
Manejo de errores
Configure siempre MaximumIterations en su estrategia de terminación. Sin él, los agentes pueden entrar en bucles infinitos, especialmente cuando un revisor sigue encontrando problemas y un escritor sigue revisando sin mejorar.
TerminationStrategy = new ApprovalTerminationStrategy()
{
MaximumIterations = 12 // Safety net
}
Envuelva las invocaciones de su agente en bloques try-catch. Los límites de velocidad de API, los problemas de red y los errores de modelo son realidades de los sistemas de producción:
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);
}
ObservabilidadAgent Framework se integra con OpenTelemetry, lo que significa que puede rastrear cada interacción del agente, llamada de herramienta y uso de token. Esto es esencial para depurar flujos de trabajo de múltiples agentes donde no siempre es obvio qué agente causó un problema.
Configure la telemetría básica agregando los paquetes de telemetría del Kernel Semántico y configurando su exportador preferido (Application Insights, Jaeger, etc.):
builder.Services.AddOpenTelemetry()
.WithTracing(tracing =>
{
tracing.AddSource("Microsoft.SemanticKernel*");
tracing.AddOtlpExporter();
});
Gestión de costes
Los sistemas multiagente multiplican los costos de API: cada turno de agente es una llamada de API y los chats grupales pueden generar muchos turnos. Algunas estrategias para mantener los costos bajo control:
- Utilice modelos más económicos para agentes más simples: No todos los agentes necesitan GPT-4o. Un revisor podría funcionar bien con un modelo más pequeño, mientras que sólo el escritor necesita el peso pesado.
- Limitar historial: use
ReducedHistoryCounten su configuración de ejecución para limitar la cantidad de contexto de conversación que recibe cada agente. - Establezca límites estrictos de iteración: evite conversaciones descontroladas con valores
MaximumIterationsrazonables. - Almacenar en caché cuando sea posible: si un agente realiza la misma búsqueda repetidamente, almacene en caché los resultados en un complemento.
Diseño de agente
- Mantenga las instrucciones enfocadas: Cada agente debe tener una responsabilidad única y clara. Las instrucciones amplias conducen a un rendimiento mediocre en todas las tareas.
- Sea explícito sobre el formato de salida: dígales a los agentes exactamente cómo estructurar sus respuestas. Esto hace que el análisis posterior sea confiable.
- Utilice palabras clave de terminación: defina señales claras (como “APROBADO” o “COMPLETO”) que los agentes utilizan para indicar que han terminado. Esto hace que las estrategias de terminación sean simples y predecibles.
Conclusión
Los sistemas de IA multiagente representan un cambio fundamental en la forma en que creamos aplicaciones inteligentes. En lugar de luchar con un único mensaje para manejar todo, podemos descomponer los problemas en roles especializados y dejar que los agentes colaboren.
Agent Framework de Microsoft hace que esto sea práctico para los desarrolladores de .NET. Las abstracciones son claras (agentes, chats grupales, estrategias de selección y terminación) y se componen de forma natural. Combinado con el ecosistema de complementos de Semantic Kernel y el alojamiento de modelos de Azure, tiene una pila completa para crear sistemas multiagente de nivel de producción.
El marco aún está evolucionando (muchos paquetes están en versión preliminar), pero los patrones centrales son sólidos y la dirección es clara. Si está creando aplicaciones basadas en IA en .NET, ahora es el momento de comenzar a experimentar con arquitecturas multiagente.
Empiece poco a poco: cree dos agentes que colaboren en una tarea sencilla. Una vez que vea la mejora de la calidad con respecto a los enfoques de un solo agente, querrá descomponer todo en equipos de agentes.
¡Feliz codificación!