Search

0
0

Claude3.7Sonnetモデルは何が違う?旧モデルとの違いを実例をもとに解説!

はじめに

皆さま、いかがお過ごしでしょうか。本記事では、AIモデル「Claude 3.7 Sonnet」がリリースされたことにあわせ、前バージョンの3.5と比較しながらフロントエンド開発の事例や物理学の問題解法などをご紹介します。

直近、なかなか新しいニュースが発表されていなかったClaudeAIですが、つい先日、新しいニュースが入りました。

今回の主役である3.7は、従来の速度重視スタイルを継承しつつ、複雑な課題を深い思考で解決するハイブリッド推論を取り入れており、その柔軟性が大きな特徴です。さらに「Claude Code」というコマンドラインツールも登場しており、コーディング支援やリファクタリングを迅速化することが期待されます。本記事では実際に投げたプロンプトと、その出力結果を踏まえながら、両バージョンの使い分け方を考察していきたいと思います。


Claude 3.7 Sonnetの概要

Claude 3.7 Sonnetは、「迅速な応答」と「段階的に深い思考」をユーザーの要求に応じて切り替えられるハイブリッド推論モデルです。API側では、思考に使うトークン数の予算(バジェット)を調整できるため、回答のスピードと精度のバランスを細かく制御できる点が大きなメリットとされています。また、フロントエンドからバックエンドまで多彩なコーディングタスクに対応できることが実証されており、実務的な場面でも使いやすい構成になっているようです。

Claude Codeについて

新しくリリースされた「Claude Code」は、コマンドラインでファイルの検索や編集、テスト、GitHubへのプッシュなどを自動的に行うエージェント型ツールです。大規模リファクタリングやテスト駆動開発を行う際に、複数のファイルを一括操作できるため、作業時間を大幅に短縮できると期待されています。実際にClaude Codeのプレビュー版を試したユーザーからは、「複雑なコードベースの修正も、あらかじめ指示しておけば自動化できる」との声が上がっています。

価格と利用プラン

今回のリリースでは、従来のプランと同じ価格体系が引き継がれており、入力・出力トークン数に応じた課金方式となっています。特筆すべきは、複雑なタスク向けに「extended thinking mode」を使ったとしても、追加料金が発生しない点です。ただし、当然ながら多くのトークンを使うほど費用はかさむため、どこまで深い推論を行うかは使用ケースに合わせて選択する必要があるでしょう。

(出典:公開情報 Claude 3.7 Sonnet)


3.5と3.7の比較:物理学の例

本題に入る前に、まずは3.5と3.7がどのように物理学の問題を解くかを見比べてみます。両バージョンとも、二次元空間の運動方程式から速度ベクトル・加速度ベクトルを求める問題にはスムーズに対応できましたが、その説明方法や途中計算の可視化に違いが見られました。

3.5の場合

3.5では、物理学の問題に対して必要最低限の手順を示し、速度と加速度を計算するといった要点を押さえた回答が多い印象を受けました。式の微分結果と数値代入の結果を示す一方、ステップバイステップの途中式や解説が簡潔にまとめられがちです。そのため、暗算力や物理の基礎知識がある人にとっては十分ですが、学習者がじっくり理解したい場合には若干物足りないケースもあるかもしれません。

3.5の回答例

ClaudeSonnet3.5からの解答例
  • 速度ベクトルを x(t), y(t) の1階微分で提示。
  • t=2 を代入して数値を簡潔に算出。
  • ベクトルの大きさを最終的に√221などの形で説明。
  • 加速度ベクトルはさらにもう1回微分し、同様にt=2で具体値を出す。
  • 詳細な補足や計算過程の説明は少なめ。

3.7の場合

3.7は、計算の途中経過をより丁寧に表現する傾向が強いです。位置ベクトル→速度ベクトル→加速度ベクトルといった形で段階的に微分作業を見せ、さらに「なぜその微分になるのか」や「ベクトルの大きさを求めるにはどのような式を使うのか」など、解説の粒度が細かくなっています。学習者や、計算ミスを防ぎたい場面で役立つでしょう。

3.7の回答例

ClaudeSonnet3.5からの解答例
Claude3.7からの回答例2
  • x(t), y(t)をしっかり書き出し、「速度ベクトルは1階微分、加速度は2階微分」という原理を冒頭で明示。
  • t=2への代入時も、係数の計算を一つずつステップを踏んで示す。
  • 結果として速度ベクトル(11, 10)、加速度ベクトル(4, 12)を導き出し、その大きさもそれぞれ数式で展開。
  • 近似値として14.87 m/sや12.65 m/s²を出しており、最終的なまとめが明解。

フロントエンド開発プロンプト例

次にご紹介するのは、ReactとTailwind CSSを使った問い合わせフォームの作成を依頼するプロンプトです。今回は、実際に投げたプロンプトと、その結果として3.7が生成したコードを提示します。なお、3.5でも同様のコードは生成されて、問い合わせフォーム自体の見た目を比較しただけだと違いを感じづらいですが、生成されたコードの細部の違いを比較することで、モデルの進化を感じられるはずです。

Claude3.5で作成した問い合わせフォーム

Claude3.5で作成した問い合わせフォーム

Claude3.7で作成した問い合わせフォーム

Claude3.7で作成した問い合わせフォーム

実際に投げたプロンプト

「問い合わせフォームのページをReactで作成してください。末尾のコードはexport default RegistrationFormで」

Claude 3.5からの出力コード

以下は、先のプロンプトに対して3.5が返してきたサンプルコードです。

import React, { useState } from 'react';

const RegistrationForm = () => {
  // State for form fields
  const [formData, setFormData] = useState({
    name: '',
    email: '',
    phone: '',
    message: ''
  });

  // State for validation errors
  const [errors, setErrors] = useState({});

  // Handle input changes
  const handleChange = (e) => {
    const { name, value } = e.target;
    setFormData(prevState => ({
      ...prevState,
      [name]: value
    }));
  };

  // Validate form fields
  const validateForm = () => {
    const newErrors = {};

    // Name validation
    if (!formData.name.trim()) {
      newErrors.name = '名前は必須です';
    }

    // Email validation
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    if (!formData.email.trim()) {
      newErrors.email = 'メールアドレスは必須です';
    } else if (!emailRegex.test(formData.email)) {
      newErrors.email = '有効なメールアドレスを入力してください';
    }

    // Phone validation (optional, but must be valid if provided)
    const phoneRegex = /^[0-9]{10,11}$/;
    if (formData.phone.trim() && !phoneRegex.test(formData.phone.replace(/[-\s]/g, ''))) {
      newErrors.phone = '有効な電話番号を入力してください';
    }

    // Message validation
    if (!formData.message.trim()) {
      newErrors.message = 'メッセージは必須です';
    }

    setErrors(newErrors);
    return Object.keys(newErrors).length === 0;
  };

  // Handle form submission
  const handleSubmit = (e) => {
    e.preventDefault();
    
    if (validateForm()) {
      // Form is valid - you would typically send the data to a server here
      console.log('Form submitted:', formData);
      
      // Optional: Reset form after successful submission
      setFormData({
        name: '',
        email: '',
        phone: '',
        message: ''
      });
      
      // Optional: Show success message
      alert('お問い合わせありがとうございます。');
    }
  };

  return (
    <div className="max-w-md mx-auto p-6 bg-white rounded-lg shadow-md">
      <h2 className="text-2xl font-bold mb-6 text-center">お問い合わせフォーム</h2>
      <form onSubmit={handleSubmit}>
        <div className="mb-4">
          <label htmlFor="name" className="block text-gray-700 font-bold mb-2">
            お名前 <span className="text-red-500">*</span>
          </label>
          <input
            type="text"
            id="name"
            name="name"
            value={formData.name}
            onChange={handleChange}
            className={`w-full px-3 py-2 border rounded-lg focus:outline-none ${
              errors.name ? 'border-red-500' : 'border-gray-300'
            }`}
            placeholder="山田 太郎"
          />
          {errors.name && (
            <p className="text-red-500 text-sm mt-1">{errors.name}</p>
          )}
        </div>

        <div className="mb-4">
          <label htmlFor="email" className="block text-gray-700 font-bold mb-2">
            メールアドレス <span className="text-red-500">*</span>
          </label>
          <input
            type="email"
            id="email"
            name="email"
            value={formData.email}
            onChange={handleChange}
            className={`w-full px-3 py-2 border rounded-lg focus:outline-none ${
              errors.email ? 'border-red-500' : 'border-gray-300'
            }`}
            placeholder="example@example.com"
          />
          {errors.email && (
            <p className="text-red-500 text-sm mt-1">{errors.email}</p>
          )}
        </div>

        <div className="mb-4">
          <label htmlFor="phone" className="block text-gray-700 font-bold mb-2">
            電話番号 (任意)
          </label>
          <input
            type="tel"
            id="phone"
            name="phone"
            value={formData.phone}
            onChange={handleChange}
            className={`w-full px-3 py-2 border rounded-lg focus:outline-none ${
              errors.phone ? 'border-red-500' : 'border-gray-300'
            }`}
            placeholder="09012345678"
          />
          {errors.phone && (
            <p className="text-red-500 text-sm mt-1">{errors.phone}</p>
          )}
        </div>

        <div className="mb-4">
          <label htmlFor="message" className="block text-gray-700 font-bold mb-2">
            メッセージ <span className="text-red-500">*</span>
          </label>
          <textarea
            id="message"
            name="message"
            value={formData.message}
            onChange={handleChange}
            rows="4"
            className={`w-full px-3 py-2 border rounded-lg focus:outline-none ${
              errors.message ? 'border-red-500' : 'border-gray-300'
            }`}
            placeholder="お問い合わせ内容をご記入ください"
          ></textarea>
          {errors.message && (
            <p className="text-red-500 text-sm mt-1">{errors.message}</p>
          )}
        </div>

        <div className="text-center">
          <button
            type="submit"
            className="bg-blue-500 text-white px-6 py-2 rounded-lg hover:bg-blue-600 transition duration-300"
          >
            送信
          </button>
        </div>
      </form>
    </div>
  );
};

export default RegistrationForm;

Claude 3.7からの出力コード

以下は、先のプロンプトに対して3.7が返してきたサンプルコードです。実務で使う際には、適宜API連携などを組み込んでいただくことを想定しています。

import React, { useState } from 'react';

function RegistrationForm() {
  const [formData, setFormData] = useState({
    name: '',
    email: '',
    subject: '',
    message: ''
  });
  
  const [errors, setErrors] = useState({});
  const [isSubmitted, setIsSubmitted] = useState(false);

  // 入力変更ハンドラ
  const handleChange = (e) => {
    const { name, value } = e.target;
    setFormData(prev => ({
      ...prev,
      [name]: value
    }));
    
    // エラーをクリア
    setErrors(prev => ({
      ...prev,
      [name]: null
    }));
  };

  // バリデーション
  const validateForm = () => {
    const newErrors = {};

    if (!formData.name.trim()) {
      newErrors.name = 'お名前を入力してください。';
    }
    if (!formData.email.trim()) {
      newErrors.email = 'メールアドレスを入力してください。';
    } else if (!/\S+@\S+\.\S+/.test(formData.email)) {
      newErrors.email = '有効なメールアドレスを入力してください。';
    }
    if (!formData.subject.trim()) {
      newErrors.subject = '件名を入力してください。';
    }
    if (!formData.message.trim()) {
      newErrors.message = 'お問い合わせ内容を入力してください。';
    }

    return newErrors;
  };

  // フォーム送信時の処理
  const handleSubmit = (e) => {
    e.preventDefault();
    const newErrors = validateForm();
    if (Object.keys(newErrors).length > 0) {
      setErrors(newErrors);
      return;
    }
    
    // 本来はここでサーバー側に送信処理を行う
    // とりあえず送信完了フラグをセット
    setIsSubmitted(true);
  };

  // 送信後画面
  if (isSubmitted) {
    return (
      <div className="max-w-md mx-auto mt-10 p-4 bg-green-50 border border-green-300 rounded">
        <h2 className="text-xl font-bold text-green-700">送信完了</h2>
        <p className="text-green-600 mt-2">お問い合わせありがとうございます。追ってご連絡いたします。</p>
        <button
          onClick={() => {
            setFormData({
              name: '',
              email: '',
              subject: '',
              message: ''
            });
            setIsSubmitted(false);
          }}
          className="mt-4 px-4 py-2 bg-green-500 text-white rounded hover:bg-green-600"
        >
          新しい問い合わせ
        </button>
      </div>
    );
  }

  return (
    <div className="max-w-md mx-auto mt-10 p-4 bg-white border border-gray-300 rounded">
      <h2 className="text-xl font-bold mb-4">お問い合わせフォーム</h2>
      <form onSubmit={handleSubmit} className="space-y-4">
        <div>
          <label className="block font-medium">お名前</label>
          <input
            type="text"
            name="name"
            value={formData.name}
            onChange={handleChange}
            className={`w-full p-2 border rounded ${
              errors.name ? 'border-red-500' : 'border-gray-300'
            }`}
            placeholder="例)山田太郎"
          />
          {errors.name && <p className="text-red-500 text-sm mt-1">{errors.name}</p>}
        </div>

        <div>
          <label className="block font-medium">メールアドレス</label>
          <input
            type="email"
            name="email"
            value={formData.email}
            onChange={handleChange}
            className={`w-full p-2 border rounded ${
              errors.email ? 'border-red-500' : 'border-gray-300'
            }`}
            placeholder="example@example.com"
          />
          {errors.email && <p className="text-red-500 text-sm mt-1">{errors.email}</p>}
        </div>

        <div>
          <label className="block font-medium">件名</label>
          <input
            type="text"
            name="subject"
            value={formData.subject}
            onChange={handleChange}
            className={`w-full p-2 border rounded ${
              errors.subject ? 'border-red-500' : 'border-gray-300'
            }`}
            placeholder="お問い合わせタイトル"
          />
          {errors.subject && <p className="text-red-500 text-sm mt-1">{errors.subject}</p>}
        </div>

        <div>
          <label className="block font-medium">お問い合わせ内容</label>
          <textarea
            name="message"
            rows="5"
            value={formData.message}
            onChange={handleChange}
            className={`w-full p-2 border rounded ${
              errors.message ? 'border-red-500' : 'border-gray-300'
            }`}
            placeholder="お問い合わせの内容をご記入ください"
          />
          {errors.message && <p className="text-red-500 text-sm mt-1">{errors.message}</p>}
        </div>

        <button
          type="submit"
          className="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600"
        >
          送信
        </button>
      </form>
    </div>
  );
}

export default RegistrationForm;

このコードでは、バリデーションの粒度、送信完了画面への遷移、再度フォームを初期化して問い合わせを続行できる機能などが盛り込まれており、非常に実用的な形になっています。Tailwindのユーティリティクラスを使ったレイアウト調整や赤枠表示によるエラー強調など、UI面でもわかりやすく実装されているのが特徴です。


モデルアップデートと実務への導入

3.7では、数学問題やフロントエンド開発の事例だけでなく、より大規模なコーディングタスクのサポートや、エージェント的な自動修正が期待されると公表されています。しかし、以下の点には注意を払う必要があります。

  • 思考プロセスを長く取りすぎない
    Extended thinking modeを多用すると、トークン消費量が増えがちです。コストを抑えたい場合は、より短い思考プロセスで解けるタスクだけを回すなど、運用方針を定めておきましょう。
  • コードの最終チェック
    AIが生成したコードをそのまま本番投入するのはリスクがあります。特にセキュリティやパフォーマンス面の確認は人間が行い、必要に応じて修正を加えることが大切です。
  • モデルの互換性
    今回の比較でも分かるように、3.5と3.7では生成スタイルに差があります。プロジェクトの途中でモデルを切り替える際は、既存のコードベースとの整合性に注意が必要です。

まとめ

本記事では、「Claude 3.7 Sonnet」とその周辺ツールを軸に、前バージョン3.5との比較を行いながら、物理学の問題解法例やReact・Tailwind CSSによる問い合わせフォームのコード例を紹介しました。3.5はシンプルかつ必要最低限の手順で結果を出すのに対し、3.7は深い思考プロセスやより実践的な機能を備え、ユーザー体験を向上させる追加要素も盛り込む傾向が強いといえます。

実務でAIを活用する場合、モデルの進化に合わせて新しい機能を積極的に取り入れるメリットは大きいですが、コスト管理や最終的な品質チェックなど、人間の関与が不可欠な領域もまだまだ存在します。モデル選択の際には、プロジェクトの目的や開発スケジュールに合わせて、どの程度の自動化を求めるのかを明確にし、3.5のような軽量版と3.7のような深い推論ができる版とをうまく使い分けると良いでしょう。

今後もAIの進化は続くと予想されますので、定期的に最新の情報をチェックして、皆さんに惜しみなくお届けしたいと思います!

Tags:

machiko

話題沸騰中の新サービス!生成AIプロンプト広場のご紹介

ChatGPTの登場により、効率化やイノベーションを促進するAIツールの需要はますます高まっています。

これまで、生成AIの活用方法について様々な研修やコンサルティングの実績がある筆者が、「より多くの人に、生成AIを活用する楽しみを覚えてほしい」という思いのもと、誰でも気軽にプロンプトのテンプレートを使えるサイト、「プロンプト広場」をスタートいたしました。

無料で気軽に使える、プロンプトテンプレート

プロンプト広場では、無料で様々な用途に応じたプロンプトテンプレートを使うことができます。利用したい製品やサービス、あなたの用途に合わせて細かくカスタマイズしたプロンプトを瞬時に作成することも可能です。また、お気に入りのプロンプトを保存して、いつでもコピーアンドペーストで使うことができます。ぜひこの機会に、試してみてください!

多彩なプロンプトのラインナップ

私たちプロンプト広場は、ChatGPTやMidjourneyなど最先端の生成AI技術を活用したプロンプトを取り揃え、
情報検索やマーケティング、業務の自動化など、さまざまなシーンで使えるプロンプトを提供しています。

こちらの記事もおすすめ

X