自己修復 (自己修正ルールエンジン)
ユーザーの修正、プロジェクトの慣習、バグ修正を永続的なルールセットファイル (autofix.json) に記録する、自己修正型のメモリおよび学習エンジンです。これにより、エージェントは継続的に適応し、セッションをまたいだ同じミスの繰り返しを排除し、ユーザーの好みに厳密に従います。
なぜ機能するのか: AIエージェントは、セッションが新しくなるたびに同じデフォルトの仮定やスタイル上のエラーを繰り返す傾向があります。学習した知識を、厳密な優先順位(新しいルールが優先)を持つ命令的なバージョン管理されたJSONルールセットに外部化することで、エージェントは特定のユーザーとリポジトリに合わせたハードな境界を保持できます。
ストレージと設定
スキルは、以下の場所からルールセットファイルを検索します(優先順位順):
.agents/autofix.jsonautofix.json(ワークスペースルート).rules/autofix.json
新しいルールを追加する必要がある時点でこれらのファイルが存在しない場合、.agents/autofix.json(またはプロジェクトの慣習に応じてルートの autofix.json)を作成します。
ルールスキーマ
各ルールは、以下のスキーマを持つJSON配列内に格納されます:
[
{
"Rule_number": 1,
"Category": "CODE",
"Instruction": "Reactコンポーネントにはデフォルトエクスポートを使用せず、常に名前付きエクスポートを使用してください。",
"Why": "コードベースの一貫性を確保し、リファクタリングを容易にします。"
}
]
許可されているカテゴリ
| カテゴリ | 説明 | 例 |
|---|---|---|
[STYLE] | コードのフォーマット、命名規則、インポート順序、コメント | 「ヘルパー関数には常にキャメルケースを使用する」 |
[CODE] | 言語パターン、ライブラリの選択、型定義、エラーハンドリング | 「TypeScriptでanyを決して使用しない。型ガード付きのunknownを使用する」 |
[ARCH] | ディレクトリ構造、モジュール境界、アーキテクチャ層 | 「APIルートはsrc/api/ではなくsrc/server/routes/に配置する」 |
[TOOL] | CLIコマンド、ビルドツール、パッケージマネージャー、テストフレームワーク | 「npmやyarnではなく常にpnpmを使用する」 |
[PROCESS] | Gitワークフロー、コミットメッセージ、PR要件、テストゲート | 「コミットメッセージに絵文字を決して追加しない」 |
[DATA] | データベーススキーマ、マイグレーション、キャッシュ戦略、状態の形状 | 「テーブルには常にcreated_atとupdated_atタイムスタンプを含める」 |
[UX] | UIの動作、コピーの慣習、アクセシビリティ標準 | 「アイコンのみのボタンには常に明示的なaria-labelを提供する」 |
[OTHER] | 一般的なプロジェクトまたはドメイン固有の設定 | 「公開APIエンドポイントは常にマークダウンテーブル形式で文書化する」 |
操作ワークフロー
[セッション開始 / タスク受信]
│
▼
┌───────────────────────────────┐
│ 1. タスク前スキャン │ ◄── autofix.json を読み込む
│ - すべてのルールをロード │
│ - 競合を解決 (新しい>古い)
│ - アクティブな制約を構築 │
└───────────┬───────────────────┘
│
▼
┌───────────────────────────────┐
│ 2. タスク実行 │
│ - 制約を適用 │
│ - コード/編集を実行 │
└───────────┬───────────────────┘
│
├─────────────────────────────────────────┐
│ │
[修正なし] [トリガー検出]
│ │
▼ ▼
┌───────────────────────────────┐ ┌───────────────────────────────┐
│ タスク完了 │ │ 3. 自己修復とキャプチャ │
│ 出力をユーザーに提供 │ │ - 命令的なルールを策定│
└───────────────────────────────┘ │ - autofix.json に追加 │
│ - 学習したことを通知 │
└─────────────┬─────────────────┘
│
▼
┌───────────────────────────────┐
│ 4. 再実行と修正 │
│ 現在のタスク出力を修正 │
└───────────────────────────────┘
詳細なステップバイステップの実行
1. タスク前スキャン (何かをする前に行う)
タスクの計画やファイルの変更を行う前に、以下を実行します:
autofix.jsonを見つけてロードします。- ルールをスキャンします:
- 現在のプロンプトに関係するファイル、ツール、またはパターンに直接適用されるルールがないか確認します。
- 競合を解決します:
- 2つのルールが相反する指示を与える場合、番号が大きい(新しい)ルールが優先されます。
- 制約をアクティブに保持します:
- すべてのアクティブなルールをハード制約(プロンプトコントラクトの
CONSTRAINTSと同等)として扱います。
- すべてのアクティブなルールをハード制約(プロンプトコントラクトの
2. ルールを追加するタイミング (トリガー条件)
以下のいずれかが発生した場合、直ちにルールのキャプチャをトリガーします:
- ユーザーが明示的に出力を修正: 例: "いいえ、Xは使わないで、Yでやってください"、"ここではクラスコンポーネントを使いません"。
- ユーザーがファイル、アプローチ、パターンを拒否: 例: "テストファイルをソースコードの隣に置かないでください"。
- ユーザーが個人またはチームの好みを表明: 例: "コミットメッセージは常にConventional Commits形式にしてください"、"ドキュメントに絵文字は使わないでください"。
- 間違った仮定が原因でバグが発生: エージェントがライブラリやファイルの場所を誤って想定し、それが原因で障害が発生しました。
- ユーザーが
/learnを実行するか、ルールを記憶するように要求する。
3. 新しいルールの追加
トリガーが発生した場合、以下のアトミックな更新を実行します:
- 既存の
autofix.json配列を読み取ります。 - 次の連続した
Rule_numberを決定します:- 既存の最大ルール番号が $N$ の場合、新しいルールは $N + 1$ です。
- ファイルが空または新規の場合、
1から開始します。
- 新しいルールオブジェクトをフォーマットします:
- Rule_number: 連続した整数。
- Category: 標準カテゴリ(
STYLE,CODE,ARCH,TOOL,PROCESS,DATA,UX,OTHER)のいずれか。 - Instruction: 厳密な命令形式で記述:
"絶対にXをする/しない - なぜならYだからです。" - Why: 簡単な理由(例: "ユーザーの好み", "コードベースのパターン", "フレームワークの制限")。
- ルールをJSON配列に追加し、2スペースインデントでフォーマットしてファイルを保存します。
- 既存のルールを決して削除しないでください。古いルールが新しいルールに取って代わられる場合、新しいルールの番号が大きくなるように記述して優先させます。
- ユーザーに簡単に通知します:
"ルール #
<N>([CATEGORY]) を学習しました:<Instruction>—autofix.jsonに記録しました。"
4. ルールファイルの例 (autofix.json)
[
{
"Rule_number": 1,
"Category": "PROCESS",
"Instruction": "コミットメッセージに絵文字を決して追加しないでください - コミットタイトルはプレーンなConventional Commitsにしてください。",
"Why": "ユーザーの好み"
},
{
"Rule_number": 2,
"Category": "ARCH",
"Instruction": "APIルートハンドラは常に 'src/server/routes/' に配置し、'src/api/' には決して配置しないでください - 一貫したバックエンドアーキテクチャを維持します。",
"Why": "既存のコードベースのパターン"
},
{
"Rule_number": 3,
"Category": "CODE",
"Instruction": "すべての外部エントリポイントの入力検証には常にZodスキーマを使用してください - 型付けされていないランタイム入力を防ぎます。",
"Why": "ランタイムエラーを防ぎ、型を強制します"
}
]
ベストプラクティスとエッジケース
- アトミックなJSON書き込み: 既存のJSON配列を常にパースし、新しいオブジェクトを追加し、有効なJSONを書き戻します。エスケープされていないテキストでファイルを破損しないでください。
- 具体的かつ命令的に: 別のAIがあいまいさなく従えるルールを記述してください。"きれいなコードを書く" のような漠然としたアドバイスは避け、"コンポーネントの実装と一緒に、
.types.tsファイルに型を常にエクスポートする" のようにしてください。 - 無限ループを避ける: ルールを記録する際に、ルールファイル自体に対して別の自己修復ループをトリガーしないでください。
- ルールの上書き: ルール1が "Axiosを使用する" と言っていて、ユーザーが後で "すべてFetchに移行する" と指示した場合、理由を "ユーザーがネイティブFetchへの移行を要求(ルール1を上書き)" としてルール4 "Axiosの代わりに常にネイティブFetchを使用する" を追加します。