7
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Pydantic AIで作る!AIエージェントによるじゃんけんバトル 🤖✂️📄🪨

Last updated at Posted at 2025-05-10

巷ではAIエージェントのファクトチェック機能などが急速に進化していますが、「じゃんけんくらいはできるのでは?」と思い、試してみました。LLMを使わなくてもプログラムで実装できますが、今回はシンプルなケースとしてLLMを用いて試してみました。

janken-ai-diagram.png

はじめに

「AIに推論させる」といえば、情報検索や文章生成が一般的ですが、今回はちょっと変わったアプローチで、複数のAIエージェントを作成して「じゃんけん」をさせてみました。さらに、別のAIエージェントを審判として配置し、勝敗を判定させるシステムを構築しました。

この記事では、Pydantic AIライブラリを使用して、以下のようなシステムを実装します:

  • マルチエージェントシステム(複数のエージェントが協調動作)
  • 構造化出力による型安全な実装

なぜPydantic AI?

Pydantic AIは、LLMとのやり取りをより構造化し、型安全にできるライブラリです。以下のような特徴があります:

  • 型による安全な出力の定義
  • 複数のエージェントの管理が容易
  • エージェント間での情報の受け渡しがシンプル

環境構築

まずは必要なライブラリをインストールします。Google Colaboratoryでの実行を想定しています。

!pip -q install pydantic-ai
!pip -q install nest_asyncio

import nest_asyncio
nest_asyncio.apply()

print("Setup complete!")

次に、APIキーを設定します。この例ではGemini APIを使用していますが、他のLLMプロバイダーも使用可能です。

from google.colab import userdata
import os

os.environ["GEMINI_API_KEY"] = userdata.get('GEMINI_API_KEY')
from pydantic_ai import Agent
from pydantic_ai.models.gemini import GeminiModel

model = GeminiModel('gemini-2.0-flash', provider='google-gla')

基本:構造化出力

まずはPydantic AIの基本的な使い方として、構造化された出力を得る例を見てみましょう。

from pydantic import BaseModel
from pydantic_ai import Agent

class CityLocation(BaseModel):
    city: str
    country: str

# CityLocation で構造化
agent = Agent(
    model,
    result_type=CityLocation
)

# Q1: 2012年のオリンピック開催都市はどこ?
question1 = "Where were the olympics held in 2012?"
result1 = agent.run_sync(question1)

print("[Q1]", question1)
print("[A1]", result1.data)   # -> CityLocation型
print("Usage1:", result1.usage())

このように、LLMの出力をPydanticモデルとして定義することで、型安全な結果を得ることができます。

image.png

実装: マルチエージェントによるじゃんけん

プレイヤーエージェントの定義

まず、じゃんけんをするプレイヤーエージェントを作成します。

system_prompt_player = """\
あなたはじゃんけんプレイヤーです。「rock」(グー)、「paper」(パー)、または「scissors」(チョキ)のいずれかを
選んでください。選択したら、単にその選択だけを返してください。
例: 「rock」または「paper」または「scissors」
"""

# プレイヤーエージェントを作成
player_a = Agent(
    model,
    deps_type=str,
    system_prompt=system_prompt_player,
)

player_b = Agent(
    model,
    deps_type=str,
    system_prompt=system_prompt_player,
)

審判エージェントの定義

次に、勝敗を判定する審判エージェントを作成します。

system_prompt_referee = """\
あなたはじゃんけん(rock-paper-scissors)の審判です。
2人のプレイヤーの選択を比較し、ルールに基づいて勝者を判定します。

ルール:
- Rock(グー)はScissors(チョキ)に勝つ
- Scissors(チョキ)はPaper(パー)に勝つ
- Paper(パー)はRock(グー)に勝つ
- 同じ選択の場合は引き分け

プレイヤー1の名前と選択、プレイヤー2の名前と選択が与えられるので、
それに基づいて勝者を判定し、結果を説明してください。
"""

# 審判エージェントを作成
referee = Agent(
    model,
    deps_type=dict,
    system_prompt=system_prompt_referee,
)

じゃんけんの実行

実際にじゃんけんを実行してみましょう。

# プレイヤーAの選択を取得
player_a_result = player_a.run_sync('じゃんけんをしましょう。何を出しますか?', deps='Yashar')
player_a_choice = player_a_result.output.strip().lower()

# プレイヤーBの選択を取得
player_b_result = player_b.run_sync('じゃんけんをしましょう。何を出しますか?', deps='Anne')
player_b_choice = player_b_result.output.strip().lower()

print(f"プレイヤーA (Yashar)の選択: {player_a_choice}")
print(f"プレイヤーB (Anne)の選択: {player_b_choice}")

# 審判に判定してもらう - 両プレイヤーの情報を明示的に渡す
referee_input = f"""
プレイヤー1の名前: Yashar
プレイヤー1の選択: {player_a_choice}
プレイヤー2の名前: Anne
プレイヤー2の選択: {player_b_choice}

上記の情報に基づいて、勝者を判定してください。
"""

referee_result = referee.run_sync(referee_input, deps={})

print("\n審判の判定:")
print(referee_result.output)

実行結果

プレイヤーA (Yashar)の選択: paper
プレイヤーB (Anne)の選択: rock

審判の判定:
Yashar (paper) は Anne (rock) に勝ちます。なぜなら、Paper(パー)はRock(グー)に勝つからです。

**結果:Yashar の勝ち!**

image.png

実装のポイント

1. エージェントの独立性

各エージェントは独自のシステムプロンプトと役割を持ち、それぞれが独立して動作します。

2. 責任の分離

  • プレイヤーエージェント:じゃんけんの手を選択する責任
  • 審判エージェント:勝敗を判定する責任

このように責任を明確に分離することで、シンプルで理解しやすいシステムになります。

3. deps(依存関係)の活用

depsパラメータを使用して、エージェントに追加のコンテキスト(プレイヤー名など)を渡すことができます。

4. 型安全性

Pydanticの型システムを活用することで、エージェント間のデータやり取りが型安全になります。

マルチエージェントアプローチの利点

マルチエージェントアプローチでは、各エージェントが独立した役割を持つことで責任が明確に分離されます。プレイヤーは手の選択に、審判は勝敗判定に専念できるため、システムの拡張や変更が容易になります。また、実際のじゃんけんゲームと同じ構造を再現しているため、コードの理解が直感的になります。

拡張のアイデア

このシステムは様々な方向に拡張できます。複数のプレイヤーによるトーナメント戦の実装、対戦履歴を分析して相手の傾向を学習する戦略的なエージェントの開発、StreamlitやGradioを使用した対話型UIの追加などが考えられます。さらに、あいこが続いた場合の特殊ルールの導入や、勝率・手の使用頻度の統計分析を行うことで、より高度なゲームシステムに発展させることができます。

まとめ

summary-diagram-svg.png

AIエージェントが急速に進化する中、「じゃんけん」という誰もが知るシンプルなゲームでその可能性を探ってみました。プログラムで簡単に実装できる内容ですが、あえてLLMとPydantic AIを使うことで、マルチエージェントシステムの本質が見えてきます。

各エージェントに明確な役割を与え、責任を分離することで、単純なじゃんけんも拡張性の高いシステムに変貌します。この考え方は、カスタマーサポートやデータ処理パイプラインなど、実務での複雑な問題解決にも応用できる強力なアプローチです。

ぜひこのシンプルな例を出発点に、独自のAIエージェントシステムを作ってみてください!

参考資料

感想

image.png

Pydantic AIでじゃんけんAIを作ってみて感じたのは、「プログラムなのか自然言語なのか」「非構造なのか構造化なのか」の境界線のコントロールが想像以上に難しいということ。
こんなシンプルなゲームでも、どこまでLLMに任せてどこからコードで制御するか、その判断が設計の要になる。
AIシステム設計の本質的な難しさと面白さがここにある気がする。

7
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?