KINTO FACTORYにおけるマイクロサービスアーキテクチャの採用と生成AI時代への対応

KINTO FACTORY開発グループ、技術広報グループ、QAグループなどなど色々な事を兼務でやらせて頂いているエンジニアの中西です。KINTO FACTORYでエンジニアリングリードとしてマイクロサービスアーキテクチャを採用した経緯と、その後の展開についてお話しします。
なぜマイクロサービスを選んだのか
短期的には、運用負荷が増え、開発の手間もモノリシック構成より大きくなることは想定していました。それでも、組織やサービスをスケールさせる段階では、チームを細かく分けられるなどのメリットが大きいと判断したのがポイントです。
また、私自身、過去に担当したシステムでも、顧客規模の拡大に合わせて柔軟にスケールできるよう、マイクロサービスで開発を進めた経験がありました。この経験も判断材料の一つとなっています。ただし、システムアーキテクチャには唯一の正解はなく、サービス開発のスピード感、将来のスケール、チームの規模に応じて、適切に選択していくことが重要だと考えています。
トヨタグループのスケール
私たちはトヨタグループの中で事業を拡大していく役割を担ったソフトウェア開発組織です。トヨタグループは世界最大の自動車メーカーであり、世界中で1億5000万台ものトヨタ車が走っています。
KINTO FACTORYはトヨタ自動車のリフォーム、アップグレード、パーソナライズなどを提供しているサービスです。将来的にこれらの車両が私たちのサービスを利用することを想定すると、以下の課題に直面します。
- スケーラビリティ: 膨大な数の車両に対応できる拡張性
- 高速性: 24時間365日、世界中で走行する車両への即座の応答
- コスト効率: 高負荷に伴うインフラコストの最適化
パフォーマンスとコストの関係
高負荷はそのままコスト増につながります。たとえばAWSであれば、ECSのコンテナ数やインスタンス数が増えるほどコストは大きく変動します。
私は過去の開発経験から、パフォーマンスチューニングにおいて「無駄を削ぎ落とす」ことの重要性を学びました。パフォーマンスを突き詰めていくと、処理はどんどん低レイヤーへと移っていきます。実際、JavaのようなVM環境やSpring Bootのような大規模フレームワークは、相対的にオーバーヘッドが大きくなることもあります。大規模なシステムでは、その特性を理解した上で最適化やチューニングを行うことが求められます。
オンプレ時代には、Apacheで運用していたシステムの性能がボトルネックとなり、アプリケーション層に処理を渡す前にApacheモジュールを自作して対応したこともありました。この経験から、システム設計では「必要な箇所だけを低レイヤーでチューニングできる状態」にしておくことが重要だと考えています。全てを低レイヤーで実装する必要はなく、開発効率とのバランスを取りながら設計することがポイントです。
現在のクラウド環境において、その解決策の一つがマイクロサービスです。マイクロサービスであれば、パフォーマンスが求められる箇所だけを切り出し、ピンポイントでチューニングすることができます。他のサービスはそのまま維持しつつ、必要な部分だけ外出しして最適化できる。これが、マイクロサービスを選択する大きな利点の一つだと考えています。
こうした設計思想を支えるのが、マイクロサービスが持つ「小さく試せる」特性と、それによって広がる 「技術選定の自由度」 です。
マイクロサービスが可能にした技術選定の幅
理想と現実のギャップ
マイクロサービスを採用したことで、サービスごとに最適な技術を柔軟に選べる土台ができました。例えば当初は、私自身運用経験がありパフォーマンスも十分なGo言語を使うことを検討しましたが、以下の課題に直面しました。
- 社内でGo言語を扱える人材が限られていた
- 組織として過去にGo言語開発経験がないため、採用メッセージが弱かった
- 当時の開発体制や採用市場を踏まえると、JavaとSpring Bootであれば安定的に人材を確保できるという判断
こうした背景から、初期フェーズではKotlinをメインに選択しましたが、その後エンジニアが増えた現在では、Go言語で開発したサービスも実際に運用しています。つまり、当初の制約に縛られるのではなく、組織の成長や人材状況に応じて技術選定を柔軟に進化させてきた、という点がKINTO FACTORYの開発の大きな特徴です。
Kotlinの採用
開発スケジュールはあらかじめ決まっており、利用可能なリソースを踏まえた結果、KINTO FACTORYの開発開始当初はSpring Bootを選択することになりました。ただし「単にJavaで開発するだけでは、新たなチャレンジが生まれにくいのではないか」と考え、社内で既に利用実績があったKotlinを採用しました。
私自身がAndroid開発でKotlinを扱っていたことも大きな安心感の一つです。サーバーサイドKotlinの利用は初めてでしたが、社内には知見を持つメンバーがいたため相談できる環境がありました。また、言語的な習熟度についても、JetBrainsのIDE(IntelliJ IDEA)による強力な補完機能のおかげで、Kotlin未経験者であってもJava経験者であればスムーズに開発に参加できることがわかっていました。
さらに、KotlinにはJavaと比べて次のようなメリットがあります。
1. コードが簡潔(ボイラープレート削減)
data class Car(val model: String, val year: Int)
👉 Javaだと何十行も必要な getter/setter・toString・equals/hashCode が、Kotlinでは1行で自動生成。
2. Null安全
var car: Car? = null
println(car?.model) // 安全にアクセス(nullならnullを返す)
👉 ?
を使うことで コンパイル時にNullチェックが担保され、実行時のNullPointerExceptionを未然に防げる。
3. 関数型プログラミングのサポート
val cars = listOf(Car("Toyota", 2022), Car("Lexus", 2025))
val models = cars.map { it.model }
👉 map
・filter
・ラムダ式・拡張関数などを活用し、柔軟で表現力のあるコードが書ける。
4. Javaとの高い互換性
// KotlinからJavaのクラスをそのまま利用可能
val date = java.util.Date()
👉 JVM上で動作するため、既存のJavaライブラリやフレームワークをシームレスに利用できる。
5. 非同期処理が簡単(コルーチン)
import kotlinx.coroutines.*
fun main() = runBlocking {
launch {
delay(1000)
println("Finished!")
}
}
👉 suspend
関数や launch
を使って、複雑な非同期処理を直感的に記述できる。
3つのポイント
- KotlinはJavaと比べて 簡潔・安全・表現力豊か
- Null安全・関数型サポート・コルーチンで モダンな開発が可能
- Java資産を活かしつつ、新しい設計スタイルを取り入れられる
Rustへの挑戦
マイクロサービスによりサービス単位で独立して実装できたからこそ、私たちは一部の機能でRustに挑戦できました。もしモノリシック構成を採っていたら、新言語を取り入れるのは難しかったでしょう。マイクロサービスという仕組みがあったからこそ、リスクを抑えながら実験的に適用できたのです。
以下のような理由からRustを選びました。
- 人材戦略: 低レイヤーでカリカリにチューニングできるエンジニアを採用できる
- 技術的魅力: Stack Overflowでも人気の高い言語として注目されている
- 将来性: Rustはその高い安全性と信頼性を持つ特長から、自動車業界での採用が拡大している
Rustは自動車業界での活用が広がりつつあり、Woven Planet(現Woven by Toyota)のArene OSチームの求人でも言及されていました。こうした動向も参考にしながら、私たちの開発でもRustを導入することにしました。
小さく試して積み重ねる文化
そして何より大きかったのは、マイクロサービスにより小さく試しながら成果を積み重ねられたことです。社内に知見のない言語に挑戦する不安はありましたが、リスクを限定した小規模導入から始め、実運用を通じて成果を蓄積できました。このプロセスがRust採用の推進力となり、今では入社動機につながったエンジニアが活躍する基盤になっています。
将来への挑戦
将来的には、KINTO FACTORYにおいても自動車のハードウェアに近い領域でRustの強みを発揮できるようにし、そうした挑戦に取り組めるエンジニアが集まる環境をつくっていきたいと考えています。
さらに長期的には、Rustに限らず 多様な技術的挑戦を続けられる組織 を目指しています。こうした文化を通じて、新しい価値をともにつくり出せる環境を築いていくことが、私たちの目指す姿です。
スキーマ駆動開発の導入
インターフェースの重要性
マイクロサービスアーキテクチャにおいて、最も重要なのはサービス間のインターフェース定義です。インターフェースは単なる「入出力の仕様書」ではなく、チームや組織全体の開発スピードと品質を支える契約そのものです。
一見地味に見える部分ですが、これを正しく整備できるかどうかで、プロジェクト全体の成否が決まると言っても過言ではありません。
従来はExcelやWordといったドキュメントでインターフェースを管理することが一般的でした。しかし、この方法には以下のような問題があります。
- バージョン管理が困難(最新がどれか分からなくなる)
- 更新漏れが発生しやすく、実装との差分が広がる
- 複数のチームで並行開発する際に、矛盾や二重管理が避けられない
マイクロサービスのようにサービス数が増え、独立してリリースサイクルを回すスタイルでは、この「Excel管理」は早々に破綻します。だからこそ、常に正しいインターフェース定義にアクセスできる仕組みと、多重管理や齟齬を起こさない運用設計が不可欠になります。
スキーマ駆動開発のメリット
この課題を解決するアプローチがスキーマ駆動開発(Schema-First Development)です。KINTO FACTORYにおいても、スキーマ駆動開発を導入したことで次のような効果を得ることが出来ています。
-
自動生成による効率化
バリデーションロジックやスタブコードを人手で書かずに、スキーマから自動生成できます。これにより実装スピードが向上し、ヒューマンエラーを削減できます。 -
言語非依存の柔軟性
プロジェクト内で複数言語(JavaScript、Kotlin、Rust、Goなど)が混在していても、同じスキーマからクライアントやサーバーコードを自動生成可能。これにより技術選定の自由度が広がり、チームごとの得意領域を活かす開発が可能になります。 -
エラー削減と整合性担保
手作業によるスペルミスや記述漏れといった「人間特有のミス」を大幅に減らせます。加えて、CI/CDパイプラインでスキーマの整合性を常時検証することで、変更が即座に検知され、品質が保たれます。 -
変更に強い確実性
マイクロサービスが独自に進化しても、スキーマがインターフェースとして存在するため、相互に影響を受けにくい。結果として、サービスごとの独立性と同時に全体の安定性を維持できます。
生成AI時代におけるマイクロサービスの重要性
生成AIは「非常に優秀な新入社員」のような存在です。ただし、一度に扱える コンテキスト(文脈) には限界があります。だからこそ、小さく分割され、明確なインターフェースでつながるマイクロサービス との組み合わせが効果を発揮します。
AIコーディングとの親和性
AIに依頼をする際に欠かせないのは、あいまいさを排除することです。明確なゴールが示されれば短時間で成果を出せますが、指示が曖昧だと期待外れの方向へ進んでしまうことも少なくありません。
そのために重要なのは、最初に必要な情報を整理してシンプルに伝えること、そして進行中に確認と修正を行うことです。役割を切り分けたマイクロサービスは、この考え方を実装レベルで支える仕組みだと言えます。役割がはっきりすることで、次のような利点が得られます。
- 型・制約・具体例が明確になる
- DTOやバリデーション処理などの生成対象が一目で分かる
- 破壊的変更を差分として即座に検知できる
実務においては、各サービス単位でAIが理解しやすい構造化された APIドキュメント を整備することが安定性につながります。例えば以下のような内容です。
- 最新スキーマ
- リクエスト/レスポンス例
- エラー処理の設計方針
これらをREADMEなどのMarkdownファイルにまとめ、AIに渡す最小限で十分な資料とすることで、生成結果の精度と安定性は飛躍的に向上します。
コンテキストの問題
生成AIを活用した開発には、次のような課題があります。
- 大規模なコンテキストを保持・理解するのが難しい
- システムが複雑になるほど不具合が発生しやすい
これは人間にも当てはまります。大規模システムは全体像の把握が難しく、結果としてバグを生みやすい構造を持ちます。
マイクロサービスアーキテクチャは、この課題を解消するために登場したアプローチです。
マイクロサービスのメリット
サービスを小さな単位に分割することで、
- 生成AIも人間も理解すべき範囲がシンプルになる
- バグが発生しにくく、修正もしやすい
- モジュール化によって開発効率が大幅に向上する
結果として、マイクロサービスは生成AI時代の開発において「スピード」と「品質」を両立させるための最強の基盤となります。
2つの重要ポイント
インターフェースの重要性
KINTO FACTORYの開発を通じて得られた知見は、生成AI時代のシステム開発においても大きな指針となります。
-
サービスを小さく保つ
マイクロサービスに分割することで、チームの独立性と開発スピードを高め、将来的なスケーラビリティを確保できる。 -
インターフェースを明確にする
スキーマ駆動開発により、仕様の曖昧さを排除し、複数チームや複数言語が混在する環境でも一貫性と整合性を維持できる。
これらは単なる設計手法にとどまらず、生成AIとの協働を前提とした開発の安定性を支える実践知です。役割を切り分け、仕様を契約として明文化することで、人間とAIがともに安心して開発を進められる環境をつくり出せます。
理想と現実のギャップに直面しながらも改善を積み重ねることで、KINTO FACTORYは進化を続けています。生成AI時代においても、この2つのポイントは変わらぬ指針となるでしょう。最初の思想通りにうまくいった部分とうまくいかなかった部分はありますが、小さな改善を積み重ねながら、現在もサービスを運用しています。
1億5000万台のトヨタ車を視野にした壮大な挑戦は、まだ始まったばかりです。この大きな挑戦に一緒に立ち向かって行ける仲間を募集しています。カジュアル面談なども実施していますので、もし興味を持って頂けましたらぜひご連絡お待ちしております。
関連記事 | Related Posts
We are hiring!
【KINTO FACTORYバックエンドエンジニア(リーダークラス)】KINTO FACTORY開発G/東京・大阪
KINTO FACTORYについて自動車のソフトウェア、ハードウェア両面でのアップグレードを行う新サービスです。トヨタ/レクサス/GRの車をお持ちのお客様にOTAやハードウェアアップデートを通してリフォーム、アップグレード、パーソナライズなどを提供し購入後にも進化続ける自動車を提供するモビリティ業界における先端のサービスを提供します。
【PjM】プロジェクト推進G/東京
新サービス開発部 プロジェクト推進グループについてプロジェクト推進グループでは、クルマのサブスクリプションサービスである『 KINTO ONE 』をはじめ、国内向けサービスのプロジェクト計画立案からリリース、運用保守に至るまでのプロジェクト管理を行っています。