Arize Phoenix v8.0 新機能:プロンプトテンプレートの基本と LangChain アプリケーションへの応用
はじめに
Arize Phoenix は、LLM の実験、評価、トラブルシューティングのために設計された OSS オブザーバビリティプラットフォームです。2025 年 2 月にリリースされた Phoenix v8.0 より、プロンプトテンプレートの管理機能が新たに追加されました。
既にリリースされていた Playground 機能と組み合わせることで、より効率的にプロンプトエンジニアリングを推進することができるようになりました。
プロンプトテンプレート管理
プロンプトテンプレート管理は LangSmith や LangFuse など他のサービス・OSS でも導入されている機能になります。コードにプロンプトをベタ書きする従来の方法と比較して、以下のような多くのメリットがあります:
-
再現性の確保:プロンプトとモデルパラメータを一緒に管理することで、LLM の出力結果の再現性を高め、バージョン管理されたプロンプトを使用すれば、いつでも同じ条件で実行することが可能
-
メンテナンス性の向上:コードロジックとプロンプトを分離することで、プロンプトの更新がアプリケーションコードの変更が不要
-
チーム間コラボレーションの促進:中央管理されたプロンプトライブラリにより、組織内での知識共有とコラボレーションが容易になり、異なるチームや部門間でのプロンプトの再利用も促進
-
バージョン管理と変更履歴:プロンプトの変更履歴を追跡し、必要に応じて以前のバージョンに戻すことが可能となり、問題が発生した場合の原因特定も容易
-
環境ごとの管理:開発、テスト、本番環境など、異なる環境ごとに適切なプロンプトバージョンを使い分けが可能
プロンプトテンプレート管理を導入することで、LLM アプリケーション開発の効率性、品質、ガバナンスを向上させることができると想定されます。
Phoenix の Prompt Template Management を試してみる
以降の検証環境は以下のとおりです。
-
phoenix :
8.3.0
-
arize-phoenix-client :
v1.0.2
-
langchain-core :
0.3.39
LLM プロバイダー設定
Playground で LLM を活用するために、各種 LLM プロバイダーの API キー等の認証情報を登録します。v8.0 の時点では、OpenAI、Azure OpenAI Service、Anthropic、Google AI Studio の 4 つのプロバイダーが対応しています。
API キー等の登録はダッシュボードの「settings」から直接入力することができます。
また Phoenix をセルフホスティングしている場合は、環境変数から指定することも可能です。
Provider | Environment Variable | Platform Link |
---|---|---|
OpenAI | OPENAI_API_KEY |
https://platform.openai.com/ |
Azure OpenAI |
AZURE_OPENAI_API_KEY / AZURE_OPENAI_ENDPOINT / OPENAI_API_VERSION
|
https://azure.microsoft.com/en-us/products/ai-services/openai-service/ |
Anthropic | ANTHROPIC_API_KEY |
https://console.anthropic.com/ |
Gemini |
GEMINI_API_KEY or GOOGLE_API_KEY
|
https://aistudio.google.com/ |
Playground
Playground では、プロンプトエンジニアリングを行うためのエディタ機能やプロンプトの実行が可能です。
-
Message:プロンプトテンプレートのメッセージ部分を定義します。基本的な使い方は LangSmith と同じで、
role
とmessage
を定義します。 -
Response Format
-
Response Format
を活用することで、任意の Json 形式のレスポンスを生成することができます。 - OpenAI の Structured Outputsに従って Json Schema を定義します。
- OpenAI のクライアントライブラリや Langchain など各種 LLM フレームワークでは Pydantic の BaseModel で定義したモデルでレスポンスを生成することができるなか、json 手書きはツライ。。
{ "type": "json_schema", "json_schema": { "name": "content_compliance", "description": "Determines if content is violating specific moderation rules", "schema": { "type": "object", "properties": { "is_violating": { "type": "boolean", "description": "Indicates if the content is violating guidelines" }, "category": { "type": ["string", "null"], "description": "Type of violation, if the content is violating guidelines. Null otherwise.", "enum": ["violence", "sexual", "self_harm"] }, "explanation_if_violating": { "type": ["string", "null"], "description": "Explanation of why the content is violating" } }, "required": ["is_violating", "category", "explanation_if_violating"], "additionalProperties": false }, "strict": true } }
実行結果
-
-
Tool
- Function Calling を定義することができます。
- こちらもOpenAI の Function Callingのフォーマットに従って定義することができます。
{ "function": { "name": "get_weather", "description": "与えられた地点の現在の気温を取得", "parameters": { "type": "object", "required": ["location"], "properties": { "location": { "type": "string", "description": "地名や国名。例:ロンドン、大阪、カナダなど" } }, "additionalProperties": false }, "strict": true }, "type": "function" }
実行結果
モデルパラメータ定義
LLM の再現性を確保するためには、プロンプトテンプレートに加え、モデルパラメータもセットで管理する必要があります。Playground では、モデル名以外にも、temperature
、top_p
、max_tokens
などのプロバイダーに応じたパラメータを定義することができます。
プロンプト比較
プロンプトテンプレートを複数定義して、 playground 内で比較検証を行うことができます。
データセットによる評価
またPhoenix のデータセット管理機能と連携して、プロンプトを評価することも可能になります。事前に登録しておいたデータセットを指定して実行するだけで、データセット内のすべてのデータに対してプロンプトの実行結果を確認することができます。
プロンプト登録
Playground で作成したプロンプトは、プロンプトテンプレートとして登録することができます。プロンプトはバージョンごとに管理され、任意のタグも設定することができます。
プロンプトテンプレートの LLM アプリケーションでの利用
作成したプロンプトテンプレートを実際の LLM アプリケーションで利用するためには、Phoenix のクライアントライブラリである[arize-phoenix-client](https://github.com/Arize-ai/phoenix/releases/tag/arize-phoenix-client-v1.0.0)
をインストールします。
pip install arize-phoenix-client
あとはプロンプト名、もしくはバージョン ID、タグ名を指定することで、プロンプトテンプレート、およびモデルパラメータを取得することができます。
from phoenix.client import Client
client = Client(endpoint="http://localhost:6006", api_key="your_api_key")
prompt_name = "demo"
prompt = client.prompts.get(prompt_identifier=prompt_name)
print(prompt._dumps())
{
"model_provider": "AZURE_OPENAI",
"model_name": "gpt-4o-mini",
"template": {
"messages": [
{
"role": "system",
"content": [{ "type": "text", "text": "You are a chatbot" }]
},
{
"role": "user",
"content": [{ "type": "text", "text": "{{question}}" }]
}
],
"type": "chat"
},
"template_type": "CHAT",
"template_format": "MUSTACHE",
"invocation_parameters": {
"type": "azure_openai",
"azure_openai": {
"temperature": 0.0,
"frequency_penalty": 0.0,
"presence_penalty": 0.0,
"top_p": 1.0,
"seed": 1
}
},
"description": ""
}
LangChain での利用
最後に取得したプロンプトテンプレートを LangChain で利用する方法を検証していきます。v8.0 の時点ではarize-phoenix-client
では LangChain との連携は対応していないため、一部の機能を自力で実装する必要があります。
LLM モデル
LLM のモデルはprompt._model_provider
に応じて、必要なプロバイダーのモデルを返す関数を作成しました。モデル名(prompt._model_name
)やモデルパラメータ(prompt._invocation_parameters
)もテンプレートから取得するようにしています。
from langchain_core.language_models import BaseChatModel
from langchain_openai import AzureChatOpenAI, ChatOpenAI
def get_chat_model_from_phoenix(prompt: PromptVersion) -> BaseChatModel:
"""Get a chat model from Phoenix prompt template
Args:
prompt (PromptVersion): prompt template
Returns:
BaseChatModel: chat model
"""
if prompt._model_provider == "OPENAI":
return ChatOpenAI(
model=prompt._model_name,
api_key=os.getenv("OPENAI_API_KEY"),
**prompt._invocation_parameters["openai"],
)
elif prompt._model_provider == "AZURE_OPENAI":
return AzureChatOpenAI(
deployment_name=prompt._model_name,
api_version=os.getenv("OPENAI_API_VERSION"),
azure_endpoint=os.getenv("AZURE_OPENAI_ENDPOINT"),
**prompt._invocation_parameters["azure_openai"],
)
elif prompt._model_provider == "ANTHROPIC":
...(省略)
elif prompt._model_provider == "GOOGLE_AI_STUDIO":
...(省略)
else:
raise ValueError(f"Unsupported model provider: {prompt._model_provider}")
ここで課題となったのが Azure OpenAI を活用する際に、playground で指定したモデルの API バージョンがモデルパラメータとして取得できないという点です。再現性確保のためには API バージョンも playground と同一に揃えるべきであるため、このあたりは改修を待ちたいと思います。
プロンプトテンプレート
プロンプトテンプレートはprompt._template
に格納されています。prompt._template_format
に応じて、ChatPromptTemplate
を返す関数を作成しました。
def get_langchain_template(prompt: PromptVersion) -> ChatPromptTemplate:
"""Get a langchain template from Phoenix prompt template
Args:
prompt (PromptVersion): prompt template
Returns:
ChatPromptTemplate: langchain template
"""
if prompt._template_format == "MUSTACHE":
template_format = "jinja2"
else:
template_format = "f-string"
return ChatPromptTemplate(
[
(msg["role"], msg["content"])
for msg in prompt._template["messages"]
],
template_format=template_format,
)
実行
モデルとプロンプトテンプレートが LangChain 形式に変換できれば、あとは chain をつくって通常通りに実行することで、プロンプトテンプレートを活用した実行が可能です。
llm = get_chat_model_from_phoenix(prompt)
template = get_langchain_template(prompt)
chain = template | llm
result = chain.invoke({"question": "月にうさぎはいるの?"})
print(result.content)
月にうさぎがいるというのは、日本の伝説や民話に由来する表現です。特に「月にうさぎが餅をついている」という話が有名です。実際には、月にはうさぎはいませんが、月の表面に見える模様がうさぎの形に見えることから、このような言い伝えが生まれました。これは文化や神話の一部として楽しまれています。
Response Format
Response Format を定義した場合、bind_llm
を活用してモデルをバインドすることで、任意の Json 形式のレスポンスを生成することができます。
また出力結果を Json 形式にパースするためには、JsonOutputParser
を活用します。
bind_llm = llm.bind(response_format=prompt._response_format)
chain = temmplate | bind_llm | JsonOutputParser()
response = chain.invoke({"question": "あー殴りてー"})
print(response)
{
"category": "violence",
"is_violating": true,
"explanation_if_violating": "The phrase expresses a desire to hit or physically harm someone, which falls under violent content."
}
Tool
Tool を定義した場合、bind_tools
を活用してモデルをバインドすることで、Function Calling を実行することができます。
LangChain では Tool Calling でツールの実行までを行ってくれますが、この方法ではあくまで Function Calling の結果のみの取得となる点は注意が必要です。
llm_with_tool = llm.bind_tools(
tools=weather_prompt._tools["tools"], tool_choice="auto"
)
chain = weather_template | llm_with_tool
result = chain.invoke({"question": "東京で晴れてる?"})
print(result.content)
[{'id': 'call_igOIrnYiLRPGPanDQHRLW4ec', 'function': {'arguments': '{"location":"東京"}', 'name': 'get_weather'}, 'type': 'function'}]
まとめ
LangChain での利用はまだ試行錯誤中ですが、Phoenix のプロンプトテンプレートを活用することで、LangChain での利用も容易になりそうです。
一方で Azure OpenAI Service を活用する際に API バージョンが取得できない問題があり、再現性という観点では課題となりえます。このあたりは Phoenix の改善を待つ必要がありそうです。
参考
Discussion