Delen via


Groepschatindeling

Belangrijk

Agent Orchestratiefuncties in de Agent Framework bevinden zich in de experimentele fase. Ze zijn in actieve ontwikkeling en kunnen aanzienlijk veranderen voordat ze naar de preview- of releasekandidaatfase gaan.

Groepschatorkestratie modelleert een gezamenlijk gesprek tussen instanties, eventueel inclusief een menselijke deelnemer. Een groepschatmanager coördineert de stroom, waarbij wordt bepaald welke agent moet reageren op de volgende en wanneer om menselijke invoer moet worden gevraagd. Dit patroon is krachtig voor het simuleren van vergaderingen, debatten of gezamenlijke sessies voor probleemoplossing.

Veelvoorkomende gebruiksvoorbeelden

Agenten die verschillende afdelingen vertegenwoordigen, bespreken een bedrijfsvoorstel, met een manager-agent die het gesprek modereert en, indien nodig, een mens erbij betrekt.

diagram

Wat u leert

  • Hoe agenten met verschillende rollen voor een groepschat te definiëren
  • Een groepschatbeheer gebruiken om de stroom van het gesprek te beheren
  • Een menselijke deelnemer betrekken bij het gesprek
  • Het gesprek observeren en het uiteindelijke resultaat verzamelen

Uw agents definiëren

Elke agent in de groepschat heeft een specifieke rol. In dit voorbeeld definiëren we een copywriter en een revisor.

Aanbeveling

Deze ChatCompletionAgent wordt hier gebruikt, maar u kunt elk agenttype gebruiken.

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,
};

Optioneel: Agentreacties observeren

U kunt een callback maken om agentreacties vast te leggen wanneer de volgorde vordert via de ResponseCallback eigenschap.

ChatHistory history = [];

ValueTask responseCallback(ChatMessageContent response)
{
    history.Add(response);
    return ValueTask.CompletedTask;
}

De groepschatorchestratie instellen

Maak een GroupChatOrchestration object, waarbij je de agents, een groepschatmanager (hier een RoundRobinGroupChatManager) en de response-callback doorgeeft. De manager controleert de stroom. Hier wisselen we beurtelings af in een round-robin stijl voor een bepaald aantal rondes.

GroupChatOrchestration orchestration = new GroupChatOrchestration(
    new RoundRobinGroupChatManager { MaximumInvocationCount = 5 },
    writer,
    editor)
{
    ResponseCallback = responseCallback,
};

De runtime starten

Er is een runtime vereist voor het beheren van de uitvoering van agents. Hier gebruiken we InProcessRuntime en starten het voordat we de orchestratie aanroepen.

InProcessRuntime runtime = new InProcessRuntime();
await runtime.StartAsync();

De orchestratie aanroepen

Roep de orkestratie aan met uw eerste taak (bijvoorbeeld "Maak een slogan voor een nieuwe elektrische SUV..."). De agents reageren om beurten en verfijnen het resultaat.

var result = await orchestration.InvokeAsync(
    "Create a slogan for a new electric SUV that is affordable and fun to drive.",
    runtime);

Resultaten verzamelen

Wacht totdat de orkestratie is voltooid en haal de uiteindelijke uitvoer op.

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);
}

Optioneel: De runtime stoppen

Nadat de verwerking is voltooid, stopt u de runtime om resources op te schonen.

await runtime.RunUntilIdleAsync();

Voorbeelduitvoer

# 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.”

Aanbeveling

De volledige voorbeeldcode is hier beschikbaar

Uw agents definiëren

Elke agent in de groepschat heeft een specifieke rol. In dit voorbeeld:

  • Schrijver: Inhoud wordt gemaakt en bewerkt op basis van feedback.
  • Revisor: Beoordeelt de inhoud en geeft feedback voor verbetering.

Aanbeveling

Deze ChatCompletionAgent wordt hier gebruikt met Azure OpenAI, maar u kunt elk agenttype of elke modelservice gebruiken.

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]

Agentreacties observeren

U kunt een callback definiëren om het bericht van elke agent af te drukken wanneer het gesprek vordert.

from semantic_kernel.contents import ChatMessageContent

def agent_response_callback(message: ChatMessageContent) -> None:
    print(f"**{message.name}**\n{message.content}")

De groepschatorchestratie instellen

Maak een GroupChatOrchestration object door de agents, een groepschatmanager (in dit geval een RoundRobinGroupChatManager), en de reactiecallback door te geven. De manager controleert de stroom. Hier wisselen we beurtelings af in een round-robin stijl voor een bepaald aantal rondes.

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,
)

De runtime starten

Start de runtime om agentuitvoering te beheren.

from semantic_kernel.agents.runtime import InProcessRuntime

runtime = InProcessRuntime()
runtime.start()

De orchestratie aanroepen

Roep de orkestratie aan met uw eerste taak (bijvoorbeeld "Maak een slogan voor een nieuwe elektrische SUV..."). De agents reageren om beurten en verfijnen het resultaat.

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,
)

Resultaten verzamelen

Wacht totdat de orchestratie is voltooid.

value = await orchestration_result.get()
print(f"***** Final Result *****\n{value}")

Optioneel: De runtime stoppen

Nadat de verwerking is voltooid, stopt u de runtime om resources op te schonen.

await runtime.stop_when_idle()

Voorbeelduitvoer

**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!"

Aanbeveling

De volledige voorbeeldcode is hier beschikbaar.

Opmerking

Agentindeling is nog niet beschikbaar in Java SDK.

Groepschatbeheer aanpassen

U kunt de groepschatstroom aanpassen door uw eigen GroupChatManagerstroom te implementeren. Hiermee kunt u bepalen hoe resultaten worden gefilterd, hoe de volgende agent wordt geselecteerd en wanneer u gebruikersinvoer wilt aanvragen of de chat wilt beëindigen.

U kunt bijvoorbeeld een aangepaste manager maken door de abstracte methoden ervan GroupChatManager over te nemen en te overschrijven:

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." });
    }
}

Vervolgens kunt u uw aangepaste manager gebruiken in de orkestratie.

GroupChatOrchestration orchestration = new (new CustomGroupChatManager { MaximumInvocationCount = 5 }, ...);

Aanbeveling

Hier vindt u een volledig voorbeeld van een aangepast groepschatbeheer

U kunt de groepschatstroom aanpassen door uw eigen GroupChatManagerstroom te implementeren. Hiermee kunt u bepalen hoe resultaten worden gefilterd, hoe de volgende agent wordt geselecteerd en wanneer u gebruikersinvoer wilt aanvragen of de chat wilt beëindigen.

U kunt bijvoorbeeld een aangepaste manager maken door de abstracte methoden ervan GroupChatManager over te nemen en te overschrijven:

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.")

Vervolgens kunt u uw aangepaste manager gebruiken in de orkestratie.

from semantic_kernel.agents import GroupChatOrchestration

group_chat_orchestration = GroupChatOrchestration(manager=CustomGroupChatManager(max_rounds=5), ...)

Aanbeveling

Hier vindt u een volledig voorbeeld van een aangepast groepschatbeheer

Opmerking

Agentindeling is nog niet beschikbaar in Java SDK.

Volgorde van functie-aanroepen van Groepschatbeheer

Bij het organiseren van een groepschat worden de methoden van de groepschatmanager in een specifieke volgorde aangeroepen voor elke ronde van het gesprek:

  1. ShouldRequestUserInput: Controleert of invoer van de gebruiker (menselijke) vereist is voordat de volgende agent spreekt. Als dat het geval is, wordt de orkestratie onderbroken voor gebruikersinvoer. De gebruikersinvoer wordt vervolgens toegevoegd aan de chatgeschiedenis van de manager en verzonden naar alle agents.
  2. ShouldTerminate: bepaalt of de groepschat moet eindigen (bijvoorbeeld als een maximum aantal rondes wordt bereikt of aan een aangepaste voorwaarde wordt voldaan). Als dit klopt, gaat de orkestratie verder met het filteren van resultaten.
  3. FilterResults: alleen aangeroepen als de chat wordt beëindigd, om de uiteindelijke resultaten van het gesprek samen te vatten of te verwerken.
  4. SelectNextAgent: Als de chat niet wordt beëindigd, selecteert u de volgende agent om in het gesprek te reageren.

Deze volgorde zorgt ervoor dat gebruikersinvoer- en beëindigingsvoorwaarden worden gecontroleerd voordat het gesprek wordt uitgevoerd en dat de resultaten alleen aan het einde worden gefilterd. U kunt de logica voor elke stap aanpassen door de bijbehorende methoden in uw aangepaste groepschatbeheer te overschrijven.

Volgende stappen