Freigeben über


Erforschung der Zusammenarbeit von Agenten in AgentChat

Von Bedeutung

Dieses Feature befindet sich in der experimentellen Phase. Features in dieser Phase befinden sich in der Entwicklung und können sich ändern, bevor Sie zur Vorschau- oder Veröffentlichungskandidatenstufe wechseln.

Detaillierte API-Dokumentation zu dieser Diskussion finden Sie unter:

Das Feature ist derzeit in Java nicht verfügbar.

Was ist AgentChat?

AgentChat bietet ein Framework, das die Interaktion zwischen mehreren Agents ermöglicht, auch wenn sie von unterschiedlichen Typen sind. Dies ermöglicht es, dass ein ChatCompletionAgent und ein OpenAIAssistantAgent innerhalb derselben Unterhaltung zusammenarbeiten. AgentChat definiert auch Einstiegspunkte zum Initiieren der Zusammenarbeit zwischen Agents, ob über mehrere Antworten oder eine einzelne Agentantwort.

Als abstrakte Klasse können AgentChat unterklassigt werden, um benutzerdefinierte Szenarien zu unterstützen.

Eine solche Unterklasse, AgentGroupChat, bietet eine konkrete Implementierung von AgentChatunter Verwendung eines strategiebasierten Ansatzes zur Steuerung der Gesprächsdynamik.

Erstellen eines AgentGroupChat

Um eine AgentGroupChatzu erstellen, können Sie entweder die teilnehmenden Agenten angeben oder einen leeren Chat erstellen und anschließend Agent-Teilnehmer hinzufügen. Das Konfigurieren der Chat-Einstellungen und Strategien erfolgt auch während der Initialisierung. Diese Einstellungen definieren, wie die Gesprächsdynamik innerhalb der Gruppe wirken wird.

Hinweis: Die Standard-Chat-Settings führen zu einer Unterhaltung, die auf eine einzelne Antwort beschränkt ist. Weitere Informationen zum Konfigurieren von Chateinstellungen finden Sie unter AgentChat "Verhalten ".

Erstellung eines AgentGroupChat mit 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])

Das Feature ist derzeit in Java nicht verfügbar.

Hinzufügen eines Agent zu einem 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)

Das Feature ist derzeit in Java nicht verfügbar.

Verwenden von AgentGroupChat

AgentChat unterstützt zwei Betriebsmodi: Single-Turn und Multi-Turn. In single-turnwird ein bestimmter Agent dafür benannt, eine Antwort zu geben. In multi-turnwechseln sich alle Agenten im Gespräch ab, zu antworten, bis ein Beendigungskriterium erfüllt ist. In beiden Modi können Agents zusammenarbeiten, indem sie auf ein definiertes Ziel reagieren.

Bereitstellen von Eingaben

Das Hinzufügen einer Eingabenachricht zu einem AgentChat folgt demselben Muster wie bei einem ChatHistory-Objekt.

AgentGroupChat chat = new();

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

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

Das Feature ist derzeit in Java nicht verfügbar.

Aufruf des Agenten für einen einzelnen Durchgang

Bei einem Multi-Turn-Aufruf muss das System entscheiden, welcher Agent als Nächstes antwortet und wann die Unterhaltung beendet werden soll. Im Gegensatz dazu liefert ein Single-Turn-Aufruf einfach eine Rückmeldung des entsprechenden Agents, sodass der Anrufer die Agentbeteiligung direkt steuern kann.

Nachdem ein Agent an einem AgentChat durch einen einzelnen Anruf teilnimmt, wird er der Gruppe von Agenten hinzugefügt, die für mehrturn-Aufrufe berechtigt sind.

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

Das Feature ist derzeit in Java nicht verfügbar.

Aufruf eines Mehrdurchlauf-Agenten

Während die Agentzusammenarbeit erfordert, dass ein System vorhanden sein muss, das nicht nur bestimmt, welcher Agent während jeder Reihe reagieren soll, sondern auch bewertet, wann die Unterhaltung ihr beabsichtigtes Ziel erreicht hat, bleibt das Initiieren der mehrstufigen Zusammenarbeit einfach.

Agentantworten werden asynchron zurückgegeben, während sie generiert werden, sodass sich die Unterhaltung in Echtzeit entfalten kann.

Hinweis: In den folgenden Abschnitten wird die Agentauswahl und die Beendigung des Chats ausführlich in die Ausführungseinstellungen eingetaucht. Die Standard-Ausführungseinstellungen verwenden sequenzielle oder Round-Robin-Auswahl und beschränken die Agentbeteiligung auf eine einzelne Runde.

.NET-Ausführungseinstellungen-API: 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)

Das Feature ist derzeit in Java nicht verfügbar.

Zugreifen auf den Chatverlauf

Auf den AgentChat Gesprächsverlauf kann immer zugegriffen werden, selbst wenn Nachrichten über das Aufrufmuster übermittelt werden. Dadurch wird sichergestellt, dass vergangene Austausch während der gesamten Unterhaltung verfügbar bleiben.

Hinweis: Die neueste Nachricht wird zuerst bereitgestellt (absteigende Reihenfolge: neueste bis älteste).

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

Das Feature ist derzeit in Java nicht verfügbar.

Da verschiedene Agenttypen oder -konfigurationen möglicherweise ihre eigene Version des Unterhaltungsverlaufs beibehalten können, ist der agentspezifische Verlauf auch verfügbar, indem ein Agent angegeben wird. (Beispiel: OpenAIAssistant im Vergleich zu 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)

Das Feature ist derzeit in Java nicht verfügbar.

Definition des AgentGroupChat-Verhaltens

Die Zusammenarbeit zwischen Agents zur Lösung komplexer Aufgaben ist ein zentrales agentisches Muster. Um dieses Muster effektiv zu verwenden, muss ein System vorhanden sein, das nicht nur bestimmt, welcher Agent während jeder Drehung reagieren soll, sondern auch bewertet, wenn die Unterhaltung ihr beabsichtigtes Ziel erreicht hat. Dies erfordert die Verwaltung der Agentauswahl und die Festlegung klarer Kriterien für die Beendigung von Unterhaltungen, um eine nahtlose Zusammenarbeit zwischen den Agenten zu einer Lösung sicherzustellen. Beide Aspekte unterliegen der Eigenschaft "Ausführungseinstellungen".

In den folgenden Abschnitten, agent Selection and Chat Termination, werden diese Überlegungen ausführlich erläutert.

Agent-Auswahl

Bei mehrstufigen Aufrufen wird die Agentauswahl durch eine Auswahlstrategie gesteuert. Diese Strategie wird durch eine Basisklasse definiert, die erweitert werden kann, um benutzerdefinierte Verhaltensweisen zu implementieren, die auf bestimmte Anforderungen zugeschnitten sind. Zur Vereinfachung stehen auch zwei vordefinierte konkrete Auswahlstrategien zur Verfügung, die einsatzbereite Ansätze für die Behandlung der Agentauswahl während Unterhaltungen bieten.

Wenn bekannt, kann ein Erstagent angegeben werden, um immer den ersten Zug zu machen. Ein Verlaufsminderer kann auch verwendet werden, um die Tokennutzung zu begrenzen, wenn eine Strategie, die auf KernelFunction basiert, verwendet wird.

.NET Auswahlstrategie-API:

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

Python-Auswahlstrategie-API:

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",
    ),
)

Das Feature ist derzeit in Java nicht verfügbar.

Beendigung des Chats

Beim Multi-Turn-Aufruf bestimmt die Termination Strategy, wann die letzte Runde stattfindet. Diese Strategie stellt sicher, dass die Unterhaltung an dem entsprechenden Punkt endet.

Diese Strategie wird durch eine Basisklasse definiert, die erweitert werden kann, um benutzerdefinierte Verhaltensweisen zu implementieren, die auf bestimmte Anforderungen zugeschnitten sind. Zur Vereinfachung stehen auch mehrere vordefinierte konkrete Auswahlstrategien zur Verfügung, die sofort einsetzbare Ansätze zum Definieren von Beendigungskriterien für Unterhaltungen AgentChat bieten.

.NET-Beendigungsstrategie-API:

// 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(terminationFunction, 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 }
    };

Python-Beendigungsstrategie-API:

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

Das Feature ist derzeit in Java nicht verfügbar.

Zurücksetzen des Chat-Abschlussstatus

Unabhängig davon, ob AgentGroupChat der Single-Turn- oder der Multi-Turn-Ansatz aufgerufen wird, wird der Status von AgentGroupChat aktualisiert, um anzugeben, dass dieser abgeschlossen ist, sobald die Beendigungskriterien erfüllt sind. Dadurch wird sichergestellt, dass das System erkennt, wann eine Unterhaltung vollständig abgeschlossen wurde. Um eine AgentGroupChat Instanz weiterhin zu verwenden, nachdem sie den Status Abgeschlossen erreicht hat, muss dieser Zustand zurückgesetzt werden, um weitere Interaktionen zuzulassen. Ohne Zurücksetzen sind zusätzliche Interaktionen oder Agentantworten nicht möglich.

Bei einem mehrstufigen Aufruf, der die maximale Anzahl an Dialogschritten erreicht, wird der Agentenaufruf beendet, die Instanz jedoch nicht als abgeschlossen markiert. Dies ermöglicht die Möglichkeit, die Unterhaltung zu erweitern, ohne den Status "Abschluss" zurückzusetzen.

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

Das Feature ist derzeit in Java nicht verfügbar.

Zustand des kompletten Gesprächs löschen

Wenn die Verwendung eines AgentChat abgeschlossen ist, an dem ein OpenAIAssistant teilgenommen hat, kann es notwendig sein, den dem Assistenten zugeordneten Fern-Thread zu löschen. AgentChat unterstützt das Zurücksetzen oder Löschen des gesamten Unterhaltungszustands, einschließlich des Löschens einer Remotethreaddefinition. Dadurch wird sichergestellt, dass am Ende des Chats keine Restgesprächsdaten mit dem Assistenten verknüpft bleiben.

Bei einer vollständigen Zurücksetzung werden die Agenten, die dem AgentChat beigetreten sind, nicht entfernt, und der AgentChat bleibt in einem Zustand, in dem er wiederverwendet werden kann. Dies ermöglicht die Fortsetzung von Interaktionen mit denselben Agents, ohne sie erneut zu initialisieren und zukünftige Unterhaltungen effizienter zu gestalten.

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

Das Feature ist derzeit in Java nicht verfügbar.

Vorgehensweise

Ein durchgängiges Beispiel zur Nutzung von AgentGroupChat zur Agent-Zusammenarbeit finden Sie unter: