Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Оркестрация группового чата моделирует совместную беседу между несколькими агентами, координируемую менеджером, который определяет выбор говорящего и поток беседы. Этот шаблон идеально подходит для сценариев, требующих итеративного уточнения, совместного решения проблем или анализа с несколькими перспективами.
Различия между групповым чатом и другими шаблонами
Оркестрация группового чата имеет уникальные характеристики по сравнению с другими шаблонами с несколькими агентами:
- Централизованная координация: в отличие от шаблонов выдачи, в которых агенты напрямую передают управление, групповый чат использует диспетчера для координации того, кто говорит дальше
- Итеративное уточнение: агенты могут просматривать и развивать ответы друг друга в нескольких раундах
- Гибкий выбор докладчика: менеджер может использовать различные стратегии (циклический перебор, основанный на запросах, пользовательская логика) для выбора докладчиков.
- Общий контекст: все агенты видят полную историю бесед, что позволяет улучшить совместную работу.
Цели обучения
- Создание специализированных агентов для групповой совместной работы
- Настройка стратегий выбора говорящего
- Создание рабочих процессов с помощью пошаговой оптимизации агентов
- Настройка потока беседы с помощью пользовательских управляющих
Настройка клиента Azure OpenAI
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.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();
Определение агентов
Создайте специализированные агенты для разных ролей в беседе группы:
// 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");
Настройка группового чата с помощью диспетчера Round-Robin
Создание рабочего процесса группового чата с помощью 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();
Запуск рабочего процесса группового чата
Выполните рабочий процесс и просмотрите итеративную беседу:
// 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;
}
}
Пример взаимодействия
[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.
Настройка клиента чата
from agent_framework.azure import AzureOpenAIChatClient
from azure.identity import AzureCliCredential
# Initialize the Azure OpenAI chat client
chat_client = AzureOpenAIChatClient(credential=AzureCliCredential())
Определение агентов
Создайте специализированные агенты с различными ролями:
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,
)
Настройка группового чата с помощью простого селектора
Создание группового чата с логикой выбора настраиваемого докладчика:
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()
.select_speakers(select_next_speaker, display_name="Orchestrator")
.participants([researcher, writer])
.build()
)
Настройка группового чата с помощью менеджера Prompt-Based
В качестве альтернативы используйте диспетчер на базе ИИ для динамического выбора динамиков.
# Build group chat with prompt-based manager
workflow = (
GroupChatBuilder()
.set_prompt_based_manager(
chat_client=chat_client,
display_name="Coordinator"
)
.participants(researcher=researcher, writer=writer)
.build()
)
Запуск рабочего процесса группового чата
Выполните рабочий процесс и обработайте события.
from agent_framework import AgentRunUpdateEvent, WorkflowOutputEvent
task = "What are the key benefits of async/await in Python?"
print(f"Task: {task}\n")
print("=" * 80)
# Run the workflow
async for event in workflow.run_stream(task):
if isinstance(event, AgentRunUpdateEvent):
# Print streaming agent updates
print(f"[{event.executor_id}]: {event.data}", end="", flush=True)
elif isinstance(event, WorkflowOutputEvent):
# Workflow completed
final_message = event.data
author = getattr(final_message, "author_name", "System")
text = getattr(final_message, "text", str(final_message))
print(f"\n\n[{author}]\n{text}")
print("-" * 80)
print("\nWorkflow completed.")
Пример взаимодействия
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.
Основные понятия
- Централизованный менеджер: групповый чат использует диспетчер для координации выбора и потока говорящего
- AgentWorkflowBuilder.CreateGroupChatBuilderWith(): создает рабочие процессы с помощью фабричной функции менеджера
- RoundRobinGroupChatManager: встроенный менеджер, который чередует участников по кругу
- MaximumIterationCount: управляет максимальным числом итераций агента перед завершением.
-
Настраиваемые диспетчеры: расширение
RoundRobinGroupChatManagerили реализация пользовательской логики - Итеративное уточнение: агенты просматривают и улучшают вклад друг друга
- Общий контекст: все участники видят полную историю бесед
- Гибкие стратегии диспетчера: выбор между простыми селекторами, диспетчерами на основе запросов или пользовательской логикой
- GroupChatBuilder: создает рабочие процессы с настраиваемым выбором говорящего
- select_speakers(): определение пользовательских функций Python для выбора говорящего
- set_prompt_based_manager(): использование управляемой ИИ координации для динамического выбора выступающих
- GroupChatStateSnapshot: предоставляет состояние беседы для выбора решений
- Итеративная совместная работа: агенты опираются на вклад друг друга
- Потоковая передача событий: обновления и выходные данные агента обработки в режиме реального времени
Дополнительно: выбор настраиваемого говорящего
Вы можете реализовать логику пользовательского диспетчера, создав пользовательский диспетчер групповых чатов:
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();
Вы можете реализовать сложную логику выбора на основе состояния беседы:
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()
.select_speakers(smart_selector, display_name="SmartOrchestrator")
.participants([researcher, writer])
.build()
)
Когда следует использовать групповой чат
Оркестрация группового чата идеально подходит для:
- Итеративное уточнение: несколько раундов обзора и улучшения
- Совместное решение проблем: агенты с дополняющими знаниями, работающие вместе
- Создание содержимого: рабочие процессы авторов и рецензентов для создания документа
- Анализ с несколькими перспективами: получение различных точек зрения для одних и того же входных данных
- Quality Assurance: автоматизированные процессы проверки и утверждения
Рассмотрите варианты, когда:
- Требуется строгая последовательная обработка (используйте последовательную оркестрацию)
- Агенты должны работать полностью независимо (использовать параллельную оркестрацию)
- Необходимы прямые передачи между агентами (используйте оркестрацию Handoff)
- Требуется сложное динамическое планирование (использование магентической оркестрации)