本記事では、2025年5月14日に開催されたオンラインイベント「【技術選定を突き詰める】Online Conference 2025」内のセッション「技術の総合格闘技、生成AI時代のフルスタック開発」の内容をお届けします。同セッションでは、Admit AIのKenn Ejima(@kenn)さんに、生成AIの進化で予想される開発体制の変化を踏まえた上で、同氏が見いだしたシンプルなソフトウェアアーキテクチャや、その背景にある考えをお話しいただきました。ぜひ本編のアーカイブ動画とあわせてご覧ください。
Kenn Ejimaさん:まずは自己紹介をさせてください。Xのアカウント名は「Kenn Ejima」で、米国ではこの名前で活動しています。自身の肩書きについて明確に定義するのは難しいのですが、最近は「Full Stack Entrepreneur」と名乗っています。これはフルスタックの考え方を技術以外の分野にも拡張し、“会社を運営する上で必要なことは全て自分でやる”という姿勢を表しています。
6歳のとき、「ゲームを作りたい」という思いからプログラミングを始めました。それ以来、技術の探究を続けており、この世界ではもう長老の域に入っているかもしれません。大学卒業後は、日本で外資系企業やスタートアップを経験し、シリコンバレーではサービス開発に携わるほか、自らプロダクトを開発し、米国を中心とした北米市場向けに展開してきました。
その後、ニューヨークに移り、アジア系米国人向けのマッチングアプリ「EME(East Meet East)」を開発。当時はCTO 兼 Co-Founderとして、まさにフルスタックでプロダクト全体を作っていました。
帰国後は、英語圏で最大級のQ&Aプラットフォーム「Quora」の日本代表を務めました。2022年、ChatGPTが登場し、その圧倒的な進化を目の当たりにして「これは居ても立っても居られない」と感じ、再び起業を決意しました。
最初に手がけたのが、検索拡張生成(RAG)を活用し、社内データを含めたチャットボットの構築を支援する「Gista」です。現在は、米国の大学受験向けに、AIがエッセイの執筆などを支援するカウンセリングサービス「Admit AI」を開発・提供しています。従来は高額な費用がかかっていたオンラインカウンセリングを、AIが代替するというアプローチです。
こうしたプロダクトの開発を通じて、私が採用してきたソフトウェアアーキテクチャや、開発環境に対する考え方をご紹介します。
生成AIの登場で二極化するソフトウェアエンジニアの待遇
最近では生成AIがエンジニアに置き換わり、ソフトウェア開発者はいらなくなるのではないかという議論が出てきていますよね。シリコンバレーのソフトウェアエンジニアの年俸は上昇しており、中央値でも2000万円、上位10%になると5000万円を超える世界になっています。年俸1億円プレーヤーなどの人材も珍しくなくなり、夢のある職業になっている一方、生成AIの登場によってジュニアの入口はどんどん狭くなっており、二極化が進んでいます。
下図のグラフは、米国におけるソフトウェアエンジニアの求人数の推移を示しています。求人数がピークを迎えたのは、コロナ禍の時期でした。当時、米国政府が経済対策としてゼロ金利政策を実施した結果、企業は資金調達が容易になり、積極的に人材採用を行う動きが広がりました。しかし、社会経済活動が正常化するにつれて求人数は減少し、2025年現在ではコロナ禍初期の水準に戻っています。
AIの進化で予想される“少数精鋭化”と“内製化”
AIでソフトウェア開発が加速した未来には何が起きるのでしょうか。これは本当に大きな問いで誰も答えを持っていないと思いますが、私は仮説として“エンジニアの少数精鋭化&開発の内製化”という、一見矛盾している2つのことが同時に起きると考えています。
この仮説では、1人のエンジニアがDevinやCursor、Vercel v0など、さまざまなAIを使いこなすことで、これまでの10倍に及ぶパフォーマンスを発揮できるようになり、少ない人員で組織やプロダクトを運営できるようになります。同時に、現場で働く非エンジニアも自分たちが感じている課題を解決するため、AIの力を借りてソフトウェアを書くようになるでしょう。
技術スタックに対して、色眼鏡を外していく
フルスタック化には、“スタックの簡素化”を伴います。各スタックで本当に必要なものを突き詰めて考えることが、今後のトレンドになるのではないでしょうか。技術スタックの領域では、これまでの常識を疑うことが重要になります。さまざまなツールやインフラが整備されている企業で働いていると、“それがある/作るのが当たり前”という常識が刷り込まれているはずです。今後は、色眼鏡を一つ一つ外していくことが必要になるでしょう。例えば、フロント/バックエンドは本当に分離されているべきなのか、ステージング環境は本当に必要なのか、などを問い直すことは意味のあることだと思います。
従来の開発スタックを見直してみよう
ここで一般的な開発スタックを振り返ります。Macを前提としますが、まず巨大な統合開発環境のXcodeを導入し、コンパイルに必要なツール群をセットアップします。次に、Xcodeに含まれるコマンドラインツールを用いてパッケージ管理ツールのHomebrewをインストールし、開発に必要な基本的なソフトウェアを導入します。
多くの場合、Dockerを利用してプロジェクトごとに独立し、バージョン管理されたデータベース環境などを準備します。PythonやJavaScriptなど、利用するプログラミング言語のランタイムを管理するツールも必要になります(Voltaやuvなど)。そして、開発者がコードを記述・編集できるよう、Visual Studio Code(VS Code)やCursorといったエディタを導入します。これらがそろって初めて快適な開発環境が整いますが、この環境の構築は初心者がつまずくポイントです。
デプロイ環境に関しても、開発体制が確立されている企業ではAmazon Web Services(AWS)やGoogle Cloud Platform(GCP)を使っていると思いますが、皆さんはこうしたクラウドツールに対して複雑さを感じることはありませんか。AWSはローンチされて間もない頃、非常にシンプルなサービスでした。当時は“これなら使える”と感じたものですが、年々機能やリージョンが増え、理解が難しくなってきました。一つの問題を修正すると多くの箇所に影響が出るなど、不要に感じる作業も増え、特定の環境にロックインされているような感覚があります。エンタープライズレベルの要求に応えるために多機能になったことは理解できるものの、本当に全てのケースでこの複雑さが必要なのかと改めて考えたいです。
簡素化の先に見えた開発環境
ロジカルに簡素化を突き詰めた先にあったものは、“開発環境って実はこれだけでよくないか?”という気づきです。VS Codeをインストールし、コマンドラインからJavaScriptのランタイムマネージャーであるVoltaを導入するだけで済みます。SQLiteは単なるファイルなので、プロジェクトごとに一つ作成すればすぐに使い始められます。Dockerを使ってPostgreSQL(Postgres)のようなデータベースをインストールする手間はなく、すぐにアプリケーション開発に取り掛かれるのです。デプロイ環境においても、Vercel、Railway、NetlifyといったPaaSが普及しており、自分たちでインフラの管理を行うことなく、アプリケーションのデプロイを簡単に行える時代になりました。
“Dockerキラー”になり得るSQLite
ここで注目したいのがSQLiteです。これは、Dockerでデータベース管理をする必要性を減らす“Dockerキラー”になり得る重要な要素だと考えています。通常、PostgresやMySQLのようなデータベースを使う場合、プロジェクトごとにDockerコンテナを作成し、インストールする必要があります。
しかし、これからは少数のエンジニアが多くのプロジェクトを管理したり、非エンジニアが自らソフトウェアを開発したりする時代が来ると予想されます。その際に、もし100個のプロジェクトがあれば、100個のPostgresを管理するのは現実的ではありません。SQLiteは単なるファイルであるため、このような状況において、開発スピードやコストの面でより有利になると感じています。
もちろん、高いパフォーマンスや極限の負荷が求められるシステムでは、PostgresやMySQLの方が適しています。SQLiteはファイルベースで排他制御を行うため、スケールには限界があります。しかし、社内システムのようにユーザー数や同時アクセス数が限定的なケースでは、十分な速度で利用できると考えています。
SQLiteは、Devサーバーの起動中のみローカルマシンに読み込まれ、終了すれば一緒にメモリから消える特性を持っています。常時起動するサーバーのイメージとは異なり、アプリケーション起動・終了のライフサイクルと一致しているため、作業するプロジェクトを切り替えるときの管理の複雑さを軽減できるというメリットもあります。
スケール時の懸念に対しては、LibSQL/Tursoという、SQLiteへのアクセスをTCP接続で可能にし、複数のクライアントからの同時接続を処理できるように拡張した技術も存在します。これにより、SQLiteでもある程度のスケールに対応できる選択肢があると考えています。
AIはどう取り入れる?
モデル層への参入機会は当面ない
フルスタックという視点で見ると、AIの活用は重要なテーマです。これまで、ソフトウェアエンジニアと機械学習エンジニアの性質は異なるとみられてきましたが、大規模言語モデル(LLM)のような汎用的なAIが登場したことで、その境界線は曖昧になりつつあります。
現在、LLMがさまざまなタスクをこなせる方向へと進んでおり、企業が独自に開発してきたAIモデルの活用機会は減る傾向にあります。そのため、自社でMLモデルをゼロから構築することは、ごく一部のコアな領域を除いて、あまり現実的ではなくなってきています。もちろん、機械学習の基礎知識や特性を理解する必要はありますが、多くの場面ではAPIを通じてLLMを利用するだけで済むようになっています。むしろ過去に構築した独自のAIモデルやMLOpsのスタックは技術的な負債となりつつあり、新規で同様のものを構築するべきではないという議論も出てきています。
アプリ層で素振りしておく
タイミングとしては、トップレベルのフロンティアモデルと真っ向勝負するには手遅れであり、かといってオープンモデルを業務で実用的に活用するには早すぎてまだ課題が多いのが現状です。従って、当面はアプリケーション層で生成AIを使いこなす“素振り”に注力すべきだと考えられます。
生成AI、特にマルチモーダルなデータをリアルタイムに扱う場面では、さまざまな技術が必要となり、まさに“技術の総合格闘技”の様相を呈しています。LLMの機能をこちらから呼ぶのか/LLMから呼び出されるのかといった新しいパラダイムも生まれており、イベントドリブンなシステムの起点も変化しています。このような状況では、ボトルネックも変わり、フロントエンドやユーザーインターフェース/ユーザー体験(UI/UX)の革新が重要となります。
これを実現する要素技術は多岐にわたり、LLMのテキスト出力を表示するSSE(Server-Sent Events)をはじめ、双方向通信が可能なWebSockets、リアルタイム性の高いWebRTC、ストリーミング中の中途半端な状態のJSONの破損をリアルタイムに修復するOptimistic JSON Parserなどがあります。これらの技術を柔軟に組み合わせ、活用することが求められるため、まさに総合格闘技的なアプローチが必要となるのです。
Ejimaさんの思考過程
絞り込むならJavaScript、Problem-Architecture Fitになっているか?
私がこのアーキテクチャを考える過程で重視したのは、まず“ブラウザで動かすならJavaScriptは必須”という点でした。創業時は、独自のAIモデル開発を想定してバックエンドにPythonとFastAPIを採用しましたが、実際には特定のモデルに固執している場合ではなく、モデルをどんどん乗り換える状態が続いていたため、TypeScriptのみによるフルスタックに移行しました。
外部APIとの連携やLLMの出力処理はI/Oバウンドな処理が多く、JavaScriptの非同期処理モデルがCPUやメモリを無駄なく活用する上で有利です。Node.jsを使えば、nginxのようなリバースプロキシや基本的なファイル配信機能も代替できるため、Amazon S3なしでも簡易的なファイル配信システムであれば迅速に構築できるメリットがあります。このように、問題とアーキテクチャの相性が良い(Problem-Architecture Fit)と考え、JavaScriptを中心とした構成を選択しました。
環境を絞って実現した認知負荷の軽減
ステージングサーバーの必要性についても再考しました。これまで、本番環境でしか発生しない問題への防波堤として利用されてきましたが、システムがシンプルになるにつれて環境による差異が生じる可能性のある箇所そのものが減り、その意義は薄れてきました。思い切って環境を本番環境とローカルのみに絞ったところ、気持ち良いほど認知負荷が軽減されました。フロント/バックエンドそれぞれに複数のステージング環境を用意すると、環境変数などの管理対象が掛け算的に増えて煩雑になりますが、環境数を減らすことでシンプルになります。
テストの対象も最適化
UI/UXの重要性が増している現在、詳細なテストコードをメンテナンスすることのコストパフォーマンスは低下していると感じています。見た目の使いやすさや直感的な操作感はテストコードで捉えにくいものです。そのため、サインアップや決済など、失敗が許されない重要な機能(ハッピーパス)のエンドツーエンドテストに絞る方が適していると感じます。
一方で、話題のVibe Codingでは、AIが自動でコードを生成しますが、失敗も少なくありません。そこで、最初にどのようなものを作るべきかのテストを記述させることで、AIがテストを実行しながら自己修正していくアプローチが注目されています。テストファーストの手法が、Vibe Codingによって復活する可能性もあると考えています。
選ばれし「Ultra Light Stack」
このような経緯を経て、現在私が採用している超軽量スタック「Ultra Light Stack」をご紹介します。技術スタックでは、Remix(React Router v7)、Drizzle ORM(SQLite/LibSQL)、Tailwind CSS v4を使用しています。デプロイ環境では、Render、Turso、Cloudflareを気に入って使っています。ここからは個人的な好みが強く反映されますが、私は以下の構成で快適に開発できています。
Remix(React Route v7)は、Next.jsと比較して圧倒的にシンプルで、かつてRuby on Railsの初期バージョンに触れた時と同じような衝撃を受けました。HTML、JavaScript、そしてTailwind CSSによるスタイルまでを一つのファイルに記述できる点は非常に効率的です。さらに、データの取得(GET)やフォーム送信による更新(POST)といったサーバー側の処理も同じファイル内で扱えるため、シンプルにフルスタックアプリケーションを構築できます。
Drizzle ORMは、長年Railsを使ってきた私にとってTypeScriptエコシステムのORMは不満の種でしたが、DrizzleはPrismaと違ってヘビーなランタイムの制約がなく、型の事前生成なども不要で、各関数呼び出しに対して発行されるSQLが1回のみと予測しやすい点が魅力です。自分はDrizzle上にActiveRecord風のラッパーを作ってRailsのような書き味にしています。“フルスタック化に踏み切れる”と決意できた理由の一つです。
Renderは、以前からあるPaaSのHerokuをより使いやすくしたようなサービスで、git pushするだけで自動的にデプロイされます。Vercelと似ていますが、通常のNode.jsサーバーが常時起動するため、AIアプリのようなストリーミングを使った長時間の接続やプライベートネットワーク接続が必要な場合に適しています。
Tursoは、SQLiteをネットワーク経由でアクセス可能にするクラウドインフラで、500個までデータベースが無料で利用できるという、データベースがより手軽になる未来を見据えたサービスです。 Excelファイルを一つ作るような手軽さでWebプロダクトを開発できる時代において重要な要素になると考えています。
Cloudflareは、ファイルストレージやCDNが比較的早い段階で必要になるシステム開発において役立ちます。ローカルファイルシステムではすぐに限界が来ますが、Amazon S3はエグレスの料金が高額な中、Cloudflareはエグレス料金が無料で使いやすく、ブラウザからPresigned POSTで直接アップロードもできます。サーバーレス技術であるCloudflare Workersはまだ先進的すぎますが、将来的な可能性を感じています。Cloudflareは、AWSやGCPに代わるプラットフォームとして急速に人気が高まっていると感じています。
生成AI時代の正解はまだ誰にも分からない
このように、生成AIの時代はまだ始まったばかりです。現時点では、どの技術スタックが最適なのか、どのようなアーキテクチャを選べば将来的な負債を抑えられるのか、明確な答えは誰にも分かりません。だからこそ、皆さんとさまざまな議論や意見交換を重ねながら、共にその最適解を見つけていければと思っています。
アーカイブ動画・発表資料
イベント本編は、アーカイブ動画を公開しています。また、当日の発表資料も掲載しています。あわせてご覧ください。
▼動画・資料はこちら
技術の総合格闘技、生成AI時代のフルスタック開発
※動画の視聴にはFindyへのログインが必要です。