AutoGen  エージェントを選択するエージェントの実装

## 概要

[前回](https://qiita.com/knd3dayo/items/33161b95e4906d99bf10)はAIエージェントフレームワーク [AutoGen](https://microsoft.github.io/autogen) の SelectorGroupChatでは具体的にはどのような仕組みでエージェントが選択されるのかと、SelectorGroupChatのselector_prompt、selector_funcによりエージェント処理のカスタマイズを試してみましたが、
今回は計画エージェント(planner)が計画を立てる  ⇒ エージェント選択エージェント（agent_selector)がという仕組みによりエージェントがどのように選択されるかを確認してみたいと思います。

## エージェント選択エージェントの機能
plannerが立てた計画とタスク一覧にマッチする適切なエージェントを選択するための
エージェント選択処理のため以下のツールを作成します。これらのツールをエージェント選択エージェントに持たせます。
* エージェントの情報を提供するツール (list_agents)
  作業用エージェント（science_researcher、philosophy_researcher、anime_researcher）の名前と説明の一覧を返す

* 指定されたエージェントによるチャットを実行するツール (execute_agent)
  指定されたエージェントによるチャットを実行して結果を返す

そして、plannerとagent_selectorでSelectorGroupChatを実行します。

### エージェント選択エージェントのサンプル

```python: selector_group_chat_test_04.py
import os, sys, asyncio
from typing import Annotated
# autogen
from autogen_core.tools import FunctionTool
from autogen_agentchat.agents import AssistantAgent
from autogen_agentchat.messages import BaseChatMessage
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.decorators import workflow # type: ignore

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

# エージェント一覧を取得する関数
def list_agents() -> Annotated[list[dict[str, str]], "List of registered agents, each containing 'name' and 'description'"]:
    """
    This function retrieves a list of registered agents.
    """
    agent_descption_list = []
    for agent in worker_agents:
        agent_descption_list.append({"name": agent.name, "description": agent.description})
    return agent_descption_list

# execute_agent
# エージェントを実行する関数
async def execute_agent(
        agent_name: Annotated[str, "Agent name"], initial_message: Annotated[str, "Input text"],
        ) -> Annotated[str, "Output text"]:
    """
    This function executes the specified agent with the input text and returns the output text.
    First argument: agent name, second argument: input text.
    - Agent name: Specify the name of the agent as the Python function name.
    - Input text: The text data to be processed by the agent.
    """
    # agent_nameに対応するエージェントを取得
    agent_list = [item for item in worker_agents if item.name == agent_name]
    agent = agent_list[0] if len(agent_list) > 0 else None

    if agent is None:
        return "The specified agent does not exist."

    output_text = ""
    # run_agent関数を使用して、エージェントを実行
    async for message in agent.run_stream(task=initial_message):
        if isinstance(message, BaseChatMessage):
            message_str = f"{message.source}(in agent selector): {message.content}"
            # print(message_str)
            output_text += message_str + "\n"

    return output_text

@workflow(name=__file__)
async def main(input_message: str):
    # モデルクライアントを作成
    model_client = create_model_client()
    
    # エージェント選択エージェントを作成
    agent_selector = create_agent(
        name="agent_selector",
        description="他のエージェントを呼び出すエージェント",
        system_message=""""
        list_agentsで呼び出し可能なエージェント一覧を取得します。そして、
        ユーザーの要求にマッチする適切なエージェントを呼び出すことができます。
        """,
        model_client=model_client,
        tools=[
            FunctionTool(execute_agent, execute_agent.__doc__, name = "execute_agent"), # type: ignore
            FunctionTool(list_agents, list_agents.__doc__ ,name = "list_agents") # type: ignore
        ] 
    )
    # 作業用エージェントリストにagent_selectorも含める場合
    # worker_agents.append(agent_selector)

    # plannerとagent_selectorによるグループチャットを作成
    chat = SelectorGroupChat(
            [planner, agent_selector],
            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_04.py 
Traceloop exporting traces to https://api.traceloop.com authenticating with bearer token

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

planner: 以下の計画を作成し、各観点に対するタスクを割り当てます。

### 計画：
1. **宇宙の成り立ちに関する情報収集**
   - ビッグバン理論や宇宙の膨張について調査。
   - 初期の宇宙と元素の形成についてのデータを収集。

2. **哲学的な視点からの宇宙に関する情報収集**
   - 宇宙に対する哲学的問いや理論の調査。
   - 存在論や宇宙の意味についての議論をまとめる。

3. **宇宙に関するアニメの一覧作成**
   - 宇宙をテーマにした代表的なアニメのリストアップ。
   - 各アニメのテーマや特徴についての簡単な紹介を行う。

### タスクの割り当て：
- **エージェントA**：宇宙の成り立ちに関する情報収集を担当。
- **エージェントB**：哲学的な視点からの宇宙に関する情報収集を担当。
- **エージェントC**：宇宙に関するアニメのリスト作成を担当。

各エージェントにタスクを割り当てた後、確認して、もし問題があれば効率的な計画について相談します。その後、タスクを実行します。

## [計画作成完了]
agent_selector: [{'name': 'science_researcher', 'description': '科学知識に関する質問に答えるエージェント'}, {'name': 'philosophy_researcher', 'description': 
'哲学に関する質問に答えるエージェント'}, {'name': 'anime_researcher', 'description': 'アニメに関する質問に答えるエージェント'}]
planner: それでは、各エージェントにタスクを割り当てます。

### タスクの割り当て：
1. **宇宙の成り立ちに関する情報収集**
   - **担当エージェント**: science_researcher

2. **哲学的な視点からの宇宙に関する情報収集**
   - **担当エージェント**: philosophy_researcher

3. **宇宙に関するアニメの一覧作成**
   - **担当エージェント**: anime_researcher

各エージェントにタスクを通知し、進捗を確認します。もし何らかの問題があれば、その都度調整を行います。次に、それぞれのエージェントにタスクを実行してもらいます 
。
agent_selector: user(in agent selector): 宇宙の成り立ちについて、ビッグバン理論や宇宙の膨張、初期の宇宙と元素の形成について情報を収集してください。
science_researcher(in agent selector): 宇宙の成り立ちについての理解は、主にビッグバン理論に基づいています。この理論は、宇宙が約138億年前に非常に高温・高密度 
な状態から急激に膨張したというものです。以下に、ビッグバン理論、宇宙の膨張、初期宇宙、元素の形成についての情報を整理します。

### ビッグバン理論
- **起源:** ビッグバンは、宇宙のすべての物質とエネルギーが一つの点に凝縮していた初期状態から始まるとされます。この状態が「特異点」と呼ばれ、そこから空間と時 
間が創出されたと考えられています。
- **証拠:** ビッグバン理論を支持する証拠には、宇宙背景放射（宇宙の初期に放出された微弱な放射線）、宇宙の赤方偏移（遠くの銀河が私たちから遠ざかっていることの 
証拠）、そして軽元素の存在（後述）があります。

### 宇宙の膨張
- **ハッブルの法則:** エドウィン・ハッブルの観測により、遠方の銀河が私たちから遠ざかる速度は、その距離に比例することが示されました。これにより、宇宙が現在も 
膨張を続けていることが確認されました。
- **膨張のモデル:** 膨張は、宇宙の空間そのものが広がる形で進行しており、銀河同士の距離が広がっていることを意味します。膨張の速度は、宇宙の年齢や密度、ダーク 
エネルギーの状態に依存します。

### 初期の宇宙
- **プランク時代:** ビッグバン直後の最初の10^-43秒の間は「プランク時代」と呼ばれ、この間には現在の物理法則が適用できないと考えられています。
- **ブレイクダウン:** より高エネルギー状態からの冷却に伴い、基本的な素粒子（クォークや電子）が形成され、さらに時間が経つと、これらの粒子が結合して原子核を形 
成します。

### 元素の形成
- **ビッグバン核合成:** 宇宙が誕生してから数分の間に、主に水素（約75%）、ヘリウム（約25%）、微量のリチウムやベリリウムが形成されました。この過程をビッグバン 
核合成と呼びます。この時点で、宇宙の大部分の軽元素はほぼ完成します。
- **恒星の形成:** 約10億年後、宇宙は冷却され、物質が集まり始め、最初の恒星が形成されました。恒星内部での核融合により、より重い元素が生成され、超新星爆発を通 
じて宇宙に放出され、 Subsequent generations of stars and planets were enriched in heavier elements.

宇宙の成り立ちについては、これらの理論や観測が組み合わさって、私たちの理解が形成されています。新しい観測技術が進む中、今後の研究によって新たな発見も期待され 
ています。

user(in agent selector): 宇宙に対する哲学的視点について、存在論や宇宙の意味に関する理論や議論をまとめてください。
philosophy_researcher(in agent selector): 宇宙に対する哲学的視点は、主に存在論、認識論、価値論の3つの観点からアプローチされます。以下に、それぞれの観点に関連
する理論や議論をまとめます。

### 1. 存在論
存在論は、存在や実在についての哲学的探求です。宇宙に対する存在論的議論は、以下のようなテーマを含みます。

- **自然主義 vs. 超越論**: 自然主義は、宇宙のすべてが自然法則に従うものであり、超自然的な説明は不要と主張します。一方、超越論は、宇宙の外にある存在（神や霊的
な存在）を考慮します。

- **実体論と関係論**: 宇宙は何から成り立っているのかという問いに対し、実体的存在（物質的な実体）を前提とする実体論と、関係性や相互作用を重視する関係論があり 
ます。

- **多宇宙論**: 物理学に基づく宇宙の理解が進む中で、異なる宇宙が存在する可能性についての議論（例えば、インフレーション理論による多宇宙モデル）が存在します。 
これに伴い、存在の定義や意味が問われています。

### 2. 宇宙の意味
宇宙の意味についての哲学的議論は、人間の存在や宇宙そのものの意義を探ります。

- **目的論 vs. 無目的論**: 宇宙には何らかの目的があるとする立場（目的論）と、単に存在するだけで意味がないという立場（無目的論）との対立があります。

- **ヒューマニズムと宇宙観**: 人間中心的な視点から見ると、宇宙の意味は人間の経験や存在に基づきます。この観点からは、科学や芸術などが宇宙を理解し、意味を見出 
す手段とされます。

- **存在の不条理**: アルベール・カミュのように、宇宙の無意味さを受け入れながら自己の意義を見出そうとする哲学も存在します。彼は「反抗」の重要性を強調します。 

### 3. 認識論
認識論は、知識の起源と限界を探る分野であり、宇宙に対する人間の理解や認識の方法に関係します。

- **科学的認識の限界**: 科学が提供する知識が真理に近づく手段である一方で、感覚や理性がどこまで信用できるのか、また科学そのものの前提条件についての反省も重要 
です。

- **主観と客観**: 宇宙の理解には客観的なデータが必要ですが、それを解釈する過程において主観的な経験がどう影響するかが議論されています。

### 結論
宇宙に対する哲学的視点は多様であり、存在の本質、宇宙の意味、知識の方法についてさまざまな理論や議論が展開されています。これらの視点は、科学的探求とも相互に作 
用しながら、私たちの宇宙観や存在理解を深めています。

user(in agent selector): 宇宙をテーマにしたアニメの代表例をリストアップし、それぞれのテーマや特徴について簡単に紹介してください。
anime_researcher(in agent selector): 宇宙をテーマにしたアニメは多岐にわたります。以下に代表的な作品をいくつか挙げ、そのテーマや特徴について簡単に紹介します。

1. **機動戦士ガンダム（Mobile Suit Gundam）**
   - **テーマ**: 人間の conflict and war, 宇宙移民
   - **特徴**: モビルスーツと呼ばれる巨大ロボットを使用した戦争を描いています。人間の感情や葛藤、宇宙での生存を巡る争いが展開され、ロボットアニメの金字塔とな
っています。

2. **銀河英雄伝説（Legend of the Galactic Heroes）**
   - **テーマ**: 政治、戦争、歴史
   - **特徴**: 銀河を舞台にした壮大な戦争ドラマ。帝国と民主主義共和国の対立を描き、深い人間ドラマと政治的な駆け引きが魅力的です。

3. **銀魂（Gintama）**
   - **テーマ**: 科学、異星人との共存、時代劇
   - **特徴**: 江戸時代に異星人が訪れるという設定を持つコメディアニメ。宇宙の要素と日本の伝統文化が混ざり合い、バラエティに富んだストーリーが展開されます。  

4. **宇宙よりも遠い場所（A Place Further Than the Universe）**
   - **テーマ**: 冒険、友情、青春
   - **特徴**: 南極を目指して旅する高校生たちの物語。宇宙ではなく、地球の極地が舞台ですが、探索の精神や冒険がテーマとして強調されています。

5. **スペース☆ダンディ（Space Dandy）**
   - **テーマ**: SFコメディ、異星人
   - **特徴**: 宇宙を舞台にしたユニークなSFコメディ。主人公のダンディが奇妙な宇宙生物を探して旅する中で、様々なエピソードや世界観が展開される。

6. **スタートゥインクルプリキュア（Star Twinkle Precure）**
   - **テーマ**: 宇宙、友情、成長
   - **特徴**: 宇宙を舞台にしたプリキュアシリーズ。異星の友達と共に冒険し、友情や自己発見がテーマになっています。

7. **エウレカセブン（Eureka Seven）**
   - **テーマ**: 恋愛、戦争、環境問題
   - **特徴**: 人と異なる存在との恋愛や戦争を交えたストーリー。宇宙と地球の間での環境問題とそれに向き合う若者たちが描かれています。

これらの作品はそれぞれ異なる視点から宇宙を描いており、ジャンルやテーマの幅も広いものとなっています。それぞれの作品が独自の魅力を持っているため、視聴者にとっ 
て多様な楽しみ方ができるでしょう。

planner: 以下に、ユーザーからの要求に基づいて、宇宙に関する情報をまとめました。

### 宇宙の成り立ち
- **ビッグバン理論**:
  宇宙が約138億年前に高温・高密度な状態から急激に膨張したことを示す理論。証拠としては宇宙背景放射や宇宙の赤方偏移がある。

- **宇宙の膨張**:
  エドウィン・ハッブルの観測により、遠方の銀河が遠ざかる速度は距離に比例することが確認され、宇宙が現在も膨張を続けている。

- **初期の宇宙**:
  ビッグバン直後の状態から、基本的な素粒子が形成され、やがて原子核が構成される過程が展開される。

- **元素の形成**:
  ビッグバンから数分間にわたる核合成で、主に水素とヘリウムなどの軽元素が形成され、恒星による重い元素の生成に繋がる。

### 哲学的視点からの宇宙
- **存在論**:
  自然主義（宇宙のすべては自然法則に従う）と超越論（宇宙の外にある存在を考慮）についての議論。

- **宇宙の意味**:
  宇宙には何らかの目的があるとする目的論と、無意味であるとする無目的論の対立。

- **認識論**:
  科学的理解の限界や、宇宙の理解における主観と客観の関係が探求される。

### 宇宙に関するアニメ
1. **機動戦士ガンダム**: モビルスーツを使った戦争を描いたロボットアニメ。人間の感情や葛藤がテーマ。
2. **銀河英雄伝説**: 銀河を舞台にした壮大な戦争ドラマ。政治的な対立と深い人間ドラマが魅力。
3. **銀魂**: 江戸時代に異星人が訪れる設定のコメディ。宇宙と日本の伝統文化が融合。
4. **宇宙よりも遠い場所**: 南極を目指す冒険の物語。探索精神や友情がテーマ。
5. **スペース☆ダンディ**: 宇宙生物を探すSFコメディ。ユニークなエピソードが展開される。
6. **スタートゥインクルプリキュア**: 宇宙を舞台にした冒険と友情の物語。
7. **エウレカセブン**: 異なる存在との恋愛や環境問題を扱ったストーリー。

これで、ユーザーの要求に対する情報がまとめられました。全てのタスクが完了しましたので、[TERMINATE]とさせていただきます。

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

### Traceloopでエージェント選択プロンプトの内容を確認
![selector_group_chat_test_04_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3691658/a41ac66d-0acd-44bb-aea4-d6ba2130696a.png)
![selector_group_chat_test_04_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3691658/2d9b77a4-d125-4ce6-a69a-848da0e0f2a9.png)
![selector_group_chat_test_04_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3691658/e17d268a-6372-4047-9ad7-9373a2f43a68.png)


実行結果を見てみると、

1. planner が立てた計画を一度 agent_selector に渡して、タスクに具体的なエージェント名を設定しています。  
  これは planner の system_message に「タスク割り当てに問題ないか各エージェントに確認する」という指示を入れているからかと思われますが、  
  それにより agent_selector が適切なエージェントを呼び出すことができているようです。
2. planner が立てた計画に従い、agent_selector が作業用エージェント（science_researcher、philosophy_researcher、anime_researcher）を順次呼び出していることが分かります。  
  当初は、planner ⇒ agent_selector（science_researcher を実行）⇒ planner といった具合に、都度 planner に戻るかと思っていましたが、agent_selector 内でツール（execute_agent）を複数回呼び出しており、  
  planner が立てた計画を一気に実行しているようなイメージです。


## plannerに予めエージェント情報を渡してみた場合はどうなるか
上記のサンプルでは、
1. planner が立てた計画とタスク一覧を作成する
2. agent_selectorがタスク一覧を確認してタスクに具体的なエージェント名を含めたタスク一覧に修正する。
3. そのタスクをagent_selectorがexecute_agentツールを用いて実行する
という流れでした。
plannerが作成したタスク一覧にagent_selectorが具体的なエージェント名を含める処理を行っていますが、plannerのsystemメッセージに予めエージェント情報を渡してみた場合はどうなるんでしょうか？

以下のサンプルで試してみました。

### plannerのsystemメッセージにエージェント情報を含めたサンプル
```python: selector_group_chat_test_05.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, create_agent
from selector_group_chat_test_00 import worker_agents


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

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

    agents = worker_agents + [planner]
    
    # plannerとagent_callerによるグループチャットを作成
    selector_prompt: str = """
    以下の会話は、ユーザーからの指示に基づいてplannerが計画したタスクを遂行するチームのチャットです。
    チームのメンバー名とその役割は次の通りです。{roles} 

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

        {history}

    """ 
    
    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_05.py
Traceloop exporting traces to https://api.traceloop.com authenticating with bearer token

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

planner: まず、ユーザーの要求を達成するための計画を立てます。以下の観点で情報をまとめるために、各エージェントにタスクを割り当てます。

### タスク一覧

1. **宇宙の成り立ち**
   - 担当エージェント: science_researcher
   - 内容: 宇宙の起源やビッグバン理論、宇宙の進化についての情報をまとめてもらう。

2. **哲学的な視点からの宇宙**
   - 担当エージェント: philosophy_researcher
   - 内容: 宇宙についての哲学的考察、例えば宇宙の存在意義や人間の位置づけについての考えをまとめてもらう。

3. **宇宙に関するアニメ**
   - 担当エージェント: anime_researcher
   - 内容: 宇宙をテーマにしたアニメ作品やその特徴、影響等についてまとめてもらう。

タスクの割り当てに問題がないか、対象エージェントに確認します。
science_researcher: それでは、以下の観点について情報をまとめます。

### 宇宙の成り立ち
宇宙の成り立ちは、主にビッグバン理論によって説明されています。この理論によれば、宇宙は約138億年前に非常に高温・高密度の状態から急膨張を始 
め、現在のような広がりを持つようになったとされています。最初はプラズマ状態の宇宙が、約38万年後に冷却されることで原子が形成され、光が自由に
移動できる状態になりました。この時期が「再結合」と呼ばれ、現在の宇宙背景放射が生じています。その後、重力によって物質が集まり、星や銀河が形
成され、今日見られるような宇宙構造が出来上がりました。

### 哲学的な視点からの宇宙
哲学的には、宇宙の存在意義やその本質についてさまざまな議論があります。古代ギリシャの哲学者たちは、宇宙は存在する理由があるのか、人間の認識
によって成立するものなのかを考察しました。また、近代になると、宇宙が物理法則に従う体系として理解される一方で、人間と宇宙の関係や存在の根本
的な意味についても議論が続いています。存在論や宇宙論の視点からは、なぜ宇宙が存在するのかという根本的な問いが常に取り上げられています。    

### 宇宙に関するアニメ
宇宙をテーマにしたアニメは多岐にわたります。一部の代表作には、以下のようなものがあります：
- **「銀河鉄道999」**: 宇宙を旅しながら冒険するストーリー。
- **「宇宙兄弟」**: 宇宙飛行士を目指す兄弟の物語を通じて、宇宙への夢や人間関係が描かれる。
- **「新世紀エヴァンゲリオン」**: 未来の人類と宇宙の存在に対する哲学的な問いを含んだ作品。
- **「プラネテス」**: 宇宙のゴミ処理をテーマにした、リアルな宇宙活動を描写した作品。

これらの作品は、宇宙の神秘や人間の存在、未来への希望など、さまざまなテーマを扱っています。
planner: 次に、哲学的な観点からの宇宙について、philosophy_researcherに確認します。
philosophy_researcher: ### 哲学的な視点からの宇宙

宇宙を哲学的に考察する際には、以下の重要なテーマに注目することができます。

1. **存在論**:
   存在論は「何が存在するのか？」という問いに取り組みます。宇宙の存在自体がどのように説明されるべきか、宇宙が必然的に存在するのか、それと 
も偶然の産物なのかという議論が展開されます。例えば、ライプニッツは「なぜ宇宙が存在するのか」という問いかけを通じて、神が宇宙を創造した理由
を求めました。

2. **宇宙の起源**:
   哲学者たちは、宇宙の起源についても多様な見解を持っています。ビッグバン理論に基づく科学的理解を反映した考察や、創造論などの宗教的視点が 
交わる中で、宇宙がどのようにして生まれたのかを考えることは哲学的に重要です。

3. **人間の位置づけ**:
   宇宙における人間の位置づけや役割についても重要なテーマです。人間は宇宙の一部でありながら、宇宙を認識し理解できる存在でもあります。この 
二重性は、ヒューメンやカントの思想に見られる、人間中心主義と宇宙的視点の相克を表しています。

4. **宇宙の目的と意義**:
   「宇宙には目的があるのか？」という問いは、古代から現代にかけて多くの哲学者が探求してきました。宇宙が偶然の結果であったのか、ある目的に 
従って存在しているのかという議論は、倫理や存在の意義に関わる深い問いです。

5. **非ユークリッド的な宇宙観**:
   近代以降、一部の哲学者は非ユークリッド的な宇宙観を受け入れ、宇宙が必ずしも直線的または静的なものでないことを考えるようになりました。こ 
れは、たとえば、相対性理論や量子力学に影響を受けたものであり、時間や空間に対する認識を根本から変える要因となっています。

このように、宇宙に対する哲学的視点は、存在についての問いや人間の経験、知識を深く掘り下げることにつながります。宇宙は単なる物理的な現象では
なく、私たちの存在の根源に関わる重要なテーマとして、多くの哲学者による探究が続けられています。
planner: 次に、宇宙に関するアニメについて、anime_researcherからの情報を確認します。
anime_researcher: ### 宇宙に関するアニメ

宇宙をテーマにしたアニメは、さまざまなジャンルやアプローチで描かれています。以下は主な作品とその特徴です。

1. **「銀河鉄道999」**
   - **概要**: 未来の宇宙旅行を舞台にした物語で、主人公は「永遠の命」を手に入れるために銀河鉄道に乗ります。宇宙を旅しながら、人々との出会 
いや様々な冒険を通じて、生命の意味や死について考えさせられます。
   - **テーマ**: 人生や死、希望と絶望をテーマにした深いストーリーが展開されます。

2. **「宇宙兄弟」**
   - **概要**: 兄弟二人の宇宙飛行士の夢を追い求める物語。彼らは宇宙への情熱を持ち続けながら、仲間や家族との関係を築いていきます。
   - **テーマ**: 宇宙という大舞台を通じて、友情・努力・夢の重要性を描いています。

3. **「新世紀エヴァンゲリオン」**
   - **概要**: 地球を守るために人類が戦う姿を描いた作品で、精神的な葛藤や人間関係がポイント。未来の人類と宇宙の存在に対する哲学的な問いを 
含むストーリーとなっています。
   - **テーマ**: 戦争、存在、アイデンティティを絡めた複雑な物語が特徴です。

4. **「プラネテス」**
   - **概要**: 宇宙ゴミ（スペースデブリ）を処理する宇宙作業員たちの日常を描いたリアルな作品。新しい宇宙活動の現実と人間関係に焦点を当てて 
います。
   - **テーマ**: 宇宙開発の社会的側面や個人の夢、努力を描写しており、リアリズムが強調されています。

5. **「時をかける少女」**
   - **概要**: 主人公が時間を旅するストーリーですが、未来や宇宙を関連付けたテーマを含んでいます。彼女の選択が未来にどう影響を与えるのかを 
探求します。
   - **テーマ**: 時間と空間の相互作用を考察し、人間の選択が持つ力について描かれています。

これらの作品は、宇宙そのものだけでなく、宇宙を通じて人間の精神や倫理、夢についての深い探求を行っています。宇宙は単に物理的な環境として存在
するだけでなく、多くの場合、哲学的な視点や人間の感情を反映する重要な舞台となっています。
planner: 以上の情報をまとめました。

### 宇宙に関する情報まとめ

1. **宇宙の成り立ち**
   - 宇宙は約138億年前にビッグバンから始まり、高温・高密度から急膨張を経て、現在の形に進化しました。最初はプラズマ状態で、約38万年後に冷却
され原子が形成され、宇宙背景放射が生じました。その後、物質が集まり星や銀河が形成され、現在の宇宙構造が生まれました。

2. **哲学的な視点からの宇宙**
   - 存在論では宇宙の存在意義や起源、人間の位置づけ、目的について議論されます。宇宙が偶然なのか必然なのか、また宇宙には目的があるのかとい 
う問いが深く探求されています。人間と宇宙の関係性や、非ユークリッド的な宇宙観も重要なテーマです。

3. **宇宙に関するアニメ**
   - 「銀河鉄道999」：宇宙旅行を通じて生命の意味を考察。
   - 「宇宙兄弟」：宇宙飛行士を目指す兄弟の友情や努力を描く。
   - 「新世紀エヴァンゲリオン」：人類と宇宙の存在に関する哲学的な問いを含むストーリー。
   - 「プラネテス」：宇宙ゴミを処理する作業員の日常と夢を描写。
   - 「時をかける少女」：時間と空間の関係を探求する。

これにより、宇宙に関する多角的な情報を提供できました。何か他に知りたいことがあれば教えてください。

[計画作成完了]
science_researcher: 素晴らしいまとめですね！宇宙に関する幅広い視点が網羅されていて、特に成り立ちから哲学的な見解、そしてアニメ作品の紹介ま
でがバランスよく組み込まれています。もし、さらに詳しい情報が必要な観点や特定の質問、あるいは他のテーマに関する知識を求めている場合は、お気
軽にお知らせください！
planner: ありがとうございます！もし他に知りたいことや、新しいテーマについて調べたいことがありましたら、いつでもお知らせください。私たちは
お手伝いする準備が整っています！何か気になることはありますか？
```
### Traceloopでエージェント選択プロンプトの内容を確認
* plannerのsystemメッセージ

![selector_group_chat_test_05_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3691658/f64540ef-d7eb-4bf2-b237-68af098a3db3.png)
![selector_group_chat_test_05_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3691658/31f11428-d971-4654-ba87-2c2113c211fc.png)

* system_promptによるエージェント選択では、チャット履歴(タスク一覧とどのタスクまで完了しているか）から、次のエージェントが適切に選択されています

![selector_group_chat_test_05_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3691658/02364fcd-ec56-4168-9479-389b78061e5f.png)
![selector_group_chat_test_05_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3691658/c512bd64-f2a2-4c9d-a9b4-5f29ae594494.png)
![selector_group_chat_test_05_05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3691658/bb9f3d78-babd-4b0f-b5b4-57f09bfb2ee7.png)

実行結果を見てみると、
1. plannerのsystemメッセージに具体的なエージェント情報が含まれていることにより、エージェント選択エージェントが無くても、具体的なエージェントが指定されたタスク一覧を生成できました
2. エージェントの選択はselector_promptにより行われますが、計画とタスク一覧と他のエージェントの会話履歴から、次はどのエージェントを選択すべきかの判断が行われています

##  まとめ
* AutoGenのSelectorGroupChatでのエージェント選択処理をselector_promptなどに任せる代わりに、エージェント選択用のエージェントを用意することで計画にマッチしたエージェントが適切に選択されることを確認しました
* 計画エージェント(planner)のsystemメッセージに作業用のエージェントの情報を渡すことでも適切なエージェントが選ばれることを出来ました
* 要は計画エージェントが立てる計画、タスク一覧に具体なエージェント名が含まれていればよい、適切なエージェントが選択されるかは計画の立て方・具体性次第なのかもしれません


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