> This is a page from the ElevenLabs documentation. For a complete page index, fetch https://elevenlabs.io/docs/llms.txt. For the full documentation in a single file, fetch https://elevenlabs.io/docs/llms-full.txt.

# 構造化された手順

## 概要

構造化された手順は、固定された順序のステップを実行する[手順](/docs/ja/eleven-agents/customization/procedures)です。[自由形式の手順](/docs/ja/eleven-agents/customization/procedures/free-form-procedures)は、エージェントが解釈し、状況に合わせて調整する自然言語のガイダンスです。構造化された手順は、手順が適用されるたびにエージェントが順番に実行する、型付きステップの順序付きリストです。

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

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

![構造化された手順エディター](/docs/_fern-img/bc996f67b2afad8f1de5abe8febcf8af3766b4f098627b0ae60e0456b3c2703b.webp)

## 構造化された手順を使う場面

特定のステップを毎回同じ方法で実行する必要がありながら、平易なステップとして素早く作成したい場合は、構造化された手順を使用します。構造化された手順はワークフローより記述しやすい一方、表現力は低くなります。自由形式の手順、ワークフロー、システムプロンプトとの比較については、[手順を使う場面](/docs/ja/eleven-agents/customization/procedures#when-to-use-procedures)を参照してください。

## 構造化された手順の構成

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

### 名前

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

### トリガー

エージェントがこの手順を実行すべきタイミングを平易な言葉で説明します。たとえば、*ユーザーが注文の返金を求めたとき* です。エージェントはユーザーの意図を各手順のトリガーと比較し、一致するものを実行します。そのため、トリガーは具体的で明確に区別できるものにしてください。エージェントが参照するのはトリガーのテキストだけで、手順の名前やIDは参照しません。トリガーの仕組みはすべての手順で共通です。詳しくは[トリガーの記述](/docs/ja/eleven-agents/customization/procedures/free-form-procedures#writing-triggers)を参照してください。

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

### ステップ

手順本体は、型付きステップの順序付きリストです。複数のステップタイプを組み合わせて、タスクを記述します。

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

![構造化された手順のステップタイプ
メニュー](/docs/_fern-img/14976a6b9979d21fd7c77541a49e7475f8aa0764af4940746d3390804e7c4598.webp)

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

## APIステップリファレンス

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

### Ask

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

* APIタイプ：`ask`
* `instruction`：必須の空でない文字列。

```json focus={1-4}
{
  "type": "ask",
  "instruction": "Ask the user for their order ID."
}
```

### Tell

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

* APIタイプ：`tell`
* `instruction`：必須の空でない文字列。

```json focus={1-4}
{
  "type": "tell",
  "instruction": "Explain that the refund normally takes five to ten business days."
}
```

### Say

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

* APIタイプ：`say`
* `message`：必須の空でない文字列。
* `message_translations`：言語コードを`{ "value": "..." }`にマッピングする任意のオブジェクト。

```json focus={1-7}
{
  "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`リストが必要です。

```json focus={1-23}
{
  "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. アームが終了すると、手順はメインシーケンスに戻ります。

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

```json focus={1-14}
{
  "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`：任意の失敗ハンドラー。

```json focus={1-6}
{
  "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`           | フィールド              | 動作                               |
| ------------------ | ------------------ | -------------------------------- |
| `constant`         | `constant_value`   | 指定された値を常に送信します。                  |
| `dynamic_variable` | `dynamic_variable` | 指定された動的変数の現在の値を送信します。            |
| `llm`              | `prompt`（任意）       | 任意のプロンプトオーバーライドとともに、モデルが値を選択します。 |
| `omit`             |                    | パラメータを呼び出しから除外します。               |

```json focus={1-9}
{
  "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`：条件付き失敗処理用に予約されています。空のままにしてください。

```json focus={1-14}
{
  "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は失敗ハンドラーの最後のステップでなければなりません。

```json focus={1-4}
{
  "type": "retry",
  "max_retries": 2
}
```

### Sub-procedure

Sub-procedureステップは、別の構造化された手順を実行します。その手順のステップが完了すると、Sub-procedureステップの次のステップに実行が戻ります。

* APIタイプ：`sub_procedure`
* `procedure_id`：必須の空でない手順ID。
* 対象は同じエージェント上に存在する必要があります。
* 対象は構造化された手順である必要があります。
* 手順は自分自身を呼び出せません。

```json focus={1-4}
{
  "type": "sub_procedure",
  "procedure_id": "agtprc_6qbpwdq8n01bxhk44bgjy6f10ck3"
}
```

### System tool

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

* APIタイプ：`system_tool`
* `system_tool_name`：必須のシステムツール名。
* 現在サポートされているのは`end_call`のみです。今後、さらにシステムツールが追加される可能性があります。
* `end_call`は終端処理のため、含まれるシーケンス、アーム、または失敗ハンドラーの最後のステップでなければなりません。

```json focus={1-4}
{
  "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`は空であってはなりません。

これらのルールのいずれかに該当する手順の再構成方法については、[ベストプラクティス](#best-practices)を参照してください。

## 完全なAPI例

この例では、配送状況に基づく注文キャンセルを処理します。ツールパラメータを固定し、ツール呼び出しの失敗から回復し、別の構造化された手順を呼び出してから、通話を終了します。

```json maxLines=30
{
  "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"
    }
  ]
}
```

## 構造化された手順の実行方法

構造化された手順のステップをエージェントが実行する形式に変換することをコンパイルと呼びます。プラットフォームでは公開時にすべての構造化された手順をコンパイルするため、自分でコンパイルする必要はありません。現在、コンパイル結果は **ワークフロー** タブで読み取り専用ノードとして確認できます。

ユーザーのリクエストが手順のトリガーに一致すると、エージェントはその手順に入り、ステップを順番に実行します。構造化された手順内では、エージェントは各ステップを個別に処理します。最後に到達すると、会話の残りの部分に戻ります。

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

#### ユーザーを待つのはAskだけです

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

#### 手順の終端に到達してもターンは終了しません

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

#### Toolステップは成功と失敗のみを区別します

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

#### 一致しない場合、Ifステップは次へ進みます

条件を順番に評価し、最初に一致したものを実行します。どれにも一致しない場合はElseアームを実行します。
Elseがなく、どれにも一致しない場合、手順はIfの次のステップに進みます。処理されないケースが
エラーになることはありません。

#### Ifアームの状態は後続に引き継がれません

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

#### Ask、Tell、Sayステップにはツールがありません

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

## 構造化された手順を管理する

#### ダッシュボードで作成

[ダッシュボード](https://elevenlabs.io/app/agents)でエージェントを開き、**手順** を選択します。
**+** を使用して構造化された手順を作成します。トリガーを追加し、各ステップのタイプを選択して、
エージェントの変更を公開します。

ダッシュボードでは編集中に構造化された手順が検証されます。手順が
[検証ルール](#validation-rules)に違反している場合、**公開** ボタンはエラー状態になり、
**手順** タブにはエラーバッジが表示され、手順を修正するまでプレビューを開始できません。
エラーインジケーターを選択すると、影響を受けた手順とステップを確認できます。

![エラー状態のPublishボタンと、1 Error
バッジが表示された構造化された手順エディター](/docs/_fern-img/e406c33fac3966fab26d5d07e10d364a475fc4a56fd75aad2e23edbb0d1940d5.webp)

![失敗した手順と、メッセージが必要なステップを一覧表示する
検証詳細ダイアログ](/docs/_fern-img/a1cc889b2d0e68ce23725609b531938d0f7c417b1c6f4375103531eaae4ada63.webp)

#### CLIで管理

[ElevenLabs CLI](/docs/ja/eleven-agents/operate/cli)では、自由形式の手順と同じコマンドで構造化
手順を作成・公開できます。`type`を`deterministic`に設定し、ステップをJSONエンコード文字列として
`content`に渡します。

```bash
CONTENT=$(jq -n '{
  trigger: "When the user asks to refund an order",
  steps: [{ type: "ask", instruction: "Ask for the order ID." }]
}')

elevenlabs agents procedures create \
  --agent-id agent_7101k5zvyjhmfg983brhmhkd98n6 \
  --branch-id agtbranch_0901k4aafjxxfxt93gd841r7tv5t \
  --json "$(jq -n --arg content "$CONTENT" '{
    name: "Refund request",
    type: "deterministic",
    trigger: "When the user asks to refund an order",
    content: $content
  }')"

elevenlabs agents update \
  --agent-id agent_7101k5zvyjhmfg983brhmhkd98n6 \
  --branch-id agtbranch_0901k4aafjxxfxt93gd841r7tv5t \
  --json '{"version_description": "Publish refund procedure"}'
```

公開時にブランチ上のすべての構造化された手順が検証されます。いずれかが無効な場合、コマンドはゼロ以外で
終了し、手順IDをキーとするエラーを出力します。手順の下書きを修正して、再度公開してください。

#### APIで管理

APIおよびSDKのペイロードでは、構造化された手順に`type: "deterministic"`を使用します。`content`は
JSONエンコード済みドキュメントです。

### 前提条件

* `ELEVENLABS_API_KEY`環境変数に設定されたElevenLabs APIキー。
* 対象の`agent_id`と`branch_id`。ブランチ操作については[エージェントのバージョニング](/docs/ja/eleven-agents/operate/versioning)を参照してください。
* `elevenlabs` Pythonパッケージまたは`@elevenlabs/elevenlabs-js` JavaScriptパッケージのバージョン`2.60.0`以降。

APIでの編集は、新しいエージェントバージョンを公開するまで、選択したブランチ上で自分のユーザーにのみ表示されます。

### 下書きを作成または更新する

`POST /procedures`で構造化された手順を作成し、`type`を`deterministic`に設定します。
既存の手順は、以下のように`PATCH /procedures/{procedure_id}/draft`で更新します。

`trigger`はトップレベルフィールドとして設定します。ネストされたオブジェクトを送信するのではなく、
ステップドキュメントを`content`でJSONエンコードしてください。

```python focus={6-18}
import json
from elevenlabs import ElevenLabs

elevenlabs = ElevenLabs()

elevenlabs.conversational_ai.agents.procedures.drafts.update(
    agent_id="agent_7101k5zvyjhmfg983brhmhkd98n6",
    branch_id="agtbranch_0901k4aafjxxfxt93gd841r7tv5t",
    procedure_id="agtprc_6qbpwdq8n01bxhk44bgjy6f10ck3",
    name="Refund request",
    type="deterministic",
    trigger="When the user asks to refund an order",
    content=json.dumps(
        {
            "steps": [{"type": "ask", "instruction": "Ask for the order ID."}],
        }
    ),
)
```

```typescript focus={5-17}
import { ElevenLabsClient } from "@elevenlabs/elevenlabs-js";

const elevenlabs = new ElevenLabsClient();

await elevenlabs.conversationalAi.agents.procedures.drafts.update(
  "agent_7101k5zvyjhmfg983brhmhkd98n6",
  "agtbranch_0901k4aafjxxfxt93gd841r7tv5t",
  "agtprc_6qbpwdq8n01bxhk44bgjy6f10ck3",
  {
    name: "Refund request",
    type: "deterministic",
    trigger: "When the user asks to refund an order",
    content: JSON.stringify({
      steps: [{ type: "ask", instruction: "Ask for the order ID." }],
    }),
  }
);
```

```bash focus={1-9}
curl -X PATCH "https://api.elevenlabs.io/v1/convai/agents/agent_7101k5zvyjhmfg983brhmhkd98n6/branches/agtbranch_0901k4aafjxxfxt93gd841r7tv5t/procedures/agtprc_6qbpwdq8n01bxhk44bgjy6f10ck3/draft" \
  -H "xi-api-key: $ELEVENLABS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Refund request",
    "type": "deterministic",
    "trigger": "When the user asks to refund an order",
    "content": "{\"steps\":[{\"type\":\"ask\",\"instruction\":\"Ask for the order ID.\"}]}"
  }'
```

手順の下書きを保存しても、そのステップは検証されません。検証は公開時、または
`POST /v1/convai/agents/{agent_id}/drafts`でエージェントの下書きを保存したときに実行されます。

### 変更を公開する

[エージェントを更新](/docs/ja/api-reference/agents/update)で公開します。公開時にブランチ上のすべての
構造化された手順が検証・コンパイルされ、結果が新しいバージョンとともに保存されます。リクエストに
`workflow`フィールドは不要です。コンパイルは公開処理の一部として行われます。コンパイルの意味については、
[構造化された手順の実行方法](#how-a-structured-procedure-runs)を参照してください。

```python focus={5-8}
from elevenlabs import ElevenLabs

elevenlabs = ElevenLabs()

elevenlabs.conversational_ai.agents.update(
    agent_id="agent_7101k5zvyjhmfg983brhmhkd98n6",
    branch_id="agtbranch_0901k4aafjxxfxt93gd841r7tv5t",
)
```

```typescript focus={5-7}
import { ElevenLabsClient } from "@elevenlabs/elevenlabs-js";

const elevenlabs = new ElevenLabsClient();

await elevenlabs.conversationalAi.agents.update("agent_7101k5zvyjhmfg983brhmhkd98n6", {
  branchId: "agtbranch_0901k4aafjxxfxt93gd841r7tv5t",
});
```

```bash focus={1-5}
curl -X PATCH \
  "https://api.elevenlabs.io/v1/convai/agents/agent_7101k5zvyjhmfg983brhmhkd98n6?branch_id=agtbranch_0901k4aafjxxfxt93gd841r7tv5t" \
  -H "xi-api-key: $ELEVENLABS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'
```

構造化された手順が無効な場合、公開は`400`を返し、何も書き込まれません。

```json
{
  "detail": {
    "status": "procedure_validation_failed",
    "message": "Structured procedures failed validation.",
    "data": {
      "errors": {
        "agtprc_6qbpwdq8n01bxhk44bgjy6f10ck3": [
          {
            "path": "steps[0].ask.instruction",
            "message": "Step 1: Ask step requires an instruction"
          }
        ]
      }
    }
  }
}
```

`errors`は手順IDをキーとします。各エントリには、失敗したフィールドとステップが示されます。
手順の下書きを修正して、再度公開してください。

> **Note**
>
> このAPIの旧バージョンにあった`/procedures/compile`エンドポイントも引き続き動作しますが、
> レガシーであり、いずれ非推奨になります。公開時にコンパイルされるため、新しいコードでコンパイル
> エンドポイントを呼び出さないでください。

下書きの削除と破棄の動作については[手順を管理する](/docs/ja/eleven-agents/customization/procedures#manage-procedures)、
完全なエンドポイントスキーマについては
[Procedures APIリファレンス](/docs/ja/api-reference/agents/procedures/)を参照してください。

## ベストプラクティス

各ステップタイプにはそれぞれ固有の動作がすでに設定されているため、詳細を明示する必要はほとんどありません。各ステップの意図を書けば、あとはステップタイプが処理します。以下では、特に重要なケースのガイダンスを紹介します。

構造化された手順をテストするには、[手順の反復改善](/docs/ja/eleven-agents/customization/procedures/free-form-procedures#iterating-on-a-procedure)で説明しているステップに従ってください。

### ステップタイプの選択

#### Askステップごとに質問は1つだけにする

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

#### 文にはTell、質問にはAskを使用する

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

#### 質問だけでは不十分な場合、Askに明確な終了条件を設定する

Askステップは適切な回答を得ると次へ進みます。何が回答として扱われるかが
質問から明らかでない場合は、指示に明記してください。例：*注文IDを尋ねる。有効な
IDは8桁*。

#### 表現にはTell、完全に固定した文言にはSayを選択する

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

#### ツールを使わないステップにツールを避けるよう指示しない

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

### 手順の構成

#### 2つのIfステップの間に不要なステップを入れない

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

#### ネストされた判断はサブ手順に入れる

Ifステップはネストできません。ある判断が別の判断に依存する場合は、内側の判断を
専用の構造化された手順に入れ、必要なアームからサブ手順ステップで呼び出してください。

#### 「上記のいずれでもない」が重要な場合はElseを追加する

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

#### 後続ステップで必要な情報は保存する

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

#### 式条件は値を設定するツールの後に配置する

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

#### 共通ステップはサブ手順に抽出する

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

### ツールの使用

#### Toolステップは指示ではなくIfで制御する

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

#### パラメーター値は説明せず固定する

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

#### すべてのToolステップに失敗ハンドラーを設定する

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

#### Toolステップではツール呼び出しだけを行う

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

### 指示の書き方

#### 現在のステップだけを説明する

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

#### 文章でターンを終了しようとしない

\_this is the last message of this turn_のようにステップ指示へ書かれた文は、
プラットフォームにない境界をエージェントに強制させようとするものです。ユーザーを待つにはAskステップを、会話を終了するには
`end_call`システムツールを使用してください。

#### グローバルルールはシステムプロンプトに記載する

トーン、書式、締めの言葉、拒否ポリシーは[システム プロンプト](/docs/ja/eleven-agents/best-practices/prompting-guide)に記載します。ステップ指示には、そのステップに固有の内容だけを
書いてください。

### 手順の組み合わせ

手順を組み合わせるための一般的なガイダンスは構造化された手順にも適用されます。詳しくは、自由形式の手順のページにある[手順の組み合わせ](/docs/ja/eleven-agents/customization/procedures/free-form-procedures#composing-procedures)を参照してください。

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

## 制限事項

* Ifステップはネストできず、2つのIfステップを連続して配置することもできません。
* サポートされているシステムツールは`end_call`のみです。
* 構造化された手順からナレッジベースドキュメントを参照することはできません。
* 手順完了時に現在のターンを終了する方法はありません。エージェントはターンを開いたままにし、話し続ける場合があります。
* ダッシュボード内の特定のワークフローノードから構造化された手順を開始することはできません。
* 手順の開始にはレイテンシーが加わります。エージェントは手順に入るためにツール呼び出しを行い、その後生成されたワークフローを進みます。

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

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

コンテンツサイズの上限や構造化された手順と自由形式の手順の違いなど、すべての手順に適用される制限については、[手順](/docs/ja/eleven-agents/customization/procedures#limitations)を参照してください。