Compartilhar via


Explorando a colaboração entre agentes no chat de agentes

Aviso

O do Kernel Agent semântico está em versão prévia e está sujeito a alterações.

A documentação detalhada da API relacionada a esta discussão está disponível em:

No momento, os agentes não estão disponíveis em Java.

O que é o bate-papo do agente?

O Chat do agente fornece uma estrutura que permite a interação entre vários agentes, mesmo que sejam de tipos diferentes. Isso possibilita que um Agente de Conclusão de Chat e um Agente Assistente do Open AI trabalhem juntos na mesma conversa. O Chat do agente também define pontos de entrada para iniciar a colaboração entre agentes, seja por meio de várias respostas ou de uma única resposta do agente.

Como uma classe abstrata, o Chat do Agente pode ser subclassificado para dar suporte a cenários personalizados.

Uma dessas subclasses, o Bate-papo em Grupo do Agente, oferece uma implementação concreta do Bate-papo do Agente, usando uma abordagem baseada em estratégia para gerenciar a dinâmica da conversa.

Criação de um chat de grupo de agentes

Para criar um bate-papo em grupo com agentes, você pode especificar os agentes participantes ou criar um bate-papo vazio e, posteriormente, adicionar participantes do agente. A configuração das configurações e estratégias de chat também é realizada durante a inicialização do chat de grupo do agente. Essas configurações definem como a dinâmica da conversa funcionará dentro do grupo.

Observação: as configurações de bate-papo padrão resultam em uma conversa limitada a uma única resposta. Consulte Comportamento do chat do agente para obter detalhes sobre como definir as configurações do _Chat.

Criação de bate-papo em grupo de agentes com agentes:

// 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])

No momento, os agentes não estão disponíveis em Java.

Adicionando agentes a um chat de grupo de agentes:

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

No momento, os agentes não estão disponíveis em Java.

Usando o bate-papo em grupo do agente

O Bate-papo do Agente oferece suporte a dois modos de operação: Turno Único e Turno Múltiplo. Em turno único, um agente específico é designado para fornecer uma resposta. Em vários turnos, todos os agentes na conversa se revezam respondendo até que um critério de rescisão seja atendido. Em ambos os modos, os agentes podem colaborar respondendo uns aos outros para atingir uma meta definida.

Fornecendo informações

A adição de uma mensagem de entrada a um chat do agente segue o mesmo padrão de um objeto de histórico de 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>"))

No momento, os agentes não estão disponíveis em Java.

Invocação de agente de turno único

Em uma invocação de vários turnos, o sistema deve decidir qual agente responde em seguida e quando a conversa deve terminar. Por outro lado, uma invocação de turno único simplesmente retorna uma resposta do agente especificado, permitindo que o chamador gerencie diretamente a participação do agente.

Depois que um agente participa do Chat do Agente por meio de uma invocação de turno único, ele é adicionado ao conjunto de agentes qualificados para invocação de vários turnos.

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

No momento, os agentes não estão disponíveis em Java.

Invocação de agente de vários turnos

Embora a colaboração do agente exija que haja um sistema que não apenas determine qual agente deve responder durante cada turno, mas também avalie quando a conversa atingiu o objetivo pretendido, iniciar a colaboração em vários turnos permanece simples.

As respostas do agente são retornadas de forma assíncrona à medida que são geradas, permitindo que a conversa se desdobre em tempo real.

Observação: nas seções a seguir, Seleção de agente e Encerramento de bate-papo se aprofundarão nas configurações de execução em detalhes. As configurações de execução padrão empregam seleção sequencial ou round-robin e limitam a participação do agente a um único turno.

API de configurações de execução do .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)

No momento, os agentes não estão disponíveis em Java.

Acessando o histórico de bate-papo

O histórico de conversas do Chat do agente está sempre acessível, mesmo que as mensagens sejam entregues por meio do padrão de invocação. Isso garante que as trocas anteriores permaneçam disponíveis durante toda a conversa.

Observação: a mensagem mais recente é fornecida primeiro (ordem decrescente: mais recente para a mais antiga).

// 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()

No momento, os agentes não estão disponíveis em Java.

Como diferentes tipos ou configurações de agente podem manter sua própria versão do histórico de conversas, o histórico específico do agente também está disponível especificando um agente. (Por exemplo: Abra o AI Assistant versus o Chat Completion Agent.)

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

No momento, os agentes não estão disponíveis em Java.

Definição do comportamento de chat de grupo do agente

A colaboração entre agentes para resolver tarefas complexas é um padrão agêntico central. Para usar esse padrão de forma eficaz, deve haver um sistema que não apenas determine qual agente deve responder durante cada turno, mas também avalie quando a conversa atingiu o objetivo pretendido. Isso requer o gerenciamento da seleção de agentes e o estabelecimento de critérios claros para o encerramento da conversa, garantindo uma cooperação perfeita entre os agentes em direção a uma solução. Ambos os aspectos são regidos pela propriedade Configurações de Execução .

As seções a seguir, Seleção de agente e Encerramento de chat, se aprofundarão nessas considerações em detalhes.

Seleção de Agente

Na invocação de vários turnos, a seleção de agentes é guiada por uma Estratégia de Seleção. Essa estratégia é definida por uma classe base que pode ser estendida para implementar comportamentos personalizados adaptados a necessidades específicas. Por conveniência, duas estratégias de seleção concretas predefinidas também estão disponíveis, oferecendo abordagens prontas para uso para lidar com a seleção de agentes durante as conversas.

Se conhecido, um agente inicial pode ser especificado para sempre fazer o primeiro turno. Um redutor de histórico também pode ser empregado para limitar o uso de token ao usar uma estratégia baseada em uma função de kernel.

API de estratégia de seleção do .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",
    ),
)

No momento, os agentes não estão disponíveis em Java.

Encerramento do bate-papo

Na invocação de vários turnos , a Estratégia de Rescisão determina quando o turno final ocorre. Essa estratégia garante que a conversa termine no ponto apropriado.

Essa estratégia é definida por uma classe base que pode ser estendida para implementar comportamentos personalizados adaptados a necessidades específicas. Por conveniência, várias estratégias de seleção concretas predefinidas também estão disponíveis, oferecendo abordagens prontas para uso para definir critérios de rescisão para conversas de bate-papo do agente.

API de estratégia de seleção do .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,
    ),
)

No momento, os agentes não estão disponíveis em Java.

Redefinindo o estado de conclusão do bate-papo

Independentemente de o Chat de Grupo do Agente ser invocado usando a abordagem de turno único ou de vários turnos, o estado do Chat de Grupo do Agente é atualizado para indicar que ele foi concluído assim que os critérios de rescisão forem atendidos. Isso garante que o sistema reconheça quando uma conversa foi totalmente concluída. Para continuar usando uma instância do Chat de Grupo do Agente depois que ela atingir o estado Concluído , esse estado deve ser redefinido para permitir mais interações. Sem redefinir, interações adicionais ou respostas do agente não serão possíveis.

No caso de uma invocação de vários turnos que atinja o limite máximo de turnos, o sistema interromperá a invocação do agente, mas não marcará a instância como concluída. Isso permite a possibilidade de estender a conversa sem a necessidade de redefinir o estado de conclusão .

// 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

No momento, os agentes não estão disponíveis em Java.

Limpar estado de conversa completa

Quando feito o uso de um bate-papo do agente em que um assistente do Open AI participou, pode ser necessário excluir o thread remoto associado ao assistente. O Chat do agente oferece suporte à redefinição ou limpeza de todo o estado da conversa, o que inclui a exclusão de qualquer definição de thread remota. Isso garante que nenhum dado residual da conversa permaneça vinculado ao assistente após a conclusão do bate-papo.

Uma redefinição completa não remove os agentes que ingressaram no Chat do agente e deixa o Chat do agente em um estado em que pode ser reutilizado. Isso permite a continuação das interações com os mesmos agentes sem a necessidade de reinicializá-los, tornando as conversas futuras mais eficientes.

// 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()

No momento, os agentes não estão disponíveis em Java.

Instruções

Para obter um exemplo completo de como usar o Chat de Grupo do Agente para colaboração do Agente , consulte: