---
title: "에이전트 단계 및 핸드오프"
description: "에이전트를 고유한 지시 사항, 도구 및 수집된 값을 포함한 단계로 분할하고, 통화 중간에 에이전트 간 통화를 넘깁니다."
---

단일 프롬프트는 모델에 전체 작업을 한 번에 제공합니다. **단계**는 통화의 한
단계만 한 번에 제공합니다. 각 단계에는 자체 지시사항, 자체 도구, 선택적으로
한 단어도 바꾸지 않고 말하는 문구, 그리고 다음 단계로 넘어가기 전에 수집해야 하는 값이 있습니다.
**인계**를 사용하면 조직 내의 다른 에이전트가 통화 중간에 대화를 이어받을 수
있으며, 기록이 그대로 유지되므로 발신자는 같은 내용을 반복할 필요가 없습니다.

모든 에이전트는 단일 프롬프트로 시작합니다. 단계나 인계를 추가하기 전까지는
아무것도 변경되지 않습니다.

## 단계 또는 단일 프롬프트?

| 단계를 사용하는 경우 | 단일 프롬프트를 유지하는 경우 |
| --- | --- |
| 통화에 순서대로 진행해야 하는 단계가 있는 경우: 확인 후 예약 | 대화가 개방형인 경우: FAQ, 안내, 일반 지원 |
| 에이전트가 다음 단계로 넘어가기 전에 값을 수집해야 하는 경우 | 정해진 순서로 수집할 항목이 없는 경우 |
| "18세 미만 발신자는 보호자에게 연결"과 같이 절대 유연하게 적용하면 안 되는 규칙이 있는 경우 | 모든 분기에서 모델의 판단이 충분히 좋은 경우 |
| 통화의 정해진 시점에 조회를 실행해야 하는 경우 | 발신자가 요청할 때마다 도구를 호출할 수 있는 경우 |
| 통화의 일부가 자체 프롬프트와 음성을 가진 다른 에이전트의 담당인 경우 | 하나의 페르소나가 모든 것을 처리하는 경우 |

단계는 스크립트화된 전화 메뉴가 아닙니다. 단계 내에서 모델은 단일 프롬프트를
사용할 때와 마찬가지로 대화를 진행합니다. 단계는 모델이 수행 중인 작업, 사용할
수 있는 도구, 그리고 벗어나기 전에 필요한 항목을 결정합니다.

## 단계형 에이전트의 구성 방식

에이전트에 단계가 있으면 `prompt`에는 **공통 지시사항**이 포함됩니다. 즉, 모든
단계에 적용되는 페르소나와 규칙입니다. 각 단계는 여기에 자체 지시사항을
추가합니다. 매 차례마다 모델은 공통 지시사항, 현재 단계의 이름과 지시사항,
그리고 지금까지 수집된 값을 확인합니다.

빌더에서 에이전트를 **단일 프롬프트**에서 **단계**로 전환합니다. 각 단계의
이름, 지시사항, 발화 문구, 도구, 수집된 값 및 전환이 포함된 카드, 인계 선택기,
그리고 단계의 읽기 전용 흐름 그래프가 표시됩니다. 단일 프롬프트로 다시 전환하면
공통 지시사항과 모든 단계를 병합한 평면화된 프롬프트가 제공됩니다.

API에서는 `steps`와 `handoffs`가
[에이전트](/api-reference/agents)의 필드입니다. 다른 모든 에이전트 필드와
마찬가지로 `PATCH`는 초안에 이를 준비하고, `POST /v1/agents/{agent_id}/deploy`는
이를 라이브로 적용합니다. `"steps": null`을 전송하면 에이전트가 단일 프롬프트로
다시 전환됩니다. 테스트 통화와 **대화**는 초안을 실행합니다.

<Tip>
  [코파일럿](/ko/guides/ask-the-copilot)은 설명을 바탕으로 단계를 만들 수 있습니다
  ("예약 전에 생년월일을 확인하는 단계를 추가해 줘"). 또한 다른 단계는 건드리지
  않고 하나의 단계만 수정할 수 있습니다.
</Tip>

### 단계 필드

| 필드 | 의미 |
| --- | --- |
| `id` | 필수입니다. 문자로 시작하며 소문자, 숫자 및 밑줄을 사용할 수 있고 최대 40자입니다. 에이전트 내에서 고유해야 합니다. |
| `name` | 필수 표시 이름이며, 1~80자입니다. |
| `instructions` | 필수이며 최대 20,000자입니다. `prompt`와 마찬가지로 `{{var}}` [통화 변수](/ko/guides/call-variables)를 지원합니다. |
| `say` | 선택 사항이며, 단계에 진입할 때 한 단어도 바꾸지 않고 말하는 문구입니다. 최대 1,000자이며 `{{var}}`를 지원합니다. |
| `tools` | `null`이면 단계에 에이전트에 연결된 모든 도구를 제공합니다. 목록을 지정하면 이름을 기준으로 해당 도구로 단계를 제한합니다. `end_call`, `transfer_call`과 같은 내장 작업은 모든 단계에서 에이전트 설정을 따릅니다. |
| `collect` | 단계에서 수집하는 값은 최대 20개입니다. 각 값에는 `name`, `type`, `description`, `required`(기본값 `true`)가 있습니다. |
| `on_enter_tool` | 선택적 도구 이름입니다. 단계에 진입할 때 자동으로 호출됩니다. [Webhook 단계](#webhook-steps)를 참조하세요. |
| `transitions` | 단계가 다음으로 이동할 수 있는 위치의 순서가 지정된 목록입니다. [전환](#transitions)을 참조하세요. |
| `global_when` | 선택 사항입니다. 어떤 단계에서도 해당 단계에 도달할 수 있게 합니다. [전역 단계](#global-steps)를 참조하세요. |
| `voice` | 이 단계에 사용할 선택적 음성 ID입니다. 에이전트가 사용자 지정 음성 구성을 사용하는 경우 무시됩니다. |

그래프 자체는 `{"start_step": "<step id>", "steps": [...]}`입니다. 통화는
`start_step`에서 시작합니다.

## 전환

각 전환에는 `to`, 단계 ID, 그리고 다음 중 정확히 하나가 있습니다.

- **`when`**: 일반 언어로 작성하며, **모델이 결정합니다**. 에이전트에는 이동할 수 있는 단계를 나열하는 기본 제공 `go_to_step` 도구가 있으며, 각 `when`은 해당 단계를 선택하는 이유가 됩니다.
- **`condition`**: 수집된 값에 대한 규칙이며, **코드가 결정합니다**. 모델은 이를 건너뛰거나 대화로 우회할 수 없습니다.
- **`"always": true`**: 검사 없이 계속 진행합니다. 코드가 먼저 결정합니다. 단계에 진입하는 즉시 또는 필수 값이 수집되면, 모델이 `when`을 선택하기 전에 처음으로 일치하는 `condition` 또는 `always` 전환이 적용됩니다. 따라서 `always`는 조건의 대체 항목으로 조건 뒤에 배치하거나, 단계를 다음 단계로 바로 연결하려면 단독으로 사용합니다. `always`가 있는 단계는 `when` 선택을 기다리지 않습니다.

`condition`은 `{"value": <collected name or dotted path>, "op": <op>, "target": <literal>}` 형식입니다.

| `op` | 값이 참이 되는 경우 |
| --- | --- |
| `eq`, `ne` | `target`과 같거나 같지 않은 경우 |
| `lt`, `lte`, `gt`, `gte` | `target`보다 작거나, 이하이거나, 크거나, 이상인 경우 |
| `in`, `not_in` | `target` 목록의 값 중 하나이거나 아닌 경우 |
| `exists`, `missing` | 수집되었거나 수집되지 않은 경우 (`target` 없음) |

`eq`, `ne`, `in`, `not_in`은 공백을 제거한 후 대소문자를 구분하지 않고 텍스트를 비교합니다. 숫자는 숫자로, 날짜는 `YYYY-MM-DD` 문자열로 비교합니다. 한 번도 수집되지 않은 값은 `missing`을 제외한 모든 연산에서 거짓이 됩니다.

`when`과 `global_when`은 말할 내용이 아니라 "발신자가 예약을 원합니다"와 같은 조건으로 작성합니다. 에이전트는 이를 내부 라우팅 메모로 인식하며, 이를 소리 내어 읽거나 단계를 변경한다는 사실을 언급하지 않도록 지시받습니다.

모델이 `go_to_step`을 호출하면 다음이 수행됩니다.

1. 단계의 모든 `required` 값이 있어야 합니다. 하나라도 없으면 모델에 누락된 값을 알려 주며, 모델은 발신자에게 해당 값을 요청합니다.
2. 값이 저장됩니다.
3. `condition` 및 `always` 전환을 순서대로 검사합니다. 처음 일치하는 전환이 적용됩니다.
4. 그렇지 않으면 에이전트는 모델이 선택한 단계로 이동합니다.
5. 일치하는 항목이 없고 모델이 단계를 지정하지 않은 경우 에이전트는 현재 단계에 머뭅니다.

[전역 단계](#global-steps)로 이동하는 경우는 예외입니다. 발신자가 주제를 변경했으므로 현재 단계에 아직 누락된 필수 값이 있더라도 진행하며, 해당 단계의 조건을 검사하기 전에 이동합니다.

`condition` 및 `always` 전환은 단계에 진입할 때마다 검사되므로, 코드가 결정하는 단계가 연속된 경우 한 번에 진행됩니다. 체인은 다음 경우에 중지됩니다.

- 이번 실행에서 이미 방문한 단계에 도달한 경우
- 8회 이동 후
- 아직 수집할 필수 값이 있는 단계에 도달한 경우. 단, 단계에 `on_enter_tool`이 있으면 예외입니다(웹훅 단계는 항상 결과에 따라 라우팅됩니다).

체인이 중지된 단계의 `say` 줄만 음성으로 말합니다.

전환이 없는 단계는 **종료 단계**입니다. 에이전트는 해당 단계에서 완료하고 일반적인 기본 제공 작업으로 통화를 종료하거나 전환합니다.

## 값 수집

단계에 필요한 항목을 `collect`에 나열합니다. 모델은 `go_to_step`을 호출할 때 값을 전달하며, 해당 값은 통화가 끝날 때까지 계속 사용할 수 있습니다.

| `type` | 저장하는 값 |
| --- | --- |
| `string` | 모든 텍스트 |
| `number` | 숫자 |
| `boolean` | `true` 또는 `false` |
| `date` | `YYYY-MM-DD` 형식의 날짜 |

수집된 값은 통화 콘텐츠입니다. 이러한 값은 통화에서 대화 내용 옆에 표시되며 동일한 보존, 삭제 및 마스킹 규칙을 따릅니다. 에이전트의 통화 녹음이 꺼져 있으면 수집된 값은 저장되지 않으며 웹훅으로도 전송되지 않습니다. 단계 타임라인은 계속 유지됩니다. [통화에서 확인할 위치](#where-to-see-it-on-a-call)를 참조하세요.

## 안내 문구

에이전트가 단계에 진입하면 `say`는 작성된 그대로 발화됩니다. 그런 다음 모델은 해당 문구가 방금 발화된 것을 인지한 상태로 같은 응답에서 새 단계를 계속 진행하므로, 이를 반복하지 않습니다. 인사말, 필수 고지 및 고정 문구에는 `say`를 사용하고, 나머지 응답은 모델에 맡기세요.

시작 단계의 `say`는 동의 안내가 있는 경우 그 이후에 에이전트가 먼저 말할 때의 첫 문구입니다. 발신자가 먼저 말하는 경우에는 IVR이나 음성사서함 인사말이 아닌 사람에게 하는 에이전트의 첫 응답으로 시작합니다.

통화가 `__previous__` 또는 되돌려 전달하기를 통해 해당 단계로 돌아와도 단계의 `say`는 다시 발화되지 않습니다. 실제로 들려야 하는 방식으로 작성하세요. 음성이 잘못 읽을 수 있는 내용은 모두 풀어서 쓰세요. 안내 문구는 `{{var}}` 통화 변수를 지원하지만 수집된 값은 지원하지 않습니다.

## 웹훅 단계

`on_enter_tool`을 에이전트의 도구 중 하나로 설정하면 모델을 기다리지 않고 단계에 진입하는 즉시 실행됩니다. 인수는 이름이 도구의 매개변수 이름과 일치하는 수집된 값입니다. 결과는 4KB로 잘린 `<tool>_result`라는 이름의 수집된 값으로 저장되며, 단계의 `condition` 및 `always` 전환이 즉시 확인되므로 조회 결과만으로 통화를 라우팅할 수 있습니다.

저장된 값에는 두 개의 필드가 있습니다.

| 필드 | 포함 내용 |
| --- | --- |
| `status` | 엔드포인트가 반환한 HTTP 상태 코드입니다. |
| `response` | 응답 본문입니다. |

본문 필드를 기준으로 라우팅하려면 `lookup_account_result.response.<field>`를 사용하고, 상태 코드를 기준으로 라우팅하려면 `lookup_account_result.status`를 사용하세요.

조회는 최대 8초 동안 실행되며, 도구 자체의 제한 시간이 더 짧으면 해당 제한 시간이 적용됩니다. 3초 이상 걸리면 발신자가 침묵 상태로 남지 않도록 에이전트가 짧은 문구를 말합니다. 엔드포인트가 400 이상의 상태를 반환하거나 제시간에 응답하지 않으면, 에이전트는 지금은 확인할 수 없다고 발신자에게 알리고 수행할 수 있는 작업을 계속합니다.

## 전역 단계

`global_when`이 있는 단계는 해당 설명이 성립할 때 어느 단계에서나 도달할 수 있습니다. `when`과 마찬가지로 모델이 판단합니다. 청구 관련 질문, 사람 상담 요청, 불만 등 발신자가 언제든 제기할 수 있는 주제에 사용하세요.

전역 단계에서 `"to": "__previous__"`를 사용하는 전환은 통화를 이전에 활성 상태였던 단계로 되돌리므로, 발신자는 중단한 지점부터 이어갈 수 있습니다. 단계는 재개됩니다. `on_enter_tool`은 다시 실행되지 않고, `say`는 반복되지 않으며, 에이전트는 처음부터 시작하지 않고 해당 단계를 계속 진행합니다.

## 인계

`handoffs`는 통화를 이어받을 수 있는 조직 내 다른 에이전트를 나열합니다.

```json
[{"agent_id": 413, "when": "The caller asks about billing or a refund"}]
```

에이전트에는 해당 에이전트와 사유가 포함된 기본 제공 `hand_off` 도구가 있습니다. 전환과 마찬가지로 각 `when`은 내부 라우팅 메모이며, 절대 음성으로 읽지 않습니다.

인계할 때 에이전트는 자체 음성으로 "물론입니다. 청구 팀으로 연결해 드리겠습니다"와 같이 발신자에게 이동할 위치를 알려 주는 짧은 한 문장을 말합니다. 그러면 대상 에이전트의 프롬프트, 단계, 도구 및 음성이 이어받고 동일한 기록으로 통화가 계속됩니다. 새 에이전트는 간단히 자신을 소개하고 발신자의 마지막 요청에 답변하며, 전환을 알리지는 않습니다. 그 시점부터 대상 에이전트의 지식 베이스를 사용할 수 있습니다.

통화가 에이전트에 처음 도달하면 해당 에이전트의 `start_step`에서 시작합니다. 이 단계의 `on_enter_tool`이 실행되고 `say`가 음성으로 재생됩니다. 통화가 이미 방문한 에이전트로 다시 인계되면 해당 에이전트는 `on_enter_tool`을 실행하거나 `say`를 반복하거나 다시 자신을 소개하지 않고, 이전에 있던 단계를 재개합니다. 수집된 값은 통화의 모든 에이전트가 공유합니다.

- 대상은 동일한 조직의 에이전트여야 하며, 에이전트는 자신에게 인계할 수 없습니다.
- 통화 수준의 모든 설정은 응답한 에이전트에 유지됩니다. 여기에는 제품, 언어, 먼저 말하는 주체, 음성 사서함, 동의 안내 및 기타 모든 통화 설정이 포함됩니다.
- 대상은 다시 다른 에이전트에게 또는 원래 에이전트에게 인계할 수 있습니다. 하나의 통화는 최대 8개의 에이전트에 도달할 수 있습니다.
- 테스트 통화는 테스트하는 에이전트의 초안을 실행합니다. 인계 대상 에이전트는 배포된 버전을 실행합니다.
- 두 에이전트에 이름은 같지만 정의가 다른 도구가 있으면 통화에는 하나만 유지되며, 응답한 에이전트의 도구가 항상 우선합니다. 저장할 때 빌더가 경고를 표시합니다.
- 에이전트는 단계 없이도 인계를 사용할 수 있습니다. 전체 프롬프트가 그대로 사용됩니다.

`go_to_step` 및 `hand_off`는 단계 또는 인계가 있는 에이전트에서 예약되어 있으므로 자체 도구에 이 이름을 사용할 수 없습니다.

## 통화에서 확인하는 위치

**통화 기록**에서 통화를 엽니다. 기록 옆의 단계 타임라인에는 통화가 진입한 각 단계와 그 이유가 표시되며, 수집된 값도 함께 나열됩니다.

[통화 객체](/api-reference/calls#retrieve-a-call)와 통화 완료 웹훅([`telephony.complete` / `web.complete`](/ko/webhooks/call-complete))에는 `steps_trace` 및 `collected_values`와 동일한 데이터가 포함됩니다. 단계가 없는 통화에서는 둘 다 제공되지 않습니다.

```json
"steps_trace": [
  {"t_ms": 0, "agent": "a412", "step": "greet", "via": "start"},
  {"t_ms": 51230, "agent": "a412", "step": "verify", "via": "model"},
  {"t_ms": 98410, "agent": "a412", "step": "minor", "via": "condition"}
],
"collected_values": {"full_name": "Dana Reyes", "dob": "2010-04-02", "age": 15}
```

`agent`는 `a` 뒤에 에이전트 ID가 붙는 형식입니다. `via`는 통화를 이동시킨 요소를 나타냅니다.

| `via` | 의미 |
| --- | --- |
| `start` | 통화가 이 단계에서 시작되었습니다. |
| `model` | 모델이 `go_to_step`, `when` 또는 `global_when`을 통해 단계를 선택했습니다. |
| `condition` | `condition` 또는 `always` 전환이 일치했습니다. |
| `on_enter` | 웹훅 단계의 결과에 따라 전환이 일치했습니다. |
| `handoff` | 다른 에이전트가 통화를 이어받았습니다. |

## 단계가 실행되는 위치

단계는 수신, 발신 및 캠페인 통화, 테스트 통화, 웹 및 위젯 통화에서 **Spark**, **Bolt** 및 모든 **Storm** 제품에서 네이티브로 실행됩니다.

그 외 모든 환경에서도 에이전트는 구조 없이 계속 작동합니다. 공유 지시 사항과 모든 단계를 순서대로 병합한 평면화된 프롬프트를 실행합니다. 여기에는 다음이 포함됩니다.

- 실험적 Bolt 제품
- 저장된 에이전트용 세션을 포함한 [Realtime](/ko/guides/use-with-openai-realtime) 세션
- [동적 통화 구성](/ko/guides/dynamic-call-config) 웹훅이 반환하는 인라인 구성. `agent_id`를 반환하는 웹훅은 해당 에이전트의 단계를 사용합니다.

## 제한 사항

| 제한 사항 | 값 |
| --- | --- |
| 에이전트당 단계 수 | 100 |
| 단계당 수집 값 | 20 |
| 에이전트당 핸드오프 대상 | 8 |
| 한 통화에서 연결 가능한 에이전트 수 | 8 |
| `steps` JSON 크기 | 200 KB |
| 단계 `instructions` | 20,000자 |
| `say` 줄 | 1,000자 |
| 저장된 `on_enter_tool` 결과 | 4 KB |

규칙을 위반하는 저장은 `steps.steps[2].transitions[0].to`와 같이
문제가 있는 필드의 경로와 함께 `400`을 반환합니다. `tools` 및
`on_enter_tool`의 도구 이름은 에이전트에 연결된 도구여야 합니다.

단계별 언어, 모델을 건너뛰는 스크립트 단계, say 줄 내 수집 값은
지원되지 않습니다.

## 가져온 에이전트

Retell, Bland, Vapi 또는 ElevenLabs에서 [가져오기](/ko/guides/import-agents)하면
멀티 프롬프트 에이전트, 플로우, 경로 및 워크플로는 단계로 가져오고,
스쿼드와 에이전트 전환은 가져온 에이전트 간의 핸드오프로 가져옵니다.
가져오기 전에 검토 페이지에서 둘 다 표시됩니다.

## 예시: 치과 접수

순서대로 세 단계입니다. 인사, 환자 정보 수집, 예약입니다.

```json
{
  "prompt": "You are Ava, the front desk assistant at Acme Dental. Be warm and brief. Ask one question at a time.",
  "steps": {
    "start_step": "greet",
    "steps": [
      {
        "id": "greet",
        "name": "Greeting",
        "instructions": "Greet the caller and ask how you can help.",
        "say": "Thanks for calling Acme Dental, this is Ava. How can I help you today?",
        "tools": null,
        "collect": [],
        "transitions": [
          {"to": "details", "when": "The caller wants to book an appointment"}
        ]
      },
      {
        "id": "details",
        "name": "Patient details",
        "instructions": "Ask for the caller's full name, date of birth and the reason for the visit. Read the date of birth back and ask the caller to confirm it.",
        "tools": null,
        "collect": [
          {"name": "full_name", "type": "string", "description": "Caller's full name", "required": true},
          {"name": "dob", "type": "date", "description": "Date of birth", "required": true},
          {"name": "reason", "type": "string", "description": "Reason for the visit", "required": true},
          {"name": "new_patient", "type": "boolean", "description": "First visit to the practice", "required": false}
        ],
        "transitions": [
          {"to": "book", "when": "The caller has confirmed their details"}
        ]
      },
      {
        "id": "book",
        "name": "Book",
        "instructions": "Offer the two earliest open slots from book_slot and book the one the caller picks. Confirm the date and time, then say goodbye and end the call.",
        "tools": ["book_slot"],
        "collect": [],
        "transitions": []
      }
    ]
  }
}
```

`PATCH /v1/agents/{agent_id}`로 스테이징하고 **대화**에서 테스트한 다음 배포합니다.
이름, 생년월일, 방문 사유를 수집하기 전에는 `details` 단계에서 예약으로
핸드오프할 수 없습니다. `new_patient`는 선택 사항입니다.

## 예시: 연령 제한 분기

모델은 누구와도 대화할 수 있지만, 예약 대상은 코드가 결정합니다. 연령을
수집한 다음 모델 자체의 선택을 고려하기 전에 이를 기준으로 라우팅합니다.

```json
{
  "id": "verify",
  "name": "Verify age",
  "instructions": "Ask for the caller's age.",
  "tools": null,
  "collect": [
    {"name": "age", "type": "number", "description": "Caller's age in years", "required": true}
  ],
  "transitions": [
    {"to": "guardian", "condition": {"value": "age", "op": "lt", "target": 18}},
    {"to": "book", "when": "The caller has given their age"}
  ]
}
```

발신자가 열다섯이라고 말하면 모델의 결정과 관계없이 `guardian`으로 이동합니다.
그 외 모든 발신자는 `book`으로 이동합니다. 둘 다 그래프의 다른 위치에 있는 일반 단계입니다.

## 예시: 계정 조회 웹훅 단계

발신자가 계정 번호를 제공하면 다음 단계에 진입할 때 조회가 실행되고,
그 결과에 따라 경로가 선택됩니다. 간결성을 위해 `not_found`, `collections`, `support`
단계는 생략했습니다.

```json
[
  {
    "id": "identify",
    "name": "Identify",
    "instructions": "Ask for the caller's account number and read it back digit by digit.",
    "tools": null,
    "collect": [
      {"name": "account_number", "type": "string", "description": "Account number", "required": true}
    ],
    "transitions": [
      {"to": "lookup", "when": "The caller has confirmed their account number"}
    ]
  },
  {
    "id": "lookup",
    "name": "Look up account",
    "instructions": "Tell the caller what you found on their account and ask how you can help.",
    "tools": ["lookup_account"],
    "collect": [],
    "on_enter_tool": "lookup_account",
    "transitions": [
      {"to": "not_found", "condition": {"value": "lookup_account_result.response.found", "op": "eq", "target": false}},
      {"to": "collections", "condition": {"value": "lookup_account_result.response.account_status", "op": "in", "target": ["past_due", "suspended"]}},
      {"to": "support", "when": "The caller needs help with an active account"}
    ]
  }
]
```

`lookup_account`의 매개변수 이름이 `account_number`이므로 이를 수신합니다.
응답 본문에 `"found": false`가 있으면 통화는 `not_found`로 이동합니다.
`account_status`가 `past_due` 또는 `suspended`이면 `collections`로 이동합니다.
활성 계정은 `lookup`에 유지되며, 여기서 모델이 지원을 제공한 후
`support`로 이동합니다. 실패한 조회를 별도 단계로 보내려면 먼저 상태에 대한
조건을 추가합니다. 오류 응답은 상태 코드를 저장하므로
`{"value": "lookup_account_result.status", "op": "gte", "target": 400}`로
이를 포착할 수 있습니다. 시간 초과 또는 응답 없음은 `"error"`를 저장하므로
`{"value": "lookup_account_result.status", "op": "eq", "target": "error"}`로
이를 포착할 수 있습니다.

## 예시: 대표 전화에서 청구로 연결

에이전트는 두 개입니다. 대표 전화(에이전트 `412`)가 모든 통화에 응답하고,
청구 관련 문의는 자체 프롬프트, 도구 및 음성을 사용하는 청구 에이전트(에이전트 `413`)에게 연결합니다.

대표 전화에서 다음을 설정합니다.

```json
{
  "handoffs": [
    {"agent_id": 413, "when": "The caller asks about a bill, a payment or a refund"}
  ]
}
```

청구 에이전트에서 발신자를 다시 연결할 수 있도록 다음을 설정합니다.

```json
{
  "handoffs": [
    {"agent_id": 412, "when": "The billing question is resolved and the caller needs something else"}
  ]
}
```

대표 전화는 "청구팀으로 연결해 드리겠습니다"와 같은 짧은 안내를 하고,
청구 에이전트는 자신을 소개한 뒤 대표 전화가 중단한 지점부터 대화를 이어갑니다.
청구 담당에서 다시 연결하면 대표 전화는 발신자에게 다시 인사하지 않고
중단한 지점부터 이어서 진행합니다. 통화의 제품, 언어, 동의 안내 및 기타
통화 설정은 대표 전화가 응답했으므로 대표 전화에 유지됩니다.

청구에 자체 에이전트가 아니라 자체 지시만 필요하다면, 대신 대표 전화에서
전역 단계를 사용합니다. 문의에 답변하면 통화는 발신자가 있던 단계로 돌아갑니다.

```json
{
  "id": "billing",
  "name": "Billing questions",
  "instructions": "Answer questions about bills and payments. Offer to send a payment link by email.",
  "tools": null,
  "collect": [],
  "transitions": [
    {"to": "__previous__", "when": "The billing question is answered"}
  ],
  "global_when": "The caller asks about a bill or payment at any point"
}
```

## 다음 단계

<CardGroup cols={2}>
  <Card title="프롬프트 가이드" icon="pen" href="/ko/guides/prompting">
    전화 통화에서도 효과적인 공통 지시와 단계 지시를 작성합니다.
  </Card>
  <Card title="도구 통합 구축" icon="code" href="/ko/guides/build-tool-integration">
    단계와 웹훅 단계에서 호출하는 도구를 만듭니다.
  </Card>
  <Card title="에이전트 테스트" icon="flask" href="/ko/guides/test-agents">
    배포 전에 모든 분기에 대해 동일한 시나리오를 실행합니다.
  </Card>
  <Card title="Agents API" icon="robot" href="/api-reference/agents">
    모든 에이전트 필드, 초안 및 배포를 확인합니다.
  </Card>
</CardGroup>
