🧑‍💻 開発者向けNode.js・Git・Claude Code

【自社事例】AIエージェント(Claude Code)でメディアサイトを運用する仕組み【2026】静的HTML×Git×自動チェック

いま読んでいる「AIエージェント研究所」は、記事の追加・内部リンクの張り替え・デザイン変更まで、日々の運用の大半をAIエージェント(Claude Code)と一緒に行っています。本記事では、その裏側をリポジトリの実物(build.js・keihyo-check.js・.gitignore・コミット履歴)に基づいて公開します。ポイントは「AIを賢くする」ことではなく、AIが間違えても公開前に機械で止まり、人がレビューでき、いつでも戻せる構造を先に作ることです。

🔬
調査・編集:AIエージェント研究所 編集部
運営=広告運用・生成AIエージェント導入支援の現役コンサル。このサイト自体も、AIエージェントと一緒に作り・公開・運用しています。

本記事の自社事例は、このサイトのリポジトリで確認できる事実のみに基づいています。数値は2026年9月時点で実際に数えた値です。→ 運営者・編集方針について

公開:2026年9月26日/最終更新:2026年9月26日
この記事の結論(要点まとめ)
  • CMSではなく静的HTML+Gitにしたのは、AIエージェントがファイルを直接読み書きでき、全変更がGitの差分でレビュー・ロールバック可能になるから
  • build.js(共通フッターの流し込み)とkeihyo-check.js(景表法まわりの機械チェック)が、問題があれば exit 1 で止まるガードレール
  • AIは「作業ブランチで変更→PR」、人は「差分と見た目を確認→マージ」。マージ後はCloudflare Pagesが自動公開
  • 2026年9月時点、mainの全25コミットにAIとの共同作業の記録(Co-Authored-By: Claude)が付いている
  • 運用ルールは、Claude CodeのCLAUDE.md・permissions・hooks・Skillsで「言葉」ではなく「設定」として渡すのが次の一手
基礎から学びたい方へ Git・ブランチ・プルリクエスト・デプロイの基本がまだの方は、先にAIエージェント時代のIT基礎ロードマップ(特に第7章 Git・GitHub・デプロイ入門)を読むと、本記事がぐっと読みやすくなります。

なぜCMSではなく「静的HTML+Git」にしたのか

本サイトはHTMLとCSSだけでできた静的サイトです。WordPressのようなCMSも、Next.jsのようなフレームワークも、静的サイトジェネレーターも使っていません。記事1本が1つのHTMLファイルで、それをGitで管理し、GitHub経由でCloudflare Pagesから配信しています。

メディアサイトならWordPressが定番です。それでも静的HTML+Gitを選んだのは、「AIエージェントに運用を任せる」前提で、私たちが重視した点が次の3つだったからです。

私たちが重視した点静的HTML+Git一般的なCMS(WordPress等)
AIが直接触れるか記事も設定も全部ファイル。コーディングエージェントが標準のファイル操作だけで読み書きできる本文はDB、操作は管理画面かAPI経由。エージェントに専用の接続手段が必要
変更を全部レビューできるか1行単位の差分がPRで見える。「AIが何を変えたか」に死角がないDB上の変更は差分として残りにくい。リビジョン機能は本文中心
すぐ戻せるかコミット単位で git revert。全ページ一括の変更でも1コミットで戻るDBバックアップからの復元など、戻す粒度が粗くなりがち

加えて、静的サイトはサーバー側で動くコードがないため、プラグインの脆弱性対応やPHPのバージョン管理といった保守作業が発生しません。AIエージェントに「触ってよい範囲」を渡すうえでも、攻撃面が小さいことは安心材料です。

トレードオフ(静的HTMLで失ったもの)

もちろん代償もあります。ここを正直に書いておかないと、判断材料になりません。

  • 共通パーツの重複:ヘッダーやフッターが全HTMLにコピーされる。修正が全ページに波及する → 後述の build.js でフッターだけは正本から自動で流し込む形にした
  • 非エンジニアが直接編集しにくい:管理画面がない。修正依頼は基本的にAIエージェント経由になる
  • 一覧・サイトマップの手動更新:記事を足したら index.html・sitemap.xml・llms.txt への登録も必要。これもAIの作業手順に含めている
  • 動的機能が作れない:検索・会員機能・コメントなどは別サービスが必要
助手アイ
助手アイ「重複が多い」という静的HTMLの弱点も、AIエージェントなら全ページ一括で直せるから気にならない……ということですか?
エージェント博士
エージェント博士半分正解じゃ。一括で直せる代わりに、一括で壊すこともできる。だから「全ページに必ず入っていなければならないもの」は、AIの注意力に頼らず、スクリプトで検査して止める設計にしたんじゃよ

リポジトリ構成

リポジトリはビルド工程をほぼ持たない、素朴な構成です。約57ページ規模(2026年9月時点、本シリーズ追加前)で、トップ直下に記事HTMLが並び、レビュー記事だけ reviews/ 配下にあります。

ai-agent-lab/(抜粋)Tree
ai-agent-lab/
├── index.html / about.html / privacy.html / 404.html
├── generative-ai.html ほか記事HTML   # 1記事=1ファイル
├── reviews/                        # レビュー記事(1階層深い)
├── assets/                         # style.css・キャラ画像・OGP画像
├── partials/
│   └── footer.html                 # 共通フッターの「正本」
├── build.js                        # フッター流し込み+表記漏れで停止
├── keihyo-check.js                 # 景表法まわりの機械チェック
├── sitemap.xml / llms.txt / robots.txt / ads.txt
└── .gitignore                      # 秘密情報をコミットしない

ポイントは、「配信するもの」と「運用のための道具」が同じリポジトリにあることです。build.js や partials/ はサイトの訪問者には不要な、運用のための道具です。記事と道具を同じリポジトリで管理することで、AIエージェントは「記事を直す」と「チェックを回す」を1つの作業の流れで行えます。

build.jsの設計:正本を流し込み、失敗したら止める

build.js は依存パッケージのない約180行のNode.jsスクリプトで、役割は1つだけです。partials/footer.html(正本)の内容を、全HTMLの <!-- FOOTER:START --> と <!-- FOOTER:END --> の間に流し込む。このフッターにはアフィリエイト(広告)の表記が含まれているため、「フッターが入らないページ=表記漏れのページ」になります。

① マーカー方式で「正本」を流し込む

build.js(抜粋)JavaScript
const START_MARKER = '<!-- FOOTER:START -->';
const END_MARKER = '<!-- FOOTER:END -->';

// そのページから見たサイトTOPまでの相対パス(reviews/配下なら ../)
const depth = file.split(path.sep).length - 1;
const basePath = '../'.repeat(depth);
const note = NOTE_OVERRIDES[file] || DEFAULT_NOTE;

const footerHtml = footerTemplate
  .replace(/\{\{BASE\}\}/g, () => basePath)
  .replace(/\{\{NOTE\}\}/g, () => note);

html =
  html.slice(0, startIndex + START_MARKER.length) +
  '\n' + footerHtml + '\n' +
  html.slice(endIndex);

設計上のポイントは3つです。

  • ページ一覧を持たない:対象HTMLはディレクトリを再帰的に探索して自動で見つける。「新しい記事をスクリプトに登録し忘れる」というミスが構造的に起きない。AIが記事を追加するたびに設定ファイルを直す必要もない
  • マーカー間を丸ごと置換:何度実行しても同じ結果になる(冪等)。正本を直して再実行すれば全ページが揃う
  • 階層差とページ別の注記を吸収:{{BASE}} で reviews/ 配下の相対パスを、{{NOTE}} で調査時点などページ別の注意書きを差し込む。例外は NOTE_OVERRIDES と SKIP_FILES の2か所に集約

なお .replace() の第2引数に文字列ではなく関数(() => basePath)を渡しているのは、置換文字列中の $ が特殊パターンとして解釈されるのを避けるための、地味ですが大事な書き方です。

② 問題を集めて、最後に exit 1 で止める

build.js(抜粋)JavaScript
// 念のため、書き出す前にアフィリエイト表記が入ったか確認する
if (!html.includes('class="footer-pr"')) {
  problems.push(`${file}\n    アフィリエイト表記が入りませんでした。`);
  continue;
}

// ……全ページを処理したあと……

// 問題があれば、デプロイに進ませずここで止める
if (problems.length > 0) {
  console.error(`⚠️  ${problems.length}件のページで問題が見つかりました。`);
  problems.forEach((p) => console.error(`  ▸ ${p}\n`));
  console.error('直してから、もう一度 node build.js を実行してください。');
  process.exit(1);
}

ここが本記事でいちばん伝えたい設計です。1ページ目で問題が見つかっても即座に落とさず、全ページを検査して問題をまとめて報告してから exit 1 する。こうすると、AIエージェントはエラー出力を読んで一度に全部を直せます(1件直すたびに再実行して次の1件が出る、という往復を減らせる)。

エラーメッセージも「何が起きたか」だけでなく「どこをどう直せばいいか」まで書いています。たとえばマーカーが見つからないページについては、「マーカー2行を書き足すか、フッター不要なら SKIP_FILES に追加してください」と具体的な選択肢を出します。エラーメッセージは、AIエージェントへの次の指示文でもあるからです。

ほかにも、使わなくなった旧パーツ(CSSを削除済みの古いPR表示バー)が残っていたら止める、既存の <footer> タグがあれば自動でマーカーに置き換える、といった移行期の面倒も吸収しています。

エージェント博士
エージェント博士「exit 1」は、AIにとっての赤信号じゃ。人間に「気をつけてね」と頼むより、機械が非ゼロで終わるほうが確実に止まる。コーディングエージェントはコマンドの終了コードを見て次の行動を決めるからのう

keihyo-check.js:HARD/WARNの2段階チェック

本サイトはアフィリエイトプログラムを利用しているため、景品表示法(ステマ規制を含む)への配慮が欠かせません。keihyo-check.js は、2026年8月24日に手作業で直した観点を毎回機械でチェックして再発を防ぐために作ったスクリプトです(ファイル冒頭のコメントにそう明記されています)。チェック観点は次の5つです。

#チェック観点レベル
1アフィリエイトリンクを含む記事にPR表示があるか。かつ星評価より前にあるかHARD
2星評価に「採点方法・調査ベースか実機か」の根拠注記があるかHARD
3評価操作を促す表現(レビュー依頼の不適切な形など)が残っていないかWARN
4target="_blank" のリンクに noopener が付いているかHARD
5件数を示せない断定的な口コミ表現が残っていないかWARN

HARD(要修正)が1件でもあれば exit 1、WARN(要確認)は表示するだけで exit 0 のまま、という2段階にしています。

keihyo-check.js(抜粋)JavaScript
// <head>内のメタ情報(title/og等)を除外し、本文(<body>以降)だけで判定する
const bodyIdx = raw.indexOf('<body');
const html = bodyIdx >= 0 ? raw.slice(bodyIdx) : raw;

const hasAffiliate = /rel="[^"]*sponsored/.test(html);

// --- 4. noopener(全リンク対象)---
const anchors = html.match(/<a\b[^>]*target="_blank"[^>]*>/g) || [];
const noNoopener = anchors.filter((a) => !/noopener/.test(a)).length;

if (hasAffiliate) {
  // --- 1. PR表示の有無&位置 ---
  const prIdx = PR_PATTERNS.map((p) => html.indexOf(p))
    .filter((i) => i >= 0).sort((a, b) => a - b)[0];
  // 星評価ウィジェットが PR表示より前に出ていないか
  const ratingIdx = firstRatingIndex(html);
  if (ratingIdx >= 0 && ratingIdx < prIdx) { /* HARD */ }
}

なぜ2段階にしたのか(判断基準)

  • HARDは「文字列の有無・位置」で機械的に白黒がつくものに限定:PR表示があるか、星より前か、noopenerがあるか。誤検知が少ないので、公開を止めても運用が回る
  • WARNは「文脈で意味が変わるもの」:評価操作の疑いは、「〜は避けましょう」という注意喚起の文でも同じ単語が出る。打ち消し表現があれば除外する簡易判定はしているが、最終判断は人に回す
  • 全部HARDにしない理由:誤検知で毎回止まるチェックは、そのうち無視されるか無効化される。止める基準を厳選するほど、止まったときの信頼度が上がる

また、判定を<body> 以降に限定しているのも工夫です。<head> 内のtitleやOGPに「★」や「評価」といった語が入っていても、それは星評価ウィジェットではないため、誤検知を避けています。星評価の検出も「★が3つ以上連続」「特定のclass名」など、実際の評価表示の形に絞った正規表現にしています。

ガードレールは「過去の失敗の翻訳」 build.jsもkeihyo-check.jsも、ゼロから網羅的に設計したものではありません。一度人間が手で直した問題を、二度と起こさないためのコードです。AIエージェントに運用を任せるほど、この「失敗→チェック化」のサイクルが効いてきます。

AIに任せる作業と、人が見る作業の線引き

「全部AIに任せる」わけでも、「AIは下書きだけ」でもありません。私たちが採っている線引きは、「機械で正否を判定できる作業はAI+スクリプト、価値判断と最終承認は人」です。

作業担当理由
記事HTMLの作成・既存テンプレートの踏襲AI型が決まっており、差分で確認できる
index.html・sitemap.xml・llms.txtへの登録AI機械的で漏れやすい。手順化しやすい
全ページ一括の置換(ヘッダー統一など)AI+スクリプト人手では現実的でない量。結果はbuild.jsと差分で検証
内部リンクの監査(リンク切れ・孤児ページ)AI全ページ走査は機械が得意
表記漏れ・景表法まわりの形式チェックスクリプト毎回・同じ基準で・漏れなく
何を書くか・どの案件を扱うか人事業判断・編集方針
事実関係・表現の最終確認、WARNの判断人文脈と責任が伴う
マージ(=公開の決定)人公開責任は人が持つ

この線引きの根底にあるのは、「AIの出力を信じる」のではなく「AIの出力を検証できる構造にする」という考え方です。検証手段がない作業ほど人が厚く見て、検証手段がある作業ほどAIに大きく任せられます。

PR運用と、Git履歴から見える実態

作業の基本の流れは次のとおりです。

① 依頼目的・対象・制約人② 作業ブランチブランチを切り変更Claude Code③ 機械チェックbuild/keihyo-checkスクリプト伝える変更exit 1なら直す合格④ PR変更点を箇条書きClaude Code⑤ 人がレビュー差分と見た目を確認人⑥ 自動公開Cloudflare Pages提出マージ
① 人が目的・対象ページ・制約を伝え、② Claude Codeがブランチを切って変更、③ build.js/keihyo-check.jsでチェックし、exit 1なら直してやり直します。④ 変更点を箇条書きにしたPRを、⑤ 人が差分と見た目を確認してマージすると、⑥ Cloudflare Pagesで自動公開されます。

build.jsは実行結果(フッターを流し込んだHTML)をそのままファイルに書き戻す方式なので、チェックを通った成果物がそのままコミットされ、配信されることになります。ビルドサーバー上でしか見えない生成物がないため、レビューで見た差分と本番の中身が一致します。

自社事例

Git履歴を実際に数えてみた(2026年9月時点)

  • mainブランチのコミットは25件(2026年9月20日のGit管理開始〜9月24日)
  • そのうち25件すべてに「Co-Authored-By: Claude …」のトレーラーが付いている。記録されたモデル名は時期によって異なる
  • 件名末尾にPR番号((#1)〜(#9))が付いたコミットが9件。マージコミットは0件で、PRの変更は1コミットにまとめて取り込まれている
  • 件名は「記事追加:〜」「内部リンク更新(週次メンテ):〜」「SEO改善:〜」のように種別:内容の形式で、本文に変更点の箇条書きが入る

コミットメッセージの本文には、変更したファイルごとの要点や「なぜそうしたか」が書かれています。AIに書かせると、人が書くよりコミットメッセージが丁寧になるのは、地味ですが運用上の大きな利点です。数か月後に「この変更はなぜ?」を追えるからです。

助手アイ
助手アイ「Co-Authored-By」が全部に付いているということは、人が一人で書いたコミットはゼロなんですね。履歴がそのまま「AIとの共同作業の記録」になっている……!

週次の内部リンクメンテナンス

記事が増えるほど、「新しい記事にどこからもリンクが張られていない(孤児ページ)」「リンク先が消えている(リンク切れ)」が起きやすくなります。本サイトでは週1回、AIエージェントに全ページを走査させて内部リンクを点検・補強しています。

2026年9月23日の週次メンテのコミットでは、次のような作業が記録されています。

  • ハブ記事(ガジェットまとめ)からカテゴリ別の子記事8本への導線を追加
  • 各ガジェット記事に、関連カテゴリの記事を2本ずつ相互リンク
  • モデル比較・各社モデル史の記事から、AIエージェントの基礎記事へのリンクを追加
  • 結果として、被リンクが1〜2本しかない記事が8件→0件、リンク切れ0・孤児ページ0を維持

このような「全ページを読んで、関係性を判断して、少しずつ手を入れる」作業は、人がやると後回しになりがちですが、AIエージェントには向いています。定期作業として手順を固定し、結果の数値(被リンク不足の件数など)をコミットメッセージに残させることで、次回との比較もしやすくなります。

AI検索(LLMO)対応:llms.txt・robots.txt・JSON-LD・sitemap

生成AIの回答や、AIを使った検索で参照されやすくするための取り組みをLLMO(Large Language Model Optimization)などと呼びます。確立した手法はまだ少ないため、本サイトでは「AIのクローラーがサイトを正しく理解できる材料を揃える」ことに絞っています。

ファイル・仕組み本サイトでやっていること
llms.txtサイトの概要・運営者・カテゴリ別の記事一覧(タイトル+URL+要約)をMarkdownで記述。AI向けのサイト案内として提案されている形式
robots.txt全体を許可したうえで、GPTBot・OAI-SearchBot・ClaudeBot・Claude-SearchBot・PerplexityBot・Google-Extended などのAIクローラーを明示的に許可
JSON-LD記事ページに BlogPosting・FAQPage・BreadcrumbList の構造化データ。FAQの質問・回答は本文と完全一致させる
sitemap.xml全ページのURLと最終更新日(lastmod)

llms.txtは2024年に提案された比較的新しい慣習で、どのAIサービスがどの程度参照しているかは公式に明らかでないものも多く、効果が保証されたものではありません。それでも、記事を追加するたびに一覧・サイトマップ・llms.txtを揃えて更新する作業は、AIエージェントに手順として任せれば負担がほぼないため、「やっておいて損はない」という判断で整備しています。

構造化データの「本文との不一致」に注意 FAQPageのJSON-LDを本文と別に書くと、本文だけ修正されて食い違う、ということが起こりがちです。本サイトでは執筆ルールとして「JSON-LDのFAQは本文のFAQと完全一致」を定め、AIエージェントへの指示に含めています。本来はこれもスクリプトで機械チェックするのが理想です。

秘密情報の扱い

静的サイトなので、本番で使うAPIキーはありません。それでも、運用の過程でトークンや認証ファイルが手元に置かれることはあります。.gitignore では次のように方針を明記しています。

.gitignore(抜粋)Git
# 機密情報(APIキー・トークン・環境変数はコミットしない)
.env
.env.*
*.key
*.pem
*.p12
credentials.json
secrets.json
  • コミットさせない:.env 系・鍵ファイル・認証JSONをパターンで除外。AIエージェントが git add . しても入らない

さらに一段進めるなら、AIエージェント自体に秘密情報を読ませない設定も有効です。後述のClaude Codeの permissions で .env の読み取りを禁止しておけば、「うっかりログやコミットメッセージにキーが混ざる」経路そのものを断てます。

運用で学んだこと

① 404ページは「どの階層でも表示される」

build.jsはページの階層に応じて相対パスでフッターを組み立てます。しかし404ページは、存在しない任意のURL(深い階層を含む)で表示されるため、相対パスのリンクが壊れるという特殊な事情があります。2026年9月24日に404ページを追加した際、404.htmlは絶対パスの独自フッターを持たせてbuild.jsの対象から外す(SKIP_FILES)判断をし、その理由をコード中のコメントに残しました。例外を作るときは、例外の理由をコードの隣に書く。次にAIエージェントがそのファイルを読んだとき、例外を「バグ」と誤解して直してしまうのを防げます。

② 手作業の修正は、その日のうちにチェック化する

前述のとおり、keihyo-check.jsは手作業で直した観点をそのままコード化したものです。build.jsの「旧PRバーが残っていたら止める」チェックも、表記の置き場所をフッターに移した際に、古い部品の消し忘れを検出するために入れたものです。一度直した問題の再発を、人の記憶ではなくスクリプトに覚えさせるのが、AIエージェント運用で最も効く習慣だと感じています。

Claude Codeに運用ルールを渡す:CLAUDE.md・permissions・hooks・Skills

ここまでの仕組みは、主に「スクリプト」と「Gitの運用」で成り立っています。Claude Codeには、こうした運用ルールをエージェント側に設定として持たせる機能があります。なお、本リポジトリには現時点でCLAUDE.mdも .claude/ ディレクトリもありません。以下は「こうしておくと良い」という提案として、一般的な使い方を紹介します(機能や設定形式は執筆時点(2026年9月)の情報です。最新は公式ドキュメントで確認してください)。

CLAUDE.md:リポジトリの「手順書」

プロジェクト直下に CLAUDE.md を置くと、Claude Codeが毎回読み込む「このリポジトリのルール・手順書」になります。/init コマンドで雛形を生成することもできます。本サイトなら、たとえば次のような内容が考えられます。

CLAUDE.md(提案例)Markdown
# AIエージェント研究所 運用ルール

## 構成
- HTML+CSSのみの静的サイト。1記事=1HTMLファイル
- フッターは partials/footer.html が正本。各HTMLのフッターを直接編集しない

## 記事を追加・変更したら必ず
1. node build.js を実行(exit 1 なら原因を直して再実行)
2. node keihyo-check.js を実行(HARDは必ず修正、WARNはPR本文で報告)
3. index.html / sitemap.xml / llms.txt に登録
4. JSON-LD の FAQPage は本文の FAQ と完全一致させる

## 禁止事項
- main への直接 push、強制 push
- .env や認証ファイルの読み取り・コミット

permissions:実行してよい操作を絞る

.claude/settings.json の permissions に allow/deny/ask を書くと、承認なしで実行させる操作と、禁止する操作を明示できます。

.claude/settings.json(提案例:permissions)JSON
{
  "permissions": {
    "allow": [
      "Bash(node build.js)",
      "Bash(node keihyo-check.js)",
      "Bash(git status)",
      "Bash(git diff:*)"
    ],
    "ask": [
      "Bash(git push:*)"
    ],
    "deny": [
      "Read(./.env)",
      "Read(./.env.*)",
      "Bash(git push --force:*)"
    ]
  }
}

検査スクリプトや差分確認のような読み取り・検証系は承認なし、pushのように外に影響する操作は確認つき、秘密情報の読み取りや強制pushは禁止、という3段階です。

hooks:ルールを「お願い」から「強制」に変える

hooks を使うと、PreToolUse(ツール実行前)・PostToolUse(実行後)・Stop(応答を終える時)などのイベントにシェルコマンドを登録できます。PreToolUseのフックが終了コード2で終わるとその操作はブロックされ、標準エラーに書いた理由がClaudeに返されます。

.claude/settings.json(提案例:hooks)JSON
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          { "type": "command", "command": "node .claude/hooks/guard-push.js" }
        ]
      }
    ]
  }
}
.claude/hooks/guard-push.js(提案例)JavaScript
// フックには、実行しようとしているツールの情報がJSONで標準入力から渡される
let input = '';
process.stdin.on('data', (c) => (input += c));
process.stdin.on('end', () => {
  const cmd = JSON.parse(input).tool_input?.command || '';
  // main への push はブロック(作業ブランチ→PRの流れを強制)
  if (/git\s+push\b.*\bmain\b/.test(cmd)) {
    console.error('main への直接 push は禁止です。作業ブランチに push して PR を作成してください。');
    process.exit(2); // 2 = ブロックして理由をClaudeに返す
  }
  process.exit(0);
});

ブロック時のメッセージを「次に何をすべきか」まで書くのは、build.jsのエラーメッセージと同じ発想です。同様に、Stopイベントに node build.js && node keihyo-check.js を登録しておけば、作業を終える前に必ずチェックが走るようにもできます。

エージェント博士
エージェント博士CLAUDE.mdは「お願い」、permissionsとhooksは「鍵」じゃ。大事なルールほど鍵で守る。さらにGitHub側でもmainの保護ルールを設定しておけば、エージェント側とサーバー側の二重の鍵になるぞ

Skills:定型業務を手順ごとパッケージ化

.claude/skills/<name>/SKILL.md に、フロントマター(name・description)付きで手順を書いておくと、Claudeが必要なときに読み込んで使います。「記事追加」「週次の内部リンクメンテ」「公開前チェック」のような繰り返し発生する業務に向いています。実際、keihyo-check.jsの冒頭コメントには「スキルの『検証→公開』ステップで build.js の後に実行する」と書かれており、公開前検証を手順として組み込む考え方で運用してきました。これをリポジトリ内の .claude/skills/ に置けば、チームの誰が(どのセッションが)作業しても同じ手順になります。

CIで回す:人の手順にも依存しない

最後の一手は、同じスクリプトをGitHub ActionsなどのCIでPRごとに実行し、失敗したらマージできないようにすることです。現状の本サイトは作業手順の中でスクリプトを実行する運用で、CIでの必須チェックはまだ入れていません。hooks・Skills・CIの三層にしておけば、「AIが手順を飛ばした」「人が急いでいた」といったケースでもガードレールが外れません。

他社サイトへの応用

この仕組みは、メディアサイト以外にもそのまま応用できます。共通点は「静的なページが中心」「変更をレビューしてから公開したい」「全ページに守るべきルールがある」ことです。

用途AIに任せやすい作業機械チェック(ガードレール)の例
技術ドキュメントサイト仕様変更に合わせた記述の更新、サンプルコードの修正リンク切れ検査、コード例の実行テスト、用語表記の統一チェック
LP(ランディングページ)文言差し替え、A/Bテスト用の派生ページ作成広告表記・注釈の有無、計測タグの有無、薬機法などNGワード検出
ヘルプセンター・FAQ問い合わせ傾向からのFAQ追加、古い手順の更新構造化データと本文の一致、廃止機能名の残存検出
コーポレートサイトお知らせ追加、採用ページ更新会社情報(住所・電話番号)の全ページ一致、個人情報の混入チェック

導入の順番としては、①Git管理とPR運用 → ②「全ページで必ず守ること」のチェックスクリプト化 → ③AIエージェントへの作業委任 → ④CLAUDE.md・permissions・hooksでのルール固定 → ⑤CIでの必須チェックがおすすめです。AIエージェントの導入を①より先にすると、「AIが何を変えたか分からない」状態で運用が始まってしまいます。

企業のAI活用方針としても、たとえばShopifyはCEOが社内メモでAI活用を前提とする方針を示したと公表しています(2025年)。一方で、AI活用を大きく打ち出した企業が、その後に人間の対応も重視する方向へ調整したと報じられた例もあります。「AIに任せる範囲」は一度決めて終わりではなく、検証手段の整備に合わせて広げていくものだと私たちは考えています。

当社は広告運用と生成AIエージェントの導入支援を本業としており、本サイトはその考え方を自分たちで試す場でもあります。広告の現場でClaude Codeと広告媒体のAPIをつなぐ設計については、Claude Code×広告媒体API連携入門で解説しています。

よくある質問

WordPressのサイトでも同じ運用はできる?

部分的には可能です。テーマやプラグインのコードはGitで管理できますが、記事本文や設定の多くはデータベースに入るため、AIエージェントの変更をGitの差分で全部レビューし、コミット単位で戻す、という運用はそのままでは成り立ちません。記事をMarkdownなどのファイルで管理するヘッドレスCMSや静的サイトジェネレーターに寄せるほど、本記事の設計に近づきます。

build.jsのような自動チェックは、GitHub Actionsで回すべき?

理想はCIでも回すことです。手元やエージェントの作業手順の中で実行するだけだと、手順を飛ばしたときに検出できません。プルリクエストごとにCIで同じスクリプトを実行し、失敗したらマージできないようにしておくと、ガードレールが人やAIの注意力に依存しなくなります。

AIエージェントにmainへ直接pushさせないためにはどうする?

GitHub側でmainブランチの保護ルールを設定し、プルリクエスト経由でしかマージできないようにするのが確実です。加えて、Claude Codeならpermissionsのdenyやhooksで、mainへのpushや強制pushのコマンドを実行前にブロックできます。サーバー側とエージェント側の二重で止めるのがおすすめです。

この仕組みに向いていないサイトは?

会員機能や決済、ユーザー投稿のように、データベースと動的な処理が中心のサイトには、そのまま当てはまりません。また、非エンジニアの編集者が毎日大量に記事を更新する体制では、Gitやプルリクエストの運用が負担になることもあります。静的なページが中心で、変更をレビューしてから公開したいサイトほど効果が出ます。

まとめ

  • 静的HTML+Gitは、AIエージェントが直接触れて、全変更をレビューでき、いつでも戻せる構成。代わりに重複や手動登録のコストを負う
  • build.jsは「正本の流し込み+表記漏れでexit 1」、keihyo-check.jsは「HARDで停止・WARNで表示」の2段階。どちらも過去の失敗をコードにしたもの
  • 線引きは「機械で正否判定できる作業はAI+スクリプト、価値判断と公開の決定は人」
  • Git履歴は、AIとの共同作業の記録そのもの。2026年9月時点でmainの全25コミットにCo-Authored-By: Claudeが付いている
  • 次の一手は、CLAUDE.md・permissions・hooks・Skills、そしてCIで、ルールを「お願い」から「仕組み」へ移すこと

AIエージェントに運用を任せるうえで大切なのは、優秀なAIを選ぶこと以上に、AIが間違えることを前提にした仕組みを先に作ることです。本記事の構成は小規模サイトのものですが、「正本・機械チェック・レビュー・ロールバック」の4点セットは、どんな規模のサイトにも持ち込めます。

業務自動化のスキルを、キャリアと収入につなげる

APIとAIエージェントで業務を自動化できる人材は、社内でも社外でも求められています。次の一歩に役立つ記事です。

AIライティングツールおすすめ比較【編集部評価】SEO記事の作成をツールで効率化するなら
記事を読む

次の一歩

姉妹サイトの記事で、次に気になりやすいことを調べられます。