AGENTS.md CI/CD GitHub Actions DevOps 自動化 Claude Code pre-commit 2026

AGENTS.mdをCI/CDに組み込む:自動差分レビュー・検証・ドリフト検知の実践

The Prompt Shelf ·

AGENTS.mdには、ほとんどの設定ファイルには起きない特有の障害モードがある:何も壊さずに陳腐化するのだ。package.jsonが間違っていればビルドが失敗する。AGENTS.mdが陳腐化してもAIエージェントが古い前提で動き続けるだけで——エージェントが古いテストコマンドを使い続けたり、触らないはずのファイルに手を出したりするまで、誰も気づかない。

CI/CDはこれを解決する適切な場所だ。すべてのプッシュでAGENTS.mdをリンターに通す必要があるわけではないが、ドリフトを検知する場所としてCIは最適だ:pnpm-lock.yamlが変更されたとき、AGENTS.mdのインストールコマンドは更新されたか?新しい保護対象ディレクトリが追加されたとき、そこに記載はあるか?テストランナーがJestからVitestに変わったとき、AGENTS.mdは追いついているか?

このガイドでは、AGENTS.mdを実際のコードベースと同期し続けるためのGitHub Actionsワークフロー、Pre-commitフック、軽量なレビューボット設定を解説する。

核心的な問題:設定ファイルは変わるがAGENTS.mdは変わらない

実際のドリフトパターンはこうだ。チームが2スプリントでJestからVitestへ移行する。誰かがpackage.jsonvitest.config.ts、全テストファイルを更新する。PRはCIを通過する。しかしAGENTS.mdには依然としてnpx jest --testPathPattern=と書いてあり、AIエージェントはその誤った情報を受け継ぐ。

修正策は、重要な設定ファイルが変更されたときにAGENTS.mdも更新されているか確認するCIチェックだ。AGENTS.mdの内容を検証するのではなく、更新が必要そうなときに検知する。

GitHub Actions:ドリフト検知

最も役立つチェックは驚くほど単純だ。PRがウォッチリスト上のファイルを変更するとき、AGENTS.mdも更新されているか確認する。されていなければ、著者にAGENTS.mdの更新か更新不要の確認コメントを求める。

# .github/workflows/agents-md-check.yml
name: AGENTS.md ドリフトチェック

on:
  pull_request:
    types: [opened, synchronize, reopened]

jobs:
  agents-md-drift:
    runs-on: ubuntu-latest
    permissions:
      pull-requests: write
      contents: read

    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: ドリフトを引き起こす変更をチェック
        id: drift-check
        run: |
          BASE=${{ github.event.pull_request.base.sha }}
          HEAD=${{ github.event.pull_request.head.sha }}

          # 変更時にAGENTS.mdのレビューをトリガーすべきファイル
          WATCHED_PATTERNS=(
            "package.json"
            "pnpm-lock.yaml"
            "package-lock.json"
            "yarn.lock"
            "Makefile"
            "*.config.ts"
            "*.config.js"
            "docker-compose*.yml"
            ".env.example"
            ".env.ci"
          )

          PATTERN=$(IFS="|"; echo "${WATCHED_PATTERNS[*]}")
          
          CHANGED=$(git diff --name-only "$BASE" "$HEAD")
          AGENTS_CHANGED=$(echo "$CHANGED" | grep -c "AGENTS.md" || true)
          CONFIG_CHANGED=$(echo "$CHANGED" | grep -E "$PATTERN" | grep -v "node_modules" || true)

          if [ -n "$CONFIG_CHANGED" ] && [ "$AGENTS_CHANGED" -eq 0 ]; then
            echo "drift_detected=true" >> $GITHUB_OUTPUT
            echo "changed_files<<EOF" >> $GITHUB_OUTPUT
            echo "$CONFIG_CHANGED" >> $GITHUB_OUTPUT
            echo "EOF" >> $GITHUB_OUTPUT
          else
            echo "drift_detected=false" >> $GITHUB_OUTPUT
          fi

      - name: ドリフト検知時にPRにコメント
        if: steps.drift-check.outputs.drift_detected == 'true'
        uses: actions/github-script@v7
        with:
          script: |
            const changedFiles = `${{ steps.drift-check.outputs.changed_files }}`;
            
            await github.rest.issues.createComment({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: context.issue.number,
              body: `## AGENTS.mdのレビューが必要です
            
            このPRで以下の設定ファイルが変更されましたが、\`AGENTS.md\`は更新されていません:
            
            \`\`\`
            ${changedFiles}
            \`\`\`
            
            **要対応:** 変更されたコマンド・パス・規則を反映するよう\`AGENTS.md\`を更新するか、更新が不要な理由をコメントに記載してください。`
            });

これはハードな失敗ではなくコメントによる促しを提供する——AGENTS.mdには適切な判断だ。設定ファイルとAGENTS.mdの内容の関係は構文的ではなく意味的であり、更新が必要かどうかは人間が判断する必要があるからだ。

Pre-commitフック:構文と構造の検証

構造検証には、素早く動作して大きな声で失敗するPre-commitフックが、CIより役立つ。コミットが入る前にAGENTS.mdに期待されるセクションがあるかチェックする:

#!/bin/bash
# .git/hooks/pre-commit(またはpre-commitフレームワーク経由)
# scripts/validate-agents-md.sh としても利用可能

set -e

AGENTS_FILE="AGENTS.md"

if [ ! -f "$AGENTS_FILE" ]; then
  echo "エラー: リポジトリルートにAGENTS.mdが見つかりません"
  exit 1
fi

# 必須セクションのチェック
REQUIRED_SECTIONS=(
  "## Commands"
  "## Code Style"
)

MISSING=()
for section in "${REQUIRED_SECTIONS[@]}"; do
  if ! grep -q "^${section}$" "$AGENTS_FILE"; then
    MISSING+=("$section")
  fi
done

if [ ${#MISSING[@]} -gt 0 ]; then
  echo "エラー: AGENTS.mdに必須セクションがありません:"
  printf '  %s\n' "${MISSING[@]}"
  echo ""
  echo "これらのセクションを追加するか、.git/hooks/pre-commitのREQUIRED_SECTIONSを更新してください"
  exit 1
fi

# 明らかな陳腐化マーカーをチェック
STALE_PATTERNS=(
  "npm install"   # pnpmを使っている場合
  "yarn add"      # pnpmを使っている場合
  "TODO:"
  "FIXME:"
)

for pattern in "${STALE_PATTERNS[@]}"; do
  if grep -qi "$pattern" "$AGENTS_FILE"; then
    echo "警告: AGENTS.mdに陳腐化している可能性のある内容: '$pattern'"
    echo "コミット前にレビューして更新または削除してください。"
    # 警告のみ——これではコミットをブロックしない
  fi
done

echo "AGENTS.mdの検証を通過しました"
exit 0

pre-commitフレームワーク(生フックよりも管理しやすい)で使う場合:

# .pre-commit-config.yaml
repos:
  - repo: local
    hooks:
      - id: agents-md-validate
        name: AGENTS.md構造を検証
        entry: scripts/validate-agents-md.sh
        language: script
        files: AGENTS.md
        pass_filenames: false

CI:コマンドの実際動作を検証

最も信頼できるAGENTS.mdチェックは、最もシンプルでもある:実際に正しいと主張しているコマンドを実行する。

# .github/workflows/verify-agents-md-commands.yml
name: AGENTS.mdコマンドを検証

on:
  push:
    paths:
      - 'AGENTS.md'
  schedule:
    - cron: '0 6 * * 1'  # 毎週月曜——他のマージによるドリフトを検知

jobs:
  verify-commands:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: pnpm/action-setup@v4
        with:
          version: 9

      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'pnpm'

      - name: AGENTS.mdからビルドコマンドを解析して検証
        run: |
          # AGENTS.mdからビルドコマンドを抽出
          BUILD_CMD=$(grep -A1 "^\- \*\*Build\*\*:" AGENTS.md | head -1 | sed 's/.*`\(.*\)`.*/\1/')
          
          if [ -z "$BUILD_CMD" ]; then
            echo "AGENTS.mdからビルドコマンドを解析できませんでした"
            exit 1
          fi
          
          echo "AGENTS.mdのビルドコマンドをテスト: $BUILD_CMD"
          pnpm install --frozen-lockfile
          eval "$BUILD_CMD"

      - name: AGENTS.mdからテストコマンドを解析して検証
        run: |
          TEST_CMD=$(grep -A1 "^\- \*\*Test\*\*:" AGENTS.md | head -1 | sed 's/.*`\(.*\)`.*/\1/')
          
          if [ -z "$TEST_CMD" ]; then
            echo "AGENTS.mdからテストコマンドを解析できませんでした"
            exit 1
          fi
          
          echo "AGENTS.mdのテストコマンドをテスト: $TEST_CMD"
          eval "$TEST_CMD"

このアプローチは、AGENTS.mdのコマンドを一貫したフォーマット(- **Build**: `cmd`)で記載することを前提とするが、それ自体は良いプラクティスだ。週次スケジュールは、コードベースが変更されたが同じPRではAGENTS.mdが更新されなかったケースを検知する。

保護パスの検証

AGENTS.mdがエージェントが触ってはいけないディレクトリを列挙しているなら、それらのパスが実際に存在するか検証する:

#!/bin/bash
# scripts/verify-agents-md-paths.sh

AGENTS_FILE="AGENTS.md"

# "Never modify"や"Do not touch"パターンの行からパスを抽出
PROTECTED_PATHS=$(grep -oE '`[^`]+/[^`]+`' "$AGENTS_FILE" | tr -d '`' | grep "/" | sort -u)

MISSING_PATHS=()
for path in $PROTECTED_PATHS; do
  # コマンドパターンに見える場合はスキップ
  if [[ "$path" == *"$"* ]] || [[ "$path" == *"*"* ]]; then
    continue
  fi
  
  if [ ! -e "$path" ]; then
    MISSING_PATHS+=("$path")
  fi
done

if [ ${#MISSING_PATHS[@]} -gt 0 ]; then
  echo "警告: AGENTS.mdが存在しないパスを参照しています:"
  printf '  %s\n' "${MISSING_PATHS[@]}"
  echo ""
  echo "これらは陳腐化した参照かもしれません。AGENTS.mdを確認して削除または更新してください。"
  exit 1
fi

echo "AGENTS.mdで参照されているすべてのパスが存在します。"

スケジュールレビュー:週次の鮮度チェック

PRタイムのチェックに加え、週次のスケジュールワークフローでコマンド検証を実行すると、複数の小さいPRが蓄積することで生じるドリフトを検知できる。個々のPRは設定ファイル1つしか変更せず、AGENTS.mdの更新が不要に見える。しかし4つのPRの後、ドキュメントは明らかに間違いだらけになっている。

# .github/workflows/agents-md-weekly-review.yml
name: AGENTS.md週次ヘルスチェック

on:
  schedule:
    - cron: '0 9 * * 1'  # 月曜9時UTC
  workflow_dispatch:

jobs:
  health-check:
    runs-on: ubuntu-latest
    permissions:
      issues: write
      contents: read

    steps:
      - uses: actions/checkout@v4

      - name: AGENTS.md完全検証を実行
        id: verify
        run: |
          bash scripts/validate-agents-md.sh 2>&1 | tee verify-output.txt
          echo "exit_code=$?" >> $GITHUB_OUTPUT

      - name: 検証失敗時にイシューを作成
        if: steps.verify.outputs.exit_code != '0'
        uses: actions/github-script@v7
        with:
          script: |
            const output = require('fs').readFileSync('verify-output.txt', 'utf8');
            
            // 同件のイシューが既に開いているか確認
            const issues = await github.rest.issues.listForRepo({
              owner: context.repo.owner,
              repo: context.repo.repo,
              state: 'open',
              labels: 'agents-md-stale'
            });
            
            if (issues.data.length > 0) {
              console.log('陳腐化AGENTS.mdのイシューは既に開いています');
              return;
            }
            
            await github.rest.issues.create({
              owner: context.repo.owner,
              repo: context.repo.repo,
              title: 'AGENTS.mdが陳腐化している可能性——週次チェックが失敗',
              body: `週次のAGENTS.mdヘルスチェックが失敗しました。\n\n\`\`\`\n${output}\n\`\`\`\n\nAGENTS.mdを確認して必要に応じて更新してください。`,
              labels: ['agents-md-stale', 'maintenance']
            });

自動化すべきことの判断

AGENTS.mdメンテナンスのすべてを自動化すべきではない。判断表:

チェック自動化すべきかアプローチ
必須セクションが存在するかYesPre-commitフック
コマンドが実際に動作するかYesCIワークフロー(AGENTS.mdプッシュ時 + 週次)
設定のドリフトが検知されるかYesPRコメントボット
参照パスが存在するかYesCIスクリプト
内容が正確で完全かNo設定PRでの人間によるレビュー
AIエージェントにとって有益なコンテキストかNo開発者の判断

自動化は機械的な正確さを担当する。コンテンツ品質は依然として人間の仕事だ。目標は「AGENTS.mdの更新を忘れた」という障害モードを排除すること——ファイルに何を書くべきかの判断を置き換えることではない。


関連記事

Related Articles

Explore the collection

Browse all AI coding rules — CLAUDE.md, .cursorrules, AGENTS.md, and more.

Browse Rules