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

실시간 전사

Realtime 세션에서 실시간 오디오를 전사하세요.

애플리케이션에서 어시스턴트의 음성 응답 없이 마이크 입력, 통화 음성 또는 기타 실시간 오디오 스트림을 텍스트로 변환하려면 실시간 전사를 사용하세요. 권장 모델은 음성이 들어오는 대로 새로 전사된 텍스트를 반환하고, 애플리케이션이 각 발화 턴을 커밋하면 해당 턴의 최종 전사 결과를 반환합니다.

먼저 gpt-live-transcribe 모델을 사용해 보세요. 이미 녹음된 오디오에는 파일 전사를 사용하세요. 두 워크플로우를 비교하려면 전사 개요를 참고하세요.

전사 세션 만들기

표준 API 키로 서버 측에서 WebSocket 전사를 수행하려면 wss://api.openai.com/v1/realtime?intent=transcription에 연결하세요. WebSocket 가이드에 나온 인증 헤더를 사용하되 URL에서 model을 생략하세요. 가이드에 나온 것처럼 URL에 모델을 지정하면 대화 세션이 생성되며, 이 세션은 아래의 전사 세션 업데이트를 허용하지 않습니다.

연결이 열리면 session.update 이벤트를 보내세요. 이때 type: "transcription"을 지정하고 세션 설정에서 gpt-live-transcribe를 선택하세요. 브라우저에서 오디오를 전송하려면 WebRTC를 참고하세요.

{
  "type": "session.update",
  "session": {
    "type": "transcription",
    "audio": {
      "input": {
        "format": {
          "type": "audio/pcm",
          "rate": 24000
        },
        "transcription": {
          "model": "gpt-live-transcribe"
        },
        "turn_detection": null
      }
    }
  }
}

이 예제에서는 24 kHz PCM 오디오를 사용합니다. gpt-live-transcribe 전사 세션에서는 audio.input.turn_detection을 생략하거나 null로 설정하세요. 이 모델은 server_vad와 semantic_vad를 지원하지 않습니다. 전체 세션 설정은 Realtime 세션 레퍼런스를 참고하세요.

오디오 스트리밍하기

input_audio_buffer.append로 오디오 청크를 전송하세요.

ws.send(
  JSON.stringify({
    type: "input_audio_buffer.append",
    audio: base64Pcm16,
  })
);

각 발화 턴이 끝날 때 input_audio_buffer.commit을 보내면 해당 턴의 최종 전사 결과를 받을 수 있습니다.

ws.send(
  JSON.stringify({
    type: "input_audio_buffer.commit",
  })
);

클라이언트 측 VAD로 발화가 끝나는 시점을 감지한 다음 input_audio_buffer.commit을 보내세요.

전사 이벤트 처리하기

전사 텍스트가 추가될 때 발생하는 델타 이벤트와 전사가 끝날 때 발생하는 완료 이벤트를 수신하세요.

ws.on("message", (data) => {
  const event = JSON.parse(data);

  if (event.type === "conversation.item.input_audio_transcription.delta") {
    process.stdout.write(event.delta);
  }

  if (event.type === "conversation.item.input_audio_transcription.completed") {
    console.log("\nFinal transcript:", event.transcript);
  }
});

델타 이벤트에는 새로 전사된 텍스트가 포함됩니다.

{
  "type": "conversation.item.input_audio_transcription.delta",
  "item_id": "item_003",
  "content_index": 0,
  "delta": "Hello,"
}

완료 이벤트에는 커밋한 항목의 최종 전사 결과가 포함됩니다.

{
  "type": "conversation.item.input_audio_transcription.completed",
  "item_id": "item_003",
  "content_index": 0,
  "transcript": "Hello, how are you?"
}

서로 다른 발화 턴의 완료 이벤트는 발화 순서대로 도착한다는 보장이 없습니다. item_id를 사용해 각 전사 이벤트를 해당 턴에서 커밋한 입력 항목과 연결하세요.

전사 세션을 설정한 뒤에는 다음 Go 함수로 24 kHz 모노 PCM16 오디오를 전송하고 턴을 커밋한 다음, 최종 전사 결과를 커밋한 항목과 연결하세요.

func transcribeTurn(ctx context.Context, conn *realtime.RealtimeConnection, audio []byte) error {
	for start := 0; start < len(audio); start += 9600 {
		end := min(start+9600, len(audio))
		if err := conn.Send(ctx, realtime.RealtimeClientEventParamOfInputAudioBufferAppend(base64.StdEncoding.EncodeToString(audio[start:end]))); err != nil {
			return err
		}
	}
	if err := conn.Send(ctx, realtime.RealtimeClientEventUnionParam{
		OfInputAudioBufferCommit: &realtime.InputAudioBufferCommitEventParam{},
	}); err != nil {
		return err
	}
	// Match the final transcript to the committed item, not event arrival order.
	var itemID string
	for {
		event, err := conn.Recv(ctx)
		if err != nil {
			return err
		}
		switch event.Type {
		case "input_audio_buffer.committed":
			itemID = event.OfInputAudioBufferCommittedEvent.ItemID
		case "conversation.item.input_audio_transcription.delta":
			delta := event.OfConversationItemInputAudioTranscriptionDeltaEvent
			if itemID != "" && delta.ItemID == itemID {
				fmt.Fprintf(os.Stderr, "Partial transcript (%s): %s\n", delta.ItemID, delta.Delta)
			}
		case "conversation.item.input_audio_transcription.completed":
			completed := event.OfConversationItemInputAudioTranscriptionCompletedEvent
			if itemID == "" || completed.ItemID != itemID {
				continue
			}
			fmt.Println("Final transcript:", completed.Transcript)
			return nil
		case "conversation.item.input_audio_transcription.failed":
			if itemID != "" && event.OfConversationItemInputAudioTranscriptionFailedEvent.ItemID == itemID {
				return fmt.Errorf("transcription failed")
			}
		case "error":
			return fmt.Errorf("Realtime API error: %s", event.OfRealtimeErrorEvent.Error.Message)
		}
	}
}

전사 컨텍스트 추가하기

오디오에 전문 용어가 포함되어 있거나 여러 언어가 사용될 것으로 예상되면 컨텍스트를 추가하세요. 진행 중인 세션의 전사 설정을 변경하려면 session.update 이벤트를 다시 보내세요.

{
  "type": "session.update",
  "session": {
    "type": "transcription",
    "audio": {
      "input": {
        "format": {
          "type": "audio/pcm",
          "rate": 24000
        },
        "transcription": {
          "model": "gpt-live-transcribe",
          "prompt": "A customer support call about a premium plan and account AC-42.",
          "keywords": ["premium plan", "AC-42", "billing"],
          "languages": ["en", "fr"],
          "delay": "low"
        },
        "turn_detection": null
      }
    }
  }
}
  • prompt에는 녹음 내용이나 녹음 당시의 상황을 설명하세요.
  • keywords에는 제품명, 약어 등 오디오에 나올 수 있는 용어를 표기 그대로 입력하세요.
  • languages에는 입력에 사용될 것으로 예상하는 언어를 지정하세요.

지원되는 언어 코드 형식은 다음과 같습니다.

  • ISO 639-1 코드(예: en, es, fr)
  • 일부 ISO 639-3 코드(예: eng, spa, yue, cmn)
  • 지역별 zh 로캘 코드(예: zh-cn, zh-tw, zh-hk)

Realtime API는 지원되지 않거나 형식이 잘못된 언어 코드를 거부합니다.

모델은 키워드를 전사에 참고하므로 결과에 모든 키워드가 포함될 필요는 없습니다. 각 키워드는 한 줄로 작성하고 <, >, 캐리지 리턴 또는 라인 피드 문자를 포함하지 마세요. 키워드에 이러한 문자가 있거나 prompt가 모델의 길이 제한을 초과하면 Realtime API는 세션 업데이트를 거부합니다.

gpt-live-transcribe에서는 languages 필드를 사용합니다. 단수형 필드인 language와 함께 보내지 마세요.

커밋한 턴 전사하기

발화 턴을 커밋한 후에 전사를 시작해야 하거나 감지된 언어를 결과로 받아야 하는 경우에만 Realtime 세션에서 gpt-transcribe를 사용하세요. 이 워크플로우에는 WebSocket 연결이 필요합니다.

gpt-transcribe는 Realtime API 세션에서 입력 오디오를 전사하거나 전사 전용 세션에서 실행될 때 이전에 전사한 턴을 자동으로 컨텍스트로 활용합니다.

{
  "type": "session.update",
  "session": {
    "type": "transcription",
    "audio": {
      "input": {
        "format": {
          "type": "audio/pcm",
          "rate": 24000
        },
        "transcription": {
          "model": "gpt-transcribe"
        },
        "turn_detection": null
      }
    }
  }
}

버퍼에 오디오를 추가한 다음 input_audio_buffer.commit을 보내세요. 그러면 모델이 최종 완료 이벤트를 보내기 전에 전사 델타를 보낼 수 있습니다. 완료 이벤트에는 감지된 언어도 포함됩니다.

{
  "type": "conversation.item.input_audio_transcription.completed",
  "item_id": "item_003",
  "content_index": 0,
  "transcript": "Bonjour, pouvez-vous m'entendre ?",
  "languages": [{ "code": "fr" }]
}

gpt-transcribe가 언어를 신뢰할 만한 수준으로 예측할 수 없으면 languages는 빈 배열입니다. gpt-live-transcribe는 언어 감지 결과를 반환하지 않습니다.

지연 시간과 정확도 조정하기

스트리밍 전사에서는 지연 시간과 전사 품질 사이에 절충이 필요합니다. 지연 시간을 짧게 설정하면 부분 전사 결과를 더 빨리 받을 수 있습니다. 길게 설정하면 모델이 텍스트를 출력하기 전에 더 많은 오디오를 컨텍스트로 활용하므로 단어 오류율이 낮아질 수 있습니다.

먼저 audio.input.transcription.delay를 설정하고 실제로 사용할 오디오로 테스트하세요. 처음에는 용도에 따라 다음 설정을 사용해 보세요.

  • minimal은 지연 시간에 가장 민감한 상호작용에 적합합니다.
  • low는 지연 시간이 짧아야 하는 실시간 자막에 적합합니다.
  • medium은 지연 시간과 정확도의 균형이 필요할 때 적합합니다.
  • high는 결과를 즉시 표시하는 것보다 정확도가 더 중요할 때 적합합니다.
  • xhigh는 더 많은 컨텍스트를 확보하기 위해 워크플로우에서 가장 긴 지연 시간을 허용할 수 있을 때 적합합니다.

실제 지연 시간(밀리초)은 모델 설정에 따라 달라질 수 있습니다. 단계별 지연 시간이 고정되어 있다고 가정하지 말고 실제 사용 환경을 대표하는 오디오로 측정하세요.

합성 오디오만으로 설정을 결정하지 마세요. 실제 환경에서 사용할 마이크와 전화 통화 오디오로 테스트하세요. 다양한 억양, 배경 소음, 발화 중 언어 전환, 분야별 전문 용어, 장시간 세션도 테스트에 포함하세요.

신뢰도, 타임스탬프, 화자 레이블 처리하기

gpt-live-transcribe는 단어 단위 타임스탬프, 화자 레이블, 전사 신뢰도 점수를 반환하지 않습니다. 애플리케이션에 타임스탬프나 화자 레이블이 필요하면 해당 기능을 지원하는 파일 전사 모델을 사용하거나 애플리케이션에서 대체 처리 방식을 구현하세요.

프로덕션 체크리스트

  • 설정을 조정하기 전에 목표 지연 시간과 최소 정확도를 정하세요.
  • 잡음이 없는 샘플뿐 아니라 실제 프로덕션 환경의 오디오로 테스트하세요.
  • 대상 언어를 각각 테스트하세요.
  • 평가 데이터셋에 숫자, 날짜, 통화 금액, 이메일 주소, 제품명, 분야별 전문 용어를 포함하세요.
  • 단어 오류율과 별도로 전사 결과가 비어 있거나 중간에 잘리거나 늦게 도착하는 경우를 추적하세요.
  • 후속 델타에서 앞선 텍스트가 정정될 때 UI에 표시된 부분 전사 결과를 어떻게 수정할지 정하세요.
  • item_id를 사용해 최종 전사 결과를 해당 입력 항목과 대조하고 순서대로 정렬하세요.
  • 타임스탬프, 화자 레이블 또는 신뢰도 필드가 지원되지 않을 때 사용할 대체 처리 방식을 마련하세요.

관련 가이드

Realtime 및 오디오 개요

음성 에이전트 세션, 번역 세션, 전사 세션을 비교하세요.

실시간 번역

번역 전용 세션에서 음성을 실시간으로 번역하세요.

WebSocket 연결

서버 측 미디어 파이프라인으로 원시 오디오를 스트리밍하세요.

음성 활동 감지

실시간 오디오 스트림의 턴 감지를 설정하세요.