AutoGen の SocietyOfMindAgent によるネスト型マルチエージェント構成(GraphFlow)


AutoGen v0.5.6 に `GraphFlow` が追加されワークフローを定義可能なったということで、より複雑なマルチエージェント構成を考えてみます。AutoGen を愛用しているユーザーにとっては、`GraphFlow` と既存の自律性の高い `SelectorGroupChat` や `RoundRobinGroupChat` と組み合わせてみたいと考えるのは自然かと思います。

https://qiita.com/nohanaga/items/60c66935d75d3dbc48e2

[Azure OpenAI Developers Seminar 2025](https://youtu.be/jHW6zcIzm7g?feature=shared&t=3579) においても複合型のデザインパターンを解説しましたが、実際にこれらの実装を行います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/8848a425-4a53-4b85-af77-51c549955829.png)




# 全体フロー(GraphFlow)
```mermaid
flowchart TD
    A["🖋️ Writer Agent<br/>小説家"] --> B["🔍 Critic Team<br/>批判的評価チーム"]
    A --> C["💡 Progressive Team<br/>肯定的評価チーム"]
    B --> D["📋 Summary Agent<br/>あらすじ作成"]
    C --> D
    
    classDef writer fill:#e1f5fe,stroke:#01579b,stroke-width:3px
    classDef critic fill:#fce4ec,stroke:#880e4f,stroke-width:2px
    classDef progressive fill:#e8f5e8,stroke:#1b5e20,stroke-width:2px
    classDef summary fill:#fff3e0,stroke:#e65100,stroke-width:3px
    
    class A writer
    class B critic
    class C progressive
    class D summary
```

# チーム編成
`RoundRobinGroupChat` で 2 つの井戸端会議的パターンを定義。例として批判的評価チームと肯定的評価チームに分けてみました。実際は各 `AssistantAgent` には適切なロールとナレッジ、アクションをアタッチします。今回は簡単のため、`TextMessageTermination("critic_agent3")` のようにして会話終了条件を 3 人目のエージェントが発言したら終了するようにしました。


```mermaid
flowchart TD



    %% 肯定チーム内部構造（サブグラフ）- 閉パス（サイクリック）
    subgraph progressive ["💡 肯定的評価チーム (RoundRobin)"]
        direction TB
        PA1["progressive_agent1<br/>✨ 肯定的観点から評価"]
        PA2["progressive_agent2<br/>🚀 先進的アイデア提案"]
        PA3["progressive_agent3<br/>📚 生ける百科事典<br/>俯瞰的視点から評価"]
        
        PA1 --> PA2
        PA2 --> PA3
        PA3 --> PA1
    end
    
    %% 批判チーム内部構造（サブグラフ）- 閉パス（サイクリック）
    subgraph critic ["🔍 批判的評価チーム (RoundRobin)"]
        direction TB
        CA1["critic_agent1<br/>💢 批判的観点から評価"]
        CA2["critic_agent2<br/>⚠️ リスクアドバイザー<br/>炎上リスク評価"]
        CA3["critic_agent3<br/>⚖️ 法学スペシャリスト<br/>法的観点から評価"]
        
        CA1 --> CA2
        CA2 --> CA3
        CA3 --> CA1
    end
    
    %% スタイリング
    classDef writerStyle fill:#e1f5fe,stroke:#01579b,stroke-width:3px
    classDef criticStyle fill:#fce4ec,stroke:#880e4f,stroke-width:2px
    classDef progressiveStyle fill:#e8f5e8,stroke:#1b5e20,stroke-width:2px
    classDef summaryStyle fill:#fff3e0,stroke:#e65100,stroke-width:3px
    
    class WA writerStyle
    class SOM1,CA1,CA2,CA3 criticStyle
    class SOM2,PA1,PA2,PA3 progressiveStyle
    class SA summaryStyle

    
```

## エージェント定義(SocietyOfMindAgent)
Agent Specific な `tools` や `memory` は省略しています。
```python
from autogen_agentchat.ui import Console
from autogen_agentchat.agents import AssistantAgent, SocietyOfMindAgent
from autogen_ext.models.openai import OpenAIChatCompletionClient
from autogen_agentchat.teams import RoundRobinGroupChat
from autogen_agentchat.conditions import TextMessageTermination  

# Create the final reviewer agent
writer_agent = AssistantAgent(
    "writer_agent",
    model_client=model_client,
    system_message="あなたはプロの小説家です。魅力的な文章を完結なタッチで書くことができます。",
)

# Create the final reviewer agent
critic_agent1 = AssistantAgent(
    "critic_agent1",
    model_client=model_client,
    system_message="作成された文章を批判的な観点から評価し、改善点を提案すること。",
)

# Create the final reviewer agent
critic_agent2 = AssistantAgent(
    "critic_agent2",
    model_client=model_client,
    system_message="あなたはリスクアドバイザーです。作成された文章のアイデア被りやSMS等で炎上しないかどうかを評価し、改善点を提案すること。",
)

# Create the final reviewer agent
critic_agent3 = AssistantAgent(
    "critic_agent3",
    model_client=model_client,
    system_message="あなたは法学のスペシャリストです。作成された文章を法的観点から評価し、改善点を提案すること。",
)

# add agents to array
critic_agents: List[AssistantAgent] = [
    critic_agent1,
    critic_agent2,
    critic_agent3,
]

termination_condition = TextMessageTermination("critic_agent3") #3人目が発言したら終了
critic_team = RoundRobinGroupChat(critic_agents, termination_condition=termination_condition)


# Create the final reviewer agent
progressive_agent1 = AssistantAgent(
    "progressive_agent1",
    model_client=model_client,
    system_message="作成された文章を肯定的な観点から評価し、改善点を提案すること。",
)

# Create the final reviewer agent
progressive_agent2 = AssistantAgent(
    "progressive_agent2",
    model_client=model_client,
    system_message="あなたは先進的なアイデアを持っています。作成された文章を肯定的に評価し、品質を向上させるアイデアを提案すること。",
)

# Create the final reviewer agent
progressive_agent3 = AssistantAgent(
    "progressive_agent3",
    model_client=model_client,
    system_message="あなたは生ける百科事典です。作成された文章を万物を理解している俯瞰的視点から評価し、作品背景をよりリッチで深みのあるものにするために提案すること。",
)

# add agents to array
progressive_agents: List[AssistantAgent] = [
    progressive_agent1,
    progressive_agent2,
    progressive_agent3,
]

termination_condition = TextMessageTermination("progressive_agent3") #3人目が発言したら終了
progressive_team = RoundRobinGroupChat(progressive_agents, termination_condition=termination_condition)

society_of_mind_agent1 = SocietyOfMindAgent("society_of_mind1", team=critic_team, model_client=model_client)
society_of_mind_agent2 = SocietyOfMindAgent("society_of_mind2", team=progressive_team, model_client=model_client)


# Create the final reviewer agent
summary_agent = AssistantAgent(
    "summary_agent",
    model_client=model_client,
    system_message="作成された文章を簡潔なあらすじにして出力すること。",
)
```

# GraphFlow 定義
[並行ファンアウト/ファンイン](https://qiita.com/nohanaga/items/60c66935d75d3dbc48e2#2-%E7%B5%90%E5%90%88%E3%81%AB%E3%82%88%E3%82%8B%E4%B8%A6%E5%88%97%E3%83%95%E3%83%AD%E3%83%BC%E4%B8%A6%E5%88%97%E3%83%95%E3%82%A1%E3%83%B3%E3%82%A2%E3%82%A6%E3%83%88)パターンを実装します。


```python
# Build the workflow graph
builder = DiGraphBuilder()
builder.add_node(writer_agent).add_node(society_of_mind_agent1).add_node(society_of_mind_agent2).add_node(summary_agent)

# Fan-out from writer to editor1 and editor2
builder.add_edge(writer_agent, society_of_mind_agent1)
builder.add_edge(writer_agent, society_of_mind_agent2)

# Fan-in both editors into final reviewer
builder.add_edge(society_of_mind_agent1, summary_agent)
builder.add_edge(society_of_mind_agent2, summary_agent)

# Build and validate the graph
graph = builder.build()

# Create the flow
flow = GraphFlow(
    participants=builder.get_participants(),
    graph=graph,
)
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/ae6ead60-b637-457d-b0b1-3a05cab2d1d3.png)


```python
stream = flow.run_stream(task="SEが異世界に転生して無双する異世界転生系短編小説を書いてください。")
await Console(stream)
```

# トレース解析から分かる実際のフロー

```mermaid
flowchart TD
    %% メインエージェント
    WA["📝 Writer Agent<br/>プロの小説家"]
    
    %% 批判的評価エージェント群
    CA1["📊 Critic Agent 1<br/>批判的観点から評価"]
    CA2["⚠️ Critic Agent 2<br/>リスクアドバイザー"]
    CA3["⚖️ Critic Agent 3<br/>法学スペシャリスト"]
    CA4["SocietyOfMindAgent1<br/>結果集約"]
    
    %% 肯定的評価エージェント群
    PA1["✨ Progressive Agent 1<br/>肯定的観点から評価"]
    PA2["🚀 Progressive Agent 2<br/>先進的アイデア提案"]
    PA3["📚 Progressive Agent 3<br/>生ける百科事典"]
    PA4["SocietyOfMindAgent2<br/>結果集約"]
    
    %% 最終要約エージェント
    SA["📋 Summary Agent<br/>あらすじ作成"]
    
    %% メインフロー - 個別エージェントレベル
    WA --> CA1
    WA --> PA1
    
    %% 批判的評価チェーン（RoundRobin）
    CA1 --> CA2
    CA2 --> CA3
    CA3 --> CA1
    CA3 --> CA4
    
    %% 肯定的評価チェーン（RoundRobin）
    PA1 --> PA2
    PA2 --> PA3
    PA3 --> PA1
    PA3 --> PA4
    
    %% 終了エージェントから要約へ
    CA4 --> SA
    PA4 --> SA
    
    %% スタイリング
    classDef writerStyle fill:#e1f5fe,stroke:#01579b,stroke-width:3px
    classDef criticStyle fill:#fce4ec,stroke:#880e4f,stroke-width:2px
    classDef progressiveStyle fill:#e8f5e8,stroke:#1b5e20,stroke-width:2px
    classDef summaryStyle fill:#fff3e0,stroke:#e65100,stroke-width:3px
    
    class WA writerStyle
    class CA1,CA2,CA3 criticStyle
    class PA1,PA2,PA3 progressiveStyle
    class SA summaryStyle
```



# SocietyOfMindAgent
ソサイアティ・オブ・マインド（多重思考）の名前の通り、複数のエージェントが協働してまず内部で議論し、その**議論の要旨をもとに最終的な回答だけを LLM に生成させる**という役割を担うエージェントです。`SocietyOfMindAgent1` には 3つのエージェントを含む `RoundRobinGroupChat` を内部チームとして含めていますが、チームの議論終了後に `SocietyOfMindAgent` が議論の結果を集約するのがポイントです。


## System Prompt
*DEFAULT_RESPONSE_PROMPT* = """
元のリクエストに対して、中間での議論を一切言及せずに独立した回答を出力します。
"""

## SocietyOfMindAgent1 集約結果例
Critic Agent 1~3 までの評価結果をコンテキストとして集約を実行している。

>ご依頼の異世界転生×SE（システムエンジニア）無双短編小説に対する総合的な評価と、今後の改善ポイントを以下にまとめます。
>### 総合評価
>本作は、現実世界のSE（システムエンジニア）が異世界に転生し、現代の知識やスキルで問題を次々に解決していく「無双」系の定番構成と言えます。エラーやデバッグなどIT用語をうまく取り入れるギャグ展開やイベントは、ライトな読み味を目指すうえで有効です。しかし、題材・発想の面で既視感が強く、他作品との差別化に課題が見受けられます。主人公の心理描写や世界観の掘り下げもやや浅く、物語の印象や読後感に深みを持たせる余地があります。
>法的にも現段階で大きな問題点はありませんが、今後商業展開などを考える場合は固有性や独自世界観の強化が望ましいです。
>### 改善点・アドバイス
>中略
>1. **オリジナル要素の強化**
>2. **主人公とキャラクター性の掘り下げ**
>3. **万能スキルからの脱却**
>4. **世界観や用語設定の一貫性・説得力強化**
>5. **固有名詞・描写の配慮**
>### まとめ
>
>表現やアイデアの工夫によって、既存ジャンルの枠を超えた魅力的な作品へと発展させる余地は十分にあります。主人公や異世界、その両者の関係性を深掘りし、システムエンジニアの視点を活かした唯一無二の物語を目指してください。また、投稿サイトや出版の運用規則等も事前に確認し、リスク要因を把握のうえで創作を進めることをおすすめします。


# 自律性＋ワークフロー＝😎
夢が広がる


# 参考

https://microsoft.github.io/autogen/stable/reference/python/autogen_agentchat.agents.html#autogen_agentchat.agents.SocietyOfMindAgent


https://qiita.com/nohanaga/items/60c66935d75d3dbc48e2