Condividi tramite


Argomenti avanzati sull'orchestrazione avanzata degli agenti del kernel semantico

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.

Tempo di esecuzione

Il runtime è il componente fondamentale che gestisce il ciclo di vita, la comunicazione e l'esecuzione di agenti e orchestrazioni. Funge da bus di messaggi e ambiente di esecuzione per tutti gli attori (agenti e attori specifici dell'orchestrazione) nel sistema.

Ruolo del runtime

  • Routing dei messaggi: Il runtime è responsabile del recapito di messaggi tra agenti e attori di orchestrazione, usando un modello di messaggistica diretta o pub-sub a seconda del modello di orchestrazione.
  • Gestione del ciclo di vita degli attori: Crea, registra e gestisce il ciclo di vita di tutti gli attori coinvolti in un'orchestrazione, garantendo l'isolamento e la corretta gestione delle risorse.
  • Contesto di esecuzione: Il runtime fornisce il contesto di esecuzione per le orchestrazioni, consentendo l'esecuzione di più orchestrazioni (e delle relative chiamate) in modo indipendente e simultaneo.

Relazione tra runtime e orchestrazioni

Si pensi a un'orchestrazione come un grafico che definisce il modo in cui gli agenti interagiscono tra loro. Il runtime è il motore che esegue questo grafico, gestendo il flusso dei messaggi e il ciclo di vita degli agenti. Gli sviluppatori possono eseguire questo grafico più volte con input diversi nella stessa istanza di runtime e il runtime garantirà che ogni esecuzione sia isolata e indipendente.

Timeout

Quando viene richiamata un'orchestrazione, l'orchestrazione viene restituita immediatamente con un gestore che può essere usato per ottenere il risultato in un secondo momento. Questo modello asincrono consente una progettazione più flessibile e reattiva, soprattutto negli scenari in cui l'orchestrazione può richiedere molto tempo per il completamento.

Importante

Se si verifica un timeout, la chiamata dell'orchestrazione non verrà annullata. L'orchestrazione continuerà a funzionare in modalità invisibile fino al completamento. Gli sviluppatori possono comunque recuperare il risultato in un secondo momento.

Gli sviluppatori possono ottenere il risultato di una chiamata di orchestrazione in un secondo momento chiamando il GetValueAsync metodo sull'oggetto risultato. Quando l'applicazione è pronta per elaborare il risultato, la chiamata potrebbe essere stata completata o meno. Gli sviluppatori possono quindi specificare facoltativamente un timeout per il GetValueAsync metodo . Se l'orchestrazione non viene completata entro il timeout specificato, verrà generata un'eccezione di timeout.

string output = await result.GetValueAsync(TimeSpan.FromSeconds(60));

Se l'orchestrazione non viene completata entro il timeout specificato, verrà generata un'eccezione di timeout.

Gli sviluppatori possono ottenere il risultato di una chiamata di orchestrazione in un secondo momento chiamando il get metodo sull'oggetto risultato. Quando l'applicazione è pronta per elaborare il risultato, la chiamata potrebbe essere stata completata o meno. Gli sviluppatori possono quindi specificare facoltativamente un timeout per il get metodo . Se l'orchestrazione non viene completata entro il timeout specificato, verrà generata un'eccezione di timeout.

value = await orchestration_result.get(timeout=60)

Se l'orchestrazione non viene completata entro il timeout specificato, verrà generata un'eccezione di timeout.

Annotazioni

L'orchestrazione dell'agente non è ancora disponibile in Java SDK.

Human-in-the-Loop

Richiamata di risposta dell'agente

Per visualizzare le risposte dell'agente all'interno di una chiamata, gli sviluppatori possono fornire un oggetto ResponseCallback all'orchestrazione. Ciò consente agli sviluppatori di osservare le risposte di ogni agente durante il processo di orchestrazione. Gli sviluppatori possono usare questo callback per gli aggiornamenti, la registrazione o altri scopi dell'interfaccia utente.

public ValueTask ResponseCallback(ChatMessageContent response)
{
    Console.WriteLine($"# {response.AuthorName}\n{response.Content}");
    return ValueTask.CompletedTask;
}

SequentialOrchestration orchestration = new SequentialOrchestration(
    analystAgent, writerAgent, editorAgent)
{
    ResponseCallback = ResponseCallback,
};

Per visualizzare le risposte dell'agente all'interno di una chiamata, gli sviluppatori possono fornire un oggetto agent_response_callback all'orchestrazione. Ciò consente agli sviluppatori di osservare le risposte di ogni agente durante il processo di orchestrazione. Gli sviluppatori possono usare questo callback per gli aggiornamenti, la registrazione o altri scopi dell'interfaccia utente.

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

sequential_orchestration = SequentialOrchestration(
    members=agents,
    agent_response_callback=agent_response_callback,
)

Annotazioni

L'orchestrazione dell'agente non è ancora disponibile in Java SDK.

Funzione di risposta umana

Per le orchestrazioni che supportano l'input dell'utente (ad esempio, handoff e chat di gruppo), fornire un oggetto InteractiveCallback che restituisce una risposta ChatMessageContent da parte dell'utente. Usando questo callback, gli sviluppatori possono implementare la logica personalizzata per raccogliere l'input dell'utente, ad esempio la visualizzazione di un prompt dell'interfaccia utente o l'integrazione con altri sistemi.

HandoffOrchestration orchestration = new(...)
{
    InteractiveCallback = () =>
    {
        Console.Write("User: ");
        string input = Console.ReadLine();
        return new ChatMessageContent(AuthorRole.User, input);
    }
};

Per le orchestrazioni che supportano l'input dell'utente (ad esempio, handoff e chat di gruppo), fornire un oggetto human_response_function che restituisce una risposta ChatMessageContent da parte dell'utente. Usando questo callback, gli sviluppatori possono implementare la logica personalizzata per raccogliere l'input dell'utente, ad esempio la visualizzazione di un prompt dell'interfaccia utente o l'integrazione con altri sistemi.

def human_response_function() -> ChatMessageContent:
    user_input = input("User: ")
    return ChatMessageContent(role=AuthorRole.USER, content=user_input)

handoff_orchestration = HandoffOrchestration(
    ...,
    agent_response_callback=agent_response_callback,
)

Annotazioni

L'orchestrazione dell'agente non è ancora disponibile in Java SDK.

Dati strutturati

Crediamo che i dati strutturati siano una parte fondamentale nella creazione di flussi di lavoro agentici. Usando dati strutturati, gli sviluppatori possono creare orchestrazioni più riutilizzabili e l'esperienza di sviluppo è migliorata. Semantic Kernel SDK consente di passare dati strutturati come input alle orchestrazioni e restituire dati strutturati come output.

Importante

Internamente, le orchestrazioni elaborano ancora i dati come ChatMessageContent.

Input strutturati

Gli sviluppatori possono passare dati strutturati come input alle orchestrazioni usando una classe di input fortemente tipizzata e specificandola come parametro generico per l'orchestrazione. Ciò consente la sicurezza dei tipi e una maggiore flessibilità per le orchestrazioni per gestire strutture di dati complesse. Ad esempio, per valutare i problemi di GitHub, definire una classe per l'input strutturato:

public sealed class GithubIssue
{
    public string Id { get; set; } = string.Empty;
    public string Title { get; set; } = string.Empty;
    public string Body { get; set; } = string.Empty;
    public string[] Labels { get; set; } = [];
}

Gli sviluppatori possono quindi usare questo tipo come input per un'orchestrazione fornendolo come parametro generico:

HandoffOrchestration<GithubIssue, string> orchestration =
    new(...);

GithubIssue input = new GithubIssue { ... };
var result = await orchestration.InvokeAsync(input, runtime);

Trasformazioni di input personalizzate

Per impostazione predefinita, l'orchestrazione userà la trasformazione di input integrata, che serializza l'oggetto in JSON e lo avvolge in un ChatMessageContent. Se si vuole personalizzare la modalità di conversione dell'input strutturato nel tipo di messaggio sottostante, è possibile fornire una funzione di trasformazione di input personalizzata tramite la InputTransform proprietà :

HandoffOrchestration<GithubIssue, string> orchestration =
    new(...)
    {
        InputTransform = (issue, cancellationToken) =>
        {
            // For example, create a chat message with a custom format
            var message = new ChatMessageContent(AuthorRole.User, $"[{issue.Id}] {issue.Title}\n{issue.Body}");
            return ValueTask.FromResult<IEnumerable<ChatMessageContent>>([message]);
        },
    };

In questo modo è possibile controllare esattamente come viene presentato l'input tipizzato agli agenti, abilitando scenari avanzati, ad esempio formattazione personalizzata, selezione di campi o input multi-messaggio.

Suggerimento

Vedere l'esempio completo in Step04a_HandoffWithStructuredInput.cs

Gli sviluppatori possono passare dati strutturati come input alle orchestrazioni specificando un modello Pydantic (o qualsiasi classe personalizzata) come parametro generico per l'orchestrazione. Ciò consente la sicurezza dei tipi e consente alle orchestrazioni di gestire strutture di dati complesse.

Ad esempio, per valutare i problemi di GitHub, definire un modello Pydantic per l'input strutturato:

from pydantic import BaseModel

class GithubIssue(BaseModel):
    id: str
    title: str
    body: str
    labels: list[str] = []

È quindi possibile usare questo tipo come input per l'orchestrazione specificandolo come parametro generico:

from semantic_kernel.agents import HandoffOrchestration

def custom_input_transform(input_message: GithubIssue) -> ChatMessageContent:
    return ChatMessageContent(role=AuthorRole.USER, content=f"[{input_message.id}] {input_message.title}\n{input_message.body}")


handoff_orchestration = HandoffOrchestration[GithubIssue, ChatMessageContent](
    ...,
    input_transform=custom_input_transform,
)

GithubIssueSample = GithubIssue(
    id="12345",
    title="Bug: ...",
    body="Describe the bug...",
    labels=[],
)

orchestration_result = await handoff_orchestration.invoke(
    task=GithubIssueSample,
    runtime=runtime,
)

Suggerimento

Consulta l'esempio completo nel file step4a_handoff_structured_inputs.py

Annotazioni

L'orchestrazione dell'agente non è ancora disponibile in Java SDK.

Output strutturati

Gli agenti e le orchestrazioni possono restituire output strutturati specificando una classe di output fortemente tipizzata come parametro generico per l'orchestrazione. In questo modo è possibile usare risultati avanzati e strutturati nell'applicazione, anziché semplicemente testo normale.

Si supponga, ad esempio, di voler analizzare un articolo ed estrarre temi, sentimenti ed entità. Definire una classe per l'output strutturato:

public sealed class Analysis
{
    public IList<string> Themes { get; set; } = [];
    public IList<string> Sentiments { get; set; } = [];
    public IList<string> Entities { get; set; } = [];
}

È quindi possibile usare questo tipo come output per l'orchestrazione specificandolo come parametro generico:

ConcurrentOrchestration<string, Analysis> orchestration =
    new(agent1, agent2, agent3)
    {
        ResultTransform = outputTransform.TransformAsync, // see below
    };

// ...
OrchestrationResult<Analysis> result = await orchestration.InvokeAsync(input, runtime);
Analysis output = await result.GetValueAsync(TimeSpan.FromSeconds(60));

Trasformazioni di output personalizzate

Per impostazione predefinita, l'orchestrazione utilizzerà la trasformazione di output incorporata, che tenta di deserializzare il contenuto della risposta dell'agente nel tipo di output desiderato. Per scenari più avanzati, è possibile fornire una trasformazione di output personalizzata, ad esempio con output strutturato da alcuni modelli.

StructuredOutputTransform<Analysis> outputTransform =
    new(chatCompletionService, new OpenAIPromptExecutionSettings { ResponseFormat = typeof(Analysis) });

ConcurrentOrchestration<string, Analysis> orchestration =
    new(agent1, agent2, agent3)
    {
        ResultTransform = outputTransform.TransformAsync,
    };

Questo approccio consente di ricevere ed elaborare dati strutturati direttamente dall'orchestrazione, semplificando la creazione di flussi di lavoro e integrazioni avanzati.

Suggerimento

Guarda esempio completo in Step01a_ConcurrentWithStructuredOutput.cs

Gli agenti e le orchestrazioni possono restituire output strutturati specificando un modello Pydantic (o qualsiasi classe personalizzata) come tipo di output generico per l'orchestrazione. In questo modo è possibile usare risultati avanzati e strutturati nell'applicazione, anziché semplicemente testo normale.

Si supponga, ad esempio, di voler analizzare un articolo ed estrarre temi, sentimenti ed entità. Definire un modello Pydantic per l'output strutturato:

from pydantic import BaseModel

class ArticleAnalysis(BaseModel):
    themes: list[str]
    sentiments: list[str]
    entities: list[str]

È quindi possibile usare questo tipo come output per l'orchestrazione specificandolo come parametro generico e specificando una trasformazione di output:

from semantic_kernel.agents import ConcurrentOrchestration
from semantic_kernel.agents.orchestration.tools import structured_outputs_transform
from semantic_kernel.connectors.ai.open_ai import AzureChatCompletion

# `structured_outputs_transform` is a built-in transform that uses the structured output

concurrent_orchestration = ConcurrentOrchestration[str, ArticleAnalysis](
    members=agents,
    output_transform=structured_outputs_transform(ArticleAnalysis, AzureChatCompletion()),
)

...

orchestration_result = await concurrent_orchestration.invoke(
    task="article text",
    runtime=runtime,
)

value = await orchestration_result.get(timeout=20)

# `value` is now an instance of ArticleAnalysis

Questo approccio consente di ricevere ed elaborare dati strutturati direttamente dall'orchestrazione, semplificando la creazione di flussi di lavoro e integrazioni avanzati.

Suggerimento

Guarda l'esempio completo in step1a_concurrent_structured_outputs.py

Annotazioni

L'orchestrazione dell'agente non è ancora disponibile in Java SDK.

Annullamento

Importante

L'annullamento impedirà agli agenti di elaborare altri messaggi, ma non arresterà gli agenti che stanno già elaborando i messaggi.

Importante

L'annullamento non arresterà il runtime.

È possibile annullare un'orchestrazione chiamando il Cancel metodo nel gestore dei risultati. In questo modo l'orchestrazione verrà arrestata propagando il segnale a tutti gli agenti e interromperà l'elaborazione di eventuali altri messaggi.

var resultTask = orchestration.InvokeAsync(input, runtime);
resultTask.Cancel();

Gli sviluppatori possono annullare un'orchestrazione chiamando il cancel metodo nel gestore dei risultati. In questo modo l'orchestrazione verrà arrestata propagando il segnale a tutti gli agenti e interromperà l'elaborazione di eventuali altri messaggi.

orchestration_result = await orchestration.invoke(task=task, runtime=runtime)
orchestration_result.cancel()

Annotazioni

L'orchestrazione dell'agente non è ancora disponibile in Java SDK.

Passaggi successivi

Annotazioni

L'orchestrazione dell'agente non è ancora disponibile in Java SDK.