For the complete documentation index, see llms.txt. Markdown versions of documentation pages are available by appending .md to the page URL.
기본 탐색 메뉴
Theme

GPT-Live 세션 관리

세션을 구성하고 컨텍스트를 유지하며 대화의 시작부터 종료까지 관리하세요.

GPT-Live에 연결한 후에는 세션 이벤트를 사용해 컨텍스트를 추가하고 대화록을 표시하며 연결을 관리하세요. GPT-Live는 들으면서 동시에 말할 수 있습니다. 대화록 텍스트, 실제로 재생된 오디오, 백엔드 작업 진행 상황을 각각 추적하면 어시스턴트가 하는 말과 아직 진행 중인 작업을 인터페이스에 구분해 표시할 수 있습니다.

이 가이드는 연결에서 session.started 이벤트가 이미 발생했다고 가정합니다. 연결 설정과 오디오 스트리밍은 연결을, 백엔드 작업은 위임 및 도구를 참고하세요.

세션 구성

세션을 생성할 때 모델, 음성, 위임 모드를 선택하세요. 모델에 대화 지침을 제공하고 관련 대화 기록을 포함하세요. 대화가 길어지면 GPT-Live가 컨텍스트를 자동으로 관리합니다.

구성 필드

설정 시작 시 구성 세션 중 변경
모델 필수 필드인 model을 설정하세요. 변경하려면 새 세션을 시작하세요.
지침 instructions에 대화 방식에 관한 지침을 최대 16,384토큰까지 설정하세요. session.instructions.append로 지침을 추가하세요.
대화 기록 input에 관련 있는 이전 텍스트 메시지를 지정하세요. 기본값은 []입니다. 추가 이벤트로 컨텍스트를 보충하세요.
음성 audio.output.voice에 지원되는 음성 또는 사용 권한이 있는 사용자 지정 음성을 지정하세요. 기본값은 marin입니다. 변경하려면 새 세션을 시작하세요.
위임 delegation.type을 client 또는 responses로 설정하세요. 위임 설정을 생략하거나 null로 지정하면 클라이언트 모드가 선택됩니다. 기존 모드에서 Responses 설정을 업데이트하세요.
저장 store를 true로 설정하면 세션을 포크할 수 있습니다. 기본값은 false입니다. 시작 시 선택하세요.

음성 옵션

세션을 생성할 때 음성을 선택하세요. audio.output.voice에 "quartz"와 같은 API 이름을 지정하세요. GPT-Live에서는 다음 음성도 사용할 수 있습니다.

음성 API 이름 언어 지역적 특색 음색 출처
Quartz quartz 영어 호주 여성적 생성 음성
Ripple ripple 영어 호주 남성적 자연 음성
Vesper vesper 영어 영국 남성적 자연 음성
Willow willow 영어 아일랜드 여성적 자연 음성
Stone stone 영어 아일랜드 남성적 자연 음성
Gleam gleam 영어 북미 여성적 자연 음성
Meridian meridian 영어 북미 남성적 자연 음성
Bossa bossa 포르투갈어 브라질 여성적 자연 음성
Tempo tempo 포르투갈어 브라질 남성적 자연 음성
Beacon beacon 영어 필리핀 남성적 생성 음성
Delta delta 영어 미국 남부 여성적 생성 음성
Cinder cinder 영어 미국 남부 남성적 생성 음성
Nuri nuri 독일어 — 여성적 자연 음성
Juni juni 독일어 — 여성적 자연 음성
Flitz flitz 독일어 — 남성적 자연 음성
Brise brise 프랑스어 — 여성적 자연 음성
Sillage sillage 프랑스어 — 남성적 자연 음성
Nira nira 힌디어 — 여성적 자연 음성
Harema harema 일본어 — 여성적 자연 음성
Shida shida 일본어 — 남성적 자연 음성
Noeul noeul 한국어 — 여성적 자연 음성

지역적 특색은 해당 음성의 말투를 나타냅니다. 애플리케이션에 필요한 언어와 발음으로 음성을 테스트하세요. 텍스트 설명이나 승인된 녹음으로 음성을 만들려면 사용자 지정 음성을 참고하세요.

WebSocket에서는 시작 시 audio.format을 선택하세요. 세션의 입력과 출력 오디오에 같은 형식이 적용됩니다. 다른 형식을 사용하려면 새 세션을 시작하세요. WebRTC는 연결 설정 중에 오디오 형식을 협상하므로 WebRTC 요청에서는 audio.format을 생략하세요. 지원되는 형식과 스트리밍 방법은 WebSocket 오디오 형식을 참고하세요.

실행 중인 세션 업데이트

이미 Responses 위임을 사용하는 세션에서는 session.update로 session.delegation.responses를 변경하세요. 변경하려는 설정만 보내세요. 생략한 설정은 기존 값을 유지합니다. 설정 항목과 업데이트 워크플로우는 Responses 위임 구성을 참고하세요.

위임 모드와 model, instructions, input, audio, store 필드는 시작 시 지정하세요. session.update는 위에서 설명한 Responses 설정에만 사용하세요. 다른 구성 필드를 보내면 요청이 거부됩니다. 위임 모드를 전환하려면 새 세션을 생성하세요. 시작 시 delegation: null을 지정하면 클라이언트 위임이 선택되며 Responses 기본 설정으로 복원되지 않습니다.

업데이트가 성공하면 변경 후 세션 구성이 담긴 session.updated 이벤트가 발생합니다. 보낸 이벤트의 event_id와 수신한 이벤트의 client_event_id를 대조하세요. 같은 이벤트 루프에서 거부된 명령어도 처리하세요. 백엔드 작업과 음성 출력은 각각 해당 이벤트로 추적하세요.

대화 기록 및 컨텍스트 제공

이전 주제를 이어 가려면 세션 시작 시 대화 기록을 제공하고, 대화가 진행되면 관련 컨텍스트를 추가하세요. 신뢰할 수 있는 애플리케이션 지침은 사용자 메시지 및 사실을 담은 결과와 구분하세요.

이전 대화로 세션 초기화

세션을 생성할 때 session.input에 이전 텍스트 메시지를 포함하세요. 예를 들어 다음 input 필드를 세션 생성 구성에 추가하세요.

export const session = {
  model: "gpt-live-1",
  input: [
    {
      type: "message",
      role: "user",
      content: [
        {
          type: "input_text",
          text: "I need help with my recent order.",
        },
      ],
    },
    {
      type: "message",
      role: "assistant",
      content: [
        {
          type: "output_text",
          text: "What is the order number?",
        },
      ],
    },
  ],
};

목록에는 최대 128개의 메시지를 넣을 수 있으며 전체 메시지의 토큰 합계는 8,192개까지입니다. 각 메시지에는 텍스트 파트 하나가 있으며 역할은 developer, user, assistant 중 하나입니다. 개발자 및 사용자 메시지에는 input_text를 사용하고 어시스턴트 메시지에는 text 또는 output_text를 사용하세요. 신뢰할 수 있는 애플리케이션 지침은 instructions 또는 개발자 메시지에 넣으세요.

다음 상호작용에 필요한 텍스트 기록을 골라 시작 시 제공하세요. 세션 중에는 아래의 컨텍스트 이벤트로 새 정보를 추가하세요. 도구 결과처럼 백엔드에 해당하는 항목은 위임 워크플로우를 통해 보내세요.

컨텍스트가 모델에 전달되는 시점

모델이 처음부터 알아야 할 컨텍스트는 input에 넣으세요. 세션이 시작되면 모델이 이 필드의 전체 내용을 사용할 수 있습니다.

세션이 실행되는 동안 session.instructions.append, session.thinking.append, session.commentary.append로 추가한 컨텍스트는 점진적으로 전달됩니다. 세션 타임라인이 추가된 컨텍스트의 예상 종료 시점에 도달하면 확인 이벤트가 도착합니다. 이벤트의 start_ms와 end_ms는 해당 업데이트가 세션 타임라인에서 차지하는 구간의 추정값입니다.

이 시각은 컨텍스트 전달 시점을 나타내며 발화나 재생 시점과는 별개입니다. 모델이 업데이트 전체를 활용하기 전에 응답할 수도 있습니다. 어떤 동작에 새 지침이나 사실이 필요하다면 애플리케이션에서 실제 동작을 확인하세요.

세션 타임라인이 멈추면 확인 이벤트가 대기 상태로 남을 수 있습니다. 보낸 이벤트의 event_id와 확인 이벤트의 client_event_id를 대조하고, 기다리는 동안에도 오류를 계속 처리하세요. 세션을 닫으면 아직 대기 중인 추가 요청에 대해 오류가 반환됩니다.

대화 중 컨텍스트 추가

모델이 업데이트를 어떻게 활용해야 하는지에 따라 이벤트를 선택하세요.

  • session.instructions.append로 모델의 행동과 발화에 영향을 주는 신뢰할 수 있는 애플리케이션 지침을 추가합니다.
  • session.thinking.append로 사실에 관한 컨텍스트를 추가합니다. 모델에 그 내용을 즉시 말하도록 요청하지는 않습니다.
  • session.commentary.append로 모델이 소리 내어 전달할 정보를 제공합니다. 모델이 표현을 바꿔 말할 수 있습니다.

각 이벤트에는 최대 500토큰의 일반 문자열인 content와 필수 필드 delegation_id가 필요합니다. 세션 전체에 적용되는 컨텍스트에는 null을 사용하세요. 예를 들어 애플리케이션이 사용자의 동의를 확인하고 조회를 시작한 후 다음 이벤트를 보내세요.

export function sendUpdate(connection) {
  connection.send({
    type: "session.thinking.append",
    event_id: "context_1",
    delegation_id: null,
    content:
      "The user has already accepted the terms. The account lookup is still running.",
  });
}

이 업데이트를 추적하려면 session.thinking.appended 이벤트 중 client_event_id: "context_1"인 이벤트 또는 해당 오류를 처리하세요. 확인 이벤트가 도착하는 시점은 컨텍스트가 모델에 전달되는 시점을 참고하세요.

어시스턴트는 이러한 이벤트로 받은 정보를 대화에서 그대로 말할 수 있습니다. 대화에 적합한 정보만 보내고 자격 증명과 비밀 정보는 백엔드에 보관하세요. 애플리케이션에서 정한 행동 지침에는 session.instructions.append를 사용하세요. 도구가 반환한 사실은 컨텍스트로 제공하고, 권한 검사와 필수 확인 절차는 애플리케이션 코드에서 수행하세요.

페이지 이동, 항목 선택 등 UI 변경 사항은 UI 컨텍스트 공유를 참고하세요. 간결한 업데이트로 사용자가 무엇을 가리키는지 GPT-Live에 알려 줄 수 있습니다.

특정 백엔드 작업에 관한 업데이트에는 해당 클라이언트 위임의 ID를 사용하세요. 위임 ID는 Live 작업을 식별합니다. Responses 응답 ID와 도구 호출 ID는 각각 다른 객체를 식별합니다. 워크플로우는 상황에 맞는 업데이트 보내기를 참고하세요.

애플리케이션에서 문제를 감지하면 세션의 기본 WebSocket 또는 사이드밴드 WebSocket으로 짧은 정정 메시지를 보내세요. 검사, 동작 제어, 재생 처리는 대화 가드레일 적용을 참고하세요.

음성 및 대화록 관리

대화록 델타

사용자 발화는 session.input_transcript.delta 이벤트로, 어시스턴트 발화는 session.output_transcript.delta 이벤트로 수신하세요. 각 이벤트에는 텍스트 조각과 해당 조각이 세션 타임라인에서 차지하는 구간이 포함됩니다.

{
  "type": "session.input_transcript.delta",
  "event_id": "event_transcript_1",
  "delta": "What is",
  "start_ms": 1000,
  "end_ms": 1200
}

화자별로 delta 조각을 받은 그대로 이어 붙여 공백과 반복된 단어를 보존하세요. 각 조각의 start_ms와 end_ms도 보관하세요. 두 값은 세션 시작 후 경과한 시간을 밀리초로 나타냅니다. 위 예시의 구간은 1,000ms 이상 1,200ms 미만입니다. 두 값은 조각의 대략적인 시간대를 나타내며 개별 단어의 경계와 정확히 일치하지는 않습니다. 대화록을 정리할 때는 패킷 도착 시각 대신 이 값을 사용하세요.

대화록 이벤트는 텍스트가 있는 구간에 대해 발생하며 일정한 간격으로 도착하지 않을 수 있습니다. 한 조각에 문장의 일부만 담길 수 있고, 이벤트가 한동안 도착하지 않는 이유가 네트워크 지연일 수도 있습니다. 대화록 델타에는 항목 ID가 없고 한 차례의 발화가 끝났음을 알리는 이벤트도 없으므로, 화면에 표시할 조각을 어떻게 묶을지는 애플리케이션에서 결정합니다.

대화록 조각 처리는 선택 사항입니다. 대화가 이어지는 동안 조각을 활용해 UI를 업데이트하거나 검사를 실행하거나 작업을 미리 시작할 수 있습니다. 간단한 검사에는 gpt-5.6-luna와 같은 소형 모델의 추론 수준을 낮게 설정하는 방법을 고려하세요. 예시와 연결 방법은 대화록 조각에 대응하기를 참고하세요.

대화록 가드레일을 사용하면 발화가 이어지는 동안 대화를 모니터링하고 필요할 때 개입할 수 있습니다. 재생 전에 어시스턴트의 발화를 검사해야 한다면 재생 전 발화 검사에서 버퍼링, 승인, 중단 및 복구 방법을 확인하세요.

대화록의 시간 정보와 오디오 재생은 구분해서 관리하세요. WebSocket의 session.output_audio.delta 이벤트에는 시간 필드가 없으며 출력 오디오가 끝났음을 알리는 이벤트도 없습니다. WebRTC에서는 미디어 트랙을 통해 오디오를 전달합니다. 오디오 처리 방법은 연결을 참고하세요.

자막 표시

GPT-Live는 전이중 통신을 지원하므로 통화자와 어시스턴트가 동시에 말할 수 있습니다. 발화가 겹쳐도 양쪽 자막에 텍스트를 계속 추가할 수 있도록 화자별로 자막을 업데이트하세요.

앱에서 채팅 말풍선을 사용한다면 “예약을”과 “ 변경하고 싶어요”라는 두 조각을 하나의 통화자 말풍선에 표시할 수 있습니다. 통화자가 계속 말하는 도중 어시스턴트가 “네”라고 답하면 그 대답을 별도로 표시하고 통화자의 말풍선에는 텍스트를 계속 추가하세요. 나중에 도착한 텍스트를 알맞은 말풍선에 반영할 수 있도록 원래 조각과 타임스탬프를 보관하세요.

음성 자막에는 session.output_transcript.delta를 사용하고 백엔드 업데이트는 별도로 표시하세요. 도구 실행이나 작업 취소 여부는 텍스트를 화면에 표시하기 위해 묶는 방식과 별개로 애플리케이션의 작업 로직에서 결정하세요.

마이크 입력 제어

세션을 종료하지 않고 입력을 음소거하려면 session.input_audio.mute를 보내세요.

export function sendUpdate(connection) {
  connection.send({
    type: "session.input_audio.mute",
    event_id: "mute_1",
  });
}

session.input_audio.muted 이벤트에서 client_event_id: "mute_1"을 확인한 후에만 명령어가 수락된 것으로 처리하세요. 입력을 재개하려면 session.input_audio.unmute를 보내고 session.input_audio.unmuted를 기다리세요. 두 명령어 모두 오류를 처리하세요.

입력을 음소거해도 세션은 계속 실행됩니다. 모델은 음성을 계속 생성할 수 있고 위임된 작업도 계속 진행될 수 있습니다. 로컬 녹음이나 재생까지 중지해야 한다면 애플리케이션의 마이크 캡처 및 오디오 플레이어 제어 기능을 사용하세요.

통화자가 말하기 전에 인사하기

GPT-Live가 먼저 대화를 시작해야 한다면 세션 생성 시 developer 메시지에 인사 지침을 작성해 session.input에 넣는 것이 효과적입니다. WebSocket에서는 이 메시지를 session.start 이벤트에 포함하세요. 그러면 모델이 처음부터 인사 지침을 사용할 수 있습니다.

사용할 언어와 어시스턴트가 할 말을 지정하고, 즉시 인사한 다음 말을 멈추고 듣도록 지시하세요. 통화자가 말하기 전까지는 애플리케이션에서 선택한 인사 언어를 사용하세요. 예를 들어 개발자 메시지에는 다음 텍스트를 사용할 수 있습니다.

지금 통화자에게 영어로 인사하세요. 지원 담당 어시스턴트라고 자신을 소개하고 무엇을 도와드릴지 물어보세요. 그런 다음 말을 멈추고 통화자의 말을 들으세요.

  1. 메시지를 session.input에 추가하고 role: "developer"와 input_text 콘텐츠 파트 하나를 지정하세요. 메시지 형식은 이전 대화로 세션 초기화를 참고하세요.
  2. session.started를 기다린 다음, 아래 예시처럼 session.commentary.append로 같은 인사 지침을 한 번 보내세요. 고유한 event_id와 delegation_id: null을 사용하세요. 통화자가 말하기 전의 무음 구간에도 오디오 입력을 유지하세요. WebSocket에서는 session.input_audio.append를 계속 보내고, WebRTC에서는 입력 오디오 트랙을 활성 상태로 유지하세요.
  3. 출력 오디오와 대화록을 확인해 어시스턴트가 통화자에게 인사했는지 검증하세요. 시작 지침을 제공하면 인사를 더 잘 유도할 수 있지만 모델이 반드시 말하는 것은 아닙니다.
{
  "type": "session.commentary.append",
  "event_id": "greeting_1",
  "delegation_id": null,
  "content": "Greet the caller now in English. Introduce yourself as the support assistant and ask how you can help. Then pause and listen."
}

session.commentary.appended 이벤트는 요청을 수락했음을 알립니다. 실제로 인사말을 발화했거나 재생했는지는 이 이벤트로 확인할 수 없습니다. GPT-Live는 인사말을 바꿔 말하거나 말을 덧붙이거나 아무 말도 하지 않을 수 있습니다.

인사말을 일정하게 재생하거나 정확한 문구를 사용하거나 재생 완료 시점을 알아야 한다면, 애플리케이션에서 검증된 녹음 또는 렌더링된 클립을 재생하고 그동안 GPT-Live 재생을 제어하세요. 지원하는 각 언어에서 인사말을 테스트하고, 인사 도중 통화자가 말을 시작하는 경우도 확인하세요. 프롬프트 설계는 음성 모델 프롬프트 작성을 참고하세요.

고지 사항 전달

고지 사항을 특정 문구로 말하도록 요청하려면 session.instructions.append를 사용하세요. session.commentary.append를 사용하면 모델이 문구를 바꿔 말할 수 있습니다. 예를 들어 session.started 이후 다음 이벤트를 보내세요.

export function sendUpdate(connection) {
  connection.send({
    type: "session.instructions.append",
    event_id: "disclosure_1",
    delegation_id: null,
    content:
      "Immediately say the following disclosure exactly and in full before responding to the caller: This call may be recorded for quality and training purposes.",
  });
}

통화자가 말하기 전에 인사하기에서와 같이 오디오 입력을 유지하세요. 대화 중에 보낸 지침은 진행 중인 발화를 중단시킬 수 있습니다.

고지 사항을 전달 완료로 표시하기 전에 생성된 고지 내용과 재생 여부를 확인하세요. 지침에 대한 확인 이벤트는 지침 수락 여부를 기록합니다. 실제로 어떤 문구를 말했는지는 오디오를 들어 확인하세요. 정확한 문구를 사용하고 재생 완료 시점을 알아야 한다면 애플리케이션에서 검증된 녹음 또는 렌더링된 클립을 재생하고 그동안 GPT-Live 출력을 제어하세요. 필요한 경우 재생 제어를 참고하세요.

긴 대화 관리

GPT-Live는 긴 대화를 자동으로 관리하며 세션 시작 시 제공한 원래 지침을 유지합니다.

기본 컨텍스트 윈도우의 크기는 128,000토큰입니다. 여기에는 지침, 대화 텍스트, 대화록에 나타나지 않는 오디오 토큰이 포함됩니다.

GPT-Live는 백그라운드에서 오래된 대화 기록을 요약합니다. 컨텍스트 사용률이 90%를 넘으면 같은 세션에서 새 음성 엔진을 시작해 기존 엔진을 교체합니다. 새 엔진은 원래 지침과 최대 8,192토큰의 대화 기록을 받습니다. 이 기록에는 최근 메시지가 포함되며, 이전 메시지의 요약이 있으면 함께 전달됩니다. 요약이 준비되더라도 실행 중인 엔진의 컨텍스트가 즉시 바뀌지는 않습니다.

오래된 대화의 세부 내용은 요약되거나 생략될 수 있습니다. 중요한 사실, 확인된 조치, 현재 작업 상태는 애플리케이션에 보관하고 필요할 때 관련 컨텍스트를 제공하세요.

세션 저장 및 포크

포크하면 저장된 음성 대화를 바탕으로 새 세션이 시작됩니다. 같은 기준 대화에서 여러 차례 평가를 실행하거나 이전 세션이 종료된 후 사용자가 대화를 이어 갈 수 있도록 할 때 사용하세요. 포크할 때마다 새 연결과 세션 ID가 생성되며, 원본 대화와 저장된 구성이 새 세션의 출발점이 됩니다.

기준 대화에서 평가 실행

통화자가 주문을 변경할 때 에이전트가 어떻게 대응하는지 테스트한다고 가정해 보겠습니다. 통화자가 어떤 주문인지 밝히는 시점까지 대화를 한 번 녹음하세요. 통화자가 주문 변경을 요청하기 전에 세션을 종료하고 종료 처리를 완료하세요. 그러면 평가할 때마다 같은 기준 세션을 포크한 뒤 “Actually, can you send it to my office instead?”라는 동일한 통화자 오디오를 다음 입력으로 사용할 수 있습니다.

매 평가에서 동일한 테스트 주문과 애플리케이션 상태를 복원하고 통화자의 다음 입력을 제공한 뒤, 새 응답과 도구가 수행한 동작을 평가하세요. 같은 시나리오를 반복하거나 지원되는 Responses 백엔드 설정을 비교할 수 있습니다. 포크 시작 시간은 응답 시간과 별도로 측정하세요. 시나리오 선택과 결과 측정은 GPT-Live 평가 가이드를 참고하세요.

포크한 세션은 GPT-Live 모델, 음성, 원래 지침을 상속합니다. 다른 음성 모델이나 시작 프롬프트를 비교하려면 해당 구성으로 새 세션을 생성하세요. 포크 API는 녹음이 완료된 원본을 사용하므로 평가를 시작하려는 지점에서 기준 세션을 종료하세요.

세션 종료 후 대화 이어 가기

통화자가 전화를 끊고 나중에 다시 걸거나 통화가 끊긴 뒤 재연결할 수 있습니다. 이전 세션의 녹음이 완료되어 저장되었다면 애플리케이션에서 새 연결로 해당 세션을 포크해 저장된 대화를 이어 갈 수 있습니다.

애플리케이션의 작업 상태를 원본 세션 ID와 함께 저장하세요. 대화를 이어 가기 전에 미완료 백엔드 작업의 상태를 확인하고 현재까지의 결과를 새 세션에 제공하세요. 예를 들어 주문 변경 요청을 이미 제출했다면 다시 변경을 시도하기 전에 결과를 확인하세요. 세션 제어와 사이드밴드 연결에는 새 세션 ID를 사용하고 이후의 백엔드 결과도 새 세션으로 보내세요.

포크를 위한 세션 준비

  1. 원본 세션을 생성할 때 저장을 활성화하세요. 세션 구성에 store: true를 설정하세요. 저장 설정의 기본값은 false입니다. 프로젝트에서 저장 기능이 활성화되어 있어야 하며 데이터 정책에서 데이터 보관을 허용해야 합니다.
  2. 원본 세션 ID를 저장하세요. session.started 또는 WebRTC 생성 응답에서 ID를 읽고 애플리케이션의 대화 기록과 연결하세요.
  3. 원본 세션의 작업을 마치고 세션을 닫으세요. 필요한 백엔드 작업을 완료한 다음 사용량 확인 및 정상 종료 절차를 따르세요. session.closed가 도착할 때까지 연결을 열어 두고 종료 처리 중에 발생하는 오류를 처리하세요. 포크하려면 녹음이 완료되어 저장되어 있어야 합니다. 녹음을 저장하는 만큼 종료 처리 시간이 늘어날 수 있습니다.
  4. 새 연결에서 포크를 시작하세요. 아래 전송 방식별 절차에 원본 ID를 사용하고 새 세션 ID를 저장하세요. 시작 절차가 완료된 후 대화를 이어 가세요. 자식 세션의 store를 명시적으로 설정하세요. 이어진 대화를 나중에 다시 포크하려면 true로, 해당 평가를 저장할 필요가 없다면 false로 설정하세요. 생략하면 원본 설정을 상속합니다.

저장된 녹음은 30일간 사용할 수 있습니다. 데이터 비보관(ZDR)이 적용되면 store가 false로 처리되어 포크할 수 없습니다. 포크 기반 평가에는 ZDR이 적용되지 않는 조직을 사용하고 프로젝트에서 저장을 활성화하세요.

완료되어 저장된 녹음이 없다면 저장된 텍스트 기록 중 관련 내용을 사용해 새 세션을 시작하세요. 저장 요건은 GPT-Live 데이터 제어를 참고하세요.

예를 들어 원본 세션의 WebSocket session.start 구성 또는 WebRTC 생성 요청에 다음 필드를 설정하세요.

{
  "store": true
}

애플리케이션에서 사용하는 전송 방식에 따라 포크를 시작하세요.

전송 방식 포크 시작 방법
WebSocket wss://api.openai.com/v1/live/sessions/{source_session_id}/fork에 연결하세요.
WebRTC POST /v1/live/sessions/{source_session_id}/fork로 새 SDP 오퍼를 보내세요. 반환된 transport.sdp 응답을 새 피어 연결에 적용하세요.

포크한 세션은 원본 세션의 모델, 원래 지침, 입력을 상속합니다. 시작 시에는 재정의가 지원되는 설정만 보내세요.

  • WebSocket: store, Responses 위임 설정, 새 연결의 audio.format을 지정할 수 있습니다. session.start 이벤트에 session 객체를 넣어 보내세요. 상속을 지원하는 설정에서 기존 값을 유지하려면 {}를 사용하세요.
  • WebRTC: store, Responses 위임 설정, 프런트엔드 클라이언트 권한을 지정할 수 있습니다.

WebSocket 포크에서는 새 연결의 audio.format을 설정하거나 기본 형식인 24kHz PCM16을 사용하세요. 원본의 오디오 형식과 프런트엔드 데이터 채널 권한은 상속되지 않습니다. WebRTC는 연결 설정 중에 오디오 형식을 협상하므로 audio.format을 생략하세요. WebRTC에서는 프런트엔드 권한 설정을 재정의하지 않으면 기존 설정이 유지됩니다.

WebSocket에서는 session.started를 기다린 후 추가 명령어를 보내세요. WebRTC에서는 HTTP 요청으로 세션이 시작됩니다. session.start를 다시 보내지 말고 협상된 연결에서 계속 진행하세요.

WebSocket 포크 시작

OPENAI_API_KEY를 설정하세요. 다음 예시는 애플리케이션에 저장한 원본 세션 ID를 사용합니다. 포크한 세션이 시작되었는지 확인한 다음 세션을 닫습니다. 대화를 이어 가려면 session.started 이후 WebSocket 연결 플로우에 따라 오디오를 주고받으세요. 시작 필드와 이벤트는 포크용 WebSocket 레퍼런스를 참고하세요.

import OpenAI from "openai";
import { ForksWS } from "openai/resources/live/forks/ws";

async function forkSession(sourceSessionId) {
  const ws = new ForksWS(new OpenAI(), { session_id: sourceSessionId });
  let finalized = false;
  let closeRequested = false;
  try {
    for await (const event of ws) {
      if (event.type === "open") {
        ws.send({ type: "session.start", session: {} });
      } else if (event.type === "error") {
        throw event.error;
      } else if (event.type === "message") {
        if (event.message.type === "session.started") {
          console.log("Fork ready:", event.message.session.id);
          // This startup example closes the fork after confirming it is ready.
          ws.send({ type: "session.close" });
          closeRequested = true;
        } else if (event.message.type === "session.closed") {
          console.log("Final usage:", event.message.usage);
          if (!closeRequested) {
            throw new Error("Fork ended before startup completed");
          }
          finalized = true;
          break;
        }
      }
    }
    if (!finalized) throw new Error("Connection closed before session.closed");
  } finally {
    ws.close();
  }
}

WebRTC 포크 시작

프런트엔드에서 새 SDP 오퍼를 생성해 백엔드로 보내세요. 다음 백엔드 예시에서는 이 오퍼와 애플리케이션에 저장한 원본 세션 ID를 사용합니다.

import OpenAI from "openai";

async function forkSession(sourceSessionId, offerSdp) {
  const client = new OpenAI();
  const fork = await client.live.sessions.fork(sourceSessionId, {
    transport: { type: "webrtc", sdp: offerSdp },
  });
  console.log(JSON.stringify(fork));
}

응답을 프런트엔드로 반환하고 transport.sdp를 새 피어 연결의 응답으로 적용한 뒤 새 session.id를 보관하세요. API 키는 백엔드에 보관하세요.

사이드밴드 연결과 세션 제어에는 새 세션 ID를 사용하세요. 미완료 작업을 다시 시도하기 전에 백엔드에서 결과를 확인하고 애플리케이션의 현재 작업 상태를 복원하세요. 완료되어 저장된 녹음이 없다면 저장된 기록으로 새 세션을 초기화하세요.

녹음 다운로드

저장된 녹음의 처리가 완료되면 GET /v1/live/sessions/{session_id}/content로 오디오를 다운로드하세요. 응답은 바이너리 스테레오 WAV 형식이며 왼쪽 채널에는 입력 오디오, 오른쪽 채널에는 출력 오디오가 담깁니다. 다음 예시는 애플리케이션에 저장한 세션 ID를 사용해 응답을 recording.wav 파일로 스트리밍합니다.

import OpenAI from "openai";
import { createWriteStream } from "node:fs";
import { pipeline } from "node:stream/promises";

async function downloadRecording(sessionId) {
  const client = new OpenAI();
  const response = await client.live.sessions.downloadRecording(sessionId);
  if (!response.body) throw new Error("Recording response has no body");
  await pipeline(response.body, createWriteStream("recording.wav"));
}

유휴 세션 종료 및 대화 재개

상호작용 사이의 간격이 긴 애플리케이션에서는 활동이 없는 동안 음성 세션을 닫고 사용자가 돌아오면 새 세션을 시작하세요. 사용자가 같은 말을 반복하지 않고 대화를 이어 갈 수 있도록 대화 컨텍스트와 애플리케이션 작업 상태를 보관하세요. 예를 들어 차량용 어시스턴트는 운전자가 음성 기능을 다시 켜면 대화를 재개할 수 있고, 코딩 어시스턴트는 음성 대화 사이에도 백엔드 워커를 계속 실행할 수 있습니다.

  1. 종료 시점을 정하세요. 오디오 활동, 어시스턴트 음성 재생, 애플리케이션 내 상호작용을 기준으로 애플리케이션에서 유휴 시간 제한을 관리하세요. 사용자가 읽거나 생각하느라 잠시 말을 멈추는 경우도 고려하세요. 재생이 끝났고 현재 음성 세션이 필요한 대기 작업이 없을 때만 세션을 닫으세요. 대화록 이벤트가 한동안 도착하지 않았다는 이유만으로 무음이라고 판단할 수는 없습니다.
  2. 상태를 저장하고 정상 종료하세요. 원본 세션 ID, 대화 컨텍스트, 현재 작업 상태를 저장하세요. 필요한 Responses 작업을 마친 후 사용량 확인 및 정상 종료 절차에 따라 session.closed 리스너를 등록하고 session.close를 보내세요. session.closed를 받은 뒤 연결을 해제하세요. 클라이언트 위임을 사용하면 음성 세션이 닫혀 있는 동안에도 애플리케이션이 관리하는 백엔드 작업을 독립적으로 계속 실행할 수 있습니다.
  3. 재시작 시점을 감지하세요. 대화 재개 버튼, 눌러서 말하기 기능 또는 애플리케이션이 관리하는 깨우기 트리거를 제공하세요. 닫힌 Live 세션은 사용자의 말을 들을 수 없습니다. 로컬 음성 감지로 세션을 자동 재시작한다면 마이크 캡처를 활성 상태로 유지하고 연결을 설정하는 동안 사용자의 첫 발화를 버퍼에 저장하세요. 새 세션이 준비되면 해당 오디오를 전달해 사용자의 첫마디가 누락되지 않도록 하세요.
  4. 새 세션에서 컨텍스트를 복원하세요. 원본을 store: true로 생성했고 저장 기능이 활성화되어 있으며 정책상 저장이 허용되고 녹음 처리가 성공적으로 완료되었다면 저장된 세션을 포크하세요. 그렇지 않으면 저장된 텍스트 기록으로 새 세션을 시작하세요. 새 세션 ID를 저장하고 미완료 백엔드 작업의 상태를 확인한 다음 이후 결과를 새 세션으로 보내세요. 재시작할 때 이미 완료한 동작을 반복하지 않도록 작업 상태를 애플리케이션에 보관하세요.

마이크를 음소거해도 세션은 활성 상태로 유지됩니다. 유휴 시간 제한을 정할 때는 절약되는 음성 사용 시간과 세션 생성 비용, 음성 기능을 다시 사용할 수 있을 때까지의 지연 시간을 비교하세요. 음성 세션 비용과 WebRTC 초기화 요금을 참고하세요.

오류 처리 및 세션 종료

종료 처리가 완료될 때까지 세션 이벤트를 계속 읽으세요. 애플리케이션이 상황에 맞게 복구할 수 있도록 명령어 거부, 연결 실패, 세션 종료 완료를 구분하세요.

거부된 명령어 처리

확인 이벤트와 함께 error 이벤트도 읽으세요. error.client_event_id가 있으면 보낸 명령어 중 어떤 것이 실패했는지 식별할 수 있습니다.

{
  "type": "error",
  "event_id": "event_error",
  "error": {
    "type": "invalid_request_error",
    "code": "immutable_field_update",
    "message": "The delegation type cannot change after session startup.",
    "param": "session.delegation.type",
    "client_event_id": "event_update"
  }
}

코드가 null이거나 클라이언트 이벤트 ID가 없는 오류를 처리할 수 있도록 공통 오류 핸들러를 마련하세요. 변경할 수 없는 필드에 관한 오류가 발생하면 현재 구성을 유지하거나 원하는 설정으로 새 세션을 생성하세요.

콘텐츠 검토 처리

콘텐츠 검토는 세션에 두 가지 방식으로 영향을 줄 수 있습니다.

  • 일부 콘텐츠 검토 이벤트는 세션을 종료합니다.
  • 그 밖의 이벤트는 어시스턴트의 현재 발화에서 남은 오디오를 차단하고 error 이벤트를 발생시킵니다. 이 경우 세션은 계속 실행됩니다.

오디오 재생 중에도 error 이벤트를 계속 처리하세요. 오디오 중단과 세션 종료를 별도로 추적하고, 음성 메시지는 재생 여부를 확인한 후에만 전달 완료로 표시하세요. 기본 제공 콘텐츠 검토와 함께 자체 대화 가드레일을 적용하세요.

사용량 확인 및 정상 종료

session.usage.updated는 누적 음성 사용 시간을 초 단위로 보고합니다.

{
  "type": "session.usage.updated",
  "event_id": "event_usage_1",
  "usage": { "seconds": 12 },
  "context_window": { "usage_ratio": 0.42 }
}

가장 최근의 usage.seconds 값을 현재까지의 누적 음성 사용 시간으로 사용하세요. 예를 들어 업데이트 값이 12초였다가 15초가 되었다면 사용 시간은 15초입니다. 백엔드 토큰 사용량은 중첩된 Responses 완료 이벤트에서 별도로 추적하세요. 사용량 집계는 비용 최적화를 참고하세요.

세션을 정상 종료하려면 다음 절차를 따르세요.

  1. 대기 중인 함수 결과 처리와 후속 응답 생성을 포함해 애플리케이션에 필요한 Responses 위임 작업을 마치세요.
  2. session.closed 리스너를 등록하세요. 이 작업은 session.close를 보내기 전에 마쳐야 합니다.
  3. session.close를 보내고 세션에 새 작업을 제출하지 마세요. 대기 중인 세션 이벤트를 모두 수신할 때까지 WebSocket 또는 WebRTC 연결, 데이터 채널, 연결된 사이드밴드 수신기를 유지하세요.
  4. 최종 usage.seconds, reason, 세션 스냅샷을 session.closed에서 읽으세요. response.event를 통해 이미 받은 위임 작업 사용량도 보관하세요.
  5. 해당 이벤트를 받은 후 전송 연결과 오디오 장치의 리소스를 정리하세요. 종료 처리가 실패하거나 애플리케이션에서 설정한 시간 제한을 초과하면 종료 처리가 완료되지 않았음을 보고하고 리소스를 해제하세요.

session.close를 보내면 대기열에 있는 Responses 요청이 취소되고 이후의 명령어는 거부됩니다. 실행 중인 응답은 완료될 수 있지만 함수 결과를 기다리는 응답은 종료가 시작된 후에 계속 진행할 수 없습니다. 클라이언트 위임으로 애플리케이션이 실행하는 작업은 완료할지 취소할지 별도로 결정하세요.

session.closed로 종료 처리 완료를 확인하고 최종 구성 스냅샷을 읽으세요. 이 이벤트가 도착할 때까지 전송 연결을 열어 두세요. 소켓이 먼저 닫히면 종료 처리 여부를 미확인으로 기록하세요. 유효한 session.closed를 받은 후 소켓이 닫혔다면 확인된 결과를 유지하세요.

최종 이벤트의 reason은 세션이 종료된 이유를 나타냅니다.

종료 사유 의미
close_requested 애플리케이션이 session.close를 보냈거나 통화 종료 엔드포인트를 호출했습니다.
expired 세션이 최대 지속 시간에 도달했습니다.
content 안전 필터가 세션을 종료했습니다.
remote_hangup 원격 기본 연결이 정상 종료되었습니다.
connection_lost 기본 연결 또는 업스트림 연결이 예기치 않게 끊겼습니다.

session.closed 이벤트를 받으면 종료 사유가 연결 끊김이나 안전 필터에 의한 종료이더라도 종료 처리가 완료된 것입니다. 이 이벤트가 없으면 최종 사용량은 미확인 상태로 남습니다. 저장이 설정된 세션은 녹음을 저장하느라 종료 처리에 더 오래 걸릴 수 있으므로 이를 고려해 애플리케이션의 시간 제한을 설정하세요.

연결 실패 복구

HTTP 세션 생성 오류가 발생했다면 세션이 session.started 단계에 도달하지 못한 것입니다. 시작 오류는 실행 중인 세션에서 발생한 오류와 구분해 처리하세요. 실행 중인 연결이 session.closed 전에 끊기면 마지막으로 확인한 사용량을 보관하고 최종 사용량은 미확인으로 표시하세요.

완료되어 저장된 녹음이 있다면 해당 세션을 포크해 새 세션에서 대화를 이어 가세요. 그렇지 않으면 저장된 기록 중 관련 내용을 사용해 대체 세션을 생성하세요. 대화를 이어 가기 전에 백엔드에서 미완료 작업을 확인하고 현재 작업 상태를 복원하세요. 이전 세션에서 늦게 도착한 결과가 이후 작업을 덮어쓰지 않도록 결과 라우팅도 업데이트하세요.