最近、AIを使ったプロダクトをAIを使って開発している中で、プロンプトの管理をどうするのがいいのか、ずっと考えている。しかも、似たような問題に全く別の2つのプロダクトで同時にぶつかっていて、なかなか答えが出ない。ただ、考えているうちに、これは単に「プロンプトをどこに保存するか」という話ではなさそうだと思うようになった。むしろ、専門家が持っている判断基準や会話の進め方を、どうやってAIプロダクトの中に受け渡すのか、という話に近いと言える。
正直まだ結論はない。ただ、現時点での仮説としては、プロンプト本文だけを管理しても足りない。モデル、パラメータ、システムプロンプト、セッション間のハンドオフ、評価、バージョン管理まで含めて、専門家とエンジニアが一緒に触れる場所が必要なのではないか、という気がしている。整理がてらそんな話を書く。みんなどうしてるのかも気になるテーマなので。
どういうプロダクトを作っているか
僕が関わっているのは、どちらもこれまで人と人が対話していて行っていたことの片側をAIが担うようなプロダクト。代替とまで言うと言い過ぎだけど、人との対話をAIが一部限定的に代わりに行う、というイメージ。
ここでのAIとの対話はいわゆるフリートークではない。一定のドメイン知識と専門性を持った会話ができる必要がある。一つは対外的にも公表している『Speech Link』で、こっちは言語聴覚士的な振る舞いが求められる。ただし、言語聴覚士そのものを代替するものではなく、専門家が設計・監修した範囲の中で、練習や振り返りの一部をAIが担う、という位置づけに近い。もう一つはここでは言えないんだけど、そっちはそっちで別の専門家であることが求められる。
人間が完全にAIで代替できるとは思っていないけれど、これまで人間じゃないとできなかったことの一部をAIで担えるようにして、リソースを広げる、エンハンスメントする、みたいなのがどちらも目的になっている。イメージとしてはカウンセリングやコーチングをAIに受ける、みたいな感じが近いかもしれない(ちょっと違うか)。
ちなみにSpeech Linkの方は、本番でGemini Live APIを使うときの構成でも別途悩んでいて、それは前に別の記事に書いた(
)。今回のはそれとはまた違うレイヤーの、プロンプトそのものを誰がどう作るか、という話。
エンジニアが作れる部分と、作れない部分
僕らソフトウェアエンジニア(エンジニアっていうと物を作るエンジニアとかいろいろいるけど、ここではソフトウェアエンジニアの意味で、以下単にエンジニアと書く)は、こういうプロダクトを作るとき、いわゆるWebアプリケーション形式でUIを持たせたりする。対話はキーボード入力だったり音声だったり、その形でAIとやり取りする。
「それってChatGPTと何が違うの?」と言われると、ざっくり言えば「専門家としての振る舞い」ができる、というのが大きな違いかなと思っている。今やChatGPTも音声でやり取りできるので、見た目だけだと差がわかりにくいがやり取りの質の違いと思ってもらえばいい。
で、Webアプリケーションの部分そのものは普通に作れる。UIも全然作れる。それは本職だし多くの場合特別難しいこともないので。問題はLLMとの対話設計の部分だ。
ソフトウェア的には、ユーザーの入力を受け取って、一定のプロンプトと一緒にLLMに投げて、レスポンスを整形して画面に出す。基本はこれだ。マルチエージェントや複雑なワークフローになったりアダプティブにやるとなるともう少し込み入ってくるけど、やっていることはLLMのAPIにリクエストを投げてレスポンスを処理する、というところに集約される。
つまりこのプロダクトの価値は、コードの方ではなく、どういうプロンプトを投げるか、セッションとセッションの受け渡しをどう設計するか、ユーザーの対話から何を抽出して次のインプットにするか、というような対話設計の側にあると言っても過言ではない。そしてここが、エンジニアの本職から一番遠いところだったりする。
いちばんの難所は、専門性の受け渡し
ここで効いてくるのが、専門家と呼ばれる人のエッセンスを抽出してプロンプト設計に落とし込む、という作業。ここにエンジニアと専門家の間で、結構深い隔たりがあるなと感じている。
順番に書くと、まずエンジニアが「専門家らしい振る舞い」をさせるためのプロンプトを考えるのは、実際難しい。それなりに考えて作ったものを専門家に触ってもらうと、多くの場合「これじゃダメだ」となる。応答のクオリティに満足してもらえない。
やっかいなのはその次で、エンジニア側は、専門家が言う「応答クオリティの高い・低い」をそのドメインの専門教育を受けていないエンジニアには判断できない。ドメイン知識がない、と言ってしまってもいいのかもしれない。とにかく良し悪しがわからない。だから専門家に「もっとこういう回答をしてほしい」と言われて、それをプロンプトに落とし込んで、専門家が「これなら大丈夫」と思える回答を引き出すまで、ひたすら往復することになる。専門家が新人に教えるみたいに指摘して、それをエンジニアがプロンプトの形に作り込んでLLMに投げて品質を確認して……と、間に伝言ゲームが挟まる感じ。ここがうまく回らない。というか辛い。
しかも満たすべきはプロンプト本文だけじゃなくて、システムプロンプトやシステムパラメータとの合わせ技でもある。受け渡すべき「専門性」が、エンジニアにとっては評価もできないし、置き場所も一箇所じゃない、という状態になっている。
もう一つ厄介なのが、専門家の方が、ちょっと進んでいると自分でChatGPTなどを使っていて「AIとの対話でこのくらいの質は出せるはず」と確信を持っているケース。ところがChatGPTのようなプロダクトは、モデル単体ではなく、UI、会話履歴の扱い、ツール、プロダクト側の安全設計や挙動制御などが組み合わさった体験として提供されている。API経由でコールする場合、同じバージョンのモデルを使っていてもそのあたりは自分のアプリケーション側で設定するものなので、わりと素の状態に近い。だから同じことをやっているつもりでも回答精度にばらつきが出て、「ChatGPTではできたのに」という期待値とのズレが生まれる。繰り返しになるが、ChatGPTのような完成されたチャットプロダクトと、API経由でモデルを呼び出す自前アプリケーションでは、同じモデル名を使っていても、周辺の体験設計やシステム指示、ツール、会話履歴の扱いが違う。だから「ChatGPTでできたこと」をそのままAPIアプリに持ち込めるとは限らないのだ。
だったら専門家にプロンプトを作ってもらう
じゃあどうするか。一つ分かりやすいのは、伝言ゲームをやめて、専門家自身にプロンプトを作ってもらって、それをエンジニアに渡す形にすることだ。エンジニアはプロンプトを実行するための箱を作る。ワークフローやオーケストレーションも含めて箱を用意して、LLMへの指示そのものは専門家に作ってもらう。
ただここで難しいのは、専門家が非エンジニアだと、APIを使ってテストしてもらうのがなかなか厳しいこと。だからみんなChatGPTでプロンプトを作り込むんだけど、さっき書いたようにChatGPTとAPIコールでは前提条件が変わってくる。
理想は、本番で使う想定のAPIモデルを指定して、必要ならシステムパラメータも設定して、システムプロンプトも注入して、その状態で満足いく回答品質になるまでプロンプトを練り上げてもらうこと。でも、専門家にそこまで求められるのか、という別の課題が出てくる。
仕組みの面でも課題がある。たとえばLangfuseのプロンプトマネジメント機能を使えば、それに近いことはできる。プレイグラウンドでAPIのモデルもパラメータも指定できるので、そこを非エンジニアの専門家に開放して、練り上げてもらって、磨き込んだら本番プロンプトとして昇格させる。アプリケーション側は常に同じキーでプロンプトを取り出して実行しているだけなので、そこに影響なくやれる。これはこれで一つの解だと思う。
ただLangfuseのプレイグラウンドはあくまで1セッション単位だ。少なくとも自分たちが専門家に渡したい「複数ステップの対話ワークフロー全体」を、そのまま自然に設計・検証する場所としては少し粒度が合わなかった。長大なものを設計しようとすると、1つのプロンプトで全部処理しようとして巨大なプロンプトになる。巨大なプロンプトは重要情報の位置や構造によって挙動が不安定になり得るなど、いろいろ問題があってあまり望ましくないとされている。かといってセッションをぶつ切りにしてA→B→C→Dと繋ぎ、Aの結果をBに渡してまたLLMで処理して……とやっていくと、今度はこのハンドオフの設計が重要になってくる。そのハンドオフ込みでLangfuseのプレイグラウンドで練り上げられるかというと、できない。専門家に渡したい単位と、ツールが扱える単位がずれている、という感じ。
結局、自前で作っている
なので別の何かがあるのかな、というところなんだけど、いいツールを知っている人がいたら教えてほしい。ただ、探すよりは自前で作ってしまった方が早いのかな、という気もしている。
実際どちらのプロダクトも、コールする予定のAPIを指定して、場合によってはAPIそのものも専門家側で変更できるようにして、その上でシステムパラメータやシステムプロンプトを含めて指定できる管理ツールを自前で持つ、という形に現時点では落ち着いている。
ただ、その管理ツールの粒度が2つのプロダクトでも微妙に違う。専門家のAI習熟度と実現したいことの複雑性に引っ張られている、という方が正確かもしれない。
片方は、専門家がチャットを使うこと自体にまだ不慣れな人たちだったりするので、アプリの管理機能の一つとして、プロンプトをその場で実行して確認できる機能を作り込んでいる。APIやパラメータを直接扱う前提のツールは、専門家の本来の作業環境から遠いのだ。プロンプト全文を自由に設計させるというより、システムプロンプトと一定の型をテンプレートとして用意して、振る舞いを大きく特徴づける何箇所かだけをフィールドとして用意して、そこに入力されているものをプレースホルダーで差し込めるようにする、という実装だ。専門家がプロンプトを作って保存して公開する、というCMSっぽい機能も付けているし、公開したプロンプトがいまいちだったときに戻せるよう、バージョニングやリバートの機能も持たせている。自由度を絞る代わりに、踏み外しにくくしている、という方向。
もう片方は、これは僕が作ったわけじゃなくてエンジニアの方が似たものを作ってくれているんだけど、こっちは専門家がかなりChatGPTを使いこなしているのもあって、よりプリミティブな画面でモデルやパラメータを素で設定できるツールになっている。自由度が高いぶん、専門家の習熟度に乗っかれる、という方向。ただこっちのプロダクトでは、仕様上より大きな処理をする分プロンプトのサイズの問題が出ていて、プロンプトを分割して処理も分割していく必要が出てきている。そしてそこに関しては、エンジニア側も専門家側も最適な答えを持っていない。どこで切って、何をどうハンドオフするのか、場合によっては決定論的な処理を挟むのか。世の中にベストプラクティスやガイドライン的なものは転がっているが、ではそれを自分たちのプロダクトにどう当てはめるか、は答えがない。その辺りを参考にしつつ試行錯誤するしかないのだ。そしてこれはどちらかが一元的に決めるのは難しいとも感じている。
まだ答えは出ていない
このワークフローそのものを専門家が組めるようにする必要があるのかな、と思いつつ、なんとなく車輪の再発明っぽい気もしていて、どうするのがいいのか決めかねている。プロンプト単体を渡せるようにするだけでは足りなくて、ハンドオフまで含めて渡せる場所がいる、というあたりが今の引っかかりどころ。
結局のところ、AIが扱う領域がエンジニア的にはドメイン知識として存在していないとき、その専門性をエンジニアと非エンジニアの間でどう受け渡すか、という話なんだと思う。プロンプトを誰が書くか、どの単位で処理を分けるか、セッション間で何をどうハンドオフするか、それを支えるツールは買うのか作るのか。このあたりに実例や具体的なやり方について答えを持っている人がいたら、ぜひ教えてほしい。今のところは上に書いたやり方に落ち着いているけど、もっといいのがあれば乗り換えたい。