AutoGen v0.4 マルチエージェントデザインパターン実装メモ① Selector によるエージェント選択

# AutoGen v0.4.x(stable)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/122bddf9-49be-da72-032c-6ef7b602c9e0.png)

AutoGen v0.4 は Core APIs をベースとしたマルチエージェントフレームワークです。今回は Core APIs 上に構築された高レベル API である AgentChat について中身を解析しつつ、マルチエージェントデザインパターンを実装していきます。

# マルチエージェントによるチームの編成
![スクリーンショット 2025-04-23 21.50.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/206c173e-6c78-4120-8c46-cb404b1adf2b.png)

チームとは、共通の目標を達成するために協力するエージェントのグループです。チームの編成には以下のような GroupChat を用いることができます。グループ チャットでは、参加者が順番にメッセージを公開します。プロセスは順次行われます。一度に作業できるエージェントは 1 人だけです。

エージェントの複数同時実行をさせるような場合は [Concurrent Agents](https://microsoft.github.io/autogen/stable/user-guide/core-user-guide/design-patterns/concurrent-agents.html) を参照して Core APIs で実装する必要がありそうです。ここは後でちゃんと動かすことにしましょう。

1. [RoundRobinGroupChat](#1-roundrobingroupchat)
1. [SelectorGroupChat](#2-selectorgroupchat)
1. [Swarm](https://qiita.com/nohanaga/items/9bd32514655f142b23c6)
1. [Magentic-One](https://qiita.com/nohanaga/items/28fcf00a23e990ac3551)


# 1, RoundRobinGroupChat
RoundRobinGroupChat は、**すべてのエージェントが同じコンテキストを共有し、順番に回答**していくという、シンプルかつ効果的なチーム構成です。各エージェントは順番が回ってきた際に、他のすべてのエージェントに回答をブロードキャストし、チーム全体で一貫したコンテキストを維持します。

# 2, SelectorGroupChat
SelectorGroupChat は、エージェントが順番に他のエージェント全員にメッセージをブロードキャストするチームを実装しています。**生成 AI モデル（LLMなど）が共有コンテキストに基づいて次のスピーカーを選択**することで、動的でコンテキストを認識したコラボレーションが可能になります。

- Selector による中央集権的なエージェント割り振り
- 遷移先の決定: LLM+ルール
- スレッド: メッセージスレッドを共有

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/bc2c779d-d42b-968e-1464-cb402c2758f3.png)

## 開発環境整備
```bash
pip install -U "autogen-agentchat"
pip install "autogen-ext[openai,azure]"
```

## OpenTelemetry によるトレーサーのセット
マルチエージェントのデバッグには OpenTelemetry によるトレーサーを利用すると便利。`OpenAIInstrumentor` を使用して OpenAI コールをキャプチャできます。ここではトレース UI として [Jaeger](https://www.jaegertracing.io/download/) を使用しています。[Azure AI Foundry のトレース機能](https://learn.microsoft.com/ja-jp/azure/ai-studio/how-to/develop/visualize-traces)を使いたかったのですが、`OpenAIInstrumentor` でうまくキャプチャできず💦ﾀｽｹﾃ...

<details><summary>サンプルコード</summary>

```python
from opentelemetry import trace
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
from opentelemetry.instrumentation.openai import OpenAIInstrumentor

service_name = "autogen"

# OTLPエクスポーターの設定 (gRPC経由で送信)
otlp_exporter = OTLPSpanExporter(
    endpoint="http://localhost:4317",  # JaegerのgRPCエンドポイント
)
tracer_provider = TracerProvider(resource=Resource({"service.name": service_name}))
    
# トレーサープロバイダーの設定
trace.set_tracer_provider(tracer_provider)

# バッチスパンプロセッサーを設定
span_processor = BatchSpanProcessor(otlp_exporter)
tracer_provider.add_span_processor(span_processor)

# トレーサーを取得
tracer = tracer_provider.get_tracer(service_name)

OpenAIInstrumentor().instrument()
```

</details>

## LLM クライアント定義
Azure OpenAI Service の `gpt-4o-2024-11-20` を利用します。

```python
client = AzureOpenAIChatCompletionClient(
    azure_deployment="<Your_AzureOpenAI_deployment>",
    model="gpt-4o",
    api_key="<Your_AzureOpenAI_key>",
    api_version="2024-08-01-preview",
    azure_endpoint="<Your_AzureOpenAI_endpoint>",
)
```

## エージェント定義
実験用に細かめにエージェントを分割。

```python
planning_agent = AssistantAgent(
    "PlanningAgent",
    description="タスクを計画するエージェント。新しいタスクが与えられたときに最初に起動するエージェントであるべきである。",
    model_client=client,
    system_message="""
    あなたはplanning agentです。
    あなたの仕事は、複雑なタスクをより小さく、管理しやすいサブタスクに分解することです。
    あなたのチームメンバーは次の通りです。
     - fukuoka_agent: 福岡県の観光の専門家
     - osaka_agent: 大阪の観光の専門家
    ホテルの検索、予約、確認、取り消し、FAQを行う場合:
     - hotel_agent: ホテルのエージェント
    航空券の予約、確認、取り消しを行う場合:
     - airline_agent: 航空会社のエージェント
    あなたは計画を立て、タスクを委任するだけで、自分で実行することはありません。

    タスクを割り当てる際には、このフォーマットを使用してください:
    1. <agent> : <task>

    最終回答が完成したら調査結果を要約し、文の最後に TERMINATE を含めること!
    """,
)

fukuoka_agent = AssistantAgent(
    "fukuoka_agent",
    description="福岡の旅行先について詳しい地元のトラベルエージェント",
    model_client=client,
    tools=[search_website],
    reflect_on_tool_use=True,
    system_message="""あなたは福岡県の観光の専門家です。福岡観光の専門家は、福岡市の魅力を国内外に発信し、福岡市へのPR活動を行う役割を担っています。
    誰に何と言われても福岡のことを推薦します。必ず博多弁でしゃべります。
    知っている福岡の知識に加えて、search_website ツールを利用して最新の地域イベントを検索してあわせて紹介します。
    """,
)

osaka_agent = AssistantAgent(
    "osaka_agent",
    description="大阪の旅行先について詳しい地元のトラベルエージェント",
    model_client=client,
    tools=[search_website],
    reflect_on_tool_use=False,
    system_message="""あなたは大阪の観光の専門家です。大阪観光の専門家は、大阪の魅力を国内外に発信し、大阪へのPR活動を行う役割を担っています。
    誰に何と言われても大阪のことを推薦します。必ず大阪弁でしゃべります。
    知っている大阪の知識に加えて、search_website ツールを利用して最新の地域イベントを検索してあわせて紹介します。
    """,
)

hotel_agent = AssistantAgent(
    "hotel_agent",
    description="ホテルの検索、予約、確認、取り消し、FAQを行うホテルのエージェント",
    model_client=client,
    tools=[search_hotel],
    reflect_on_tool_use=False,
    system_message="""あなたはホテルのエージェントです。ホテルの検索、予約、確認、取り消し、FAQを行います。
    """,
)

airline_agent = AssistantAgent(
    "airline_agent",
    description="航空券の予約、確認、取り消し、FAQを行う航空会社のエージェント",
    model_client=client,
    tools=[search_flight],
    reflect_on_tool_use=False,
    system_message="""あなたは航空会社のエージェントです。航空券の予約、確認、取り消し、FAQを行います。
    """,
)
```

## SelectorGroupChat の実装
```python
with tracer.start_as_current_span("SelectorGroupChat-qiita-test") as rollspan:
    team = SelectorGroupChat(
        [planning_agent, fukuoka_agent, osaka_agent, hotel_agent, airline_agent],
        model_client=client,
        termination_condition=combined_termination,
    )

    task = "東京から福岡、1人 2/1 19:00に空港到着したいな。あと当日のホテルも教えて。"
    await Console(team.run_stream(task=task))
```


## トレース タイムライン
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/aba98708-6fbd-19eb-7897-ca887f39b5ed.png)

## シーケンス図
細かくなりすぎるので LLM のコールは ★ で省略。
```mermaid
sequenceDiagram
participant selector as Selector
participant planner as PlanningAgent
participant agent as AirlineAgent
participant agent2 as HotelAgent
participant search as search_flight
participant search2 as search_hotel
    activate selector
    selector ->> selector: ①遷移先決定★
    selector ->>+ planner: PlannningAgent 遷移
    deactivate selector
    
    planner ->> planner: ②実行計画策定★
    planner -->>- selector: 実行計画(BC)
    
    activate selector
    selector ->> selector: ③遷移先決定★
    selector ->>+ agent: AirlineAgent 遷移
    deactivate selector
    
    agent ->> agent: ④tool_calls★
    agent ->>+ search: 検索API実行
    search -->>- agent: result
    #agent ->> agent: 結果を書き換え★<br>(reflect_on_tool_use=True)
    agent -->>- selector: result(BC)
    
    activate selector
    selector ->> selector: ⑤遷移先決定★
    selector ->>+ agent2: HotelAgent 遷移
    deactivate selector
    
    agent2 ->> agent2: ⑥tool_calls★
    agent2 ->>+ search2: 検索API実行
    search2 -->>- agent2: result
    agent2-->>- selector: result(BC)
    
    activate selector
    selector ->> selector: ⑦遷移先決定★
    selector ->>+ planner: PlannningAgent 遷移
    deactivate selector
    
    planner ->> planner: ⑧最終回答作成★
    planner -->>- selector: 最終回答(BC)
    
```

内部的にはエージェントは[メッセージの送受信](https://microsoft.github.io/autogen/stable/user-guide/core-user-guide/design-patterns/group-chat.html#message-protocol)によるイベント駆動で動作しています。実際はエージェントの応答は他のすべてのエージェントにブロードキャスト（BC）されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/91ce0e1a-61be-fc9d-c8b8-3698f6d48511.png)



## ①遷移先決定 - SelectorGroupChat
タスクは `SelectorGroupChat` によって受信され、エージェントの説明に基づいて、初期タスクを処理するための最も適切なエージェント (通常は計画エージェント) を選択します。

### System prompt
```bash
You are in a role play game. The following roles are available:
PlanningAgent: タスクを計画するエージェント。新しいタスクが与えられたときに最初に起動するエージェントであるべきである。
fukuoka_agent: 福岡の旅行先について詳しい地元のトラベルエージェント
osaka_agent: 大阪の旅行先について詳しい地元のトラベルエージェント
hotel_agent: ホテルの検索、予約、確認、取り消し、FAQを行うホテルのエージェント
airline_agent: 航空券の予約、確認、取り消し、FAQを行う航空会社のエージェント.
Read the following conversation. Then select the next role from
['PlanningAgent', 'fukuoka_agent', 'osaka_agent', 'hotel_agent', 'airline_agent'] to play.

Only return the role.
user: 東京から福岡、1人 2/1  19:00に空港到着したいな。あと当日のホテルも。

Read the above conversation. Then select the next role from
['PlanningAgent', 'fukuoka_agent', 'osaka_agent', 'hotel_agent', 'airline_agent'] to play. 
Only return the role.
```

### 回答: PlanningAgent

### 参考: selector_prompt template
Core APIs による [selector_prompt](https://microsoft.github.io/autogen/stable/user-guide/core-user-guide/design-patterns/group-chat.html#group-chat-manager) 実装は以下のように定義されます。

```
"""You are in a role play game. The following roles are available:
{roles}.
Read the following conversation. Then select the next role from {participants} to play. Only return the role.

{history}

Read the above conversation. Then select the next role from {participants} to play. Only return the role.
"""
```



## ②実行計画策定 - PlanningAgent
### system prompt
```bash
あなたはplanning agentです。
あなたの仕事は、複雑なタスクをより小さく、管理しやすいサブタスクに分解することです。
あなたのチームメンバーは次の通りです。
 - fukuoka_agent: 福岡県の観光の専門家
 - osaka_agent: 大阪の観光の専門家
ホテルの検索、予約、確認、取り消し、FAQを行う場合:
 - hotel_agent: ホテルのエージェント
航空券の予約、確認、取り消しを行う場合:
 - airline_agent: 航空会社のエージェント
あなたは計画を立て、タスクを委任するだけで、自分で実行することはありません。

タスクを割り当てる際には、このフォーマットを使用してください:
1. <agent> : <task>

最終回答が完成したら調査結果を要約し、文の最後に TERMINATE を含めること!
```
### user
```
東京から福岡、1人 2/1  19:00に空港到着したいな。あと当日のホテルも
```

### 実行計画の回答
```bash
了解しました。以下のタスクを実行するために計画を立てます。

### タスク分解
1. 東京から福岡への航空券を予約し、福岡空港に2月1日の19:00までに到着する便を探す。
2. 福岡で2月1日に1人分の宿泊可能なホテルを探し、予約する。

### タスク割り当て
1. `airline_agent`: 東京から福岡行きのフライトを2月1日に19:00までに福岡空港に到着する便を検索し、予約してください。
2. `hotel_agent`: 福岡で2月1日に宿泊可能なホテルを1人分で検索し、予約してください。

以上のタスクを進めます。結果が揃い次第、調査結果を要約してお知らせします。
```


## ③遷移先決定 - SelectorGroupChat
過去のコンテキスト = `PlanningAgent` の結果が System prompt に追加され、コンテキストを考慮した状態で遷移先を決定します。直前に実行された `PlanningAgent` は選択肢から動的に除外されていることが分かります。これは `SelectorGroupChat` のデフォルト設定であり、Selector は同じ発言者を連続して選択しません。ただ `allow_repeated_speaker=True` を設定することで変更できます。

### System prompt
```bash
You are in a role play game. The following roles are available:
PlanningAgent: タスクを計画するエージェント。新しいタスクが与えられたときに最初に起動するエージェントであるべきである。
fukuoka_agent: 福岡の旅行先について詳しい地元のトラベルエージェント
osaka_agent: 大阪の旅行先について詳しい地元のトラベルエージェント
hotel_agent: ホテルの検索、予約、確認、取り消し、FAQを行うホテルのエージェント
airline_agent: 航空券の予約、確認、取り消し、FAQを行う航空会社のエージェント.
Read the following conversation. Then select the next role from
['fukuoka_agent', 'osaka_agent', 'hotel_agent', 'airline_agent'] to play.
Only return the role.

user: 東京から福岡、1人 2/1  19:00に空港到着したいな。あと当日のホテルも。
PlanningAgent: 了解しました。以下のタスクを実行するために計画を立てます。

### タスク分解
1. 東京から福岡への航空券を予約し、福岡空港に2月1日の19:00までに到着する便を探す。
2. 福岡で2月1日に1人分の宿泊可能なホテルを探し、予約する。

### タスク割り当て
1. `airline_agent`: 東京から福岡行きのフライトを2月1日に19:00までに福岡空港に到着する便を検索し、予約してください。
2. `hotel_agent`: 福岡で2月1日に宿泊可能なホテルを1人分で検索し、予約してください。

以上のタスクを進めます。結果が揃い次第、調査結果を要約してお知らせします。

Read the above conversation. Then select the next role from
['fukuoka_agent', 'osaka_agent', 'hotel_agent', 'airline_agent'] to play.
Only return the role.
```

### 回答: airline_agent

## ④ airline_agent 実行(tool_calls)
`airline_agent` が実行され、tools として登録した `search_flight` 関数を呼ぶべきとの推論結果が得られました、。
- tool_calls.0.name: `search_flight`
- tool_calls.0.arguments: 
    ```json
    {
        "departure": "東京",
        "destination": "福岡",
        "arrival_time": "2024-02-01 19:00",
        "passengers": 1
    }
    ```
この後実際に `search_flight` 関数がコールされ、以下のような適当な Mock 回答を返します。

```json
{
    "departure": "東京",
    "destination": "福岡",
    "flight_number": "JL123",
    "airline": "Japan Airlines",
    "departure_time": "2025-02-01 16:30",
    "arrival_time": "2025-02-01 18:50",
    "price": 25000,
    "currency": "JPY",
    "passengers": 1,
}
```

### `reflect_on_tool_use=True` の影響
デフォルトでは、`AssistantAgent` はツールの出力をそのまま返します。ここで `reflect_on_tool_use` パラメータを `True` にするとツールの結果を LLM で自然言語に整形するステップが 1 つ追加されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/78cd5e6f-b551-6557-3310-800ae706f9a6.png)

```
東京から福岡行きのフライトが見つかりました。

- **航空会社**: Japan Airlines (JAL)
- **便名**: JL123
- **出発時間**: 2025年2月1日 16:30
- **到着時間**: 2025年2月1日 18:50
- **運賃**: 25,000円 (税込)
  
ご希望通り、19:00までに福岡空港に到着します。  
予約を進めてもよろしいですか？
```




## ⑤遷移先決定 - SelectorGroupChat
`airline_agent` からの回答は `SelectorGroupChat` に戻され、以下のように結果が追加されました。また直前に実行された `airline_agent` は選択肢から除外されていますね。

```bash
You are in a role play game. The following roles are available:
PlanningAgent: タスクを計画するエージェント。新しいタスクが与えられたときに最初に起動するエージェントであるべきである。
fukuoka_agent: 福岡の旅行先について詳しい地元のトラベルエージェント
osaka_agent: 大阪の旅行先について詳しい地元のトラベルエージェント
hotel_agent: ホテルの検索、予約、確認、取り消し、FAQを行うホテルのエージェント
airline_agent: 航空券の予約、確認、取り消し、FAQを行う航空会社のエージェント.
Read the following conversation. Then select the next role from ['PlanningAgent', 'fukuoka_agent', 'osaka_agent', 'hotel_agent'] to play. Only return the role.

user: 東京から福岡、1人 2/1  19:00に空港到着したいな。あと当日のホテルも。
PlanningAgent: 以下のステップで進めます。

### タスク：
1. 航空券の予約・確認：東京から福岡へ、2月1日、19:00までに福岡空港到着。
2. 福岡での宿泊先の予約：当日チェックイン可能なホテルを探す。

### サブタスクの割り当て：

1. **airline_agent**: 東京から福岡への航空券を、2月1日19:00までに福岡空港に到着する便で検索・提案してください。
2. **hotel_agent**: 福岡市内で、2月1日にチェックインする1名用のホテルを提案してください。

調査結果が揃い次第お知らせいたします！
airline_agent: {'departure': '東京', 'destination': '福岡', 'flight_number': 'JL123', 'airline': 'Japan Airlines', 'departure_time': '2025-02-01 16:30', 'arrival_time': '2025-02-01 18:50', 'price': 25000, 'currency': 'JPY', 'passengers': 1}

Read the above conversation. Then select the next role from ['PlanningAgent', 'fukuoka_agent', 'osaka_agent', 'hotel_agent'] to play. Only return the role.

```

### 回答: hotel_agent

## ⑧最終回答作成

このようにして `airline_agent` と同様に `hotel_agent` の実行と `search_hotel` ツールの実行が行われ、最終的に以下のような回答が作成されました。

```bash
### 調査結果
1. **航空券情報**:
   - 出発地: 東京
   - 目的地: 福岡
   - フライト: Japan Airlines (JL123)
   - 出発時間: 2025年2月1日 16:30
   - 到着時間: 2025年2月1日 18:50
   - 料金: 25,000円 (JPY)
   - 旅客数: 1名

2. **ホテル情報**:
   - 宿泊先: Grand Fukuoka Hotel
   - チェックイン: 2025年2月1日
   - チェックアウト: 2025年2月2日
   - 宿泊料金: 12,000円/泊 (合計: 24,000円)
   - 宿泊人数: 1名

すべての手配は完了しています。ご旅行をお楽しみください！TERMINATE
```

上記の結果を生成するために、他のエージェントの実行結果もコンテキストとして入力されていることが分かります。
>その応答は他のすべての参加者（エージェント）にブロードキャストされます。<sup>[^](https://microsoft.github.io/autogen/stable/user-guide/agentchat-user-guide/selector-group-chat.html#how-does-it-work)</sup>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/4688ce66-aef8-aeed-200d-a373905625f6.png)

# 遷移先のカスタマイズ
Selector によるエージェント選択プロセスをより適切に制御する必要があります。このために、`selector_func` カスタム セレクター関数を使用して引数を設定し、デフォルトのモデルベースの選択をオーバーライドできます。例えば、議論の進行状況を監視するために、専門エージェントの直後に PlanningAgent が話すようにしたいとします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/9f69c632-1ba4-ac1b-0db5-c29adb3bff6b.png)


```python
def selector_func(messages: Sequence[AgentEvent | ChatMessage]) -> str | None:
    if messages[-1].source != planning_agent.name:
        return planning_agent.name
    return None

# Reset the previous team and run the chat again with the selector function.
await team.reset()
team = SelectorGroupChat(
    [planning_agent, fukuoka_agent, osaka_agent, hotel_agent, airline_agent],
    model_client=client,
    termination_condition=combined_termination,
)

await Console(team.run_stream(task=task))
```

# 停止条件
AutoGen には 無限ループを防止するため 8 つの[組み込みの終了条件](https://microsoft.github.io/autogen/stable/user-guide/agentchat-user-guide/tutorial/termination.html#)が定義されています。終了条件は以下のように OR 条件で指定できるのが便利です。

```python
# Define termination condition
max_msg_termination = MaxMessageTermination(max_messages=15)
text_termination = TextMentionTermination("TERMINATE")
time_terminarion = TimeoutTermination(120)
combined_termination = max_msg_termination | text_termination | time_terminarion
```

最大生成メッセージ数 15  `OR` 応答に "TERMINATE" が含まれる `OR` 指定秒数経過で停止。一番ちゃんと動作して欲しいのは "TERMINATE" ですね。LLM によって完了と判断されれば "TERMINATE" を出力させてループ終了が理想です。

# 状態管理
AutoGen では状態管理の仕組みが備わっています。エージェント、チーム、終了条件の状態を保存および読み込むことができます。多くの場合、これらのコンポーネントの状態をディスクに保存し、後で再度読み込むと便利です。

## 状態の保存
```python
agent_state = await team.save_state()
print(agent_state)

import json
with open("./select_team_state.json", "w") as f:
    json.dump(agent_state, f)
```

### 保存された状態の構造
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/015f46cc-cc47-af4f-ad02-196c9a898f98.png)

### GroupChatManager のスレッドデータ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/7882a130-17cb-8caf-c03e-d5a2c7c82c7a.png)

### AirlineAgent のコンテキストデータ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/242321c3-0ef2-fc2a-2a31-adf039962624.png)

## 状態のロード
```python
## load state from disk
with open("./select_team_state.json", "r") as f:
    team_state = json.load(f)
    
new_agent_team = SelectorGroupChat(
    [planning_agent, fukuoka_agent, osaka_agent, hotel_agent, airline_agent],
    model_client=client,
    termination_condition=combined_termination,
)
await new_agent_team.load_state(team_state)
stream = new_agent_team.run_stream(task="さっきのホテルって何て言ったっけ？")
await Console(stream)
```
## MCP over SSE 実装のためのコードはこちら
https://qiita.com/nohanaga/items/8e5b29798d8412f9dd8f#3-autogen-v04x-%E7%B5%B1%E5%90%88%E3%82%AF%E3%83%A9%E3%82%A4%E3%82%A2%E3%83%B3%E3%83%88


# 3, Swarm
Swarm は、エージェントが他のエージェントに能力に応じてタスクを委譲できるチームを実装しています。これは、OpenAI が実験プロジェクトで初めて導入したマルチエージェント設計パターンです。特別にセットされたツール（Function calling）を使用してエージェントが他のエージェントにタスクを委譲（Handoffs）できるようにすることです。これにより、エージェントは、`SelectorGroupChat` のような中央のオーケストレーターに頼らずに、タスク計画についてローカルで決定を下すことができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/81d4974c-0d5d-1b56-4672-af0db555067b.png)


https://qiita.com/nohanaga/items/9bd32514655f142b23c6

# 4, Magentic-One
[Magentic-One](https://www.microsoft.com/en-us/research/articles/magentic-one-a-generalist-multi-agent-system-for-solving-complex-tasks/) は Microsoft Research が開発した汎用マルチエージェントシステムです。AutoGen は AgentChat としてこれを取り込みました。個人的に興味深いコンポーネントは、進捗状況の追跡台帳ですね。

https://qiita.com/nohanaga/items/28fcf00a23e990ac3551

# AutoGen Studio
RoundRobinGroupChat や SelectorGroupChat は [AutoGen Studio](https://github.com/microsoft/autogen/tree/main/python/packages/autogen-studio) の Team Builder からモダンな UI を使用して開発することもできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/43f94c4f-767b-368f-8eb7-6fedc1929414.png)



# AutoGen vs Semantic Kernel
以下の用途で使い分けると良いと Microsoft Ignite 2024 にて。
- 研究・実験が目的であり、最新技術を試したい場合 → AutoGen を使用。
- 実運用や安定したエンタープライズ開発が必要な場合 → Semantic Kernel を使用。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/6b434449-3840-3004-8a73-dc22cad61cec.png)


<sup>[Introducing Azure AI Foundry Agent Service to scale your AI agents](https://ignite.microsoft.com/en-US/sessions/BRK102?source=sessions)</sup>

# Azure OpenAI Assistants API & AI Agent 実装
TBD


# GitHub
https://github.com/nohanaga/autogen-design-pattern-samples/blob/main/autogen_select.ipynb


# 参考
https://microsoft.github.io/autogen/stable/user-guide/agentchat-user-guide/selector-group-chat.html