langfuse-prompt-migration について
langfuse-prompt-migrationは、ハードコードされたLLMプロンプトをLangfuseへ移し、アプリケーションコードを更新するスキルです。プロンプトの検出、テンプレート互換性の確認、承認を得た構成案、コードのリファクタリングと検証を案内します。
主な機能
- 01コード内のハードコードされたプロンプトを検索
- 02テンプレート互換性の確認
- 03プロンプト名と変数の構成案
- 04Langfuseでのプロンプト作成
- 05プロンプト取得用のコードへリファクタリング
- 06移行とトレース連携の検証
活用シーン
- 01アプリケーションのプロンプトをLangfuseへ移行
- 02テンプレート変数をLangfuse形式へ変換
- 03移行したプロンプトを既存トレースに関連付け
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ langfuse/ skills --skill langfuse-prompt-migrationインストール後、Claude Code で/langfuse-prompt-migrationを入力して読み込まれたか確認します。
詳細
Langfuse プロンプトの移行
ハードコードされたプロンプトを Langfuse に移行して、バージョン管理、A/B テスト、デプロイ不要の反復改善を実現します。
前提条件
開始前に認証情報を確認します。
echo $LANGFUSE_PUBLIC_KEY # pk-...
echo $LANGFUSE_SECRET_KEY # sk-...
echo $LANGFUSE_HOST # https://cloud.langfuse.com or self-hosted
設定されていない場合は、まずユーザーに設定を依頼してください。
移行の流れ
1. Scan codebase for prompts
2. Analyze templating compatibility
3. Propose structure (names, subprompts, variables)
4. User approves
5. Create prompts in Langfuse
6. Refactor code to use get_prompt()
7. Link prompts to traces (if tracing enabled)
8. Verify application works
ステップ 1:プロンプトを探す
次のパターンを検索します。
| フレームワーク | 検索対象 |
|---|---|
| OpenAI | messages=[{"role": "system", "content": "..."}] |
| Anthropic | system="..." |
| LangChain | ChatPromptTemplate、SystemMessage |
| Vercel AI | system: "..."、prompt: "..." |
| Raw | LLM 呼び出しの近くにある複数行の文字列 |
ステップ 2:テンプレートの互換性を確認する
重要: Langfuse がサポートするのは、単純な {{variable}} による置換のみです。条件分岐、ループ、フィルターは使えません。
| テンプレート機能 | Langfuse 標準対応 | 対応 |
|---|---|---|
{{variable}} | ✅ | そのまま移行 |
{var} / ${var} | ⚠️ | {{var}} に変換 |
{% if %} / {% for %} | ❌ | ロジックをコードに移す |
{{ var | filter }} | ❌ | フィルターをコードで適用 |
判断フロー
Contains {% if %}, {% for %}, or filters?
├─ No → Direct migration
└─ Yes → Choose:
├─ Option A (RECOMMENDED): Move logic to code, pass pre-computed values
└─ Option B: Store raw template, compile client-side with Jinja2
└─ ⚠️ Loses: Playground preview, UI experiments
複雑なテンプレートを簡素化する
条件分岐 → コードで事前に計算します。
# Instead of {% if user.is_premium %}...{% endif %} in prompt
# Use {{tier_message}} and compute value in code before compile()
ループ → コードで事前にフォーマットします。
# Instead of {% for tool in tools %}...{% endfor %} in prompt
# Use {{tools_list}} and format the list in code before compile()
外部テンプレートの詳細については、https://langfuse.com/faq/all/using-external-templating-libraries を取得してください。
ステップ 3:構成案を提示する
命名規則
| ルール | 例 | 悪い例 |
|---|---|---|
| 小文字とハイフンを使用 | chat-assistant | ChatAssistant_v2 |
| 機能に基づく名前にする | document-summarizer | prompt1 |
| 関連するものには階層構造を使う | support/triage | supportTriage |
サブプロンプトには _ を接頭辞として付ける | _base-personality | shared-personality |
サブプロンプトを特定する
次の場合に抽出します。
- 同じテキストが 2 つ以上のプロンプトにある
- 独立したコンポーネント(ペルソナ、安全ルール、形式)を表している
- 一緒に変更する必要がある
変数の抽出
| 変数にする | ハードコードのままにする |
|---|---|
ユーザー固有({{user_name}}) | 出力形式の指示 |
動的コンテンツ({{context}}) | 安全ガードレール |
リクエストごとの値({{query}}) | ペルソナ/性格 |
環境固有({{company_name}}) | 静的な例 |
ステップ 4:ユーザーに計画を提示する
形式:
Found N prompts across M files:
src/chat.py:
- System prompt (47 lines) → 'chat-assistant'
src/support/triage.py:
- Triage prompt (34 lines) → 'support/triage'
⚠️ Contains {% if %} - will simplify
Subprompts to extract:
- '_base-personality' - used by: chat-assistant, support/triage
Variables to add:
- {{user_name}} - hardcoded in 2 prompts
Proceed?
ステップ 5:Langfuse にプロンプトを作成する
次の項目を指定して langfuse.create_prompt() を使用します。
name:選択した名前prompt:テンプレートテキスト(または chat タイプの場合はメッセージ配列)type:"text"または"chat"labels:["production"](すでに本番環境で使用中です)config:任意のモデル設定
ラベル付けの方針:
production→ 移行したすべてのプロンプトstaging→ テスト用に後から追加latest→ Langfuse により自動適用
API の詳細については、https://langfuse.com/docs/prompts/get-started を取得してください。
ステップ 6:コードをリファクタリングする
ハードコードされたプロンプトを次のように置き換えます。
prompt = langfuse.get_prompt("name", label="production")
messages = prompt.compile(var1=value1, var2=value2)
重要なポイント:
- 安定性のため、常に
label="production"を使用します(latestではありません) .compile()を呼び出して変数を置換します- chat プロンプトの場合、結果は API に渡せるメッセージ配列です
SDK の例(Python/JS/TS)については、https://langfuse.com/docs/prompts/get-started を取得してください。
ステップ 7:プロンプトをトレースにリンクする
コードベースで Langfuse トレーシングを使用している場合は、プロンプトをリンクすると、どのバージョンが各応答を生成したかを確認できます。
既存のトレーシングを検出する
次を検索します。
@observe()デコレーターlangfuse.trace()の呼び出しfrom langfuse.openai import openai(計測済みクライアント)
リンク方法
| 構成 | リンク方法 |
|---|---|
@observe() デコレーター | langfuse_context.update_current_observation(prompt=prompt) |
| 手動トレーシング | trace.generation(prompt=prompt, ...) |
| OpenAI 連携 | openai.chat.completions.create(..., langfuse_prompt=prompt) |
UI で確認する
- Traces に移動し、トレースを選択します
- Generation をクリックします
- Prompt フィールドに名前とバージョンが表示されていることを確認します
トレーシングの詳細については、https://langfuse.com/docs/prompts/get-started#link-with-langfuse-tracing を取得してください。
ステップ 8:移行を確認する
チェックリスト
-
productionラベルを付けてすべてのプロンプトを作成している - コードが
label="production"を指定して取得している - 変数がエラーなくコンパイルされる
- サブプロンプトが正しく解決される
- アプリケーションの動作に変更がない
- 生成結果にリンクされたプロンプトが UI に表示される(トレース機能を使用する場合)
よくある問題
| 問題 | 解決方法 |
|---|---|
PromptNotFoundError | 名前のスペルを確認する |
| 変数が置換されない | {var} ではなく {{var}} を使用し、.compile() を呼び出す |
| サブプロンプトが解決されない | 同じラベルで存在している必要がある |
| 古いプロンプトがキャッシュされる | アプリを再起動する |
対象範囲外
- プロンプトエンジニアリング(より良いプロンプトの作成)
- 評価のセットアップ
- A/B テストのワークフロー
- LLM 以外の文字列テンプレート