マキモノ
Google Workspace無料✅ 公式検証済みv1.0.0 / 更新

機密列を含む共有スプレッドシートにAIを安全に書き込ませる型

パスワードや手書きメモと同居する管理表に、AIに本文を読ませずに自動更新させる実装型。許可リスト書込・見出し行の自動検出・行を奪わない突合・列順シャッフルの敵対的テスト・定期実行の引数固定まで。

出品者: kim@orgiast.jp1 DL📖 読込 約2,869トークン (約4円)💰 コスパ 14
トークン節約メーター92%節約
ゼロからAIに作らせた場合4.2万トークン
このMDを読ませた場合3,200トークン

3.9万トークンの節約 (API料金換算で約58円分)。 要件定義・技術調査・試行錯誤ぶんのトークンがまるごと不要になります。※ 出品者申告とレビューに基づく推定値。モデル・タスク内容により変動します。

この巻物について

機密列を含む共有スプレッドシートにAIを安全に書き込ませる型」は、Google WorkspaceカテゴリのAI指示書(MDファイル)です。パスワードや手書きメモと同居する管理表に、AIに本文を読ませずに自動更新させる実装型。許可リスト書込・見出し行の自動検出・行を奪わない突合・列順シャッフルの敵対的テスト・定期実行の引数固定まで。この巻物をAIに読み込ませると、ゼロから設計・調査する場合に比べて 約3.9万トークン(API料金換算で約58円)・92%のトークンを節約できます。

カテゴリ
Google Workspace
対応AI
claude-code、cursor、codex-cli
ライセンス
商用利用可 (再販不可)
価格
無料
ゼロから開発時
約4.2万トークン
この巻物使用時
約3,200トークン
節約量
約3.9万トークン (約58円)
更新日
2026-08-28

使い方 (AIに渡す3つの方法)

いちばん簡単なのはワンライナー。Claude Code のターミナルに貼るだけです。

⬇ .md をダウンロード
claude "https://makimono-md.vercel.app/api/v1/files/md-45af39d0/raw を読み込んで、この指示書どおりに実装して"
claude-codecursorcodex-cliライセンス: 商用利用可 (再販不可)

中身

機密列を含む共有スプレッドシートに、AIに本文を読ませずに安全に書き込む

社内の管理表には、AI に自動更新させたい列(機器スペック・稼働状態・最終更新日)と、 絶対に触らせたくない列(パスワード・購入金額・担当者の手書きメモ)が同じシートに同居していることが多い。

素直に「AI にシートを読ませて書き換えさせる」と2つの事故が起きる。

  1. AI のコンテキストにパスワードが載る(ログ・履歴・外部送信に残る)
  2. 人が手で書いた列を上書きする(復旧できない)

この2つを構造的に潰す型。AI エージェントにこの MD を読ませればそのまま実装できる。


全体像

各端末のスクリプト  --POST-->  Apps Script Web App  -->  スプレッドシート
   (値を集めるだけ)              (列解決と書き込みを独占)

原則: 端末側にも AI 側にもシートを読ませない。列の解決と書き込みは Apps Script の中だけで行う。 読まなければ漏らせない。


1. 書き込みは許可リスト方式にする(denylist にしない)

禁止列を列挙する方式は、列が増えた瞬間に破綻する。書いてよい列だけを定義する。

// Apps Script 側
var WRITABLE_ = {
  maker: 'メーカー', computerName: 'コンピュータ名', cpu: 'CPU',
  os: 'OS', memoryGb: 'メモリ容量(GB)', updatedAt: '情報更新日'
};

function normalizeHeader(v) {
  // 全角/半角、改行入り見出し、前後空白の差で「見つからない」と誤判定しないため
  return String(v == null ? '' : v).normalize('NFKC').replace(/\s+/g, '').toLowerCase();
}

function findHeader(headers, wanted) {
  var target = normalizeHeader(wanted);
  for (var i = 0; i < headers.length; i++) if (normalizeHeader(headers[i]) === target) return i;
  return -1;
}

function planWrite(headers, rows, payload) {
  var values = {};
  Object.keys(WRITABLE_).forEach(function (key) {
    var col = findHeader(headers, WRITABLE_[key]);
    var value = payload[key];
    // 値が無いときは書かない = 空文字で既存値を潰さない
    if (col >= 0 && value !== '' && value != null) values[col] = value;
  });
  return values;
}

禁止列は WRITABLE_ に載せないというだけで、コードが参照すらしないので構造的に書けない。

2. 「書き込んだ列名」を応答で返す

呼び出し側がシートを読まずに許可リスト遵守を検証できるようにする。これが無いと、 本番で許可リストが守られたかを確認するために結局シートを読むことになる。

var written = [];
Object.keys(values).forEach(function (col) {
  sheet.getRange(targetRow, Number(col) + 1).setValue(values[col]);
  written.push(headers[Number(col)]);
});
return { ok: true, row: targetRow, written: written };

3. 見出し行だけを返す診断コマンドを用意する

実装には実際の列名の表記が要る(PC No. なのか No なのか、改行が入るのか)。 しかし本文を読むと機密が載る。1行目だけ返す関数を用意して解決する。

function describeHeaders() {
  var sheet = targetSheet_();
  var found = findHeaderRow_(sheet);
  return { headerRow: found.row, headers: found.headers };  // 本文は返さない
}

4. 見出し行が1行目とは限らない

実務のシートは1行目が結合されたタイトル行で、見出しは2行目や3行目にあることが多い。 行1固定で実装すると「必須ヘッダが見つからない」で落ちる。

function findHeaderRow_(sheet) {
  var props = PropertiesService.getScriptProperties();
  var lastColumn = sheet.getLastColumn();
  var cached = Number(props.getProperty('HEADER_ROW') || 0);
  if (cached > 0) {
    var h = sheet.getRange(cached, 1, 1, lastColumn).getDisplayValues()[0];
    if (findHeader(h, WRITABLE_.computerName) >= 0) return { row: cached, headers: h };
    props.deleteProperty('HEADER_ROW');   // 構造が変わったらキャッシュを捨てる
  }
  var scan = Math.min(10, sheet.getLastRow());
  for (var row = 1; row <= scan; row++) {
    var headers = sheet.getRange(row, 1, 1, lastColumn).getDisplayValues()[0];
    if (findHeader(headers, WRITABLE_.computerName) >= 0) {
      props.setProperty('HEADER_ROW', String(row));
      return { row: row, headers: headers };
    }
  }
  throw new Error('見出し行が先頭' + scan + '行に見つかりません');
}

列レターをハードコードしない。必ず見出し文字列で解決する。 人が列を挿入しても壊れない。

5. 行の突合は「奪わない」規則にする

同じ端末を指す行が、人の手入力行と機械書き込み行に分かれて複数存在するのが普通。

  • 第1キー: 機械が書くラベル列の完全一致
  • 第2キー: 人が書く名前列の一致 かつ ラベル列が空
  • 「名前列は一致するがラベル列に別の名前が入っている行」は絶対に触らない(他人の行を奪う)

さらに 一致した行は全部更新する。最初の1件で打ち切ると、別表記の行が空欄のまま残り、 利用者には「ほとんど書かれていない」ように見える。

突合できなかった項目は既定では行を作らない。明示フラグを付けた時だけ最下部に追記し、 その場合も ラベル列と自動更新列だけ書いて人の入力欄は空のままにする。

6. 敵対的テストで守る(これが本体)

「たまたま今の列順で通った」を排除する。列順をシャッフルして数百回回す。

for (let t = 0; t < 200; t++) {
  const headers = shuffle([...FORBIDDEN, ...ALLOWED], t);
  const forbidden = new Set(FORBIDDEN.map(h => headers.indexOf(h)));
  // 禁止列名をキーに持つ敵対的 payload を投げる
  const plan = planWrite(headers, rows, { maker: 'X', 'パスワード': 'p', 'デバイスID': 'd' });
  for (const col of Object.keys(plan)) {
    assert(!forbidden.has(Number(col)), '禁止列に書き込んだ');
  }
  assert(plan[headers.indexOf('型番')] === undefined, '空値で既存を上書きした');
}

検証すること:

  • 禁止列への書き込みが0件
  • 空の値で既存セルを潰さない
  • 名前列一致だがラベル列が別名の行を更新しない
  • 追記時も人の入力欄が空のまま

7. 定期実行の引数を機械で固定する

新しい収集項目にフラグ(例 --specs)を足したら、定期実行の呼び出し側にも入れる。 入れ忘れると「手で叩いた1台しか記録されない」状態が延々と続き、誰も気付かない。

test('定期ジョブは --specs を渡す', () => {
  const line = read('scheduler.mjs').match(/collector\.mjs'[^\n]*/)[0];
  assert.match(line, /--specs/);
});

このテストはわざとフラグを外して落ちることまで確認する(落ちないテストは無いのと同じ)。

8. 黙って成功しない

書き込み系のコマンドは、成功時にも 更新件数・書き込んだ列・突合できなかった対象を必ず出力する。 何も出さないと「届いていない」ことに誰も気付けない。例外を握り潰す catch {} は置かない。


つまずきやすい実装上の罠

症状原因対処
値が全部空になる生のオブジェクトを JSON 化してメタデータごと数百KBになり、値が取り出せない直列化の前に必要なプロパティだけ選ぶ
must be a string without null bytesパス中の \0 がテンプレートリテラルで NUL 文字になる\\0 と書く
見出しに一致しない見出しに改行や全角が混じるNFKC 正規化+空白除去で照合
端末情報が文字化け日本語 OS のコマンド出力が別のエンコーディング出力を UTF-8 に固定し、さらに数値だけ抜く正規化関数を通す
容量が実際の半分以下32bit 幅のフィールドが上限で飽和している64bit の別ソースを優先し、飽和値なら書かない
「無し」と誤って記録される接続中のものしか列挙しない API を「存在しない」証拠に使っているあり / なし / 判定不能 の3値にし、断定できない側は判定不能

認証について

新しい鍵を増やさない。Web App 側に共有トークンを1つ持たせ、端末はそれを送るだけにする。 トークンの投入は、Drive にコマンドファイルを置いて時間トリガーで処理させる方式にすると 人の手作業がゼロになる(結果もファイルで返る)。

よくある質問

「機密列を含む共有スプレッドシートにAIを安全に書き込ませる型」とは何ですか?

パスワードや手書きメモと同居する管理表に、AIに本文を読ませずに自動更新させる実装型。許可リスト書込・見出し行の自動検出・行を奪わない突合・列順シャッフルの敵対的テスト・定期実行の引数固定まで。

どれくらいトークン(費用)を節約できますか?

ゼロから開発すると約4.2万トークンかかりますが、この巻物を使えば約3,200トークンで済みます。差し引き約3.9万トークン(API料金換算で約58円)・92%の節約です。

どうやって使いますか?

無料です。MDファイルを Claude Code などのAIに読み込ませるだけ。ワンライナーをターミナルに貼れば実装が始まります。要件定義や技術調査を省いて実装だけにトークンを使えます。

どのAIツールに対応していますか?

claude-code、cursor、codex-cli に対応しています。

商用利用できますか?

ライセンスは「商用利用可 (再販不可)」です。

🤝 自分でAIを動かすのは、まだ不安…という方へ

この巻物の内容を、AIを使うプロに丸ごと任せることもできます。姉妹サービスAI代行堂なら「LINEで頼むだけで、仕事が完成」。

AI代行堂を見る →

関連する巻物

この巻物、誰かのトークンも救えます

𝕏 で節約レシートをシェア