マキモノ
AIのしつけ無料✅ 公式検証済みv1.0.0 / 更新

AI の返答に出てくる URL に「どのアカウントで開くか」を必ず書かせる Stop hook の作り方

管理画面・課金ページの URL をアカウント名なしで人に渡すと別アカウントで開いて 404 になる。返答の送信直前に止める Stop hook(判定ロジック・免除条件・逃がし弁・テスト・配線)を依存なしの Node.js で作る手順。

出品者: seisaku-team@orgiast.jp📖 読込 約2,718トークン (約4円)💰 コスパ 8倍
トークン節約メーター84%節約
ゼロからAIに作らせた場合約2.5万トークン
このMDを読ませた場合約4,000トークン

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

この巻物について

「AI の返答に出てくる URL に「どのアカウントで開くか」を必ず書かせる Stop hook の作り方」は、AIのしつけカテゴリのAI指示書(MDファイル)です。管理画面・課金ページの URL をアカウント名なしで人に渡すと別アカウントで開いて 404 になる。返答の送信直前に止める Stop hook(判定ロジック・免除条件・逃がし弁・テスト・配線)を依存なしの Node.js で作る手順。この巻物をAIに読み込ませると、ゼロから設計・調査する場合に比べて 約2.1万トークン(API料金換算で約32円)・84%のトークンを節約できます。

カテゴリ
AIのしつけ
対応AI
claude-code、cursor、codex-cli
ライセンス
商用利用可 (再販不可)
価格
無料
ゼロから開発時
約2.5万トークン
この巻物使用時
約4,000トークン
節約量
約2.1万トークン (約32円)
更新日
2026-10-08

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

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

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

中身

AI の返答に出てくる URL に「どのアカウントで開くか」を必ず書かせる Stop hook の作り方

何を解決するか

AI エージェント(Claude Code など)が管理画面や課金ページの URL を人に渡すとき、「どの Google / GitHub アカウントで開くか」が書かれていないと、受け取った人は既定のアカウントで開いて 404 やログイン画面に飛ばされ、別アカウントのまま操作して事故になる。実例: 課金ページの URL をアカウント名なしで渡し、受け取った人は別アカウントのブラウザで 11 回ログイン画面に戻された。

ルール文を書くだけでは守られない。返答を送る直前に機械で止める(Stop hook)。

完成形

  • tools/url-account-gate.mjs: 返答本文を判定し、アカウントが要る URL にアカウント名が無ければブロック理由を返す
  • 既存の Stop hook ランナーに 1 行登録(無ければ単体で Stop hook として登録)
  • テスト(node:test)で「止まる文/通る文」を固定

判定ロジック(この順で実装する)

  1. コードフェンス(…)内は判定しない。行の境界は保つ(フェンス内を空にするだけ)。
  2. 逃がし弁: 本文に [URL-ACCOUNT-OK] があれば通す。
  3. 全体宣言: 「以下の URL はすべて <メール> で開く」のような行(すべて|全部|いずれも と <メール> で開く)があれば、本文の全 URL を合格にする。
  4. 対象 URL だけを抽出する:
    • ドメイン一致(サブドメイン含む): aistudio.google.com, console.cloud.google.com, admin.google.com, mail.google.com, github.com, vercel.com, supabase.com, npmjs.com, x.com, discord.com, dash.cloudflare.com, platform.openai.com, console.anthropic.com, notion.so, slack.com, figma.com, canva.com など、自社で使う「ログインが要るサービス」を列挙する
    • パス一致: /admin /console /dashboard /settings /login /signin /account を含む URL
    • 常に対象外: localhost, 127.0.0.1, .local, raw.githubusercontent.com
    • Google Workspace(docs/drive/sheets/script)は、URL に authuser= か /a/<自社ドメイン>/ が含まれていれば「アカウントが URL に埋め込まれている」とみなして免除
  5. 対象 URL ごとに「同じ行か前後 2 行」に次のどれかがあれば合格:
    • メールアドレス
    • で開く または アカウント を含み、かつ太字の名前 **…** がある(例: (**team@<自社ドメイン>** で開く))
    • 自社のブラウザ起動ヘルパー呼び出し(例: open-url-as.ps1 -Account)
  6. 1 つでも不合格があれば { triggered: true, missing: [URL…] } を返す。

ブロック理由の文面(人が直せるように、直し方を含める)

[URL-ACCOUNT] 次の URL に「どのアカウントで開くか」が書かれていません。
形式: <URL>(**<アカウント名>** で開く)。既定アカウントと違うなら「シークレットウィンドウで開く」も併記。
本文の URL が全部同じアカウントなら「以下の URL はすべて **x@y** で開く」の 1 行でよい。例外は [URL-ACCOUNT-OK]。
<URL 1>
<URL 2>

実装の骨子(Node.js ESM・依存なし)

const accountDomains = ['aistudio.google.com', 'console.cloud.google.com', 'github.com', /* … */];
const workspaceDomains = ['docs.google.com', 'drive.google.com', 'sheets.google.com', 'script.google.com'];
const email = /[\w.+-]+@[\w-]+\.[\w.-]+/;
const matchesDomain = (host, d) => host === d || host.endsWith('.' + d);

function needsAccount(raw) {
  let url; try { url = new URL(raw); } catch { return false; }
  const host = url.hostname.toLowerCase();
  if (host === 'localhost' || host === '127.0.0.1' || host.endsWith('.local')) return false;
  if (matchesDomain(host, 'raw.githubusercontent.com')) return false;
  if (workspaceDomains.some(d => matchesDomain(host, d)))
    return !url.searchParams.has('authuser') && !url.pathname.includes('/a/<自社ドメイン>/');
  return accountDomains.some(d => matchesDomain(host, d))
    || /\/(?:admin|console|dashboard|settings|login|signin|account)/i.test(url.pathname);
}

export function judge(text) {
  const body = text.replace(/```[\s\S]*?```/g, b => b.replace(/[^\r\n]/g, ''));
  if (body.includes('[URL-ACCOUNT-OK]')) return { triggered: false, missing: [] };
  const lines = body.split(/\r?\n/);
  const found = [];
  lines.forEach((line, i) => {
    for (const m of line.matchAll(/https?:\/\/[^\s<>"'()「」、。]+/g)) {
      const url = m[0].replace(/[.,;:!?]+$/, '');
      if (needsAccount(url)) found.push({ url, i });
    }
  });
  const global = lines.some(l => /(すべて|全部|いずれも)/.test(l) && /[\w.+-]+@[\w.-]+(\*\*)?\s*で開く/.test(l));
  if (global) return { triggered: true, missing: [] };
  const ok = i => lines.slice(Math.max(0, i - 2), i + 3).some(l =>
    email.test(l) || (/(で開く|アカウント)/.test(l) && /\*\*[^*\n]+\*\*/.test(l)) || /open-url-as\.ps1.*-Account/.test(l));
  const missing = [...new Set(found.filter(f => !ok(f.i)).map(f => f.url))];
  return { triggered: found.length > 0, missing };
}

Stop hook としての配線

  • Claude Code の settings.json → hooks.Stop にこのスクリプトを登録する。stdin に JSON(transcript_path, stop_hook_active)が来るので、stop_hook_active が true なら何もしない(ループ防止)。
  • 最新の assistant 発話を transcript から取り出して judge() に渡し、missing があれば理由を stderr に出して exit 2(ブロック)。
  • 既に複数の gate を 1 本のランナーで回している場合は、ランナーの gate 配列に ['url-account-gate', () => …] を 1 行足すだけでよい。

テスト(最低限)

  • 課金ページの URL にアカウント名なし → ブロック、missing にその URL
  • 同じ文に (**team@<自社ドメイン>** で開く) → 通る
  • 「以下の URL はすべて team@<自社ドメイン> で開く」+ GitHub の URL 複数 → 通る
  • 出典リンク(公開ブログ・raw.githubusercontent.com)だけ → 発火しない
  • docs.google.com/…?authuser=1 → 対象外/authuser なし → ブロック
  • コードフェンス内の URL → 無視
  • http://localhost:3000/admin → 対象外
  • try { … } catch の中で assert を呼ばない(握りつぶして常に pass になる)

併せて作ると効くもの

  • 「そのアカウントのブラウザプロファイルで URL を開く」ヘルパー(Chrome の Local State の profile.info_cache[*].user_name からメール→プロファイル名を引き、chrome.exe --profile-directory=<名前> <URL> で起動)。手で保守する対応表を持たない。
  • 所有アカウントが分からないときは、各プロファイルの History(SQLite)をコピーして対象ドメインの訪問履歴を引く(last_visit_time は CAST(... AS TEXT) で読む。人に聞く前に自分で引ける)。

導入後に起きること

  • アカウント名のない URL を含む返答は送信前に止まり、AI が自分で書き直す。人への手戻り(別アカウントで開いて 404)が消える。
  • 誤検知は [URL-ACCOUNT-OK] で逃がせるが、逃がし弁を使った返答はレビューで目立つようにしておく。

よくある質問

+「AI の返答に出てくる URL に「どのアカウントで開くか」を必ず書かせる Stop hook の作り方」とは何ですか?

管理画面・課金ページの URL をアカウント名なしで人に渡すと別アカウントで開いて 404 になる。返答の送信直前に止める Stop hook(判定ロジック・免除条件・逃がし弁・テスト・配線)を依存なしの Node.js で作る手順。

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

ゼロから開発すると約2.5万トークンかかりますが、この巻物を使えば約4,000トークンで済みます。差し引き約2.1万トークン(API料金換算で約32円)・84%の節約です。

+どうやって使いますか?

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

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

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

+商用利用できますか?

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

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

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

AI代行堂を見る →

関連する巻物

AIのしつけ無料✅ 公式

AIっぽくない提案書を作る — ハイブリッド企画書モデル(コードAI組版×画像モデル写真×スライドAI配置参照)

コード生成AIの組版・画像編集モデルの写真合成・スライド生成AIの配置文法を分担させ、経営者の差し戻し3回→0回にした提案書パイプラインの作り方と失敗パターン

87%節約
約78万トークン (料金換算 約1,170円)
新着
AIのしつけ無料✅ 公式

AI運用ルールを機械的に守らせる hook 設計 — ルール文が守られない本当の理由

チームでAIエージェントを使うと運用ルールが必ず守られなくなる。真因は「読んでいない」ではなく hook がそのマシンで登録されていない/委譲先が沈黙して壊れていること。禁止=実行前拒否・誘導=依頼時の具体コマンド注入・担保=セッション開始時の自己修復の3層、明示例外の短命トークン、warn→blockの段階昇格、BOM/サンドボックス/timeout など失敗が沈黙する罠と、環境依存で落ちないテストの作り方までを実測ベースでまとめた導入手順。

95%節約
約24.6万トークン (料金換算 約370円)
新着
AIのしつけ無料✅ 公式

AIの応答を止める番人hookを1ランナーに統合し、書き直しを最大1回にする(誤爆率をfixtureで先に測る)

Stop hook を9本積んだら Stop の65%が書き直し・最多ゲートの91%が誤爆だった。誤爆測定→否定文除外→1プロセス合流→再試行上限統一→全PC移行→KPIで効果確認までの手順。

95%節約
約17.1万トークン (料金換算 約260円)
新着

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

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