OpenAI Agents SDK でエージェントのグラフ表現を dot から Mermaid に変換させた

# はじめに

OpenAI Agents SDK は、いわゆる「AI エージェント」を作るための SDK です。この記事では、実際に動作を確認しながら重要なポイントや興味深い点を書きます。

## OpenAI Agents SDK の紹介


OpenAI Agents SDK 公式ドキュメントの「[はじめに](https://openai.github.io/openai-agents-python/ja/)」から引用します。

> OpenAI Agents SDK は、軽量で使いやすく、抽象化を最小限に抑えたエージェントベースの AI アプリケーションを構築できるようにします。これは、以前のエージェント実験である Swarm を本番環境向けにアップグレードしたものです。Agents SDK は非常に少数の基本コンポーネント（primitives）で構成されています。
>
> - エージェント : instructions と tools を備えた LLM
> - ハンドオフ : 特定のタスクを他のエージェントに委任する仕組み
> - ガードレール : エージェントへの入力を検証する仕組み
>
>これらの基本コンポーネントを Python と組み合わせることで、ツールとエージェント間の複雑な関係を表現でき、急な学習曲線なしに実世界のアプリケーションを構築できます。さらに SDK には、エージェントのフローを視覚化・デバッグし、評価やモデルのファインチューニングまで可能にする組み込みの トレーシング 機能が備わっています。


要するに AI エージェントアプリを作ることができる、シンプルな SDK です。


また、OpenAI Platform 公式ドキュメントの[Agents のページ](https://platform.openai.com/docs/guides/agents)によると、

> エージェントの構築には、モデル、ツール、知識と記憶、音声、ガードレール、オーケストレーションなど、複数のドメインにわたるコンポーネントの組み立てが必要です。OpenAI は、各ドメインに対して、組み合わせ可能なプリミティブを提供しています。

| ドメイン |	説明	 | OpenAI の提供要素 |
| --- |--- |---| 
|Model | 推論、意思決定、さまざまなモダリティの処理が可能な、中核となる知能 | o1, o3-mini, GPT-4.5, GPT-4o, GPT-4o-mini|
|Tool | 外部とのインターフェース。環境との対話、関数呼び出し、組み込みツールなど | 関数呼び出し、Web検索、ファイル検索、コンピュータ利用|
|Knowledge and memory | 外部の永続的な知識でエージェントを強化 | ベクターストア、ファイル検索、埋め込み|
|Audio and speech | 音声を理解し、自然言語で応答できるエージェントを作成 | 音声生成、リアルタイム音声、音声エージェント|
|Guardrails| 不適切、有害、または望ましくない動作を防止 | モデレーション、指示階層|
| Orchestration | エージェントの開発、デプロイ、監視、改善 | Agents SDK、トレース、評価、ファインチューニング|


と記載されています。扱いが小さいですが、Orchestration に Agents SDK があります。

Agents SDK を利用することで、OpenAI の様々な機能(Model、Tool、Knowledge、Audio)を柔軟に組み合わせたアプリを開発できるようです。


# 背景と目的

OpenAI Agents SDK には、エージェント間の連携構造を Graphviz を使って可視化する便利な機能 (agents.extensions.visualization) があります。しかし、生成されるのは画像データや Graphviz dot 形式のテキストであり、ドキュメントや README などに埋め込みやすい Mermaid 形式で扱いたい場面もあります。

そこで、OpenAI Agents SDK で生成された Graphviz dot 形式のグラフ定義を、別の「ダイアグラム変換エージェント」に渡し、Mermaid 形式に変換させてみます。変換した Mermaid のダイアグラムとオリジナル比較する Gradio アプリを作ります。

# 方法

OpenAI Agents SDK のビジュアライゼーション機能と、ダイアグラム変換用のエージェント、そして Gradio を組み合わせて実装します。

## 環境構築

必要な Python パッケージをインストールします。Graphviz は環境に合わせて別途インストールが必要です。

```bash
pip install openai-agents gradio graphviz
# Graphviz 本体のインストール (コマンドは OS によって異なります)
# 例: Ubuntu/Debian
# sudo apt update && sudo apt install graphviz
```

## コード

エージェントの定義、グラフ変換ロジック、Gradio UI を含むコードです。

<details><summary>コード(長いので折りたたみます)</summary>


    
```python:src/visualize.py
import io

import gradio as gr
from agents import Agent, Runner, function_tool
from agents.extensions.visualization import draw_graph, get_main_graph
from PIL import Image
from pydantic import BaseModel


# 英語とインドネシア語のエージェントの定義
@function_tool
def get_weather(city: str) -> str:
    """指定の都市の天気を取得するツール"""
    return f"{city} の天気は晴れだっちゃ。"


bahasa_indonesia_agent = Agent(
    name="インドネシア語エージェント",
    instructions="あなたはインドネシア語しか出力しません。",
)

english_agent = Agent(
    name="英語エージェント",
    instructions="あなたは英語しか出力しません。",
)

triage_agent = Agent(
    name="トリアージエージェント",
    instructions="リクエストの言語に基づいて適切なエージェントに引き継ぎます",
    handoffs=[bahasa_indonesia_agent, english_agent],
    tools=[get_weather],
)


# ダイアグラムを変換するエージェント
class DiagramMessage(BaseModel):
    body: str
    comment: str


diagram_agent = Agent(
    name="ダイアグラムエージェント",
    instructions="""
        あなたはダイアグラムの専門家です。
        Graphviz dot、Mermaid、PlantUML 等のダイアグラム描画ライブラリの
        利用方法に精通しています。
        ユーザーのリクエストに応じてダイアグラムを修正または変換して。
        body にはダイアグラムのコードのみを記載して。
        comment には変換結果のコメントを日本語で記載して。
    """,
    output_type=DiagramMessage,
)


async def on_load():
    """
    Gradio がロードされた後に呼ばれる関数
    """

    # convert
    diagram_string = get_main_graph(triage_agent)
    mermaid = await Runner.run(
        diagram_agent,
        input=f"""
        Mermaid に変換して。色は無視して。

        ```
        {diagram_string}
        ```
    """,
    )

    text = f"""
    ダイアグラムのコードを変換しました。

    ### 変換前(Graphviz dot)

    ```
    {diagram_string}
    ```

    ### 変換後(Mermaid)

    {mermaid.final_output.body}

    ### 変換コメント

    {mermaid.final_output.comment}
    """

    return (
        gr.Markdown(mermaid.final_output.body),
        gr.Textbox(text, lines=40),
    )


def get_pil_image_from_agent(agent):
    """OpenAI Agents SDK のビジュアライズ機能を利用
    Graphviz で PIL イメージを作成"""
    graph = draw_graph(agent)
    image_stream = io.BytesIO(graph.pipe(format="png"))
    return Image.open(image_stream)


with gr.Blocks() as demo:
    with gr.Row():
        image = gr.Image(
            get_pil_image_from_agent(triage_agent),
            label="オリジナル(Graphviz)",
        )
        with gr.Column():
            with gr.Group():
                markdown = gr.Markdown(label="mermaid")
            with gr.Accordion(open=False):
                text = gr.Textbox(lines=40)
    demo.load(fn=on_load, inputs=[], outputs=[markdown, text])

if __name__ == "__main__":
    demo.launch(share=False, debug=True)
```

</details>


コードのポイントです。

- エージェント定義
    - triage_agent
        - 複数の言語エージェント (bahasa_indonesia_agent, english_agent) に処理を振り分けるエージェント
        - get_weather ツールを利用できる
    - diagram_agent
        - ダイアグラムの変換タスクを実行するエージェント
        - 実際に変換処理をするのは gpt-4o 等のバックエンドの LLM
        - 出力を DiagramMessage (body: 変換後のコード, comment: コメント) で定義
- グラフ取得と変換 (on_load 関数)
    - get_main_graph(triage_agent)
        - triage_agent を起点とするエージェントグラフの Graphviz dot 形式文字列を取得
    - Runner.run(diagram_agent, ...)
        - diagram_agent に dot 文字列を渡し、「Mermaid に変換して」と指示
        - 結果を DiagramMessage 型で受け取る
- Gradio UI (gr.Blocks)
    - gr.Image
        - draw_graph で生成した元の Graphviz 画像を表示
        - get_pil_image_from_agent で PIL Image に変換
    - gr.Markdown
        - diagram_agent が生成した Mermaid コードを表示
        - Gradio の Markdown コンポーネントは Mermaid をレンダリング可能 :sparkling_heart:
            - PlantUML はダメだった・・・:relaxed:
    - gr.Textbox & gr.Accordion
        - 変換前後のコードと diagram_agent のコメントをアコーディオン内に表示
    - demo.load
        - アプリケーション起動時に on_load を実行し、Mermaid コードと詳細テキストを UI にセット

実行方法。

```
$ gradio src/visualize.py
```

# 結果

実行結果です。良い感じに変換できています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126852/532559d2-e236-4313-839c-74b018995de5.png)


画面左(オリジナル): triage_agent を起点とするエージェント構成が Graphviz によって描画されてます

画面右(変換): diagram_agent によって Graphviz dot 形式から Mermaid に変換されたコードがレンダリングされています。エージェント定義で色情報を無視するようにしたため、Mermaid のデフォルトスタイルで描画されています。

右下のアコーディオンを開くと、変換前の Graphviz dot コード、変換後の Mermaid コード、そして diagram_agent が生成した変換に関するコメント（例：「Graphviz の dot 形式から Mermaid 形式に変換しました。ノードとエッジの関係性を維持し、Mermaid の構文に合わせて調整しました。」など）を確認できます。

詳細表示の例です。

```
ダイアグラムのコードを変換しました。

### 変換前(Graphviz dot)

<変換前のコード>

### 変換後(Mermaid)

<変換後のコード>

### 変換コメント

GraphvizのコードをMermaidに変換しました。色の指定は無視され、形状とリンクは正しく再現されています。

```


### 変換前の画像
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126852/91920710-1eb4-46d7-be4c-5fa00268b5bd.png)

### 変換語の Mermaid

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126852/1bd6d26b-5934-4d12-95e4-cb9fc294a03f.png)

# 考察

- エージェントによるタスク実行
    - エージェントに指示を与えるだけでダイアグラムのフォーマット変換ができました
    - diagram_agent は内部で LLM を利用し、指示に基づいて Graphviz dot を解釈し Mermaid に変換しています
    - エージェントのシステムプロンプトにはフォーマットの指示はしておらず、ユーザーの指示だけで対応しています
    - output_type に Pydantic モデルを指定することで、構造化された出力を容易に得られました
        - 今回は body にコード、comment に説明を含めるように指示しましたが、回答フォーマットを規制することで必要な情報を取り出せています
    - 時々失敗するのは LLM らしいと思います。失敗が許されない場合は、ガードレールとか静的構文解析ツールを利用してチェックが必要です。何度か生成させてみましたが、成功 5、微妙 4、失敗 1 ぐらいの比率でした。
- SDK のビジュアライゼーション機能
    - get_main_graph や draw_graph はエージェントの連携構造を理解する上で非常に便利です。デバッグや設計のレビューに役立ちます。
    - get_main_graph の内部では Agent や Tool をトラバースしています。独自の可視化をする際は参考になるコードだと思いました。
- Gradio との連携
    - Gradio を使うことで簡単にデモアプを作れました。Gradio の Markdown コンポーネントが Mermaid を直接レンダリングできるのは嬉しいです
        - (PlantUMLも・・・)
    - demo.load を使うことで、アプリケーション起動時に非同期処理 (on_load) を実行し、動的にコンテンツを生成・表示できました
- Mermaid の利便性
    - テキストベースである Mermaid は、ドキュメントへの埋め込み、バージョン管理システムでの差分確認などが容易です。
    - 多くのプラットフォーム（GitHub、GitLab、Qiita など）でサポートされているため、情報共有に適しています。テキストベースなのでコードのバージョン管理にも組み込みやすいです。


# まとめ

この記事では、OpenAI Agents SDK のビジュアライゼーション機能を使ってみました。公式サンプルでは、Graphviz dot 形式のエージェントグラフを PIL Image にしてファイルに出力していましたが、別のダイアグラム変換エージェントを使って Mermaid 形式に変換し、Gradio で表示するサンプルを作成しました。

エージェントにタスクを依頼するだけでフォーマット変換が可能であること、OpenAI Agents SDK のビジュアライゼーション機能と Gradio を組み合わせることで Web アプリとしての表示が容易に実現できることを確認できました。エージェント構成のドキュメンテーションや共有において、Mermaid 形式への変換は有効な手段の一つと言えるでしょう。

今後も OpenAI Agents SDK の様々な機能を探求していきたいと思います。

最後までお読み頂きありがとうございました！


# 参照

参照した情報です。



##  OpenAI Agents SDK Documentation

最近、日本語訳版がリリースされたようです。

https://openai.github.io/openai-agents-python/ja/

## OpenAI Agents SDK 可視化モジュールのソースコード

https://github.com/openai/openai-agents-python/blob/main/src/agents/extensions/visualization.py

## Gradio Documentation

https://www.gradio.app/docs/

# 参考


## 失敗例

点線にしたいところが実線になり「dotted」という注釈がついています。微妙な例です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126852/108bf0ec-fd54-409e-924d-9b56d3b8624d.png)

構文エラーの失敗例です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126852/fc38c1a0-537c-466d-87cc-7d2548efc01e.png)

生成したコードです。たぶん end が予約語なんだと思います。end_ にしたら動作しました。

```
graph TD
    start("__start__")
    end("__end__")
    triage("トリアージエージェント")
    get_weather("get_weather")
    indo("インドネシア語エージェント")
    en("英語エージェント")

    start --> triage
    triage --> get_weather
    get_weather --> triage
    triage --> indo
    indo --> end
    triage --> en
    en --> end
```