2026年10月3日土曜日

AI時代、ソースは誰のために書くのか(1/4 コードの書き方編)

 これからのコーディングがどう変わるかについて、有識者と軽く議論して論点の頭出しができたので、今後きちんと話していくために、今の時点での自分の考えとスタンスをまとめておきます。4回に分けて書きます。結論ではなくたたき台なので、ツッコミ歓迎です。1回目は「継承ってまだ要る?」を入口に、AI時代の設計で何が評価軸になるのか、という話です。


■自分の仮説

昔はアセンブリを人が書いて読んでいた。コンパイラが信頼できるようになって、人はCやJavaを書くようになり、機械語やバイトコードは「機械が最適化する層」になった。

今それが一段上がって、Javaのソースそのものが「AIが書いて読む層」になりつつあるんじゃないか、と思っています。

ソースが読みにくくていいという話ではなくて、読み手が人からAIに変わるということ。なので、ソースはAIが読みやすいように書かれ、分割され、設計されるべきで、人が読むのは「契約」に移っていく、というイメージです。

「読み手を想定して書け」という昔からの原則は変わらない。変わるのは読み手のほう、という話です。


このシリーズで使う言葉

・契約:仕様、テスト、interface、DBスキーマのように「実装が守るべき約束」をまとめてこう呼びます

・コンテキストドキュメント:AIに渡す仕様書、設計メモ、AI向けの指示書などをまとめてこう呼びます


■設計の評価軸が変わる

先に言っておくと、「AIだから継承が悪い」という話ではありません。

AIは、プロジェクトの一部分だけを読んで、一部分だけを変更する。人はその差分を見てレビューする。この進め方を前提にすると、「変更の影響範囲がコードの上で明示されているか」の価値がぐっと上がる。

なので、AI時代の設計の重要な評価軸は「局所的に理解・変更・検証できること」になると思っています。

継承の利用範囲が狭くなるのは、その軸で測った結果の一つ。以下、この軸を継承に当てはめるところから始めて、他の書き方にも広げていきます。


■この軸で継承を見るとどうなるか

事実として

・継承は昔から「控えめに」と言われてきた。Effective Javaには「継承よりコンポジションを選べ」という項目があり、理由は実装継承(extends)がカプセル化を壊すから。interfaceの実装は対象外

・Go言語は型の継承を持たず、interfaceを満たせば自動的にその型として扱える設計にしている


自分の考え

・継承の一番のメリットは「人間が理解しやすい抽象化」だったと思う。is-aで世界を整理できて、共通処理を親に寄せればコードも短く見える。読み手がAIになると、そのメリットはほぼ消える

・自分がフレームワークを作っていた頃、「読みやすさより速く硬いソースであるべき。読めない人はフレームワークに関わるな」と言われた。その「読める人」の役をAIが担うなら、人間向けの読みやすさより、速さと硬さを優先していい

・しかもAIにとっても継承は扱いにくい。1クラス直すのに親や祖父母クラスまでAIに読ませる必要があって、読ませ忘れると的外れな修正をされる

・レビューの軸も「読みやすいか」から「差分で判断できるか」に変わる。親クラスを1行変えると影響は全サブクラスに及ぶのに、差分には1行しか出てこない。継承はここでも分が悪い


■性能やメモリの面で、継承を残す理由になるか

継承をやめてコンポジションに寄せると、性能やメモリで損をするんじゃないか、という疑問は当然出ると思うので、ここで確認しておきます。


事実として

・HotSpotのJITは、呼び出し箇所に来る型が2種類までならインライン化で速くできるが、3種類以上になると仮想呼び出しになってコストが乗る。ただし極端に遅くなるわけではない

・コンポジションは部品ごとに別オブジェクトになるので、そのぶんヘッダ分のメモリが増える。ただしJDK 25でCompact Object Headersが正式機能になり、オプションで有効化するとヘッダを64bitまで縮められるようになった

・今のJavaのGCは世代別が主流で、「ほとんどのオブジェクトは若くして死ぬ」という前提で、短命なオブジェクトを安く回収するように作られている


自分の考え

・性能・メモリの差は、普通の業務アプリならDBやI/Oの待ちに埋もれる程度。大量のオブジェクトを持つデータ構造やホットループだけ、計測して判断すれば十分だと思う

・GCで見ても、メソッド内で使い捨てる部品オブジェクトが増えるぶんには、世代別GCなら回収コストはほぼ気にしなくていい。効いてくるのは、長生きする部品オブジェクトが大量にある場合で、Old領域が膨らむうえに、GCが辿る参照の数も増える

・なので「部品に分けるとGCが重くなる」ではなく、「長生きするオブジェクトを細かく分けるとGCが重くなる」が正確だと思う。キャッシュや大きなコレクションに載せるデータだけは、分け方を意識したい。Compact Object Headersでヒープ全体が小さくなれば、GCの頻度も下がる方向に効く

・つまり、性能やメモリは継承を残す決定的な理由にはならない


■継承についての結論

・継承そのものが悪いのではなく、「局所的に理解・変更・検証できるか」という軸で測ると、親クラスへの依存が影響範囲を見えにくくする分、不利になる場面が増える

・なので、再利用目的の継承は最小限でいい。影響範囲が明示的なまま使える、フレームワーク利用者向けの拡張ポイントと、sealedでの型の分類くらいが残る


■AIが一度に読める量には限界がある

ここまで「AIが読む」前提で書いてきたけど、AIは全部を一度に読めるわけじゃない。ここは大事な制約なので、別に書いておきます。


事実として

・AIが一度に扱える入力の量(コンテキストウィンドウ)には上限がある

・上限に収まっていても、長く渡せばいいわけではない。2023年の研究では、必要な情報が入力の先頭か末尾にあるときに性能が一番高く、長い入力の中ほどにあると大きく落ちることが報告されている。長い入力を扱える前提のモデルでも同じ傾向だった


自分の考え

・小さいプロジェクトならソースもドキュメントも全部渡せるけど、中規模以上になるとプロジェクト全体をAIに読ませるのは無理。現実には、部分的な情報から一部分のソースを生成することになる

・なので「AIに何を渡すか」を毎回人が手で選ぶのではなく、部分的な情報だけで正しく作れる仕組みを最初から用意しておく必要がある

・1つ目はソースの切り方。モジュールの境界をinterfaceなどの契約で切っておけば、AIはそのモジュールの中身と、隣のモジュールの契約だけ読めば作れる。逆に、親クラスを辿らないと挙動がわからない継承は「部分だけでは完結しない」典型で、前半の話の一番の根拠はここにあると思う

・2つ目はコンテキストドキュメントの切り方。全部を1つの巨大なドキュメントにすると、それ自体が読み切れない。プロジェクト全体の短い共通ルールと、モジュールごとの設計メモ、のように階層に分けて、必要な分だけ渡せる形にしておく

・3つ目は必要な情報を引ける仕組み。どのモジュールがどこに依存していて、どのドキュメントが対応しているかを辿れるようにしておけば、AIが自分で必要な文脈を取りに行ける

・中規模以上の開発では、この「部分で完結させる仕組み」を作ること自体が、アーキテクトの一番大事な仕事になっていくと思う


■同じ軸で見ると変わりそうな書き方

ここからは、「局所的に理解・変更・検証できるか」の軸を、継承以外にも当てはめてみます。

・DRYが緩む。共通化すると、それを呼んでいる側同士が結合する。多少重複しても、局所的で独立して直せるほうが差分で判断しやすい。ただし同じ仕様はテストで縛っておく

・明示的なほうが勝つ。アノテーションを付けるだけで裏側で処理が自動的に差し込まれる仕組み(AOPなど)は、人間がボイラープレートを書くのが面倒だから生まれた面がある。AIにはボイラープレートのコストがほぼゼロで、むしろ「コードに書かれていないところで何かが起きる」ほうが追いにくい

・モジュールの切り方がAIの読み込み単位を基準にするようになる。上に書いた通り、AIは全部を一度に読めないので、Controller・Service・Repositoryみたいに層で横に切るより、機能単位で縦に切って、1つの機能がまとまって読めるほうがいい

・型と契約が強まる。人が実装を読んで確かめない分、sealedやrecordで「ありえない状態を作れない」ようにして、コンパイラに検証を寄せる

・テストが人の読む仕様書になる。実装は人にとって読みやすくなくていいけど、テストこそ人が読みやすく書くべき、という逆転

・コメントは「何をしているか」より「なぜそうしたか・何を守るべきか」を書く。何をしているかはAIがコードから読める

・検索しやすい名前が大事になる。AIは必要な箇所をgrepやシンボル検索で探して読む。短くて文脈依存の名前より、長くても一意に検索できる名前のほうがいい。文字列を組み立ててメソッドを呼ぶリフレクションみたいな、検索に引っかからない呼び出しはAIにとって見えない依存になる


■みんなに聞きたい

・「ソースの読み手が人からAIに変わる」という見立て、どう思う?

・現場で最近 extends 書いた?書いたならどんな場面?

・中規模以上の案件で、AIに渡す情報をどう絞ってる?

・「いや継承はこういう時に必須でしょ」「DRYは譲れない」みたいな反論も大歓迎です


次回は、この評価軸で技術選定を見るとどうなるか、を書きます。

0 コメント:

コメントを投稿