はじめに
株式会社LITALICOでエンジニアをやっている@kazuisです。
この記事は『LITALICO Engineers Advent Calendar 2025』の15日目の記事になります。
LITALICOは、放課後等デイサービスや就労移行支援の事業所を300以上運営している会社です。
だがしかし、障害者福祉・介護領域・学校教育領域でSaaSプロダクトを自社で開発し提供している会社でもあります。
ChatGPTやGitHub Copilotに代表される大規模言語モデル使っていますか?
コードの記述、デバッグ、ドキュメント作成といったエンジニアの核心的業務を劇的に変化させつつあります。
そんな2025年の年末に、日本でWindows95が発売された30年前の1995年11月23日を思い出して黄昏れるための記事です。(当時自分は、高校生、C言語でミニゲームを作っていたりしました。)
30年前のエンジニアリングの難しさ
1995年当時、業務系システムから組み込みソフトウェア、パッケージソフトに至るまで、開発言語の主流はC言語およびC++だったと思います。これは、ハードウェアのリソース(CPUパワーやメモリ容量)が今(2025年)と比較して極めて貧弱であったため、人間が機械語に近いレベルで最適化を行う必要があったからです。
「Hello, World!」を表示するプログラムを見ながら体感してみてください。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
// 1. メモリの確保 (malloc)
char *message = (char *)malloc(sizeof(char) * 14);
// メモリ確保に失敗していないか確認(当時のマナーであり、必須のエラー処理)
if (message == NULL) {
fprintf(stderr, "メモリの確保に失敗しました。\n");
return 1;
}
// 2. 確保したメモリ領域にデータをコピー
// ポインタ変数 message が指すアドレスに文字列を格納します。
strcpy(message, "Hello, World!");
// 3. 標準出力へ書き出し
// ポインタを渡して、そのアドレスにあるデータを表示させます。
printf("%s\n", message);
// 4. メモリの解放 (free)
// 使い終わったら必ずOSに返却します。これを忘れるとメモリリークになります。
free(message);
return 0;
}
※実行できるか未確認なコード
ポインタ is 何?
char *messageの宣言は、文字データそのものではなく、そのメモリ上のアドレス(ポインタ)を扱う変数を意味する。この「実体」と「参照」の区別は、当時のプログラミング初心者の大きな壁でした。ポインタ操作の誤りは、OSや他アプリの領域を書き換える危険があり、「セグメンテーション違反」としてプログラムの強制終了を引き起こすこともありました。 これがわからないとコード書くことはできない世界でした。
メモリがあふれる
mallocで確保したメモリは、使用後に必ずfreeで解放する必要があります。これを怠ると「メモリリーク」となり、メモリが消費されたまま再利用できなくなってしまいます。サーバープログラムでは、わずかなメモリリークでも繰り返し発生すると物理メモリを食い尽くし、システムダウンの原因になります。長期運用テスト等でメモリリークがない事を検証したり、あらゆる分岐ルートで例外発生時も含め、freeが正しく呼ばれるかを検証する必要がありました。
なんか挙動不審
さらに深刻な問題は、freeで解放された後のポインタにアクセスするバグでした。 運が良ければすぐにクラッシュしますが、厄介なことに、その場所にたまたま別の重要なデータが書き込まれていた場合、そのデータを破壊しながら処理が続行されてしまうことがあります。この種のデータ不整合は原因究明が非常に難しく、数日間徹夜で原因究明をしたりします。
なにやら難しそうで、複雑そうですよね? このように、30年前のエンジニアは、顧客の要求を満たすロジックを実装することに加え、あるいはそれ以上に、「メモリを慎重に管理し、コンピュータの機嫌を損ねないようにする」ことに多くの時間を費やしていたのです。これをメモリ管理といいます。
複雑性の隠蔽
2000年代、JavaやC#の普及により「ガベージコレクション(GC)」が標準化されました。メモリ管理は自動化され、エンジニアはポインタの呪縛から解放されました!! しかし、エンジニアの仕事は楽になったでしょうか? 否、我々は解放された脳のリソースを、より複雑な「オブジェクト指向設計」や「Webフレームワーク」の習得へと振り向けたのでした。オープンソース(Linux)やフレームワーク(struts等)もこの頃から普及していきました。それまでは「車輪の再発明」が各現場で行われていたのです。オリジナルなフレームワークを作っていた人も多かったと思います。
難しい事、複雑な事を、隠蔽することによって、エンジニアの手法も進化していきました。
AWSやGCPもそうですよね。もう、物理層は隠蔽化されて開発者は意思しない世界になっています。
そして2025年、AIによるコード生成は、この流れの最新かつ最大の波です。かつてメモリ管理を機械に任せたように、コーディングそのものを機械に任せようとしています。技術のレイヤーは変われど、「人間がやらなくていいことを機械に譲り、より高次の問題に取り組む」というエンジニアリングの進化プロセス自体は、30年前から何一つ変わってはいません。
AI時代のボトルネック
「書く仕事」から「選ぶ仕事」への転換
この30年間でエンジニアの役割は大きく変化しました。1995年頃のエンジニアは、コンピュータの制約(リソース等)と向き合いながら、実現したい機能をコードに「翻訳する」ことに多くの時間を費やしていました。しかしAI時代では、その役割は、単にコードを書く「コーダー」から、設計し、最適な技術を選定する「アーキテクト」へとシフトしたと考えます。
AIという優秀な(ちょいちょい嘘をつく)翻訳者をそばに置いています。エンジニアは、ソートアルゴリズムを書く必要はありません。エンジニアの仕事は、AIが提示した複数の実装案の中から、現在のプロジェクトの要件(パフォーマンス、可読性、保守性)に最も適した選択肢を見極める「目利き」の能力へと変化しているのです。
大量のコードから選ぶのは難しい
爆発するレビューコスト
AIはコーヒーを飲んでいる間に数千行のコードを生成します。
しかし、そのコードが「正しい」保証はありません。AIが生成した一見もっともらしいコードの中に潜む、微細な論理エラーやセキュリティホール、あるいは存在しないライブラリへの呼び出し(ハルシネーション)を見つけ出す作業は、自分でゼロから書くより大変負荷が高い時間になります。(楽しくない)
ある研究ではAIツールを使用した開発者が、タスク完了までに逆に19%多くの時間を費やしたというデータもあるようです。
人間の認知限界
AIがどれだけ大量のコードを吐き出そうとも、それを受け止める人間の脳のスペック(ワーキングメモリ)は30年前と変わりません。人間が一度に把握できる情報は4つ前後と言われています。 AIによって生成されたブラックボックス化したコードの山は、エンジニアの認知負荷を限界まで高めます。
コードの全体像、データの流れ、依存関係...それらを脳内で整理できなくなったときに、エンジニアは、そのアプリケーションの品質を担保する事はできなくなるでしょう。
AI時代において、本当の制約条件はCPUの速度ではなく、エンジニアの「認知能力」なのだと思います。
変わるもの
「AIが出てきてエンジニアの仕事はなくなるのか?」という話が巷では時々でてきます。
この問いに対する答えは、自分は「No」だと思っています。
ただし、30年前のエンジニアの仕事と、2025年のエンジニアの仕事と違うように変化は大きいと思います。
コードをタイピングする速度や、フレームワークを知っていることの価値は今のように大きい価値ではなくなるかもしれません。 AIというパートナーと仲良くするには、エンジニアは以下のようなスキルが重要になるでしょう。
- AIが生成したアウトプットを品質保証・評価する「審美眼」
膨大なAI生成コードの中から、筋の良い実装を選び抜き、悪手を見抜く能力
- 複雑なドメインルールや事象を構造化する「設計力」
モジュールをどう分割するか、どのクラウドサービスを組み合わせるか。AIという強力な「部品メーカー」から供給されるパーツを、堅牢で持続可能なシステムへと組み上げる「アーキテクト」として能力
- ビジネス課題を技術的課題へと翻訳する「定義力」
「何を作るべきか」を定義する力、すなわち要求分析・要件定義の能力
シンプルにいうと上流工程で、システムを定義する力、品質をつくる力が重要になるんだと思います。
[tips] AI駆動型のマイクロサービス開発
現代のソフトウェア開発において、二つの大きな課題があります。
一つは人間の認知負荷をいかに最小限にするかという点、もう一つはAIが生成する大量のコードの品質をどのようにコントロールするかという点です。これらの課題を克服することが、今後のプロダクト開発の鍵を握ると考えられます。大規模なシステムを一塊で扱うのではなく、小さいシステムの組み合わせでサービスを構築するというアプローチは、複雑性の低減に貢献します。
しかし、このアプローチを突き詰めたマイクロサービスアーキテクチャは、その導入と運用において高い難易度を伴うことが指摘されています。サービス間の連携の複雑化、分散トレーシングの難しさ、インフラストラクチャの管理コストなど、多くのオーバーヘッドが発生するため、実際にはモジュラモノリスへと移行するプロダクトも少なくないと聞きます。
これらのAIによる解決策が実現すれば、「マイクロサービスは難しい」という現状認識を打破し、マイクロサービスという分離性の高いアーキテクチャのメリットを最大限に享受しつつ、AIでコード生成の負荷を最小限にするという理想的な開発体制を構築できそうだと考えています。
変わらないもの
それは、「問題を解決し、価値を生み出す」というシステム開発の喜びだと思います。 1995年のC言語プログラマが、苦労の末にmallocとfreeの整合性を取り、プログラムが完成した瞬間に感じた達成感と、2025年のエンジニアが、プロンプトを工夫し、AIと共に複雑な機能を実装し終え、ユーザーから感謝された瞬間に感じる幸福感も変わらずにエンジニアのモチベーションになるものと思います。
さいごに
最後まで読んでもらって、ありがとうございます。
毎月AIの進化があってできることが増えて、便利が止まりません。
数年先がどうなるかわかりませんが、社会課題がエンジニアリングによって解決できる事が増えると思うと楽しみでしょうがないです!
自分も世の中の困り事が少しでもなくなるよに精進していきます。
