Exploration de la collaboration des agents dans AgentChat
Important
Cette fonctionnalité est à l’étape expérimentale. Les fonctionnalités à ce stade sont toujours en cours de développement et soumises à des modifications avant de passer à la phase de préversion ou de version candidate.
La documentation détaillée de l’API relative à cette discussion est disponible à l’adresse suivante :
Les agents sont actuellement indisponibles en Java.
Qu’est-ce que AgentChat
?
AgentChat
fournit une infrastructure qui permet l’interaction entre plusieurs agents, même s’ils sont de différents types. Cela permet à un ChatCompletionAgent
et à un OpenAIAssistantAgent
de travailler ensemble au sein de la même conversation.
AgentChat
définit également des points d’entrée pour lancer la collaboration entre les agents, qu’il s’agisse de réponses multiples ou d’une réponse d’agent unique.
En tant que classe abstraite, AgentChat
peuvent être sous-classés pour prendre en charge des scénarios personnalisés.
Une sous-classe, AgentGroupChat
, offre une implémentation concrète de AgentChat
, à l’aide d’une approche basée sur une stratégie pour gérer la dynamique des conversations.
Création d’un AgentGroupChat
Pour créer un AgentGroupChat
, vous pouvez soit spécifier les agents participants, soit créer une conversation vide puis ajouter des agents participants. La configuration des paramètres de conversation et des stratégies est également effectuée lors de l'initialisation AgentGroupChat
. Ces paramètres définissent la façon dont la dynamique de conversation fonctionne au sein du groupe.
Remarque : Les paramètres de conversation par défaut entraînent une conversation limitée à une seule réponse. Consultez le comportement
AgentChat
pour plus d’informations sur la configuration des paramètres de discussion.
Création d’un AgentGroupChat
avec un 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])
Les agents sont actuellement indisponibles en Java.
Ajout d’un Agent
à un 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)
Les agents sont actuellement indisponibles en Java.
Utilisation de AgentGroupChat
AgentChat
prend en charge deux modes d’opération : Single-Turn
et Multi-Turn
. Dans single-turn
, un agent spécifique est désigné pour fournir une réponse. Dans multi-turn
, tous les agents de la conversation répondent tour à tour jusqu'à ce qu'un critère de terminaison soit atteint. Dans les deux modes, les agents peuvent collaborer en répondant les uns aux autres pour atteindre un objectif défini.
Apporter une contribution
L’ajout d’un message d’entrée à un AgentChat
suit le même modèle qu’un objet ChatHistory
.
AgentGroupChat chat = new();
chat.AddChatMessage(new ChatMessageContent(AuthorRole.User, "<message content>"));
chat = AgentGroupChat()
await chat.add_chat_message(message="<message content>")
Les agents sont actuellement indisponibles en Java.
Invocation unique de l'agent
Dans un appel à plusieurs tour, le système doit décider quel agent répond ensuite et quand la conversation doit se terminer. En revanche, un appel à un seul tour retourne simplement une réponse de l’agent spécifié, ce qui permet à l’appelant de gérer directement la participation de l’agent.
Une fois qu’un agent participe au AgentChat
par le biais d’un appel à un seul tour, il est ajouté à l’ensemble d’agents éligibles pour l’appel à plusieurs tours.
// 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)
Les agents sont actuellement indisponibles en Java.
Appel de l’agent en plusieurs étapes
Bien que la collaboration entre agents exige qu’un système soit en place, qui non seulement détermine quel agent doit répondre à chaque tour, mais évalue également quand la conversation a atteint son objectif prévu, lancer la collaboration à plusieurs tours reste simple.
Les réponses de l’agent sont retournées de manière asynchrone à mesure qu’elles sont générées, ce qui permet à la conversation de se dérouler en temps réel.
Remarque : dans les sections suivantes, la sélection de l’agent et l’arrêt de conversation, vous allez examiner en détail les paramètres d’exécution. Les paramètres d’exécution par défaut utilisent la sélection séquentielle ou le tour par tour et limitent la participation de l’agent à un tour unique.
API Paramètres d’exécution .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)
Les agents sont actuellement indisponibles en Java.
Accès à l’historique des conversations
L'historique des conversations AgentChat
est toujours accessible, même si les messages sont remis via le schéma d'invocation. Cela garantit que les échanges passés restent disponibles tout au long de la conversation.
Remarque : Le message le plus récent est fourni en premier (ordre décroissant : le plus récent au plus ancien).
// 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()
Les agents sont actuellement indisponibles en Java.
Étant donné que différents types ou configurations d’agent peuvent conserver leur propre version de l’historique des conversations, l’historique spécifique de l’agent est également disponible en spécifiant un agent. (Par exemple : OpenAIAssistant
et 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)
Les agents sont actuellement indisponibles en Java.
Définition du comportement de AgentGroupChat
La collaboration entre les agents pour résoudre des tâches complexes est un modèle agentique principal. Pour utiliser efficacement ce modèle, un système doit être en place qui détermine non seulement l’agent qui doit répondre à chaque tour, mais également évaluer quand la conversation a atteint son objectif prévu. Cela nécessite la gestion de la sélection de l’agent et l’établissement de critères clairs pour l’arrêt de conversation, ce qui garantit une coopération transparente entre les agents vers une solution. Ces deux aspects sont régis par la propriété Execution Settings .
Les sections suivantes, sélection de l’agent et arrêt de conversation, examinent en détail ces considérations.
Sélection d'agent
Lors d'une invocation à tours multiples, la sélection de l'agent est guidée par une stratégie de sélection. Cette stratégie est définie par une classe de base qui peut être étendue pour implémenter des comportements personnalisés adaptés à des besoins spécifiques. Pour plus de commodité, deux stratégies de sélection concrètes prédéfinies sont également disponibles, offrant des approches prêtes à l’emploi pour la gestion de la sélection de l’agent pendant les conversations.
Si l'on connaît l'agent initial, il peut être spécifié de manière à toujours prendre le premier tour. Un réducteur d’historique peut également être utilisé pour limiter l’utilisation des jetons lors de l’utilisation d’une stratégie basée sur un KernelFunction
.
API de stratégie de sélection .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",
),
)
Les agents sont actuellement indisponibles en Java.
Arrêt de conversation
En appel multiple, la Stratégie de terminaison détermine quand le tour final a lieu. Cette stratégie garantit que la conversation se termine au point approprié.
Cette stratégie est définie par une classe de base qui peut être étendue pour implémenter des comportements personnalisés adaptés à des besoins spécifiques. Pour plus de commodité, plusieurs stratégies de sélection concrètes prédéfinies sont également disponibles, offrant des approches prêtes à l’emploi pour définir des critères d’arrêt pour une conversation AgentChat
.
API de stratégie de sélection .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,
),
)
Les agents sont actuellement indisponibles en Java.
Réinitialisation de l’état de complétion de chat
Que AgentGroupChat
soit invoquée par l'approche à tour unique ou multitour, l'état de la AgentGroupChat
est mis à jour pour indiquer qu'elle est terminé une fois le critère d'arrêt rempli. Cela garantit que le système reconnaît lorsqu’une conversation est entièrement terminée. Pour continuer à utiliser une instance AgentGroupChat
une fois qu’elle a atteint l’état terminé terminé, cet état doit être réinitialisé pour permettre d’autres interactions. Sans réinitialisation, des interactions supplémentaires ou des réponses d’agent ne seront pas possibles.
Dans le cas d’un appel à plusieurs tour qui atteint la limite maximale de tour, le système cessera l’appel de l’agent, mais ne marquera pas l’instance comme terminée. Cela permet d’étendre la conversation sans avoir à réinitialiser l’état d’achèvement .
// 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
Les agents sont actuellement indisponibles en Java.
Effacer l’état entier de la conversation
Lorsque vous avez terminé l’utilisation d’un AgentChat
où une OpenAIAssistant
a participé, il peut être nécessaire de supprimer le thread de distant associé à l’assistant .
AgentChat
prend en charge la réinitialisation ou l’effacement de l’état de conversation entier, ce qui inclut la suppression de toute définition de thread de distante de. Cela garantit qu’aucune donnée de conversation résiduelle n’est liée à l’Assistant une fois la conversation conclue.
Une réinitialisation complète ne supprime pas les agents qui ont rejoint le AgentChat
et laisse le AgentChat
dans un état où il peut être réutilisé. Cela permet la continuation des interactions avec les mêmes agents sans avoir à les réinitialiser, ce qui rend les conversations futures plus efficaces.
// 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()
Les agents sont actuellement indisponibles en Java.
Procédure
Pour obtenir un exemple de bout en bout concernant l'utilisation de AgentGroupChat
pour la collaboration Agent
, consultez :