Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
La orquestación de chat grupal modela una conversación colaborativa entre varios agentes, coordinada por un administrador que determina la selección del hablante y el flujo de conversación. Este patrón es ideal para escenarios que requieren refinamiento iterativo, resolución de problemas de colaboración o análisis de varias perspectivas.
Diferencias entre el chat en grupo y otros patrones
La orquestación de chat en grupo tiene características distintas en comparación con otros patrones de varios agentes:
- Coordinación centralizada: a diferencia de los patrones de entrega en los que los agentes transfieren directamente el control, el chat de grupo usa un administrador para coordinar quién habla a continuación
- Refinamiento iterativo: los agentes pueden revisar y mejorar las respuestas de los demás en varias rondas
- Selección flexible del hablante: el administrador puede usar varias estrategias (round robin, basada en mensajes, lógica personalizada) para seleccionar altavoces.
- Contexto compartido: todos los agentes ven el historial de conversaciones completo, lo que permite el refinamiento colaborativo.
Temas que se abordarán
- Creación de agentes especializados para la colaboración de grupos
- Configuración de estrategias de selección de hablantes
- Creación de flujos de trabajo con refinamiento de agentes iterativos
- Personalización del flujo de conversación con administradores personalizados
Configuración del cliente de Azure OpenAI
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI.Workflows;
using Microsoft.Extensions.AI;
using Microsoft.Agents.AI;
// Set up the Azure OpenAI client
var endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT") ??
throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT is not set.");
var deploymentName = Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT_NAME") ?? "gpt-4o-mini";
var client = new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential())
.GetChatClient(deploymentName)
.AsIChatClient();
Definir los agentes
Cree agentes especializados para distintos roles en la conversación de grupo:
// Create a copywriter agent
ChatClientAgent writer = new(client,
"You are a creative copywriter. Generate catchy slogans and marketing copy. Be concise and impactful.",
"CopyWriter",
"A creative copywriter agent");
// Create a reviewer agent
ChatClientAgent reviewer = new(client,
"You are a marketing reviewer. Evaluate slogans for clarity, impact, and brand alignment. " +
"Provide constructive feedback or approval.",
"Reviewer",
"A marketing review agent");
Configuración del chat de grupo con Round-Robin Manager
Compile el flujo de trabajo de chat de grupo mediante AgentWorkflowBuilder:
// Build group chat with round-robin speaker selection
// The manager factory receives the list of agents and returns a configured manager
var workflow = AgentWorkflowBuilder
.CreateGroupChatBuilderWith(agents =>
new RoundRobinGroupChatManager(agents)
{
MaximumIterationCount = 5 // Maximum number of turns
})
.AddParticipants(writer, reviewer)
.Build();
Ejecución del flujo de trabajo de chat en grupo
Ejecute el flujo de trabajo y observe la conversación iterativa:
// Start the group chat
var messages = new List<ChatMessage> {
new(ChatRole.User, "Create a slogan for an eco-friendly electric vehicle.")
};
StreamingRun run = await InProcessExecution.StreamAsync(workflow, messages);
await run.TrySendMessageAsync(new TurnToken(emitEvents: true));
await foreach (WorkflowEvent evt in run.WatchStreamAsync().ConfigureAwait(false))
{
if (evt is AgentRunUpdateEvent update)
{
// Process streaming agent responses
AgentRunResponse response = update.AsResponse();
foreach (ChatMessage message in response.Messages)
{
Console.WriteLine($"[{update.ExecutorId}]: {message.Text}");
}
}
else if (evt is WorkflowOutputEvent output)
{
// Workflow completed
var conversationHistory = output.As<List<ChatMessage>>();
Console.WriteLine("\n=== Final Conversation ===");
foreach (var message in conversationHistory)
{
Console.WriteLine($"{message.AuthorName}: {message.Text}");
}
break;
}
}
Interacción de ejemplo
[CopyWriter]: "Green Dreams, Zero Emissions" - Drive the future with style and sustainability.
[Reviewer]: The slogan is good, but "Green Dreams" might be a bit abstract. Consider something
more direct like "Pure Power, Zero Impact" to emphasize both performance and environmental benefit.
[CopyWriter]: "Pure Power, Zero Impact" - Experience electric excellence without compromise.
[Reviewer]: Excellent! This slogan is clear, impactful, and directly communicates the key benefits.
The tagline reinforces the message perfectly. Approved for use.
[CopyWriter]: Thank you! The final slogan is: "Pure Power, Zero Impact" - Experience electric
excellence without compromise.
Configurar el cliente de chat
from agent_framework.azure import AzureOpenAIChatClient
from azure.identity import AzureCliCredential
# Initialize the Azure OpenAI chat client
chat_client = AzureOpenAIChatClient(credential=AzureCliCredential())
Definir los agentes
Cree agentes especializados con roles distintos:
from agent_framework import ChatAgent
# Create a researcher agent
researcher = ChatAgent(
name="Researcher",
description="Collects relevant background information.",
instructions="Gather concise facts that help answer the question. Be brief and factual.",
chat_client=chat_client,
)
# Create a writer agent
writer = ChatAgent(
name="Writer",
description="Synthesizes polished answers using gathered information.",
instructions="Compose clear, structured answers using any notes provided. Be comprehensive.",
chat_client=chat_client,
)
Configurar chat de grupo con selector simple
Cree un chat de grupo con lógica de selección de hablantes personalizada:
from agent_framework import GroupChatBuilder, GroupChatStateSnapshot
def select_next_speaker(state: GroupChatStateSnapshot) -> str | None:
"""Alternate between researcher and writer for collaborative refinement.
Args:
state: Contains task, participants, conversation, history, and round_index
Returns:
Name of next speaker, or None to finish
"""
round_idx = state["round_index"]
history = state["history"]
# Finish after 4 turns (researcher → writer → researcher → writer)
if round_idx >= 4:
return None
# Alternate speakers
last_speaker = history[-1].speaker if history else None
if last_speaker == "Researcher":
return "Writer"
return "Researcher"
# Build the group chat workflow
workflow = (
GroupChatBuilder()
.set_select_speakers_func(select_next_speaker, display_name="Orchestrator")
.participants([researcher, writer])
.build()
)
Configuración del chat de grupo con Agent-Based Manager
Como alternativa, use un administrador basado en agente para la selección inteligente del hablante. El administrador tiene un perfil completo ChatAgent con acceso a herramientas, contexto y capacidad de observación:
# Create coordinator agent for speaker selection
coordinator = ChatAgent(
name="Coordinator",
description="Coordinates multi-agent collaboration by selecting speakers",
instructions="""
You coordinate a team conversation to solve the user's task.
Review the conversation history and select the next participant to speak.
Guidelines:
- Start with Researcher to gather information
- Then have Writer synthesize the final answer
- Only finish after both have contributed meaningfully
- Allow for multiple rounds of information gathering if needed
""",
chat_client=chat_client,
)
# Build group chat with agent-based manager
workflow = (
GroupChatBuilder()
.set_manager(coordinator, display_name="Orchestrator")
.with_termination_condition(lambda messages: sum(1 for msg in messages if msg.role == Role.ASSISTANT) >= 4)
.participants([researcher, writer])
.build()
)
Ejecución del flujo de trabajo de chat en grupo
Ejecute los eventos de flujo de trabajo y proceso:
from typing import cast
from agent_framework import AgentRunUpdateEvent, Role, WorkflowOutputEvent
task = "What are the key benefits of async/await in Python?"
print(f"Task: {task}\n")
print("=" * 80)
final_conversation: list[ChatMessage] = []
last_executor_id: str | None = None
# Run the workflow
async for event in workflow.run_stream(task):
if isinstance(event, AgentRunUpdateEvent):
# Print streaming agent updates
eid = event.executor_id
if eid != last_executor_id:
if last_executor_id is not None:
print()
print(f"[{eid}]:", end=" ", flush=True)
last_executor_id = eid
print(event.data, end="", flush=True)
elif isinstance(event, WorkflowOutputEvent):
# Workflow completed - data is a list of ChatMessage
final_conversation = cast(list[ChatMessage], event.data)
if final_conversation:
print("\n\n" + "=" * 80)
print("Final Conversation:")
for msg in final_conversation:
author = getattr(msg, "author_name", "Unknown")
text = getattr(msg, "text", str(msg))
print(f"\n[{author}]\n{text}")
print("-" * 80)
print("\nWorkflow completed.")
Interacción de ejemplo
Task: What are the key benefits of async/await in Python?
================================================================================
[Researcher]: Async/await in Python provides non-blocking I/O operations, enabling
concurrent execution without threading overhead. Key benefits include improved
performance for I/O-bound tasks, better resource utilization, and simplified
concurrent code structure using native coroutines.
[Writer]: The key benefits of async/await in Python are:
1. **Non-blocking Operations**: Allows I/O operations to run concurrently without
blocking the main thread, significantly improving performance for network
requests, file I/O, and database queries.
2. **Resource Efficiency**: Avoids the overhead of thread creation and context
switching, making it more memory-efficient than traditional threading.
3. **Simplified Concurrency**: Provides a clean, synchronous-looking syntax for
asynchronous code, making concurrent programs easier to write and maintain.
4. **Scalability**: Enables handling thousands of concurrent connections with
minimal resource consumption, ideal for high-performance web servers and APIs.
--------------------------------------------------------------------------------
Workflow completed.
Conceptos clave
- Administrador centralizado: el chat de grupo usa un administrador para coordinar la selección y el flujo del hablante.
- AgentWorkflowBuilder.CreateGroupChatBuilderWith(): crea flujos de trabajo con una función de fábrica de administrador.
- RoundRobinGroupChatManager: administrador integrado que alterna oradores de forma rotativa
- MaximumIterationCount: controla el número máximo de turnos de agente antes de la finalización
-
Administradores personalizados: extensión
RoundRobinGroupChatManagero implementación de lógica personalizada - Refinamiento iterativo: los agentes revisan y mejoran las contribuciones entre sí
- Contexto compartido: todos los participantes ven el historial de conversaciones completo
- Estrategias de administrador flexible: elegir entre selectores simples, administradores basados en agentes o lógica personalizada
- GroupChatBuilder: crea flujos de trabajo con selección configurable del hablante
- set_select_speakers_func(): definición de funciones personalizadas de Python para la selección del hablante
- set_manager(): uso de un administrador basado en agente para la coordinación inteligente del hablante
- GroupChatStateSnapshot: proporciona el estado de conversación para las decisiones de selección.
- Colaboración iterativa: los agentes se basan en las contribuciones de los demás
-
Streaming de eventos: procesar
AgentRunUpdateEventyWorkflowOutputEventen tiempo real - list[ChatMessage] Output: Todas las orquestaciones devuelven una lista de mensajes de chat
Avanzado: Selección de altavoz personalizada
Puede implementar la lógica del administrador personalizado mediante la creación de un administrador de chat de grupo personalizado:
public class ApprovalBasedManager : RoundRobinGroupChatManager
{
private readonly string _approverName;
public ApprovalBasedManager(IReadOnlyList<AIAgent> agents, string approverName)
: base(agents)
{
_approverName = approverName;
}
// Override to add custom termination logic
protected override ValueTask<bool> ShouldTerminateAsync(
IReadOnlyList<ChatMessage> history,
CancellationToken cancellationToken = default)
{
var last = history.LastOrDefault();
bool shouldTerminate = last?.AuthorName == _approverName &&
last.Text?.Contains("approve", StringComparison.OrdinalIgnoreCase) == true;
return ValueTask.FromResult(shouldTerminate);
}
}
// Use custom manager in workflow
var workflow = AgentWorkflowBuilder
.CreateGroupChatBuilderWith(agents =>
new ApprovalBasedManager(agents, "Reviewer")
{
MaximumIterationCount = 10
})
.AddParticipants(writer, reviewer)
.Build();
Puede implementar una lógica de selección sofisticada basada en el estado de conversación:
def smart_selector(state: GroupChatStateSnapshot) -> str | None:
"""Select speakers based on conversation content and context."""
round_idx = state["round_index"]
conversation = state["conversation"]
history = state["history"]
# Maximum 10 rounds
if round_idx >= 10:
return None
# First round: always start with researcher
if round_idx == 0:
return "Researcher"
# Check last message content
last_message = conversation[-1] if conversation else None
last_text = getattr(last_message, "text", "").lower()
# If researcher asked a question, let writer respond
if "?" in last_text and history[-1].speaker == "Researcher":
return "Writer"
# If writer provided info, let researcher validate or extend
if history[-1].speaker == "Writer":
return "Researcher"
# Default alternation
return "Writer" if history[-1].speaker == "Researcher" else "Researcher"
workflow = (
GroupChatBuilder()
.set_select_speakers_func(smart_selector, display_name="SmartOrchestrator")
.participants([researcher, writer])
.build()
)
Cuándo usar chat de grupo
La orquestación de chat en grupo es ideal para:
- Refinamiento iterativo: varias rondas de revisión y mejora
- Solución de problemas de colaboración: agentes con conocimientos complementarios que trabajan juntos
- Creación de contenido: flujos de trabajo escritor-revisor para la creación de documentos
- Análisis de varias perspectivas: obtención de diversos puntos de vista en la misma entrada
- Control de calidad: procesos automatizados de revisión y aprobación
Tenga en cuenta alternativas cuando:
- Necesita un procesamiento secuencial estricto (use Orquestación secuencial)
- Los agentes deben funcionar completamente de forma independiente (usar orquestación simultánea)
- Se necesitan transferencias directas de agente a agente (utilice la orquestación de traspaso)
- Se requiere una planificación dinámica compleja (utilice orquestación Magentic)