> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tryvox.co/llms.txt
> Use this file to discover all available pages before exploring further.

# 실시간 음성 런타임 API 작성

> v3 API의 프롬프트 에이전트에서 실시간 음성 런타임을 지정하고 제공사별 제약을 확인할 수 있어요.

v3 에이전트 계약은 `single_prompt` 음성 통화에 GPT-Live, Grok Voice, Gemini Live를 지정할 수 있어요. `data.runtime`은 실시간 음성 제공사를 고르고, `data.llm`은 텍스트 업무 처리를 맡아요. 이 페이지는 요청 계약과 런타임별 제약을 설명해요.

<Note>
  `type: "flow"` 에이전트에는 `gpt_live`, `grok_voice`, `gemini_live` 런타임을 보낼 수 없어요. 기존 플로우 에이전트는 `pipeline` 런타임을 쓰고, `single_prompt`로 자동 변환하거나 마이그레이션하지 않아요.
</Note>

<Note>
  현재 API 스키마는 요청 형식을, 요청 후 조회는 저장된 설정을 확인해요. 둘 다 런타임 배포나 워크스페이스 권한은 보장하지 않으니, 사용할 환경에서 시험 통화로 제공사 세션을 확인하세요.
</Note>

## 런타임별 값

런타임마다 API 스키마에 정의된 모델과 그 제공사(provider) 전용 음성만 받아요. 다른 런타임의 모델이나 음성을 섞지 마세요.

| 런타임 | `type` | `model` | `voice` |
| - | - | - | - |
| GPT-Live | `gpt_live` | `gpt-live-1` | 빌트인(`builtin`) 또는 커스텀(`custom`) |
| Grok Voice | `grok_voice` | `grok-voice-think-fast-2.0` | 빌트인(`builtin`)만 |
| Gemini Live | `gemini_live` | `gemini-2.5-flash-native-audio-preview-12-2025` | 빌트인(`builtin`)만 |
| 기존 파이프라인 | `pipeline` | - | `runtime`이 아니라 `data.voice` |

## 제공사별 기능 호환성

현재 vox.ai 통합은 GPT-Live와 Gemini Live에서 아래 음성 설정을 제한해요. 표는 현재 런타임의 검증 조건을 나타내며, 제공사 자체가 TTS나 외부 오디오 재생을 지원하지 않는다는 뜻은 아니에요.

| 런타임 | 통화 스크리닝 | `transfer_call` | `speakDuringExecution` |
| - | - | - | - |
| GPT-Live | `callSettings.callScreening`이 `null`이 아니면 거부돼요. 인바운드와 아웃바운드 모두 적용돼요. | 상담사(`operator`) 대상이 하나라도 있으면 전체 구성을 거부해요. 안내 후 전환은 동적 문구면 항상 거부하고, 정적 문구는 공백이 아닌 내용이 있을 때 거부해요. | `enabled`가 켜져 있고 `messages`에 비어 있지 않은 항목이 있으면 거부돼요. |
| Gemini Live | GPT-Live와 같은 제한이 적용돼요. | GPT-Live와 같은 제한이 적용돼요. | GPT-Live와 같은 제한이 적용돼요. |
| Grok Voice | 이 표의 제한은 적용하지 않아요. | 이 표의 제한은 적용하지 않아요. | 이 표의 제한은 적용하지 않아요. |

`operator` 대상은 전환 대상 목록을 모두 검사해요. 전화나 SIP 대상과 섞었거나, 선택한 전환 대상이 달라도 거부돼요. 즉시 전환과 안내 후 전환 모두 해당해요. 안내 후 전환의 동적 문구는 프롬프트를 생략하거나 비워도 기본 문구를 만들기 때문에 거부돼요. 정적 문구는 `warmTransferStaticSentence`에 공백이 아닌 내용이 있을 때만 거부돼요. 이 제한은 기존 파이프라인 동작을 바꾸거나 파이프라인 설정을 자동으로 옮기지 않아요.

### Grok Voice

```json theme={null}
{
  "type": "grok_voice",
  "model": "grok-voice-think-fast-2.0",
  "voice": { "type": "builtin", "name": "eve" }
}
```

음성 이름은 소문자예요. 허용 목록은 `carina`, `zagan`, `helix`, `orion`, `luna`, `iris`, `altair`, `zenith`, `perseus`, `helios`, `lux`, `kepler`, `rigel`, `cosmo`, `celeste`, `ursa`, `sirius`, `lumen`, `castor`, `naksh`, `atlas`, `ara`, `eve`, `leo`, `rex`, `sal`이에요. `eve`는 예시이고 기본값으로 자동 선택되지 않아요.

### Gemini Live

```json theme={null}
{
  "type": "gemini_live",
  "model": "gemini-2.5-flash-native-audio-preview-12-2025",
  "voice": { "type": "builtin", "name": "Puck" }
}
```

이 계약은 LiveKit 1.8.1 호환 초기 릴리스의 Gemini 2.5 모델을 써요. Gemini 3.1과 3.8 모델은 이 계약에서 지원하지 않아요. 음성 이름은 대소문자를 구분하고, 허용 목록은 `Achernar`, `Achird`, `Algenib`, `Algieba`, `Alnilam`, `Aoede`, `Autonoe`, `Callirrhoe`, `Charon`, `Despina`, `Enceladus`, `Erinome`, `Fenrir`, `Gacrux`, `Iapetus`, `Kore`, `Laomedeia`, `Leda`, `Orus`, `Pulcherrima`, `Puck`, `Rasalgethi`, `Sadachbia`, `Sadaltager`, `Schedar`, `Sulafat`, `Umbriel`, `Vindemiatrix`, `Zephyr`, `Zubenelgenubi`이에요. `Puck`은 예시이고 기본값으로 자동 선택되지 않아요.

## 런타임 선택

새로 만드는 요청에서 `data.runtime`을 생략하거나 `{"type":"pipeline"}`으로 보내면 기존 파이프라인 동작을 유지해요. 네이티브 실시간 런타임을 고를 때는 런타임 객체에 `type`, `model`, `voice`를 모두 적으세요. 수정 요청에서 `runtime`을 생략하면 현재 런타임을 유지해요.

```json theme={null}
{
  "runtime": {
    "type": "gpt_live",
    "model": "gpt-live-1",
    "voice": {
      "type": "builtin",
      "name": "marin"
    }
  }
}
```

OpenAI 네이티브 GPT-Live 커스텀 음성 참조는 아래 꼴이에요.

```json theme={null}
{
  "runtime": {
    "type": "gpt_live",
    "model": "gpt-live-1",
    "voice": {
      "type": "custom",
      "id": "voice_..."
    }
  }
}
```

음성은 다음 규칙을 따라요.

* **자리**: 모든 네이티브 음성은 `runtime.voice`에 두세요. 기존 파이프라인용 `data.voice`나 TTS 설정 아래에 넣지 마세요.
* **GPT-Live**: OpenAI 빌트인 음성이나 승인된 커스텀 음성 참조를 써요. 커스텀 음성은 기본으로 꺼져 있고 워크스페이스별 승인과 프로비저닝이 필요해요. `voice_...` 값은 파이프라인 음성 카탈로그에서 조회했거나 소유했다는 이유만으로 허용되지 않아요. 커스텀 참조만으로 품질 검증까지 끝났다고 볼 수 없어요.
* **Grok Voice, Gemini Live**: 제공사가 정한 빌트인 이름만 받고, `custom` 음성과 OpenAI 커스텀 참조는 거부해요.
* **기존 파이프라인 음성**: 설정을 그대로 유지하고 자동으로 마이그레이션하지 않아요.

## LLM과의 관계

`data.llm`은 텍스트 채팅과 음성 통화의 업무 처리에 쓰는 텍스트 LLM 선택 필드예요. 음성 통화에서는 `data.runtime`의 제공사가 실시간 음성을 처리하고, `data.llm`은 업무 판단과 도구 실행에 쓰여요. 새 `chatLlm` 필드를 더하거나 `runtime.model`을 `data.llm`에 암묵적으로 매핑하지 않아요.

| 요청 | `data.runtime` | `data.llm` |
| - | - | - |
| 음성 통화 | 실시간 음성 입력과 응답을 처리해요. | 업무 처리에 필요해요. |
| 텍스트 채팅 | 실시간 음성 런타임을 시작하지 않아요. | 채팅 응답에 써요. |

정적 첫 메시지는 저장한 녹음으로 재생하지 않고 제공사의 음성 세션에서 말소리로 만들어요. GPT-Live와 Gemini Live에는 지정 문구를 유지하라고 요청하지만, 정확한 문구와 발음은 녹음처럼 고정되지 않아요.

만드는 요청에는 `data.llm.model`을 꼭 적어야 해요. 먼저 모델 카탈로그에서 고를 수 있는 값을 읽으세요.

```bash theme={null}
curl "https://client-api.tryvox.co/v3/models/llms" \
  -H "Authorization: Bearer $VOX_API_KEY"
```

기존 플로우를 수정할 때는 `flow.nodes[].data.llm` 노드별 LLM 오버라이드를 그대로 보존하세요. 이 설정은 기존 플로우 계약이고 GPT-Live 기능이 아니에요. 네이티브 실시간 요청에는 플로우 노드 설정을 넣지 마세요.

## 수정 충돌 방지와 데이터 병합

`GET /v3/agents/{agent_id}?version=current` 응답의 `head_revision`을 확인한 뒤 `PATCH` 본문 최상위에 `expected_head_revision`을 보내세요. 플로우 그래프도 바꾼다면 같은 응답의 `flow_revision`을 `expected_flow_revision`으로 함께 보내세요. 메뉴얼 변경과 버전 만들기·복원에도 현재 revision이 필요해요. 프로덕션 버전을 바꾸는 요청에는 `expected_production_version`도 현재 값이나 `null`로 적으세요.

revision이 맞지 않으면 API가 `REVISION_CONFLICT`를 돌려줘요. 이 응답을 받은 뒤 최신 설정을 자동으로 다시 읽어 요청을 재전송하지 마세요. 변경 충돌을 알리고, 사용자가 최신 내용을 확인한 뒤 병합할지 정하게 하세요.

`PATCH`에서 생략한 `data` 필드는 그대로 남아요. 일반 객체는 한 단계만 병합하고, 배열은 전체를 바꿔요. `runtime`, `manuals`, `presetDynamicVariables`는 보내면 값 전체를 원자적으로 바꾸니 완전한 객체나 맵을 보내세요. 예를 들어 새 런타임으로 바꿀 때는 `type`, `model`, `voice`를 모두 넣고, 메뉴얼 맵을 바꿀 때는 모든 항목을 넣으세요.

## 네이티브 실시간 에이전트 만들기

다음 예시는 `data.llm.model`을 카탈로그에서 확인한 뒤 바꿔 넣는 꼴이에요. 실제 모델 식별자를 추측해서 넣지 마세요.

```bash theme={null}
curl -X POST "https://client-api.tryvox.co/v3/agents" \
  -H "Authorization: Bearer $VOX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "업무 상담 에이전트",
    "type": "single_prompt",
    "data": {
      "prompt": {
        "prompt": "고객의 업무 문의를 짧고 정확하게 안내하세요."
      },
      "llm": {
        "model": "<GET /v3/models/llms에서 선택한 모델>"
      },
      "runtime": {
        "type": "gpt_live",
        "model": "gpt-live-1",
        "voice": {
          "type": "builtin",
          "name": "marin"
        }
      }
    }
  }'
```

네이티브 실시간으로 만드는 요청에는 기존 파이프라인의 `stt`, `voice`, `parallelSTT`를 함께 보내지 마세요. `sttPreference`, `voicePreference`처럼 현재 스키마에서 네이티브 실시간과 호환되지 않는 legacy speech preference도 보내지 마세요. 공통 음성 제어 필드는 `data.speech` 전체를 추측으로 지우거나 복사하지 말고 현재 agent schema에 따라 다루세요. 네이티브 실시간 입력에 STT·TTS 설정을 적으면 받아들이지 않고, 유효 설정을 합친 뒤 남은 기존 파이프라인 기본값도 저장하지 않아요.

세 런타임은 제공사 측 턴 감지를 사용하므로 유효한 `data.speech.isAllowInterruption`이 `false`이면 거부돼요. 만드는 요청에서 생략하면 기본값 `true`를 쓰지만, 수정 요청에서 생략하면 현재 값을 유지해요. 현재 값이 `false`인 에이전트를 전환하려면 `true`를 적으세요. API는 값을 조용히 바꾸지 않아요.

## 런타임 전환

아래 전환표는 `type: "single_prompt"` 에이전트에만 적용돼요. 기존 플로우 에이전트는 `pipeline` 런타임을 유지하고, 네이티브 실시간으로 자동 변환하지 않아요.

전환은 한 번에 한 방향만 하고, 전환한 뒤 `GET /v3/agents/{agent_id}`로 저장된 `data`를 다시 읽어 확인하세요.

| 단계 | 요청 | 기대하는 데이터 계약 |
| - | - | - |
| 기존 파이프라인에서 네이티브 실시간으로 | `runtime.type`을 `gpt_live`, `grok_voice`, `gemini_live` 가운데 하나로 바꾸기 | 기존 `data.llm`을 유지해요. 그 런타임의 `model`과 `runtime.voice`를 모두 지정해요. `runtime`을 생략하면 전환되지 않아요 |
| 네이티브 실시간에서 기존 파이프라인으로 | `runtime.type`을 `pipeline`으로 바꾸기 | `stt`와 `voice`를 적어요. 이전 `runtime.voice`가 `data.voice`로 자동 변환된다고 가정하지 마세요 |
| 네이티브 실시간 유지 | `runtime`은 그대로 두고 다른 필드만 수정하기 | 네이티브 전용 필드와 파이프라인 전용 필드를 섞지 마세요. `data.llm`은 필요할 때만 바꿔요 |

파이프라인으로 돌아가는 예시예요. `stt`와 `voice`의 정확한 필드는 스키마와 모델 카탈로그에서 확인하세요.

```json theme={null}
{
  "data": {
    "llm": {
      "model": "<기존 또는 새로 선택한 text LLM>"
    },
    "runtime": {
      "type": "pipeline"
    },
    "stt": {
      "languages": ["ko"],
      "speed": "high"
    },
    "voice": {
      "id": "<GET /v3/models/voices에서 선택한 voice id>",
      "provider": "<voice catalog provider>"
    }
  }
}
```

네이티브 실시간 에이전트 응답에서 `data.stt`나 `data.voice`가 `null`이거나 없을 수 있어요. 저장 결과는 `runtime.type`과 `runtime.voice`로 확인하세요.

## 스키마 확인하기

필드를 기억해서 조립하지 말고, 쓰기 직전에 지금 스키마와 카탈로그를 읽으세요.

<Steps>
  <Step title="모델 카탈로그 조회하기">
    `GET /v3/models/llms`에서 `data.llm.model`을 고르세요. 네이티브 실시간의 `runtime.model`은 런타임마다 따로 정해진 값이라 이 목록의 텍스트 LLM과 섞지 마세요.
  </Step>

  <Step title="에이전트 스키마 조회하기">
    `GET /v3/schemas/agent-schema/agent-data-create?detail=minimal`이나 `agent-data-update`를 호출해 지금 `runtime`과 관련 필드의 모양을 확인하세요.
  </Step>

  <Step title="요청을 보내고 조회로 확인하기">
    만들거나 수정한 뒤 `GET /v3/agents/{agent_id}`를 호출하세요. 응답에서 `runtime.type`, `runtime.voice`, `llm`, `stt`, `voice`가 어떻게 저장됐는지 확인하세요.
    이 조회는 저장 결과를 확인해요. 제공사 세션을 시험하려면 실제 음성 통화 환경에서 별도로 통화해 보세요.
  </Step>
</Steps>

스키마 응답이 이 페이지의 예시와 다르면 API가 돌려준 스키마를 기준으로 작성하세요. OpenAPI에 실리는 스키마도 API 서버가 제공하는 계약을 따라 갱신돼요.

## 작성 체크리스트

* **런타임 생략**: 새로 만들 때 `data.runtime`을 생략하거나 `type: "pipeline"`으로 보내면 기존 파이프라인 계약을 써요. 수정할 때 `runtime`을 생략하면 현재 런타임을 유지해요.
* **런타임 객체**: 네이티브 실시간은 `type`, `model`, `voice`를 `runtime` 안에 두세요.
* **GPT-Live 빌트인 음성**: 예시는 `runtime.voice: {"type":"builtin","name":"marin"}`이에요. 이 값은 예시이고 런타임이 음성을 자동으로 고르지 않아요.
* **Grok Voice, Gemini Live의 모델과 음성**: 각각 `grok-voice-think-fast-2.0`과 `gemini-2.5-flash-native-audio-preview-12-2025` 모델, 그 제공사 전용 빌트인 음성을 꼭 적으세요. 음성 허용값은 지금 스키마에서 확인하세요.
* **Grok Voice, Gemini Live의 음성 형식**: `builtin` 음성만 받아요. GPT-Live의 `custom` 형식은 이 두 런타임에서 거부돼요.
* **GPT-Live 커스텀 음성**: 파이프라인 카탈로그와 별개인 새 GPT-Live 전용 참조예요. 기존 파이프라인 음성은 그대로 두고 마이그레이션하지 않아요. 승인과 품질 검증 전에는 실행할 수 있는 설정이라고 약속하지 않아요.
* **`data.llm.model`**: 새 네이티브 실시간 에이전트를 만들 때 고를 수 있는 값을 꼭 넣으세요.
* **`chatLlm`**: 만들지 마세요. `data.llm`을 네이티브 런타임 모델로 암묵 변환하지도 않아요.
* **파이프라인 필드**: 네이티브 실시간 요청에 `stt`, `data.voice`, `parallelSTT`, `sttPreference`, `voicePreference`, 지금 스키마에서 호환되지 않는 legacy speech preference를 넣지 마세요. `data.speech` 전체를 한꺼번에 지우지도 마세요.
* **끼어들기 허용**: 세 런타임 모두 유효한 `data.speech.isAllowInterruption` 값이 `true`여야 해요. 만들 때 생략하면 기본값 `true`를 쓰지만, 수정할 때 생략하면 현재 값을 유지해요. 서버가 값을 강제로 바꾸지 않아요.
* **파이프라인 복귀**: 파이프라인으로 되돌릴 때는 `stt`와 `voice`를 적으세요.
* **플로우 노드 LLM**: 기존 플로우를 수정할 때 `flow.nodes[].data.llm` 오버라이드를 보존하세요. GPT-Live 기능이 아니에요.
* **조회 응답**: 읽은 응답의 `stt`, `voice`가 `null`이거나 없을 수 있으니 그 경우를 처리하세요.

## 관련 문서

* [소개](/api-reference/v3/introduction): v3 API의 인증, 컨벤션, 에이전트 data 수정 규칙
* [에이전트 버전 관리](/docs/build/versioning): 버전을 배포하고 프로덕션으로 지정하기
* [음성 인식 & 발화](/docs/build/voice/voice-select): 파이프라인 에이전트의 언어와 목소리 정하기
* [API로 플로우 작성 및 검증](/docs/build/flow/api-authoring): `flow` 필드로 플로우 에이전트를 작성하고 검증하기
