[GPT-4o] 冷蔵庫内の写真から「おすすめレシピ」を受け取ってみました。

[GPT-4o] 冷蔵庫内の写真から「おすすめレシピ」を受け取ってみました。

「冷蔵庫内の写真から食材を見て、レシピを考えてもらう」というミッション。1年前、まだ、マルチモーダルなLLMが無かった頃の試行錯誤したした画像をそのまま使用して、最新のGPT-4oで同じことを試してみました。今では、当たり前であまり驚かなくなってしまった進化について思いを寄せてます。
Clock Icon2024.11.11

1 はじめに

製造ビジネステクノロジー部の平内(SIN)です。

以下は、約1年前、当時まだ、マルチモーダルなLLMが存在せず、画像から何かのレスポンスを得るという事ができなかったので、面白そう!って乗りで試したブログです。

https://dev.classmethod.jp/articles/chatgpt-recomend-recip/

上記では、冷蔵庫の中の食品を検出する部分を自前で実装しています。

しかし、予想通りというか、想像した通りというか、今では、マルチモーダルLLMなんか当たり前となってしまっています。またLLMのレスポンスもかなり精度が上がっています。

そこで、以前のブログで試した冷蔵庫内の写真をそのまま使用して、現在のLLMの実力を試してみました。

内容がなくて申し訳ありませんが、1年前との比較という趣旨でご了承ください。

2 実装

今回は、画像の検出などは必要ないので、GPT-4oへの質問のみとなってます。

動作を安定させるため、LLMへのアクセスは、2段階としました。(1回でもそれなりのレスポンスは得られました)

最初に、画像を渡して、食材を列挙します。そして、列挙された食材をプロンプトに入れて、レシピを考えてもらってます。

(1) プロンプト

食材の一覧を得るためのものです。食品サンプルの野菜が、模型として認識(正確に認識)されてしまったので、実物として見てくださいとお願いしています。

prompt_food_enumeration.txt

冷蔵庫の内部の写真を分析します。あなたの課題は、画像に写っているすべての食品を特定してリストすることです。

以下の指示に注意深く従ってください:

1. 画像を詳しく調べ、冷蔵庫に写っているすべての食品を特定します。

2. これらの食品の簡単なリストを作成します。

3. 食品や画像についての説明、説明、または追加のコメントは提供しないでください。

4. 確実に特定できない食品は、リストに含めないでください。

5. 回答を箇条書きリストとして提示します。

6. 回答には日本語を使用してください。

7. 袋にパッケージされているのはソーセージです。

8. 模型のように見えるものもありますが、全て実物です。

リストは <food_list> タグ内に提供してください。食品のリストのみを含め、他のものは含めないでください。

レシピを取得するためのものです。この辺は、以前とあまり変わってません。

prompt_create_recipe.txt


あなたは高級レストランのプロのシェフです。あなたの仕事は、<food_list>タグ内にある材料を使って 1 つのレシピを作成することです。

%%FOOD_LIST%%

レシピには以下の要素を含める必要があります:
1. キャッチーなタイトル
2. 調理時間の目安
3. 材料リスト(分量付き)
4. 調理手順のステップバイステップの説明

タイトルを作成するときは、魅力的で、調理する料理を説明するものにしてください。創造性を発揮しながらも、主な材料や調理方法を反映するようにしてください。

レシピは次の形式で提示してください:
1. タイトル
2. 調理時間
3. 材料 (分量付き)
4. 手順 (番号付きステップ)

上記のリストに記載されている材料のみを使用するようにしてください。塩、コショウ、食用油などの基本的な食料品は揃っていると想定してください。

完全なレシピを <recipe> タグ内に出力します。今すぐ始めましょう:

<recipe>
[ここにあなたのレシピを記入してください]
</recipe>

(2) コード

コードは、かなりシンプルです。

import base64
from openai import OpenAI

client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
model_name = "gpt-4o"

def encode_image(image_path):
    with open(image_path, "rb") as image_file:
        img = base64.b64encode(image_file.read()).decode("utf-8")
    return {"url": f"data:image/jpeg;base64,{img}"}

def read_prompt_file(file_path):
    with open(file_path, "r", encoding="utf-8") as file:
        return file.read()

def execute_gpt4o(messages):
    response = client.chat.completions.create(
        model=model_name,
        messages=messages,
        max_tokens=1200,
    )
    return response.choices[0].message.content

def create_messages(prompt, image_file=None):
    content = [{"type": "text", "text": prompt}]
    if image_file:
        content.append({"type": "image_url", "image_url": encode_image(image_file)})
    return [{"role": "user", "content": content}]

def process_request(prompt_file, image_file=None, replacements=None):
    prompt = read_prompt_file(prompt_file)
    if replacements:
        for key, value in replacements.items():
            prompt = prompt.replace(key, value)
    messages = create_messages(prompt, image_file)
    return execute_gpt4o(messages)

def food_enumeration(image_file):
    return process_request("prompt_food_enumeration.txt", image_file)

def create_recipe(food_list):
    replacements = {"%%FOOD_LIST%%": food_list}
    return process_request("prompt_create_recipe.txt", replacements=replacements)

def main():
    # 食材の列挙
    food_list = food_enumeration("image006.jpg")
    print(food_list)
    # レシピの作成
    recipe = create_recipe(food_list)
    print(recipe)

main()

3 試してみた様子

003

<food_list>
- りんご
- バナナ
- ソーセージ(袋入り)
- 黄パプリカ
- 緑パプリカ
- トマト
- なす
</food_list>

<recipe>
1. タイトル: フルーツと野菜のソーセージグリルプレート

2. 調理時間: 約30分

3. 材料 (分量付き):
   - りんご: 1個 (薄切り)
   - バナナ: 1本 (斜めに切る)
   - ソーセージ(袋入り): 3本 (斜めにスライス)
   - 黄パプリカ: 1個 (一口大に切る)
   - 緑パプリカ: 1個 (一口大に切る)
   - トマト: 2個 (スライス)
   - なす: 1本 (一口大に切る)
   - オリーブオイル: 大さじ2
   - 塩: 適量
   - コショウ: 適量

4. 手順:
   1. 準備として、すべての野菜とフルーツ、ソーセージを指定されたサイズにカットします。
   2. 大きなフライパンまたはグリルパンを中火で熱し、オリーブオイルを加えて全体に広げます。
   3. まずソーセージをフライパンに入れ、軽く焦げ目がつくまで5分ほど炒めます。その後、取り出しておきます。
   4. 同じフライパンに、なす、黄パプリカ、緑パプリカを加え、柔らかくなるまで約7分炒めます。
   5. 次にトマトスライスを加え、さらに3分ほど加熱します。全体に塩とコショウで味を整えます。
   6. 野菜を片側に寄せ、空いたスペースにりんごとバナナを並べて、軽く色づくまで約3分焼きます。
   7. 最後に、すべての材料をフライパンに戻し、軽く混ぜ合わせて温めます。
   8. 皿に盛り付けて、熱々のうちにお召し上がりください。

</recipe>

002

<food_list>
- 牛乳
- ソーセージ
- 鶏肉
- トマト
- 玉ねぎ
- パプリカ
- キャベツ
</food_list>

<recipe>
1. タイトル: 辛味ソーセージと鶏肉のトマトクリーム煮込み

2. 調理時間: 約45分

3. 材料 (分量付き):
   - 牛乳: 200ml
   - ソーセージ: 4本
   - 鶏むね肉: 300g
   - トマト: 3個
   - 玉ねぎ: 1個
   - パプリカ: 1個
   - キャベツ: 1/4個
   - 塩: 適量
   - コショウ: 適量
   - オリーブオイル: 大さじ2

4. 手順:
   1. **準備**  
      - 鶏むね肉を一口大にカットします。  
      - ソーセージは斜めにスライスし、玉ねぎは薄切り、トマトはざく切りします。  
      - パプリカとキャベツもそれぞれ食べやすい大きさに切ります。

   2. **炒める**  
      - 大きめのフライパンにオリーブオイルを熱し、中火で鶏むね肉を炒め、表面が白くなるまで焼きます。
      - 鶏肉を一旦取り出し、同じフライパンでソーセージ、玉ねぎを加え、玉ねぎが透明になるまで炒めます。

   3. **煮込む**  
      - フライパンに戻した鶏肉、トマト、パプリカ、キャベツを加え、全体を混ぜ合わせます。
      - 塩とコショウで味を整え、材料がしんなりするまで中火でさらに炒めます。

   4. **クリームソースを作る**  
      - 牛乳をフライパンに注ぎ、弱火にしながら全体がなじむまで煮込みます。  
      - 牛乳がとろりとしたソース状になるまで10分ほど煮続けます。

   5. **仕上げ**  
      - 盛り付ける前に全体の味を確認し、必要であれば塩コショウで調整します。
      - 皿に盛り付け、お好みでパセリを散らして完成です。

</recipe>

4 最後に

今回は、1年前と同じ作業が、いとも簡単にできてしまうことを実感してみました。

最近、AnthropicのClaudeばかり使っていて、プロンプトの形式がClaudeに合わせたものになっていますが、GPT-4oでも適切に処理できていることを確認しました。

来年は、どうなっているんでしょうね・・・

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.