Изучение совместной работы агентов в 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
SelectionStrategy
SequentialSelectionStrategy
KernelFunctionSelectionStrategy
Microsoft.SemanticKernel.Agents.History
// 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.
TerminationStrategy
RegexTerminationStrategy
KernelFunctionSelectionStrategy
KernelFunctionTerminationStrategy
AggregatorTerminationStrategy
Microsoft.SemanticKernel.Agents.History
// 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
см. здесь: