Condividi tramite


Esplorazione della collaborazione tra agenti nella chat agente (sperimentale)

Avviso

Il framework dell'agente del kernel semantico è sperimentale, ancora in fase di sviluppo ed è soggetto a modifiche.

La documentazione dettagliata dell'API relativa a questa discussione è disponibile all'indirizzo:

Gli agenti non sono attualmente disponibili in Java.

Che cos'è Agent Chat?

Agent Chat offre un framework che consente l'interazione tra più agenti, anche se sono di tipi diversi. In questo modo è possibile che un agente di completamento chat e un agente Open AI Assistant funzionino insieme all'interno della stessa conversazione. Agent Chat definisce anche i punti di ingresso per avviare la collaborazione tra gli agenti, sia tramite più risposte che una singola risposta dell'agente.

Come classe astratta, Agent Chat può essere sottoclassata per supportare scenari personalizzati.

Una di queste sottoclassi, Agent Group Chat, offre un'implementazione concreta di Agent Chat, usando un approccio basato sulla strategia per gestire le dinamiche di conversazione.

Creazione di una chat del gruppo di agenti

Per creare una chat del gruppo di agenti, è possibile specificare gli agenti partecipanti o creare una chat vuota e successivamente aggiungere i partecipanti all'agente. La configurazione di Chat-Settings and Strategies viene eseguita anche durante l'inizializzazione di Chat del gruppo di agenti. Queste impostazioni definiscono il funzionamento delle dinamiche della conversazione all'interno del gruppo.

Nota: il risultato predefinito di Chat-Settings è una conversazione limitata a una singola risposta. Per informazioni dettagliate sulla configurazione di _Chat-Impostazioni, vedere Comportamento della chat dell'agente.

Creazione della chat del gruppo di agenti con gli agenti:

// Define agents
ChatCompletionAgent agent1 = ...;
OpenAIAssistantAgent agent2 = ...;

// Create chat with participating agents.
AgentGroupChat chat = new(agent1, agent2);
# Define agents
agent1 = ChatCompletionAgent(...)
agent2 = OpenAIAssistantAgent(...)

# Create chat with participating agents
chat = AgentGroupChat(agents=[agent1, agent2])

Gli agenti non sono attualmente disponibili in Java.

Aggiunta di agenti a una chat del gruppo di agenti:

// Define agents
ChatCompletionAgent agent1 = ...;
OpenAIAssistantAgent agent2 = ...;

// Create an empty chat.
AgentGroupChat chat = new();

// Add agents to an existing chat.
chat.AddAgent(agent1);
chat.AddAgent(agent2);
# Define agents
agent1 = ChatCompletionAgent(...)
agent2 = OpenAIAssistantAgent(...)

# Create an empty chat
chat = AgentGroupChat()

# Add agents to an existing chat
chat.add_agent(agent=agent1)
chat.add_agent(agent=agent2)

Gli agenti non sono attualmente disponibili in Java.

Uso della chat del gruppo di agenti

Agent Chat supporta due modalità di funzionamento: a turno singolo e multi turni. A turno singolo, un agente specifico viene designato per fornire una risposta. In più turni, tutti gli agenti della conversazione prendono il turno di risposta fino a quando non viene soddisfatto un criterio di terminazione. In entrambe le modalità, gli agenti possono collaborare rispondendo l'uno all'altro per raggiungere un obiettivo definito.

Inserimento dell'input

L'aggiunta di un messaggio di input a una chat agente segue lo stesso modello di un oggetto Cronologia chat.

AgentGroupChat chat = new();

chat.AddChatMessage(new ChatMessageContent(AuthorRole.User, "<message content>"));
chat = AgentGroupChat()

await chat.add_chat_message(ChatMessageContent(role=AuthorRole.USER, content="<message content>"))

Gli agenti non sono attualmente disponibili in Java.

Chiamata dell'agente a turno singolo

In una chiamata a più turni, il sistema deve decidere quale agente risponde successivamente e quando la conversazione deve terminare. Al contrario, una chiamata a turno singolo restituisce semplicemente una risposta dall'agente specificato, consentendo al chiamante di gestire direttamente la partecipazione dell'agente.

Dopo che un agente partecipa alla chat dell'agente tramite una chiamata a turno singolo, viene aggiunto al set di agenti idonei per la chiamata a più turni.

// Define an agent
ChatCompletionAgent agent = ...;

// Create an empty chat.
AgentGroupChat chat = new();

// Invoke an agent for its response
ChatMessageContent[] messages = await chat.InvokeAsync(agent).ToArrayAsync();
# Define an agent
agent = ChatCompletionAgent(...)

# Create an empty chat
chat = AgentGroupChat()

# Invoke an agent for its response(s)
async for message in chat.invoke(agent)
    # process message response(s)

Gli agenti non sono attualmente disponibili in Java.

Chiamata dell'agente a più turni

Anche se la collaborazione tra agenti richiede che un sistema sia attivo che non solo determina quale agente deve rispondere durante ogni turno, ma valuta anche quando la conversazione ha raggiunto il suo obiettivo previsto, l'avvio della collaborazione a più turni rimane semplice.

Le risposte dell'agente vengono restituite in modo asincrono man mano che vengono generate, consentendo la conversazione in tempo reale.

Nota: nelle sezioni seguenti, Selezione agente e terminazione della chat, verranno approfondite in dettaglio le impostazioni di esecuzione. Le impostazioni di esecuzione predefinite usano la selezione sequenziale o round robin e limitano la partecipazione dell'agente a un singolo turno.

API Delle impostazioni di esecuzione .NET:AgentGroupChatSettings

// Define agents
ChatCompletionAgent agent1 = ...;
OpenAIAssistantAgent agent2 = ...;

// Create chat with participating agents.
AgentGroupChat chat =
  new(agent1, agent2)
  {
    // Override default execution settings
    ExecutionSettings =
    {
        TerminationStrategy = { MaximumIterations = 10 }
    }
  };

// Invoke agents
await foreach (ChatMessageContent response in chat.InvokeAsync())
{
  // Process agent response(s)...
}
# Define agents
agent1 = ChatCompletionAgent(...)
agent2 = OpenAIAssistantAgent(...)

# Create chat with participating agents
chat = AgentGroupChat(
    agents=[agent1, agent2],
    termination_strategy=DefaultTerminationStrategy(maximum_iterations=10),
)

async for response in chat.invoke():
    # process agent response(s)

Gli agenti non sono attualmente disponibili in Java.

Accesso alla cronologia chat

La cronologia delle conversazioni di Agent Chat è sempre accessibile, anche se i messaggi vengono recapitati tramite il modello di chiamata. Ciò garantisce che gli scambi passati rimangano disponibili in tutta la conversazione.

Nota: il messaggio più recente viene fornito per primo (ordine decrescente: più recente al meno recente).

// Define and use a chat
AgentGroupChat chat = ...;

// Access history for a previously utilized AgentGroupChat
ChatMessageContent[] history = await chat.GetChatMessagesAsync().ToArrayAsync();
# Define a group chat
chat = AgentGroupChat(...)

# Access history for a previously utilized AgentGroupChat
history = await chat.get_chat_messages()

Gli agenti non sono attualmente disponibili in Java.

Poiché diversi tipi di agenti o configurazioni possono mantenere la propria versione della cronologia delle conversazioni, la cronologia specifica dell'agente è disponibile anche specificando un agente. Ad esempio: Aprire Assistente intelligenza artificiale e agente di completamento chat.

// Agents to participate in chat
ChatCompletionAgent agent1 = ...;
OpenAIAssistantAgent agent2 = ...;

// Define a group chat
AgentGroupChat chat = ...;

// Access history for a previously utilized AgentGroupChat
ChatMessageContent[] history1 = await chat.GetChatMessagesAsync(agent1).ToArrayAsync();
ChatMessageContent[] history2 = await chat.GetChatMessagesAsync(agent2).ToArrayAsync();
# Agents to participate in a chat
agent1 = ChatCompletionAgent(...)
agent2 = OpenAIAssistantAgent(...)

# Define a group chat
chat = AgentGroupChat(...)

# Access history for a previously utilized AgentGroupChat
history1 = await chat.get_chat_messages(agent=agent1)
history2 = await chat.get_chat_messages(agent=agent2)

Gli agenti non sono attualmente disponibili in Java.

Definizione del comportamento della chat del gruppo di agenti

La collaborazione tra gli agenti per risolvere attività complesse è un modello agenteco di base. Per usare questo modello in modo efficace, un sistema deve essere attivo che non solo determina quale agente deve rispondere durante ogni turno, ma valuta anche quando la conversazione ha raggiunto l'obiettivo previsto. Ciò richiede la gestione della selezione dell'agente e la definizione di criteri chiari per la terminazione della conversazione, garantendo una perfetta cooperazione tra gli agenti verso una soluzione. Entrambi questi aspetti sono regolati dalla proprietà Impostazioni di esecuzione.

Le sezioni seguenti, Selezione agente e terminazione della chat, verranno approfondite in dettaglio queste considerazioni.

Selezione agente

Nella chiamata a più turni, la selezione dell'agente è guidata da una strategia di selezione. Questa strategia è definita da una classe base che può essere estesa per implementare comportamenti personalizzati personalizzati in base a specifiche esigenze. Per praticità, sono disponibili anche due strategie di selezione concrete predefinite, offrendo approcci pronti all'uso per la gestione della selezione degli agenti durante le conversazioni.

Se noto, è possibile specificare un agente iniziale per eseguire sempre il primo turno. Un riduttore di cronologia può essere usato anche per limitare l'utilizzo dei token quando si usa una strategia basata su una funzione kernel.

API Strategia di selezione .NET:

// Define the agent names for use in the function template
const string WriterName = "Writer";
const string ReviewerName = "Reviewer";

// Initialize a Kernel with a chat-completion service
Kernel kernel = ...;

// Create the agents
ChatCompletionAgent writerAgent =
    new()
    {
        Name = WriterName,
        Instructions = "<writer instructions>",
        Kernel = kernel
    };

ChatCompletionAgent reviewerAgent =
    new()
    {
        Name = ReviewerName,
        Instructions = "<reviewer instructions>",
        Kernel = kernel
    };

// Define a kernel function for the selection strategy
KernelFunction selectionFunction =
    AgentGroupChat.CreatePromptFunctionForStrategy(
        $$$"""
        Determine which participant takes the next turn in a conversation based on the the most recent participant.
        State only the name of the participant to take the next turn.
        No participant should take more than one turn in a row.

        Choose only from these participants:
        - {{{ReviewerName}}}
        - {{{WriterName}}}

        Always follow these rules when selecting the next participant:
        - After {{{WriterName}}}, it is {{{ReviewerName}}}'s turn.
        - After {{{ReviewerName}}}, it is {{{WriterName}}}'s turn.

        History:
        {{$history}}
        """,
        safeParameterNames: "history");

// Define the selection strategy
KernelFunctionSelectionStrategy selectionStrategy = 
  new(selectionFunction, kernel)
  {
      // Always start with the writer agent.
      InitialAgent = writerAgent,
      // Parse the function response.
      ResultParser = (result) => result.GetValue<string>() ?? WriterName,
      // The prompt variable name for the history argument.
      HistoryVariableName = "history",
      // Save tokens by not including the entire history in the prompt
      HistoryReducer = new ChatHistoryTruncationReducer(3),
  };   

// Create a chat using the defined selection strategy.
AgentGroupChat chat =
    new(writerAgent, reviewerAgent)
    {
        ExecutionSettings = new() { SelectionStrategy = selectionStrategy }
    };
REVIEWER_NAME = "Reviewer"
WRITER_NAME = "Writer"

agent_reviewer = ChatCompletionAgent(
    service_id=REVIEWER_NAME,
    kernel=kernel,
    name=REVIEWER_NAME,
    instructions="<instructions>",
)

agent_writer = ChatCompletionAgent(
    service_id=WRITER_NAME,
    kernel=kernel,
    name=WRITER_NAME,
    instructions="<instructions>",
)

selection_function = KernelFunctionFromPrompt(
    function_name="selection",
    prompt=f"""
    Determine which participant takes the next turn in a conversation based on the the most recent participant.
    State only the name of the participant to take the next turn.
    No participant should take more than one turn in a row.

    Choose only from these participants:
    - {REVIEWER_NAME}
    - {WRITER_NAME}

    Always follow these rules when selecting the next participant:
    - After user input, it is {WRITER_NAME}'s turn.
    - After {WRITER_NAME} replies, it is {REVIEWER_NAME}'s turn.
    - After {REVIEWER_NAME} provides feedback, it is {WRITER_NAME}'s turn.

    History:
    {{{{$history}}}}
    """,
)

chat = AgentGroupChat(
    agents=[agent_writer, agent_reviewer],
    selection_strategy=KernelFunctionSelectionStrategy(
        function=selection_function,
        kernel=_create_kernel_with_chat_completion("selection"),
        result_parser=lambda result: str(result.value[0]) if result.value is not None else COPYWRITER_NAME,
        agent_variable_name="agents",
        history_variable_name="history",
    ),
)

Gli agenti non sono attualmente disponibili in Java.

Terminazione della chat

Nella chiamata a più turni, la strategia di terminazione determina quando si verifica il turno finale. Questa strategia garantisce che la conversazione termini al punto appropriato.

Questa strategia è definita da una classe base che può essere estesa per implementare comportamenti personalizzati personalizzati in base a specifiche esigenze. Per praticità, sono disponibili anche strategie di selezione predefinite serverali, offrendo approcci pronti all'uso per definire i criteri di terminazione per le conversazioni di Chat agente.

API Strategia di selezione .NET:

// Initialize a Kernel with a chat-completion service
Kernel kernel = ...;

// Create the agents
ChatCompletionAgent writerAgent =
    new()
    {
        Name = "Writer",
        Instructions = "<writer instructions>",
        Kernel = kernel
    };

ChatCompletionAgent reviewerAgent =
    new()
    {
        Name = "Reviewer",
        Instructions = "<reviewer instructions>",
        Kernel = kernel
    };

// Define a kernel function for the selection strategy
KernelFunction terminationFunction =
    AgentGroupChat.CreatePromptFunctionForStrategy(
        $$$"""
        Determine if the reviewer has approved.  If so, respond with a single word: yes

        History:
        {{$history}}
        """,
        safeParameterNames: "history");

// Define the termination strategy
KernelFunctionTerminationStrategy terminationStrategy = 
  new(selectionFunction, kernel)
  {
      // Only the reviewer may give approval.
      Agents = [reviewerAgent],
      // Parse the function response.
      ResultParser = (result) => 
        result.GetValue<string>()?.Contains("yes", StringComparison.OrdinalIgnoreCase) ?? false,
      // The prompt variable name for the history argument.
      HistoryVariableName = "history",
      // Save tokens by not including the entire history in the prompt
      HistoryReducer = new ChatHistoryTruncationReducer(1),
      // Limit total number of turns no matter what
      MaximumIterations = 10,
};

// Create a chat using the defined termination strategy.
AgentGroupChat chat =
    new(writerAgent, reviewerAgent)
    {
        ExecutionSettings = new() { TerminationStrategy = terminationStrategy }
    };

REVIEWER_NAME = "Reviewer"
WRITER_NAME = "Writer"

agent_reviewer = ChatCompletionAgent(
    service_id=REVIEWER_NAME,
    kernel=kernel,
    name=REVIEWER_NAME,
    instructions="<instructions>",
)

agent_writer = ChatCompletionAgent(
    service_id=WRITER_NAME,
    kernel=kernel,
    name=WRITER_NAME,
    instructions="<instructions>",
)

termination_function = KernelFunctionFromPrompt(
    function_name="termination",
    prompt="""
    Determine if the copy has been approved.  If so, respond with a single word: yes

    History:
    {{$history}}
    """,
)

chat = AgentGroupChat(
    agents=[agent_writer, agent_reviewer],
    termination_strategy=KernelFunctionTerminationStrategy(
        agents=[agent_reviewer],
        function=termination_function,
        kernel=_create_kernel_with_chat_completion("termination"),
        result_parser=lambda result: str(result.value[0]).lower() == "yes",
        history_variable_name="history",
        maximum_iterations=10,
    ),
)

Gli agenti non sono attualmente disponibili in Java.

Reimpostazione dello stato di completamento della chat

Indipendentemente dal fatto che la chat del gruppo di agenti venga richiamata usando l'approccio a turno singolo o multi-turno, lo stato della chat del gruppo di agenti viene aggiornato per indicare che viene completato una volta soddisfatti i criteri di terminazione. Ciò garantisce che il sistema riconosca quando una conversazione è stata completata. Per continuare a usare un'istanza di Chat del gruppo di agenti dopo aver raggiunto lo stato Completato , questo stato deve essere reimpostato per consentire ulteriori interazioni. Senza reimpostazione, non saranno possibili interazioni aggiuntive o risposte dell'agente.

Nel caso di una chiamata a più turni che raggiunge il limite massimo di turni, il sistema interromperà la chiamata dell'agente, ma non contrassegnerà l'istanza come completata. Ciò consente di estendere la conversazione senza dover reimpostare lo stato completamento .

// Define an use chat
AgentGroupChat chat = ...;

// Evaluate if completion is met and reset.
if (chat.IsComplete) 
{
  // Opt to take action on the chat result...

  // Reset completion state to continue use
  chat.IsComplete = false;
}
# Define a group chat
chat = AgentGroupChat()

# Evaluate if completion is met and reset
if chat.is_complete:
    # Reset completion state to continue use
    chat.is_complete = False

Gli agenti non sono attualmente disponibili in Java.

Cancellare lo stato completo della conversazione

Al termine dell'uso di una chat di Agent in cui è stato partecipato un Assistente open AI, potrebbe essere necessario eliminare il thread remoto associato all'assistente. Agent Chat supporta la reimpostazione o la cancellazione dell'intero stato della conversazione, che include l'eliminazione di qualsiasi definizione di thread remoto. Ciò garantisce che nessun dato di conversazione residuo rimanga collegato all'assistente al termine della chat.

Una reimpostazione completa non rimuove gli agenti che avevano aggiunto la chat dell'agente e lascia la chat dell'agente in uno stato in cui può essere riutilizzato. Ciò consente la continuazione delle interazioni con gli stessi agenti senza dover reinizializzare le interazioni, rendendo le conversazioni future più efficienti.

// Define an use chat
AgentGroupChat chat = ...;

// Clear the all conversation state
await chat.ResetAsync();
# Define a group chat
chat = AgentGroupChat()

# Clear the conversation state
await chat.reset()

Gli agenti non sono attualmente disponibili in Java.

Procedure

Per un esempio end-to-end per l'uso di Agent Group Chat for Agent Collaboration, vedere: