Orchestrace skupinového chatu

Důležité

Funkce orchestrace agentů v rozhraní Agent Framework jsou v experimentální fázi. Jsou ve fázi aktivního vývoje a můžou se výrazně změnit před přechodem do fáze Preview nebo release candidate.

Orchestrace skupinového chatu modeluje spolupráci mezi agenty, volitelně včetně lidského účastníka. Vedoucí skupinového chatu koordinuje tok a určuje, který agent by měl reagovat, a kdy požádat o vstup člověka. Tento model je účinný pro simulaci schůzek, debat nebo relací pro řešení problémů ve spolupráci.

Další informace o modelu, například kdy použít vzor nebo kdy se vyhnout vzoru v úloze, najdete v tématu Orchestrace skupinového chatu.

Běžné případy použití

Agenti reprezentující různá oddělení diskutují o obchodním návrhu s manažerem, který v případě potřeby moderuje konverzaci a zahrnuje člověka:

diagram

Co se naučíte

  • Jak definovat agenty s různými rolemi pro skupinový chat
  • Jak pomocí správce skupinového chatu řídit tok konverzace
  • Zapojení člověka do konverzace
  • Jak sledovat konverzaci a shromáždit konečný výsledek

Definování agentů

Každý agent ve skupinovém chatu má určitou roli. V tomto příkladu definujeme korektora a recenzenta.

Návod

Tady se ChatCompletionAgent používá, ale můžete použít libovolný typ agenta.

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

Volitelné: Sledování odpovědí agenta

Můžete vytvořit zpětné volání pro zachycení odpovědí agenta při průběhu sekvence prostřednictvím ResponseCallback vlastnosti.

ChatHistory history = [];

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

Nastavení orchestrace skupinového chatu

GroupChatOrchestration Vytvořte objekt, který předává agenty, manažer skupinového chatu (zde, aRoundRobinGroupChatManager) a zpětné volání odpovědi. Manažer řídí tok – zde se střídají tahy střídavým pořadím pro nastavený počet kol.

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

Spuštění modulu runtime

Modul runtime se vyžaduje ke správě provádění agentů. Tady použijeme InProcessRuntime a zahájíme to před vyvoláním orchestrace.

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

Vyvolání orchestrace

Zavolejte orchestraci pomocí počátečního úkolu (např. "Vytvořte heslo pro nové elektrické SUV..."). Agenti se budou střídat v odpovědích a zpřesňovat výsledek.

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

Shromáždit výsledky

Počkejte na dokončení orchestrace a načtení konečného výstupu.

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

Volitelné: Zastavení modulu runtime

Po dokončení zpracování zastavte modul runtime pro vyčištění prostředků.

await runtime.RunUntilIdleAsync();

Ukázkový výstup

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

Návod

Úplný vzorový kód je k dispozici tady.

Definování agentů

Každý agent ve skupinovém chatu má určitou roli. V tomto příkladu:

  • Autor: Vytváří a upravuje obsah na základě zpětné vazby.
  • Kontrolor: Kontroluje obsah a poskytuje zpětnou vazbu k vylepšení.

Návod

Používá se ChatCompletionAgent zde s Azure OpenAI, ale můžete použít libovolný typ agenta nebo službu modelu.

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]

Sledování odpovědí agenta

Při průběhu konverzace můžete definovat zpětné volání, které vytiskne zprávu jednotlivých agentů.

from semantic_kernel.contents import ChatMessageContent

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

Nastavení orchestrace skupinového chatu

Vytvořte GroupChatOrchestration objekt, předejte jako argumenty agenty, manažera skupinového chatu (zde RoundRobinGroupChatManager) a zpětné volání odpovědi. Manažer řídí tok – zde se střídají tahy střídavým pořadím pro nastavený počet kol.

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

Spuštění modulu runtime

Spusťte modul runtime pro správu provádění agenta.

from semantic_kernel.agents.runtime import InProcessRuntime

runtime = InProcessRuntime()
runtime.start()

Vyvolání orchestrace

Zavolejte orchestraci pomocí počátečního úkolu (např. "Vytvořte heslo pro nové elektrické SUV..."). Agenti se budou střídat v odpovědích a zpřesňovat výsledek.

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

Shromáždit výsledky

Počkejte na dokončení orchestrace.

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

Volitelné: Zastavení modulu runtime

Po dokončení zpracování zastavte modul runtime pro vyčištění prostředků.

await runtime.stop_when_idle()

Ukázkový výstup

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

Návod

Úplný vzorový kód je k dispozici tady.

Poznámka:

Orchestrace agentů zatím není v Java vývojovém prostředí SDK k dispozici.

Přizpůsobení Správce skupinového chatu

Tok skupinového chatu můžete přizpůsobit implementací vlastního GroupChatManager. To vám umožní řídit, jak se výsledky filtrují, jak je vybrán další agent a kdy požádat o uživatelský vstup nebo ukončit chat.

Vlastního správce můžete například vytvořit tak, že zdědíte GroupChatManager a přepíšete jeho abstraktní metody:

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

Potom můžete v orchestraci použít vlastního manažera:

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

Návod

Úplný příklad vlastního správce skupinového chatu je k dispozici tady.

Tok skupinového chatu můžete přizpůsobit implementací vlastního GroupChatManager. To vám umožní řídit, jak se výsledky filtrují, jak je vybrán další agent a kdy požádat o uživatelský vstup nebo ukončit chat.

Vlastního správce můžete například vytvořit tak, že zdědíte GroupChatManager a přepíšete jeho abstraktní metody:

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

Potom můžete v orchestraci použít vlastního manažera:

from semantic_kernel.agents import GroupChatOrchestration

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

Návod

Úplný příklad vlastního správce skupinového chatu je k dispozici tady.

Poznámka:

Orchestrace agentů zatím není v Java vývojovém prostředí SDK k dispozici.

Pořadí volání funkce Správce skupinového chatu

Při orchestraci skupinového chatu se metody vedoucího skupinového chatu volají v určitém pořadí pro každé kolo konverzace:

  1. ShouldRequestUserInput: Zkontroluje, jestli je vyžadován vstup uživatele (člověka), než další agent promluví. Pokud je hodnota true, orchestrace se pozastaví pro uživatelský vstup. Uživatelský vstup se pak přidá do historie chatu manažera a odešle se všem agentům.
  2. ShouldTerminate: Určuje, jestli má skupinový chat končit (například pokud je dosažen maximální počet kol nebo je splněna vlastní podmínka). Pokud je hodnota true, orchestrace pokračuje k filtrování výsledků.
  3. FilterResults: Volá se pouze v případě, že chat končí, aby se shrnuly nebo zpracovávaly konečné výsledky konverzace.
  4. SelectNextAgent: Pokud chat není ukončený, vybere dalšího agenta, který odpoví v konverzaci.

Toto pořadí zajišťuje, že se před zahájením konverzace kontrolují podmínky vstupu a ukončení uživatele a že výsledky se filtrují jenom na konci. Logiku pro každý krok můžete přizpůsobit přepsáním odpovídajících metod ve vlastním správci skupinového chatu.

Další kroky