Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Importante
Le funzionalità di orchestrazione dell'agente in Agent Framework si trovano nella fase sperimentale. Sono in fase di sviluppo attivo e possono cambiare significativamente prima di passare alla fase di anteprima o candidato al rilascio.
L'orchestrazione di chat di gruppo modella una conversazione collaborativa tra gli agenti, includendo facoltativamente un partecipante umano. Un gestore di chat di gruppo coordina il flusso, determinando quale agente deve rispondere successivamente e quando richiedere l'input umano. Questo modello è efficace per simulare riunioni, dibattiti o sessioni di risoluzione dei problemi collaborativi.
Per ulteriori informazioni sul modello, ad esempio su quando utilizzarlo o evitarlo nel proprio carico di lavoro, consultare Orchestrazione di chat di gruppo.
Casi d'uso comuni
Gli agenti che rappresentano diversi reparti discutono di una proposta di business, con un agente manager che modera la conversazione e coinvolge un essere umano quando necessario:
Contenuto dell'esercitazione
- Come definire gli agenti con ruoli diversi per una chat di gruppo
- Come usare un gestore di chat di gruppo per controllare il flusso della conversazione
- Come coinvolgere un partecipante umano nella conversazione
- Come osservare la conversazione e raccogliere il risultato finale
Definire gli agenti
Ogni agente nella chat di gruppo ha un ruolo specifico. In questo esempio viene definito un copywriter e un revisore.
Suggerimento
Viene ChatCompletionAgent usato qui, ma è possibile usare qualsiasi tipo di agente.
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Agents;
using Microsoft.SemanticKernel.Agents.Orchestration;
using Microsoft.SemanticKernel.Agents.Orchestration.GroupChat;
using Microsoft.SemanticKernel.Agents.Runtime.InProcess;
// Create a kernel with an AI service
Kernel kernel = ...;
ChatCompletionAgent writer = new ChatCompletionAgent {
Name = "CopyWriter",
Description = "A copy writer",
Instructions = "You are a copywriter with ten years of experience and are known for brevity and a dry humor. The goal is to refine and decide on the single best copy as an expert in the field. Only provide a single proposal per response. You're laser focused on the goal at hand. Don't waste time with chit chat. Consider suggestions when refining an idea.",
Kernel = kernel,
};
ChatCompletionAgent editor = new ChatCompletionAgent {
Name = "Reviewer",
Description = "An editor.",
Instructions = "You are an art director who has opinions about copywriting born of a love for David Ogilvy. The goal is to determine if the given copy is acceptable to print. If so, state that it is approved. If not, provide insight on how to refine suggested copy without example.",
Kernel = kernel,
};
Facoltativo: osservare le risposte dell'agente
È possibile creare un callback per acquisire le risposte dell'agente durante l'avanzamento della sequenza tramite la ResponseCallback proprietà .
ChatHistory history = [];
ValueTask responseCallback(ChatMessageContent response)
{
history.Add(response);
return ValueTask.CompletedTask;
}
Configurare l'orchestrazione di Chat di gruppo
Creare un GroupChatOrchestration oggetto, passando gli agenti, un gestore di chat di gruppo (qui, un RoundRobinGroupChatManager) e il callback della risposta. Il manager controlla il flusso: qui, alterna i turni in una modalità round-robin per un numero prestabilito di round.
GroupChatOrchestration orchestration = new GroupChatOrchestration(
new RoundRobinGroupChatManager { MaximumInvocationCount = 5 },
writer,
editor)
{
ResponseCallback = responseCallback,
};
Avviare il runtime
È necessario un runtime per gestire l'esecuzione degli agenti. In questo caso, usiamo InProcessRuntime e lo iniziamo prima di richiamare l'orchestrazione.
InProcessRuntime runtime = new InProcessRuntime();
await runtime.StartAsync();
Attivare l'orchestrazione
Richiama l'orchestrazione con il tuo compito iniziale (ad esempio, "Crea uno slogan per un nuovo SUV elettrico..."). Gli agenti risponderanno a turno, affinando il risultato.
var result = await orchestration.InvokeAsync(
"Create a slogan for a new electric SUV that is affordable and fun to drive.",
runtime);
Raccogliere i risultati
Attendere il completamento dell'orchestrazione e recuperare l'output finale.
string output = await result.GetValueAsync(TimeSpan.FromSeconds(60));
Console.WriteLine($"\n# RESULT: {text}");
Console.WriteLine("\n\nORCHESTRATION HISTORY");
foreach (ChatMessageContent message in history)
{
this.WriteAgentChatMessage(message);
}
Facoltativo: arrestare il runtime
Al termine dell'elaborazione, arrestare il runtime per pulire le risorse.
await runtime.RunUntilIdleAsync();
Output di esempio
# RESULT: “Affordable Adventure: Drive Electric, Drive Fun.”
ORCHESTRATION HISTORY
# Assistant - CopyWriter: “Charge Ahead: Affordable Thrills, Zero Emissions.”
# Assistant - Reviewer: The slogan is catchy but it could be refined to better ...
# Assistant - CopyWriter: “Electrify Your Drive: Fun Meets Affordability.”
# Assistant - Reviewer: The slogan captures the essence of electric driving and ...
# Assistant - CopyWriter: “Affordable Adventure: Drive Electric, Drive Fun.”
Suggerimento
Il codice di esempio completo è disponibile qui
Definire gli agenti
Ogni agente nella chat di gruppo ha un ruolo specifico. In questo esempio:
- Writer: crea e modifica il contenuto in base al feedback.
- Revisore: rivede il contenuto e fornisce commenti e suggerimenti per migliorare.
Suggerimento
Viene ChatCompletionAgent usato qui con Azure OpenAI, tuttavia, è possibile usare qualsiasi tipo di agente o servizio modello.
from semantic_kernel.agents import Agent, ChatCompletionAgent
from semantic_kernel.connectors.ai.open_ai import AzureChatCompletion
def get_agents() -> list[Agent]:
writer = ChatCompletionAgent(
name="Writer",
description="A content writer.",
instructions=(
"You are an excellent content writer. You create new content and edit contents based on the feedback."
),
service=AzureChatCompletion(),
)
reviewer = ChatCompletionAgent(
name="Reviewer",
description="A content reviewer.",
instructions=(
"You are an excellent content reviewer. You review the content and provide feedback to the writer."
),
service=AzureChatCompletion(),
)
return [writer, reviewer]
Osservare le risposte dell'agente
È possibile definire un callback per stampare il messaggio di ogni agente durante l'avanzamento della conversazione.
from semantic_kernel.contents import ChatMessageContent
def agent_response_callback(message: ChatMessageContent) -> None:
print(f"**{message.name}**\n{message.content}")
Configurare l'orchestrazione di Chat di gruppo
Creare un oggetto GroupChatOrchestration introducendo gli agenti, un gestore della chat di gruppo (in questo caso RoundRobinGroupChatManager) e il callback di risposta. Il manager controlla il flusso: qui, alterna i turni in una modalità round-robin per un numero prestabilito di round.
from semantic_kernel.agents import GroupChatOrchestration, RoundRobinGroupChatManager
agents = get_agents()
group_chat_orchestration = GroupChatOrchestration(
members=agents,
manager=RoundRobinGroupChatManager(max_rounds=5), # Odd number so writer gets the last word
agent_response_callback=agent_response_callback,
)
Avviare il runtime
Avviare il runtime per gestire l'esecuzione dell'agente.
from semantic_kernel.agents.runtime import InProcessRuntime
runtime = InProcessRuntime()
runtime.start()
Attivare l'orchestrazione
Richiama l'orchestrazione con il tuo compito iniziale (ad esempio, "Crea uno slogan per un nuovo SUV elettrico..."). Gli agenti risponderanno a turno, affinando il risultato.
orchestration_result = await group_chat_orchestration.invoke(
task="Create a slogan for a new electric SUV that is affordable and fun to drive.",
runtime=runtime,
)
Raccogliere i risultati
Attendere il completamento dell'orchestrazione.
value = await orchestration_result.get()
print(f"***** Final Result *****\n{value}")
Facoltativo: arrestare il runtime
Al termine dell'elaborazione, arrestare il runtime per pulire le risorse.
await runtime.stop_when_idle()
Output di esempio
**Writer**
"Drive Tomorrow: Affordable Adventure Starts Today!"
**Reviewer**
This slogan, "Drive Tomorrow: Affordable Adventure Starts Today!", effectively communicates the core attributes...
**Writer**
"Embrace the Future: Your Affordable Electric Adventure Awaits!"
**Reviewer**
This revised slogan, "Embrace the Future: Your Affordable Electric Adventure Awaits!", further enhances the message...
**Writer**
"Feel the Charge: Adventure Meets Affordability in Your New Electric SUV!"
***** Result *****
"Feel the Charge: Adventure Meets Affordability in Your New Electric SUV!"
Suggerimento
Il codice di esempio completo è disponibile qui.
Annotazioni
L'orchestrazione dell'agente non è ancora disponibile in Java SDK.
Personalizzare Gestione chat di gruppo
È possibile personalizzare il flusso di chat di gruppo implementando il proprio GroupChatManager. In questo modo è possibile controllare come vengono filtrati i risultati, come viene selezionato l'agente successivo e quando richiedere l'input dell'utente o terminare la chat.
Ad esempio, è possibile creare un gestore personalizzato ereditando da GroupChatManager ed eseguendo l'override dei relativi metodi astratti:
using Microsoft.SemanticKernel.Agents.Orchestration.GroupChat;
using Microsoft.SemanticKernel.ChatCompletion;
using System.Threading;
using System.Threading.Tasks;
public class CustomGroupChatManager : GroupChatManager
{
public override ValueTask<GroupChatManagerResult<string>> FilterResults(ChatHistory history, CancellationToken cancellationToken = default)
{
// Custom logic to filter or summarize chat results
return ValueTask.FromResult(new GroupChatManagerResult<string>("Summary") { Reason = "Custom summary logic." });
}
public override ValueTask<GroupChatManagerResult<string>> SelectNextAgent(ChatHistory history, GroupChatTeam team, CancellationToken cancellationToken = default)
{
// Randomly select an agent from the team
var random = new Random();
int index = random.Next(team.Members.Count);
string nextAgent = team.Members[index].Id;
return ValueTask.FromResult(new GroupChatManagerResult<string>(nextAgent) { Reason = "Custom selection logic." });
}
public override ValueTask<GroupChatManagerResult<bool>> ShouldRequestUserInput(ChatHistory history, CancellationToken cancellationToken = default)
{
// Custom logic to decide if user input is needed
return ValueTask.FromResult(new GroupChatManagerResult<bool>(false) { Reason = "No user input required." });
}
public override ValueTask<GroupChatManagerResult<bool>> ShouldTerminate(ChatHistory history, CancellationToken cancellationToken = default)
{
// Optionally call the base implementation to check for default termination logic
var baseResult = base.ShouldTerminate(history, cancellationToken).Result;
if (baseResult.Value)
{
// If the base logic says to terminate, respect it
return ValueTask.FromResult(baseResult);
}
// Custom logic to determine if the chat should terminate
bool shouldEnd = history.Count > 10; // Example: end after 10 messages
return ValueTask.FromResult(new GroupChatManagerResult<bool>(shouldEnd) { Reason = "Custom termination logic." });
}
}
È quindi possibile usare il gestore personalizzato nell'orchestrazione:
GroupChatOrchestration orchestration = new (new CustomGroupChatManager { MaximumInvocationCount = 5 }, ...);
Suggerimento
Un esempio completo di un gestore di chat di gruppo personalizzato è disponibile qui
È possibile personalizzare il flusso di chat di gruppo implementando il proprio GroupChatManager. In questo modo è possibile controllare come vengono filtrati i risultati, come viene selezionato l'agente successivo e quando richiedere l'input dell'utente o terminare la chat.
Ad esempio, è possibile creare un gestore personalizzato ereditando da GroupChatManager ed eseguendo l'override dei relativi metodi astratti:
from semantic_kernel.agents import GroupChatManager, BooleanResult, StringResult, MessageResult
from semantic_kernel.contents import ChatMessageContent, ChatHistory
class CustomGroupChatManager(GroupChatManager):
async def filter_results(self, chat_history: ChatHistory) -> MessageResult:
# Custom logic to filter or summarize chat results
summary = "Summary of the discussion."
return MessageResult(result=ChatMessageContent(role="assistant", content=summary), reason="Custom summary logic.")
async def select_next_agent(self, chat_history: ChatHistory, participant_descriptions: dict[str, str]) -> StringResult:
# Randomly select an agent from the participants
import random
next_agent = random.choice(list(participant_descriptions.keys()))
return StringResult(result=next_agent, reason="Custom selection logic.")
async def should_request_user_input(self, chat_history: ChatHistory) -> BooleanResult:
# Custom logic to decide if user input is needed
return BooleanResult(result=False, reason="No user input required.")
async def should_terminate(self, chat_history: ChatHistory) -> BooleanResult:
# Optionally call the base implementation to check for default termination logic
base_result = await super().should_terminate(chat_history)
if base_result.result:
return base_result
# Custom logic to determine if the chat should terminate
should_end = len(chat_history.messages) > 10 # Example: end after 10 messages
return BooleanResult(result=should_end, reason="Custom termination logic.")
È quindi possibile usare il gestore personalizzato nell'orchestrazione:
from semantic_kernel.agents import GroupChatOrchestration
group_chat_orchestration = GroupChatOrchestration(manager=CustomGroupChatManager(max_rounds=5), ...)
Suggerimento
Un esempio completo di un gestore di chat di gruppo personalizzato è disponibile qui
Annotazioni
L'orchestrazione dell'agente non è ancora disponibile in Java SDK.
Ordine delle chiamate delle funzioni del gestore della chat di gruppo
Quando si orchestra una chat di gruppo, i metodi del gestore di chat di gruppo vengono chiamati in un ordine specifico per ogni round della conversazione:
- ShouldRequestUserInput: controlla se l'input dell'utente (umano) è necessario prima che l'agente successivo parli. Se è vero, l'orchestrazione viene sospesa per ricevere input dall'utente. L'input dell'utente viene quindi aggiunto alla cronologia delle chat del manager e inviato a tutti gli agenti.
- ShouldTerminate: determina se la chat di gruppo deve terminare (ad esempio, se viene raggiunto un numero massimo di round o viene soddisfatta una condizione personalizzata). Se vero, l'orchestrazione procede con il filtraggio dei risultati.
- FilterResults: chiamato solo se la chat termina, per riepilogare o elaborare i risultati finali della conversazione.
- SelezionareNextAgent: se la chat non termina, seleziona l'agente successivo per rispondere nella conversazione.
Questo ordine garantisce che le condizioni di input e terminazione dell'utente vengano controllate prima di avanzare la conversazione e che i risultati vengano filtrati solo alla fine. È possibile personalizzare la logica per ogni passaggio eseguendo l'override dei metodi corrispondenti nel gestore chat del gruppo personalizzato.