Googleの最新LLM「Gemini 2.0 Pro」とは?概要から使い方、実際に試した結果まで解説!

Google Gemini 2.0 Pro 概要 使い方 結果
押さえておきたいポイント
  • Gemini 2.0 Flashをベースとしたモデル
  • Geminiの中で最も優れたコーディング能力を持つ
  • マルチモーダル対応

2025年2月6日、Googleから新たなLLMが登場!

新しくリリースされた「Gemini 2.0 Pro」は12月にリリースされたGemini 2.0 Flashをベースとしたモデル。たった2ヶ月で新たなモデルがリリースされました。

Gemini 2.0 ProはこれまでのGeminiモデルの中で最も優れたコーディング性能を有しており、複雑なプロンプトに対しする理解力と推論能力が向上しています。

本記事ではGemini 2.0 Proの概要から性能、使い方までをご紹介します。本記事を最後まで読むことでGemini 2.0 Proについて理解を深めることが可能です。ぜひ最後までお読みください!

目次

Gemini 2.0 Proの概要

Gemini 2.0 Proは2024年12月にリリースされたGemini 2.0 Flashをベースとした新たなモデルです。今回発表されたLLMは2つです。Gemini 2.0 Proのほか、Gemini 2.0 Flash-Liteが発表されました。

Gemini 2.0 Proは特にコーディング性能はこれまでのGeminiモデルの中で最も優れたパフォーマンスを発揮。

また、複雑なプロンプトに対する理解力と推論能力が改善しているのでこれまで以上にユーザーの指示に対して適切な回答を出力できます。

Gemini 2.0 Proは200万トークンのコンテキストウィンドウをもち、大量の情報を一度に処理することも可能となりました。

Gemini 2.0 Proの技術

Gemini 2.0 Proの性能が向上した背景には2つの要因があります。

  • 新しい強化学習技術
  • 自動レッドチーム

まず、Gemini 2.0 Proは新しい強化学習技術として、Gemini自体にその対応を批判させる技術を用いています。その結果、より正確で的を絞ったフィードバックが得られ、モデルのデリケートなプロンプトへの対応能力が向上

次に自動レッドチームはレッドチームを自動化して、間接的なプロンプトインジェクション攻撃によるリスクを含め、安全性とセキュリティのリスクを評価しています。
(※悪意のある命令をAIシステムが取得する可能性のあるデータに隠すサイバーセキュリティ攻撃の一種)

上記2点を組み合わせることにより、モデルのパフォーマンス・コスト・安全性が向上しています。

Gemini 2.0 Proの性能

Geminiモデル内での比較になってしまいますが、Gemini 2.0 ProはFACTS Groundingの面でのみ、他のモデルに負けています。それ以外については最も性能が高くなっています。

参考:https://developers.googleblog.com/en/gemini-2-family-expands/

FACTS Groundingは、Google DeepMindとGoogle Researchが共同開発したLLMの事実性評価ベンチマーク。

LLMが与えられた文脈に基づいて、どれだけ事実に忠実で詳細な回答を生成できるかを測定することを目的としています。評価基準としては、「事実性」と「詳細性」の二つの観点からLLMの回答を分析し、金融、技術、小売、医療、法律といった幅広い分野をカバーする1,719の事例をもとに検証を行うものです。

Gemini 2.0 Proのスコアは82.8%であり、Gemini 2.0 Flashの84.6%に比べ性能は低いです。そのため、Gemini 2.0 Proは長文の理解や推論能力に優れる一方で、もしかするとハルシネーションを発生しやすい可能性はあるかもしれません。

ChatBot ArenaにGemini 2.0 Proがアップされていましたが、全体的な性能としては、Gemini 2.0 Flash Thinking Exp 0121の方が高いようです。

参考:https://huggingface.co/spaces/lmarena-ai/chatbot-arena-leaderboard

また、コーディングの性能を確認してみると、最も性能が良いのがGemini 2.0 Proという結果になっています。

参考:https://huggingface.co/spaces/lmarena-ai/chatbot-arena-leaderboard

筆者個人的な所感ですが、Claude 3.5 sonnetのコーディング性能は高いと感じていて、実用に耐えられうるものを出力してくれる、という感覚でした。

しかし、ChatBot Arenaを確認してみると、ランクは12位であり、Claude 3.5 sonnetよりも性能が良いモデルが多くあることに驚きです。

さらに、Gemini 2.0 Proはマルチターンの性能も1位です。ということは、会話の文脈を維持した状態で複数回のやり取りを行うことができます。

コーディングでは複数回のやり取りを行うかと思います。ただ、会話が長すぎると最初と最後で一貫性のある回答を受け取ることができません。しかし、Gemini 2.0 Proであれば、会話の一貫性を保ったまま、コーディングをはじめとしたタスクを遂行することが可能です。

参考:https://huggingface.co/spaces/lmarena-ai/chatbot-arena-leaderboard

Gemini2.0モデル一覧

Gemini 2.0モデルは2025/02/06時点で3つです。

スクロールできます
Gemini 2.0 FlashGemini 2.0 Flash-Lite PreviewGemini 2.0 Pro Experimental
リリース状況一般提供中プレビュー提供中実験的な提供
マルチモーダル入力⭕️⭕️⭕️
テキスト出力⭕️⭕️⭕️
画像出力今後追加予定⭕️今後追加予定
音声出力今後追加予定⭕️今後追加予定
マルチモーダルLive API実験的な提供今後追加予定
コンテキストウィンドウ100万トークン100万トークン200万トークン
構造化出力⭕️⭕️⭕️
検索ツールの利用⭕️⭕️
コード実行ツールの利用⭕️⭕️

一覧で見てみるとコンテキストウィンドウの違いはありますが、Gemini 2.0 FlashとProでできることが結構被っていますね。Gemini 2.0 Flashは幅広い機能に適応しており、日常的に使いやすいかもしれません。

Gemini 2.0 Proの料金体系

Gemini 2.0 ProはGoogle AI Studioを使えば無料で利用できます。また従量課金制になりますがVertex AIでも使用可能。

Gemini 2.0 ProのAPI利用料はまだ発表されておらず、おそらく「Experimental」の段階なので正式にリリースされたら発表されるかもしれません。

それ以外のAPI使用料は以下のとおりです。gemini-exp-1206が開発段階から進めば、API料も公開されるかもしれません。

スクロールできます
特徴Gemini 2.0 FlashGemini 1.5 FlashGemini 1.5 Flash-8BGemini 1.5 ProGemini 1.0 Pro
レート制限 (リクエスト/分)Tier1:2,000
Tier2:10,000
2,0004,0001,000360
レート制限 (トークン/分)Tier1:4,000,000
Tier2:10,000,000
4,000,0004,000,0004,000,000120,000
1プロンプトあたりの最大トークン数未記載128,000128,000128,00030,000
入力料金 (100万トークンあたり)100 万トークンあたり $0.10(テキスト/画像/動画)
100 万トークンあたり $0.70(音声)
$0.075$0.0375$1.25$0.50
出力料金 (100万トークンあたり)100 万トークン(テキスト)あたり $0.40$0.30$0.15$5.00$1.50
コンテキストキャッシュ保存料金 (100万トークンあたり/時間)100 万トークンあたり $0.025(テキスト/画像/動画)
100 万トークンあたり $0.175(音声)
$1.00$0.25$4.50利用不可
チューニング料金利用不可無料無料利用不可利用不可
Googleサービス改善への利用いいえいいえいいえいいえいいえ

なお、思考プロセスが生む推論力を持つGemini 2.0 Flash Thinkingについて詳しく知りたい方は、下記の記事を合わせてご確認ください。

Gemini 2.0 Proの使い方

Gemini 2.0 ProはGoogle AI Studioを使えば無料で使えます。

参考:https://aistudio.google.com/prompts/new_chat

画面向かって右側の「Model」から「Gemini 2.0 Pro Experimental 02-05」を選択すればOKです。

参考:https://aistudio.google.com/prompts/new_chat

あとはプロンプトを入力して出力されるのを待ちます。

Gemini 2.0 ProにGemini 2.0 Proのことを聞いてもまだ学習されていませんでした。

Gemini 2.0 Proのコーディング能力を検証

Gemini 2.0 Proのコーディング能力は従来のGeminiモデルの中でも最も優れたパフォーマンスを発揮すると報告されています。

そこで、Claude 3.5 sonnetとGemini 2.0 Proに同じプロンプトを与えて、コーディング能力を検証してみたいと思います。

一つ目のタスクでは言語を指定せずに、Gradioで動くオセロアプリを作ってもらいます。二つ目のタスクではJavaScriptnという縛りを与えて五目並べのアプリを作ってもらいます。

オセロアプリ

入力するプロンプトはこちらです。

Gradioで動くオセロアプリを作ってください。

Gemini 2.0 Proの結果はこちら
import gradio as gr
import numpy as np

def initial_board():
    """初期盤面を作成する関数"""
    board = np.zeros((8, 8), dtype=int)
    board[3, 3] = board[4, 4] = 1  # 白石
    board[3, 4] = board[4, 3] = -1 # 黒石
    return board

def is_valid_move(board, row, col, player):
    """指定されたマスに石を置けるか判定する関数"""
    if board[row, col] != 0:
        return False

    for dr in [-1, 0, 1]:
        for dc in [-1, 0, 1]:
            if dr == 0 and dc == 0:
                continue

            r, c = row + dr, col + dc
            if 0 <= r < 8 and 0 <= c < 8 and board[r, c] == -player:
                while 0 <= r < 8 and 0 <= c < 8:
                    if board[r, c] == player:
                        return True
                    if board[r, c] == 0:
                        break
                    r += dr
                    c += dc
    return False

def flip_stones(board, row, col, player):
    """石をひっくり返す関数"""
    board[row, col] = player
    for dr in [-1, 0, 1]:
        for dc in [-1, 0, 1]:
            if dr == 0 and dc == 0:
                continue

            r, c = row + dr, col + dc
            if 0 <= r < 8 and 0 <= c < 8 and board[r, c] == -player:
                to_flip = []
                while 0 <= r < 8 and 0 <= c < 8:
                    if board[r, c] == player:
                        for flip_r, flip_c in to_flip:
                            board[flip_r, flip_c] = player
                        break
                    if board[r, c] == 0:
                        break
                    to_flip.append((r, c))
                    r += dr
                    c += dc
    return board

def get_possible_moves(board, player):
    """可能な手のリストを返す関数"""
    possible_moves = []
    for row in range(8):
        for col in range(8):
            if is_valid_move(board, row, col, player):
                possible_moves.append((row, col))
    return possible_moves

def check_game_over(board):
    """ゲーム終了判定"""
    return len(get_possible_moves(board, 1)) == 0 and len(get_possible_moves(board, -1)) == 0

def count_stones(board):
    """石の数を数える"""
    black_count = np.count_nonzero(board == -1)
    white_count = np.count_nonzero(board == 1)
    return black_count, white_count

def othello_game(row, col, current_board_str, current_player):
    """オセロゲームのロジック"""

    # 現在の盤面をNumPy配列に変換
    current_board = np.array(eval(current_board_str))

    player = int(current_player)  # playerを整数型に

    # 入力が有効な手か確認
    if not is_valid_move(current_board, row, col, player):
      message = "そこには置けません"
      return current_board.tolist(), str(current_board.tolist()), str(player) ,message  # 同じ盤面とプレイヤーを返す


    # 石をひっくり返す
    updated_board = flip_stones(current_board.copy(), row, col, player)

    # ターンを交代 (1 -> -1, -1 -> 1)
    next_player = -player

    # パスの処理: 次のプレイヤーが打てる手がない場合、現在のプレイヤーが続行
    if not get_possible_moves(updated_board, next_player):
        next_player = player
        if not get_possible_moves(updated_board, next_player):
            message = "ゲーム終了" # 両者とも打てない場合

            black_count, white_count = count_stones(updated_board)
            if black_count > white_count:
              message += f"黒の勝ち! 黒:{black_count}、白:{white_count}"
            elif white_count > black_count:
              message += f"白の勝ち! 黒:{black_count}、白:{white_count}"
            else:
              message += f"引き分け! 黒:{black_count}、白:{white_count}"

            return updated_board.tolist(), str(updated_board.tolist()), str(next_player), message


        message = "置ける場所がないので、ターンが継続されます" #相手が置けない場合
    else:
      message = " "

    return updated_board.tolist(), str(updated_board.tolist()), str(next_player) ,message




def create_board_display(board):
  """盤面表示用のリストを作成"""
  display_board = []
  for row in board:
    display_row = []
    for cell in row:
      if cell == 1:
        display_row.append("⚪️") # 白石
      elif cell == -1:
        display_row.append("⚫️") # 黒石
      else:
        display_row.append("🟩") # 空きマス
    display_board.append(display_row)
  return display_board


# Gradioインターフェース
with gr.Blocks() as demo:
    # 状態変数
    board_state = gr.State(str(initial_board().tolist()))
    player_state = gr.State("1")   # 1: 黒, -1: 白


    with gr.Row():

        with gr.Column():
          # 入力
          row_input = gr.Slider(0, 7, step=1, label="行 (Row)")
          col_input = gr.Slider(0, 7, step=1, label="列 (Column)")

          # メッセージ表示
          message_output = gr.Textbox(label="メッセージ")
          # 実行ボタン
          play_button = gr.Button("Play")

        with gr.Column():
          # 盤面表示
          board_output = gr.Dataframe(value = create_board_display(initial_board()), label="オセロ盤面", interactive=False, every=1)


    # ボタンクリック時の処理
    play_button.click(
        othello_game,
        [row_input, col_input, board_state, player_state],
        [board_output, board_state, player_state, message_output]
    )
    # 盤面表示の更新関数
    def update_board_display(board):
      return create_board_display(board)

    # 定期的に盤面表示を更新するためのイベントハンドラ
    board_state.change(update_board_display, board_state, board_output)

demo.launch()
Claude 3.5 sonnetの結果はこちら
import gradio as gr
import numpy as np

class OthelloGame:
    def __init__(self):
        self.board = np.zeros((8, 8), dtype=int)
        # 初期配置
        self.board[3:5, 3:5] = [[1, -1], [-1, 1]]
        self.current_player = 1  # 1: 黒, -1: 白

    def is_valid_move(self, row, col):
        if self.board[row, col] != 0:
            return False
        
        directions = [(0, 1), (1, 0), (0, -1), (-1, 0),
                     (1, 1), (-1, -1), (1, -1), (-1, 1)]
        
        valid = False
        for dr, dc in directions:
            r, c = row + dr, col + dc
            pieces_to_flip = []
            
            while 0 <= r < 8 and 0 <= c < 8 and self.board[r, c] == -self.current_player:
                pieces_to_flip.append((r, c))
                r, c = r + dr, c + dc
                
            if pieces_to_flip and 0 <= r < 8 and 0 <= c < 8 and self.board[r, c] == self.current_player:
                valid = True
                break
                
        return valid

    def make_move(self, row, col):
        if not self.is_valid_move(row, col):
            return False
        
        directions = [(0, 1), (1, 0), (0, -1), (-1, 0),
                     (1, 1), (-1, -1), (1, -1), (-1, 1)]
        
        pieces_flipped = False
        for dr, dc in directions:
            r, c = row + dr, col + dc
            pieces_to_flip = []
            
            while 0 <= r < 8 and 0 <= c < 8 and self.board[r, c] == -self.current_player:
                pieces_to_flip.append((r, c))
                r, c = r + dr, c + dc
                
            if pieces_to_flip and 0 <= r < 8 and 0 <= c < 8 and self.board[r, c] == self.current_player:
                pieces_flipped = True
                for flip_r, flip_c in pieces_to_flip:
                    self.board[flip_r, flip_c] = self.current_player
        
        if pieces_flipped:
            self.board[row, col] = self.current_player
            self.current_player = -self.current_player
            return True
        return False

    def get_valid_moves(self):
        valid_moves = []
        for i in range(8):
            for j in range(8):
                if self.board[i, j] == 0 and self.is_valid_move(i, j):
                    valid_moves.append((i, j))
        return valid_moves

    def get_score(self):
        black = np.sum(self.board == 1)
        white = np.sum(self.board == -1)
        return black, white

def create_board_image(game):
    board = game.board
    valid_moves = game.get_valid_moves()
    
    import matplotlib.pyplot as plt
    
    fig, ax = plt.subplots(figsize=(8, 8))
    ax.set_facecolor('green')
    
    # グリッドを描画
    for i in range(9):
        ax.plot([i, i], [0, 8], 'black')
        ax.plot([0, 8], [i, i], 'black')
    
    # 石を描画
    for i in range(8):
        for j in range(8):
            if board[i, j] == 1:  # 黒
                circle = plt.Circle((j + 0.5, 7.5 - i), 0.4, color='black')
                ax.add_artist(circle)
            elif board[i, j] == -1:  # 白
                circle = plt.Circle((j + 0.5, 7.5 - i), 0.4, color='white')
                ax.add_artist(circle)
    
    # 有効な手を表示
    for i, j in valid_moves:
        circle = plt.Circle((j + 0.5, 7.5 - i), 0.15, color='red')
        ax.add_artist(circle)
    
    ax.set_xlim(-0.5, 8.5)
    ax.set_ylim(-0.5, 8.5)
    ax.set_aspect('equal')
    ax.axis('off')
    
    return fig

def play_game(row, col, state):
    game = OthelloGame()
    game.board = np.array(eval(state))
    game.current_player = 1 if np.sum(game.board == 0) % 2 == 0 else -1
    
    if game.make_move(row, col):
        black_score, white_score = game.get_score()
        valid_moves = game.get_valid_moves()
        
        if not valid_moves:
            game.current_player = -game.current_player
            valid_moves = game.get_valid_moves()
            if not valid_moves:
                return create_board_image(game), str(game.board.tolist()), f"ゲーム終了!\n黒: {black_score} 白: {white_score}"
        
        return create_board_image(game), str(game.board.tolist()), f"黒: {black_score} 白: {white_score}"
    else:
        return create_board_image(game), state, "無効な手です。もう一度お試しください。"

def reset_game():
    game = OthelloGame()
    return create_board_image(game), str(game.board.tolist()), "新しいゲームを開始しました。"

# Gradioインターフェースの作成
with gr.Blocks() as demo:
    gr.Markdown("# オセロゲーム")
    gr.Markdown("黒が先手です。赤い点は有効な手を示しています。")
    
    with gr.Row():
        board_display = gr.Plot()
        
    with gr.Row():
        row_input = gr.Number(label="行 (0-7)", minimum=0, maximum=7, step=1)
        col_input = gr.Number(label="列 (0-7)", minimum=0, maximum=7, step=1)
    
    state = gr.State(str(OthelloGame().board.tolist()))
    message = gr.Markdown("")
    
    with gr.Row():
        play_button = gr.Button("Play")
        reset_button = gr.Button("Reset")
    
    play_button.click(
        play_game,
        inputs=[row_input, col_input, state],
        outputs=[board_display, state, message]
    )
    
    reset_button.click(
        reset_game,
        outputs=[board_display, state, message]
    )

if __name__ == "__main__":
    demo.launch()

実装はできましたが、ClaudeもGemini 2.0 Proも遊ぶことはできませんでした。ただ、見た目的にはGemini 2.0 Proの方がオセロっぽい見た目にはなりました。

JavaScriptで五目並べを作成

では次に、JavaScriptで五目並べのアプリを作ってください、と指示を与えます。

Gemini 2.0 Proの結果はこちら
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>五目並べ</title>
    <style>
        body {
            font-family: sans-serif;
            display: flex;
            flex-direction: column;
            align-items: center;
        }

        .board {
            display: grid;
            grid-template-columns: repeat(15, 30px); /* 15x15のマス */
            grid-template-rows: repeat(15, 30px);
            border: 2px solid black;
            margin-bottom: 10px;
        }

        .cell {
            width: 30px;
            height: 30px;
            border: 1px solid #ccc;
            text-align: center;
            font-size: 24px;
            line-height: 30px;
            cursor: pointer;
        }

        .cell.black {
            background-color: black;
            color: white;
            border-radius: 50%; /* 円形にする */
        }

        .cell.white {
            background-color: white;
            color: black;
            border: 1px solid black;  /* 白石の境界線 */
            border-radius: 50%; /* 円形にする */
        }
        
        #message {
            font-size: 1.2em;
            font-weight: bold;
            margin-top: 10px;
            min-height: 1.5em; /* メッセージがない時も高さを確保 */
        }

        button {
            padding: 8px 16px;
            font-size: 1em;
            margin-top: 10px;
        }
    </style>
</head>
<body>
    <h1>五目並べ</h1>

    <div class="board"></div>

    <div id="message"></div>

    <button id="reset-button">リセット</button>


    <script>
        const boardSize = 15;
        const board = document.querySelector('.board');
        const message = document.getElementById('message');
        const resetButton = document.getElementById('reset-button');
        let currentPlayer = 'black'; // 'black' or 'white'
        let gameBoard = [];  // 盤面の状態を保持する配列

        // 盤面の初期化
        function initBoard() {
            gameBoard = []; // 盤面データをクリア
            board.innerHTML = ''; // 盤面表示をクリア
            for (let i = 0; i < boardSize; i++) {
                gameBoard[i] = [];
                for (let j = 0; j < boardSize; j++) {
                    gameBoard[i][j] = null; // null: 空, 'black', 'white'
                    const cell = document.createElement('div');
                    cell.classList.add('cell');
                    cell.dataset.row = i;
                    cell.dataset.col = j;
                    cell.addEventListener('click', handleCellClick);
                    board.appendChild(cell);
                }
            }
            currentPlayer = 'black';  // 先手は黒
            message.textContent = "黒の番です";
        }


        function handleCellClick(event) {
            const row = parseInt(event.target.dataset.row);
            const col = parseInt(event.target.dataset.col);

            // すでに石がある場合は何もしない
            if (gameBoard[row][col]) {
                return;
            }

            // 石を置く
            gameBoard[row][col] = currentPlayer;
            event.target.classList.add(currentPlayer);

            // 勝敗判定
            if (checkWin(row, col, currentPlayer)) {
                message.textContent = `${currentPlayer === 'black' ? '黒' : '白'}の勝ち!`;
                // 全てのセルのクリックイベントを無効にする
                document.querySelectorAll('.cell').forEach(cell => {
                    cell.removeEventListener('click', handleCellClick);
                });
                return;
            }

            // 引き分け判定 (盤面が全て埋まったら)
            if (checkDraw()) {
                message.textContent = "引き分け!";
                return;
            }

            // プレイヤー交代
            currentPlayer = currentPlayer === 'black' ? 'white' : 'black';
            message.textContent = `${currentPlayer === 'black' ? '黒' : '白'}の番です`;
        }



        function checkWin(row, col, player) {
            // 横方向
            let count = 1;
            for (let i = col - 1; i >= 0 && gameBoard[row][i] === player; i--) count++;
            for (let i = col + 1; i < boardSize && gameBoard[row][i] === player; i++) count++;
            if (count >= 5) return true;

            // 縦方向
            count = 1;
            for (let i = row - 1; i >= 0 && gameBoard[i][col] === player; i--) count++;
            for (let i = row + 1; i < boardSize && gameBoard[i][col] === player; i++) count++;
            if (count >= 5) return true;

            // 斜め (右上から左下)
            count = 1;
            for (let i = 1; row - i >= 0 && col - i >= 0 && gameBoard[row - i][col - i] === player; i++) count++;
            for (let i = 1; row + i < boardSize && col + i < boardSize && gameBoard[row + i][col + i] === player; i++) count++;
            if (count >= 5) return true;

            // 斜め (左上から右下)
            count = 1;
            for (let i = 1; row - i >= 0 && col + i < boardSize && gameBoard[row - i][col + i] === player; i++) count++;
            for (let i = 1; row + i < boardSize && col - i >= 0 && gameBoard[row + i][col - i] === player; i++) count++;
            if (count >= 5) return true;


            return false;
        }



        function checkDraw() {
          for (let i = 0; i < boardSize; i++) {
            for (let j = 0; j < boardSize; j++) {
              if (gameBoard[i][j] === null) {
                return false; // 空きマスがあれば引き分けではない
              }
            }
          }
          return true; // 全て埋まっていれば引き分け
        }


        // リセットボタンの処理
        resetButton.addEventListener('click', initBoard);

        // 初期化
        initBoard();

    </script>
</body>
</html>
Calude 3.5 sonnetの結果はこちら
<!DOCTYPE html>
<html>
<head>
    <title>五目並べ</title>
    <style>
        .board {
            display: grid;
            grid-template-columns: repeat(15, 40px);
            grid-template-rows: repeat(15, 40px);
            gap: 1px;
            background-color: #deb887;
            padding: 10px;
            border: 2px solid #8b4513;
        }

        .cell {
            width: 40px;
            height: 40px;
            background-color: #deb887;
            border: 1px solid #8b4513;
            display: flex;
            align-items: center;
            justify-content: center;
            cursor: pointer;
            position: relative;
        }

        .cell::before {
            content: '';
            position: absolute;
            width: 30px;
            height: 30px;
            border-radius: 50%;
        }

        .black::before {
            background-color: black;
        }

        .white::before {
            background-color: white;
            border: 1px solid black;
        }

        .game-container {
            display: flex;
            flex-direction: column;
            align-items: center;
            gap: 20px;
            padding: 20px;
        }

        .status {
            font-size: 24px;
            font-weight: bold;
        }

        .reset-button {
            padding: 10px 20px;
            font-size: 16px;
            background-color: #4CAF50;
            color: white;
            border: none;
            border-radius: 5px;
            cursor: pointer;
        }

        .reset-button:hover {
            background-color: #45a049;
        }
    </style>
</head>
<body>
    <div class="game-container">
        <h1>五目並べ</h1>
        <div class="status" id="status">黒の番です</div>
        <div class="board" id="board"></div>
        <button class="reset-button" onclick="resetGame()">リセット</button>
    </div>

    <script>
        const BOARD_SIZE = 15;
        let currentPlayer = 'black';
        let gameBoard = Array(BOARD_SIZE).fill().map(() => Array(BOARD_SIZE).fill(null));
        let gameActive = true;

        function createBoard() {
            const board = document.getElementById('board');
            board.innerHTML = '';
            
            for (let i = 0; i < BOARD_SIZE; i++) {
                for (let j = 0; j < BOARD_SIZE; j++) {
                    const cell = document.createElement('div');
                    cell.className = 'cell';
                    cell.dataset.row = i;
                    cell.dataset.col = j;
                    cell.addEventListener('click', handleClick);
                    board.appendChild(cell);
                }
            }
        }

        function handleClick(event) {
            if (!gameActive) return;

            const row = parseInt(event.target.dataset.row);
            const col = parseInt(event.target.dataset.col);

            if (gameBoard[row][col]) return;

            gameBoard[row][col] = currentPlayer;
            event.target.classList.add(currentPlayer);

            if (checkWin(row, col)) {
                document.getElementById('status').textContent = 
                    `${currentPlayer === 'black' ? '黒' : '白'}の勝ちです!`;
                gameActive = false;
                return;
            }

            currentPlayer = currentPlayer === 'black' ? 'white' : 'black';
            document.getElementById('status').textContent = 
                `${currentPlayer === 'black' ? '黒' : '白'}の番です`;
        }

        function checkWin(row, col) {
            const directions = [
                [[0, 1], [0, -1]],  // 横
                [[1, 0], [-1, 0]],  // 縦
                [[1, 1], [-1, -1]], // 斜め(右下-左上)
                [[1, -1], [-1, 1]]  // 斜め(右上-左下)
            ];

            return directions.some(direction => {
                const count = countInDirection(row, col, direction[0])
                    + countInDirection(row, col, direction[1])
                    + 1;
                return count >= 5;
            });
        }

        function countInDirection(row, col, [dx, dy]) {
            let count = 0;
            let currentRow = row + dx;
            let currentCol = col + dy;

            while (
                currentRow >= 0 && 
                currentRow < BOARD_SIZE && 
                currentCol >= 0 && 
                currentCol < BOARD_SIZE && 
                gameBoard[currentRow][currentCol] === currentPlayer
            ) {
                count++;
                currentRow += dx;
                currentCol += dy;
            }

            return count;
        }

        function resetGame() {
            gameBoard = Array(BOARD_SIZE).fill().map(() => Array(BOARD_SIZE).fill(null));
            currentPlayer = 'black';
            gameActive = true;
            document.getElementById('status').textContent = '黒の番です';
            
            const cells = document.getElementsByClassName('cell');
            Array.from(cells).forEach(cell => {
                cell.classList.remove('black', 'white');
            });
        }

        // 初期化
        createBoard();
    </script>
</body>
</html>

今回はどちらも遊ぶことができました。見た目はClaudeの方がリッチな雰囲気があります。

Gemini 2.0 ProとClaudeを比較してみましたが、どちらもそれなりのものを出力してくれました。特にClaude 3.5 sonnetはChatBot Arenaのランクが12位にも関わらず、1位のGemini 2.0 Proと同等の出力をしてくれています。

もしかすると、会話が長くなるにつれてGemini 2.0 Proの良さが目立つようになるのかもしれません。

なお、GPT-4oやDeepSeek V3を超えるQwen2.5-Maxについて詳しく知りたい方は、下記の記事を合わせてご確認ください。

まとめ

本記事ではGemini 2.0 Proの概要から性能、使い方について解説をしました。現在はまだExperimentalモデルですが、今後正式リリースされればAPI経由でも利用できるようになるでしょう。

コーディング能力に凄さにはまだまだ検証が足りていませんが、Claude 3.5 sonnetと同等もしくはそれ以上の場合には、個人開発をはじめとしたアプリ制作などが非常に活発になりそうです。

ぜひ皆さんも本記事を参考にGemini 2.0 Proを使ってみてください!

最後に

いかがだったでしょうか

生成AIは、単なる業務の自動化だけでなく、クリエイティブな業務支援や開発の効率化、社内DXの推進など、企業の多くの領域で活用できます。

貴社の事業にどう活かせるか、具体的な導入事例や最適な活用方法をご提案できますので、ぜひご相談ください。

株式会社WEELは、自社・業務特化の効果が出るAIプロダクト開発が強みです!

開発実績として、

・新規事業室での「リサーチ」「分析」「事業計画検討」を70%自動化するAIエージェント
・社内お問い合わせの1次回答を自動化するRAG型のチャットボット
・過去事例や最新情報を加味して、10秒で記事のたたき台を作成できるAIプロダクト
・お客様からのメール対応の工数を80%削減したAIメール
・サーバーやAI PCを活用したオンプレでの生成AI活用
・生徒の感情や学習状況を踏まえ、勉強をアシストするAIアシスタント

などの開発実績がございます。

まずは、無料相談にてご相談を承っておりますので、ご興味がある方はぜひご連絡ください。

➡︎生成AIを使った業務効率化、生成AIツールの開発について相談をしてみる。

生成AIを社内で活用していきたい方へ
LLM比較レポート

「生成AIを社内で活用したい」「生成AIの事業をやっていきたい」という方に向けて、生成AI社内セミナー・勉強会をさせていただいております。

セミナー内容や料金については、ご相談ください。

また、大規模言語モデル(LLM)を対象に、言語理解能力、生成能力、応答速度の各側面について比較・検証した資料も配布しております。この機会にぜひご活用ください。

投稿者

  • 翔平

    総合病院で10年間理学療法士として勤務し、患者のリハビリテーション支援に従事。その後、Pythonを独学で学び、データ分析のスキルを活かしてデータアナリストに転身。 データ分析の知見を活かし、主にテクニカル記事を担当。趣味はキックボクシング。

  • URLをコピーしました!
  • URLをコピーしました!
目次