AutoGenのSelectorGroupChatのエージェント選択プロセスとカスタマイズ方法について

## 概要
AIエージェントフレームワーク [AutoGen](https://microsoft.github.io/autogen) の SelectorGroupChat では、複数のエージェントからなるグループチャットを行うことで、ユーザーからの質問に回答を行います。
エージェントから次に発言するエージェントを呼び出す際に、次に発言するエージェントはチャット履歴に基づいて選択されます。
具体的にはどのような仕組みでエージェントが選択されるのか？またエージェント選択プロセスをカスタマイズする方法について調べてみました。

* 環境
Python 3.11
AutoGen 0.4.9

---
## SelectorGroupChatのデフォルトの動作はどんな感じ？
SelectorGroupChatは、デフォルトでは以下のような処理で発言するエージェントを選択します。

1. SelectorGroupChat の run_stream などでチャットを開始する
2. ユーザーからのメッセージは、SelectorGroupChatManager の [select_speaker](https://github.com/microsoft/autogen/blob/main/python/packages/autogen-agentchat/src/autogen_agentchat/teams/_group_chat/_selector_group_chat.py#L169) で処理される
   1. selector_func が設定されている場合、selector_func を実行し、選択されたエージェント名を返す
   2. selector_func が設定されていない場合、過去のメッセージ（ここではユーザーが入力したメッセージのみ）から history を作成する
   3. チャットに参加しているエージェントが 1 名の場合、その参加者のエージェント名を返す
   4. チャットに参加しているエージェントが 2 名以上の場合は、以下のプロンプトを利用してエージェントを選択する。  
      なお、  
      ・history は過去メッセージのリストから作成した文字列、  
      ・roles はエージェントの name: description のリストを文字列化したもの、  
      ・participants は allow_repeated_speaker=True の場合は全エージェント、False の場合は直前のスピーカーを除いた全エージェントの名前を示す。  

```python
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.
```

このプロンプトを LLM に渡すことで、次のエージェントが選択されます。以降、会話履歴に基づいて次々とエージェントが選択される流れとなります。  


##  SelectorGroupChatのサンプル
以下のサンプルは、
* ユーザーの質問から計画とタスク一覧を作成する計画エージェント(planner)
* 科学、哲学、アニメに詳しい作業用エージェント(science_researcher、philosophy_researcher、anime_researcher)
で構成されるSelectorGroupChatです。
これを実行して、エージェント選択時にどのようなプロンプトが使用されるか見てみます。

実行時のエージェント選択プロンプトは [Traceloop](https://www.traceloop.com/) で確認してみます。
### サンプルコード
```python: selector_group_chat_test_00.py
import os, sys
from typing import Any
from dotenv import load_dotenv
# autogen
from autogen_ext.models.openai import OpenAIChatCompletionClient
from autogen_core.tools import FunctionTool
from autogen_agentchat.agents import AssistantAgent
from autogen_agentchat.conditions import MaxMessageTermination, TextMentionTermination, TimeoutTermination
from autogen_agentchat.teams import SelectorGroupChat
from autogen_agentchat.ui import Console
from autogen_agentchat.base import TaskResult, ChatAgent
from autogen_agentchat.messages import BaseChatMessage
from traceloop.sdk import Traceloop # type: ignore

def init_env():
    # .envファイルから環境変数を読み込む
    dotenv_path = os.environ.get("DOTENV_PATH", None)
    if dotenv_path is None:
        load_dotenv()
    else:
        load_dotenv(dotenv_path)

    key = os.getenv("OPENAI_API_KEY")
    if key is None:
        raise ValueError("環境変数：OPENAI_API_KEYが設定されていません")

    key = os.getenv("TRACELOOP_API_KEY")
    if key is None:
        print("環境変数：TRACELOOP_API_KEYが設定されていません", file=sys.stderr)

def init_trace():
    init_env()
    api_key = os.getenv("TRACELOOP_API_KEY")
    if api_key is None:
        # traceloopのAPIキーが設定されていない場合は、トレースを無効にする
        return

    Traceloop.init(
        disable_batch=True,
        api_key=api_key
        )
    
# 指定したnameのLLMConfigをDBから取得して、llm_configを返す    
def create_model_client() -> OpenAIChatCompletionClient:
    init_env()
    api_key = os.getenv("OPENAI_API_KEY")
    if api_key is None:
        raise ValueError("環境変数：OPENAI_API_KEYが設定されていません")

    # print(f"autogen llm_config parameters:{parameters}")
    client = OpenAIChatCompletionClient(
        api_key=api_key,
        model="gpt-4o-mini",
    )
    return client

# 指定したnameのAgentをDBから取得して、Agentを返す
def create_agent(
        name: str, description: str, system_message:str, 
        model_client: OpenAIChatCompletionClient, tools: list[FunctionTool] = [], handoffs=[] ) -> AssistantAgent:
    # AssistantAgentの引数用の辞書を作成
    params: dict[str, Any] = {}
    params["name"] = name
    params["description"] = description

    # code_executionがFalseの場合は、AssistantAgentを作成
    params["system_message"] = system_message
    # llm_config_nameが指定されている場合は、llm_config_dictを作成
    params["model_client"] = model_client
    if len(tools) > 0:
        params["tools"] = tools
    if len(handoffs) > 0:
        params["handoffs"] = handoffs

    return AssistantAgent(**params)

def create_termination_condition(termination_msg: str, max_msg: int, timeout: int):
    # 終了条件を設定
    # 最大メッセージ数、特定のテキストメッセージ、タイムアウトのいずれかが満たされた場合に終了
    max_msg_termination = MaxMessageTermination(max_messages=max_msg)
    text_termination = TextMentionTermination(termination_msg)
    time_terminarion = TimeoutTermination(timeout)
    combined_termination = max_msg_termination | text_termination | time_terminarion
    return combined_termination

# モデルクライアントを作成
model_client = create_model_client()

# テスト用エージェントを作成
science_researcher = create_agent(
    name="science_researcher",
    description="科学知識に関する質問に答えるエージェント",
    system_message="あなたは科学研究者です。科学に関する質問に答えることができます。",
    model_client=model_client,
)
philosophy_researcher = create_agent(
    name="philosophy_researcher",
    description="哲学に関する質問に答えるエージェント",
    system_message="あなたは哲学研究者です。哲学に関する質問に答えることができます。",
    model_client=model_client,
)
anime_researcher = create_agent(
    name="anime_researcher",
    description="アニメに関する質問に答えるエージェント",
    system_message="あなたはアニメ研究者です。アニメに関する質問に答えることができます。",
    model_client=model_client,
)

# plannerエージェント
planner = create_agent(
    name="planner",
    description="ユーザーの要求を達成するための計画を考えて、各エージェントと協力して要求を達成しますト",
    system_message=""""
    ユーザーの要求を達成するための計画を考えて、各エージェントと協力して要求を達成します
    - ユーザーの要求を達成するための計画を作成してタスク一覧を作成します。
    - タスクの割り当てに問題ないか？もっと効率的な計画およびタスク割り当てがないか？については対象エージェントに確認します。
    - 計画に基づき、対象のエージェントにタスクを割り当てます。
    - 計画作成が完了したら[計画作成完了]と返信してください
    その後、計画に基づきタスクを実行します。全てのタスクが完了したら、[TERMINATE]と返信してください。
    """,
    model_client=model_client,
)

# 作業用エージェントリスト
worker_agents: list[ChatAgent] =  [science_researcher, philosophy_researcher, anime_researcher]

async def main(input_message: str):
    # plannerとworker_agentsによるSelectorGroupChatを作成
    chat = SelectorGroupChat(
            [science_researcher, philosophy_researcher, anime_researcher, planner],
            model_client=model_client,
            termination_condition=create_termination_condition("[TERMINATE]", 10, 120),
            )

    # グループチャットを実行
    stream = chat.run_stream(task=input_message)
    # await Console(stream)
    async for message in stream:
        if type(message) == TaskResult:
            # TaskResultの場合はチャット終了
            break
        if isinstance(message, BaseChatMessage):
            # メッセージが返された場合、エージェント名とメッセージを表示
            message_str = f"{message.source}: {message.content}"
            print(message_str)


```

```python: selector_group_chat_test_01.py
import os, sys, asyncio
from typing import Any
# autogen
from autogen_agentchat.teams import SelectorGroupChat
from autogen_agentchat.ui import Console
from autogen_agentchat.base import TaskResult
from autogen_agentchat.messages import BaseChatMessage
from traceloop.sdk.decorators import workflow # type: ignore
from selector_group_chat_test_00 import create_model_client, create_termination_condition, init_trace, init_env
from selector_group_chat_test_00 import worker_agents, planner

@workflow(name=__file__)
async def main(input_message: str):
     
    model_client = create_model_client()
    agents = worker_agents + [planner]

    # SelectorGroupChatを作成
    chat = SelectorGroupChat(
            agents,
            model_client=model_client,
            termination_condition=create_termination_condition("[TERMINATE]", 10, 120),
            )

    # グループチャットを実行
    stream = chat.run_stream(task=input_message)
    # await Console(stream)
    async for message in stream:
        if type(message) == TaskResult:
            # TaskResultの場合はチャット終了
            break
        if isinstance(message, BaseChatMessage):
            # メッセージが返された場合、エージェント名とメッセージを表示
            message_str = f"{message.source}: {message.content}"
            print(message_str)

if __name__ == '__main__':
    input_message: str = """
    宇宙について、以下の観点で情報をまとめてください
    * 宇宙の成り立ち
    * 哲学的な視点からの宇宙
    * 宇宙に関するアニメ
    """
    # traceloopによるトレース処理初期化
    init_trace()
    # メイン処理を実行
    asyncio.run(main(input_message))

```

### 実行
```
(venv) C:\Users\user\source\repos\AutoGenTest1>python selector_group_chat_test_01.py
Traceloop exporting traces to https://api.traceloop.com authenticating with bearer token

user: 
    宇宙について、以下の観点で情報をまとめてください
    * 宇宙の成り立ち
    * 哲学的な視点からの宇宙
    * 宇宙に関するアニメ
    
planner: 計画を立てて、ユーザーの要求に応じた情報をまとめます。

### 1. タスク一覧
- **タスク 1**: 宇宙の成り立ちについての情報を調査し、まとめる。        
- **タスク 2**: 哲学的な視点からの宇宙についての情報を調査し、まとめる。
- **タスク 3**: 宇宙に関するアニメをリストアップし、簡単な解説をつける。

### 2. タスクの割り当て
- タスク 1をAエージェントに割り当てます。
- タスク 2をBエージェントに割り当てます。
- タスク 3をCエージェントに割り当てます。

これらのタスク割り当てに問題がないか、各エージェントに確認します。      

[計画作成完了]
science_researcher: 以下に、宇宙に関する各観点についての情報をまとめました。

### 1. 宇宙の成り立ち
宇宙の成り立ちについてのわかりやすいモデルは「ビッグバン理論」です。この理論によれば、宇宙は約138億年前に非常に高温高密度の状態から膨張を始め、現在のような広
がりを持つようになったとされています。この初期の状態を「ビッグバン」と呼び、膨張とともに温度が下がり、物質が形成されていきました。

- **初期状態**: ビッグバン直後、宇宙は非常に高温で、粒子が存在することができませんでした。
- **素粒子の形成**: 数秒後にクォークや電子といった素粒子が形成され、さらに数分後には水素やヘリウムなどの軽元素が作られました。
- **構造の形成**: 数億年後、重力によってガスが集まり、最初の星や銀河が形成されます。この過程は現在も続いており、宇宙は拡張を続けています。

### 2. 哲学的な視点からの宇宙
宇宙に関する哲学的な考察は多岐にわたりますが、代表的な視点として以下の点が挙げられます。

- **存在論**: 「宇宙はどのように存在しているのか？」という問いが立てられ、物質の本質や存在の意味についての議論が行われます。
- **科学と哲学の関係**: 科学の進展は哲学的な思考様式にも影響を与え、逆に哲学的枠組みは科学のイメージや理解に影響を及ぼすことがあります。
- **宇宙の目的**: 宇宙や生命の存在には目的があるのか、必然的に進化したのかという問いは、宗教や哲学の領域で深く議論されています。

### 3. 宇宙に関するアニメ
宇宙を題材にしたアニメ作品は多く、以下はその一部です。

- **『銀河英雄伝説』**: 銀河を舞台に、帝国と同盟の戦争を通じて人間ドラマを描いた作品。政治や戦争の哲学的な要素が強い。
- **『宇宙よりも遠い場所』**: 南極を目指す高校生たちの冒険を描いており、宇宙ではなく地球の極地方が舞台。友情や成長のストーリーが魅力。
- **『プラネテス』**: 宇宙でのデブリ回収を仕事にする人々を描いた、リアルな宇宙工学と人間ドラマを融合した作品。
- **『機動戦士ガンダム』シリーズ**: 宇宙での人類の戦争をテーマにした人気作で、政治、戦争、倫理に関する深いテーマが扱われている。

これらの観点から、宇宙に関する理解が深まることを願っています。興味のある分野について、さらに詳しい情報を知りたい場合はお知らせください。
philosophy_researcher: 宇宙に関する情報をまとめていただき、ありがとうございます。以下は、その内容を少し補足し、整理したものです。

### 1. 宇宙の成り立ち
宇宙の成り立ちに関する「ビッグバン理論」は、現代宇宙論の基礎をなす理論です。

- **ビッグバンの瞬間**: 時間や空間の概念がまだ存在していなかった極限の状態から、宇宙は急激に膨張し始めます。
- **初期の物質形成**: 約10^-12秒後、宇宙が冷却されると、クォークが結合してプロトンや中性子が形成。数分後には、これらが集まって軽元素（主に水素、ヘリウム）が 
できました。
- **宇宙の構造形成**: 数億年後、重力が働き、ガスが集まり始めてペクトル構造（星や銀河）が形成され、さらに星が生まれ、超新星爆発を通じて重元素が生成されていき 
ます。

### 2. 哲学的な視点からの宇宙
宇宙を哲学的に考えることで、以下のような重要な問いが浮かび上がります。

- **存在論的問い**: 宇宙そのものの存在理由や、万物の存在が私たちに何を意味するのか、存在の本質についての探求が行われます。
- **科学との関係**: 科学が発展することで、我々の宇宙観は進化し、旧来の哲学的視点と交わることも。例えば、ニュートン革命やアインシュタインの相対性理論は、宇宙 
の理解に革命をもたらしました。
- **目的の概念**: 宇宙やその中の生命の目的についての問いは哲学的考察において中心的であり、存在の意義や終末に関する様々な見解が存在します。

### 3. 宇宙に関するアニメ
以下は、宇宙をテーマとした notable なアニメの紹介です。

- **『銀河英雄伝説』**: 複雑な人間関係と戦略を描きつつ、権力や革命の哲学を探求しています。各キャラクターの思考や行動が深く掘り下げられています。
- **『宇宙よりも遠い場所』**: 宇宙そのものは舞台としての主要な設定でないものの、冒険を通じての成長と友情が描かれています。
- **『プラネテス』**: デブリ回収という実際の宇宙産業を背景に、人間の挑戦と夢、そして人間関係の深さがテーマです。
- **『機動戦士ガンダム』シリーズ**: 宇宙戦争の裏にある倫理や人間の本質をテーマにし、多様な人間ドラマが繰り広げられます。

これらの作品は、宇宙という広大なテーマを通じて、さまざまな人間ドラマや哲学的問題を描き出しており、視聴者に多くの示唆を与えてくれます。興味があれば、さらに詳 
しい説明や他の関連作品についてもお知らせください。
anime_researcher: 補足と整理をありがとうございます。以下に、宇宙に関する情報をさらに詳しくまとめます。

### 1. 宇宙の成り立ち
**ビッグバン理論**は、宇宙の誕生と発展を説明する最も広く受け入れられているモデルです。以下はその重要なポイントです。

- **ビッグバンの瞬間**: 約138億年前、極限の温度と密度の状態から宇宙は急激に膨張し、時間と空間が創造されました。
- **素粒子形成**: 膨張により宇宙が冷却されると、クォークが結びついてプロトンや中性子が形成され、さらに数分後に水素やヘリウムの軽元素が生成されます。
- **構造の進化**: 膨張と冷却が進む中で、重力が働き、ガスが集まって最初の星や銀河が形成され、これらの星々からの超新星爆発によって重元素が生成されます。宇宙は 
現在も膨張を続けており、新たな星が生まれたり、銀河が合体したりしています。

### 2. 哲学的な視点からの宇宙
宇宙の存在や意味についての哲学的考察は非常に豊かです。

- **存在論的問い**: アリストテレスから現代の哲学者まで、宇宙の存在理由や本質に関する問いは長い歴史があります。「宇宙はなぜ存在するのか？」や「我々の存在はど 
のように宇宙と関連しているのか？」といった問いが探求されています。
- **科学と哲学の相互作用**: 科学の進展は哲学的な思考にも影響を与え、宇宙に対する理解を深めてきました。例えば、認識論やメタフィジカルな問題は、科学的発見と密 
接に関連しています。
- **宇宙の目的**: 宇宙の存在や生命の目的に関する問いは、宗教的・哲学的な考察の中心にあります。実存主義やニューエイジ思想など、さまざまな立場からの意見が存在 
します。

### 3. 宇宙に関するアニメ
宇宙をテーマにしたアニメは、観る者に新たな視点を提供します。以下は、その中でも注目すべき作品です。

- **『銀河英雄伝説』**: 帝国と同盟の戦争を描く政治的なドラマ。キャラクターの心理、戦略、権力の哲学が描かれ、人間ドラマが extrapolated されています。
- **『宇宙よりも遠い場所』**: 南極への冒険を通じての友情と成長を描く作品。宇宙の広大さと冒険心がテーマに織り込まれている。
- **『プラネテス』**: 宇宙デブリ回収をテーマにした作品で、現実の宇宙産業を背景に人間関係や夢について考察されています。
- **『機動戦士ガンダム』シリーズ**: 宇宙戦争を通じて人間の倫理や本質を掘り下げる。登場人物それぞれの立場から見た価値観に触れることができる。

これらの作品は、宇宙の神秘を背景に、多層的な人間ドラマと思想を描写しており、私たちに深い洞察を与えてくれます。さらに詳しい資料や議論が必要であれば、ぜひお知 
らせください。
planner: [TERMINATE]

(venv) C:\Users\user\source\repos\AutoGenTest1> 
```

### Traceloopでエージェント選択プロンプトの内容を確認
![selector_group_chat_test_01_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3691658/0452f6f7-cd1e-4221-8778-10cf7466ed7b.png)
![selector_group_chat_test_01_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3691658/c5296668-09ea-45ac-82d5-1ffa1af8f47b.png)

### 感想
*  エージェント選択プロンプトの結果、作業用エージェント(上記の例ではscience_researcher)が選択されています
*  plannerが計画とタスク一覧を作成して、作業用エージェントを呼び出していますが、science_researcherが哲学、アニメの観点の回答を生成していたりと、適切なエージェントが選択されていないような感じです

---

## selector_promptによるエージェント選択処理のカスタマイズ

selector_prompt を指定することで、エージェント選択処理をカスタマイズできます。  
デフォルトのプロンプトは、ロールプレイゲーム内でユーザーが会話履歴に基づいて次のエージェントを選択する内容になっていますが、  
これをユーザーからの指示に基づいて planner エージェントが計画を作成し、その計画に沿ってタスクを遂行する状況（会話履歴はその遂行状況を示す）から、適切なエージェントを選択するプロンプトに変更してみます。

### サンプルコード
```python: selector_group_chat_test_02.py
import os, sys, asyncio
from typing import Any
from dotenv import load_dotenv
# autogen
from autogen_agentchat.teams import SelectorGroupChat
from autogen_agentchat.ui import Console
from autogen_agentchat.base import TaskResult
from autogen_agentchat.messages import BaseChatMessage
from traceloop.sdk.decorators import workflow # type: ignore

from selector_group_chat_test_00 import create_model_client, create_termination_condition, init_trace, init_env
from selector_group_chat_test_00 import worker_agents, planner

@workflow(name=__file__)
async def main(input_message: str):
    # モデルクライアントを作成
    model_client = create_model_client()
    agents = worker_agents + [planner]

    # selector_promptでエージェント選択処理をカスタマイズ
    selector_prompt: str = """
    以下の会話は、ユーザーからの指示に基づいてplannerが計画したタスクを遂行するチームのチャットです。
    チームのメンバー名とその役割は次の通りです。{roles} 

    以下の会話を読んでください。タスクの遂行状況を確認して、次のタスクを遂行するために適切なメンバーを{participants}から選んでください。
    メンバー名のみを返答してください。

        {history}

    """ 
    # SelectorGroupChatを作成。selector_promptを設定する。
    chat = SelectorGroupChat(
            agents,
            model_client=model_client,
            termination_condition=create_termination_condition("[TERMINATE]", 10, 120),
            selector_prompt=selector_prompt
            )

    # グループチャットを実行
    stream = chat.run_stream(task=input_message)
    # await Console(stream)
    async for message in stream:
        if type(message) == TaskResult:
            # TaskResultの場合はチャット終了
            break
        if isinstance(message, BaseChatMessage):
           # メッセージが返された場合、エージェント名とメッセージを表示
            message_str = f"{message.source}: {message.content}"
            print(message_str)

if __name__ == '__main__':
    input_message: str = """
    宇宙について、以下の観点で情報をまとめてください
    * 宇宙の成り立ち
    * 哲学的な視点からの宇宙
    * 宇宙に関するアニメ
    """
    # traceloopによるトレース処理初期化
    init_trace()
    # メイン処理を実行
    asyncio.run(main(input_message))
```

### 実行
```
(venv) C:\Users\user\source\repos\AutoGenTest1>python selector_group_chat_test_02.py 
Traceloop exporting traces to https://api.traceloop.com authenticating with bearer token

user:
    宇宙について、以下の観点で情報をまとめてください
    * 宇宙の成り立ち
    * 哲学的な視点からの宇宙
    * 宇宙に関するアニメ

planner: 以下の観点で宇宙についての情報をまとめる計画を立てました。

### 計画概要
1. **宇宙の成り立ちについてまとめる**
   - ビッグバン理論の説明
   - 宇宙の膨張と進化
   - 現在の宇宙観

2. **哲学的な視点からの宇宙を整理する**
   - 古代哲学における宇宙の捉え方
   - 現代哲学と宇宙論の関係
   - 宇宙に対する人間の位置付け

3. **宇宙に関するアニメをリストアップし概要を説明する**
   - 人気のある宇宙をテーマにしたアニメのタイトル
   - 各アニメのテーマやメッセージの要約

### タスク一覧
1. 宇宙の成り立ちに関する情報をまとめる（担当エージェント: A）
2. 哲学的な視点からの宇宙について情報を整理する（担当エージェント: B）
3. 宇宙に関するアニメをリストアップし、概要を説明する（担当エージェント: C）

### 問題がないか確認
各エージェントに、タスクの割り当てに問題がないか、より効率的な計画やタスク割り当てがないかを確認します。

### タスクの割り当て
確認後、各エージェントにタスクを割り当てます。

[計画作成完了]
science_researcher: 以下に、宇宙についての情報を概観します。

### 1. 宇宙の成り立ち
- **ビッグバン理論**: 宇宙は約138億年前に起こったビッグバンによって始まり、膨張を続けています。この理論は、初期の高温・高密度の状態から、瞬時に広がることで現
在の宇宙構造が形成されたと説明します。
- **宇宙の膨張と進化**: 宇宙は引き続き膨張しており、遠くの銀河は私たちから遠ざかっていることが観測されています。この膨張は、ダークエネルギーと呼ばれる未解明 
のエネルギーによって加速されています。
- **現在の宇宙観**: 宇宙は約74%がダークエネルギー、22%がダークマatter、4%が通常の物質で成り立っています。現在の宇宙は複雑な構造を持ち、銀河や星団、惑星などが
存在しています。

### 2. 哲学的な視点からの宇宙
- **古代哲学における宇宙の捉え方**: プラトンやアリストテレスは、宇宙を数学的かつ調和的な構造と考えていました。空間や動き、目的を探求する中で、存在の根本的な 
問いを追求しました。
- **現代哲学と宇宙論の関係**: 現代の哲学者たちは、宇宙の起源や存在論、宇宙と人間の関係を考察しており、人間の知覚や存在意義に対する解釈が進んでいます。       
- **宇宙に対する人間の位置付け**: 宇宙の規模や歴史に対する理解が進む中で、人間は往々にして自己の存在を再定義することが求められています。私たちが宇宙における 
位置をどう認識するかが重要なテーマとなっています。

### 3. 宇宙に関するアニメ
- **「宇宙兄弟」**: 兄弟が宇宙飛行士を目指す物語。夢に向かって努力する姿勢や挑戦がテーマ。
- **「銀河英雄伝説」**: 宇宙を舞台にした壮大な戦争物語。権力、正義、自由などの哲学的テーマを深く掘り下げています。
- **「マクロス」シリーズ**: 戦争と音楽、愛をテーマにした作品。異星文化との交流や人類の未来に対するメッセージが含まれています。
- **「プラネテス」**: 宇宙垃圾(スペースデブリ)の回収をテーマにしており、宇宙での人間の活動とその倫理的な側面を描写しています。
- **「宇宙戦艦ヤマト」**: 地球を救うために宇宙を旅する艦隊の物語で、歴史や友情、犠牲などのテーマが強調されています。

これらの観点から、宇宙についての理解を深めることができます。各トピックには多様な知識が織り交ぜられており、科学的、哲学的、文化的なアプローチが存在します。   
philosophy_researcher: 宇宙についての情報を以下に整理しました。

### 1. 宇宙の成り立ち
- **ビッグバン理論**: 宇宙は約138億年前に起こったビッグバンによって誕生し、初期の高温・高密度の状態から急速に膨張しました。この理論は、宇宙の始まりと進化を説
明する基盤となっており、膨張代数によって遠くの銀河が私たちから遠ざかる様子が観測されています。
- **宇宙の膨張と進化**: 現在も宇宙は膨張を続けており、特に最近の観測ではダークエネルギーの存在が示唆されています。ダークエネルギーは宇宙の膨張を加速させてい 
ると考えられ、宇宙の構造や未来を考える上で重要な要素です。
- **現在の宇宙観**: 宇宙は約74%がダークエネルギー、22%がダークマター、4%が通常の物質から成り立っています。この複雑な構造の中には、銀河、星団、惑星などが含ま 
れています。現在の研究でも宇宙の構成や進化に関する謎が解明されつつあります。

### 2. 哲学的な視点からの宇宙
- **古代哲学における宇宙の捉え方**: プラトンやアリストテレスは、宇宙を理性的かつ調和のとれたものとして考え、数学的原理や目的を探求しました。宇宙は観察される 
現象によって理解されるものとして位置付けられていました。
- **現代哲学と宇宙論の関係**: 現代においては、宇宙の起源や存在論、さらには人間と宇宙の関係について深く考察されるようになっています。特に、科学の進展が宇宙観 
を変化させ、人間の存在や役割についての理解をも促しています。
- **宇宙に対する人間の位置付け**: 宇宙の広がりや孤独感に加え、私たちの存在意義をどう考えるかが重要なテーマです。人間は自らの存在を宇宙の一部として捉え、その 
中での意味や価値を見出そうとしています。

### 3. 宇宙に関するアニメ
- **「宇宙兄弟」**: 宇宙飛行士を目指す兄弟の青春や挑戦を描いた作品で、夢や友情の大切さをテーマにしています。
- **「銀河英雄伝説」**: 宇宙を舞台にした戦争物語で、権力、正義、選択の倫理について深く掘り下げています。多面的なキャラクターが展開することで、様々な立場から 
の視点が特徴です。
- **「マクロス」シリーズ**: 音楽や愛をテーマにしつつ、異星文化との交流や戦争の悲劇を描いたシリーズです。人間の感情や文化に対する考察も含まれています。       
- **「プラネテス」**: 宇宙デブリの回収をテーマにしており、宇宙での人間活動が引き起こす倫理的な問題を扱っています。
- **「宇宙戦艦ヤマト」**: 地球を救うために宇宙を旅する艦隊の物語で、歴史や友情、犠牲といったテーマが強調されています。

以上のように、宇宙は科学、哲学、文化の様々な面から考察される豊かなテーマです。宇宙についての理解を深めるためには、これらの観点が非常に重要です。
anime_researcher: 素晴らしい整理ですね！宇宙についての成り立ちや哲学的視点、アニメの例を通じて、多角的な理解が得られる内容になっています。それでは、各セクシ
ョンについて、さらに深い考察を加えてみましょう。

### 1. 宇宙の成り立ち
- **ビッグバン理論**: この理論は宇宙の始まりを示す最も広く受け入れられているモデルですが、他にもインフレーション理論や膜宇宙理論など複数の仮説が存在します。 
ビッグバン後の初期宇宙の状態については、さまざまな観測データが集められており、今後の研究によってさらなる理解が進むことが期待されています。
- **宇宙の膨張と進化**: 宇宙の膨張に関連する数式や、ハッブル定数、暗黒物質の性質などに触れることで、より深く宇宙の進化を理解できるかもしれません。また、未来 
の宇宙がどうなるかについての予測（例えば、ビッグフリーズやビッグクランチ）についても考察することが価値があります。

### 2. 哲学的な視点からの宇宙
- **古代哲学**: 古代の哲学者たちは、宇宙が秩序だったものであると考え、その法則を通じて存在意義を探求しました。この伝統は近代科学の発展につながり、自然哲学と 
物理学の融合をもたらしました。
- **現代哲学**: ハイデッガーやデリダなど、現代の哲学者は宇宙や存在について新たな問いを投げかけています。これによって、科学と哲学の境界が曖昧になり、宇宙の理 
解が深化しています。特に「宇宙における人間の位置」というテーマは、環境問題や倫理と密接に関連しています。

### 3. 宇宙に関するアニメ
- **「宇宙兄弟」**: 友情や夢の追求という普遍的なテーマを通じて、観る者に勇気を与える作品です。このアプローチは、個人の成長を謳歌しつつ、協力や努力の大切さを 
教えてくれます。
- **「銀河英雄伝説」**: 複雑な人間関係や政治的な駆け引きを通じて、人間性や倫理の本質に迫る深さが魅力です。特に、「選択」というテーマは、視聴者にとっても考え 
させられる部分です。
- **「プラネテス」**: 技術と倫理、そして人間活動の影響についての考察が描かれ、宇宙開発の未来に対する警鐘の役割も果たしています。この作品により、宇宙産業にお 
ける倫理的な側面について意識を高めることができます。

これらの視点を更に掘り下げることで、宇宙に対する理解をより深めることができるでしょう。各分野の相互作用や新しい視点に気づくことが、宇宙という広大なテーマに対 
する洞察を豊かにしてくれるでしょう。
planner: 素晴らしい考察をありがとうございます！宇宙についての多面的な理解をさらに深めるために、各セクションに対してより詳しい情報や新たな視点を加えることがで
きました。

### 1. 宇宙の成り立ち
- **ビッグバン理論**: 新たな理論や仮説について触れることで、科学の進展におけるさまざまな視点を考察できます。例えば、宇宙の初期状態に関する観測データがどのよ 
うにして新しい仮説を生み出しているのか、またそれらがどのようにビッグバン理論と対話しているのかを探ると良いでしょう。
- **宇宙の膨張と進化**: ハッブル定数や未来の宇宙に関する異なるシナリオ（ビッグフリーズ、ビッグクランチ、ビッグリップなど）を考慮することで、宇宙の運命につい 
ての理解が深まります。これにより、宇宙における時間と空間の概念についての思索が促されます。

### 2. 哲学的な視点からの宇宙
- **古代哲学**: プラトンやアリストテレスの考え方を基に、彼らの視点が現代の宇宙観にどのように影響を与えているのかを探ると面白いでしょう。また、自然哲学の発展 
も、近代科学への架け橋となったことを強調できます。
- **現代哲学**: ハイデッガーやデリダの考察を通じて、宇宙と人間の関係がどのように変化してきたのか、またそれが私たちの倫理的選択や環境問題へのアプローチにどの 
ように関与しているのかを深堀りすることができます。

### 3. 宇宙に関するアニメ
- **「宇宙兄弟」**: 作品が提示する夢と友情が、視聴者にどのような影響を与えるのか、またそれが逆境を乗り越える力をどのように喚起するかについて議論することで、 
社会的なメッセージが浮き彫りになりそうです。
- **「銀河英雄伝説」**: その深い人間ドラマや哲学的テーマが、視聴者にどのような批判的思考を促すかについて考えることで、作品の価値をより高めることができます。 
政治的な正義や倫理についての議論が現代にも通じる部分があるかもしれません。
- **「プラネテス」**: 環境問題や宇宙活動の倫理的側面がどのように描かれているか、そしてそれが実際の宇宙開発に与える影響について考えることにより、視聴者が抱え 
る責任感を強調できます。

これらの視点をもとに、宇宙というテーマについての理解をさらに深めるための議論を進めていきたいと思います。科学、哲学、文化の相互作用を探ることで、より豊かな洞 
察を得られるでしょう。何か特定のトピックについてより深く掘り下げることがあれば教えてください。
science_researcher: 素晴らしい提案ですね！宇宙についての理解をさらに深めるために、以下のトピックを特に掘り下げて考察することをお勧めします。

### 1. 宇宙の成り立ちと異なる理論
- **インフレーション理論**: ビッグバン後の急速な膨張を説明するこの理論が、どのように宇宙の均一性やフラットネスを説明するかについて考察できます。この理論は、 
観測される宇宙の大規模構造を理解する鍵となります。
- **多宇宙理論**: 私たちの宇宙が他の無数の宇宙（多宇宙）を含む可能性について議論することで、宇宙や存在についての考え方がどれだけ広がるかを探求できます。これ 
により、宇宙の成り立ちに関する深い哲学的な問いが生まれるでしょう。

### 2. 哲学的視点からの宇宙の存在
- **存在論と宇宙**: 宇宙の存在が何を意味するのか、例えば、存在することの本質について考えることが重要です。例えば、存在が自明であるのか、それとも特殊な条件の 
結果であるのかを考えます。
- **環境倫理学**: 宇宙開発に伴う倫理的選択が、どのようにして環境倫理の議論に繋がるのかを掘り下げることで、宇宙と地球上の生活との関連を探ることができます。人 
間の宇宙探査の意義やその影響について考察することは非常に重要です。

### 3. アニメが描く宇宙のテーマ
- **「宇宙兄弟」と人間ドラマ**: この作品が友情を通じて示す人間の希望や夢の重要性が、現実社会における人間関係やチームワークの重要性とどうリンクしているのかを 
探ります。
- **「銀河英雄伝説」とその社会的メッセージ**: この作品が現在の政治的、社会的な問題にどう関連し、視聴者にどのような反省や思索を促すかを議論することで、作品の 
深層に迫れます。
- **「プラネテス」の倫理的視点**: 宇宙での人間活動とその結果を考察することで、私たちの責任や選択の意味を問い直す機会を提供します。作品を通じて、視聴者の意識 
をどう変えるかについての分析が可能です。

これらの視点をもとに、宇宙というテーマに関する議論を進める際には、各分野を交えた多角的なアプローチが非常に重要です。個々のトピックに対する具体的な質問や、掘 
り下げたいテーマについての要望があれば教えてください。一緒に更に深い探求を進めていきましょう。
philosophy_researcher: 素晴らしい提案ですね！各トピックについてさらに掘り下げることで、宇宙に対する理解が深まります。以下にそれぞれのテーマに関する具体的な考
察や議論の方向性を示します。

### 1. 宇宙の成り立ちと異なる理論
- **インフレーション理論**:
  - **考察の方向性**: インフレーション理論の歴史的背景や、どのようにしてこの理論が提案されたのか、またそれが観測結果（例えば、宇宙背景放射の均一性）とどのよ 
うに結びついているかを探求します。さらに、近年の観測技術の進歩がこの理論の検証にどのように寄与しているかを考察することも重要です。

- **多宇宙理論**:
  - **考察の方向性**: 多宇宙理論が提起する哲学的課題（存在の多様性、偶然と必然）を議論し、こうした理論が私たちの宇宙観にどのような影響を及ぼすかを考察します 
。多宇宙的な視点が娯楽メディアやフィクション（例えば、「マルチバース」をテーマにしたアニメや映画）にどのように表現されているかも興味深いトピックです。       

### 2. 哲学的視点からの宇宙の存在
- **存在論と宇宙**:
  - **考察の方向性**: 宇宙の存在が持つ意味や、その存在理由を問い直すことが重要です。デカルトやハイデッガーのような哲学者が宇宙の存在に関してどのようなアプロ 
ーチを取っているかを見ながら、存在が個々の経験や認識に与える影響を探ります。

- **環境倫理学**:
  - **考察の方向性**: 宇宙開発が地球環境や宇宙環境に与える影響を分析し、倫理的観点から人類の行動に対する責任を問うことが鍵です。宇宙でのリソース利用が持つ潜 
在的な環境問題について議論し、持続可能な宇宙利用についての視点を加えることができます。

### 3. アニメが描く宇宙のテーマ
- **「宇宙兄弟」と人間ドラマ**:
  - **考察の方向性**: 作品が描く友情や仲間意識が、現実のチームワークやリーダーシップにおける重要性とどのようにリンクしているのかを分析します。また、視聴者に 
与える心理的な影響や感情的共鳴を考察することも可能です。

- **「銀河英雄伝説」とその社会的メッセージ**:
  - **考察の方向性**: この作品が歴史や政治に関する元素をどのように取り入れ、視聴者にどういった批判的思考を促すかを掘り下げます。権力と倫理の問題について、具 
体的なキャラクターの選択とその結果を通じて議論すると良いでしょう。

- **「プラネテス」の倫理的視点**:
  - **考察の方向性**: 宇宙ゴミ問題やそれに伴う倫理的ジレンマに注目し、現実の宇宙開発における倫理的影響と比較します。作品がどのようにして環境意識を高め、視聴 
者に責任を持たせるかについて議論を進めると深みが増します。

これらのトピックをさらに深めて行くことで、宇宙についての理解やより豊かな視点が得られるはずです。特定の項目について詳しく探求したい場合、または他の関連するト 
ピックについても討論したい場合は、お知らせください。共に更に探求を深めていきましょう！

(venv) C:\Users\user\source\repos\AutoGenTest1>
```

### Traceloopでエージェント選択プロンプトの内容を確認
![selector_group_chat_test_02_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3691658/126ece51-9e7d-4b46-ab5f-a7ab980e7d50.png)
![selector_group_chat_test_02_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3691658/c9de4f06-e49f-4863-8173-e557b6264cda.png)

### 感想
*  selector_promptで設定した内容が、エージェント選択プロンプトとして使用されています
*  デフォルトの場合と同様に、science_researcherが哲学、アニメの観点の回答を生成していたりと、適切なエージェントが選択されていないような感じです

---

## selector_func によるエージェント選択処理のカスタマイズ

selector_func を指定することで、エージェント選択処理をカスタマイズできます。  
この場合、デフォルトの selector_msg やユーザーが指定した selector_msg は使用されません。  
以下のような処理に変更してみます。

* 前回の発言者が planner 以外であれば、planner を選択する。  
* 前回の発言者が planner の場合は、[selector_promptによるエージェント選択処理のカスタマイズ](#selector_promptによるエージェント選択処理のカスタマイズ) のプロンプトでエージェントを選択する

### サンプルコード
```python: selector_group_chat_test_03.py
import os, sys, asyncio, json
from typing import Any, Sequence, Union
# openai
from openai import OpenAI
# autogen
from autogen_agentchat.teams import SelectorGroupChat
from autogen_agentchat.ui import Console
from autogen_agentchat.base import TaskResult, ChatAgent
from autogen_agentchat.messages import BaseChatMessage, ChatMessage, AgentEvent
from traceloop.sdk.decorators import workflow # type: ignore

from selector_group_chat_test_00 import create_model_client, create_termination_condition, init_trace, init_env
from selector_group_chat_test_00 import worker_agents, planner


def select_worker_agent(agents: list[ChatAgent], messages: Sequence[AgentEvent | ChatMessage]) -> Union[str, None]:
    """
    Select the worker agent to respond to the user message.
    """
    roles = "\n".join([agent.name + ":" + agent.description for agent in agents])
    participants = ", ".join([agent.name for agent in agents])
    history = "\n".join([f"{message.source}: {message.content}" for message in messages])
    json_format_sample = {"member": "メンバー名"}
    prompt = f"""
    以下の会話は、ユーザーからの指示に基づいてplannerが計画したタスクを遂行するチームのチャットです。
    チームのメンバー名とその役割は次の通りです。{roles} 

    以下の会話を読んでください。タスクの遂行状況を確認して、次のタスクを遂行するために適切なメンバーを{participants}から選んでください。
    出力形式はJSONで、{json_format_sample}としてください。

        {history}
    """
    init_env()
    openai_client = OpenAI(
        api_key=os.getenv("OPENAI_API_KEY")
    )

    response = openai_client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[
            {"role": "user", "content": prompt}
        ],
        response_format={"type": "json_object"}
    )

    content: Union[str, None] = response.choices[0].message.content
    if content is None:
        return None

    return json.loads(content).get("member", None)

@workflow(name=__file__)
async def main(input_message: str):
    # モデルクライアントを作成
    model_client = create_model_client()
    agents = worker_agents + [planner]
    
    # selector_funcでエージェント選択処理をカスタマイズ

    def selector_func(messages: Sequence[AgentEvent | ChatMessage]) -> str | None:
        # 最後のメッセージがplannerからのものでない場合、plannerを選択
        if messages[-1].source != planner.name:
            return planner.name
        else:
            selected_agent_name = select_worker_agent(agents, messages)
            # エージェントが選択されなかった場合、plannerを選択
            if selected_agent_name is None:
                return planner.name

            return selected_agent_name

    # SelectorGroupChatを作成。selector_funcを設定する。
    chat = SelectorGroupChat(
            agents,
            model_client=model_client,
            termination_condition=create_termination_condition("[TERMINATE]", 10, 120),
            selector_func=selector_func
            )

    # グループチャットを実行
    stream = chat.run_stream(task=input_message)
    # await Console(stream)
    async for message in stream:
        if type(message) == TaskResult:
            # TaskResultの場合はチャット終了
            break
        if isinstance(message, BaseChatMessage):
            # メッセージが返された場合、エージェント名とメッセージを表示
            message_str = f"{message.source}: {message.content}"
            print(message_str)

if __name__ == '__main__':
    input_message: str = """
    宇宙について、以下の観点で情報をまとめてください
    * 宇宙の成り立ち
    * 哲学的な視点からの宇宙
    * 宇宙に関するアニメ
    """
    # traceloopによるトレース処理初期化
    init_trace()
    # メイン処理を実行
    asyncio.run(main(input_message))

```

### 実行
```
(venv) C:\Users\user\source\repos\AutoGenTest1>python selector_group_chat_test_03.py 
Traceloop exporting traces to https://api.traceloop.com authenticating with bearer token

user:
    宇宙について、以下の観点で情報をまとめてください
    * 宇宙の成り立ち
    * 哲学的な視点からの宇宙
    * 宇宙に関するアニメ

planner: 計画を立てて、ユーザーの要求を達成するためのタスクリストを作成します。

**タスク一覧:**

1. 宇宙の成り立ちに関する情報をまとめるエージェントを選定し、内容を依頼する
2. 哲学的な視点からの宇宙について情報をまとめるエージェントを選定し、内容を依頼する
3. 宇宙に関するアニメについて情報を収集しまとめるエージェントを選定し、内容を依頼する
4. 各エージェントからの情報を収集し、一つのドキュメントにまとめるエージェントを選定する
5. 最終的な情報をユーザーに提供する準備をする

それぞれのタスクの割り当てに問題がないか、またはもっと効率的な計画がないか、対象エージェントに確認します。      

この計画を進めるために、対象エージェントにタスクを割り当てます。計画作成が完了したら[計画作成完了]と返信します。
science_researcher: 以下に、ユーザーの要求に基づいた宇宙に関する情報をまとめました。

### 1. 宇宙の成り立ち
宇宙の成り立ちは、主にビッグバン理論によって説明されます。この理論によれば、宇宙は約138億年前に非常に高温・高密度の状態から急速に膨張し始め、それが現在のよう
な広がりを持つ宇宙を形成しました。ビッグバン後、最初の数分間に原子核合成が起こり、軽元素（主に水素、ヘリウム）が形成されました。数百万年後、宇宙は冷却され、 
原子が形成され、初めての星や銀河が誕生しました。その後、星の生死や銀河の形成、さらにはブラックホールや暗黒物質の存在などが観測され、宇宙は現在も膨張し続けて 
います。

### 2. 哲学的な視点からの宇宙
宇宙に対する哲学的視点は多岐にわたりますが、主なテーマには「宇宙の起源」「存在の意味」「人間の位置付け」があります。古代ギリシャの哲学者たちは、宇宙が無限で 
あり、自然法則に従って運行していると考えていました。近代哲学では、宇宙の無限性や終わりについての議論が行われ、例えばカントは宇宙の形成や倫理的な観点から人間 
の役割を問いかけています。現代の哲学では、宇宙の終焉や多元宇宙論、科学と哲学の関係性についても議論されています。

### 3. 宇宙に関するアニメ
宇宙をテーマにしたアニメには、科学的な要素を含む作品からファンタジー的なものまで多様です。以下は代表的な作品です：
- **『宇宙兄弟』**：宇宙飛行士を目指す兄弟の成長を描いた作品で、リアルな宇宙の描写が魅力です。
- **『銀河英雄伝説』**：宇宙戦争を背景にした壮大なストーリーで、政治や戦略がテーマとなっています。
- **『Planetes』**：宇宙ゴミの回収作業を行う人々を描き、宇宙を身近に感じさせる作品です。
- **『スタートゥインクルプリキュア』**：宇宙をテーマにした子供向けアニメで、宇宙の神秘や多様性を表現しています。

これらの作品は、宇宙に対する夢や冒険を描きつつ、視聴者に科学的な興味をもたらす要素を含んでいます。

### まとめ
宇宙の成り立ちや哲学的視点、関連するアニメについて広範な知識が必要とされますが、これらの情報を基にさらに興味を深めることができるでしょう。宇宙は常に私たちに 
新たな問いや発見をもたらしていることが分かります。
planner: [計画作成完了]

エージェントからの情報が収集できました。以下の内容でまとめられています。

### 宇宙についての情報

1. **宇宙の成り立ち**
   - ビッグバン理論に基づき、宇宙は約138億年前に高温・高密度の状態から膨張を始めた。
   - 最初の数分で水素とヘリウムが形成された。
   - 数百万年後に原子が形成され、最初の星や銀河が誕生。
   - 現在も宇宙は膨張中で、星や銀河の生成・消失、ブラックホールの存在が観測されている。

2. **哲学的な視点からの宇宙**
   - 古代から現代まで多くの哲学者が宇宙の起源や人間の位置付けについて考察してきた。
   - 宇宙の無限性や終わりに関する議論があり、カントの倫理的な視点も重要。
   - 現代では多元宇宙論や科学と哲学の関係も考察されている。

3. **宇宙に関するアニメ**
   - **『宇宙兄弟』**：宇宙飛行士を目指す兄弟の物語。
   - **『銀河英雄伝説』**：宇宙戦争を舞台にした壮大な物語。
   - **『Planetes』**：宇宙ゴミの回収作業を描く。
   - **『スタートゥインクルプリキュア』**：宇宙の神秘を子供向けに表現した作品。

これらの情報をユーザーに提供する準備ができました。全てのタスクが完了したため、[TERMINATE]と返信いたします。

(venv) C:\Users\user\source\repos\AutoGenTest1> 
```

### Traceloopでエージェント選択プロンプトの内容を確認
![selector_group_chat_test_03_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3691658/126c5c66-ba72-47df-9728-73462801067e.png)
![selector_group_chat_test_03_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3691658/3eb469cb-0aee-439c-b825-434fec636e61.png)

### 感想
*  selector_funcでエージェント選択プロンプトを用いたチャットの結果によりエージェントが選択されています
*  デフォルトの場合と同様に、science_researcherが哲学、アニメの観点の回答を生成してます
*  science_researcherの発言が終わった時点でplannerは全タスクが完了したと判断しています。  
   selector_funcの実装方法が悪いのか、science_researcherが哲学、アニメの観点の回答も行っているから完了と判断したのか、ちょっと調査が必要です

----
## まとめ
AutoGenのSelectorGroupChatでのエージェントを選択動作とカスタマイズ方法について調べました。
デフォルトのエージェント選択動作、selector_promptによるカスタマイズ、selector_funcによるカスタマイズした結果の動作を確認しましたが、
plannerが作成したタスクとは無関係なエージェントが回答することもあるようでした。
デフォルトのエージェント選択動作、selector_promptによるカスタマイズ、selector_funcによるカスタマイズした場合でもそれなりの回答が返ってくる感じですが、
「plannerが作成したタスクを適切なエージェントに割り当てることが出来るか？」という観点では、想定通りの動作には至っていません・・・

ということで、次回はselector_prompt、selector_funcとは別のアプローチとして「エージェントを選択するエージェント」を実装し、検証してみます。

## 備考
今回使用したサンプルのソースは[https://github.com/knd3dayo/AutoGenTest1](https://github.com/knd3dayo/AutoGenTest1)に置いてあります。