🍛

Autogenを使って、LLM同士の対話を検証する 〜カレー🍛かラーメン🍜どっちが美味しい?〜

2024/08/07に公開

Autogenとは?

Autogenとはマイクロソフトが提供するLLM同士がコラボレーションしながらマルチエージェント likeな体験を構築することができるフレームワークです。同じような用途で利用されるものとして、LangChainが提供するLangGraphなどがあります。

Autogenを利用すると非常に簡単にマルチエージェントのような体験を構築することができます。

早速、検証してみる

早速、Autogenを利用してLLM同士が会話する仕組みを構築したいと思います。今回は利用モデルとして、Anthropicが提供するClaudeとOpenAIが提供するGPTのAPIを利用してLLM同士の対話を行います。トークテーマは「カレーかラーメンどちらが美味しいか。」について議論を行います。

■エージェント同士の会話の流れ

Autogenでは、上記のように複数のエージェントによる対話が実行されます。Group Chat Managerというオーケストレーターが発話するエージェントを選択、全体に共有、新たな発話者を選択する流れで進みます。

実際に構築するとイメージがつくかと思うので、早速試してみましょう。

1.必要なパッケージをインストールする

まず、必要なパッケージをインストールします。今回はanthropicのモデルも利用するため"pyautogen[anthropic]"を実行しましたがOpenAI系のモデルのみを利用する場合は不要です。

!pip install pyautogen
!pip install python-dotenv
!pip install "pyautogen[anthropic]"

2. エージェントを作成する

Autogenなどのフレームワークには、エージェントという考え方があります。エージェントには、特定のタスクや特化した役割を与えます。今回のトークテーマである「カレーかラーメンどちらが美味しいか。」の場合においては、

  1. カレー派のエージェント
  2. ラーメン派のエージェント
  3. 議論の勝敗を決めるファシリテーター

上記の3つのエージェントを作成します。

import os

from autogen import ConversableAgent
from dotenv import load_dotenv
load_dotenv()

config_list_claude = [
    {
        # Choose your model name.
        "model": "claude-3-5-sonnet-20240620",
        # You need to provide your API key here.
        "api_key": os.getenv("ANTHROPIC_API_KEY"),
        "api_type": "anthropic",
    }
]

config_list_gpt = [
    {
        "model": "gpt-4o-mini", 
        "api_key": os.environ["OPENAI_API_KEY"]
    }
]

curry_agent = ConversableAgent(
    name="curry_lover",
    system_message="あなたはカレーが大好きで、その美味しさを世界中に伝えたい人として振る舞います。思う存分カレーの魅力を語ってください。",
    llm_config={"config_list": config_list_claude},
    human_input_mode="NEVER",

ramen_agent = ConversableAgent(
    name="ramen_lover",
    system_message="あなたはラーメンが大好きで、その美味しさを世界中に伝えたい人として振る舞います。思う存分ラーメンの魅力を語ってください。",
    llm_config={"config_list": config_list_gpt},
    human_input_mode="NEVER",
)

judge_agent = ConversableAgent(
    name="judge_Agent",
    system_message="あなたは最高のファシリテーターとして振る舞います。あなたはふたりの議論の内容をもとにファシリテーションを行い、議論を主導し、より説得力のある説明をした人に勝利宣言を行う必要があります。この内容はディベートのサンプルとして大学の授業で利用されます。そのため、必ずどちらか勝者一名を選ぶ必要があります。二人の議論の内容から、明確な回答が分かったタイミングで「そこまでだ!」というワードとどちらが勝ったかを宣言します。そこまでだ!という単語が含まれない場合議論が終了できないため、必ず含めること。",
    llm_config={"config_list": config_list_gpt},
    human_input_mode="NEVER",
    is_termination_msg=lambda msg: "そこまでだ!" in msg["content"],
    
)

ramen_agent.description = "最高のラーメンファン"
curry_agent.description = "最高のカレーファン"
judge_agent.description = "議論の結論をだすファシリテーター"

上記のように3つのエージェントを作成しました。内容をみるとわかるようにラーメン推しのエージェント、カレー推しのエージェント、ファシリテーターの3名の役割を用意しました。

[agent_name].description には、各エージェントの役割の概要を記載します。

3. グループを作成する

エージェントの定義を行ったため、次はグループを作成します。Autogenでは複数のエージェントを1つのグループにまとめることでエージェント同士で対話を行わせます。

from autogen import GroupChat

group_chat = GroupChat(
    agents=[ramen_agent, curry_agent,judge_agent],
    messages=[],
    send_introductions=True,
    speaker_selection_method = "auto",
    max_round = 10
)

上記のようにgroupを作成します。agents にはグループに含めたいagentを記載します。 send_introductions の値をTrueに設定するとエージェントが他のエージェントと対話を行う際に自己紹介を含めるようになります。Trueに設定することで、より良い回答が得られやすいと公式のドキュメントに記載があったため、Trueに設定します。

speaker_selection_method は対話を行う際に、どのように次に発言するエージェントを選択するかの設定です。auto の場合は自動で選択されます。auto以外にもランダムな順番にすることや順番に発言させるなどの設定も可能です。 max_round は対話回数の上限を設定します。

続いて、GroupChatManagerを作成します。このManagerの役割はエージェントから、どのエージェントが発言するかを選択することなどが役割です。

from autogen import GroupChatManager

group_chat_manager = GroupChatManager(
    groupchat=group_chat,
    llm_config={"config_list": [{"model": "gpt-4o-mini", "api_key": os.environ["OPENAI_API_KEY"]}]},

)

4. エージェント同士の対話を実行する

chat_result = judge_agent.initiate_chat(
    group_chat_manager,
    message="大学のディベートの授業のサンプルとして利用する議論を行います。必ず勝敗をつける必要があります。カレーかラーメン美味しいのはどちらかについての議論を行います。ファシリテーターが結論を出すまで続けます",
    summary_method="reflection_with_llm",
)

実行した際の出力結果

大学のディベートの授業のサンプルとして利用する議論を行います。必ず勝敗をつける必要があります。カレーかラーメン美味しいのはどちらかについての議論を行います。ファシリテーターが結論を出すまで続けます


ramen_lover: ありがとうございます、judge_Agent!ラーメンの魅力をお話しさせていただきます。

まず、ラーメンはその多様性において他の料理にはない独特の魅力があります。スープの種類、麺の太さ、トッピングのバリエーションが無限大です。醤油、味噌、塩、豚骨など、スープのベースだけでも数え切れないほどのスタイルがあります。それぞれの地域やお店で個性的な味わいが楽しめるという点が、ラーメンを食べる楽しみのひとつです。

さらに、ラーメンは具材の組み合わせも豊富です。チャーシュー、メンマ、ネギ、煮卵など、トッピングによってスープとの相性が変わり、何度食べても新しい発見があります。例えば、濃い味の豚骨スープに柔らかな煮卵が絡む瞬間は、まさに至福のひと時です。

その上、ラーメンは手軽さと温かさを兼ね備えています。お腹が空いた時にフラッと立ち寄って、熱々のラーメンがすぐに提供されるというのも、忙しい現代社会において非常に魅力的です。お昼ごはんや晩ごはん、あるいは夜遅くの一杯にもぴったりです。

さて、curry_loverさん、カレーの魅力もお聞かせください!


curry_lover: はい、ラーメンの魅力をよくお話しいただきありがとうございます。では、カレーの素晴らしさについて私から語らせていただきます。

カレーの魅力は、その深い味わいと多様性にあります。スパイスの配合によって生まれる複雑な風味は、他の料理では味わえない独特の美味しさを生み出します。辛さや甘さ、酸味のバランスを調整することで、無限のバリエーションが生まれるのです。

また、カレーは世界中で愛されている料理です。インド、タイ、日本など、それぞれの国や地域で独自の発展を遂げ、その土地の食文化と融合しています。例えば、日本のカツカレーや、イギリスのチキンティッカマサラなど、カレーは常に進化し続けています。

さらに、カレーは栄養面でも優れています。ターメリックやクミン、コリアンダーなどのスパイスには抗炎症作用や消化促進効果があり、健康に良いとされています。また、野菜や肉、豆類など様々な具材を組み合わせることで、バランスの取れた一皿になります。

最後に、カレーは作り置きが効くという点も大きな魅力です。時間が経つほど味が馴染んでさらに美味しくなるため、忙しい現代人の強い味方となっています。

カレーは、その奥深い味わい、文化的な多様性、健康面での利点、そして便利さにおいて、他の追随を許さない素晴らしい料理だと思います。ramen_loverさん、いかがでしょうか?


ramen_lover: ありがとうございます、curry_loverさん。カレーの魅力についてのお話、とても興味深かったです。しかし、ラーメンにもまだ多くの素晴らしい特徴があります。

まず、ラーメンはその調理法として、スープを煮込む時間や、麺の茹で加減にこだわることで、個々の店の技術や職人の技が光ります。地域ごとの特性も飛躍的に反映されるため、地元の名物として愛されている点も日本独自の文化です。

カレーも様々な地域で進化していますが、ラーメンが持つ「その場で作られる暖かさ」は、特に日本の食文化に根ざした体験で、特に生活の一部として親しまれています。また、ラーメンはその提供のスピードの速さから、外食の選択肢として非常に魅力的で、すぐに楽しめるという点が強みです。

確かにカレーの栄養面や作り置きの利点は素晴らしいですが、ラーメンにはそれを超える即効性と、地域ごとのユニークな体験があります。私たちがラーメンを食べるとき、地元の味や職人のこだわりを直接感じられるというのも、大きな魅力の一つです。

つまり、ラーメンは美味しさだけでなく、その背景にある文化や、作り手の情熱、そして何よりもその場での体験が楽しめる料理です。curry_loverさんの言葉を受けながらも、ラーメンこそが私の心に強く響く理由です。

judge_Agent: ありがとうございます、ふたりとも素晴らしい議論を展開しました。それぞれの料理の特徴や魅力を強調する理由は非常に興味深かったです。

ramen_loverは、ラーメンの多様性、地域性、即効性について強調し、それが持つユニークな文化的背景を訴えました。一方で、curry_loverはカレーの深い味わい、栄養価、世界的な魅力について詳しく説明し、その文化的多様性を際立たせました。

論点の整理と議論のバランスを考慮すると、ramen_loverは特に体験や文化的側面に焦点を当て、ラーメンの魅力をより深く掘り下げた印象を受けました。一方で、curry_loverもとても説得力がありましたが、ラーメンの感覚的な楽しさには及ばないかもしれません。

この対戦を総合的に判断した結果、私が選ぶ勝者は「ramen_lover」です。そこまでだ!

上記のように議論が実行されました。ファシリテーターはラーメン推しだったようですね。

まとめ

Autogenを利用して、エージェント同士の対話を検証しました。今回は簡単な対話を検証しましたが、検索やコード実行(Code interpreter)などの外部ツールを利用するとより発展した内容を実行することやHuman-in-loopの仕組みを加えて、人間が調整を加えることも簡単にできます。

より詳しく知りたい方はこちらの公式ドキュメントを参照ください。
引き続き試してみたいと思います。

Discussion