9
6

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で作る「曖昧レシピ明確化の仕組み」- 実装してみた

Last updated at Posted at 2025-07-19

はじめに

FireShot Capture 006 - Pydantic AI レシピ明確化システム - [].png

「玉ねぎをしんなりするまで炒める」「適量の調味料を加える」...料理レシピでよく見る曖昧な表現。初心者には分かりにくく、失敗の原因にもなりがちです。

今回はPydantic AIを使って、曖昧なレシピを具体的な指示に変換するシステムを作ってみました。

何を作るのか

Before(曖昧):

玉ねぎを炒めて、しんなりしたら肉を入れる。
肉の色が変わったら調味料を加えて、いい感じまで煮る。

After(明確化):

1. 📝 元: 玉ねぎを炒めて、しんなりしたら
   ✨ 明確化: 玉ねぎを中火で透明になるまで5分炒める
   ⏰ 時間: 5分
   💡 コツ: 焦がさないよう時々混ぜる

2. 📝 元: 肉の色が変わったら調味料を加えて
   ✨ 明確化: 肉全体が茶色になったら醤油大さじ2、みりん大さじ1を加える
   ⏰ 時間: 2-3分
   💡 コツ: 肉から出た水分を飛ばしてから調味料を加える

Pydantic AIの魅力

Pydantic AIの最大の特徴は、構造化された出力を簡単に得られる点にあります。従来のLLM APIでは、プロンプトエンジニアリングの複雑さや不安定な出力形式に加え、レスポンスの解析処理も必要でした。一方、Pydantic AIではPydanticモデルによって出力形式を明示的に定義でき、型安全性が保証されるため、エラーハンドリングもシンプルに行えます。

実装の例

Google Colabでの実行方法

# 必要なライブラリのインストール
!pip -q install pydantic-ai nest_asyncio

# Jupyter環境での設定
import nest_asyncio
nest_asyncio.apply()

# APIキー設定(Google Colab)
from google.colab import userdata
os.environ["GEMINI_API_KEY"] = userdata.get('GEMINI_API_KEY')

1. データ構造の定義(型安全性の確保)

class ClarifiedStep(BaseModel):
    """明確化された1つの調理工程"""
    original: str = Field(description="元の曖昧な表現")
    clarified: str = Field(description="明確化された指示")
    time: str = Field(description="具体的な時間")
    tip: str = Field(description="失敗しないコツ")

class SimpleRecipe(BaseModel):
    """シンプルなレシピ分析結果"""
    steps: list[ClarifiedStep] = Field(description="明確化された工程リスト")

ポイント:

  • Field(description=)でAIに各フィールドの意味を明示
  • 型注釈により出力データの構造を保証
  • ネストした構造も自然に表現

2. AIエージェントの設定(システムプロンプトの最適化)

model = GeminiModel('gemini-2.0-flash', provider='google-gla')
agent = Agent(
    model,
    output_type=SimpleRecipe,  # 出力形式を指定
    system_prompt="""
    曖昧なレシピ表現を具体的に変換してください。
    
    変換例:
    - "しんなり""透明になるまで5分"
    - "適量""小さじ1/2"
    - "中火""中火(手をかざして温かく感じる程度)"
    
    各工程に失敗しないコツを必ず含めてください。
    """
)

ポイント:

  • output_typeで出力形式を指定するだけで構造化出力が可能
  • システムプロンプトに具体例を含めることで品質向上
  • プロンプトエンジニアリングがシンプル

3. メイン処理(非同期処理)

async def clarify_recipe(text: str):
    """レシピを明確化"""
    result = await agent.run(f"以下を明確化: {text}")
    return result.output  # SimpleRecipe型で返される

# 使用例
result = await clarify_recipe(vague_recipe)
# result.steps[0].original でアクセス可能

ポイント:

  • async/awaitで非同期処理
  • 戻り値が型安全
  • エラーハンドリング

実際の出力例

🍳 レシピ明確化デモ
========================================
元のレシピ:
玉ねぎを炒めて、しんなりしたら肉を入れる。
肉の色が変わったら調味料を加えて、いい感じまで煮る。

========================================
✨ 明確化結果:

1. 📝 元: 玉ねぎを炒めて、しんなりしたら肉を入れる
   ✨ 明確化: 玉ねぎを中火で透明になるまで5分炒めてから豚肉200gを加える
   ⏰ 時間: 5分
   💡 コツ: 玉ねぎが焦げないよう木べらで時々混ぜる

2. 📝 元: 肉の色が変わったら調味料を加えて、いい感じまで煮る
   ✨ 明確化: 肉全体が茶色になったら醤油大さじ2、砂糖大さじ1を加え弱火で10分煮込む
   ⏰ 時間: 10分
   💡 コツ: 煮汁が少なくなったら水を50ml追加する

まとめ

image.png

Pydantic AIを活用して、入力情報を具体化・明確化する仕組みを試作してみました。
時間やコツといった要素については、参考情報の入力が必要になる場面もありますが、入力内容を整形し、登録すべき情報を抽出する用途には十分活用できそうです。あくまでたたき台としての利用を想定しており、最終的な結果の確認や修正は必要になるかと思います。


実装例

実装の全体像は以下のような構成になります:
筆者はgoogle colab で動作確認しました。

# ===== セットアップ =====
!pip -q install pydantic-ai
!pip -q install nest_asyncio
!pip -q install matplotlib
!pip -q install seaborn
!pip -q install plotly
!pip -q install wordcloud

import nest_asyncio
import asyncio
import os
# Jupyter環境でasyncio を使用するための設定
nest_asyncio.apply()

# ===== API設定 =====
# Google Colabでの実行時は以下のコメントを解除してAPIキーを設定
from google.colab import userdata
os.environ["GEMINI_API_KEY"] = userdata.get('GEMINI_API_KEY')
"""
シンプルなレシピ明確化システム
曖昧な表現を具体的な指示に変換する
"""

import asyncio
from pydantic import BaseModel, Field
from pydantic_ai import Agent
from pydantic_ai.models.gemini import GeminiModel

# データ構造
class ClarifiedStep(BaseModel):
    """明確化された1つの調理工程"""
    original: str = Field(description="元の曖昧な表現")
    clarified: str = Field(description="明確化された指示")
    time: str = Field(description="具体的な時間")
    tip: str = Field(description="失敗しないコツ")

class SimpleRecipe(BaseModel):
    """シンプルなレシピ分析結果"""
    steps: list[ClarifiedStep] = Field(description="明確化された工程リスト")

# AIエージェント(シンプル設定)
model = GeminiModel('gemini-2.0-flash', provider='google-gla')
agent = Agent(
    model,
    output_type=SimpleRecipe,
    system_prompt="""
    曖昧なレシピ表現を具体的に変換してください。
    
    変換例:
    - "しんなり""透明になるまで5分"
    - "適量""小さじ1/2"
    - "中火""中火(手をかざして温かく感じる程度)"
    
    各工程に失敗しないコツを必ず含めてください。
    """
)

# メイン処理(超シンプル)
async def clarify_recipe(text: str):
    """レシピを明確化"""
    result = await agent.run(f"以下を明確化: {text}")
    return result.output

def show_result(recipe: SimpleRecipe):
    """結果表示"""
    for i, step in enumerate(recipe.steps, 1):
        print(f"\n{i}. 📝 元: {step.original}")
        print(f"   ✨ 明確化: {step.clarified}")
        print(f"   ⏰ 時間: {step.time}")
        print(f"   💡 コツ: {step.tip}")

# サンプル実行
async def main():
    # 曖昧なレシピ例
    vague_recipe = """
    玉ねぎを炒めて、しんなりしたら肉を入れる。
    肉の色が変わったら調味料を加えて、いい感じまで煮る。
    """
    
    print("🍳 レシピ明確化デモ")
    print("=" * 40)
    print(f"元のレシピ:\n{vague_recipe}")
    print("=" * 40)
    
    # AI処理
    result = await clarify_recipe(vague_recipe)
    
    # 結果表示
    print("✨ 明確化結果:")
    show_result(result)

# 実行
if __name__ == "__main__":
    asyncio.run(main())

image.png

参考情報

9
6
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
9
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?