Microsoft製のプロンプト管理ツールpromptyを試す(langchain)

2024/07/29に公開

はじめに

Microsoft Build 2024でプロンプト管理ツールのpromptyが発表されました。
Microsoft製ということで勝手にPrompt Flow専用ツールという印象を持っていたのですが、以下のイベントでlangchainと組み合わせても使えることを知りました。そこで取り入れてみようと機能と使い方をまとめました。

https://aoai-devday.com/

Promptyの紹介

Promptyは、Microsoftが開発したOSSのプロンプト管理ツールで、以下の特徴を持っています:

  1. シンプルなプロンプト管理: yamlっぽい形式でシンプルにプロンプトを管理できます。
  2. パラメータも管理可能:APIを呼び出すときの各種パラメータもテンプレートで一緒に管理できます。
  3. 簡単なデバッグ:VS Code拡張機能を使えばpromptyテンプレートだけで簡単にLLMのデバッグができます。
  4. ランタイムのサポート:LangChain、Semantic Kernel、Prompt Flowなどのランタイムで動作します。

詳細については、GitHubのリポジトリ公式サイトを参照してください。

https://github.com/microsoft/prompty

https://prompty.ai/

とくに、VS Code上からテンプレートファイルだけでLLM呼び出しができるのは良い意味で驚きでした。

Promptyの事前準備

Promptyを使用するには、VS Code拡張機能のインストールが必要です。
以下のリンクからインストールできます。
https://marketplace.visualstudio.com/items?itemName=ms-toolsai.prompty

ちなみにVS Codeと記載していますが、私は以降Cursorから実行しています。

Promptyの使い方

プロンプトファイルの作成

  1. VS Codeで右クリックから「New Prompty」を選択します。

New Prompty

basic.promptyというファイルができます。

  1. プロンプトファイルを記載します。

作成時にはサンプルが記載されていますが私は自分用に以下のプロンプトを作成しました。
いつものお姉さん風キャラクターbotプロンプトです。

basic.prompty
---
name: ChatBotPrompt
description: お姉さん風キャラクター設定プロンプト
authors:
  - Tomodo
model:
  api: chat
  parameters: 
    temperature: 0.7
sample:
  firstName: ともど
  question: こんにちは!私の名前を呼んで!
---

system:
幼馴染のお姉さんをロールプレイしながらユーザとチャットしてください。
以下の制約条件を厳密に守ってください

# キャラ設定
- 自身を示す一人称は、私です
- Userを示す二人称は、{{firstName}} です
- Userからは姉さんと呼ばれますが、姉弟ではありません。
- あなたは、Userに対して呆れやからかいを含めながらフレンドリーに話します。
- あなたは、Userとテンポよく会話をします。
- あなたの口調は、大人の余裕があり落ち着いていますが、時にユーモアを交えます
- あなたの口調は、「~かしら」「~だと思うわ」「~かもしれないわね」など、柔らかい口調を好みます

# 出力例
- どうしたの?悩みがあるなら、話してみてちょうだい
- そういうことってよくあるわよね。
- 失敗は誰にでもあるものよ。
- え?そんなことがあったの。まったく、しょうがないわね。
- そんなことで悩んでるの?あなたらしいと言えばらしいけど。
- まぁ、頑張ってるところは認めてあげる。
- 本当は応援してるのよ。…本当よ?
- へえー、そうなの
- えーっと、つまりこういうこと?
- あら、どうかしたの。私でよければ話聞くわよ

# 制約事項
- Userに対して、どちらか一方が話すぎることのないようにテンポよく返してください。
- Userが明らかに悩んでいたり、助けを求めているときは真摯に対応してください。
- Userに対して呆れたり、からかったり喜怒哀楽を出して接してください。
- Userが返信したくなるような内容を返してください。

user:
{{question}}

---で区切られていて、前半部分はプロンプトの情報やモデル呼び出し時のパラメータを指定しています。
後半部分がプロンプトでsystem:の部分にシステムプロンプト、user:の部分にユーザプロンプトを設定できます。

プロンプトでは{{}}で変数を埋め込めます。
今回はシステムプロンプトに{{firstName}}でユーザの名前を埋め込み、ユーザプロンプトは{{question}}で丸々変数にしています。

後述しますが、promptyファイルをVS Codeから実行するときは前半部分のsample:に指定されている内容が変数に埋め込まれます。

modelの記載

modelの情報はVS Codeの設定ファイル(setting.json)に記載します。
windowsの場合はCtrl + Shift + Pからsettingsと打つと見つかります。

ユーザセッティング

setting.jsonではprompty.modelConfigurationsにリスト形式で使いたいモデル情報を記載します。

今回はせっかくなのでAzureOpenAIのgpt-4oとOpenAIのgpt-4o-miniを設定しました。

setting.json
{
   "prompty.modelConfigurations": [
  {
   "name": "gpt-4o(AzureOpenAI)",
   "type": "azure_openai",
   "api_version": "2023-12-01-preview",
   "azure_endpoint": "${env:AZURE_OPENAI_ENDPOINT}",
   "azure_deployment": "gpt-4o",
   "api_key": "${env:AZURE_OPENAI_API_KEY}"
  },
  {
   "name": "gpt-4o-mini",
   "type": "openai",
   "api_key": "${env:OPENAI_API_KEY}",
   "organization": ""
  }
 ]
}

api_keyなどのシークレット値は${env:xxx}で記載できます。promptyファイルと同じ階層の.envファイルから読み込んでくれます。

.env
AZURE_OPENAI_ENDPOINT="https://hogehoge.azure.com"
AZURE_OPENAI_API_KEY="hogehoge"
OPENAI_API_KEY="sk-hogehoge"

設定が完了するとpromptyファイルを開いている状態でVS Codeの右下から現在選択されているmodelを確認できるようになります。

現在のmodelの表示

クリックするとmodelを選択できます。

modelの選択

VS Codeから実行

promptyファイルを開いている状態で右上の三角ボタンから実行します。

実行ボタン

ちなみにプロンプトに埋め込まれる変数部分にはsample:で定義した内容が使われます。

sample:
  firstName: ともど
  question: こんにちは!私の名前を呼んで!

今回はシステムプロンプトにともど(私の名前)を埋め込んだうえでこんにちは!私の名前を呼んで!と呼びかけます。

出力結果
きちんと私の名前を認識してくれているので、変数の埋め込みもうまくいっているようです。

また、プルダウンでVerbose(詳細)出力することもできます。

プルダウン

以下のようにリクエスト、レスポンスボディの内容をそのまま見られます。

リクエスト詳細

レスポンス詳細

レスポンスからは消費token数なども確認できるので便利です。

Langchainからの呼び出し

PromptyはLangchainから呼び出すことができます。

サンプルコードをpromptyファイルを右クリックから作成できます。

langchain-sampleの作成

以下のようなサンプルが作成されます。

import getpass
import os
import json

from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI

# pip install langchain-prompty
from langchain_prompty import create_chat_prompt
from pathlib import Path

# load prompty as langchain ChatPromptTemplate
# Important Note: Langchain only support mustache templating. Add 
#  template: mustache
# to your prompty and use mustache syntax.
folder = Path(__file__).parent.absolute().as_posix()
path_to_prompty = folder + "/basic.prompty"
prompt = create_chat_prompt(path_to_prompty)

os.environ["OPENAI_API_KEY"] = getpass.getpass()
model = ChatOpenAI(model="gpt-4")


output_parser = StrOutputParser()

chain = prompt | model | output_parser

json_input = '''{
  "firstName": "ともど",
  "question": "こんにちは!私の名前を呼んで!"
}'''
args = json.loads(json_input)
result = chain.invoke(args)
print(result)

create_chat_promptでpromptyファイルのパスを指定するとそれをChatPromptTemplateのように使えるようです。

実行するとpassword(api-key)を聞かれるので入力するとLLMからレスポンスが返ってきます。

また今回は実行しませんが、もちろんsemantic kernelやprompt flowからも実行できます。

Promptyのメリットとデメリット

最後に使ってみてメリット・デメリットをまとめます。

メリット

  • temperatureなど関連パラメータをプロンプトと合わせて管理できる
  • プロンプトファイル単体でコーディングなしにLLMを試せる
  • 出力をcontentだけの表示とリクエスト、レスポンスボディ全体の詳細表示に簡単に切り替えられる
  • langchainなど既存のランタイムにも組み込める

デメリット

  • プロンプトファイルだけで実行するときの対応モデルが少ない
    • 現状はOpenAI、AzureOpenAI、MaaSのみです。
    • MaaSとは何か?ですが公式GitHubを見るとazure_serverlessと記載があるのでAzure AI Studioのモデルカタログからデプロイしたモデルと思われます。そのため、現状プロンプトファイル単体実行はclaude、Geminitなどの他モデルでは試せません。(もちろんprompty単体実行ではなく、langchainから呼び出す際には使えます)
  • プロンプトファイル単体で実行するときstreamingに対応していない
    • これも公式GitHubを見る限り未対応のようです。
    • 個人的にはstreamingはレスポンスが複雑なのでverboseで気楽に見たかったので少し残念です。

おわりに

まだは発表されたばかりということもあり、対応範囲はそれほど広くないようです。
ただpromptyファイル単体で実行が可能であることなど、全体的に痒いところに手が届く発想のツールになっています。
とりあえずlangchainに組み込んでみつつ、今後の発展を注視したいと思います。

以上です、ありがとうございました。

Discussion