GASでスプレッドシートの文章を
AIで校正・誤字脱字チェックする方法

スプレッドシートに並んだ原稿やメール文面を、UrlFetchApp(GASから外部APIを呼ぶ標準機能)とClaude API(Anthropic社の生成AI)を組み合わせ、 誤字脱字や不自然な表現を自動で校正し、修正案と指摘理由を隣の列に書き込む方法を、そのまま動くコードで解説します。

|対象: GAS / スプレッドシート / Claude API / 業務自動化

Table of Contents

なぜ文章校正をGAS×AIで自動化するのか

結論から言うと、スプレッドシートにためた大量の文章の校正は、 GAS(Google Apps Script。Googleサービスを操作する無料のプログラム実行環境)とAIで自動化できます。 原稿やメール文面をA列に並べておけば、AIが1行ずつ誤字脱字や言い回しをチェックし、 校正後の文と指摘理由を隣の列に書き込んでくれます。目視での読み合わせにかかる時間を大きく減らせます。

スプレッドシート自体には文章校正の機能はありません。手作業でチェックすると、 件数が増えるほど見落としが出ます。Claude APIなどのAI校正は、次のような「指示できる校正」が強みです。

誤字脱字に強い

変換ミスや抜け字、送り仮名のゆれなど、目視で見落としやすい点を拾う

言い回しを整える

冗長な表現や二重敬語を、意味を変えずに自然な文へ直す

指摘理由が残る

どこをなぜ直したかを一覧で受け取れるので、採否を人が判断できる

原文は上書きしない

校正後を別の列に書くので、元の文章はそのまま残せる

この記事では、A列の原文を読み取り、Claude APIで校正して、B列に校正後の文・C列に指摘理由を書き込む流れを実装します。 校正済みの行は自動でスキップするので、途中で止まっても再実行するだけで続きから埋められます。

準備:APIキーの保管と校正シートの用意

必要なのは2つです。1つ目は校正シート。A列に原文、B列を校正後、C列を指摘理由の書き込み先とし、1行目はヘッダー(原文 / 校正後 / 指摘など)にしておきます。シート名はここでは「校正」とします。2つ目はClaude APIのキーです。 このキーは料金が発生する権限そのものなので、コードに直書きしてはいけません。GASの「スクリプトプロパティ」(PropertiesServiceで読み書きする、スクリプト単位の設定保存領域)に入れ、コードからはキー名で読み出します。

// 一度だけ実行してAPIキーを安全に保存する
function saveApiKey() {
  // 実行後、この関数のキー文字列は削除しておく
  PropertiesService.getScriptProperties()
    .setProperty("ANTHROPIC_API_KEY", "sk-ant-xxxxxxxx");
}

// コードからはキー名で読み出す(直書きしない)
function getApiKey() {
  const key = PropertiesService.getScriptProperties()
    .getProperty("ANTHROPIC_API_KEY");
  if (!key) throw new Error("APIキーが未設定です。saveApiKeyを実行してください。");
  return key;
}

saveApiKeyを一度だけ実行したら、キー文字列はコードから消しておきましょう。共有スプレッドシートでは、 編集権限を持つ人にスクリプトも見えます。直書きを避けるのはそのためです。以降はどの関数からもgetApiKey()で安全に取り出せます。

Claude APIで校正する関数を作る(JSONで受け取る)

まずは文章を渡すと、校正後の文と指摘一覧を返す関数を作ります。校正では「どこをなぜ直したか」も欲しいので、結果をJSON(データを構造化して表す形式)で受け取ります。プロンプト(AIへの指示文)で 出力するJSONの形を明示し、「意味は変えず最小限の修正に」と伝えるのがコツです。

// 文章を校正し、校正後の文と指摘一覧をJSONで返す
// 戻り値: { corrected: "校正後の文", issues: [{ original, suggestion, reason }] }
function proofreadText(text) {
  const url = "https://api.anthropic.com/v1/messages";

  const prompt =
    "あなたは日本語のビジネス文書の校正者です。\n" +
    "次の文章の誤字脱字・変換ミス・不自然な表現・敬語の誤りを直してください。\n" +
    "・意味は変えず、最小限の修正にとどめる。\n" +
    "・下のJSON形式だけを出力し、前置きや注釈は書かない。\n" +
    "・修正が不要ならissuesは空配列にする。\n\n" +
    'JSON形式: {"corrected":"校正後の全文","issues":[{"original":"元の語句","suggestion":"修正案","reason":"理由"}]}\n\n' +
    "文章:\n" + text;

  const payload = {
    model: "claude-haiku-4-5",
    max_tokens: 1500,
    messages: [{ role: "user", content: prompt }]
  };

  const options = {
    method: "post",
    contentType: "application/json",
    headers: {
      "x-api-key": getApiKey(),
      "anthropic-version": "2023-06-01"
    },
    payload: JSON.stringify(payload),
    muteHttpExceptions: true // エラー時も例外にせずレスポンスを受け取る
  };

  const res = UrlFetchApp.fetch(url, options);
  const code = res.getResponseCode();
  if (code !== 200) {
    throw new Error("API エラー (" + code + "): " + res.getContentText());
  }

  const answer = JSON.parse(res.getContentText()).content[0].text;
  return parseResult(answer);
}

// 返答からJSON部分だけを取り出して読み込む
function parseResult(answer) {
  // いちばん外側の { ... } を抜き出す(前置きが混ざっても解析できる)
  const start = answer.indexOf("{");
  const end = answer.lastIndexOf("}");
  if (start === -1 || end === -1) {
    throw new Error("JSONが見つかりません: " + answer);
  }
  return JSON.parse(answer.substring(start, end + 1));
}

返答はcontent配列の先頭textに入ります。それをそのままJSON.parseせず、parseResult()で最初の{から最後の}までを取り出しています。こうすると、AIが前置きを付けてしまってもJSON部分だけを安全に読み込めます。モデルは軽量なclaude-haiku-4-5から始め、精度を上げたいときに高性能なclaude-opus-4-8へ差し替えるだけで切り替えられます。

エラーに強くする:リトライとJSON抽出

外部APIは、一時的な混雑や通信の不調で失敗することがあります。特にセルを大量に処理すると、 短時間に呼び出しが集中して一時的なエラー(レート制限)が返ることがあります。そこで、失敗したら 少し待ってから再試行する仕組みを入れます。待ち時間を1秒・2秒・4秒と倍にしていく方式を 「指数バックオフ」と呼びます。

// 一時的なエラー時に少し待って再試行する
function proofreadWithRetry(text, maxRetry) {
  maxRetry = maxRetry || 3;

  for (let i = 0; i < maxRetry; i++) {
    try {
      return proofreadText(text);
    } catch (e) {
      // 最後の試行で失敗したら、そのまま呼び出し元に投げる
      if (i === maxRetry - 1) throw e;
      // 待ち時間を1秒・2秒・4秒と伸ばす(指数バックオフ)
      Utilities.sleep(1000 * Math.pow(2, i));
    }
  }
}

一時的な失敗はこのリトライで自動回復します。加えて、前の関数のparseResult()がJSONの取り出しを担うので、「APIの失敗」と「返答が壊れている」の両方に備えられます。 校正の本体はこのproofreadWithRetry()を呼ぶようにすれば、安定性がぐっと上がります。

シートの文章列をまとめて校正する

いよいよ本体です。A列(原文)・B列(校正後)・C列(指摘)をまとめて読み込み、原文があってB列が空の行だけを校正します。校正後をB列、指摘理由をC列に書き込み、済んだ行はスキップするので、 途中で止まっても再実行すれば未処理分だけを埋められます。

// A列の原文を校正し、B列に校正後・C列に指摘理由を書き込む
// シート構成: A=原文, B=校正後, C=指摘(Bが空の行だけ処理する)
function proofreadColumn() {
  const sheet = SpreadsheetApp.getActive().getSheetByName("校正");
  const lastRow = sheet.getLastRow();
  if (lastRow < 2) return; // データなし(1行目はヘッダー想定)

  // A(原文)・B(校正後)・C(指摘)をまとめて読み込む
  const rows = sheet.getRange(2, 1, lastRow - 1, 3).getValues();

  let count = 0;
  for (let i = 0; i < rows.length; i++) {
    const source = String(rows[i][0]).trim();
    const done = String(rows[i][1]).trim();

    if (!source) continue;   // 原文が空ならスキップ
    if (done) continue;      // すでに校正済みならスキップ

    let result;
    try {
      result = proofreadWithRetry(source);
    } catch (e) {
      // 解析やAPIで失敗した行は記録して次へ進む(全体は止めない)
      sheet.getRange(i + 2, 3).setValue("エラー: " + e.message);
      continue;
    }

    // 指摘一覧を1セルに読みやすく整形する
    const notes = (result.issues || [])
      .map(function (x) { return "・" + x.original + " → " + x.suggestion + "(" + x.reason + ")"; })
      .join("\n");

    sheet.getRange(i + 2, 2).setValue(result.corrected);        // B列: 校正後
    sheet.getRange(i + 2, 3).setValue(notes || "修正なし");      // C列: 指摘
    SpreadsheetApp.flush(); // 途中経過をすぐ画面に反映する

    count++;
    if (count >= 20) break;  // 1回20件までに区切る(実行時間制限対策)
    Utilities.sleep(300);    // 連続呼び出しの間隔をあける
  }
}

1行ごとにtry...catchで囲み、解析やAPIで失敗した行はC列にエラー内容を残して次へ進みます。1件の失敗で全体を止めない作りです。 指摘一覧は「・元の語句 → 修正案(理由)」の形に整えて1セルにまとめ、SpreadsheetApp.flush()で途中経過をすぐ画面に反映します。1回の実行は20件までに区切っているので、行が多い場合はもう一度実行すれば続きから進みます。

カスタムメニューとトリガーで実行する

最後に、校正をワンクリックで呼び出せるようにします。onOpen()(スプレッドシートを開いたときに自動で走る特別な関数)でメニューを追加すると、 シート上部に「AI校正」メニューが出て、そこから校正を実行できます。

// シートを開いたときに校正メニューを追加する
function onOpen() {
  SpreadsheetApp.getUi()
    .createMenu("AI校正")
    .addItem("空の行を校正する", "proofreadColumn")
    .addToUi();
}

原文が随時追加されるシートなら、時間主導トリガー(決まった間隔で関数を自動実行するGASの仕組み)でproofreadColumnを定期的に回すのも有効です。B列が空の行だけを校正する作りなので、トリガーで繰り返し実行しても 同じ行を二重に校正することはありません。1回20件の区切りと合わせれば、件数が多くても 実行時間制限(無料枠で6分)に達しにくくなります。分割実行の詳しい実装は関連記事で解説しています。

まとめ

スプレッドシートとClaude APIをGASでつなぐと、文章校正を丸ごと自動化できます。ポイントは4つです。 APIキーはスクリプトプロパティで安全に保管し、校正結果はJSONで受け取って「校正後の文」と「指摘理由」に分け、 原文を上書きせず別の列に書いて採否を人が判断でき、空の行だけを対象にしてリトライと件数の区切りで API制限と実行時間制限をかわす——この型を押さえれば、校正に限らず、翻訳・要約・分類といった AI活用にも同じ流れで応用できます。

よくある質問

スプレッドシートには文章校正の標準機能はありません。Googleドキュメントにはスペルと文法の候補表示がありますが、日本語の言い回しや敬語の統一までは踏み込めません。Claude APIなどのAI校正は「ビジネス文書として自然に」「二重敬語を直す」といった指示を添えられるため、単純な誤字だけでなく読みやすさの改善まで任せられます。

本文のコードは、原文をA列に残したまま校正後をB列、指摘理由をC列に書き込む方式です。原文は上書きしないので、AIの修正が過剰だと感じた行だけ人が見て採否を判断できます。プロンプトで「意味を変えず最小限の修正にとどめる」と指示しておくと、書き換えすぎを抑えられます。

GASには1回の実行あたり6分(Google Workspaceは30分)の実行時間制限があります。1回あたりの処理件数を区切り、校正済みのセルはスキップして続きは次回の実行で再開する作りにすると安定します。本文でスキップ処理を、関連記事で分割実行の方法を解説しています。

書いてはいけません。APIキーは料金が発生する権限そのものです。共有スプレッドシートのスクリプトに直書きすると、編集権限を持つ他の人にキーが見えてしまいます。GASのスクリプトプロパティ(PropertiesServiceで読み書きする設定保存領域)に保管し、コードからはキー名で読み出してください。

まれに前置きの文が混ざることがあります。本文のコードは、返答からいちばん外側の中括弧の範囲を取り出してからJSONとして読み込むので、多少の前置きが付いても解析できます。それでも解析に失敗した行は校正をスキップし、他の行の処理は止めない作りにしています。

Claude APIは処理した文字数(トークン)に応じた従量課金です。校正は入力・出力とも短いことが多いため、軽量モデルのclaude-haiku-4-5を使えば1セルあたりの費用はごくわずかです。まずは少量で試して1回あたりの消費量を確認し、対象範囲を広げるのがおすすめです。

AI×GASの業務自動化を
相談する。

校正のほかにも、翻訳・要約・問い合わせ分類・返信下書きの自動生成など、 AI APIとGASを組み合わせた自動化をご相談いただけます。既存のスプレッドシート運用にもそのまま組み込めます。

AI×GAS自動化の対応範囲を見る