Поделиться через


Изучение совместной работы агентов в AgentChat

Важный

Эта функция находится на экспериментальном этапе. Функции на этом этапе по-прежнему находятся в стадии разработки и могут изменяться перед переходом к стадии предварительной версии или кандидатской версии.

Подробная документация по API, связанная с этим обсуждением, доступна по адресу:

Агенты в настоящее время недоступны в Java.

Что такое AgentChat?

AgentChat предоставляет платформу, которая обеспечивает взаимодействие между несколькими агентами, даже если они имеют разные типы. Это позволяет ChatCompletionAgent и OpenAIAssistantAgent работать вместе в рамках одной беседы. AgentChat также определяет точки входа для инициирования совместной работы между агентами, будь то через несколько ответов или один ответ агента.

В качестве абстрактного класса AgentChat можно подклассировать для поддержки пользовательских сценариев.

Один из таких подклассов, AgentGroupChat, предлагает конкретную реализацию AgentChat, используя стратегический подход к управлению динамикой диалога.

Создание объекта AgentGroupChat

Чтобы создать AgentGroupChat, можно указать участвующих агентов или создать пустой чат, а затем добавить агентов-участников. Настройка параметров чата и стратегий также выполняется во время инициализации AgentGroupChat. Эти настройки определяют, как будут функционировать динамика общения в рамках группы.

Примечание. Параметры чата по умолчанию приводят к беседе, которая ограничена одним ответом. Дополнительные сведения о настройке _Настроек чата см. в разделе "Поведение" AgentChat.

Создание AgentGroupChat с помощью Agent:

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

Агенты в настоящее время недоступны в Java.

Добавление Agent в AgentGroupChat:

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

Агенты в настоящее время недоступны в Java.

Использование AgentGroupChat

AgentChat поддерживает два режима работы: Single-Turn и Multi-Turn. В single-turnопределенный агент назначается для предоставления ответа. В multi-turnвсе агенты в беседе по очереди отвечают до тех пор, пока не будет выполнено условие завершения. В обоих режимах агенты могут совместно работать, отвечая друг другу на достижение определенной цели.

Предоставление входных данных

Добавление входного сообщения в AgentChat соответствует тому же шаблону, что и объект ChatHistory.

AgentGroupChat chat = new();

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

await chat.add_chat_message(message="<message content>")

Агенты в настоящее время недоступны в Java.

Вызов агента за один шаг

В многошаговом взаимодействии система должна решить, какой агент отвечает далее и когда беседа должна завершиться. В отличие от этого, одиночный вызов лишь возвращает ответ от указанного агента, что позволяет вызывающей стороне напрямую управлять участием агента.

После того как агент принимает участие в AgentChat через одноразовый вызов, он добавляется в набор агентов , доступных для многократного вызова.

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

Агенты в настоящее время недоступны в Java.

Многошаговый вызов агента

Хотя для совместной работы агентов требуется система, которая не только определяет, какой агент должен реагировать на каждом этапе, но и оценивает, когда достигнута поставленная цель в разговоре, начало многоэтапной совместной работы остается простым.

Ответы агента возвращаются асинхронно по мере их создания, что позволяет беседе разворачиваться в режиме реального времени.

Примечание: В следующих разделах Выбор агента и Завершение чата будут подробно обсуждаться Параметры выполнения. Параметры выполнения по умолчанию используют последовательный или циклический выбор и ограничивают участие агента только одним циклом.

API параметров выполнения .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)

Агенты в настоящее время недоступны в Java.

Доступ к журналу чата

История переписок AgentChat всегда доступна, даже если сообщения доставляются с помощью модели вызова. Это гарантирует, что прошлые обмены остаются доступными во время беседы.

Примечание. Самое новое сообщение предоставляется первым (порядок убывания: от новейшего к старым).

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

Агенты в настоящее время недоступны в Java.

Так как различные типы агентов или конфигурации могут поддерживать собственную версию журнала бесед, журнал конкретных агентов также доступен путем указания агента. (Например, OpenAIAssistant и ChatCompletionAgent.)

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

Агенты в настоящее время недоступны в Java.

Определение поведения AgentGroupChat

Совместная работа между агентами для решения сложных задач — это основной шаблон агента. Чтобы эффективно использовать этот шаблон, должна быть внедрена система, которая не только определяет, какой агент должен реагировать на каждом этапе, но и оценивает, когда беседа достигла своей цели. Для этого требуется управление выбором агента и установление четких критериев для завершения разговора, обеспечивающих беспрепятственное сотрудничество между агентами для достижения решения. Оба этих аспекта управляются свойством "Параметры выполнения".

В следующих разделах, выбор агента и завершение чата подробно рассматриваются эти рекомендации.

Выбор агента

При многоэтапном вызове выбор агента руководствуется стратегией выбора. Эта стратегия определяется базовым классом, который можно расширить для реализации пользовательских поведения, адаптированных к конкретным потребностям. Для удобства также доступны две стандартные конкретные стратегии выбора, предлагающие готовые подходы к использованию для обработки выбора агента во время бесед.

Если известно, начальный агент может быть указан для того, чтобы всегда брать первый ход. Кроме того, для ограничения использования токенов при использовании стратегии на основе KernelFunctionможет также применяться средство уменьшения журнала.

API выбора стратегии .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(
    kernel=kernel,
    name=REVIEWER_NAME,
    instructions="<instructions>",
)

agent_writer = ChatCompletionAgent(
    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",
    ),
)

Агенты в настоящее время недоступны в Java.

Завершение чата

В многоэтапном вызове Стратегия завершения определяет, когда осуществляется последний этап. Эта стратегия гарантирует, что беседа заканчивается в соответствующей точке.

Эта стратегия определяется базовым классом, который можно расширить для реализации пользовательских поведения, адаптированных к конкретным потребностям. Для удобства также доступны несколько стандартных конкретных стратегий выбора, предлагая готовые подходы для определения критериев завершения AgentChat бесед.

API выбора стратегии для .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(
    kernel=kernel,
    name=REVIEWER_NAME,
    instructions="<instructions>",
)

agent_writer = ChatCompletionAgent(
    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,
    ),
)

Агенты в настоящее время недоступны в Java.

Сброс состояния завершения чата

Независимо от того, вызывается ли AgentGroupChat с помощью одноэтапного или многоэтапного подхода, состояние AgentGroupChat обновляется, чтобы указать, что завершено после соблюдения условий завершения. Это гарантирует, что система распознает, когда беседа полностью завершена. Чтобы продолжить использование экземпляра AgentGroupChat после того, как он достиг состояния Завершено, необходимо сбросить это состояние, чтобы разрешить дальнейшее взаимодействие. Без сброса дополнительные взаимодействия или ответы агента будут невозможны.

В случае, когда многошаговый вызов достигает максимального предела, система прекратит вызов агента, но не будет отмечать экземпляр как завершенный. Это позволяет расширить разговор без необходимости сброса завершенного состояния.

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

Агенты в настоящее время недоступны в Java.

Очистить полное состояние беседы

После использования AgentChat, в которой участвовал OpenAIAssistant, может потребоваться удалить удалённый поток , связанный с помощником . AgentChat поддерживает сброс или очистку состояния всей беседы, включая удаление определения любого удаленного потока . Это гарантирует, что данные остаточной беседы не остаются связанными с помощником после завершения чата.

Полный сброс не удаляет агентов ,, присоединившихся к AgentChat, и оставляет AgentChat в состоянии, в котором его можно повторно использовать. Это позволяет продолжать взаимодействие с теми же агентами без необходимости повторно инициализировать их, что делает будущие беседы более эффективными.

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

Агенты в настоящее время недоступны в Java.

Инструкции

Полный пример использования AgentGroupChat для совместной работы Agent см. здесь: