引き算・整合・証明:AIエージェントにリポジトリをスパゲッティ化させない3つのスキル

Jul 1, 2026 によって シュテファン・モラヴィク に公開されました。
AI Agents Developer Productivity Agentic Workflows Code Review
このページの内容 2 分で読める
  1. 1Part 1 · WHAT — エントロピーがデフォルト
  2. 2Part 2 · SO WHAT — 5本のPR、それぞれ一つの本能
  3. 3Part 3 · NOW WHAT

私たちは毎日、コーディングエージェントに本物のチケットを渡しています。そして彼らはほぼ常に、動くものを出荷してきます。そこが心配だったことは一度もありません。心配なのはどのように働くかです。すでに仕事をしてくれている3つのヘルパーの隣に新しいヘルパーを一つ、呼び出し元が1つだけの抽象化を新しく一つ、チケットが名指しした1つの経路だけを塞ぎ、兄弟にあたる4つの経路を壊れたまま放置する修正、どちらとも証明のない「たぶんバグ」という指摘。個々の変更は局所的に見ればもっともです。集積すれば、それはエントロピーです。

TL;DR: 当社のエージェントオーケストレーションコアに対する5本のTier-3プルリクエストで、組み合わせ可能な3つのスキル — ponytail(引き算)、grain(整合)、review-proof(証明) — が5つの機能を出荷しながら821行を削除し、もっともらしさだけならマージされていたであろう無言のコントラクト破壊を捕まえ、すべての変更を既存アーキテクチャの木目に沿わせ続けました。それぞれが何をするのか、実際のdiffを証拠に説明します。

ガードレールを外せば、コーディングエージェントは、もっともらしく見える負債を高速生成する装置です。だから私たちは、逆方向に押す3つの小さなスキルに頼っています — それぞれ一つの本能:引き算、整合、証明。

  • ponytail — 実際に動く中で最も怠惰なものを書く。追加する前に削除する。(これは私たちが書いたものではありません — Dietrich Gebertによるオープンソーススキル を当社のスタック向けに適合させたものです。)
  • grain / grain-review — コードベースがすでにそこだと決めた場所に置く。二つ目のやり方を発明しない。
  • review-proof — 失敗するテストとして再現するまで、指摘を信じない。

grainとreview-proofは、ponytailと同じ精神で、当社のアーキテクチャに合わせて調整して私たちが作りました。以下の5本のPRはどれも当社のエージェントオーケストレーションコアに触れています — リポジトリの中でいい加減にすると最も高くつく場所です — そしてどれもTier 3に分類されています:自動レビュアーの上に追加のテストカバレッジと人間のレビュー、例外なしです。

3つのコーディングエージェントスキル、それぞれ一つの本能:ponytailは引き算し、grainは整合させ、review-proofは証明する — それぞれが何を殺し、何を報酬として得るのか

3つのスキルの概要:ponytailは引き算し、grainは整合させ、review-proofは証明する。

Part 1 · WHAT — エントロピーがデフォルト

リポジトリをAIエージェントに渡すとき、誰も警告してくれないことがあります。各エージェントは局所的に最適化し、何も覚えていないのです。エージェントはチケットを見ており、あなたのチームが何か月もかけて収束させてきた慣習は見ていません。既存のメールサービスより新しいものを好む理由もなく、リダイレクトステータスの集合がすでに3ファイル先で定義されている記憶もなく、「修正はこの1つの呼び出し元ではなく共有関数に入れるものだ」という本能もありません。放っておけば、N個のエージェントは同じことをするための微妙に異なるN通りのやり方を生み出します。これはリントで消せるコード品質の問題ではありません — 複合的に積み上がる構造的ドリフトなのです。

3つのスキルはそれぞれ、そのドリフトの一つの軸を狙います。

ponytail — 動く中で最も怠惰なもの

Ponytailは、他人の気の利いた抽象化のせいで午前3時に叩き起こされた経験を持ち、次の抽象化を書くことを拒むシニア開発者です。はしごを登り、最初に耐える段で止まります:これはそもそも存在する必要があるのか(YAGNI)→ このコードベースにすでにあるか → 標準ライブラリがやってくれるか → ネイティブのプラットフォーム機能はどうか → すでにインストール済みの依存関係はどうか → 1行にできるか → ここでようやく、動く最小限のコード。

エージェントにとって最も重要な段は**「これはすでにこのコードベースにあるか?」**です。数ファイル先にあるものを再実装するのは、エージェントの雑な仕事の中で最もよくある形です。そしてponytailのバグ修正ルールはdiffを正直に保ちます:症状ではなく根本原因を直せ。 これから触る関数のすべての呼び出し元をgrepせよ。共有関数に1つガードを置く方が、すべての呼び出し元にガードを置くより小さなdiffです — しかも兄弟の経路を壊れたまま残しません。

grain / grain-review — 木目に沿う

ponytailがどれだけ少なく書くかを律するなら、grainはそれがどこに行き、どんな形を取るかを律します。その唯一のルール:最も近い既存の例を見つけ、その形をコピーし、何をコピーしたかを名指しする。 新しいコードは、隣のファイルを書いた人がこれも書いたかのように読めるべきです。

grainはアーキテクチャが強制される場所でもあります。当社のバックエンドはかなり標準的な垂直スライス+ヘキサゴナル構成です — プレゼンテーションがアプリケーションを呼び、アプリケーションがドメインを呼び、インフラストラクチャは内側に依存し、ドメインは決して外に手を伸ばしません。*「このルートはコントローラを飛ばしてサービスを直接引いている」*といった指摘は重箱の隅つつきではありません — エージェントが来月もナビゲートできるコードベースとできないコードベースの違いです。grain-reviewはまさにこうしたものを狩ります:重複したヘルパー、越えられたレイヤー境界、別機能の内部への手出し、すでに一つのやり方で行われているものに対する二つ目の慣習。

review-proof — 指摘の資格を得る

標準的なAIコードレビューは、もっともらしい指摘を生み出します。本物もあります。自信満々のナンセンスもあります。外から見ると両者は同じに見えます。review-proofは自分自身を信じることを拒みます:レビューした後、すべての正確性に関する指摘を、実際に失敗するテストまたは実行可能な再現として再現することを強制し、できないものは捨てます。最後に構造的な適合性のためのgrain-reviewパスで締めくくります。出荷されるのは、各項目が実行可能な証拠を伴うレビューであり — 雰囲気ではありません。

これが機能していれば見えるはずのもの

  • H1 — 機能PRで削除が現れる。 ponytail + grainが機能しているなら、機能を追加すると、しばしばネットで構造が削除されるはずで、追加されるだけではないはずです。
  • H2 — 修正は一度だけ、共有の場所に着地する。 根本原因の修正は、多数の呼び出し箇所を1つのガードに収束させるべきで、呼び出し元ごとにガードをばら撒くべきではありません。
  • H3 — レビューが、人間が見逃すコントラクト破壊を捕まえる。 証明に裏打ちされたレビューは、「問題なさそう」というレビューが見逃すバグ — 特に無言の種類のもの — を浮かび上がらせるはずです。

Part 2 · SO WHAT — 5本のPR、それぞれ一つの本能

当社のエージェントコアに対する5つの実際の変更。リポジトリは非公開なので内部の詳細は意図的に曖昧にしていますが、数字は実際のdiffから計算したもので、教訓こそが移植可能な部分です。

引き算:十数か所のfetchサイトに1つのガード

あるフロー手順の一族が、DNS解決の安全チェックなしにユーザー提供のURLをfetchしていたため、内部アドレスに解決されるホスト名がバックエンドからクラウドメタデータに到達できる状態でした。誘惑に負ける修正は、十数か所以上あるfetchサイトそれぞれにチェックを追加することです。ponytailの答えは逆でした:共有されたガード付きfetchヘルパーを1つ、どこでも使う — そしてワイルドカードDNSのトリックがすり抜けた手書きのプライベートネットワークテーブル、重複した3つのリダイレクトループ、いくつかのファイルにコピペされたネットワークチェックを削除しました。

そのdiffは共有ヘルパーを追加し、22ファイルにまたがる約90行の重複を削除しました。その削除こそが物語です。これは生きたH2です — 根本原因の修正が、チケットが名指しした1つの経路にパッチを当てるのではなく、すべての呼び出し元を1つのガードに通したのです。

十数か所のユーザーURL fetchサイトが、それぞれに回避可能なチェックを持ち、1つの共有されたガード付きfetchヘルパーに集約される

根本原因の修正:十数か所の場当たり的なfetchサイトが、1つの共有されたガード付きヘルパーに収束する。怠惰な修正と安全な修正は同じ修正である。

引き算 + 証明:1つの形ガードを、実ランタイムで証明

当社のワーカーランタイムは、実行の結果をシリアライズされた文字列として永続化し、それを単一要素のリストで包むこともあります。素のオブジェクトを期待していたコンシューマーはそれでクラッシュしました。間違った修正は、各コンシューマーに防御的な型チェックを散らばせます。代わりに:小さな形を正規化するヘルパーを1つ作り、すべてのコンシューマーをそこに再ポイントしました — 規律の緩いエージェントが書いたであろうN個の場当たり的なガードを置き換える、ほぼ純粋な1つのガードの追加です(+558 / −24、7ファイル)。

これをreview-proofの物語にしているのはテストです。想定されたシリアライズ形式に対してアサートするのではなく、実際のランタイムとストレージを通して本物のワークフローを実行し — モックなしで — ランタイムが実際に永続化する形を証明しました。チケットの未解決の問いは文字通り*ここでランタイムは何をシリアライズするのか?*であり、唯一の正直な答えは実行できるものなのです。

証明:レビューが無言のコントラクト破壊を捕まえた

機能:ノードごとのフォールバックモデルで、あるプロバイダーに固定されたフローが障害時に優雅に劣化できるようにするもの。明白な最初の実装は、モデルをフレームワーク内蔵のフォールバックコンビネータで包むことでした。

それはハッピーパスでは動きました。しかし同時に、isinstanceを通じて具体的なモデル型でゲートされる2つのプロバイダー機能を無言でオフにしていました — 包まれたオブジェクトはもうその型ではないので、ネイティブの構造化出力とプロンプトキャッシュの両方が静かに無効になったのです。エラーはありません。ハッピーパスの失敗テストもありません。まさに人間のレビューが見逃し、「問題なさそう」というエージェントが承認してしまう類のものです。

review-proofはそれを承認しませんでした — 両方の破壊を失敗するテストとして再現し、それが再設計を強制しました:フォールバックをより下の実行時に適用し、すべてのモデルが具体的な型のままで、型でゲートされる機能が動き続けるようにする。H3は決定的に確認されました:証明は、もっともらしさなら出荷してしまったバグを捕まえたのです。

整合:コピー2つではなく、ピッカー1つ

2つ目の通知チャネルを追加すると、チャネルピッカーUIに2つの住処ができました — 作成ウィザードと設定モーダルです。デフォルトのエージェントの動きは、両方に新しい分岐を追加し、同じ状態機械のコピーを2つに増やすことです。grainは言いました:これが形作られるべきやり方はすでに1つある — 共有にせよ。 私たちは単一のピッカーフックを抽出して両方の画面をそれで動かし、新しいチャネルを既存の設定ユニオンに差し込み、新しい送信機構を追加する代わりに既存のメールサービスを再利用しました。

+1,735 / −340、24ファイルにまたがる。 この規模の機能が340行を削除するのは、H1が可視化されたものです:2つのピッカーコピーを1つに重複排除したことが、新しいチャネルのかなりの部分の費用を賄ったのです。

整合 + 証明:既存のエンドポイントを再利用し、パスをミラーする

課題作成時にユーザーがファイルを添付できるようにすることは、新しいアップロードエンドポイント、新しいディスパッチ機構、新しいプロンプト経路を意味する可能性がありました。grainはそのほぼすべてを既存のレールに載せました:既存のアップロードエンドポイント、バックエンドのホワイトリストを正確にミラーするフロントエンドのacceptリスト、そしてスケジュールされた作業がすでに使っていた適格性機構を再利用した遅延ディスパッチの修正。それは証明に裏打ちされた修正とともに出荷され、並列アップロード下でデータを失っていたであろう本物のトランザクション分離バグも含まれていました。+1,776 / −218、27ファイルにまたがる — 新しいスライスを発明するのではなく既存のスライスに合流することで、大きな機能でありながら218行の削除を見つけたのです。

スコアボード

5本のTier-3 PRのスコアボード。PRごとに追加・削除された行数と、それぞれを形作った本能:引き算、整合、証明

5本のTier-3 PR:それぞれが何を追加し、何を削除し、その背後にどの本能があったか。

エージェントコアに対する5本の機能・修正PRは821行を削除した — より少なくやったからではなく、すでに存在していたものを複製することを拒み、根本原因の修正によって冗長になった症状パッチを残すことを拒んだからである。

完全な開示

  • これらはスキルであり、研究ではありません。 ベースラインアームを置いた対照実験ではなく、規律を適用した5本の実在のPRです。反事実 — 同じエージェントがスキルなしで出荷していたであろうもの — は、測定ではなく情報に基づく推定です。無言のコントラクト破壊の話が最もクリーンな証拠です。再設計の前にレビューがバグを再現するのを私たちが目撃したからです。
  • 行数は代理指標です。 −821はdiffから得た実数ですが、「削除された行」は「避けられた重複と不要な柔軟性」の代わりです。エージェントに200行の憶測的なコードを書くのをやめさせたスキルは、diffにまったく痕跡を残しません — 最大の成果はここでは見えないのです。
  • トークン節約は方向性の話です。 より小さなdiff、触れるファイルの減少、再利用された構造は、生成・レビュー・再レビューに費やすトークンが少ないことを意味します — ただし、PRごとの厳密なトークン差分を引用しているわけではありません。
  • ponytailは当社のものではありません。 Dietrich Gebertによるオープンソーススキル を当社が適合させたものです。grainとreview-proofは当社が同じ精神で作りました。3つともClaude Code上のローカルプロジェクトスキルとして動作します — インストールするバイナリではなく、プロンプトと手順です。
FlowHuntロゴ

ビジネスを成長させる準備はできましたか?

今日から無料トライアルを開始し、数日で結果を確認しましょう。

Part 3 · NOW WHAT

出荷されたもの。 組み合わせ可能な3つのスキル。ponytailとgrainは書いている間に動き、ponytail-review、grain-review、review-proofはあるdiffに対して動きます。review-proofは最終フェーズとしてgrain-reviewを連結するので、1回の証明済みレビューが構造パスも無料で得られます。

月曜日にあなたができること — 当社の正確なスキルは必要ありません:

  1. 「再利用」を10番目のはしごではなく2番目の段にする。 エージェントがヘルパーを書く前に、既存のものをgrepさせましょう。「これはすでにこのコードベースにあるか?」は「きれいに書けるか?」より上に属します。
  2. 根本で直し、呼び出し元リストで証明する。 すべてのバグ修正に、触った関数のすべての呼び出し元を名指しすることを要求しましょう。共有関数の1つのガードは、呼び出し元ごとのガードに勝ります — しかも小さなdiffです。
  3. 新しいコードにコピーすべき最も近い兄弟を与える。 「最も近い既存の例を見つけ、その形をミラーせよ」は、誰も読まないドキュメントから、エージェントが従うデフォルトへとアーキテクチャを変えます。
  4. レイヤー境界は雰囲気ではなくCIで強制する。 新規のレイヤー越えインポートだけを失敗させるラチェットを使えば、既存の負債の海を沸騰させずに一線を守れます。
  5. 再現できない指摘は出荷しない。 エージェントにまず失敗するテストを書かせましょう。バグを再現できなければ、それはバグではなく意見です。捨てましょう。
  6. レビューに削除させよ。 正確性とは別に、レビューパスを過剰設計に — 「何を削れるか」 — 特に向けましょう。diffの最良の結果は、それが短くなることです。

試してみてください、あなたにとって失敗する場合こそ特に。 実際のコードベースでコーディングエージェントを動かしているなら、エントロピーはすでに起きています — ただ測定していないだけです。これらの1つを、次の10本のエージェントPRに対するレビューパスに変えて、削除を数えてみてください。引き算・整合・証明がdiffを縮めない、あるいは無言の破壊を捕まえないなら、ぜひ聞きたいです。訂正と反例は特に歓迎します。

エージェントは追加する。仕事は、エージェントにすべての行の資格を稼がせることだ。

よくある質問

シュテファンはFlowHuntを開発するAIおよびソフトウェアエンジニアです。製品そのものを超えて、彼は開発コストを削減しながらコード品質を向上させる、開発者向けのエージェント的ソフトウェアエンジニアリングワークフローを設計しています。

シュテファン・モラヴィク
シュテファン・モラヴィク
AIおよびソフトウェアエンジニア

元が取れるエージェントワークフローを構築する

FlowHuntは、開発コストを削減しながらコード品質を高めるエージェント型ワークフロー、レビューゲート、MCP連携の設計をエンジニアリングチームが行うのを支援します。