AutoGen v0.2 で遊べる環境を作ってみた

# はじめに
## AutoGen とは何か？
AutoGen は、AI エージェントを構築し、複数のエージェント間の連携を促進してタスクを解決するためのオープンソース プログラミング フレームワークです。AutoGen は、相互に対話できるエージェント、さまざまな大規模言語モデル (LLM) の使用とツール使用サポート、自律型および人間参加型ワークフロー、マルチエージェント会話パターンなどの機能を提供しています。このフレームワークを活用することで、昨今話題となっている、Agentic AI の開発や研究をシンプルに行うことが可能になります。

AutoGen には現状、安定して利用できるバージョンとしては v0.2 があり、一方より堅牢でスケーラブルなクロス言語ライブラリとして作り変えるための開発中バージョンとして v0.4 があります。

https://microsoft.github.io/autogen/0.2/

## この記事でカバーすること
この記事では、現状の安定板となっている AutoGen v0.2 を実行する環境を整え、一番簡単なマルチエージェント対話型のシステムのサンプルコードを実行するところまでをカバーします。

# 事前準備
## テスト環境として用意した OS
今回は、Hyper-V 上にインストールした Windows 11 Pro をテスト環境として利用して解説します。但し、今回利用するツールやフレームワークについては、Windows 以外にも macOS や Linux でも動作するはずなので、お好みの環境でテストいただければ良いと思います。

## Azure OpenAI Service リソース
この手順を進めるにあたり、有効な Azure OpenAI Service リソースが必要です。

Microsoft Azure の契約をお持ちでない方は、まずは以下のサイトから Azure 無償評価版をサインアップしてください。

https://azure.microsoft.com/ja-jp/pricing/purchase-options/azure-account?icid=ai-services&azure-portal=true

その後、以下の手順に従って Azure OpenAI Service リソースをデプロイし、GPT-4o モデルをデプロイして利用可能な状態にしてください。

https://learn.microsoft.com/ja-jp/azure/ai-services/openai/how-to/create-resource?pivots=web-portal

# 手順
## Python のインストール
AutoGen v0.2 の動作環境としては、Python 3.8 以上 3.12 未満という指定があります。今回は動作環境として指定されている中で一番新しいバージョンとなる、Python 3.12.8 をインストールしました。

https://www.python.org/downloads/windows/

:::note info
Python のインストーラーを実行する際、環境変数 PATH に Python のパスを追加するためのオプションのチェックボックスがあるので、そこにはチェックを入れておくと後々楽な気がします。
:::

## Visual Studio Code のインストール
Visual Studio Code を下記のサイトからダウンロードしてインストールします。

https://code.visualstudio.com/Download

## Python 拡張機能を Visual Studio Code にインストールする
Visual Studio Code の拡張機能マーケットプレイスで、"Python" と検索して、発行元が Microsoft の Python 拡張機能をインストールしましょう。

https://marketplace.visualstudio.com/items?itemName=ms-python.python

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199379/8e0b3eff-4111-1fb1-9bd3-675eff680f69.png)

## プロジェクトの保存先フォルダを決める
まずは、今回の成果物を保存するためのプロジェクトの保存先フォルダを決める必要があります。Visual Studio Code のメニューから [File] -> [Open Folder] を選択し、Open Folder ダイアログで任意の空の保存先フォルダを選択します。

保存先フォルダを指定すると、そのフォルダ内にあるコードを信頼するかどうかを確認するダイアログが表示されますが、現状そのフォルダには何もファイルが無いはずなので、そのまま "Yes, I trust the authors" を選択しましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199379/b83c1bd0-c6db-5c0a-94be-5cfa4bf12e87.png)

## 仮想環境を作る
Visual Studio Code のメニューから [Terminal] -> [New Terminal] を選択し、新しいターミナルを開きます。ターミナルを開いたら、以下のコマンドを順に実行し、仮想環境を作ってアクティブ化します。

```powershell
python -m venv .venv
.\.venv\Scripts\activate
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199379/c84a82f5-63de-fc42-f419-1f88fe5ecad1.png)

## AutoGen v0.2 をインストールする
続いて同じターミナルに以下のコマンドを入力し、AutoGen v0.2 をインストールします。

```powershell
pip install autogen-agentchat==0.2.40
```

:::note warn
以前は下記のコマンドで v0.2 系の autogen が入れられていましたが、今は下記のコマンドだと v0.4 系の依存関係が入ってしまうようで、v0.2 系のサンプルコードは動かないので注意が必要です。
（公式ドキュメントもまだ下記の表記のままメンテナンスされていないのでたちが悪い…）

```powershell
pip install autogen-agentchat~=0.2
```
:::

## Azure OpenAI への接続情報を .env ファイルに書き込む
Visual Studio Code の左ペインの Explorer ビューの上で右クリックし [New File] を選択します。ファイル名には ".env" とつけて保存しましょう。

このファイルに、以下の情報を記録します。

```.env
API_KEY=<Azure OpenAI の API Key>
API_ENDPOINT=https://<Azure OpenAI の API エンドポイント>
API_VERSION=2024-08-01-preview
DEPLOYMENT_NAME=<Azure OpenAI の GPT-4o モデルのデプロイ名>
```

## まずはシンプルなエージェントを定義して AutoGen につないで試してみる。
まずは、AutoGen のフレームワークがきちんと使えるようになっているかテストしてみます。Explorer ビュー上で右クリックメニューを開き [New File] を選択し、"000_test.py" とファイル名を付けて、以下のコードをまるまるコピーして貼り付けてください。

```000_test.py
from dotenv import load_dotenv
load_dotenv()

import os
from autogen import AssistantAgent, UserProxyAgent

# LLM への接続設定を環境変数から読み込む。キャッシュは無効化して繰り返し実行時に同じ結果にならないようにする
llm_config = {
    "cache_seed": None,
    "config_list": [
        {
            "model": os.getenv("DEPLOYMENT_NAME"),
            "api_type": "azure",
            "api_key": os.getenv("API_KEY"),
            "base_url": os.getenv("API_ENDPOINT"),
            "api_version": os.getenv("API_VERSION"),
        }
    ]
}

# LLM でタスク解決を行うためのアシスタントエージェントを定義
assistant = AssistantAgent("assistant", llm_config=llm_config)

# ユーザーの代理となるエージェント (user_proxy) を定義
user_proxy = UserProxyAgent("user_proxy",
                            code_execution_config=False,
                            human_input_mode="NEVER",
                            is_termination_msg=lambda msg: msg.get("content") is not None
                            and "TERMINATE" in msg["content"]
                            )

# user_proxy からチャットを開始する。ユーザーからの依頼となるメッセージもここで設定
user_proxy.initiate_chat(
    assistant,
    message="Microsoft の株価について、ポジティブに笑えるジョークを考えてください。一つジョークを考えおわったら TERMINATE と出力してください。",
)
```

ターミナルで、Python コードを実行すると、例えば以下のような応答が出力されてくるはずです。

```powershell
(.venv) PS C:\code\autogen> python .\000_test.py
C:\code\autogen\.venv\Lib\site-packages\flaml\__init__.py:20: UserWarning: flaml.automl is not available. Please install flaml[automl] to enable AutoML functionalities.
  warnings.warn("flaml.automl is not available. Please install flaml[automl] to enable AutoML functionalities.")     
user_proxy (to assistant):

Microsoft の株価について、ポジティブに笑えるジョークを考えてください。一つジョークを考えおわたら TERMINATE と出力してください。

--------------------------------------------------------------------------------
assistant (to user_proxy):

以下のようなジョークはいかがでしょうか？

「最近Microsoftの株価が上がったって？そりゃそうさ、だって彼らは常に'Excel'lent（エクセレント）だからね！」

TERMINATE

--------------------------------------------------------------------------------
```

このコードでは、user_proxy エージェントがユーザーの代わりになって assistant エージェントに指示を行い、assistant エージェントは LLM の助けを借りてユーザーの依頼を達成するための応答を返していることが出力からも確認できるかと思います。

## Agent に自律的にコードを書かせて実行させてみる
ここまでの内容は、旧来からある LLM を活用した自然言語による対話のアプリケーションと大して変わらないもの二見えているかと思います。

ここで、AutoGen の真骨頂ともいえる「自律的にコードを書いて自律的に実行する能力」についても、サンプルコードで試してみましょう。適当なサンプルを作ってみましたので、また新しい Python ファイルを作成して、以下のコードをまるまるコピーして貼り付けてください。

```001_code_test.py
from dotenv import load_dotenv
load_dotenv()
from pathlib import Path

import os
import autogen
from autogen import AssistantAgent, UserProxyAgent
from autogen.coding import LocalCommandLineCodeExecutor

# LLM の設定（AOAI につなぐための設定）を環境変数から読み込み。キャッシュも無効化する。
llm_config = {
    "cache_seed": None,
    "config_list": [
        {
            "model": os.getenv("DEPLOYMENT_NAME"),
            "api_type": "azure",
            "api_key": os.getenv("API_KEY"),
            "base_url": os.getenv("API_ENDPOINT"),
            "api_version": os.getenv("API_VERSION"),
        }
    ]
}

# LLM が生成したコードを保存する先の作業ディレクトリとコード実行環境の設定
work_dir = Path("coding")
work_dir.mkdir(exist_ok=True)

# ローカルにセットアップされた Python を使う設定
executor = LocalCommandLineCodeExecutor(work_dir=work_dir,timeout=240)

# LLM でタスク解決を行うためのアシスタントエージェントを定義。コードもこのエージェントが書く
assistant = AssistantAgent("assistant", llm_config=llm_config)

# ユーザーの代理となるエージェント (user_proxy) を定義。このエージェントがユーザーの代わりにコードも実行するため、code_execution_config を設定してある
user_proxy = UserProxyAgent(
    "user_proxy",
    human_input_mode="NEVER",
    is_termination_msg=lambda msg: msg.get("content") is not None
    and "TERMINATE" in msg["content"],
    code_execution_config={"executor": executor}
)

# user_proxy にユーザーの依頼を message として渡してエージェント間の対話をスタートさせる
message = "MSFT の創業時からの株価を msftstock.png に保存してください。文字コードは CP932 で取り扱います。"
user_proxy.initiate_chat(assistant, message=message)

```

このコードを実行すると、以下のような形で、何度かのトライ＆エラーを繰り返して、最終的に coding ディレクトリに msftstock.png という画像ファイルが出力されるはずです。

### 実行過程を読み込んでみる
先述のコードを実行すると、coding ディレクトリの中に AI が自動的に生成したコードなどの成果物が出力されることを確認できるかと思います。

生成 AI の出力結果は一定とはならないため、あくまで参考程度ですが、以下のような試行プロセスを経て最終的にユーザーの依頼にこたえるような結果を出していることをログから確認できるかと思います。

1. まずは実行計画のプラン
以下のように、LLM が実行計画をプランする
    1. **データの取得**:
        - Microsoftの株価データをYahoo Finance などの株価情報提供サービスから取得
    2. **データの処理**:
        - 取得した株価データをデコードします。
    3. **データの可視化**:
        - PandasとMatplotlibを使って、株価データをプロットし、画像として保存
2. 株価の取得とグラフのプロットを行うための、get_msft_stock.py というコードを LLM が実装
3. 試しに実行してみるもエラー
    1. エージェントが自動的にエラーの内容を確認し、実行環境に必要なライブラリ (pandas,matplotlib,yfinance) がインストールされていないことが原因と特定。
    1. ライブラリをインストールするためのシェルスクリプトを追加で実装
1. 依存関係のインストール完了を確認し、再度株価の取得とグラフのプロットを実行
1. 最終的に Yahoo Finance から株価を自動取得し、coding ディレクトリ内に株価をプロットしたファイルが生成されたことをもってタスク完了判定

# まとめ
## 今までの実験の結果からわかること
ここまで試した結果から、AutoGen を使うことで、簡単にエージェントに課題解決を任せるようなアプリケーションの実験が出来ることを確認できました。

特に、Code Executor を組み合わせた場合の動作は **「自律的に与えられたタスクを解決するための戦略を立てて、それに必要なコードを実装し、デバッグ作業まで自律的に行って結果にたどり着く」** という挙動となっており、いままでの LLM を活用したツール呼び出しに比べてエラーに対して堅牢で粘り強くタスクをこなしてくれる可能性を感じるものになっているかと思います。

## AutoGen でそのほかにできること
今回紹介したのは AutoGen の機能のごく一部にすぎません。

そのほかにも、Function Calling に似た形で Agent が利用するツールを定義して、必要に応じてツールの呼び出しを自律的に判断させることが出来たり…

https://microsoft.github.io/autogen/0.2/docs/tutorial/tool-use

複数のキャラクターの違うエージェント同士を対話させて、人間同士の会議のような意思決定を行わせてみたり…

https://microsoft.github.io/autogen/0.2/docs/tutorial/conversation-patterns

LLM が生成するコードをローカル環境ではなく、もっとセキュアな Docker 環境で実行させることもできたり…

https://microsoft.github.io/autogen/0.2/docs/topics/code-execution/cli-code-executor

Ollama でホストしたローカルの SLM で推論を行わせたり…

https://microsoft.github.io/autogen/0.2/docs/topics/non-openai-models/local-ollama

といった色々な機能が実装されています。

これらの機能についても、今回作ったテスト環境さえあれば、AutoGen のドキュメントを読み解いていくことでどなたでも試してみることが可能です。

今後ヒマを見つけて、そのほかの AutoGen のサンプルコードも公開していこうと思いますが、是非皆さんも AutoGen を使って色々なエージェントとの対話を楽しみながら、Agentic AI の勘所を掴む一助にしていただけたら幸いです。

## 参考ドキュメント
https://microsoft.github.io/autogen/0.2/

https://learn.microsoft.com/ja-jp/azure/ai-services/openai/chatgpt-quickstart?tabs=command-line%2Cjavascript-keyless%2Ctypescript-keyless%2Cpython-new&pivots=programming-language-studio

https://learn.microsoft.com/ja-jp/azure/ai-services/openai/how-to/create-resource?pivots=web-portal

https://code.visualstudio.com/docs/python/python-tutorial