AIは「からあげ」と「とり天」を見分けられるのか。Gemini、Claude、GPTのVision検証

こんにちは、のびすけです。

皆さんが気になっている  **AIは「からあげ」と「とり天」を見分けられるのかを見ていきます。**

> <img src="https://i.gyazo.com/c6487e4024b981a0b5bbeae398da8368.jpg" width="200px" /> <img src="https://i.gyazo.com/f6f6535e99cad0637845eecb01b8421f.png" width="200px" />

この記事は[からあげ帝国アドベントカレンダー2024](https://qiita.com/advent-calendar/2024/karaage)の記事となります。

## 先行研究と今回新しくやること

去年の今くらいの時期で、GPTのVision APIが出てきていたので試していました。

https://qiita.com/n0bisuke/items/1dc99747d31316df6c44

去年の記事ではGPTだけで検証していましたが、同じ検証だと面白くないので今回はClaudeとGeminiも使って比較してみたいと思います。

### とり天とは（おさらい）

一応知らない人もいるかも？なので紹介すると大分発祥とされる鶏の天ぷらです。

[農林水産省のページ](https://www.maff.go.jp/j/keikaku/syokubunka/k_ryouri/search_menu/menu/toriten_oita.html)によるとこんな感じらしい。

> 「とり天」は、別府市内にある県内初のレストラン「東洋軒」が発祥だとされている。昭和初期、既存メニューの唐揚げが骨付きであったために女性が食べづらいだろうという気遣いから、骨のないもも肉を食べやすい大きさに切り、天ぷら風にアレンジしたのがはじまり。唐揚げより早く調理できて、サクサクと柔らかい衣は、またたく間に評判となり、やがて、さまざまな飲食店が「とり天」を提供するようになったという。

## 共通ルール

検証時のルールです。GPT、Claude、Geminiでなるべく条件を同じにして比較します。

### プロンプト

プロンプトは去年利用した、 `「あなたは画像の説明が上手い優秀なアシスタントです。この画像に何が写っているのかを小学生にも分かるように丁寧に説明をしてください。」` というプロンプトを使います。

もっとこういうプロンプトにした方が良いなどあればコメント下さい。

### とり天とからあげの画像

画像も去年使ったとり天とからあげの画像を利用します。

これは農林水産省が運営する[「うちの郷土料理」](https://www.maff.go.jp/j/keikaku/syokubunka/k_ryouri/search_menu/menu/toriten_oita.html)というサイトにある画像を使っています。

> <img src="https://i.gyazo.com/c6487e4024b981a0b5bbeae398da8368.jpg" width="200px" /> <img src="https://i.gyazo.com/f6f6535e99cad0637845eecb01b8421f.png" width="200px" />

### トークンとTemperature

Maxトークンは1024、Temperatureは0.9を指定して検証します。

### 実装方法

Node.jsからClaude、Gemini、GPTのビジョンAPIを呼び出して利用します。
サンプルを動かすくらいですが、Base64変換してAPIに投げるという流れです。

- 実装方法の参考
    - Gemini
        - https://qiita.com/tatsuki-tsuchiyama/items/90c674435f1a942a41a7
    - Claude
        - https://zenn.dev/sekitobatech/articles/f0492e485fbe7d
        - https://gaprot.jp/2024/03/13/claude3/
        - https://zenn.dev/voiceapplab/articles/d2c948e6f80108

## 各種検証コード

結果に行く前に、各API利用のコードを紹介しておきます。

「からあげ」と「とり天」判定の結果を見たい人はこの章はスキップしてください。

### Gemini APIをNode.jsから

GPTとClaudeばかり触っていてGeminiのAPIは初めて触ります。

- APIキーを発行します。

> ![スクリーンショット 2024-12-03 17.10.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/0f7268be-2264-abe4-6c64-203a4c08bdad.png)

- ライブラリのインストール

Node.jsで試していきます。

https://www.npmjs.com/package/@google/generative-ai

こちらのライブラリがアクティブで良さそうです。

```bash
$ npm install @google/generative-ai
```

```js

import { GoogleGenerativeAI } from "@google/generative-ai";
import fs from "fs";

const genAI = new GoogleGenerativeAI(`APIキー`);

const model = genAI.getGenerativeModel({ model: "gemini-1.5-flash" });

const prompt = "あなたは画像の説明が上手い優秀なアシスタントです。この画像に何が写っているのかを小学生にも分かるように丁寧に説明をしてください。";
const image = {
  inlineData: {
    data: Buffer.from(fs.readFileSync("karaage.png")).toString("base64"),
    mimeType: "image/png",
  },
};

const result = await model.generateContent([prompt, image]);
console.log(result.response.text());
```

ES Moduleを使ってるのでmjsとして実行。

```bash
$ node gemini.mjs
```

### ClaudeのAPIをNode.jsから

ClaudeもGeminiと同じようにAPIキーを発行、npmでライブラリを入れる、実行するという流れでいけました。

> ![スクリーンショット 2024-12-03 17.34.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/96e4836a-9dbb-d92c-de08-75e7d38c5638.png)

Claudeはドキュメントページで聞いたらコードも出してくれたのが体験として良かったです。

> ![スクリーンショット 2024-12-03 18.36.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/6f4c8d2e-ad9c-dd4e-ddd7-aeb0e0c62498.png)

```bash
$ npm i @anthropic-ai/sdk
```

```js
import { Anthropic } from '@anthropic-ai/sdk';
import fs from 'fs';

const anthropic = new Anthropic({
  apiKey: 'APIキー'  // 実際のAPIキーに置き換えてください
});

const prompt = "この画像に何が写っているのかを小学生にも分かるように丁寧に説明をしてください。";
const imageBase64 = Buffer.from(fs.readFileSync("karaage.png")).toString("base64");

async function analyzeImage() {
  try {
    const message = await anthropic.messages.create({
      model: "claude-3-5-sonnet-20241022",
      max_tokens: 1024,
      temperature: 0.9,
      messages: [{
        role: "user",
        content: [
          {
            type: "image",
            source: {
              type: "base64",
              media_type: "image/png", // 画像の種類に応じて変更してください
              data: imageBase64
            }
          },
          {
            type: "text",
            text: prompt
          }
        ]
      }]
    });

    console.log(message.content[0].text);
  } catch (error) {
    console.error('エラー:', error);
  }
}

analyzeImage();
```

### GPTのAPIをNode.jsから

GPTも流れは一緒です。

```js
import OpenAI from 'openai';
import fs from 'fs';

const openai = new OpenAI({
  apiKey: `APIキー`,  // 実際のAPIキーに置き換えてください
});

const prompt = "あなたは画像の説明が上手い優秀なアシスタントです。この画像に何が写っているのかを小学生にも分かるように丁寧に説明をしてください。";
const imageBase64 = Buffer.from(fs.readFileSync("karaage.png")).toString("base64");

async function analyzeImage() {
  try {
    const response = await openai.chat.completions.create({
      model: "gpt-4o",
      temperature: 0.9,
      max_tokens: 1024,
      messages: [
        {
          role: "user",
          content: [
            {
              type: "text",
              text: prompt
            },
            {
              type: "image_url",
              image_url: {
                url: `data:image/png;base64,${imageBase64}`
              }
            }
          ]
        }
      ]
    });

    console.log(response.choices[0].message.content);
  } catch (error) {
    console.error('エラー:', error);
  }
}

analyzeImage();
```

...とサンプルコードはここまで。

いよいよ結果見ていきましょう。


## Geminiは「からあげ」と「とり天」を見分けられるのか

さて結果です。

モデルは`gemini-1.5-flash`となっています。

### 「からあげ」の画像に対してのGeminiの解説

> <img src="https://i.gyazo.com/f6f6535e99cad0637845eecb01b8421f.png" width="200px" />

> 写真には、おいしそうな唐揚げが盛り付けられていますね！
> 
> 黒いお皿の上に、白い紙が敷いてあり、その上にカリッとした唐揚げが山盛りになっています。唐揚げは、鶏肉を衣で揚げたもので、きつね色に揚がっていて、とっても美味しそうですね。唐揚げのそばには、緑色のレタスが添えられていて、そして、レモンの輪切りも一緒に置かれています。レモンを絞って唐揚げと一緒に食べると、より一層美味しくなるかもしれませんね！
> 
> 全部で、何個くらいの唐揚げがあるか数えてみるのも楽しいですよ！  美味しそうで、食べたくなっちゃいますね！

まずは、「からあげ」判定いけましたね。

### 「とり天」の画像に対してのGeminiの解説

> <img src="https://i.gyazo.com/c6487e4024b981a0b5bbeae398da8368.jpg" width="200px" />

> 写真には、衣をつけて揚げた鶏肉が写っています。
>
> まるで小さな、きつね色の雲みたいでしょう？  これは「鶏の唐揚げ（からあげ）」の一種で、衣がサクサク、お肉はジューシーな、おいしい料理です！
> 
> たくさんのお肉が、きれいに並べられていますね。  隣には、小さな鉢にマスタードのような黄色いソースが入っています。  唐揚げにつけて食べると、さらに美味しくなるかもしれませんね！  そして、緑色のパセリが彩りを添えています。
> 
> 白い紙の上に置かれていて、お皿の上にあるので、食べる準備万端！  とっても美味しそうですね！

**。。。残念！！！**

天ぷらではなく"鶏の唐揚げ"と判断してしまっています。

”鶏の唐揚げの一種”という表現をしているのは惜しいですね。
**この画像から鶏の判断ができているのはすごい**ですね。適当に決めつけてしまって若干ハルシネーションしているようにも感じます。

今回は「天ぷら」なのか「からあげ」なのかは大きな違いになると思うので、ここは一旦残念ということにしておきます。

Geminiさん一歩出遅れ。

### Geminiの「からあげ」と「とり天」判定まとめ

Geminiは現時点（20241203）でとり天とからあげを区別できていないです。

天ぷらと唐揚げの判断も怪しい状況なので一歩遅れを取った感じでしょうか。

## Claudeは「からあげ」と「とり天」を見分けられるのか

Geminiの次はClaudedeです。

モデルは`claude-3-5-sonnet-20241022`を指定

### からあげの画像に対してのClaudeの解説

> <img src="https://i.gyazo.com/f6f6535e99cad0637845eecb01b8421f.png" width="200px" />

> この画像には、からあげ（鶏の唐揚げ）が写っています。
> 
> 黒い和風のお皿の上に、サクサクとした衣で揚げられた、きつね色の唐揚げが数個のっています。お皿には白い紙が敷かれていて、揚げ物の油を吸収するようになっています。
> 
> 付け合わせとして、新鮮な緑色のレタスの葉と、黄色いレモンの輪切りが添えられています。レモンを唐揚げにかけると、さっぱりとした味わいになります。
> 
> 唐揚げはとても人気がある日本の料理で、お弁当やおかずとしてよく食べられます。外はカリッと、中はジューシーな食感が特徴です。

唐揚げは問題なく判断できています。

素晴らしい。

### とり天の画像に対してのClaudeの解説

> <img src="https://i.gyazo.com/c6487e4024b981a0b5bbeae398da8368.jpg" width="200px" />

> この画像には天ぷらが写っています。特に白身魚やカレイのような魚の天ぷらのようです。
> 
> 天ぷらは、食材に衣をつけて、油で揚げた日本の伝統的な料理です。この写真では:
> - サクサクとした黄金色の衣がきれいについています
> - 白い皿の上に盛り付けられています
> - 横には緑の飾り（パセリ）があります
> - 小さな茶色の器（おそらく天つゆを入れる器）も添えられています
> 
> 天ぷらの衣は、小麦粉と卵と水を混ぜて作ります。揚げたての天ぷらは、外はカラッと揚がっていて、中はジューシーで柔らかいのが特徴です。
> お店やレストランで食べることもできますし、お家でも作ることができる人気の料理です。天つゆやお塩をつけて食べるのが一般的です。

「天ぷら」として判断してくれましたね！

ただ、"白身魚やカレイのような魚の天ぷらのようです"と中身の予想は外れています。

### Claudeの「からあげ」と「とり天」判定まとめ

「からあげ」と「天ぷら」の判断は出来たけど中身の予想は間違っていました。

天ぷら判定してくれてるだけですごいですが、中身の予想も素晴らしいですね。
そう言われるとそう見えるし人が判断してもそうなる気はします。

天ぷら判定がなかったGeminiよりやや優勢な気がしています。

## GPTは「からあげ」と「とり天」を見分けられるのか

最後にGPTです。GPT-4oを利用。

### からあげの画像に対してのGPTの解説

> <img src="https://i.gyazo.com/f6f6535e99cad0637845eecb01b8421f.png" width="200px" />

> この画像には「からあげ」が写っています。からあげは、鶏肉を一口サイズに切って、衣をつけて油で揚げた料理です。写真のからあげは、お皿の上に白い紙が敷かれてその上に盛り付けられています。からあげの横には、緑色の葉っぱとレモンのくし切りが添えられています。葉っぱは見た目を良くするための飾りで、レモンはしぼってからあげにかけると、さっぱりとした味になりますよ。とても美味しそうですね！

問題なく解説できています。

"からあげは、鶏肉を一口サイズに切って、衣をつけて油で揚げた料理"という決めつけは鶏の唐揚げ以外は認めないという思想も感じます。

### とり天の画像に対してのGPTの解説

> <img src="https://i.gyazo.com/c6487e4024b981a0b5bbeae398da8368.jpg" width="200px" />

> この画像には、美味しそうな「天ぷら」が写っています。天ぷらは、日本の料理で、魚や野菜などを特別な衣（ころも）で包んで揚げたものです。このお皿には、いくつかの天ぷらが盛り付けられており、その横にはパセリのような緑色の葉っぱと、黄色いマスタードが少し添えられています。全体的にカリッと美味しそうに揚がっていますね。

天ぷらとして判断しています。
鶏の天ぷらとして判断は出来てませんね。

Claudeと同様な感じです。去年も同様の結果だったのでGPTは去年からからあげ界隈であまり進化していませんね。

### GPTの「からあげ」と「とり天」判定まとめ

Claudeと同様な判定具合で、からあげと天ぷらは見分けられるけど、天ぷらの中身に関しては当てられていません。

## おまけ: からあげ先生の画像

去年同様に、からあげ先生のアイコンを読ませてみました。

> > <img src="https://i.gyazo.com/b8b3ab62020c27b508380b289400dcf1.png" width="200px" />

各AIの反応はこちら

- GPT（GPT-4o)の回答

> これは、かわいい猫の顔のイラストです。猫は茶色のベレー帽をかぶっていて、笑っているように見えます。口にはパイプをくわえていて、楽しそうな表情をしています。背景は白くて、イラストのアウトラインが黒で描かれています。

- Geminiの回答

> これはね、とっても可愛いイラストのステッカーだよ！
> 
> 白い猫さんの顔が描かれていて、頭にはオレンジ色のベレー帽をかぶっているんだ。ベレー帽って、画家さんとかが被っている帽子だよ。
> 
> そして、猫さんはパイプをくわえて、にこにこ笑っているんだ。パイプって、煙草を吸うための小さな管だよ。この猫さんは煙草を吸っているわけじゃないよ、きっとお気に入りのパイプをくわえて、リラックスしているんだね。
> 
> 全体として、とってもかわいくて、ちょっとおしゃれなデザインのステッカーなんだ！  まるで、芸術家のような猫さんだね！

- Claudeの回答

> この画像は可愛らしい漫画のような白い猫のイラストです。
> 
> 特徴的なのは:
> - 猫の頭に茶色いベレー帽をかぶっています
> - パイプをくわえています
> - 目を細めて幸せそうな表情をしています
> - シンプルな線で描かれたステッカーのようなデザインです
> 
> このイラストは、芸術家や知識人のような雰囲気を漂わせる可愛らしい猫のキャラクターを表現しています。白い背景に浮かぶようなデザインで、ステッカーとして使えそうなイラストです。

GPTは割と味気ない解説、Geminiはテンションが高い、Claudeは丁寧に説明してくれている感じがしますね。

## まとめ

**「からあげ」と「てんぷら」の判定はできるけど、「からあげ」と「とり天」を見分けるまでは惜しくも出来ていない。**

というのがまとめな気がします。

去年は"天ぷらとからあげの見分けができていること"を「優秀」と書いていましたが、AIに対しての期待値が変わっているなと去年の記事と今回の検証を見て思いました。

去年はAIがからあげと天ぷらの判断をしてくれるとは思ってなかったですが、去年の段階でそこくらいは出来ていたので何の天ぷらかも含めて出してくれたら面白いなと思った次第です。

期待が高すぎたし、そもそもこの画像、人間が見ても何の天ぷらか当てるのは結構厳しい気がします。

> この画像だけ
> <img src="https://i.gyazo.com/c6487e4024b981a0b5bbeae398da8368.jpg" width="200px" />

その中で野菜や魚の天ぷらじゃないかな？と予想しているClaudeに優秀さを感じました。
Geminiは当てずっぽうかもしれないですが、鶏の唐揚げと言っていたので中身は合ってそうですよね。

この子たちをディスカッションさせたらちょうど良い答えが出るかもなのでマルチエージェントで試したらまた変わりそう。

そろそろ画像を変えたり、中身の予想をしてみてほしいとプロンプト調整をしてジャッジしても良さそうですね。中身の予想もしてほしいというプロンプトにしたり、とり天かからあげかどっちかの画像を送るから判断してほしいといった旨のプロンプトにしたら簡単に判断してくれそうな気もします。

誰かお願いします。