壁紙アプリのリファクタリングをAntigravityに依頼したとき、エージェントは完璧なコードを書いてくれました。TypeScriptの型は整っており、テストも通り、パフォーマンスも改善されていました。でも、違ったのです。
そのアプリは、2014年から毎日ダウンロードされ続けているシンプルな壁紙アプリです。累計で5,000万を超えるダウンロードの大半は、機能より「静けさ」を求めるユーザーが支えています。エージェントが書いたコードは技術的に正しかったけれど、そのアプリが12年間大切にしてきた「余白」を削ってしまっていました。
私の指示には「リファクタリング」とだけ書いてありました。What は伝えた。でも Why を伝えていませんでした。
正しいコードが間違った仕事をするとき
Antigravityエージェントは、指示の文字通りを誠実に実行します。「リファクタリングする」と言えば、現代的なベストプラクティスに従ってコードを整理します。それは正しい。でも、そのリファクタリングの方向性を決めるはずの「なぜ今これをするのか」「このコードは何を守るためにあるのか」という文脈がないと、エージェントは合理的な標準解を採用するしかありません。
AIエージェントの判断ミスの多くは、指示が間違っているのではなく、意図が伝わっていないことから生まれます。
これは個人開発者にとって特有の問題です。エンタープライズ開発では要件定義書・設計書・コードレビューの慣行が「なぜ」を暗黙的に補完します。でも個人開発では、そのコードがなぜそう書かれているかを知っているのは自分だけです。エージェントには見えない文脈が、ローカルの頭の中にだけあります。
10年以上の個人開発を通じて、私はこの問題に何度もぶつかりました。そして最終的に辿り着いたのが、Whyコンテキスト設計という考え方です。
「What」だけのコンテキストが生み出す静かな混乱
まず、典型的な失敗パターンを見てみましょう。
Before(Whatだけのコンテキスト):
# AGENTS.md
## プロジェクト概要
壁紙アプリのiOS版。Swift + SwiftUIで実装。
## 技術スタック
- Swift 6
- SwiftUI
- PhotosUI framework
- Cloudflare R2(画像ストレージ)
## ルール
- Swift Concurrencyを使う
- エラーハンドリングを丁寧に
- テストを書くこのAGENTS.mdで「パフォーマンス改善をしてほしい」と依頼したとき、エージェントは何をするでしょうか。おそらく次のことを検討します:画像のプリロード、キャッシュの最適化、並列フェッチの導入、UIのラジカルな再設計。これらはすべて「パフォーマンス改善」として正しい。
でも、このアプリのユーザーが本当に求めているのは「画像切替のなめらかさ」ではなく「開いたときの静けさ」かもしれません。それはAGENTS.mdには書かれていません。
After(Whyを含むコンテキスト):
# AGENTS.md
## プロジェクト概要
壁紙アプリのiOS版。2014年から運営中、累計5,000万DL超。
## このアプリが大切にしていること(Why)
このアプリのユーザーは「豊富な機能」ではなく「静かで使いやすい体験」を求めている。
12年間のユーザーレビューが示すのは、「シンプルさ」こそが継続的に選ばれる理由だということ。
機能追加よりも「削除しない」ことが重要。新機能は既存ユーザーの体験を壊す可能性があるため、
特に断りがない限り、変更は既存の動作を保守的に保ちながら行うこと。
## 技術スタック
- Swift 6
- SwiftUI
- PhotosUI framework
- Cloudflare R2(画像ストレージ)
## 変更時の判断基準(Why)
「この変更は、5年前から使ってくれているユーザーを混乱させないか?」を常に問う。
パフォーマンス改善は、UXを変えない範囲で行うこと。
設定画面の構造は変えない(ユーザーが覚えている位置に機能があることが大切)。
## ルール
- Swift Concurrencyを使う
- エラーハンドリングを丁寧に
- テストを書くこの違いは大きいです。「静かさを守る」「既存ユーザーを混乱させない」という意図が書かれているだけで、エージェントの選択肢の絞り込みが変わります。
Whyコンテキスト設計の5原則
10年の個人開発と、それ以前のNTT DATAでのシステム設計経験を経て、私が辿り着いた5つの原則があります。
原則1:目的を一文で書く("For whom" を明示する)
コードを書く目的は何か。そして誰のために書くのか。これを一文で書けない設計は、エージェントも迷います。
## このコードは誰のために(原則1:目的)
このAPIは、スマートフォンで壁紙を探している「時間のない会社員」のために存在する。
1秒以内のレスポンス、1タップで設定完了、それ以外の機能は不要。原則2:制約の理由を書く("Why not" を説明する)
制約だけ書いても、エージェントは「なぜ」を知りません。制約の背景を書くことで、エッジケースでの判断精度が上がります。
## しないこと(原則2:制約の理由)
- SNSシェア機能は実装しない
理由:過去に実装したが、シェア後にアプリを戻さないユーザーが増えセッション時間が低下した
- ログイン機能は実装しない
理由:匿名性を好むユーザー層に合わせて意図的にアカウント不要にしている原則3:未来のコードへの影響を書く("Direction" を示す)
「今のコードがどこへ向かうのか」を書いておくと、エージェントは将来的な拡張を見越した設計をします。逆に「今だけで十分」と書けば、不必要な抽象化を避けます。
## このコードの未来(原則3:方向性)
このモジュールは6ヶ月以内にAndroid版にも展開する予定。
ただし今は精度より速度を優先。複雑な抽象化は後回しで、まず動くものを作る。原則4:「十分」の基準を書く("Done" を定義する)
エージェントが「完成した」と判断する基準が曖昧だと、過剰な実装をしたり、逆に最低限しかやらなかったりします。
## このタスクの完了基準(原則4:Doneの定義)
- 既存のユニットテストが全て通ること
- Xcode Instruments で50MB以内のメモリ使用量を確認できること
- UIKitとSwiftUIの境界が明確に分離されること
上記3つを満たせば完了。それ以外の「改善できそうなこと」は別タスクとして切り出すこと。原則5:「なぜ今これをするのか」を書く("Now" の文脈)
タイミングの文脈は、優先順位の付け方を変えます。「WWDC前のリリースに向けて」「App Store審査が近い」「ユーザーからのクレームが増えている」といった情報が、エージェントの緊急度判断を正確にします。
## このタスクのタイミング(原則5:Now の文脈)
iOS 26リリースに合わせた更新作業。Xcode 26 Beta での動作確認が最優先。
App Store提出は2週間後の予定。破壊的変更は避け、バグ修正と最適化のみ。実装例1:AGENTS.md への統合
5原則を組み合わせた、実際のAGENTS.mdの例を示します。これは私が現在実際に使っているテンプレートをベースに、サンプル用に調整したものです。
# AGENTS.md(Whyコンテキスト統合版)
## プロジェクトの目的(原則1:For whom)
このアプリは「毎朝スマートフォンを手に取ったとき、少し気分が上がる壁紙」を求める
30〜40代のユーザーのために存在する。技術的な洗練より、感情的な安心感を優先する。
## アーキテクチャの制約と理由(原則2:Why not)
- Redux/TCA などの状態管理フレームワークは使わない
理由:1人での保守が前提。複雑なフレームワークはアップデート時のコストが高い
- Firebase を使わない(Cloudflare Workers + R2 で代替済み)
理由:Firebase の依存度を下げることでApple審査を通過しやすくなった経験から
- 画像圧縮ロジックはサーバー側(Worker)で完結させる
理由:クライアントでの圧縮はバッテリー消費の苦情が出た(2022年の教訓)
## このコードの未来(原則3:Direction)
短期(3ヶ月):iOS版の安定運用
中期(6ヶ月):Android版への移植(Kotlin Multiplatform で共通ロジックを抽出予定)
長期:ウィジェット対応(WidgetKit + Live Activities)
現在のアーキテクチャはこの中期計画を前提に設計すること。
特にビジネスロジックはUIから完全に分離すること(将来のKMP対応のため)。
## 完了基準(原則4:Done)
各PRは以下を満たすまで完了とみなさない:
1. `xcodebuild test` が全て通る
2. Xcode Memory Graph で循環参照がないことを確認
3. Swift Concurrency の `async/await` に `Task.init { @MainActor ... }` の誤用がない
「完成できそうな改善」があっても、完了基準外のものは別Issueに切り出すこと。
## 現在のタスクの文脈(原則5:Now)
iOS 26 Beta 3 への対応が急務(WWDC後のアップデートでユーザーからの報告が増えている)。
App Store への提出は2週間後。機能追加は凍結中。バグ修正とAPIの非推奨置き換えのみ。このAGENTS.mdを見たエージェントは、「CircularReference の修正中に、パフォーマンス改善のリファクタリングもついでにやろう」という過剰な判断をしなくなります。「Nowの文脈」が「今は修正だけ」を明示しているからです。
実装例2:タスク単位での意図コンテキスト
AGENTS.mdはプロジェクト全体の文脈です。個々のタスクにも「Why」を埋め込むと、より精度が上がります。
Whyのないタスク指示(Before):
SwiftDataの`@Model`クラスで保存された壁紙のお気に入りリストを、
ページネーション対応に変更してほしい。
Whyを含むタスク指示(After):
## タスク:お気に入りリストのページネーション対応
### What
SwiftDataの`@Model`クラスで保存された壁紙のお気に入りリストを、
ページネーション対応に変更してほしい。
### Why
現在、5,000件以上お気に入りを保存しているユーザーでアプリが
起動時にフリーズするという報告が3件届いた。
App Store レビューに「重い」というコメントも2件追加された(今週)。
### 制約(Why not)
UIの見た目は変えないこと。「もっと読み込む」ボタン方式ではなく、
スクロール時の自動ロード方式にすること(既存ユーザーの操作習慣を崩さないため)。
### 完了基準
5,000件のモックデータで起動時間が3秒以内になること。
既存のお気に入り追加・削除の操作に影響がないこと。
同じ「What」でも、「Why」があるとエージェントの選択肢が絞られます。「ページネーション方式の選択」「UIへの影響範囲」「パフォーマンス目標値」が明確になるからです。
実装例3:エラー時の自己診断プロンプト設計
エージェントが行き詰まったときに、意図コンテキストを活用した自己診断を促すプロンプトパターンです。
# エラー診断時のWhyコンテキスト確認プロンプト
エラーが解決できない、または判断に迷った場合、以下の順で自己診断すること:
1. AGENTS.mdの「アーキテクチャの制約と理由」を読み直す
→ この制約が今の問題に関係しているか確認する
2. 「このコードの未来(Direction)」と照合する
→ 今取ろうとしている解決策は、中期計画と整合しているか
3. 「完了基準(Done)」を確認する
→ この問題は今のタスクの完了基準に含まれているか、含まれていなければ別Issueを作成する
4. 上記3つを確認しても判断できない場合は:
「この判断はAGENTS.mdの範囲外です。以下の選択肢を提案します:[A] [B]」
と報告し、判断を委ねること。このプロンプトをAGENTS.mdに組み込むと、エージェントが「迷ったときに何をすべきか」を自律的に判断できます。最も重要なのは「4番」で、判断できないとき、エージェントが黙って進めるのではなく報告するという設計です。
「なぜ」を伝えることの本質
宮大工だった両祖父から受け継いだ感覚があります。「手を動かすことが一つの信心」という言葉です。
彼らが作った建物には、なぜその木材をここに使うのか、なぜこの角度で組まれているのか、すべてに理由がありました。それは設計図には書かれない、職人の中にある文脈でした。師匠から弟子へ、語りながら伝えるもの。
AIエージェントと仕事をするのは、その文脈を言語化して渡すことだと、今は思っています。
私がAntigravityを使い始めた2024年頃、最初はコードを書いてもらうことに集中していました。でも徐々に気づいたのは、良い結果を出すエージェントとそうでないエージェントの違いは、私が渡す文脈の質にあるということでした。
これはあるいみで創作の話でもあります。
17歳のとき、オンラインで出会ったメンターが言いました。「芸術とは全ての人に開かれた自然な言語だ」と。技術もそうかもしれありません。私がAntigravityに「なぜ」を伝えるとき、それは単なる効率化ではなく、12年間のユーザーとの関係性、宮大工の祖父から受け継いだ信念、吉祥寺の空で感じた何か——そういったものを言語化して渡す行為なのかもしれない、と感じることがあります。
哲学的に聞こえるかもしれませんが、実際には非常に実用的な話です。
AIエージェントに「なぜ」を伝えるコストは、最初の設計のときだけかかります。一度書いてしまえば、その後の全てのタスクにその文脈が適用されます。長期的に見れば、曖昧な指示を繰り返して修正するコストより、はるかに低い。
「考えすぎさせない」判断境界の設計
Whyコンテキストのもう一つの効果は、エージェントを「考えすぎさせない」ことです。
Antigravityエージェントは、文脈が少ないほど多くの選択肢を検討します。それは丁寧さからくる行動ですが、個人開発では時間的コストになります。
私が発見したパターンは次のとおりです:
## 判断委任の階層(AGENTS.md に追記するパターン)
### エージェントが自律的に判断してよいこと
- コードのフォーマット・命名規則
- ユニットテストの追加
- コメントの改善
- 型エラーの修正(ロジックを変えない範囲)
### 人間に確認すること(変更前にコメントで報告)
- 既存のAPIシグネチャの変更
- 外部ライブラリの追加・削除
- データ構造の変更(マイグレーションが必要なもの)
### 絶対にやらないこと
- App Store Connect の設定変更
- 課金フローへの変更(Stripe含む)
- プライバシー関連の処理の変更この三層構造を書いておくと、エージェントは「これは自分が決めていい範囲か」を都度判断できます。agents カテゴリの記事「AGENTS.md を活用したマルチエージェント設計」でも触れましたが、判断境界の明示はマルチエージェント設計においても同様に重要です。
また、エラーからの回復設計については「AIエージェントのエラーリカバリ設計パターン」も参考になります。
実装の一歩
今日できることは一つだけです。
既存プロジェクトのAGENTS.mdを開き、「このプロジェクトの目的は何か」「誰のために作っているのか」「なぜこのアーキテクチャを選んだのか」を、5原則のうち1つだけ書き加えてみてください。
書きながら気づくことがあります。「なぜ自分はこのアプローチを選んだのだろう」という問いに、明確に答えられないとき、それはエージェントだけの問題ではなく、設計の整理が必要なサインかもしれません。
Antigravityエージェントに「なぜ」を伝えることは、自分自身のコードへの理解を深める行為でもあります。私はそこに、少し面白さを感じています。