blue-team について
blue-teamは、red-teamの検証結果やCIテストレポートにある具体的な失敗を修正する防御用スキルです。根本原因の分類ごとにパッチを適用し、失敗が減り回帰がない場合だけ変更を保持します。
主な機能
- 01red-teamまたはJUnitの失敗を取り込み
- 02根本原因の分類ごとにケースを整理
- 03回帰ガードで修正を検証
- 04パッチを個別に保持または破棄
- 05残存失敗と反復予算を追跡
- 06プルリクエスト用の引き継ぎを準備
活用シーン
- 01red-team検証で見つかった問題を修正
- 02CIで失敗したテスト群を解消
- 03フィルターを強化し、新たな誤検知を確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ gaasher/ agent-loop-skills --skill blue-teamインストール後、Claude Code で/blue-teamを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
examples/run.example.yamltests.run.yamltools/ingest.pyverify.py詳細
Blue Team
red-team の逆となる、防御的な修正ループです。成果物は対象となり、今度は書き込み可能です。フィードバック信号は optimize-loop と同様に 2 つあり、維持すべきゲート(以前に合格したものが何も悪化しないこと)と、減らすべきメトリクス(未解決の失敗クラスの数をゼロに近づけること)です。具体的な失敗ケースのセットを指定し、根本原因のクラスを 1 つずつ修正します。各イテレーションで 1 つのクラスにパッチを適用し、tools/verify.py を実行します。リグレッションなしでクラスを解消できた場合にのみパッチを維持し、それ以外の場合は元に戻します。すべてのクラスが解消する(dry)か、予算を使い切るまでループし、その後、パッチ一式をプルリクエストとして引き渡します。これは find→fix セットアップの fix 側です(ペアリングを参照)。
失敗ケースは実際のソースから取得します。tools/ingest.py は、どのソースも 1 つのカタログに正規化します。
oracleモード —red-teamのfailures.jsonl:各ケースは、対象の判定が正解となるオラクルと一致しない入力です。対象とオラクルが一致すると、ケースは解消です。リグレッションとは、新たに判定が一致しなくなった、無害な<holdout>入力のことです(多くの場合、新たな過剰ブロックです)。testsモード — CI/CD のテスト失敗レポート(pytest --junitxml/ JUnit XML、または失敗したノード ID のリスト):各ケースは失敗したテストです。そのテストが合格すると、ケースは解消です。リグレッションとは、以前は合格していた別のテストが新たに失敗することです。
使用する場面
ユーザーが所有するコードやガードレール/分類器/フィルター/プロンプト/APIで、具体的な失敗ケース一式を修正する際に使用します。対象は、red-team のカタログ、または CI 実行で失敗したテストです。これまで機能していたものを壊さずに、未解決クラスの数をゼロにします。class とは、このループで一括して解消する根本原因のグループです(red-team の手法、または CI の失敗領域/テストクラス)。
デフォルトでは、ソースに合ったモードを選択します(red-team には oracle、CI/CD には tests)。例外として、別個の機能テストスイートがない oracle モードでは、<holdout> のみをリグレッションガードとして使用します。tests モードでは、テストスイート内の、以前は合格していたテストがガードになります。新たな失敗の発見には使用しません(red-team を実行してください)。また、正解データ(オラクル、テスト、または holdout)の編集にも使用しません。
セットアップ
バインディングを対話形式で解決します。loop.run.yaml が存在する場合は読み込み、値を1行で確認してからループに進みます。存在しない場合は、Claude Code(AskUserQuestion ツールを利用可能)では各バインディングの値として有力な候補を推測し、推奨します。それ以外のホストでは、それぞれを引用符で囲んだプロンプトとして尋ねます。その後、loop.run.yaml を書き込み、ほかのファイルを作成する前に確認します。設定例は次の2つです。
examples/run.example.yaml(オラクルモード)と examples/tests.run.yaml(テストモード)。
| binding | 意味 | デフォルト | 推測方法 |
|---|---|---|---|
<source> | 失敗ケースの取得元:oracle(レッドチーム)または tests(CI/CD) | — | レッドチームの failures.jsonl → oracle、失敗した pytest/JUnit → tests |
<target_files> | ループが対象を修正するために編集できるファイル | — | 失敗の背後にあるソース/ガードレール/分類器 |
<catalogue> | 解消する失敗ケースの JSONL。tools/ingest.py で構築します(下記参照) | <sandbox_root>/catalogue.jsonl | レッドチームの <failures_log>、または JUnit レポート |
<oracle_cmd> | (オラクルモード) 正解の判定(固定)。レッドチームと同じ stdin→判定の契約 | — | 参照チェッカー/ポリシー実装 |
<holdout> | (オラクルモード) 合格し続ける必要のある正常な入力(回帰ガード) | <sandbox_root>/holdout.jsonl | オラクルが正しいと認める既知の正常な入力 |
<test_cmd> | (テストモード) テストスイートを実行し、JUnit XML を書き出します。回帰はそこから読み取ります | — | pytest --junitxml=<junit>(または JUnit を出力する任意のランナー) |
<junit> | (テストモード) <test_cmd> が書き出す JUnit XML のパス | <sandbox_root>/junit.xml | — |
<iter_strategy> | branches(採用した修正ごとにコミットし、PR に反映)または snapshots(反復ごとにフォルダーを作成) | branches | 変更が残っているツリー/Git 管理されていないツリー → snapshots |
<pr_branch> | 修正が反映され、PR の起点となるブランチ | blue-team/<tag> | <tag> には今日の日付を指定 |
<sandbox_root> | スナップショットと台帳の保存場所 | ./sandbox | — |
<budget> | 最大反復回数 | 8 | — |
<patience> | 1つのクラスで N 回失敗したら打ち切り、残課題として記録します | 3 | — |
<skill_dir> はこのスキルがインストールされているフォルダーです。loop.run.yaml を書き込む際は、実際のパスに置き換えてください。
まず tools/ingest.py でカタログを構築します。これにより、あらゆるソースが {id, ..., class} に正規化されます。
python3 <skill_dir>/tools/ingest.py --from red-team --in <failures.jsonl> --out <catalogue> # oracle mode
python3 <skill_dir>/tools/ingest.py --from junit --in <report.xml> --out <catalogue> # tests mode
各反復のシグナルは tools/verify.py です。<source> に一致するモードを使います。
# oracle mode — <target_cmd> runs <target_files>, e.g. "python3 ./guardrail.py"
python3 <skill_dir>/tools/verify.py --target "<target_cmd>" --oracle "<oracle_cmd>" \
--catalogue <catalogue> --holdout <holdout>
# tests mode — <test_cmd> writes the JUnit report verify.py then reads
python3 <skill_dir>/tools/verify.py --test-cmd "<test_cmd>" --junit <junit> --catalogue <catalogue>
どちらのモードでも、次の JSON オブジェクトが出力されます。
{mode, open_classes, closed_classes, open_count, closed_count, regressions, regression_count, still_failing}。
ループ
このチェックリストをコピーして、項目にチェックを入れてください。
- Iteration 0 — ベースライン:
<source>モードでtools/verify.pyを実行し、カタログと一致するはずの 未解決クラス を現状として記録し、regression_countが 0 であることを確認します。そうでない場合、カタログまたはホールドアウトに問題があるため、対象を修正する前に解決してください。ベースラインの行を記録します。<target_files>の未変更のコピーを<sandbox_root>/iter0/に保存する(snapshots モード)か、ブランチのベースを記録します(branches モード)。これが最終的な引き継ぎで差分を取る ベースライン であり、Iteration 1 の復元先となるスナップショットでもあります。 -
branchesモードでは、新しいブランチで実行を開始します:git checkout -b <pr_branch>。 - Iteration N(≥1)では、編集する前に、パッチ適用前の現在の
<target_files>をiter<N>/にスナップショットする(または git HEAD を記録する)ことで、破棄時にこの状態を正確に復元できるようにします。 - 未解決クラスを 1 つ選びます。カタログにあるそのクラスの
still_failingの例と推奨される修正を読み、<target_files>の根本原因を修正します。1 つの修正で、そのクラスのペイロードをすべて解決できるようにします(例:キーワードごとではなく、一度だけ大文字・小文字を正規化します)。変更の差分を個別に特定できるよう、1 回のイテレーションにつき 1 クラスとします。 - 結果を確認します:
tools/verify.pyを実行します。regression_count > 0(ゲート)または対象クラスが未解決のままなら、破棄してスナップショットを復元するか、git reset --hardを実行します。verify.pyの回帰チェックがゲートです。oracle モードでは、回帰とは新たに失敗した<holdout>ケースです(例:無害な入力まで過剰にブロックし、バイパスを解決する修正)。tests モードでは、パッチによって、それまで成功していたテストが失敗することです。 - 回帰がなく、
open_countが厳密に減少した場合は保持します。branchesモードではコミットします:git commit -am "close <class>: <one-line fix>"。台帳に行を追加します。 -
<patience>回試しても解決できないクラスは、試行錯誤を続けるのではなく、未解決の残件として記録して次に進みます。open_count= 0(dry)になったとき、<budget>に達したとき、または残りのすべてのクラスが未解決の残件になったときに停止します。<budget>が数えるのはクラスの解決数ではなく試行回数です(保持または破棄のいずれも 1 回のイテレーションです)。破棄しても予算を消費します。
停止時には、作業ファイルを最善のイテレーション(解決したクラスが最も多く、回帰が 0)に戻し、解決したクラスと未解決の残件、解決した失敗(oracle モードではバイパスと過剰ブロックの内訳)、回避した回帰を報告します。その後、プルリクエストを作成します(引き継ぎを参照)。
修正ツールキット。 tests モードでは、パッチは通常のバグ修正であり、失敗の領域ごとにまとめ、1 回のイテレーションにつき 1 領域に適用します。oracle モード(ガードレール/フィルターの強化)では、レッドチームの攻撃ツールキットにならい、次の根本原因パターンを活用します:
- 照合前に正規化する — 大文字・小文字を統一し、デリート(ホモグリフ/リート表記を文字に変換)し、空白と句読点を削除し、Unicode を NFKC 正規化します。正規化を 1 ステップ行うことで、大文字・小文字、リート表記、空白の各クラスを解決できます。
- ポリシーを拡張する — ブロック対象に不足している同義語/展開形を追加します(
missing-synonymクラス)。場当たり的な文字列ではなく、オラクルのカテゴリに基づいて指定します。 - 広すぎるルールを絞り込む — 単語全体や適切なコンテキストに照合範囲を限定し、無害な入力が誤検出されないようにします(
overblockクラス)。これは回帰の最も一般的な原因です。
適用順序に注意してください(両モード共通):範囲を絞る修正や過剰ブロックへの修正を、広範囲に及ぶ修正より先に行います。区切り文字を削除する修正(spacing を解決する修正)によって、無害な入力が再び広すぎる部分文字列と一致し、overblock クラスが気付かないうちに再発することがあります。同様に、広範囲に及ぶコード変更によって、より限定的な修正で保護していたテストが再び失敗することもあります。まず範囲が狭いケースや過剰ブロックのケースを修正し、その後に一般化してください。
Ledger
<sandbox_root>/ledger.tsv、タブ区切り。説明にはカンマを使用しないでください。regr = regression_count
このイテレーションの回帰数(ゲート:0なら問題なし)。status ∈ {keep,discard,baseline,residual}。ヘッダー
iter class_targeted regr open_classes status description:
iter class_targeted regr open_classes status description
0 - 0 5 baseline catalogue: 5 open classes
1 case-bypass 0 4 keep case-fold the input before matching
2 leetspeak 1 4 discard de-leet regex also over-blocked a holdout input (regression)
3 leetspeak 0 3 keep de-leet via translate table, holdout clean
4 missing-synonym 0 2 keep add passphrase/credentials/api-key to the policy set
5 overblock 0 1 keep require whole-word "secret key", not bare "secret"
6 spacing 0 0 keep strip non-alphanumerics before matching — dry
最後のイテレーションとは限らず、最良のイテレーション(regr が 0 で open_classes が最も少ないもの)を報告してください。
制約
<target_files>だけを編集してください。 正解データであるオラクルと<holdout>(オラクルモードの場合)、またはテストスイート(テストモードの場合)、そしてtools/verify.pyは変更できません。修正を評価するものを編集して合格を作り出すことは、レッドチームや最適化ループの場合と同じく禁止です。オラクルやテスト自体に誤りがある場合は、ここで修正するのではなく、報告すべき問題として指摘してください。- ペイロードではなく、根本原因を修正してください。 1つの修正で、あるクラスのすべての項目を解決する必要があります。同種の項目が失敗したまま、単一のサンプル文字列だけを修正しても、そのクラスは解決済みではありません。これはレッドチームのクラス単位の計上方法に合わせたものであり、2つのループで「解決済み」の定義が一致します。
- 回帰ゲートは必ず守ってください。 以前は通過していたものを壊すパッチ(オラクルモードで新たな過剰ブロックやバイパスが発生する、またはテストモードで以前通過していたテストが失敗する)は、進展ではなく回帰です。どれだけ多くのクラスを解決できても、必ず元に戻してください。広範囲に及ぶ修正より、対象を絞った修正を優先してください。
- 1回のイテレーションにつき1クラスとし、各差分の原因を特定できるようにしてください。修正が悪かった場合も、簡単に元に戻せます。
- 変更はプロジェクトの既存の依存関係の範囲内にとどめてください(標準ライブラリは使用可能です)。リポジトリと
<sandbox_root>の外に出ないでください。続行するかどうかを尋ねてループを中断せず、調査対象がなくなるか、予算上限に達するか、残余項目が残るまで実行してください。
引き継ぎ:プルリクエスト
成果物は、人がレビューできるプルリクエストです。これは対象の担当者との連絡窓口です(Copilot Autofix と同様、最終承認は人が行います)。停止時には、作業ツリーを最良のイテレーションの状態にしたうえで、次の作業を行ってください。
branchesモードでは、採用した各修正はすでに<pr_branch>上のコミットになっており、コミットメッセージにはクラス名と1行の修正内容が記されています。gh pr createでプッシュしてプルリクエストを作成し、本文には台帳(カタログから修正内容、解決したクラス、残余項目、回避した回帰)と、解決した各クラスにつき再現可能な例を1つ記載してください。- プルリクエストを作成する前に、必ず一度確認してください。 ブランチのプッシュとプルリクエストの作成は外部に公開される操作です。確認なしに自動でプッシュしてはいけません。
- 失敗させず、代替手段に切り替えてください。 リモートがない場合や、
ghが利用できない場合、または認証されていない場合でも、引き継ぎ資料を作成してください。コミットは<pr_branch>に残し、git format-patchの出力とPR_BODY.mdを<sandbox_root>に書き込み、ユーザー自身がプルリクエストを作成するためのコマンドを1つ伝えてください。snapshotsモード(Git なし)の場合は、代わりに<target_files>とiter0/のベースラインコピーとの差分を統合 diff 形式で出力し、PR_BODY.mdも作成してください。
ペアリング
このスキルは修正担当であり、検出から修正までのループの後半を担います。すでにカタログがあることを前提とし、単独ではクラスを解決しますが、新たなクラスは探しません。
- 検出 —
red-teamが変更不能な対象に対して実行され、個別クラスを記録したfailures.jsonlが生成されます。 - 修正(このループ)— red-team の実行と実行の間に、ゲートを通過する形で対象にパッチを適用し、各クラスを解決します。実行中に修正を行ってはいけません。
- 再検証 — パッチ適用後の対象に対して新たに
red-teamを実行し、各クラスが解決されたことを確認するとともに、修正によって新たなクラスが生じていないかを明らかにします(このループ内では、回帰ゲートによって過剰ブロックの方向の問題はすでに防止されます)。
2つのエージェントは独立させてください。カタログを作成した攻撃側エージェントが、自分のパッチを評価してはいけません。
purple-team ループは、検出 → 修正 → 再検証のサイクル全体を、新たな検出で問題が見つからなくなるまで調整します。このスキルが対象とするのは、修正フェーズのみです。