
はじめに
こんにちは!
エンジニア3年目のTKDSです!
今回はLLMアプリケーション開発におけるプロンプトの取得と管理について書きました。
LLMを利用したアプリケーションのプロンプト管理は多くの方が悩んでる問題だと思います。
そこで、開発中や運用時に重要となるプロンプト配信の可用性、プロンプト切り替えのしやすさ、何が今動いているか把握のしやすさの観点などから管理方法と取得方法を整理してみたいと思います。
個人の意見ですので異論は認めます。
プロンプトの管理方法
バージョニングやプロンプトの保存場所など、プロンプトを保管・管理する方法について考えていきます。
今回はスプレッドシートなどで管理、git管理、プラットフォームで管理3パターンを想定しました。
ここでいうプラットフォームはLangfuseなどのプロンプト管理機能があるソフトウェアを指しています。

管理方法
スプレッドシートなどで管理
メリット
- 管理が楽
- 見やすい
- リアルタイムでの更新が可能
- 共同編集しやすい
- コメントなどで意見など書き込みやすい
- 非エンジニアにプロンプトを見てもらう場合にも共有しやすい
デメリット
- コピペが必要
- 誤爆編集などがある
- アプリ側からの参照が面倒
- アプリに埋め込む仕組みは別途考える必要がある
git(github)管理
メリット
- PRなどで管理すれば変更履歴やコメント内容を追える
- 使い慣れたツール
- タグなどを活用して特定バージョンのプロンプトの組み合わせを固定できる
- ビルドパイプラインから利用しやすい
デメリット
- 共同編集しにくい
- github上などでコメントを募集する場合、アカウントが必要。非エンジニアに見てもらう場合、アカウント発行が必要で余計な費用がかかる
プラットフォームで管理
メリット
- 専用ツールなのでプロンプト管理に特化してる
- バージョニングに対応してる
- APIがあるので、CDパイプラインから利用しやすい
- プレイグラウンドが付属してる場合もあるので、試行錯誤がしやすい
デメリット
- 高度な権限管理は有償プランだったりする場合が多い
- プラットフォームの維持コストがかかる
- バックアップ・レストアの方法を整備しておく必要がある
プロンプトの取得方法
次はビルド時やアプリデプロイ時のプロンプトの取得方法についてです。
こちらも3つ考えてみました。
リアルタイム取得方式、事前埋め込み、後から環境変数やファイルで注入の3つです。
取得方法
- リアルタイム取得方式
- メリット
- 変更をすぐに反映できる
- デメリット
- リクエストごとに取りにいくのか、一定時間で更新するようにするのかなどアプリ側で考慮事項が増える
- 実現可能な手段(例)
- プラットフォームからAPI経由で取得
- ファイルをオブジェクトストレージなどにホスト
- メリット
- 事前埋め込み
- メリット
- ビルド時にプロンプトが固定されることによって、コンテナイメージが同じ間は変更によって動作が変わらない
- コンテナイメージを変えればすぐに切り戻せるので運用が楽
- デメリット
- 変更に毎回ビルドが必要(これは工夫によってある程度解決できる)
- コンテナレジストリにイメージがたくさん溜まってしまう(これは工夫によってある程度解決できる)
- 実現可能な手段(例)
- ビルド時にプロンプトをプラットフォーム、オブジェクトストレージ、gitリポジトリなどから取得して埋め込み
- コードに直書き
- メリット
- 後から環境変数やファイルで注入
- メリット
- 簡単に変更できる
- バージョニングは別手段でやる必要がある。
- コピペしてこないといけない
- デメリット
- シークレット経由で埋め込む場合、環境変数を変えたらPodの再起動が必要
- 実現可能な手段(例)
- (k8sの場合) ボリュームマウントやconfigmap経由で渡す
- メリット
3つともメリット・デメリットがあります。
個人的にはコンテナイメージの不変性が確保できるため、事前埋め込みが良いと思っています。
特に本番環境以降は開発エンジニアが一切触れない場合、インフラエンジニアにコンテナイメージのタグ差し替えだけ依頼すれば良いので、新たに習得してもらうことがなく運用がまわりやすいイメージを持っています。
ここまで管理方法と取得方法を列挙したので、組み合わせを考えていきます。
管理方法x取得方法の組み合わせ
組み合わせの上で考えること
これまで列挙した内容から、プラットフォームで管理が一見良さそうに見えますが、開発中に頻繁更新する場合に手間だったり、本番では誰が変更するのか、どこまで触っていいのかなど判断が難しいところです。
また、プラットフォームについて十分に耐障害性を考慮しないと単一障害点になりえます。
そこで現状の考えとして開発・運用工程を考慮した上での使い分けを考えてみました。
(あくまで個人の意見でこれで運用しているわけではありません。)
前提として、コンテナイメージをビルドしてアプリをデプロイしていることとします。
組み合わせ例
最初にあげた開発中や運用時に重要となるプロンプト配信の可用性、プロンプト切り替えのしやすさ、何が今動いているか把握のしやすさの観点も加えて組み合わせとその理由を考えていきます。
工程はローカルで開発中、ステージング環境、本番環境の3つに分けてます。
ローカルで開発中
- 開発中の試行錯誤
- スプシ管理 x アプリ稼働、後から環境変数やファイルで注入
- 考慮観点
- プロンプト配信の可用性
- 開発環境なので考慮外
- 環境でのプロンプト切り替えのしやすさ
- コピペするだけなので簡単
- 何が今動いているか把握のしやすさ
- アプリが参照してるファイルや.envをいじるので基本的に一意になるはずなため把握しやすい
- 変更時のホットリロード等の仕組みを用意しておくともっと間違えにくくなるかも
- プロンプト配信の可用性
- 開発中の試行錯誤
ステージング環境
- 評価中
- プラットフォーム x アプリ稼働、後から環境変数やファイルで注入
- 結合テストなど
- 本番と同等(後の項目で記載します)
- 考慮観点
- プロンプト配信の可用性
- 開発環境なので考慮外
- 環境でのプロンプト切り替えのしやすさ
- プラットフォームで配信するプロンプトを切り替えるだけなので簡単
- 何が今動いているか把握のしやすさ
- ログなどで担保する。開発環境よりは一定下がる
- プロンプト配信の可用性
- 評価中
本番環境
簡単に変更できることを重視する場合
- 組み合わせ
- プラットフォーム x アプリ稼働後から環境変数やファイルで注入
- 備考
- プラットフォーム自体をHA構成にする
- 取得できなかった場合にコンテナイメージ内にあるプロンプトにフォールバックするなどの対策をする
- 考慮観点
- プロンプト配信の可用性
- プラットフォームが単一障害点になりうるので備考にあるような対策を行う
- 環境でのプロンプト切り替えのしやすさ
- プラットフォームで配信するプロンプトを切り替えるだけなので簡単
- 何が今動いているか把握のしやすさ
- 開発環境よりは一定下がる、ログなどで可視性を担保する
- プロンプト配信の可用性
- 組み合わせ
不変なことを重視する場合
- 組み合わせ
- git管理 x 事前埋め込み
- 備考
- 管理自体にはプラットフォームを使うのもあり、ビルドパイプラインでコンテナイメージにバンドルして作成する
- コンテナイメージごとに何が入ってるかわかり管理が簡単
- 簡単に切り替えができないのはデメリットだが、開発者が簡単に挙動を変えられてしまうのは問題なので、許容すべき
- バージョンごとにイメージビルドせずに切替したい場合、まとめてバンドルしてビルドし、環境変数などで使用バージョンを切り替えるのもあり
- 考慮観点
- プロンプト配信の可用性
- 事前にバンドル済みなため、本番で取得できないことはない
- 環境でのプロンプト切り替えのしやすさ
- コンテナイメージを差し替えるだけなので簡単
- 複数バージョンをバンドルする場合は環境変数などを書き換えるだけなので簡単
- 何が今動いているか把握のしやすさ
- コンテナイメージごとに一意になるので把握しやすい。ただし、イメージタグ名などで工夫すべき
- 複数のバージョンを入れてバンドルする場合は組み合わせ間違いなどが起こらないように注意すれば大丈夫そう
- プロンプト配信の可用性
- 組み合わせ
以上が個人的な開発・運用工程ごとのプロンプト管理・配信方法の使い分けの案でした。 基本的には変更のしやすさと間違ったプロンプト変更がされないようにすることのトレードオフで、開発中は変更のしやすさ・本番環境ではコンテナイメージの固定による不変性の安定を重視してます。 あとは地味にプロンプト取得方法のところで書いてる「インフラエンジニアにコンテナイメージのタグ差し替えだけ依頼すれば良いので、新たに習得してもらうことがなく」の部分が大事だと思ってます。 新たに習得してもらうのはドキュメント作成や相手の学習用の工数などがかかるため、できるだけ今まで通りの手順でシンプルに運用できる方法が望ましいです。
まとめ
今回はLLMアプリケーションにおけるプロンプトの扱いについて検討してみました!
プロンプトの管理・運用に悩んでる方はぜひ参考にしてみてください!