Chrome Summarizer API

ブラウザ内蔵の要約機能


概要

- `Summarizer API` を使うことで、ブラウザ内蔵の要約機能を使うことが可能 - ChromeのビルトインGemini nanoを使って要約 - 2025/07/02現在、PC版のChrome 138 以降でのみ利用可能

デモ

長文を貼り付けて「要約」ボタンを押してください。 対応 OS/ハード要件は公式ドキュメントを参照してください。

結果

type値

| タイプ名 | 何をしてくれる? | 典型的な長さ※ | 生成される形 | 想定ユースケース | |----------|------------------|----------------|--------------|------------------| | `key-points` | 元文の重要ポイントを箇条書きで抽出。読み手が「結論だけざっと把握」できるようにする。 | `short` = 3項目
`medium` = 5項目
`long` = 7項目 | ・`bullet list`(Markdown)
・`plain text`リスト | ⭐ 報告書 / 論文の要点整理
⭐ 会議メモの即時共有 | | `tldr` | "要はこういうこと"を文で凝縮。忙しい人向けの最速サマリ。 | 1 / 3 / 5 文 | 段落(文章) | ⭐ 長いブログの冒頭に「TL;DR」
⭐ チャットの議事録要約 | | `teaser` | 面白い / 興味をそそる部分にフォーカスし、続きを読みたくさせる。宣伝文句寄り。 | 1 / 3 / 5 文 | キャッチーな導入文 | ⭐ 記事・動画の紹介文
⭐ EC商品の説明文冒頭 | | `headline` | 記事タイトル風の一文で本質を伝達。単語数制限付きで、より「見出し」らしいリズム。 | 12 / 17 / 22 語 | 一文(終止符なしが多い) | ⭐ CMSで自動見出し生成
⭐ SNSカード用タイトル | ### ポイント - まず「目的」を考える - 速攻理解 ⇒ `tldr` - 覚えておくべき要点を並べたい ⇒ `key-points` - 興味を引いて本文へ誘導 ⇒ `teaser` - 見出しだけ自動生成 ⇒ `headline` - 出力フォーマットが固定 - `key-points` は常に箇条書き、`headline` は必ず一文など - 後処理のパースが楽になる - 長さは `length` で微調整 - 文章タイプは「文数」、箇条書きは「箇条数」、`headline` は「語数」が伸びるイメージ

ポイント

- 機能検出 - `'Summarizer' in self` で API 対応を確認 - モデル状態の確認 - `Summarizer.availability()` は `unavailable` / `downloadable` / `downloading` / `available` の 4 段階で返す - モデルのダウンロード進捗 - `Summarizer.create({monitor(...)})` で `downloadprogress` イベントを購読し、UIに反映 - 要約の実行方法 - バッチ処理: `summarize()` - ストリーミング: `summarizeStreaming()` (`for-await` で逐次更新) - パラメータ - `type`, `length`, `format`, `sharedContext` は 生成時に固定 なので、オプションを変えたい場合は新しい `Summarizer.create()` を呼ぶ

コード

JavaScript

(async () => {
  /* --- 1. Summarizer API 対応検出 --- */
  if (!('Summarizer' in self)) {           // :contentReference[oaicite:0]{index=0}
    document.getElementById('nosupport').classList.remove('hidden');
    return;
  }

  const downloadPane = document.getElementById('download');
  const progress     = document.getElementById('progress');

  /**
   * Summarizer オブジェクトを生成
   * 
   * @param {Object} opts - オプション
   * @param {string} opts.type - 要約タイプ(`key-points`, `tldr`, `teaser`, `headline`)
   * @param {string} opts.length - 要約の長さ(`short`, `medium`, `long`)
   * @returns {Promise} - Summarizer オブジェクト
   */
  async function createSummarizer(opts) {
    // availability() で状態確認(unavailable / downloadable / downloading / available)
    // :contentReference[oaicite:1]{index=1}
    const avail = await Summarizer.availability();
    const summarizer = await Summarizer.create({
      ...opts,
      monitor(m) { // ダウンロード進捗イベント
        m.addEventListener('downloadprogress', e => {
          downloadPane.classList.remove('hidden');
          progress.textContent = `${Math.round(e.loaded * 100)} %`;
        });
      }
    });
    await summarizer.ready; // モデル準備完了を待つ
    downloadPane.classList.add('hidden');
    return summarizer;
  }

  /* --- 2. UI ハンドラ --- */
  document.getElementById('summarize').addEventListener('click', async () => {
    const text   = document.getElementById('input').value.trim();
    if (!text) return;

    const type     = document.getElementById('type').value;
    const length   = document.getElementById('length').value;
    const streaming= document.getElementById('streaming').checked;
    const out      = document.getElementById('output');
    out.textContent = '';

    /* --- 3. Summarizer 作成 & 実行 --- */
    const summarizer = await createSummarizer({
      type,
      length,
    });

    if (streaming) {
      // summarizeStreaming() 例
      const stream = summarizer.summarizeStreaming(text);
      for await (const chunk of stream) {
        out.textContent += chunk;
      }
    } else {
      // summarize() 例(バッチ)
      const summary = await summarizer.summarize(text, {
        context: '出力は日本語で行ってください',
      });
      out.textContent = summary;
    }
  });
})();

参照