⚡ On-Device AI Powered by Gemini Nano

nano-judgement.js

Chrome 組み込みの Prompt API (window.ai) を使用し、文脈と選択肢から最も可能性・妥当性が高い選択肢をブラウザ内で安全・高速に判定します。

📥 nano-judgement.global.js をダウンロード <script>タグ用 📦 nano-judgement.js をダウンロード ESM版
📦 JavaScript ライブラリのダウンロード 無料 / 商用利用可

ご利用のプロジェクト構成(通常のHTML、または Vite / Next.js / webpack 等のモダンフロントエンド)に合わせて、以下の2種類のいずれかを直接ダウンロードして読み込んでください。

nano-judgement.global.js 一番おすすめ

ビルドツール不要。<script src="nano-judgement.global.js"></script> で読み込むだけで、属性ベースの自動判定や window.NanoJudgement が即座に使えるスタンドアロン版です。

<script src="./nano-judgement.global.js"></script>
⬇️ nano-judgement.global.js を保存
nano-judgement.js ES Modules (ESM)

モダンな JavaScript 開発用。import { judge } from './nano-judgement.js' で個別の判定関数や初期化メソッドを直接インポートして制御したい場合に最適です。

import { judge } from './nano-judgement.js';
⬇️ nano-judgement.js を保存
📷🎵
画像(レシート・領収書・障害画面)や 音声ファイル(通話録音・留守電 .mp3/.wav)の実装例をお探しですか?
ドラッグ&ドロップ、音声ファイルの直接アップロード、カメラ撮影のコピペコード例を掲載しています。
実装例を見る →
Chrome Prompt API 動作状況
確認中...

ブラウザの AI API を確認しています...

複数入力枠の自動即時判定 & キャッシュ
data-nano-judgement 📖 実装方法を見る

data-nano-judgement 属性を持つ入力枠に 5文字以上 入力されると、Language Detector API と Translator API で即座に英語へ事前翻訳・キャッシュされ、裏で自動的に判定が開始されます。
・2秒以内の再更新: 英語に都度翻訳し、先ほどの文章とは別キーで安全にキャッシュ。
・2秒経過後の更新: 最初の文章から 25%以上テキストが変化した場合、進行中の判定を即座に中断して最新の内容で再判定を開始します。

案件 1: コスト・納期の最適解判定 ⚡ 確率のみ (最速モード)
属性: data-nano-judgement (理由なし)
判定中、または結果がここに表示されます...
案件 2: セキュリティ・スケーラビリティ判定 💬 理由付き (Translator API翻訳)
属性: data-judge-reason="true"
判定中、または結果がここに表示されます...
案件 3: セレクトボックス連携 & 自動選択 🎯 selectbox 自動連動 (テキスト入力)
📖 実装方法を見る 属性: data-judge-select="#supportPriority"
判定中、または結果がここに表示されます...
案件 4: 音声ファイル(通話録音・留守電)直接判定 🎵 音声ファイル直接入力 (.wav / .mp3 / .m4a)
🎵 音声ファイル判定の実装例 属性: data-judge-select="#audioSupportPriority"
📁🎙️
手持ちの音声ファイルをここにドラッグ&ドロップ
またはボタンをクリックして音声ファイルを選択 (.mp3, .wav, .m4a, .webm, .ogg)
📖 音声ファイル判定の実装コードを見る →
音声ファイルをアップロードすると自動判定が開始され、セレクトボックスと連動します...
案件 5: ファイルそのもの(画像・テキスト)直接判定 🤖 Gemini Nano マルチモーダル直接入力
📷 画像判定の実装例を見る 属性: data-judge-select="#expenseCategory"
サンプル画像プリセット(すべて架空・ダミー): 📖 画像・音声判定の実装コードを見る →
画像プレビュー(※検証用ダミーデータ / クリックでファイル変更可能)
判定対象サンプル画像
※ サンプル画像内の社名・店名・金額等は全て検証用の架空(ダミー)です
画像から抽出されたテキスト (Context): テキスト抽出済み
抽出テキストをロード中...
判定中、または結果がここに表示されます...
インタラクティブ判定デモ (自由入力・調整)
📖 実装方法を見る
サンプルプリセット:
判定結果 (Judgement Result)
最も可能性・妥当性が高い選択肢
-

-

全選択肢の確信度と理由
📷🎵 画像 & 音声ファイル(直接アップロード)の判定 実装例 Gemini Nano マルチモーダル対応 音声ファイル (.wav/.mp3/.m4a) 直接対応
📖 基本ガイドへ ↑ トップへ戻る

NanoJudgement.judge() の第2引数(Context)には、テキスト文字列だけでなく 画像や音声の File / Blob オブジェクトをそのまま直接渡せます。
マイクでの録音作業を行わなくても、既存の音声ファイル(コールセンターの通話録音、留守番電話、ボイスメモなど)をそのままアップロードするだけで、オンデバイス判定が実行されます。

  • Gemini Nano 直接入力: Chrome のマルチモーダル Prompt API(expectedInputs: [{ type: "audio" }, { type: "image" }])有効環境では、画像・音声のバイナリそのものを直接 Gemini Nano に渡して推論します。
  • デフォルトは「値のみ高速返却」: 速度優先のためデフォルトでは根拠(理由)は出力せず、判定値(最有力候補・確信度)のみを高速に返却します。根拠が必要な場合のみ includeReason: true(または data-judge-reason="true")を指定してください。
  • ※ サンプルデータについて: デモや実装例内のレシート・領収証画像や社名・金額等は全て検証用の架空(ダミー)です。実在する企業・団体とは一切関係ありません。音声判定はご自身の手元の音声ファイルを直接アップロードして検証いただけます。
例1 📷 領収書・レシート画像のドラッグ&ドロップ & 勘定科目自動仕訳(コピペで動作)

ユーザーが領収書画像(PNG/JPEG/SVG)をドロップまたはファイル選択すると、画像を直接 Gemini Nano へ投入し、勘定科目セレクトボックス(旅費交通費・消耗品費・会議接待費等)を瞬時に自動選択する完全な実装例です。

<!-- 1. HTML: ドロップゾーン & 勘定科目セレクトボックス -->
<div id="dropZone" style="border:2px dashed #38bdf8; padding:2rem; text-align:center; border-radius:12px; cursor:pointer;">
  <p>📂 領収書・レシート画像をここにドラッグ&ドロップ、またはクリックして選択</p>
  <input type="file" id="receiptInput" accept="image/*" style="display:none;">
</div>

<select id="accountCategory" style="margin-top:1rem; padding:0.5rem; width:100%;">
  <option value="">-- AIが自動判定して選択します --</option>
  <option value="travel" data-description="電車・タクシー・新幹線・航空券等の移動交通費">旅費交通費</option>
  <option value="supplies" data-description="PC周辺機器・文房具・事務消耗品・コピー用紙">消耗品費</option>
  <option value="entertainment" data-description="取引先との会食・カフェでの商談打ち合わせ代">会議接待費</option>
  <option value="cloud" data-description="AWS/GCPサーバー利用料・SaaSサブスクリプション">通信開発費</option>
  <option value="other" data-description="上記いずれにも当てはまらないその他の経費">その他</option>
</select>

<div id="judgementResult"></div>

<!-- 2. JavaScript ロジック -->
<script type="module">
  import { NanoJudgement } from './nano-judgement.js';
  const judgement = new NanoJudgement();

  const dropZone = document.getElementById('dropZone');
  const fileInput = document.getElementById('receiptInput');
  const selectEl = document.getElementById('accountCategory');
  const resultDiv = document.getElementById('judgementResult');

  dropZone.addEventListener('click', () => fileInput.click());
  dropZone.addEventListener('dragover', (e) => { e.preventDefault(); dropZone.style.background = 'rgba(56,189,248,0.1)'; });
  dropZone.addEventListener('dragleave', () => { dropZone.style.background = 'transparent'; });
  dropZone.addEventListener('drop', (e) => {
    e.preventDefault();
    dropZone.style.background = 'transparent';
    if (e.dataTransfer.files?.length) handleImageFile(e.dataTransfer.files[0]);
  });
  fileInput.addEventListener('change', () => {
    if (fileInput.files?.length) handleImageFile(fileInput.files[0]);
  });

  async function handleImageFile(file) {
    resultDiv.innerHTML = '⏳ Gemini Nano が画像そのものを直接解析中...';
    try {
      // judge() の第2引数に File オブジェクトを直接投入!
      const result = await judgement.judge(selectEl, file, {
        target: resultDiv,    // 判定結果カードを自動描画
        includeReason: true   // 理由も合わせて取得
      });
      console.log('自動選択された科目:', selectEl.value);
      console.log('最有力候補:', result.topChoice.name);
    } catch (err) {
      resultDiv.innerHTML = '❌ エラー: ' + err.message;
    }
  }
</script>
例2 🎵 音声ファイル(通話録音・留守電 .mp3 / .wav / .m4a)の直接判定 & 自動選択(コピペで動作)

マイク録音の手間なし! コールセンターの通話録音ファイルや留守電の音声ファイル(.wav, .mp3, .m4a, .webm)を画面にドロップするだけで、音声を Gemini Nano が直接解析し、問い合わせ優先度(P1-緊急, P2-高, P3-中, P4-低, その他)を自動選択します。

<!-- 1. HTML: 音声ドロップゾーン & 優先度セレクトボックス -->
<div id="audioDropZone" style="border:2px dashed #e879f9; padding:2rem; text-align:center; border-radius:12px; cursor:pointer;">
  <p>🎵 通話録音・音声ファイル(.mp3 / .wav / .m4a)をここにドロップ、または選択</p>
  <input type="file" id="audioFileInput" accept="audio/*,.mp3,.wav,.m4a,.ogg,.webm" style="display:none;">
</div>

<select id="supportPriority" style="margin-top:1rem; padding:0.5rem; width:100%;">
  <option value="">-- 音声解析により自動選択されます --</option>
  <option value="P1" data-description="サービス全停止やデータ破壊の恐れがある致命的インシデント">P1 - 緊急(即時対応)</option>
  <option value="P2" data-description="主要機能が制限され広範囲に影響がある障害">P2 - 高(当日中対応)</option>
  <option value="P3" data-description="軽微な表示崩れや回避策がある通常レベルの不具合">P3 - 中(通常対応)</option>
  <option value="P4" data-description="機能追加の要望や操作方法に関する質問">P4 - 低(次回リリース検討)</option>
  <option value="OTHER" data-description="一般的な問い合わせ・その他">その他</option>
</select>

<div id="audioResult"></div>

<!-- 2. JavaScript ロジック -->
<script type="module">
  import { NanoJudgement } from './nano-judgement.js';
  const judgement = new NanoJudgement();

  const dropZone = document.getElementById('audioDropZone');
  const fileInput = document.getElementById('audioFileInput');
  const selectEl = document.getElementById('supportPriority');
  const resultDiv = document.getElementById('audioResult');

  dropZone.addEventListener('click', () => fileInput.click());
  dropZone.addEventListener('dragover', (e) => { e.preventDefault(); dropZone.style.background = 'rgba(232,121,249,0.1)'; });
  dropZone.addEventListener('dragleave', () => { dropZone.style.background = 'transparent'; });
  dropZone.addEventListener('drop', (e) => {
    e.preventDefault();
    dropZone.style.background = 'transparent';
    if (e.dataTransfer.files?.length) handleAudioFile(e.dataTransfer.files[0]);
  });
  fileInput.addEventListener('change', () => {
    if (fileInput.files?.length) handleAudioFile(fileInput.files[0]);
  });

  async function handleAudioFile(file) {
    resultDiv.innerHTML = '⏳ Gemini Nano が音声ファイル(' + file.name + ')を直接解析中...';
    try {
      // judge() の第2引数に音声 File オブジェクトを直接渡す!
      const result = await judgement.judge(selectEl, file, {
        target: resultDiv,
        includeReason: true   // 判断理由も出力
      });
      console.log('自動選択された優先度:', selectEl.value);
      console.log('確信度:', result.topChoice.confidence);
    } catch (err) {
      resultDiv.innerHTML = '❌ エラー: ' + err.message;
    }
  }
</script>
例3 🪄 HTML宣言的ノーコードマークアップ(音声ファイル選択 & 画像ファイル選択)

JavaScript コードを1行も書かずに、HTML属性を付与するだけでファイル選択(音声または画像)をセレクトボックスと自動連動させることができます。

<!-- 1. 音声ファイル(通話録音 .mp3 / .wav / .m4a)選択で即座にAI優先度判定 -->
<input type="file" accept="audio/*,.mp3,.wav,.m4a"
       data-nano-judgement
       data-judge-select="#supportPriority"
       data-judge-target="#audio-result">

<!-- 2. 画像ファイル選択で即座にAI仕訳 & セレクトボックス自動選択 -->
<input type="file" accept="image/*"
       data-nano-judgement
       data-judge-select="#expenseCategory"
       data-judge-target="#image-result">

<!-- 3. 領収書画像(クリックや差し替えで自動判定) -->
<img src="sample-receipt.png"
     data-nano-judgement
     data-judge-select="#expenseCategory"
     data-judge-target="#image-result">
例4 💻 JavaScript API による音声ファイル直接投入 & 問い合わせ自動仕訳

JavaScript の File オブジェクトや Blob オブジェクトを judgement.judge() に直接渡すだけで、問い合わせ種別や感情・対応要否を直接判定させることができます。

import { NanoJudgement } from './nano-judgement.js';
const judgement = new NanoJudgement();

const audioInput = document.querySelector('#audioFileInput');

audioInput.addEventListener('change', async () => {
  const audioFile = audioInput.files[0];
  if (!audioFile) return;

  const categories = [
    { id: 'billing', name: '請求・決済に関するクレーム', description: '過大請求、二重引き落とし、返金要求' },
    { id: 'technical', name: '技術的トラブル・障害', description: 'ログインできない、アプリがクラッシュする' },
    { id: 'inquiry', name: '一般的なサービス質問', description: '料金プラン、営業時間、契約変更の手順' },
    { id: 'other', name: 'その他・該当なし', description: '間違い電話や上記に該当しない要件' }
  ];

  // 音声ファイルを直接 judge() に投入
  const result = await judgement.judge(categories, audioFile, {
    includeReason: true
  });

  console.log('音声ファイル名:', audioFile.name);
  console.log('音声仕訳結果:', result.topChoice.name);
  console.log('根拠・理由:', result.summaryReason);
});
例5 📹 Webカメラ・スマホ撮影レシートの即時キャプチャ判定

ブラウザのカメラ(navigator.mediaDevices.getUserMedia)でレシートや障害画面を写し、「撮影」ボタンを押した瞬間に canvas.toBlob() で抽出したバイナリをオンデバイスで判定します。

// 1. カメラストリームの開始
const video = document.querySelector('#cameraVideo');
const stream = await navigator.mediaDevices.getUserMedia({
  video: { facingMode: 'environment', width: 1280, height: 720 }
});
video.srcObject = stream;

// 2. シャッターを押して Canvas 経由で Blob 取得 & 即時判定
document.querySelector('#captureBtn').addEventListener('click', () => {
  const canvas = document.createElement('canvas');
  canvas.width = video.videoWidth;
  canvas.height = video.videoHeight;
  const ctx = canvas.getContext('2d');
  ctx.drawImage(video, 0, 0);

  // Blob 形式で直接画像を取り出し、judge() に渡す
  canvas.toBlob(async (imageBlob) => {
    const result = await judgement.judge('#expenseSelect', imageBlob);
    console.log('撮影レシートの判定結果:', result.topChoice.name);
    console.log('確信度:', result.topChoice.confidence);
  }, 'image/jpeg', 0.9);
});
例6 🎯 根拠(理由)表示の制御

デフォルトは速度優先のため値のみ高速返却。根拠が欲しい場合のみパラメータを指定します。

// 【デフォルト】値のみ高速返却
const fast = await judgement.judge(choices, file);
console.log(fast.topChoice.name); // 値のみ
console.log(fast.summaryReason);  // undefined

// 【根拠付き】includeReason: true
const detail = await judgement.judge(choices, file, {
  includeReason: true
});
console.log(detail.summaryReason); // 翻訳済み根拠
例7 🔔 ライフサイクルイベント連携

音声ファイルや画像ファイルの解析開始時・完了時に発火するカスタムイベントでUIインジケータを連携できます。

const fileInput = document.querySelector('input[data-nano-judgement]');

// 解析・判定開始時
fileInput.addEventListener('nano-judgement-started', (e) => {
  console.log('解析開始:', e.detail.file?.name);
});

// 判定完了時
fileInput.addEventListener('nano-judgement-complete', (e) => {
  console.log('判定結果:', e.detail.result.topChoice.name);
});
📖 実装方法ガイド (Implementation Guide) ↑ トップへ戻る

nano-judgement.js は、HTML属性を追加するだけのノーコード宣言的アプローチから、JavaScript API による完全制御、カスタムイベント連携まで、プロジェクトの要件に合わせて柔軟に実装できます。

1 ライブラリの読み込み

HTMLの末尾(</body> 直前)またはヘッダーで nano-judgement.global.js を読み込みます。モジュールバンドラ不要でそのまま動作します。
📥 nano-judgement.global.js をダウンロード

<!-- 1. scriptタグで読み込むだけでグローバルに NanoJudgement が登録・自動初期化されます -->
<script src="./nano-judgement.global.js"></script>
2 入力枠に属性を付与(最もシンプルな例)

判定させたい <textarea> または <input> に data-nano-judgement 属性を付与します。5文字以上入力されると自動で裏側で判定・キャッシュが行われます。

<!-- ======================================================== -->
<!-- 判定対象の入力枠                                         -->
<!--   data-nano-judgement : 必須フラグ                       -->
<!--   data-judge-target   : 判定カードHTMLの出力先セレクタ    -->
<!-- ======================================================== -->
<textarea
  data-nano-judgement
  data-judge-target="#my-result"
  rows="3"
  placeholder="状況や要望を入力してください(5文字以上で自動判定)..."
>スタートアップ企業で予算はほぼゼロだが、来週のピッチまでに動くプロトタイプが必要</textarea>


<!-- ======================================================== -->
<!-- 判定結果(カードHTML)が自動描画される出力先コンテナ     -->
<!-- ======================================================== -->
<div id="my-result"></div>
3 セレクトボックスと自動連動させる(おすすめ!)

data-judge-select="#セレクトボックスID" を指定すると、セレクトボックスの <option> から選択肢を自動抽出し、AIが入力テキストに合わせて最適な選択肢を自動選択(Auto-select)します。data-description を付与しておくとAIの判定精度が格段に向上します。

<!-- ======================================================== -->
<!-- 1. 選択肢を持つセレクトボックス                          -->
<!--    data-description を記述すると判定精度が飛躍的に向上    -->
<!-- ======================================================== -->
<select id="taskPriority">

  <option value="" disabled selected>
    優先度を選択してください(AIが自動選択します)
  </option>

  <option
    value="urgent"
    data-description="サービス全停止やデータ消失など致命的な障害"
  >
    P1 - 緊急(即時対応)
  </option>

  <option
    value="normal"
    data-description="主要機能の一部制限など、当日中に対応すべき問題"
  >
    P2 - 通常(当日対応)
  </option>

  <option
    value="low"
    data-description="軽微な表示崩れや改善要望など次回以降の検討事項"
  >
    P3 - 低(次回検討)
  </option>

</select>


<!-- ======================================================== -->
<!-- 2. 入力枠とセレクトボックスを data-judge-select で紐付け -->
<!-- ======================================================== -->
<textarea
  data-nano-judgement
  data-judge-select="#taskPriority"
  data-judge-target="#priorityResult"
  rows="3"
  placeholder="問い合わせ内容を入力してください..."
>データベースがダウンし、ユーザー全員がログインできない状態です</textarea>


<!-- ======================================================== -->
<!-- 3. 判定結果のカード出力先(任意)                         -->
<!-- ======================================================== -->
<div id="priorityResult"></div>
4 判定理由を翻訳して出力する

data-judge-reason="true" を指定すると、判定の根拠・理由を生成し、Chrome 組み込みの Translator API で自動翻訳して日本語(または指定言語)で出力します。

<!-- ======================================================== -->
<!-- 判定理由の自動翻訳出力を有効化する例                     -->
<!-- ======================================================== -->
<textarea
  data-nano-judgement
  data-judge-reason="true"
  data-judge-target="#reasonResult"
  rows="3"
>来週の展示会までに動くモックアップを作りたいが、予算がほぼない</textarea>

<div id="reasonResult"></div>
5 コピペでそのまま動く最小完全テンプレート

HTMLファイルを作成し、以下のコードをそのまま貼り付けて Chrome で開くだけで、自動判定とセレクトボックス連動が動作します。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>Nano Judgement Demo</title>
</head>
<body>

  <!-- 1. セレクトボックス(選択肢を定義) -->
  <label>開発アプローチ:</label>
  <select id="mySelect">
    <option value="A" data-description="高品質だが納期1ヶ月以上">フルスクラッチ開発</option>
    <option value="B" data-description="即日利用可能でコスト最小">ノーコード/SaaS利用</option>
    <option value="OTHER" data-description="上記いずれにも該当しないその他">その他</option>
  </select>

  <br><br>

  <!-- 2. 自動判定入力枠(5文字以上入力でAI判定開始) -->
  <textarea
    data-nano-judgement
    data-judge-select="#mySelect"
    data-judge-target="#myResult"
    rows="3"
    style="width: 100%; max-width: 500px;"
  >予算はほぼゼロだが、来週までにプロトタイプを動かしたい</textarea>

  <!-- 3. 判定結果カード出力先 -->
  <div id="myResult"></div>

  <!-- 4. ライブラリ読み込み -->
  <script src="./nano-judgement.global.js"></script>

  <!-- 5. 【画面描画】イベントを受け取ってHTML側で結果を描画 -->
  <script>
    document.addEventListener('nano-judgement-complete', (e) => {
      const { result } = e.detail;
      const pct = Math.round(result.rankings[0].confidence * 100);
      document.getElementById('myResult').innerHTML = `
        <div style="margin-top:0.8rem; padding:0.8rem; background:rgba(56,189,248,0.1); border:1px solid #38bdf8; border-radius:8px;">
          <strong>AI判定結果:</strong> ${result.topChoice.name} (${pct}%)
        </div>
      `;
    });
    document.addEventListener('nano-judgement-cancelled', () => {
      document.getElementById('myResult').innerHTML = '';
    });
  </script>

</body>
</html>
1 NanoJudgement インスタンスの生成

ES Modules(import)またはグローバル(window.NanoJudgement)からインスタンスを作成します。
📦 nano-judgement.js (ESM) をダウンロード

import { NanoJudgement } from './nano-judgement.js';

const judgement = new NanoJudgement({
  enableCache: true,          // キャッシュを有効化 (デフォルト: true)
  cacheStorage: 'session',    // 'session' (sessionStorage) または 'local' (localStorage)
  maxCacheGenerations: 1000,  // 最大1000世代のLRU保存 (古い順に自動破棄)
  includeReason: false,       // true にすると理由も出力 (Language Detector API で判定 & Translator API で翻訳)
  autoScan: false,            // JS側で手動制御する場合は false に設定可能
});
2 選択肢と文脈を渡して判定を実行 (judge メソッド)

judgement.judge(choices, context, options) を呼び出します。選択肢には配列、または <select> 要素をそのまま渡せます。

// 選択肢の配列、または <select> 要素を指定可能
const choices = [
  { id: "A", name: "フルスクラッチ開発", description: "自由度が高いが納期1ヶ月以上" },
  { id: "B", name: "SaaS/ノーコード", description: "即日利用可能で安価だがカスタマイズに制約" },
  { id: "C", name: "外注特急依頼", description: "短納期だが費用が高額" }
];

const context = "予算はほぼゼロだが、来週までにプロトタイプを動かしたい";

// 判定実行 (Promise)
const result = await judgement.judge(choices, context, {
  includeReason: true,        // 理由を出力(Language Detector API で入力言語を判定し Translator API で自動翻訳)
});

console.log("最有力候補:", result.topChoice.name);  // "SaaS/ノーコード"
console.log("判定理由:", result.summaryReason);
console.log("キャッシュから復元:", result.fromCache); // true / false
console.log("全ランキング:", result.rankings);
3 特定の入力要素にライブ自動判定をアタッチ

attachLiveJudgement(element, choices, options) により、任意の入力枠に 2秒ルール&25%変更チェック&0文字即時停止の監視をプログラマブルに設定できます。

const textarea = document.querySelector('#customInput');
const selectEl = document.querySelector('#customSelect');

judgement.attachLiveJudgement(textarea, selectEl, {
  selectElement: selectEl,
  targetSelector: '#customResult'
});
4 先行判定 (Pre-judgement) でボタン押下時の待ち時間をゼロ化

judgement.preJudge(choices, context, options) をユーザーの入力中に呼んでおくと、裏側でバックグラウンド判定を開始します。
ボタン押下時に judgement.judge(...) を呼ぶと、先行判定が完了していれば待ち時間ゼロ(0ms)で即座に結果を取得でき、まだ判定中であれば二重実行せず進行中の判定完了を待機して即座に画面へ反映できます。

// ユーザーが入力枠にタイピングした時点で先行判定をキック(裏側で非同期実行)
textarea.addEventListener('input', () => {
  if (textarea.value.trim().length >= 5) {
    judgement.preJudge(choices, textarea.value);
  }
});

// 送信・判定ボタンが押されたとき
submitBtn.addEventListener('click', async () => {
  // 先行判定が完了していれば 0ms で即座に返却!
  // 先行判定中なら、二重実行せずその完了を待って即座に返却!
  const result = await judgement.judge(choices, textarea.value);
  showResult(result);
});
📷🎵 画像・音声ファイルの完全実装ガイド(例1〜例7) は独立カードでもご覧いただけます。
独立セクションで見る →
1 🤖 📷🎵 ファイルそのもの(画像/音声/テキスト)を直接渡して判定する実装方法

judgement.judge() の第2引数(Context)には、テキスト文字列だけでなく File や Blob オブジェクトをそのまま直接渡せます。
Chrome のマルチモーダル Prompt API 有効環境では、画像・音声の Blob / File そのものを Gemini Nano に直接入力して推論が行われます。テキストファイル(.txt, .json, .csv)の場合は内容が自動ロードされ、非対応環境でも安全にフォールバックします。

import { NanoJudgement } from './nano-judgement.js';
const judgement = new NanoJudgement();

// A. 画像ファイル(File オブジェクト)そのものを直接渡す
const fileInput = document.querySelector('#myFileInput');
const imageFile = fileInput.files[0]; // 例: 領収書.png, 障害画面.jpg
const result = await judgement.judge(choices, imageFile);
console.log("画像判定結果:", result.topChoice.name);

// B. 音声ファイル(File オブジェクト: .mp3, .wav, .m4a)そのものを直接渡す
const audioFileInput = document.querySelector('#myAudioInput');
const audioFile = audioFileInput.files[0]; // 例: call_recording.wav, voicemail.mp3
const audioResult = await judgement.judge('#supportPriority', audioFile);
console.log("音声仕訳結果:", audioResult.topChoice.name);

// C. テキストファイル(.txt, .json, .csv)そのものを直接渡す
const textFile = logFileInput.files[0]; // 例: server_error.log
const logResult = await judgement.judge('#priority', textFile);
2 🎵 音声ファイル(通話録音・留守電)直接判定の実装方法

マイクでの録音作業を行わなくても、既存の音声ファイル(.mp3, .wav, .m4a)をユーザーが選択またはドロップするだけで、オンデバイス判定が即座に実行されます。

const audioInput = document.querySelector('#audioInput');

audioInput.addEventListener('change', async () => {
  const audioFile = audioInput.files[0];
  if (!audioFile) return;

  // judge: 音声ファイルを直接渡してAI優先度判定 & セレクトボックス自動連動
  const result = await judgement.judge('#supportPriority', audioFile, {
    includeReason: true // 理由も生成
  });

  console.log("ファイル名:", audioFile.name);
  console.log("AI判定結果:", result.topChoice.name);
  console.log("確信度スコア:", result.topChoice.confidence);
  console.log("判断理由:", result.summaryReason);
});
3 🪄 HTML宣言的ノーコードマークアップ(音声ファイル・画像ファイル連動)

JavaScript コードを1行も書かずに、HTML属性を付与するだけでファイル選択(音声または画像)をセレクトボックスと自動連動させることができます。

<!-- 1. 音声ファイル(通話録音 .wav/.mp3)選択で即座にAI優先度判定 & 連動 -->
<input type="file" accept="audio/*,.mp3,.wav,.m4a"
       data-nano-judgement
       data-judge-select="#supportPriority"
       data-judge-target="#audio-result">

<!-- 2. 画像ファイル選択で即座にAI仕訳&セレクトボックス自動選択 -->
<input type="file" accept="image/*"
       data-nano-judgement
       data-judge-select="#expenseCategory"
       data-judge-target="#result-card">

<!-- 3. 領収書画像(クリックや差し替えで自動判定) -->
<img src="sample-receipt.png"
     data-nano-judgement
     data-judge-select="#expenseCategory"
     data-judge-target="#result-card">
4 🎯 根拠(判断理由)の表示制御パラメータ(デフォルト: 値のみ高速返却)

画像や音声からの判定でも、デフォルト(パラメータ省略時)は速度優先のため根拠は生成・表示せず、値(最有力候補・確信度スコア)のみを高速に返却します。根拠を確認したい場合のみ、パラメータを明示的に指定します。

// 【デフォルト】速度優先: 値のみ高速返却(根拠なし・理由翻訳スキップ)
const fastResult = await judgement.judge(choices, fileOrSpeech);
console.log(fastResult.topChoice.name);  // "インフラ・サーバー開発費"(値のみ)
console.log(fastResult.summaryReason);   // undefined(生成スキップ)

// 【根拠を求める場合】includeReason: true を渡す(Language Detector API で入力言語を判定 & Translator API で自動翻訳)
const detailedResult = await judgement.judge(choices, fileOrSpeech, {
  includeReason: true,
});
console.log(detailedResult.topChoice.name);  // "インフラ・サーバー開発費"
console.log(detailedResult.summaryReason);   // "領収書にAWSクラウド利用料が記載されているため"(根拠)

// HTML属性で根拠を求める場合は data-judge-reason="true" を付与
<button data-nano-judgement-speech 
        data-judge-select="#supportPriority"
        data-judge-reason="true">
  🎙️ 理由付きで音声判定
</button>
5 🔔 画像・音声ライフサイクルイベントによるUIフィードバック

マイク録音中や画像解析中、判定完了時にカスタムイベントが発火するため、アニメーションやトースト表示などのUIフィードバックを簡単に実装できます。

const speechBtn = document.querySelector('[data-nano-judgement-speech]');

// 音声認識が開始された(マイク待機中)
speechBtn.addEventListener('nano-judgement-speech-start', () => {
  speechBtn.classList.add('recording-pulse');
  speechBtn.textContent = '🎙️ お話しください...';
});

// 判定完了時
speechBtn.addEventListener('nano-judgement-complete', (e) => {
  speechBtn.classList.remove('recording-pulse');
  speechBtn.textContent = '🎙️ 音声で話して判定';
  const { result, isSpeech, speechTranscript } = e.detail;
  if (isSpeech) {
    console.log('発話内容:', speechTranscript);
  }
});

// 音声認識エラー時(マイク不許可やタイムアウト等)
speechBtn.addEventListener('nano-judgement-speech-error', (e) => {
  speechBtn.classList.remove('recording-pulse');
  speechBtn.textContent = '🎙️ 音声で話して判定';
  alert('音声認識エラー: ' + e.detail.error.message);
});
例1 📷 領収書・レシート画像のドラッグ&ドロップ自動仕訳フォーム(コピペで動作)

ユーザーがレシート画像(PNG/JPEG/SVG)を画面上にドロップまたは選択すると、自動で Gemini Nano へ画像を直接渡し、勘定科目セレクトボックス(旅費交通費・消耗品費・会議接待費等)を瞬時に自動選択する完全な実装例です。

<!-- 1. HTML構造: ドロップゾーン & 勘定科目セレクトボックス -->
<div id="dropZone" style="border:2px dashed #38bdf8; padding:2rem; text-align:center; border-radius:12px; cursor:pointer;">
  <p>📂 領収書・レシート画像をここにドラッグ&ドロップ、またはクリックして選択</p>
  <input type="file" id="receiptInput" accept="image/*" style="display:none;">
</div>

<select id="accountCategory" style="margin-top:1rem; padding:0.5rem; width:100%;">
  <option value="">-- AIが自動判定して選択します --</option>
  <option value="travel" data-description="電車・タクシー・新幹線・航空券等の移動交通費">旅費交通費</option>
  <option value="supplies" data-description="PC周辺機器・文房具・事務消耗品・コピー用紙">消耗品費</option>
  <option value="entertainment" data-description="取引先との会食・カフェでの商談打ち合わせ代">会議接待費</option>
  <option value="cloud" data-description="AWS/GCPサーバー利用料・SaaSサブスクリプション">通信開発費</option>
  <option value="other" data-description="上記いずれにも当てはまらないその他の経費">その他</option>
</select>

<div id="judgementResult"></div>

<!-- 2. JavaScript ロジック -->
<script type="module">
  import { NanoJudgement } from './nano-judgement.js';
  const judgement = new NanoJudgement();

  const dropZone = document.getElementById('dropZone');
  const fileInput = document.getElementById('receiptInput');
  const selectEl = document.getElementById('accountCategory');
  const resultDiv = document.getElementById('judgementResult');

  dropZone.addEventListener('click', () => fileInput.click());
  dropZone.addEventListener('dragover', (e) => { e.preventDefault(); dropZone.style.background = 'rgba(56,189,248,0.1)'; });
  dropZone.addEventListener('dragleave', () => { dropZone.style.background = 'transparent'; });
  dropZone.addEventListener('drop', (e) => {
    e.preventDefault();
    dropZone.style.background = 'transparent';
    if (e.dataTransfer.files?.length) handleImageFile(e.dataTransfer.files[0]);
  });
  fileInput.addEventListener('change', () => {
    if (fileInput.files?.length) handleImageFile(fileInput.files[0]);
  });

  async function handleImageFile(file) {
    resultDiv.innerHTML = '⏳ Gemini Nano が画像そのものを直接解析中...';
    try {
      // judge() の第2引数に File オブジェクトを直接投入!
      const result = await judgement.judge(selectEl, file, {
        target: resultDiv,    // 判定結果カードを自動描画
        includeReason: true   // 理由も合わせて表示
      });
      console.log('自動選択された科目:', selectEl.value);
    } catch (err) {
      resultDiv.innerHTML = '❌ エラー: ' + err.message;
    }
  }
</script>
例2 📹 Webカメラ・スマホ撮影レシートの即時キャプチャ判定

ブラウザのカメラ(navigator.mediaDevices.getUserMedia)でレシートを写し、「撮影」ボタンを押した瞬間に canvas.toBlob() でバイナリを抽出し、そのままオンデバイスで判定する実装例です。

// 1. カメラストリームの開始
const video = document.querySelector('#cameraVideo');
const stream = await navigator.mediaDevices.getUserMedia({
  video: { facingMode: 'environment', width: 1280, height: 720 }
});
video.srcObject = stream;

// 2. シャッターを押して Canvas 経由で Blob 取得 & 即時判定
document.querySelector('#captureBtn').addEventListener('click', () => {
  const canvas = document.createElement('canvas');
  canvas.width = video.videoWidth;
  canvas.height = video.videoHeight;
  const ctx = canvas.getContext('2d');
  ctx.drawImage(video, 0, 0);

  // Blob 形式で直接画像を取り出し、judge() に渡す
  canvas.toBlob(async (imageBlob) => {
    const result = await judgement.judge('#expenseSelect', imageBlob);
    console.log('撮影レシートの判定結果:', result.topChoice.name);
    console.log('確信度:', result.topChoice.confidence);
  }, 'image/jpeg', 0.9);
});
例3 🎙️ マイク音声での問い合わせ優先度・感情の自動仕訳

ユーザーが「ログイン画面でエラー500が出て決済できない」と声に出して話すと、Chrome の Web Speech API がオンデバイスで即座に文字起こしし、Prompt API が緊急度(P0-緊急, P1-高, P2-中, P3-低, その他)をミリ秒単位で自動選択します。

<!-- 1. ボタンをクリックするだけでマイク起動 & 自動判定(ノーコード版) -->
<button type="button"
        data-nano-judgement-speech
        data-judge-select="#ticketPriority"
        data-judge-target="#voiceResult"
        data-judge-reason="true">
  🎙️ 声で話して優先度を判定
</button>

<select id="ticketPriority">
  <option value="p0" data-description="本番システム停止、決済不能、全ユーザー影響">P0-最優先緊急</option>
  <option value="p1" data-description="主要機能の不具合だが回避策が存在する">P1-重要度高</option>
  <option value="p2" data-description="軽微な表示崩れや一般的な問い合わせ">P2-通常対応</option>
  <option value="other" data-description="上記に該当しないその他・要望">その他</option>
</select>

<!-- 2. JavaScript でマイク音声認識とAI判定を完全に制御する場合 -->
<script type="module">
  import { NanoJudgement } from './nano-judgement.js';
  const judgement = new NanoJudgement();

  const micBtn = document.querySelector('#customMicBtn');
  micBtn.addEventListener('click', async () => {
    micBtn.textContent = '🎙️ 音声を聞き取り中...';
    try {
      const result = await judgement.judgeFromSpeech('#ticketPriority', {
        speechLang: 'ja-JP',     // 日本語認識
        speechTimeoutMs: 8000,   // 8秒無音でタイムアウト
        includeReason: true      // 理由も生成
      });

      console.log('マイクが認識した日本語テキスト:', result.speechTranscript);
      console.log('Gemini Nano が判定した選択肢:', result.topChoice.name);
      console.log('確信度スコア:', result.topChoice.confidence);
      console.log('判断理由 (日本語自動翻訳済):', result.summaryReason);
    } catch (err) {
      console.warn('音声認識エラー:', err.message);
    } finally {
      micBtn.textContent = '🎙️ 声で話して優先度を判定';
    }
  });
</script>
例4 🎵 音声ファイル(.mp3, .wav, .m4a 録音データ)の直接投入判定

コールセンターの通話録音ファイルや、会議のボイスメモ音声ファイルをそのまま File オブジェクトとして渡し、問い合わせ種別や感情・対応要否を直接判定させることができます。

// 1. 音声ファイル選択イベント
const audioInput = document.querySelector('#audioFileInput'); // <input type="file" accept="audio/*">

audioInput.addEventListener('change', async () => {
  const audioFile = audioInput.files[0];
  if (!audioFile) return;

  // 判定候補の定義(問い合わせ種別)
  const categories = [
    { id: 'billing', name: '請求・決済に関するクレーム', description: '過大請求、二重引き落とし、返金要求' },
    { id: 'technical', name: '技術的トラブル・障害', description: 'ログインできない、アプリがクラッシュする' },
    { id: 'inquiry', name: '一般的なサービス質問', description: '料金プラン、営業時間、契約変更の手順' },
    { id: 'other', name: 'その他・該当なし', description: '間違い電話や上記に該当しない要件' }
  ];

  // 音声ファイルを直接 judge() に投入
  const result = await judgement.judge(categories, audioFile, {
    includeReason: true
  });

  console.log('音声ファイル名:', audioFile.name);
  console.log('音声仕訳結果:', result.topChoice.name);
  console.log('根拠・理由:', result.summaryReason);
});
🔔 発火されるカスタムイベント一覧

自動判定対象の要素は、判定の完了や中断などのライフサイクルに合わせて標準カスタムイベント(CustomEvent)を発火します。

const textarea = document.querySelector('textarea[data-nano-judgement]');

// 1. 判定が完了したとき (nano-judgement-complete)
textarea.addEventListener('nano-judgement-complete', (e) => {
  const { result, fromCache, selectElement } = e.detail;
  console.log('判定完了:', result.topChoice.name);
  console.log('キャッシュ利用:', fromCache);

  // トースト通知を出したり、フォームの別フィールドを連動更新可能
});

// 2. 入力枠が0文字になった、または中断されたとき (nano-judgement-cancelled)
textarea.addEventListener('nano-judgement-cancelled', (e) => {
  const { reason } = e.detail;
  if (reason === 'empty_input') {
    console.log('入力が空(0文字)になったため判定が即時破棄・リセットされました');
  }
});
⚡ 判定制御とキャッシュの4大アーキテクチャ

クライアントPCのCPU/GPU負荷とトークン消費を最小化するため、以下のインテリジェント制御を内包しています。

  • 1. 入力枠が0文字になった際の即時停止(Abort & Destroy):
    スペースや改行を除去した結果が 0文字になった瞬間、進行中の待機タイマーを解除し、AbortController で判定を中断。さらに session.destroy() でネイティブAIセッションを即座に破棄して結果表示もクリアします。
  • 2. スペース・句読点正規化キャッシュ(Normalized Cache):
    キャッシュ保存および照合時に半角・全角スペースや「、」「。」「!」等の句読点を除去して正規化。誤字修正や句読点の追記による不要な再判定を防ぎます。
  • 3. 前方一致推論(Prefix Heuristic Cache):
    10文字以上の文章で、末尾の 5文字以内の微修正であれば、直前のキャッシュ結果を即座に類推活用して 0ms で判定結果を表示します。
  • 4. 1000世代のLRUキャッシュ(Least Recently Used):
    キャッシュは最大 1,000 世代まで保存。上限を超えた古いキャッシュは自動的に破棄され、ストレージ容量圧迫を防ぎます。
  • 5. 2秒ルール&25%変化チェック:
    文字入力後2秒以内の編集は別キーで都度安全にキャッシュ。2秒経過後は、元の文章から 25% 以上変更された場合のみ進行中の判定を中断して最新テキストで再実行します。
  • 6. 前方一致後のバックグラウンド再検証 (Stale-While-Revalidate):
    前方一致で即座に応答(0ms)した後、タイピング停止(デバウンス800ms)を検知すると裏側で最新文章に対する本判定を自動実行してキャッシュを最新化。最有力候補の変化・ランキング順序の変化・いずれかのスコアが20%以上変動した場合のみ画面を自動更新し、チラつきを防ぎつつ高い判定精度を維持します。
  • 7. 8文字以上入力時の1〜3文字縮小による前方一致&一時回答:
    入力文字列が8文字以上で通常の前方一致に一致するキャッシュがなかった場合、末尾を1文字、2文字、3文字減らして前方一致キャッシュを探索。見つかった場合は一時回答として即時表示(0ms)した上で、ユーザーのタイピング停止を待って裏側で最新の全文に対する本判定を実行・反映します。
1 JavaScriptが出力する判定結果データ(JudgementResult 構造)

判定が完了すると、ライブラリは以下の構造化された JavaScript オブジェクト(Promise<JudgementResult>)を出力します。すべての選択肢の確信度・理由・キャッシュ状況が綺麗に整理されています。

// 判定完了時に JavaScript が出力するオブジェクトの具体例
{
  "topChoice": {
    "id": "B",
    "name": "ノーコード/SaaSの利用",
    "description": "即日利用可能で安価だが、細かいカスタマイズに制約がある"
  },
  "rankings": [
    {
      "id": "B",
      "name": "ノーコード/SaaSの利用",
      "confidence": 0.82,    // 確信度 (0.00 〜 1.00、降順で自動ソート)
      "reason": "予算がほぼゼロかつ1週間以内のプロトタイプ作成には即日導入可能なSaaSが最も適合します。"
    },
    {
      "id": "A",
      "name": "フルスクラッチ開発",
      "confidence": 0.12,
      "reason": "開発期間が1ヶ月以上かかるため来週のピッチ期日に間に合いません。"
    },
    {
      "id": "C",
      "name": "外注専門ベンダーへ特急依頼",
      "confidence": 0.06,
      "reason": "予算ゼロの条件と相容れません。"
    }
  ],
  "summaryReason": "来週の投資家ピッチという短納期と予算ゼロの制約に基づき、SaaS/ノーコードツールの活用が最も現実的で高い適合率を示しています。",
  "fromCache": false,            // キャッシュから復元されたか (true / false)
  "inferredFromCache": false,    // 前方一致推論キャッシュか (true / false)
  "context": "スタートアップ企業で予算はほぼゼロだが来週の投資家向けピッチまでに実働するプロトタイプが必要", // スペース・句読点除去後
  "rawContext": "スタートアップ企業で予算はほぼゼロだが、来週の投資家向けピッチまでに実働するプロトタイプが必要。"
}
2 画面描画の切り離しと責務分離(SoC)の仕組み

nano-judgement.js は画面への直接的な HTML 描画を行いません(画面描画は HTML / UI 層の責任)。
ライブラリは AI 判定・翻訳・キャッシュ・ライフサイクル管理に特化し、以下の 3 つのイベントおよび属性連携を通じて HTML 側に状態を通知します。

A. 連動セレクトボックス(<select>)の自動選択(Auto-select)

data-judge-select="#セレクトボックス" が指定されている場合、最有力候補 result.topChoice.id と一致する <option value="..."> を自動選択(selectEl.value = result.topChoice.id)します。
さらに selectEl.dispatchEvent(new Event('change', { bubbles: true })) を発火させるため、既存のフォーム処理や他の連動スクリプトも自動的に動作します。

B. 判定ライフサイクルイベントの発火(HTML側で自由に描画)

判定の進行状態に合わせて、入力要素からカスタムイベントがバブリング(bubbles: true)で発火されます:
・nano-judgement-start: 判定開始時。HTML 側でローディングスピナーやプレースホルダーを表示します。
・nano-judgement-complete: 判定完了時。event.detail.result に判定結果(最有力候補、確信度、理由等)が渡されます。HTML 側で任意のカードやグラフを描画します。
・nano-judgement-cancelled: 入力枠が0文字になった、または中断された時。HTML 側で表示領域をクリアします。

C. ライフサイクル属性(data-judge-status)の自動更新

入力枠の DOM 属性がリアルタイムに変化するため、CSS セレクタでスピナーやローディング枠線を簡単に実装できます:
・data-judge-status="idle": 待機中(未入力、または0文字リセット後)
・data-judge-status="judging": Gemini Nano が判定中(裏側で実行中)
・data-judge-status="completed": 判定完了
・data-judge-cached="true": キャッシュから即座に結果を復元した際に付与

D. 0文字クリア時の即時中断と通知

ユーザーが入力テキストを全消去(スペース除去後 0文字)にした瞬間、実行中の判定を即時 abort し、セッションを破棄して nano-judgement-cancelled(reason: 'empty_input')を発火します。古い判定結果が遅れて画面に残る心配はありません。

3 HTML側でイベントを受け取って画面に描画する実装例

nano-judgement.js から送られるカスタムイベントを HTML 側で購読し、結果表示領域(#myResult)に結果カードやスピナーを描画する実装コードです。

// 1. 判定開始時: HTML側でローディングスピナーを表示
document.addEventListener('nano-judgement-start', (event) => {
  const target = event.detail.element.getAttribute('data-judge-target');
  if (target) {
    document.querySelector(target).innerHTML = '<div class="spinner">判定中...</div>';
  }
});

// 2. 判定完了時: HTML側で結果カードやグラフを描画
document.addEventListener('nano-judgement-complete', (event) => {
  const { result, fromCache, element } = event.detail;
  const target = element.getAttribute('data-judge-target');
  if (!target) return;

  const topPct = Math.round(result.rankings[0].confidence * 100);
  const container = document.querySelector(target);
  container.innerHTML = `
    <div class="result-card">
      <div>最有力: <strong>${result.topChoice.name}</strong> (${topPct}%)</div>
      <div>理由: ${result.summaryReason || '(理由なし)'}</div>
    </div>
  `;
});

// 3. 0文字リセット時: HTML側で描画エリアをクリア
document.addEventListener('nano-judgement-cancelled', (event) => {
  const target = event.detail.element.getAttribute('data-judge-target');
  if (target) {
    document.querySelector(target).innerHTML = '';
  }
});
⚙️ 属性・オプション一覧 (Reference) ↑ トップへ戻る

HTML属性による宣言的指定と、JavaScript API 初期化時に渡せるオプションの一覧です。

HTML属性リファレンス
属性名 対象要素 デフォルト 説明 記述例
data-nano-judgement <textarea>
<input>
- 自動判定対象であることを宣言する必須属性。5文字以上の入力で自動判定が発火します。 data-nano-judgement
data-judge-select 判定対象要素 - 連動する <select> のセレクタ。選択肢を自動抽出し、判定結果に合わせて自動選択します。 data-judge-select="#priority"
data-judge-auto-select 判定対象要素 true セレクトボックス連動時、最有力候補を自動選択するかどうか。"false" で自動選択のみOFFにできます。 data-judge-auto-select="false"
data-judge-target 判定対象要素 - HTML側スクリプトが描画先コンテナを特定するためのセレクタ。イベント受取時に event.detail.element.getAttribute('data-judge-target') で参照できます。 data-judge-target="#resultBox"
data-judge-reason 判定対象要素 false "true" にすると判定理由を出力し、Translator API で日本語化。"false" で確率のみ最速出力。 data-judge-reason="true"
data-judge-lang 判定対象要素 自動判定 判定理由の翻訳先言語コード(例: 'ja', 'en')。省略時はコンテキストから自動検出。 data-judge-lang="ja"
data-judge-choices 判定対象要素 デフォルト選択肢 要素固有の選択肢JSON文字列、または選択肢を含む要素のセレクタ。 data-judge-choices='[{"id":"1","name":"A"}]'
JavaScript 初期化オプション (new NanoJudgement)
オプション名 型 デフォルト値 説明
defaultChoices Array [] 全体で共通使用するデフォルトの選択肢リスト [{ id, name, description }]。
enableCache boolean true 判定結果および翻訳結果のキャッシュを有効にするか。
cacheStorage string 'session' キャッシュの保存先。'session' (sessionStorage) または 'local' (localStorage)。
maxCacheGenerations number 1000 キャッシュする最大世代数(LRU方式)。1000世代を超えると古い順に自動破棄されます。
autoScan boolean true インスタンス作成時に data-nano-judgement 属性を持つ要素を自動スキャンして監視を開始するか。
includeReason boolean false 判定理由(根拠)を生成・翻訳して返すか。true の場合、入力テキストを Language Detector API で言語判定し、Translator API で自動翻訳して戻します(省略時・false は最速で値のみ返却)。
🛠️ Chrome での事前準備 (Prompt API 利用ガイド) ↑ トップへ戻る

本ライブラリは Chrome 組み込みの Gemini Nano (Prompt API) を使用します。Prompt API は通常の Google Chrome に標準統合されているため、最新版の Chrome をご利用であれば特別なフラグ設定を行わずにそのまま利用可能です。

1 最新バージョンの Google Chrome を使用

Google Chrome が最新版に更新されていることを確認します(Chrome メニュー「ヘルプ」→「Google Chrome について」)。通常の最新ブラウザ環境であれば、事前のフラグ変更は一切不要です。

2 Gemini Nano モデルのダウンロード(初回自動処理)

初回利用時、ブラウザがオンデバイスモデル(Gemini Nano / 容量約1〜2GB)を自動ダウンロードします。ディスクに十分な空き容量があることを確認してください。

事前に手動でダウンロードを完了させたい場合は、コンポーネント管理画面を開いて Optimization Guide On Device Model の「アップデートを確認」をクリックしてください:
chrome://components
※ なぜリンクで直接開かないのか?: Web サイトから悪意あるスクリプトがブラウザ内部設定を勝手に開いたり改ざんしたりするのを防ぐため、Chrome のセキュリティ仕様により Web ページ上のリンクから chrome:// への直接遷移は一律ブロックされています。URLをコピーし、新規タブ(Cmd+T / Ctrl+T)のアドレスバーに貼り付けて開いてください。
3 (補足)動作しない場合・先行機能(マルチモーダル直接渡し等)

一部の環境や企業の制限ポリシーにより利用できない場合、あるいは画像・音声ファイルを直接渡すマルチモーダル先行入力を利用したい場合のみ、以下のフラグを新規タブのアドレスバーに貼り付けて設定してください:

chrome://flags/#prompt-api-for-gemini-nano → Enabled
chrome://flags/#prompt-api-for-gemini-nano-multimodal-input → Enabled (画像・音声直接渡し)
chrome://flags/#optimization-guide-on-device-model → Enabled BypassPerfRequirement
chrome://flags/#translation-api → Enabled (理由の多言語自動翻訳)