ナビゲーションにスキップ

構造化プロシージャ

エージェントが毎回同じ方法で実行する、型付きステップの固定シーケンス

概要

構造化プロシージャは、固定された順序でステップを実行するプロシージャです。自由形式プロシージャは、エージェントが解釈し、状況に応じて調整する自然言語のガイダンスです。構造化プロシージャは、プロシージャが適用されるたびにエージェントが順番に実行する、型付きステップの順序付きリストです。

発信者の本人確認、チケットのエスカレーション、支払いの受付など、特定のステップを毎回同じように実行する必要がある場合は、構造化プロシージャを使用します。短い平易な言葉のステップ一覧として作成できます。

すべてのプロシージャと同様に、構造化プロシージャには適用されるタイミングを説明するトリガーがあります。会話がトリガーに一致すると、エージェントはプロシージャのステップを順に実行し、その後会話の残りに戻ります。

構造化プロシージャの
エディター

構造化プロシージャを使用する場合

特定のステップを毎回同じように実行する必要があり、なおかつ平易なステップで迅速に作成したい場合は、構造化プロシージャを使用します。構造化プロシージャはワークフローより簡単に作成できますが、表現力は低くなります。自由形式プロシージャ、ワークフロー、システムプロンプトとの比較については、プロシージャを使用する場合をご覧ください。

構造化プロシージャの構成

構造化プロシージャは、名前、トリガー、順序付きステップリストの3つで構成されます。

名前

ダッシュボードでプロシージャを識別するための短いラベルです。名前がLLMに送信されることはないため、エージェントの動作には影響しません。

トリガー

エージェントがこのプロシージャを実行するタイミングを示す平易な説明です。たとえば、ユーザーが注文の返金を求めた場合 のように記述します。エージェントはユーザーの意図を各プロシージャのトリガーと比較して一致するものを実行するため、トリガーは具体的かつ明確に区別できるものにしてください。エージェントが認識するのはトリガーテキストのみで、プロシージャの名前やIDは認識しません。トリガーは他のプロシージャと同じように機能します。詳しくは、トリガーの作成をご覧ください。

トリガーを空のままにすると、別のプロシージャから呼び出された場合にのみ実行されるサブプロシージャになります。

ステップ

プロシージャの本文は、型付きステップの順序付きリストです。複数のステップタイプを組み合わせてタスクを説明します。

ステップ内容
Askユーザーに情報を尋ね、待機します。ユーザーが回答するまで繰り返し尋ねます。ユーザーを待機するのはこのステップだけです。
Tellエージェントが自分の言葉で内容を伝え、次のステップに進みます。
Sayエージェントが指定したメッセージを一言一句そのまま話し、次のステップに進みます。Sayステップでは、エージェントがサポートする各言語に対して個別に設定した翻訳を使用できます。
Tool特定のツールを呼び出します。ツールの呼び出し方を平易な言葉でLLMに指示することも、最大限の決定性が必要な場合にパラメーター値を明示的に固定することもできます。ツール呼び出しが失敗した場合に実行するステップも定義できます。
If1つ以上の条件を順に評価し、最初に一致した条件のステップを実行します。どれにも一致しない場合は、任意のElseが実行されます。
Sub-procedure別の構造化プロシージャを実行します。ステップが完了すると、この(呼び出し元)プロシージャの次のステップに制御が戻ります。
System tool組み込みのシステムアクションを実行します。現在サポートされているのは通話の終了のみです。
Retryツール呼び出しを含め、Toolステップの失敗ハンドラーを最大3回再実行します。Toolステップの失敗ハンドラー内でのみ使用できます。

構造化プロシージャのステップタイプ
メニュー

すべてのステップをどこでも使用できるわけではありません。Ifアーム内では、別のIfまたはRetry以外の任意のステップを使用できます。Toolステップの失敗ハンドラー内では、Ifまたは別のTool以外の任意のステップを使用できます。

APIステップリファレンス

構造化プロシージャの content は、steps 配列を含むJSONエンコード済みドキュメントです。各ステップは type で識別されるオブジェクトです。トリガーは content の一部ではなく、プロシージャの別の最上位フィールドです。APIおよびSDKのペイロードでは、プロシージャ自体に type: "deterministic" を使用します。

Ask

Askステップは、情報を要求し、ユーザーが適切な応答を返すまで待機するようエージェントに指示します。

  • APIタイプ:ask
  • instruction:必須の空でない文字列。
{
"type": "ask",
"instruction": "Ask the user for their order ID."
}

Tell

Tellステップは、エージェントが自分の言葉で1つのメッセージを生成するよう指示します。続行する前にユーザーの応答を待ちません。

  • APIタイプ:tell
  • instruction:必須の空でない文字列。
{
"type": "tell",
"instruction": "Explain that the refund normally takes five to ten business days."
}

Say

Sayステップは、指定されたテキストを記載どおりに正確に話してから続行します。message_translations を指定すると、エージェントがサポートする追加言語ごとに、言語コードをキーとして正確なメッセージを設定できます。

  • APIタイプ:say
  • message:必須の空でない文字列。
  • message_translations:言語コードを { "value": "..." } にマッピングする任意のオブジェクト。
{
"type": "say",
"message": "Your refund has been submitted.",
"message_translations": {
"es": { "value": "Su reembolso ha sido enviado." }
}
}

If、else if、else

Ifステップには、順序付きの条件アームが1つ以上含まれます。最初に一致したアームが実行されます。任意の fallback 配列がElseアームです。

  • APIタイプ:branch
  • branches:必須の、空でない条件アームのリスト。
  • fallback:任意のElseステップのリスト。
  • 各アームには condition と空でない steps リストが必要です。
{
"type": "branch",
"branches": [
{
"condition": {
"type": "llm",
"condition": "The user is on an annual plan."
},
"steps": [
{
"type": "say",
"message": "Your annual plan is eligible for a prorated refund."
}
]
}
],
"fallback": [
{
"type": "tell",
"instruction": "Explain that the account's plan could not be determined."
}
]
}

これはif/else-if/elseのように動作します。

  1. 条件は順に評価されます。
  2. 最初に一致したアームが実行されます。
  3. 一致する条件がない場合、fallback が実行されます。
  4. アームの完了後、プロシージャはメインシーケンスに戻ります。

上の例では、モデルが自然言語で評価するテキスト条件を使用しています。条件には、動的変数に対する式も使用できます。

{
"type": "expression",
"expression": {
"type": "eq_operator",
"left": {
"type": "dynamic_variable",
"name": "plan_tier"
},
"right": {
"type": "string_literal",
"value": "annual"
}
}
}

式条件は、ツールの結果によって入力されるか、会話開始時に設定される動的変数をテストします。ユーザーの直近の返信を読み取ることはできません。ユーザーの発言に基づいて分岐するには、テキスト条件を使用してください。

1つのIfステップ内のすべてのアームでは、llm または expression のいずれか、同じ条件タイプを使用する必要があります。

Tool

Toolステップは特定のツールを呼び出します。

  • APIタイプ:tool_call
  • tool_id:必須の空でないツールID。ツールはエージェントに接続されている必要があります。
  • tool_name:ツールと一致する必須のツール名。
  • instruction:ツールの呼び出し方を説明する任意の指示。
  • schema_overrides:ツールのパラメーターに設定する任意の固定値。
  • on_failure:任意の失敗ハンドラー。
{
"type": "tool_call",
"tool_id": "tool_abc123",
"tool_name": "lookup_order",
"instruction": "Look up the order using the order ID provided by the user."
}

固定パラメーター値

パラメーターに常に特定の値を設定する必要がある場合は、schema_overrides を使用します。モデルはオーバーライドされたパラメーターを確認も選択もできません。キーはツールのスキーマ内のパラメーターパスで、各値はソースを指定します。

sourceフィールド動作
constantconstant_value指定された値を常に送信します。
dynamic_variabledynamic_variable指定された動的変数の現在値を送信します。
llmprompt (任意)任意のプロンプトオーバーライドとともに、モデルが値を選択できるようにします。
omit呼び出しからパラメーターを除外します。
{
"type": "tool_call",
"tool_id": "tool_abc123",
"tool_name": "update_ticket",
"schema_overrides": {
"request_body.status": { "source": "constant", "constant_value": "pending" },
"request_body.ticket_id": { "source": "dynamic_variable", "dynamic_variable": "ticket_id" }
}
}

失敗時の処理

on_failure がない場合、ツール呼び出しの失敗で会話は終了します。代わりに復旧ステップを実行するには、on_failure を追加します。

  • fallback:ツールが失敗したときに実行される、必須の空でないステップリスト。
  • branches:条件付きの失敗処理用に予約されています。空のままにしてください。
{
"type": "tool_call",
"tool_id": "tool_abc123",
"tool_name": "lookup_order",
"on_failure": {
"branches": [],
"fallback": [
{
"type": "tell",
"instruction": "Explain that the order could not be retrieved and offer to connect the user with support."
}
]
}
}

失敗ハンドラーには、Ask、Tell、Say、Sub-procedure、System tool、Retryステップを含めることができます。ToolまたはIfステップは含められません。ハンドラーの実行後、プロシージャはToolステップの次のステップに進みます。

Retry

Retryステップは、ツール呼び出しを含め、それを含む失敗ハンドラーを再実行します。試行ごとにツールが再度呼び出され、再び失敗した場合はハンドラー内のすべてのステップが再度実行されます。試行回数を使い切ると、会話は終了します。

  • APIタイプ:retry
  • max_retries:1~3の任意の整数。デフォルトは1です。
  • この値は、元のツール呼び出し後の試行回数を数えます。
  • Retryは on_failure 内でのみ有効です。
  • 後続のステップには到達できないため、Retryは失敗ハンドラーの最終ステップである必要があります。
{
"type": "retry",
"max_retries": 2
}

Sub-procedure

Sub-procedureステップは、別の構造化プロシージャを実行します。そのプロシージャのステップが完了すると、Sub-procedureステップの次のステップに実行が戻ります。

  • APIタイプ:sub_procedure
  • procedure_id:必須の空でないプロシージャID。
  • 対象は同じエージェント上に存在する必要があります。
  • 対象は構造化プロシージャである必要があります。
  • プロシージャは自分自身を呼び出せません。
{
"type": "sub_procedure",
"procedure_id": "agtprc_6qbpwdq8n01bxhk44bgjy6f10ck3"
}

System tool

System toolステップは、組み込みのシステムアクションを実行します。

  • APIタイプ:system_tool
  • system_tool_name:必須のシステムツール名。
  • 現在サポートされているのは end_call のみです。今後、さらにシステムツールが追加される場合があります。
  • end_call は終了操作のため、含まれるシーケンス、アーム、または失敗ハンドラーの最終ステップである必要があります。
{
"type": "system_tool",
"system_tool_name": "end_call"
}

検証ルール

エージェントを公開するかエージェント下書きを保存すると、以下のルールのいずれかに違反する構造化プロシージャは拒否されます。エラーには、違反しているステップのパスが表示されます。

  • 2つのIfステップを連続して配置することはできません。
  • Ifステップはネストできません。
  • 式条件を持つIfステップを、Askステップの直後に配置することはできません。
  • 1つのIfステップ内のすべての条件は、llm または expression のいずれか、同じタイプである必要があります。
  • Retryは on_failure 内でのみ使用でき、そこでの最終ステップである必要があります。
  • end_call は、出現するリスト内の最終ステップである必要があります。
  • 失敗ハンドラーの fallback には、少なくとも1つのステップが必要です。
  • Sub-procedureは、同じエージェント上に存在する構造化プロシージャを指定する必要があり、自分自身は指定できません。
  • tool_id はエージェント上のツールであり、tool_name は一致し、schema_overrides はツールのスキーマに一致する必要があります。
  • steps リスト、すべての instruction、およびすべての message は空であってはなりません。

これらのルールに該当するプロシージャの再構成方法については、ベストプラクティスをご覧ください。

完全なAPI例

この例では、発送状況に基づいて注文のキャンセルを処理します。ツールのパラメーターを固定し、失敗したツール呼び出しから復旧し、別の構造化プロシージャを呼び出してから、通話を終了します。

{
"steps": [
{
"type": "ask",
"instruction": "Ask the user for their order ID."
},
{
"type": "branch",
"branches": [
{
"condition": {
"type": "llm",
"condition": "The user says the order has already shipped."
},
"steps": [
{
"type": "tell",
"instruction": "Explain that shipped orders must be returned before they can be refunded."
}
]
},
{
"condition": {
"type": "llm",
"condition": "The user says the order has not shipped."
},
"steps": [
{
"type": "tool_call",
"tool_id": "tool_abc123",
"tool_name": "cancel_order",
"instruction": "Cancel the order using the order ID provided by the user.",
"schema_overrides": {
"request_body.notify_customer": { "source": "constant", "constant_value": true }
},
"on_failure": {
"branches": [],
"fallback": [
{
"type": "tell",
"instruction": "Apologize that the cancellation did not go through and say you will try once more."
},
{
"type": "retry",
"max_retries": 1
}
]
}
}
]
}
],
"fallback": [
{
"type": "ask",
"instruction": "Ask whether the order has already shipped."
}
]
},
{
"type": "sub_procedure",
"procedure_id": "agtprc_6qbpwdq8n01bxhk44bgjy6f10ck3"
},
{
"type": "say",
"message": "Thank you for contacting us. Goodbye.",
"message_translations": {
"es": { "value": "Gracias por contactarnos. Adiós." }
}
},
{
"type": "system_tool",
"system_tool_name": "end_call"
}
]
}

構造化プロシージャの実行方法

構造化プロシージャのステップをエージェントが実行する形式に変換することを、コンパイルと呼びます。プラットフォームは、エージェント下書きの保存時またはエージェント公開時にすべての構造化プロシージャをコンパイルします。作成者が自らコンパイルする必要はありません。

ユーザーのリクエストがプロシージャのトリガーに一致すると、プラットフォームはプロシージャに入り、ステップを順に実行します。構造化プロシージャ内にいる間、エージェントは各ステップを個別に処理します。最後に到達すると、プラットフォームは会話の残りに制御を戻します。

ワークフローエッジは、構造化プロシージャとの間で接続できません。構造化プロシージャを連結するには、Sub-procedureステップを使用してください。プラットフォームは、一致するトリガーからの開始と完了を管理します。これには、プロシージャが開始されたワークフローノードへの制御の返却も含まれます。

以下のルールでは、実行時のステップの動作を説明します。

Ask以外のすべてのステップは直ちに実行され、同じターン内で次のステップに制御が移ります。 TellまたはSayステップはメッセージを伝えて続行します。Ask以外に会話を一時停止するステップはなく、 現在のターンを終了するステップもありません。ユーザーからの入力が必要な場合は、 Askステップを使用してください。会話を終了する場合は、end_call システムツールを使用してください。

最後のステップが完了すると、プロシージャは終了し、ターンは開いたままエージェントが会話の残りに戻るため、 さらに発話することがあります。サブプロシージャが完了すると、 制御はそれを呼び出したプロシージャの次のステップに戻ります。

Toolステップでは、ステータスコードやレスポンス本文に基づいて分岐できません。ツールが成功した場合、 プロシージャは続行します。失敗し、ステップに失敗ハンドラーがない場合は、会話が終了します。 ある場合は、ハンドラーのステップが実行され、プロシージャは次のステップに進みます。ハンドラー内のRetryは、 ツールを再実行し、再度失敗した場合は、ツールが成功するか試行回数を使い切るまで、 ハンドラー内のすべてのステップを再実行します。使い切った場合、会話は終了します。

条件は順に評価され、最初に一致したものが実行されます。どれにも一致しない場合はElseアームが実行されます。 Elseがなく、何にも一致しない場合は、プロシージャはIfの次のステップに進みます。 未処理のケースはエラーではありません。

Ifアーム内で決定された内容は、後続のステップには記憶されません。アーム内で得た情報が 後で必要な場合は、ツール呼び出しまたは動的変数で明示的に保持してください。

ツールを呼び出せるのはToolステップのみです。Ask、Tell、Sayステップにツールを呼び出さないよう 指示する必要はありません。呼び出すことはできません。

構造化プロシージャを管理する

ダッシュボードでエージェントを開き、Procedures を選択します。 + を使用して構造化プロシージャを作成します。トリガーを追加し、各ステップのタイプを選択して、 エージェントの変更を公開します。

ダッシュボードでは、編集時に構造化プロシージャが検証されます。プロシージャが 検証ルールに違反している場合、Publish ボタンにはエラー状態が表示され、 Procedures タブにはエラーバッジが表示され、プロシージャを修正するまで プレビューを開始できません。エラーインジケーターを選択すると、影響を受けているプロシージャと ステップを確認できます。

エラー状態のPublishボタンと1 Error
バッジが表示された構造化プロシージャエディター

失敗したプロシージャとメッセージが必要なステップを一覧表示する
検証詳細ダイアログ

ベストプラクティス

各ステップタイプには固有の動作がすでに定義されているため、通常はそれを明記する必要はありません。各ステップの意図を書き、残りはステップタイプに任せてください。以下のガイダンスでは、適切に設定すべきケースを説明します。

構造化プロシージャをテストするには、プロシージャの反復に従ってください。

ステップタイプの選択

Askステップは1つの回答を待ちます。複数の質問を1つの指示にまとめると、 エージェントが一部を飛ばしたり、まとめて扱ったりしがちです。必要な情報ごとにAskを1つ使用してください。

Tellステップはメッセージを伝えたあと、待たずに次へ進みます。質問の形にしたTellは 回答を受け取りません。ステップでユーザーからの応答が必要な場合は、Askを使用します。

Askステップは、適切な回答を得ると次へ進みます。何が回答として有効かが質問から 明らかでない場合は、指示で明記してください。たとえば、_注文IDを尋ねる。有効な IDは8桁_のように指定します。

エージェント自身にメッセージを組み立てさせる場合はTellステップを、文言を一語一句そのまま、または翻訳して伝える必要がある場合はSayステップを使用します。 どちらも送信するメッセージは1つだけなので、ステップに単一のメッセージを送るよう 指示する必要はありません。

Ask、Tell、Sayステップはツールを呼び出せません。これらに ツールを一切呼び出さない と書いても、 動作は変わらず、指示が冗長になるだけです。

プロシージャの構成

2つのIfステップを連続して配置することはできません。このルールを満たすために、無関係なTellやSayを間に挿入すると、 エージェントが本来言うべきでないことを話してしまいます。代わりに、2つ目の判断を追加のElse if分岐として 最初のIfに組み込むか、サブプロシージャに移動してください。

Ifステップはネストできません。ある判断が別の判断に依存する場合は、内側の判断を 独自の構造化プロシージャに置き、必要な分岐からサブプロシージャステップで呼び出してください。

ElseのないIfステップは、どの条件にも一致しない場合に次のステップへ進みます。一致しない 場合を別の方法で処理する必要がある場合は、そのためのElse分岐を追加してください。

If分岐内で行った判断は、その後は記憶されません。後続ステップが 分岐内で得た情報に依存する場合は、分岐内でツール呼び出しまたは動的変数を使って記録してください。

式の条件は動的変数をテストします。これらを使用するIfステップは、その変数を設定するTool ステップの直後に配置してください。ユーザーの発言に応じて分岐するには、テキスト条件を使用します。

複数の構造化プロシージャで、人間の担当者へのエスカレーションのような同じシーケンスを共有する場合は、 空のトリガーを持つ1つの構造化プロシージャに入れ、それぞれから呼び出してください。コピーしたシーケンスは 時間が経つにつれてずれていきます。

ツールの使用

Toolステップは必ずツールを呼び出します。チケットにすでにタグが付いている場合は これをスキップする のように指示に条件を書いても、呼び出しを防ぐことはできません。呼び出しが常に 必要なわけではない場合は、Toolステップの前にIfステップで条件を設定してください。

パラメータに常に特定の値を設定する必要がある場合は、 schema_overridesで constant オーバーライドを設定してください。statusを常にpendingに設定する のような指示は、モデルに 従うよう求めるだけです。オーバーライドは強制され、スキップできません。

on_failure がない場合、ツールの失敗はすべて会話を終了させます。ユーザーに 何が起きたかを伝え、再試行、エスカレーション、または続行するハンドラーを追加してください。

Toolステップはツールを実行するだけで、その間にエージェントが話したり判断したりすることはできません。ユーザーに話しかける、または ツールの返り値に基づいて分岐する場合は、Toolステップの前後に別のステップとして配置してください。

指示の書き方

プロシージャが次に実行する内容を制御し、エージェントは現在のステップを実行している間、後続のステップを認識していません。 シーケンスはステップの順序に任せてください。

これがこのターンの最後のメッセージです のようにステップの指示に書かれた文は、 プラットフォームに存在しない境界をエージェントに強制させようとします。ユーザーを待つにはAskステップを使用するか、 会話を終了するには end_call システムツールを使用してください。

トーン、書式、結びの言葉、拒否ポリシーはシステム プロンプトに記載します。ステップの指示には、そのステップに固有の内容だけを 書いてください。

プロシージャの組み合わせ

プロシージャを組み合わせるための一般的なガイダンスは構造化プロシージャにも当てはまります。詳しくは、自由形式プロシージャのページにあるプロシージャの組み合わせを参照してください。

タイプを混在させる際に特有のパターンとして、自由形式プロシージャから構造化プロシージャを参照できます。自由形式プロシージャではオープンエンドな対応を行い、本人確認やエスカレーションなど、毎回同じ方法で実行する必要がある部分は構造化プロシージャに委任してください。

制限事項

  • Ifステップはネストできず、2つのIfステップを連続して配置することもできません。
  • サポートされているシステムツールは end_call のみです。
  • 構造化プロシージャからナレッジベースドキュメントを参照することはできません。
  • プロシージャの完了時に現在のターンを終了する方法はありません。エージェントはターンを開いたままにし、話し続ける場合があります。
  • ワークフローのエッジは、構造化プロシージャへの接続および構造化プロシージャからの接続ができません。構造化プロシージャを連結するにはサブプロシージャステップを使用してください。開始と完了はプラットフォームによって管理されます。
  • プロシージャの開始にはレイテンシーが加わります。エージェントは開始時にツール呼び出しを行い、その後、生成されたワークフローを進みます。

モデルプロバイダーのサポート

構造化プロシージャでは、サブプロシージャに入るときとプロシージャを完了するときに、内部ツール呼び出しを強制します。主要なOpenAI、Anthropic、Gemini、Grokのモデルファミリーは、強制ツール選択をサポートしています。その他のモデルやカスタムプロバイダーでは保証されない場合があり、サブプロシージャへの遷移やプロシージャの完了の信頼性が低くなる可能性があります。別のモデルプロバイダーを使用する場合は、強制ツール選択のサポートを確認してください。

コンテンツサイズの上限や、構造化プロシージャと自由形式プロシージャの違いなど、すべてのプロシージャに適用される制限については、プロシージャを参照してください。