次の方法で共有


AgentChat でのエージェントコラボレーションの探索

Von Bedeutung

この機能は実験段階にあります。 この段階の機能は開発中であり、プレビューまたはリリース候補ステージに進む前に変更される可能性があります。

この説明に関連する詳細な API ドキュメントは、次のサイトで入手できます。

機能は現在 Java では使用できません。

AgentChat の概要

AgentChat は、異なる種類のエージェントであっても、複数のエージェント間の対話を可能にするフレームワークを提供します。 これにより、ChatCompletionAgentOpenAIAssistantAgent が同じ会話内で連携できるようになります。 AgentChat では、複数の応答または単一のエージェント応答を使用して、エージェント間のコラボレーションを開始するためのエントリ ポイントも定義します。

抽象クラスとして、カスタム シナリオをサポートするために AgentChat をサブクラス化できます。

そのようなサブクラスの 1 つである AgentGroupChatでは、会話のダイナミクスを管理するための戦略ベースのアプローチを使用して、AgentChatの具体的な実装を提供します。

AgentGroupChat を作成する

AgentGroupChatを作成するには、参加するエージェントを指定するか、空のチャットを作成してから、エージェント参加者を追加します。 Chat-Settings と戦略の構成は、 AgentGroupChat 初期化中にも実行されます。 これらの設定は、会話のダイナミクスがグループ内でどのように機能するかを定義します。

注: 既定の Chat-Settings では、会話は 1 つの応答に制限されます。 チャット設定の構成の詳細については、「 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 では使用できません。

AgentAgentGroupChat を追加する:

// 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-TurnMulti-Turnの 2 つの操作モードがサポートされています。 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 では使用できません。

シングルターン エージェント呼び出し

複数ターンの呼び出しでは、システムは次に応答するエージェントと会話を終了するタイミングを決定する必要があります。 これに対し、1 ターン呼び出しでは、指定したエージェントからの応答が返されるだけで、呼び出し元はエージェントの参加を直接管理できます。

エージェントは、1 ターン呼び出しを通じて 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 では使用できません。

マルチターン エージェントの呼び出し

エージェントコラボレーションでは、各ターンで応答するエージェントを決定するだけでなく、会話が意図した目標を達成したタイミングを評価するシステムが必要ですが、マルチターンコラボレーションの開始は簡単です。

エージェントの応答は、生成されると非同期的に返され、会話をリアルタイムで展開できます。

注: 次のセクション、エージェントの選択及びチャット終了では、実行設定について詳しく掘り下げて説明します。 既定の実行設定では、シーケンシャルまたはラウンド ロビン選択が採用され、エージェントの参加が 1 ターンに制限されます。

.NET 実行設定 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)

機能は現在 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 では使用できません。

エージェントの種類や構成が異なると、独自のバージョンの会話履歴が保持される可能性があるため、エージェントを指定することで、エージェント固有の履歴も使用できます。 (例: OpenAIAssistantChatCompletionAgent

// 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 動作の定義

複雑なタスクを解決するためのエージェント間のコラボレーションは、エージェントのコア パターンです。 このパターンを効果的に使用するには、各ターンで応答するエージェントを決定するだけでなく、会話が目的の目標を達成したタイミングを評価するシステムが必要です。 そのためには、エージェントの選択を管理し、会話終了の明確な基準を確立し、ソリューションに向けたエージェント間のシームレスな協力を確保する必要があります。 これらの両方の側面は、実行設定プロパティによって管理されます。

以降のセクション Agent SelectionChat Termination では、これらの考慮事項について詳しく説明します。

エージェントの選択

複数ターンの呼び出しでは、エージェントの選択は選択戦略によってガイドされます。 この戦略は、特定のニーズに合わせて調整されたカスタム動作を実装するために拡張できる基底クラスによって定義されます。 便宜上、2 つの定義済みの具象選択戦略も利用でき、会話中にエージェントの選択を処理するためのすぐに使用できるアプローチが提供されます。

既知の場合は、最初のエージェントが常に最初のターンを実行するように指定できます。 KernelFunctionに基づく戦略を使用する場合は、履歴レジューサーを使用してトークンの使用を制限することもできます。

.NET 選択戦略 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選択戦略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",
    ),
)

機能は現在 Java では使用できません。

チャット終了

複数ターンの呼び出しでは、終了戦略によって最終ターンがいつ行われるかが決まります。 この戦略により、会話は適切な時点で終了します。

この戦略は、特定のニーズに合わせて調整されたカスタム動作を実装するために拡張できる基底クラスによって定義されます。 便宜上、定義済みの具体的な選択戦略がいくつか用意されており、 AgentChat 会話の終了条件を定義するためのすぐに使用できるアプローチが提供されます。

.NET 終了戦略 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 終了戦略 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,
    ),
)

機能は現在 Java では使用できません。

チャット完了状態のリセット

AgentGroupChatが単一ターンまたは複数ターンのどちらの方法を使用して呼び出されるかに関係なく、終了条件が満たされた後に完了したことを示すようにAgentGroupChatの状態が更新されます。 これにより、会話が完全に終了したときにシステムが認識されるようになります。 AgentGroupChat インスタンスが Completed 状態に達した後も引き続き使用するには、この状態をリセットして、さらに対話できるようにする必要があります。 リセットしないと、追加の対話やエージェントの応答を行えなくなります。

複数ターン呼び出しが最大ターン制限に達した場合、システムはエージェントの呼び出しを停止しますが、インスタンスを完了としてマークしません。 これにより、完了状態をリセットしなくても会話を拡張できます。

// 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 を使用するエンド ツー エンドの例については、次を参照してください。

  • AgentGroupChat を使用してエージェントコラボレーションを調整する方法