【生成AIアプリ100チャレンジ】（13）レシピ提案アプリ

https://ai.nuevo.jp/recipe/


# 開発環境

|              |              |
|:------------:|:------------:|
| Server       | lightSail    |
| Language     | Python3.11   |
| Framework    | Django       |
| DB           | sqlite3      |

ローカル環境ではPythonのvenvを使用。エディタはvs codeです。

# 目的
画像解析の生成AIであるvison apiをつかったアプリ。
食材の写真をアップすると、その食材から作ることができるレシピを教えてくれる。
画像の解析精度がまだ低いのですが、精度を高めていてけば、冷蔵庫の画像から食材を見分け、レシピを提案できるようになれば、需要がでてくるのではないだろうか。随時、ブラッシュアップしていきたい。

# コード
```python:qiita.rb
    OPENAI_API_KEY = os.environ['OPENAI_API_IMAGE_KEY']
    DEEPL_API_KEY = os.environ['DEEPL_API_KEY']
    domain = request.build_absolute_uri('/')
    file_path = 'recipe.jpg'
    if default_storage.exists(file_path):
        default_storage.delete(file_path)
    img_results = ""
    recipe_results = ""
    image_path = ""
    if request.method == "POST":
        form = ChatForm(request.POST, request.FILES)
        if form.is_valid():
            image_file = request.FILES['image']
            image_content = image_file.read()
            default_storage.save('recipe.jpg', ContentFile(image_content))
            client = OpenAI(
                api_key = OPENAI_API_KEY,
            )
            image_path = settings.BASE_DIR / "uploads/recipe.jpg"
            print(image_path)
            def encode_image(image_path):
                with open(image_path, "rb") as image_file:
                    return base64.b64encode(image_file.read()).decode('utf-8')
            base64_image = encode_image(image_path)
            headers = {
            "Content-Type": "application/json",
            "Authorization": f"Bearer {OPENAI_API_KEY}"
            }
            payload = {
            "model": "gpt-4-vision-preview",
            "messages": [
                {
                "role": "user",
                "content": [
                    {
                    "type": "text",
                    "text": """
                        What’s in this image?
                        Just tell me the name of the vegetable in the image.
                        Please do not answer except for the name of the vegetable.
                        If there are no vegetables in the picture, please return the message No vegetables.
                        """
                    },
                    {
                    "type": "image_url",
                    "image_url": {
                        "url": f"data:image/jpeg;base64,{base64_image}"
                    }
                    }
                ]
                }
            ],
            "max_tokens": 300
            }
            response = requests.post("https://api.openai.com/v1/chat/completions", headers=headers, json=payload)
            img_results = (response.json().get("choices")[0]["message"]["content"])
            response = client.chat.completions.create(
                model="gpt-3.5-turbo",
                messages=[
                    {
                        "role": "system",
                        "content": """
                            You are a cookery researcher.
                            USER gives you an ingredient.
                            Please give us a recipe that can be cooked from that ingredient.
                        """
                    },
                    {
                        "role": "user",
                        "content": "Cooking ingredients" + img_results
                    },
                ],
            )
            recipe_results = response.choices[0].message.content

            def translate_text_with_deepl(text, auth_key):
                translator = deepl.Translator(auth_key)
                result = translator.translate_text(text, target_lang="JA")
                return result.text
            recipe_results = translate_text_with_deepl(recipe_results, DEEPL_API_KEY)
            recipe_results = recipe_results.replace("\n", "<br />")
            img_results = translate_text_with_deepl(img_results, DEEPL_API_KEY)

    else:
        form = ChatForm()
```

Visionで食材だけを表示するように指示。この際、精度を上げたいので英語で指示を出している。
VisionAPIからも英語でレスポンスをもらっている、この場合、食材のみ。
その食材をもとに何のレシピが可能かをChatGPTに問い合わせている。この際にChatGPTは料理研究家の役割を与えている。
精度をあげるために英語で役割を付与している。
DEEPLで日本語に翻訳してから、TemplatesにResponseを返している。

# アプリ画面
![スクリーンショット 2024-04-05 20.17.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398694/9b7ca941-8653-64b9-2ba8-4e14fd2ad5fc.png)


# 感想
画像解析の精度が低い。もし冷蔵庫や日常で使われることを想定するのであれば、複数の写真をアップすることになるのではないだろうか。その上で、レシピを提案するというアプリになりそうな気がする。横展開できそうなアプリなので、他にも考えてみたい。