はじめに
こんにちは、サーバーサイドエンジニアの中川(@tkdev0728)です。
最近、AIをプロダクトに組み込む機能の実装をしました。実装を通じて、AIプロバイダーを柔軟に選択できる設計にしておいてよかったと感じたので、その話を書きます。
AI業界は動きが速い
今回の機能では、Gemini Enterprise Agent Platform(旧VertexAI) を採用しました。既存のAI機能にはAzure OpenAIを使っていますが、今回使いたいモデルはAzure経由では提供されないためです。
ただ、Gemini Enterprise Agent Platform を選んだはいいものの、コスト・性能・速度のバランスが最適なモデルをこれから選定する必要がありました。AI業界では新しいモデルが次々と発表されますし、今日ベストな選択が数ヶ月後も最善とは限りません。
そのため「念のため、差し替えやすい設計にしておこう」と思って実装を始めました。
インターフェースで抽象化してプロバイダーへの依存を断ち切る
やったことはシンプルです。AIプロバイダーとのやりとりをインターフェースで抽象化し、ユースケース層が具体的な実装に依存しないようにしました。
// usecase層にインターフェースを定義 type GenerativeAIAdaptor interface { Generate(ctx context.Context, prompt string) (Response, error) } // ユースケースはインターフェースに依存する type AIUseCase struct { adaptor GenerativeAIAdaptor } func (u *AIUseCase) Execute(ctx context.Context, input Input) (Output, error) { result, err := u.adaptor.Generate(ctx, buildPrompt(input)) // ... }
プロバイダーごとの実装はそれぞれ用意しますが、ユースケースから見ると同じインターフェースです。
// Gemini実装 type GeminiAdaptor struct{ /* ... */ } func (g *GeminiAdaptor) Generate(ctx context.Context, prompt string) (Response, error) { /* ... */ } // Claude実装 type ClaudeAdaptor struct{ /* ... */ } func (c *ClaudeAdaptor) Generate(ctx context.Context, prompt string) (Response, error) { /* ... */ }
プロバイダーごとにレスポンスのフォーマットが異なるため共通インターフェースの裏側でその差分を吸収する実装が必要でしたが、
コンテナの組み立て時にどの実装を注入するかを決めるだけなので、ユースケース層には一切触れずにプロバイダーを切り替えられます。
また、機能ごとに異なるモデルを使いたいケースも想定されていたため、使用するモデルは環境変数で切り替えられるようにしました。なお、Vertex AIはGeminiだけでなくClaudeなど複数のモデルをサポートしているため、環境変数にはClaudeのモデル名を指定することもできます。
VERTEX_AI_MODEL_NAME_FEATURE_A=gemini-3.5-flash VERTEX_AI_MODEL_NAME_FEATURE_B=claude-haiku-4-5
機能単位でコストと精度のバランスを調整できますし、新しいモデルを試す際にもコードを変えずに済みます。
モデルの切り替えを気軽に試せた
今回の機能はコーディング支援ではなかったため、高精度よりも軽量・安価・高速なモデルを探していました。
まず gemini-2.5-flash と claude-haiku-4-5 で動作確認し、レスポンスの品質や特性を比較しました。色々検証した結果、Claudeの方向で進めようとしていたところ、開発中に gemini-3.5-flash が発表されました。翌日には差し替えて検証できました。環境変数を変えるだけで即座に試せたのは、この設計があってこそです。
最終的には開発中のコストも踏まえて、初回リリースはClaudeを採用することにしました。
「新モデルがいつ来るか」を予測していたわけではありません。ただ、AI業界の動きの速さを考えると「いつかは必要になるだろう」と思っていた設計が、想定より早く役に立ちました。
おわりに
AIモデルの変化は早く、新モデルの発表も突然やってきます。まさか開発中に発表されるとは思わなかったのですが、素早く試せる設計にしておいたおかげですぐ試せてよかったです。
どのモデルが最善かはプロダクトの用途やコスト・精度のバランスによって変わります。AI業界の変化の速さを考えると、特定のプロバイダーに強く依存した設計は後々の足かせになるので開発当初から柔軟な設計にしておくのが大切ですね。
ただ、この設計が本当に有効かどうかはまだ本番での長期運用で確かめる必要があります。開発中に役立ったことは確認できましたが、本番環境での実績はこれから積み上げていくところです。
引き続き運用しながら検証していきます。
具体的な実装内容に興味を持った方はぜひカジュアル面談にお越しください!