はじめに
「自然言語で指示するだけで、業務フローが自動生成される」—— そんな未来が、すでに現実になりつつあります。
本記事では、Shopify Engineering が 2026年4月に公開した論文的ブログ記事 「Flow generation through natural language: An agentic modeling approach」 を徹底的に解説します。
この記事では、Shopifyが Qwen3-32B をファインチューニング し、自然言語から Shopify Flow(自動化ワークフロー)を生成するツールコーリングエージェントを構築した全過程が語られています。
🎯 この記事で学べること
| テーマ | 内容 |
|---|---|
| コールドスタート問題の解決 | 本番データがない状態でどう学習データを作るか |
| Python DSL の活用 | なぜ JSON ではなく Python で学習させるのか |
| 本番環境のミラーリング | 微細なフォーマット差異がどれほど精度に影響するか |
| ツールコーリングの最適化 | コンテキスト爆発を防ぐアーキテクチャ設計 |
| 評価の落とし穴 | ベンチマーク上は合格でも本番で35%性能低下した話 |
| フライホイール | 週次リトレーニングによる継続的改善ループ |
| 成果 | 2.2倍高速・68%コスト削減を実現 |
1. 背景: Shopify Flow とは
Shopify Flow は、Shopifyが提供するノーコード自動化プラットフォームです。ストアオーナーは トリガー、条件、アクション を組み合わせてワークフローを構築できます。
例: 「在庫が10個以下になったら、Slackに通知を送る」
しかし、エンジニアではないストアオーナーにとって、空のキャンバスから適切なワークフローを構築するのは困難です。そこで Shopify は AI コマースアシスタント Sidekick を通じて、自然言語から Flow を自動生成 する機能を開発しました。
従来のアプローチの限界
当初、このフロー生成はクローズドモデル(フロンティアモデル)のプロンプトエンジニアリングで実現されていました。しかし、以下の問題がありました:
- 差別化が困難: API キーさえあれば誰でも同等の機能を構築可能
- コスト: フロンティアモデルの API コストが高い
- コントロール不足: モデルの挙動を細かく制御できない
💡 Shopifyの主張: 持続的な差別化は 独自データ、学習レシピ、インフラ、反復速度 から生まれる。
2. コールドスタート問題の解決: 学習データの構築
問題: データがない
ファインチューニングには学習データが必要ですが、まだ機能がデプロイされていないため、本番の会話データが存在しないというコールドスタート問題に直面しました。
解決策: 逆算アプローチ
Shopify には、すでに何千人ものストアオーナーが 手動で作成したワークフロー が存在します。この既存のワークフローから「ユーザーの意図」を逆算して学習データを生成しました。
フィルタリング基準
高品質なワークフローのみを学習データに使用するため、以下のフィルタを設けています:
| フィルタ条件 | 目的 |
|---|---|
| 直近7日間で1回以上実行 | アクティブなワークフローのみを対象 |
| 2つ以上のワークフローを持つマーチャント | ある程度の経験を持つユーザーに限定 |
| 各ディスクリプタ1例のみ | ワークフロー種別の多様性を確保 |
合成データ生成の3ステップ
- ワークフローをサンプリング: 本番で検証済みの人気ワークフローを選ぶ
- ユーザークエリを生成: 強力なLLMを使い、「このワークフローに至るであろう自然言語リクエスト」を生成
- ツール軌跡を構築: 理想的なエージェントが実行するべきマルチターンのツールコールシーケンスを構築
💡 教訓: インタラクションデータがない場合、ユーザーが既に作成した成果物から逆算するのが最初の正しいステップ。
3. Python DSL: 学習効率を劇的に向上させる表現形式
JSON DSL の問題
Shopify Flow のワークフローは内部的に JSON ベースの DSL(ドメイン固有言語)で表現されています。しかし、この形式は LLM にとって不利でした:
- 条件分岐やループなどのプログラム的ロジックが 深くネストされた JSON に埋め込まれている
- この種のパターンは 事前学習データにほとんど存在しない
- LLM は「新しいフォーマット」と「タスクそのもの」の 両方を同時に学習 しなければならない
解決策: Python への変換
ワークフローは本質的にプログラムです。そこで Shopify はワークフローを 意味的に等価な Python コード として表現する手法を採用しました。
# JSON DSL の場合(イメージ)
{
"trigger": {"type": "order_created"},
"conditions": [
{"field": "order.total_price", "operator": "greater_than", "value": 100}
],
"actions": [
{"type": "send_email", "to": "admin@shop.com", "subject": "高額注文通知"}
]
}
# Python DSL の場合(イメージ)
@trigger("order_created")
def high_value_order_notification(order):
if order.total_price > 100:
send_email(
to="admin@shop.com",
subject="高額注文通知"
)
Python は LLM の事前学習データの 大部分を占める 言語であるため、モデルは以下のパターンを既に理解しています:
- デコレータ
- if/else ロジック
- 変数
- for ループ
- 関数呼び出し
精度改善の結果
| 指標 | JSON DSL → Python DSL | 改善幅 |
|---|---|---|
| 構文正確性(Syntactic Correctness) | 大幅改善 | +22ポイント |
| 意味的正確性(Semantic Correctness) | 大幅改善 | +13ポイント |
ラウンドトリップ・トランスパイラ
この手法を実現するために、双方向変換器(トランスパイラ) を構築しました:
- 学習時: JSON → Python に変換して学習データを作成
- 推論時: モデルが Python を生成 → トランスパイラが JSON に変換 → Flow バックエンドに渡す
- ストアオーナー: Python を見ることはない
- バックエンド: Python を理解する必要はない
信頼性の担保
すべての本番ワークフローに対して ラウンドトリップテスト を継続的に実行:
JSON → Python → JSON → 元のJSONと完全一致を検証
不一致が検出された場合、学習データに流入する前にキャッチされます。
💡 教訓: カスタム DSL でモデルを学習させる場合、モデルがすでに知っている言語に翻訳 することを検討すべき。「フォーマットの学習」と「タスクの学習」を分離できる。
4. 本番環境のミラーリング: 微細な差異が精度を左右する
データの表現形式は問題の半分にすぎません。もう半分は、学習データが本番環境で実際にモデルが見るものと完全に一致すること です。
Shopify のチームが驚いたのは、モデルがどれほど 微細な差異に敏感 かということでした。
発見された問題と対策
| 問題カテゴリ | 具体的な問題 | 対策 |
|---|---|---|
| ツール名とツール順序 | 学習データでは flow_app_agent_task_search、推論時は task_search と呼ばれていた |
学習データのプレフィックスを削除して推論時と一致させた |
| システムプロンプト内のツール表示順が異なっていた | ツール順序を学習・推論間で統一 | |
| ツールレスポンス形式 | 学習データではJSONキーをアルファベット順でソート。本番では異なる順序や追加フィールドが含まれていた | 本番のレスポンス形式に完全一致させた |
| システムプロンプト・ツール説明 | プロダクトチームが頻繁に説明文を更新していた | 学習データとの同期を 継続的に 実施 |
⚠️ 重要な教訓: これらはタスクのロジックとは無関係な フォーマットの詳細 です。しかし、モデルはすべてのトークンをシグナルとして扱います。意図したかどうかに関わらず。
5. ツールコーリングスタックの最適化
問題: コンテキスト爆発
エージェントがツールを呼び出すたびに、そのレスポンスがコンテキストに追加されます。すると:
- コンテキストが増大 → レイテンシが増大 → コストが増大
- 無関係な情報がシグナルを薄める → モデルの推論精度が低下
解決策: 2段階検索パターン
ツールインターフェースを再設計し、各ステップでのコンテキストを最小化しました。
| ステップ | 従来 | 最適化後 |
|---|---|---|
| 1回目 | 全候補の完全スキーマを返却 | 名前と説明の軽量サマリーのみ |
| 2回目 | — | 選択した2〜3個の完全スキーマのみ |
| コンテキストサイズ | 大 | 小 |
| 推論精度 | 低下しやすい | 集中を維持 |
💡 設計原則: 1回の高コストな呼び出しよりも、2回の低コストな呼び出し のほうが効率的。
6. 学習インフラ: 高速反復を支える基盤
ジレンマ
学習データが増える → 精度が向上する → しかし学習時間も増える → 反復速度が低下する → 改善が遅くなる
解決策: 高速学習基盤の構築
| 要素 | 構成 |
|---|---|
| モデル | Qwen3-32B |
| ハードウェア | H200 GPU × 2ノード |
| 並列化 | FSDP(Fully Sharded Data Parallel) |
| 学習時間 | 12時間(フルトレーニング) |
| パイプライン | Tangle(Shopify のオープンソース ML 実験プラットフォーム) |
| 実験追跡 | CometML |
| データ・チェックポイント管理 | HuggingFace |
| 本番サービング | CentML |
| リトレーニング頻度 | 週次(手動介入不要) |
Tangle は各ステップをキャッシュ付きの再現可能なワークフローに構成し、変更された部分のみを再実行します。
7. 評価の落とし穴: ベンチマークは真実ではない
ベンチマーク上の成功
合成データでの学習後、300件の手作りベンチマーク で評価しました。評価指標は3つ:
| 指標 | 評価方法 | 説明 |
|---|---|---|
| 意味的正確性 | LLM ジャッジ | 生成されたワークフローが意図通りか |
| 構文正確性 | プログラム的検証 | 不正な条件、参照エラー等がないか |
| レイテンシ | 時間計測 | リクエストからワークフロー配信までの時間 |
ベンチマーク上では問題なし。いよいよ本番投入。
本番での衝撃: 35%の性能ギャップ
1% のトラフィックに対してデプロイしたところ、ワークフロー有効化率(実際にストアオーナーがワークフローをオンにする割合)がプロンプトベースのエージェントより35%低い という結果に。
なぜギャップが生じたか
ベンチマークは「期待されるリクエスト」をカバーしていましたが、実際のリクエスト は異なっていました:
| ベンチマークがカバーしていたもの | 実際のユーザーリクエスト |
|---|---|
| 新規ワークフロー生成 | 既存ワークフローの編集 |
| 基本的なトリガー・アクション | メール設定の詳細な構成 |
| Shopifyネイティブ機能 | サードパーティ連携 |
| ワークフロー生成のみ | Flow に関する質問(生成意図なし) |
⚠️ 教訓: ベンチマークパリティは、本番品質を保証しない。低トラフィックでの早期デプロイで実際のギャップを発見することが不可欠。
8. フライホイール: 継続的改善ループ
ギャップを埋める
本番デプロイで判明したギャップを体系的に埋めるために、診断レイヤー を構築しました。
LLM ジャッジ
各会話をワークフローのライフサイクル全体で採点します:
- アシスタントがマーチャントの意図を正しく理解したか
- Flow ソリューションが適切な場合にのみ選択したか
- 正しいコンポーネントを選んだか
- 次のステップを明確に提示したか
タグシステム
すべてのワークフローを複数の次元で分類:
- 使用するトリガー
- チェックする条件
- 実行するアクション
- サードパーティ連携の有無
タグ付きスライスごとにパフォーマンスを比較し、モデルが苦手な箇所を正確に特定 します。
具体的な改善例
| 問題カテゴリ | 全体失敗に占める割合 | 対策 |
|---|---|---|
| メールワークフロー | 25% | メール固有の学習例を追加 |
| 多様な条件パターン | 16% | 条件パターンの学習例を拡充 |
| ワークフロー編集 | — | 合成データでは未カバーだったため新規追加 |
週次フライホイール
- 本番会話を取り込み
- LLM ジャッジでスコアリング
- 高スコア → 学習プールに自動投入 / 低スコア → 隔離してレビュー
- タグ付きスライス分析でギャップを特定
- リトレーニング&デプロイ
💡 このアプローチは Karpathy の 「Autoresearch」 と同様の精神 —— 評価し、うまくいったものを残し、そうでないものを捨て、反復する —— を、本番データキュレーション に適用したもの。
9. 最終成果
ファインチューニングされた Flow エージェントは、現在 本番トラフィックの大部分 を処理しています。
| 指標 | 結果 |
|---|---|
| レイテンシ | 2.2倍高速 |
| コスト | 68%削減 |
| 品質 | クローズドモデルを上回る |
| リトレーニング | 週次(自動) |
6ヶ月前、このシステムは自社がコントロールできないフロンティアモデルで動いていた。今は 自社が学習したモデル、自社が所有するインフラ、自社だけが持つデータ で改善を続けている。68%のコスト削減も達成。今動いているバージョンは、その裏でリトレーニングされているバージョンよりすでに劣っている。
10. 今後の展望
| 方向性 | 内容 |
|---|---|
| シミュレーション環境 | モデルがワークフローを生成してフィードバックを受けるサンドボックス構築。検証可能な報酬による蒸留やオンポリシー最適化への道を開く |
| オフポリシー → オンポリシー | キュレーション済みの例からの学習(オフポリシー)から、自身が生成した軌跡から学習するポリシー最適化へ |
| 自己改善する評価 | LLM ジャッジの手動キャリブレーションを、ライブ本番シグナルに対する自動キャリブレーションに置き換え |
11. このアプローチが使える条件
このパターンは以下の条件を満たすときに一般化可能です:
- ✅ タスクが ツールコーリング を必要とする
- ✅ 出力形式が カスタム DSL であり、そのセマンティクスをモデルが既知の言語で表現可能
- ✅ 分布内表現と本番形式の間で ラウンドトリップ・トランスパイラ が構築可能
- ✅ 本番フィードバックループ が利用可能
まとめ: 学んだ教訓
本記事の要点を振り返ります:
| # | 教訓 |
|---|---|
| 1 | インタラクションデータがなければ、既存の成果物から逆算 してデータを作る |
| 2 | カスタム DSL ではなく、モデルが既知の言語(Python) で学習させる |
| 3 | 学習データと推論時の入力の あらゆる微細な差異 が精度に影響する |
| 4 | ツールコーリングでは コンテキストの最小化 が推論精度の鍵 |
| 5 | ベンチマーク性能は 本番品質を保証しない |
| 6 | 本番データからの 週次フライホイール が持続的改善を生む |
| 7 | 差別化は独自データ・学習レシピ・インフラ・反復速度から生まれる |
参考リンク
- 📄 元記事: Flow generation through natural language: An agentic modeling approach - Shopify Engineering
- 🔧 Tangle: Shopify のオープンソース ML 実験プラットフォーム
- 🧠 Qwen3-32B: Alibaba の大規模言語モデル