AI-Native Series・エンジニアリング実践
リポジトリの次の開発者は人間ではない。それを迎える準備のための六つの実践。
1分でわかる要点——ここから持ち帰れるもの
敵対的なAIが私のリポジトリを端から端まで読み込み、パストラバーサルを含む、見落としていた21件のバグを見つけた。この読者こそが新しい標準だ。そこで私は六つの実践——OOP、AI-native、context engineering、harness engineering、loop engineering、graph engineering——を軸にコードベースをリファクタリングし、すべてを測定した:コード品質56→95、AIの応答130秒→3秒、マージ前に9件のバグを修正。以下では、各実践が何を意味するのか、そしてその裏にある証拠を示す。
以下の各実践は、頭の良い15歳の子に説明するような調子で解説し、そのあとに1つのリポジトリで1週間実務を行った際の数字で裏付けている。所要時間は約8分。
決して読み飛ばさない読者
先週、あるブランチをマージする前に、私は自分のリポジトリを敵対的なAIレビュアーに渡し、こう指示した——find how this fails in production. No compliments.(訳:本番環境でこれがどう壊れるかを見つけろ。褒め言葉は不要だ。)すると21件の指摘が返ってきた。そのうち1件は真正のパストラバーサルで、字面上のチェックではRecordings/../../.ssh/id_rsaを素通りさせてしまうものだった。そのファイルは私自身がレビューしたはずなのに、見落としていた。
その瞬間、抽象論が腹落ちした。あなたのコードを次に読む「開発者」は、疲れた人間が差分をざっと読み流すのではない。1万行すべてを読み、すべての分岐をたどり、リポジトリの構造を文字通りに受け取るエージェントなのだ。コードベースが人間にしか読み解けないものであれば、その最良の読者であり、最も厳しいレビュアーでもある存在を、力を貸せないまま放置していることになる。
そこで問いが変わった。「このコードはきれいか?」ではなく、「このコードでエージェントは仕事ができるか?」 という問いに。それに答えるのが六つの実践だ。どれも新しいものではない。新しいのは、それが誰のため.
1・OOP──構造がそのままエージェント可読性になる
平易に言えば: オブジェクト指向プログラミングとは、コードを小さな単位にまとめ、それぞれに一つの仕事だけを持たせ、やり方は隠すことだ。その単位は「markdownを渡せばチャンクを返す」と約束するだけで、外部はそれ以上知る必要がない。
OOPの古典的な論拠は人間にとっての保守性だった。新しい論拠はさらに強い。境界(seam)こそ、エージェントが安全に作業できる場所なのだ。 私の取り込み処理スクリプトが一枚岩の手続き型コードだったとき、自動リファクタリングループはそれを56/100と評価し、ほとんど改善できなかった(+2点で断念した)。それを三つの境界に再構成したところ──ひとつは埋め込み生成を担うクラス、もうひとつはデータベース接続を担うクラスMarkdownChunker、そしてもう一つはチャンク分割を担うクラスOpenAIEmbedder, a KnowledgeStore──そのどれか一つだけを、他に触れずに入れ替えられるようになった(別の埋め込みプロバイダー、別のデータベースなど)。「ローカルの埋め込みモデルに切り替えて」と指示されたエージェントは、もはやファイル全体ではなく、たった一クラス分の影響範囲で済むようになった。
検証結果:リポジトリのPythonコード全体で品質スコアが56→95/100に向上した──型付け100%、docstring100%、ネスト深度100%──その間、リポジトリ自身のテストゲートは常にグリーンのままだった。
2・AI-native──エージェントを一級のユーザーとして扱う
平易に言えば: AI-nativeなリポジトリは、エージェントを侵入者ではなくユーザーとして扱う。エージェントが監督なしで作業するために必要なものを備えている。アーキテクチャを説明するガイドと、そして最も重要な、機械が発見できる完了条件.
私のリポジトリにはCLAUDE.md があり、コードが何をするかだけでなく、落とし穴も文書化している(「署名済みバンドルにバイナリをホットスワップしてはならない──macOSは実行時に即座に強制終了する」)。さらにルートにはMakefileがあり、ターゲットは一つ:check。そのターゲットこそ、このリポジトリにおける「完了」の定義だ。効果はすぐに現れた。私がこのリポジトリに向けて動かしたオーケストレーションツールは、自力でこのターゲットを発見し make check が自律的にそれを発見して実行し、正直なグリーンを報告した。設定は一切不要。リポジトリがエージェントに、自分自身をどう検証すればいいかを教えたのだ。
検証結果:anyagent goal --driveを発見しMakefile:check、実行し、終了コード0。同じゲートは今、プッシュのたびにCIで走っている。
3・context engineering — コンテキストは予算であってバックパックではない
平易に言えば: AIのプロンプトに詰め込むものはすべて、時間と注意力というコストを食う。context engineeringとは、何がその場所に値するかを見極め、それを運ぶことになるモデルに合わせて適切なサイズに調整することだ。
私のAIアシスタントのシステムプロンプトは、知らぬ間に蓄積されたナレッジパックによって87KBにまで膨れ上がっていた。プロンプトキャッシュが効くクラウドモデルなら、これはほぼタダ同然だ。だがAPI障害の際に切り替えたローカルの7Bモデルでは、これが致命的で——しかも目に見えない形で致命的だった。モデルはプロンプトの大半を読まずに切り捨てていた一方で、応答のたびに2分以上かかっていたのだ。実測してみた——システムプロンプトなしなら0.3秒、129.7秒がフルパック使用時。パックを5KBまで削り、必要時にのみ読み込むファイルへ移した後は:3.0秒。同じモデル、同じハードウェアで43倍速い——しかもモデルが一度も目にすらしなかった単語を削っただけで。
検証結果: 1回の応答あたり130秒→3秒。前後をそれぞれ計測して確認した。パックは削除されたのではなく、タスクが必要とするときにだけ読み込まれるファイルへ移されただけだ。
4・harness engineering — 真実を安く手に入れる
平易に言えば: harnessとは、コードを取り巻く装置であり、検証を安く、嘘を高くつくものにする——プローブ、ゲート、セルフテストがそれだ。原則は、ユーザーの高度で検証すること——関数が何を返すかではなく、ユーザーが実際に何を体験するかをテストするのだ。
これがその週を救った一件だった。私のアプリの文字起こし機能は、何も出力せず黙って失敗していた。ユニットテストは通っていたが、障害は実際のアプリバンドルでしか現れないmacOSの権限まわりの仕組みの中に潜んでいた。それを見つけ出したharnessとは、OSのキル信号を再現するプローブアプリ、そしてどのプロセスの権限が関係しているのかを特定したクラッシュレポートの解析、そして最後に人間を介さずに修正をエンドツーエンドで証明した、スピーカーからマイクへのセルフテストだ——合成音声をライブのマイク入力パイプラインに流し込むものである。私のユーザーが「私はテストのための機械じゃない」と言ったとき、彼は正しかった。それこそがharnessの仕事なのだ。
検証結果: 根本原因は3つ(権限キル、プロンプト帰属、ランループ枯渇)。それぞれを専用プローブで切り分け、最終的な自己テストでは人間の操作ゼロで、約1.2秒周期のライブ文字起こしチャンクを51件生成した。
5・ループエンジニアリング — 閉じたフィードバック、正直な採点
平易に言えば: ループとは「実行→計測→調整」というサイクルすべてを指す。ループエンジニアリングとは、そのサイクルを閉じ(計測結果が実際にフィードバックされる)、かつ正直(停滞は停滞として報告され、偽の成功にはならない)ものにすることだ。
このリポジトリは、あらゆる規模のループの上に成り立っている。サーキットブレーカー付きのLLMフェイルオーバー・チェーン(プライマリのプロバイダが呼び出し中に落ちても、次の層が応答を返す)、文字起こしにおけるチャンク単位のフォールバック(クラウドが失敗したらローカルがそのチャンクを引き継ぎ、何も失われない)、そして先述のリファクタリングループ。このループの最も価値ある振る舞いは止まることだった。56→58と報告した上で「変更案なし」と言い切り、そこで終了したのだ。自分のスコアを盛るエンジンは、エンジンがない状態より悪い。この正直な停滞のおかげで、機械の作業がどこで終わり、判断がどこから引き継ぐべきかが正確に分かった。
検証結果: リファクタリングループは勝利を偽装せず、58/100での自らの停滞を報告した。その後、人間主導のパスで同じゲートを通しながら95まで到達させた。すべてのステップはテストゲートを通過し、劣化時にはロールバックする。
6・グラフエンジニアリング — 記憶はエンティティと関係の集合である
平易に言えば: ファイルやフォルダは、物事の関係性を覚えていない。グラフ、つまり物と物がつながった構造こそが、作業を積み重ねる仕組みだ。このミーティングは、あのプロジェクトに属する。この文字起こしは、あの知識ベースを養う。
このリポジトリの記憶レイヤーは、端から端までグラフ状に構成されている。文字起こしは知識ストア内の埋め込みになり(ファイル名ではなく意味で検索できる)、ミーティングはナレッジグラフ・エンジンにエクスポートされ、「誰が何について何を言ったか」を写し取る。そして最新のエッジである「Projectize」は、ミーティングのノートを作業が続くプロジェクトフォルダの内側に配置し、次のステップまであらかじめルーティングしておく。かつて録音は行き止まりだった。今ではエッジを持つノードになっている。
検証結果: ミーティングをワンクリックすると、次のステップが自動でルーティングされた日付入りのメモがプロジェクトのリポジトリに生成される。そのミーティングは保存先フォルダで朽ちる代わりに、プロジェクトのグラフに加わったわけだ。
途中で壊れたもの(あえて残す)
- 自動リファクタリングループは58/100で頭打ちになった。エンジンはルーティングとゲートを担うが、最後にギャップを埋めるのはやはり判断力だ。
- 検証を早く回そうと、インストール済みアプリに修正済みバイナリをホットスワップしたことがある。macOSはバンドルのコード署名を壊したとみなし、即座にそれを強制終了した。この教訓はリポジトリのエージェントガイドに刻み込んだので、人間だろうとエージェントだろうと、二度と同じ轍を踏まない。
- 敵対的レビューが見つけた21件のうち、マージ前に9件を修正し、残り12件はなかったことにするのではなく、PRに記録した。誠実な❌は、見せかけの✅に勝る。
一文でまとめると
コードを継ぎ目(OOP)で区切り、エージェントに玄関とゴールライン(AI-native)を用意し、コンテキストをお金のように使い(context engineering)、真実を安く検証できるようにし(harness)、フィードバックの輪をすべて正直に閉じ(loop)、記憶を「モノと関係」として保存する(graph)。そのうえで、見つけられる限り最も手厳しいレビュアー、決して読み飛ばさないレビュアーにリポジトリを渡し、自分を鍛え直させればいい。