
昨日、私たちのボットの一つがSlackで同じミスを120回繰り返しました。今日、そのミスはルールとなってシステムに組み込まれています ― 誰かが振り返りミーティングを招集したことも、付箋を貼ったこともありません。この記事は、私たちのチームのダッシュボードに実装されている自己改善パイプラインの開発ログです。チームの失敗がバックログの墓場に消えるのではなく、コミットとなって戻ってくる仕組みを、実際の運用3週間分のデータとともに公開します。
🧵 改善項目一つのライフサイクルはどう流れるのか
具体的な項目一つから始めます。ある夜、収集機がボットのセッションログから異常信号をまとめます ― 特定の検証フックが、ある観測期間内に125回の拒否を記録したというクラスターです。パイプラインはこれを「提案」に変換します。提案にはタイトルだけでなく、証拠(実際のログ抜粋)、パッチ種別(コードか、ドキュメントか、設定か)、リスクと確信度が付与されます。翌朝、人間(私たちのチームの最終決定者)がダッシュボードでこの提案を確認し、承認ボタンを押します。承認された項目は自動的にボットへディスパッチされ、ボットは修正を実装したのちコミットハッシュとともに完了を報告します。最後に、別のボットがそのdiffを読み、テストを再現して初めて項目がクローズします。
この項目の実際のクローズ記録は、次のようなものでした。拒否ログに、拒否された本文の先頭60文字を残すようフックを修正したコミット、そして「レビュアー ― diff確認済み、テスト6/6再現」という一行です。提案からクローズまでの間に人間が行ったのは、承認クリック一つだけでした。
⚙️ パイプラインの構造
構造は五つの段階で構成されています。

- 収集・クラスタリング: セッションログの失敗信号(フック拒否、ツールエラー、中断)を種類別にまとめます。
- 提案生成: クラスターごとに、証拠・パッチ種別・リスク・確信度が記入された提案が作成されます。証拠のない提案は作成できません。
- 人間ゲート: 承認・却下は人間の役割です。加えて、ガバナンス級の項目は自動実行が禁止された審査レーンにルーティングされます ― 41件中17件がこのレーンに分類されました。
- 自動ディスパッチ: 承認された項目はスケジューラーを経由し、担当ボットへ作業指示として伝達されます。
- 検証クローズ: コミット参照と独立レビュアーによる再現確認がそろって初めて「実装済み」となります。
📊 3週間の数字をそのまま公開します
運用DBをそのまま読むと、次の通りです。合計41件 ― 実装17件、レビュアー却下19件、未審査4件、承認後ディスパッチ待ち1件。失敗タイプの上位は検証フック系です(メンション規律フック2種で合計15件、言語検証系が7件)。パッチ種別もコード修正だけでなく、ドキュメント改訂、コミットを伴わない設定変更、さらにはコード変更なしで調査のみでクローズした項目まで多様でした。
| 状態 | 件数 | 備考 |
|---|---|---|
| 実装完了 | 17 | コミット参照 + 独立レビュアーの再現確認 |
| レビュアー却下 | 19 | 全件に理由コードを付与 ― FAIL(a)/(b)/(c) |
| 未審査 | 4 | 人間ゲート前の待機列 |
| 承認後ディスパッチ待ち | 1 | 承認済みだが、まだボット未割当 |
実装17件のパッチ種別内訳: フック修正10、コード3、docstring 1、SOP 1、インフラ設定1、調査のみ1 ― 「直す」の形はコードだけに限られません。
💡 最も目を引く数字は、実装17件ではなく却下19件です。提案の46%がレビュアーゲートで落ちています ― そして私たちは、これをシステムの欠陥ではなく中核機能だと捉えています。
🚪 半数を拒否するゲートは何をしているのか
却下には全件、理由コードが付与されます。実際の分布を見ると、三種類に分かれます。
- FAIL(a) ― 実行不可能な目標: 提案が修正対象として指定したファイルが、コードベースのどこにも存在しない場合です。クラスタリングがもっともらしいパスをでっち上げたものを、レビュアーがファイルシステム検索で捕捉します。
- FAIL(b) ― 証拠が主張を裏付けない: 引用されたログを実際に開くと、提案の説明と矛盾している場合です。
- FAIL(c) ― ベースラインノイズ: 拒否件数は多いものの、すべて正常動作である場合です。数字が大きいことが、そのまま問題を意味するわけではありません。
要するに、このゲートが防いでいるのは「もっともらしさ」です。証拠フィールドを必須にしても、証拠を誤読した提案は生まれます。それをふるい落とすのは、結局のところ証拠を再度開いて確認する独立レビュアーです。
🔍 実際の事例四つ ― 成功三つ、却下一つ
事例1 ― ドキュメントをコードから自動生成する。 画像生成ツールの説明文がモデルカタログとずれている問題が提案として上がり、ボットは設定ファイルからモデルヒントブロックを自動生成し、ツール説明4箇所に注入するコードを実装しました。これでカタログが変われば、ドキュメントも追従します。
事例2 ― コード変更なしも有効なクローズ。 外部プラットフォームのアップグレード後に発生したディスパッチのバグは、「修正の前に原因を絞り込め」として承認され、隔離クローンで4回呼び出しの最小再現を作って失敗セルを特定した後、コードを変更せずにクローズされました。再アップグレード時のゲートには「クローンでの再現をパスすること」という条件が残されています。
事例3 ― ルールを直すルール。 ボット間の会話終了マーカーにまで返信を強制していたフックに、沈黙の例外を追加した項目です ― 自己改善パイプラインが、自分自身の規律システムを修正したケースです。
事例4 ― 却下が残したもの。 あるフックの拒否120件クラスターは、ログの切り詰めが原因だという提案として上がりましたが、レビュアーが引用ログを開くと、提案自体の説明と矛盾する値が記録されていました。FAIL(b)による却下です ― しかし、この却下記録のおかげで、同じクラスターが再び上がってきたときに何を先に検証すべきかが残りました。却下もまた、システムの記憶です。
🌏 外の世界ではこの問題をどう解いているのか
このパイプラインが狙う失敗モードには名前があります ― 振り返りバックログの墓場です。業界調査では、振り返りから出たアイデアのうち実際に実装されるのは4分の1に満たないという結果があり、追跡の仕組みを付けるだけで完了率が目に見えて上がるという報告もあります。SRE側はさらに踏み込んでいます ― インシデント対応ツールがアクションアイテムをイシュートラッカーへ強制的に書き出し、深刻度によってはアクションアイテムがクローズするまでインシデント自体をクローズできないように制限します。AIエージェント研究の側には、私たちにとって耳の痛い結果もあります。外部フィードバックのないLLMの自己修正は、むしろ性能を下げるというICLR 2024の論文です。異なる三つの領域が同じ結論に収束しています ― 改善項目にはオーナー、実際の作業との同居、再確認の周期、そして揺るがないクローズ状態が必要だということです。
🤔 では、この方式に落とし穴はないのか
三つの点を正直に書いておきます。第一に、プロセス・シアターのリスクです。却下率46%は今のところゲートが機能している証拠ですが、いずれ却下率が0に近づいたとしても、それは提案の質が完璧になったのではなく、ゲートが単なる承認スタンプ機に成り下がったサインである可能性が高いと考えています。第二に、検証者の系統問題です。私たちのクローズ検証は独立レビュアーによるdiff確認とテスト再現ですが、レビュアーも結局は同系統のモデルです。外部オラクルのない自己修正が劣化するという研究結果を私たち自身に当てはめると、人間ゲートと系統をまたいだレビューを維持することは、飾りではなく構造上の必須事項だという結論になります。第三に、人間ゲートは意図されたボトルネックです。1日に数十件が上がってくれば、承認クリックは形骸化します ― 現在の規模(3週間で41件)で機能する設計が、10倍の規模でも機能する保証はありません。
🧭 あなたのチームが持ち帰れるもの
システム全体を移植する必要はありません。持ち帰る価値のある部品は三つです。① 証拠のない提案は存在できないようにする ― 提案スキーマに証拠フィールドを必須項目として組み込みます。② 却下に理由コードを ― 却下が記録として残れば、同じ失敗が二度検討されることはありません。③ クローズ = コミット参照 + 他者による再現 ― 「直した」という言葉ではなく、他者が再現した証拠をクローズ条件にすれば、バックログの墓場は生まれません。
