録音が完了している場合や、リクエストで扱う音声の範囲が決まっている場合は、ファイルの文字起こしを利用します。音声をアップロードすると、文字起こしの全文を受け取れます。モデルがファイルを処理している間に、テキストをストリーミングで受け取ることもできます。
まずは gpt-transcribe を使用してください。録音した音声を元の言語のまま文字に起こす場合の推奨モデルです。以下で紹介する話者ラベル、単語単位のタイムスタンプ、字幕形式の例では、非推奨のモデルを使用しています。
whisper-1、gpt-4o-transcribe、gpt-4o-mini-transcribe、gpt-4o-transcribe-diarize、/v1/audio/translations は非推奨で、2027 年 2 月 26 日 に提供を終了します。提供終了のお知らせ を確認し、現在利用できる文字起こしワークフロー を選択してください。以下の用途別の例では、提供終了まで既存の実装で利用できる機能を説明します。
ファイルサイズの上限は 25 MB です。対応する入力形式は mp3、mp4、mpeg、mpga、m4a、wav、webm です。
マイク、通話、メディアストリームから音声を受信しながら処理する場合は、リアルタイム文字起こし を使用してください。
音声ファイルを /v1/audio/transcriptions に送信する際に、モデルに gpt-transcribe を指定します。
1
2
3
4
5
6
7
8
9
10
11 import fs from "fs";
import OpenAI from "openai";
const openai = new OpenAI();
const transcription = await openai.audio.transcriptions.create({
file: fs.createReadStream("fixtures/audio.wav"),
model: "gpt-transcribe",
});
console.log(transcription.text); 1
2
3
4
5
6
7
8
9
10 from openai import OpenAI
client = OpenAI()
audio_file = open ( "audio.wav" , "rb" )
transcription = client.audio.transcriptions.create(
model = "gpt-transcribe" , file = audio_file
)
print (transcription.text) 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 package main
import (
"context"
"fmt"
"os"
"github.com/openai/openai-go/v3"
)
func main() {
file, err := os.Open("fixtures/audio.wav")
if err != nil {
panic(err)
}
defer file.Close()
client := openai.NewClient()
transcription, err := client.Audio.Transcriptions.New(context.Background(), openai.AudioTranscriptionNewParams{
File: file,
Model: "gpt-transcribe",
})
if err != nil {
panic(err)
}
fmt.Println(transcription.Text)
} 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.audio.transcriptions.TranscriptionCreateParams;
import java.nio.file.Path;
var result =
client
.audio()
.transcriptions()
.create(
TranscriptionCreateParams.builder()
.file(Path.of(System.getenv("OPENAI_EXAMPLE_AUDIO_PATH")))
.model("gpt-transcribe")
.build());
System.out.println(result.asTranscription().text()); 1
2
3
4
5
6
7
8
9
10
11
12
13 using OpenAI.Audio;
string key = Environment.GetEnvironmentVariable("OPENAI_API_KEY")!;
string model = "gpt-transcribe";
AudioClient client = new(model, key);
await using FileStream audio = File.OpenRead("audio.wav");
AudioTranscription transcription = await client.TranscribeAudioAsync(
audio,
"audio.wav"
);
Console.WriteLine(transcription.Text); 1
2
3
4
5
6
7
8
9
10
11
12 require "openai"
require "pathname"
client = OpenAI::Client.new
audio = Pathname("audio.wav")
transcript = client.audio.transcriptions.create(
file: audio,
model: "gpt-transcribe"
)
raise "Expected a JSON transcript response" if transcript.is_a?(StringIO)
puts(transcript.text) 1
2
3
4
5 openai audio:transcriptions create \
--model gpt-transcribe \
--file /path/to/file/audio.mp3 \
--raw-output \
--transform text 1
2
3
4
5
6 curl --request POST \
--url https://api.openai.com/v1/audio/transcriptions \
--header "Authorization: Bearer $OPENAI_API_KEY" \
--header 'Content-Type: multipart/form-data' \
--form file=@/path/to/file/audio.mp3 \
--form model=gpt-transcribe
モデルは文字起こし結果と検出した言語を JSON 形式で返します。
1 2 3 4 {
"text" : "Bonjour, pouvez-vous m'entendre ?" ,
"languages" : [{ "code" : "fr" }]
}
モデルが言語を確実に判定できない場合は、"languages": [] を返します。リクエストとレスポンスの全フィールドについては、Audio API リファレンス を参照してください。
prompt、keywords、languages を gpt-transcribe に指定すると、専門用語や複数の言語を含む音声の文字起こし精度を高められます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 import fs from "fs";
import OpenAI from "openai";
const openai = new OpenAI();
const request = {
model: "gpt-transcribe",
file: fs.createReadStream("fixtures/audio.wav"),
prompt: "A customer support call about a premium plan and account AC-42.",
};
const transcription = await openai.audio.transcriptions.create(request, {
body: {
...request,
keywords: ["premium plan", "AC-42", "billing"],
languages: ["en", "fr"],
},
});
console.log(transcription.text); 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 from openai import OpenAI
client = OpenAI()
with open ( "meeting.wav" , "rb" ) as audio_file:
transcription = client.audio.transcriptions.create(
model = "gpt-transcribe" ,
file = audio_file,
prompt = "A customer support call about a premium plan and account AC-42." ,
extra_body = {
"keywords" : [ "premium plan" , "AC-42" , "billing" ],
"languages" : [ "en" , "fr" ],
},
)
print (transcription.text) 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 package main
import (
"context"
"fmt"
"os"
"github.com/openai/openai-go/v3"
)
func main() {
file, err := os.Open("fixtures/audio.wav")
if err != nil {
panic(err)
}
defer file.Close()
parameters := openai.AudioTranscriptionNewParams{
File: file,
Model: "gpt-transcribe",
Prompt: openai.String("A customer support call about a premium plan and account AC-42."),
}
parameters.SetExtraFields(map[string]any{
"keywords": []string{"premium plan", "AC-42", "billing"},
"languages": []string{"en", "fr"},
})
client := openai.NewClient()
transcription, err := client.Audio.Transcriptions.New(context.Background(), parameters)
if err != nil {
panic(err)
}
fmt.Println(transcription.Text)
} 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.core.JsonValue;
import com.openai.models.audio.transcriptions.TranscriptionCreateParams;
import java.nio.file.Path;
import java.util.List;
var result =
client
.audio()
.transcriptions()
.create(
TranscriptionCreateParams.builder()
.file(Path.of(System.getenv("OPENAI_EXAMPLE_AUDIO_PATH")))
.model("gpt-transcribe")
.prompt("A customer support call about a premium plan and account AC-42.")
.putAdditionalBodyProperty(
"keywords", JsonValue.from(List.of("premium plan", "AC-42", "billing")))
.putAdditionalBodyProperty("languages", JsonValue.from(List.of("en", "fr")))
.build());
System.out.println(result.asTranscription().text()); 1
2
3
4
5
6
7
8
9
10
11
12
13 require "openai"
require "pathname"
client = OpenAI::Client.new
audio = Pathname("audio.wav")
transcript = client.audio.transcriptions.create(
file: audio,
model: "gpt-transcribe",
keywords: ["OpenAI", "Responses API", "Codex"]
)
raise "Expected a JSON transcript response" if transcript.is_a?(StringIO)
puts(transcript.text) 1
2
3
4
5
6
7
8
9
10
11 curl https://api.openai.com/v1/audio/transcriptions \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H "Content-Type: multipart/form-data" \
-F model="gpt-transcribe" \
-F file="@/path/to/file/meeting.wav" \
-F 'prompt=A customer support call about a premium plan and account AC-42.' \
-F 'keywords[]=premium plan' \
-F 'keywords[]=AC-42' \
-F 'keywords[]=billing' \
-F 'languages[]=en' \
-F 'languages[]=fr'
prompt には、録音の背景情報を自由な形式で記述します。
keywords には、音声に含まれると予想される用語をそのまま指定します。
languages には、入力音声で使われると予想される言語を指定します。
キーワードは認識のヒントであり、必ず出力されるわけではありません。関連する用語だけを指定し、精度が向上するか、実際には発話されていない用語が出力されないかを確認してください。
gpt-transcribe では、languages が単数形の language フィールドに代わります。両方のフィールドを送信しないでください。各キーワードは 1 行に収め、<、>、キャリッジリターン、ラインフィードを含めないでください。キーワードにこれらの文字のいずれかが含まれている場合や、prompt がモデルの長さ制限を超えた場合、API はリクエスト全体を拒否します。
既存の実装では、2027 年 2 月 26 日まで、非推奨の gpt-4o-transcribe-diarize モデルを使って、録音の各区間で誰が話しているかを識別できます。このモデルは話者ラベルの付与に特化しており、通常のファイルの文字起こしには推奨されません。
レスポンス形式に diarized_json を指定すると、speaker、start、end のメタデータを含むセグメントが返されます。音声が 30 秒を超える場合は、chunking_strategy に "auto" または音声区間検出の設定を指定してください。
必要に応じて、known_speaker_names[] と known_speaker_references[] を使って短い参照音声を最大 4 件指定し、各セグメントを既知の話者に対応付けることができます。各参照音声の長さは 2~10 秒としてください。参照音声には、文字起こし対象の音声ファイルとは異なる形式でも、アップロードに対応している入力形式であればどれでも使用できます。マルチパートフォームデータで送信する場合は、参照音声を データ URL にエンコードしてください。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 import fs from "fs";
import OpenAI from "openai";
const openai = new OpenAI();
const agentRef = fs.readFileSync("fixtures/agent.wav").toString("base64");
const transcript = await openai.audio.transcriptions.create({
file: fs.createReadStream("fixtures/meeting.wav"),
model: "gpt-4o-transcribe-diarize",
response_format: "diarized_json",
chunking_strategy: "auto",
known_speaker_names: ["agent"],
known_speaker_references: ["data:audio/wav;base64," + agentRef],
});
for (const segment of transcript.segments) {
if (!("speaker" in segment)) continue;
console.log(
`${segment.speaker}: ${segment.text}`,
segment.start,
segment.end
);
} 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 import base64
from openai import OpenAI
client = OpenAI()
def to_data_url (path: str ) -> str :
with open (path, "rb" ) as fh:
return "data:audio/wav;base64," + base64.b64encode(fh.read()).decode( "utf-8" )
with open ( "meeting.wav" , "rb" ) as audio_file:
transcript = client.audio.transcriptions.create(
model = "gpt-4o-transcribe-diarize" ,
file = audio_file,
response_format = "diarized_json" ,
chunking_strategy = "auto" ,
extra_body = {
"known_speaker_names" : [ "agent" ],
"known_speaker_references" : [to_data_url( "agent.wav" )],
},
)
for segment in transcript.segments:
print (segment.speaker, segment.text, segment.start, segment.end) 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55 package main
import (
"context"
"encoding/base64"
"encoding/json"
"fmt"
"os"
"github.com/openai/openai-go/v3"
"github.com/openai/openai-go/v3/shared/constant"
)
type diarizedTranscript struct {
Segments []struct {
Speaker string `json:"speaker"`
Text string `json:"text"`
Start float64 `json:"start"`
End float64 `json:"end"`
} `json:"segments"`
}
func main() {
agentAudio, err := os.ReadFile("fixtures/agent.wav")
if err != nil {
panic(err)
}
meeting, err := os.Open("fixtures/meeting.wav")
if err != nil {
panic(err)
}
defer meeting.Close()
client := openai.NewClient()
transcription, err := client.Audio.Transcriptions.New(context.Background(), openai.AudioTranscriptionNewParams{
File: meeting,
Model: "gpt-4o-transcribe-diarize",
ResponseFormat: openai.AudioResponseFormatDiarizedJSON,
ChunkingStrategy: openai.AudioTranscriptionNewParamsChunkingStrategyUnion{
OfAuto: constant.ValueOf[constant.Auto](),
},
KnownSpeakerNames: []string{"agent"},
KnownSpeakerReferences: []string{"data:audio/wav;base64," + base64.StdEncoding.EncodeToString(agentAudio)},
})
if err != nil {
panic(err)
}
var result diarizedTranscript
if err := json.Unmarshal([]byte(transcription.RawJSON()), &result); err != nil {
panic(err)
}
for _, segment := range result.Segments {
fmt.Println(segment.Speaker+":", segment.Text, segment.Start, segment.End)
}
} 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46 import com.fasterxml.jackson.databind.json.JsonMapper;
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.audio.AudioResponseFormat;
import com.openai.models.audio.transcriptions.TranscriptionCreateParams;
import com.openai.models.audio.transcriptions.TranscriptionDiarized;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Base64;
Path audio = Path.of(System.getenv("OPENAI_EXAMPLE_AUDIO_PATH"));
Path speakerAudio = Path.of(System.getenv("OPENAI_EXAMPLE_SPEAKER_AUDIO_PATH"));
String speakerReference =
"data:audio/wav;base64,"
+ Base64.getEncoder().encodeToString(Files.readAllBytes(speakerAudio));
var result =
client
.audio()
.transcriptions()
.create(
TranscriptionCreateParams.builder()
.file(audio)
.model("gpt-4o-transcribe-diarize")
.responseFormat(AudioResponseFormat.DIARIZED_JSON)
.chunkingStrategyAuto()
.addKnownSpeakerName("agent")
.addKnownSpeakerReference(speakerReference)
.build());
TranscriptionDiarized diarized =
result.isDiarized()
? result.asDiarized()
: new JsonMapper()
.readValue(result.asTranscription().text(), TranscriptionDiarized.class);
for (var segment : diarized.segments()) {
System.out.println(
segment.speaker()
+ ": "
+ segment.text()
+ " ("
+ segment.start()
+ "-"
+ segment.end()
+ ")");
} 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 require "base64"
require "openai"
require "pathname"
client = OpenAI::Client.new
audio = Pathname("meeting.wav")
speaker_reference = Base64.strict_encode64(File.binread("agent.wav"))
transcript = client.audio.transcriptions.create(
file: audio,
model: "gpt-4o-transcribe-diarize",
response_format: :diarized_json,
chunking_strategy: :auto,
known_speaker_names: ["agent"],
known_speaker_references: ["data:audio/wav;base64,#{speaker_reference}"]
)
segments = Array(
transcript.to_h.fetch(:segments) do
raise "The transcription did not include speaker segments"
end
)
segments.each do |segment|
segment = Hash.try_convert(segment) or raise "Invalid speaker segment"
puts(
"#{segment.fetch(:speaker)}: #{segment.fetch(:text)} " \
"(#{segment.fetch(:start)}-#{segment.fetch(:end_)})"
)
end 1
2
3
4
5
6
7
8
9
10 curl --request POST \
--url https://api.openai.com/v1/audio/transcriptions \
--header "Authorization: Bearer $OPENAI_API_KEY" \
--header 'Content-Type: multipart/form-data' \
--form file=@/path/to/file/meeting.wav \
--form model=gpt-4o-transcribe-diarize \
--form response_format=diarized_json \
--form chunking_strategy=auto \
--form 'known_speaker_names[]=agent' \
--form 'known_speaker_references[]=data:audio/wav;base64,AAA...'
stream=true の場合、話者ラベル付きのレスポンスでは、セグメントが確定するたびに transcript.text.segment イベントが送信されます。transcript.text.delta イベントには segment_id フィールドが含まれますが、差分には暫定的な話者ラベルは含まれません。モデルはセグメントを確定する時点で初めて話者を割り当てます。
話者ラベルは /v1/audio/transcriptions で利用できます。リアルタイム文字起こしセッションでは利用できません。
非推奨の /v1/audio/translations エンドポイントは、whisper-1 を使って録音済みの音声を英語に翻訳します。2027 年 2 月 26 日まで利用できます。文字起こしでは録音の元の言語を維持しますが、このエンドポイントが返すテキストは英語のみです。
リアルタイム翻訳 に移行するには、gpt-realtime-translate を /v1/realtime/translations で使用します。移行には、翻訳セッションの作成、ストリーミングによる音声入力、翻訳イベントの処理が必要です。/v1/audio/translations リクエストのモデル ID を変更するだけでは移行できません。
languages を gpt-transcribe に指定すると、入力音声で使われると予想される言語を伝えられます。対応する言語コード形式には、次のものがあります。
ISO 639-1 コード(en、es、fr など)
一部の ISO 639-3 コード(eng、spa、yue、cmn など)
地域別の zh ロケールコード(zh-cn、zh-tw、zh-hk など)
未対応の言語コードや形式が正しくない言語コードを指定すると、API はリクエストを拒否します。レスポンスには、モデルが確実に検出できた言語も含まれます。
whisper-1 については、Whisper の対応言語一覧 を参照してください。Whisper は 98 言語に対応していますが、精度は言語によって異なります。言語のヒントを 1 つだけ受け付ける既存のモデルでは、language を使用し、languages は使用しません。
既存の実装では、2027 年 2 月 26 日まで、非推奨の whisper-1 モデルで単語単位またはセグメント単位のタイムスタンプを取得できます。timestamp_granularities[] パラメータ を指定すると、字幕作成や動画編集に使える構造化されたタイムスタンプデータが返されます。
1
2
3
4
5
6
7
8
9
10
11
12
13 import fs from "fs";
import OpenAI from "openai";
const openai = new OpenAI();
const transcription = await openai.audio.transcriptions.create({
file: fs.createReadStream("fixtures/audio.wav"),
model: "whisper-1",
response_format: "verbose_json",
timestamp_granularities: ["word"],
});
console.log(transcription.words); 1
2
3
4
5
6
7
8
9
10
11
12
13 from openai import OpenAI
client = OpenAI()
audio_file = open ( "speech.wav" , "rb" )
transcription = client.audio.transcriptions.create(
file = audio_file,
model = "whisper-1" ,
response_format = "verbose_json" ,
timestamp_granularities = [ "word" ],
)
print (transcription.words) 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 package main
import (
"context"
"fmt"
"os"
"github.com/openai/openai-go/v3"
)
func main() {
file, err := os.Open("fixtures/audio.wav")
if err != nil {
panic(err)
}
defer file.Close()
client := openai.NewClient()
transcription, err := client.Audio.Transcriptions.New(context.Background(), openai.AudioTranscriptionNewParams{
File: file,
Model: openai.AudioModelWhisper1,
ResponseFormat: openai.AudioResponseFormatVerboseJSON,
TimestampGranularities: []string{"word"},
})
if err != nil {
panic(err)
}
fmt.Println(transcription.Words)
} 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.audio.AudioResponseFormat;
import com.openai.models.audio.transcriptions.TranscriptionCreateParams;
import java.nio.file.Path;
var result =
client
.audio()
.transcriptions()
.create(
TranscriptionCreateParams.builder()
.file(Path.of(System.getenv("OPENAI_EXAMPLE_AUDIO_PATH")))
.model("whisper-1")
.responseFormat(AudioResponseFormat.VERBOSE_JSON)
.addTimestampGranularity(TranscriptionCreateParams.TimestampGranularity.WORD)
.build());
result
.asVerbose()
.words()
.orElseThrow()
.forEach(
word -> System.out.println(word.word() + ": " + word.start() + " - " + word.end())); 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 using OpenAI.Audio;
string key = Environment.GetEnvironmentVariable("OPENAI_API_KEY")!;
string model = "whisper-1";
AudioClient client = new(model, key);
await using FileStream audio = File.OpenRead("speech.wav");
AudioTranscriptionOptions options = new()
{
ResponseFormat = AudioTranscriptionFormat.Verbose,
TimestampGranularities = AudioTimestampGranularities.Word,
};
AudioTranscription transcription = await client.TranscribeAudioAsync(
audio,
"speech.wav",
options
);
foreach (TranscribedWord word in transcription.Words)
{
Console.WriteLine(
$"{word.Word}: {word.StartTime.TotalSeconds:0.00}s - {word.EndTime.TotalSeconds:0.00}s"
);
} 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 require "openai"
require "pathname"
require "pp"
client = OpenAI::Client.new
audio = Pathname("audio.wav")
transcript = client.audio.transcriptions.create(
file: audio,
model: "whisper-1",
response_format: :verbose_json,
timestamp_granularities: [:word]
)
raise "Expected a JSON transcript response" if transcript.is_a?(StringIO)
pp(transcript.deep_to_h.fetch(:words)) 1
2
3
4
5
6
7 curl https://api.openai.com/v1/audio/transcriptions \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H "Content-Type: multipart/form-data" \
-F file="@/path/to/file/audio.mp3" \
-F "timestamp_granularities[]=word" \
-F model="whisper-1" \
-F response_format="verbose_json"
timestamp_granularities[] パラメータに対応しているのは whisper-1 のみです。
Transcriptions API が受け付けるファイルサイズの上限は 25 MB です。それを超える録音は、圧縮音声形式を使用するか、ファイルを 25 MB 以下のチャンクに分割してください。文の途中で分割すると文脈が失われ、精度が低下することがあるため、文の切れ目で分割してください。
音声の分割には、オープンソースの Python パッケージ PyDub を使用できます。
1
2
3
4
5
6
7
8
9
10 from pydub import AudioSegment
song = AudioSegment.from_wav( "good_morning.wav" )
# PyDub handles time in milliseconds
ten_minutes = 10 * 60 * 1000
first_10_minutes = song[:ten_minutes]
first_10_minutes.export( "good_morning_10.wav" , format = "wav" )
OpenAI は、PyDub などのサードパーティ製ソフトウェアの使いやすさや安全性を保証しません。
プロンプト を使うと、名前や略語、録音特有の用語を認識しやすくなり、意図した表記形式も反映しやすくなります。gpt-transcribe では、プロンプトに加えて keywords と languages を指定してください。詳しくは文字起こし用コンテキストの追加 を参照してください。
既存の gpt-4o-transcribe と gpt-4o-mini-transcribe の実装でもプロンプトを使用できます。gpt-4o-transcribe-diarize はプロンプトに対応していません。
プロンプトは次のような場面で役立ちます。
製品名、専門用語、略語を正確に文字に起こしたい場合
長い録音を分割し、直前のチャンクの文脈を引き継ぎたい場合
句読点、大文字と小文字の区別、つなぎ言葉を残したい場合
ある言語で使う表記体系を指定したい場合
whisper-1 のプロンプトは 224 トークンが上限で、推奨の文字起こしモデルほど細かく出力を制御できません。ワークフローで Whisper が必要な場合は、信頼性の向上 を参照してください。
ファイルの文字起こしでは、モデルが録音済みの音声を処理している間に、文字起こし結果を少しずつ受け取れます。リアルタイムセッションは不要です。
stream=true を設定し、モデルに gpt-transcribe を指定します。モデルが録音の各部分を文字に起こすたびに、Transcriptions API が文字起こしイベント を返します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14 import fs from "fs";
import OpenAI from "openai";
const openai = new OpenAI();
const stream = await openai.audio.transcriptions.create({
file: fs.createReadStream("fixtures/speech.wav"),
model: "gpt-transcribe",
stream: true,
});
for await (const event of stream) {
console.log(event);
} 1
2
3
4
5
6
7
8
9
10
11
12
13 from openai import OpenAI
client = OpenAI()
audio_file = open ( "speech.wav" , "rb" )
stream = client.audio.transcriptions.create(
model = "gpt-transcribe" ,
file = audio_file,
stream = True ,
)
for event in stream:
print (event) 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 package main
import (
"context"
"fmt"
"os"
"github.com/openai/openai-go/v3"
)
func main() {
file, err := os.Open("fixtures/speech.wav")
if err != nil {
panic(err)
}
defer file.Close()
client := openai.NewClient()
stream := client.Audio.Transcriptions.NewStreaming(context.Background(), openai.AudioTranscriptionNewParams{
File: file,
Model: "gpt-transcribe",
})
for stream.Next() {
fmt.Println(stream.Current().Type)
}
if err := stream.Err(); err != nil {
panic(err)
}
} 1
2
3
4
5
6
7
8
9
10
11
12 import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.audio.transcriptions.TranscriptionCreateParams;
import java.nio.file.Path;
var params =
TranscriptionCreateParams.builder()
.model("gpt-transcribe")
.file(Path.of("speech.wav"))
.build();
try (var stream = client.audio().transcriptions().createStreaming(params)) {
stream.stream().forEach(event -> System.out.println(event));
} 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 using OpenAI.Audio;
#pragma warning disable OPENAI001
string key = Environment.GetEnvironmentVariable("OPENAI_API_KEY")!;
string model = "gpt-transcribe";
AudioClient client = new(model, key);
await foreach (StreamingAudioTranscriptionUpdate update in client.TranscribeAudioStreamingAsync("speech.wav"))
{
if (update is StreamingAudioTranscriptionTextDeltaUpdate delta)
{
Console.Write(delta.Delta);
}
}
Console.WriteLine(); 1
2
3
4
5
6
7
8
9
10
11 require "openai"
require "pathname"
client = OpenAI::Client.new
audio = Pathname("speech.wav")
stream = client.audio.transcriptions.create_streaming(
file: audio,
model: "gpt-transcribe"
)
stream.each { |event| puts(event.type) } 1
2
3
4
5
6
7 curl --request POST \
--url https://api.openai.com/v1/audio/transcriptions \
--header "Authorization: Bearer $OPENAI_API_KEY" \
--header 'Content-Type: multipart/form-data' \
--form file=@example.wav \
--form model=gpt-transcribe \
--form stream=true
モデルは音声を文字に起こしながら transcript.text.delta イベントを送信し、最後の transcript.text.done イベントで文字起こしの全文を返します。話者ラベルを付けるために response_format="diarized_json" を指定した場合、話者分離モデルはセグメントを確定するたびに transcript.text.segment イベントも送信します。
gpt-transcribe では、最後のイベントに検出した言語も含まれます。
1 2 3 4 5 {
"type" : "transcript.text.done" ,
"text" : "Bonjour, pouvez-vous m'entendre ?" ,
"languages" : [{ "code" : "fr" }]
}
既存の gpt-4o-transcribe、gpt-4o-mini-transcribe、gpt-4o-transcribe-diarize の実装でも、ファイルの文字起こし結果をストリーミングで受け取れます。whisper-1 はこの機能に対応していません。
マイク、通話、メディアストリームからのライブ音声には、上記のファイル向けの方法に代えて、リアルタイム文字起こし のガイドを参照してください。現在の文字起こしセッションの流れと、gpt-live-transcribe を使った推奨のリアルタイム文字起こし手順を説明しています。
タイムスタンプ、字幕、翻訳に whisper-1 を使用している場合、以下の方法で、使用頻度の低い単語や略語の認識精度を高められます。汎用の文字起こしを新たに実装する場合は、代わりに gpt-transcribe を使い、文字起こし用コンテキスト を指定してください。
プロンプトパラメータの使用 1 つ目の方法では、任意のプロンプトパラメータに、用語の正しい綴りをまとめた辞書を渡します。
Whisper は汎用テキストモデルのように指示に従うわけではありません。プロンプトの上限は 224 トークンです。
1
2
3
4
5
6
7
8
9
10
11
12
13
14 import fs from "fs";
import OpenAI from "openai";
const openai = new OpenAI();
const transcription = await openai.audio.transcriptions.create({
file: fs.createReadStream("fixtures/speech.wav"),
model: "whisper-1",
response_format: "text",
prompt:
"ZyntriQix, Digique Plus, CynapseFive, VortiQore V8, EchoNix Array, OrbitalLink Seven, DigiFractal Matrix, PULSE, RAPT, B.R.I.C.K., Q.U.A.R.T.Z., F.L.I.N.T.",
});
console.log(transcription); 1
2
3
4
5
6
7
8
9
10
11
12
13 from openai import OpenAI
client = OpenAI()
audio_file = open ( "speech.wav" , "rb" )
transcription = client.audio.transcriptions.create(
model = "whisper-1" ,
file = audio_file,
response_format = "text" ,
prompt = "ZyntriQix, Digique Plus, CynapseFive, VortiQore V8, EchoNix Array, OrbitalLink Seven, DigiFractal Matrix, PULSE, RAPT, B.R.I.C.K., Q.U.A.R.T.Z., F.L.I.N.T." ,
)
print (transcription) 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 package main
import (
"context"
"fmt"
"os"
"github.com/openai/openai-go/v3"
)
func main() {
file, err := os.Open("fixtures/speech.wav")
if err != nil {
panic(err)
}
defer file.Close()
client := openai.NewClient()
var transcription []byte
err = client.Post(context.Background(), "audio/transcriptions", openai.AudioTranscriptionNewParams{
File: file,
Model: openai.AudioModelWhisper1,
ResponseFormat: openai.AudioResponseFormatText,
Prompt: openai.String("ZyntriQix, Digique Plus, CynapseFive, VortiQore V8, EchoNix Array, OrbitalLink Seven, DigiFractal Matrix, PULSE, RAPT, B.R.I.C.K., Q.U.A.R.T.Z., F.L.I.N.T."),
}, &transcription)
if err != nil {
panic(err)
}
fmt.Println(string(transcription))
} 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.core.http.HttpResponse;
import com.openai.models.audio.AudioResponseFormat;
import com.openai.models.audio.transcriptions.TranscriptionCreateParams;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
try (HttpResponse result =
client
.audio()
.transcriptions()
.withRawResponse()
.create(
TranscriptionCreateParams.builder()
.file(Path.of(System.getenv("OPENAI_EXAMPLE_AUDIO_PATH")))
.model("whisper-1")
.responseFormat(AudioResponseFormat.TEXT)
.prompt(
"ZyntriQix, Digique Plus, CynapseFive, VortiQore V8, EchoNix Array, "
+ "OrbitalLink Seven, DigiFractal Matrix, PULSE, RAPT, B.R.I.C.K., "
+ "Q.U.A.R.T.Z., F.L.I.N.T.")
.build())) {
System.out.println(new String(result.body().readAllBytes(), StandardCharsets.UTF_8));
} 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 using OpenAI.Audio;
string key = Environment.GetEnvironmentVariable("OPENAI_API_KEY")!;
string model = "whisper-1";
AudioClient client = new(model, key);
await using FileStream audio = File.OpenRead("speech.wav");
AudioTranscriptionOptions options = new()
{
ResponseFormat = AudioTranscriptionFormat.Text,
Prompt = "ZyntriQix, Digique Plus, CynapseFive, VortiQore V8, EchoNix Array, OrbitalLink Seven, DigiFractal Matrix, PULSE, RAPT, B.R.I.C.K., Q.U.A.R.T.Z., F.L.I.N.T.",
};
AudioTranscription transcription = await client.TranscribeAudioAsync(
audio,
"speech.wav",
options
);
Console.WriteLine(transcription.Text); 1
2
3
4
5
6
7
8
9
10
11
12
13 require "openai"
require "pathname"
client = OpenAI::Client.new
audio = Pathname("speech.wav")
transcript = client.audio.transcriptions.create(
file: audio,
model: "whisper-1",
prompt: "The speaker says OpenAI and Responses API"
)
raise "Expected a JSON transcript response" if transcript.is_a?(StringIO)
puts(transcript.text) 1
2
3
4
5
6
7 curl --request POST \
--url https://api.openai.com/v1/audio/transcriptions \
--header "Authorization: Bearer $OPENAI_API_KEY" \
--header 'Content-Type: multipart/form-data' \
--form file=@/path/to/file/speech.mp3 \
--form model=whisper-1 \
--form prompt="ZyntriQix, Digique Plus, CynapseFive, VortiQore V8, EchoNix Array, OrbitalLink Seven, DigiFractal Matrix, PULSE, RAPT, B.R.I.C.K., Q.U.A.R.T.Z., F.L.I.N.T." この方法で認識の信頼性は高まりますが、プロンプトには 224 トークンの上限があります。運用規模が大きくなってもこの方法を使い続けるには、SKU のリストを比較的短く保つ必要があります。
テキストモデルによる後処理 2 つ目の方法では、テキストモデルを使って文字起こし結果を後処理します。
system_prompt 変数で指示を渡してください。文字起こし用のプロンプトと同様に、会社名や製品名を含めることができます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 const systemPrompt = `
You are a helpful assistant for the company ZyntriQix. Your task is
to correct any spelling discrepancies in the transcribed text. Make
sure that the names of the following products are spelled correctly:
ZyntriQix, Digique Plus, CynapseFive, VortiQore V8, EchoNix Array,
OrbitalLink Seven, DigiFractal Matrix, PULSE, RAPT, B.R.I.C.K.,
Q.U.A.R.T.Z., F.L.I.N.T. Only add necessary punctuation such as
periods, commas, and capitalization, and use only the context provided.
`;
const transcript = await transcribe(audioFile);
const completion = await openai.chat.completions.create({
model: "gpt-4.1",
temperature: temperature,
messages: [
{
role: "system",
content: systemPrompt,
},
{
role: "user",
content: transcript,
},
],
store: true,
});
console.log(completion.choices[0].message.content); 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 system_prompt = """
You are a helpful assistant for the company ZyntriQix. Your task is to correct
any spelling discrepancies in the transcribed text. Make sure that the names of
the following products are spelled correctly: ZyntriQix, Digique Plus,
CynapseFive, VortiQore V8, EchoNix Array, OrbitalLink Seven, DigiFractal
Matrix, PULSE, RAPT, B.R.I.C.K., Q.U.A.R.T.Z., F.L.I.N.T. Only add necessary
punctuation such as periods, commas, and capitalization, and use only the
context provided.
"""
def generate_corrected_transcript (temperature, system_prompt, audio_file):
response = client.chat.completions.create(
model = "gpt-4.1" ,
temperature = temperature,
messages = [
{ "role" : "system" , "content" : system_prompt},
{ "role" : "user" , "content" : transcribe(audio_file, "" )},
],
)
return response.choices[ 0 ].message.content
corrected_text = generate_corrected_transcript( 0 , system_prompt, fake_company_filepath) 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49 package main
import (
"context"
"fmt"
"os"
"github.com/openai/openai-go/v3"
)
const systemPrompt = `
You are a helpful assistant for the company ZyntriQix. Your task is
to correct any spelling discrepancies in the transcribed text. Make
sure that the names of the following products are spelled correctly:
ZyntriQix, Digique Plus, CynapseFive, VortiQore V8, EchoNix Array,
OrbitalLink Seven, DigiFractal Matrix, PULSE, RAPT, B.R.I.C.K.,
Q.U.A.R.T.Z., F.L.I.N.T. Only add necessary punctuation such as
periods, commas, and capitalization, and use only the context provided.
`
func main() {
file, err := os.Open("fixtures/speech.wav")
if err != nil {
panic(err)
}
defer file.Close()
client := openai.NewClient()
transcription, err := client.Audio.Transcriptions.New(context.Background(), openai.AudioTranscriptionNewParams{
File: file,
Model: openai.AudioModelGPT4oTranscribe,
})
if err != nil {
panic(err)
}
completion, err := client.Chat.Completions.New(context.Background(), openai.ChatCompletionNewParams{
Model: "gpt-4.1",
Temperature: openai.Float(0),
Messages: []openai.ChatCompletionMessageParamUnion{
openai.SystemMessage(systemPrompt),
openai.UserMessage(transcription.Text),
},
Store: openai.Bool(true),
})
if err != nil {
panic(err)
}
fmt.Println(completion.Choices[0].Message.Content)
} 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42 import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.audio.transcriptions.TranscriptionCreateParams;
import com.openai.models.chat.completions.ChatCompletionCreateParams;
import java.nio.file.Path;
String systemPrompt =
"""
You are a helpful assistant for the company ZyntriQix. Your task is to
correct any spelling discrepancies in the transcribed text. Make sure that
the names of the following products are spelled correctly: ZyntriQix,
Digique Plus, CynapseFive, VortiQore V8, EchoNix Array, OrbitalLink Seven,
DigiFractal Matrix, PULSE, RAPT, B.R.I.C.K., Q.U.A.R.T.Z., F.L.I.N.T.
Only add necessary punctuation such as periods, commas, and capitalization,
and use only the context provided.
""";
var result =
client
.audio()
.transcriptions()
.create(
TranscriptionCreateParams.builder()
.file(Path.of(System.getenv("OPENAI_EXAMPLE_AUDIO_PATH")))
.model("gpt-4o-transcribe")
.build());
var completion =
client
.chat()
.completions()
.create(
ChatCompletionCreateParams.builder()
.model("gpt-4.1")
.temperature(0.0)
.store(true)
.addSystemMessage(systemPrompt)
.addUserMessage(result.asTranscription().text())
.build());
completion.choices().stream()
.flatMap(choice -> choice.message().content().stream())
.forEach(System.out::println); 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 using OpenAI.Audio;
using OpenAI.Chat;
string key = Environment.GetEnvironmentVariable("OPENAI_API_KEY")!;
string model = "gpt-4.1";
ChatClient client = new(model, key);
string transcriptionModel = "gpt-4o-transcribe";
AudioClient audio = new(transcriptionModel, key);
await using FileStream source = File.OpenRead("speech.wav");
AudioTranscription transcription = await audio.TranscribeAudioAsync(source, "speech.wav");
string systemPrompt =
"""
You are a helpful assistant for the company ZyntriQix. Correct any
spelling discrepancies in the transcribed text. Make sure the names
of these products are spelled correctly: ZyntriQix, Digique Plus,
CynapseFive, VortiQore V8, EchoNix Array, OrbitalLink Seven,
DigiFractal Matrix, PULSE, RAPT, B.R.I.C.K., Q.U.A.R.T.Z., F.L.I.N.T.
Only add necessary punctuation such as periods, commas, and
capitalization, and use only the context provided.
""";
ChatCompletionOptions correctionOptions = new() { Temperature = 0 };
ChatCompletion completion = await client.CompleteChatAsync(
[
new SystemChatMessage(systemPrompt),
new UserChatMessage(transcription.Text),
],
correctionOptions
);
Console.WriteLine(completion.Content[0].Text); 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 require "openai"
require "pathname"
client = OpenAI::Client.new
audio = Pathname("speech.wav")
transcript = client.audio.transcriptions.create(
file: audio,
model: "gpt-4o-mini-transcribe"
)
raise "Expected a JSON transcript response" if transcript.is_a?(StringIO)
response = client.responses.create(
model: "gpt-4.1",
input: "Add punctuation and paragraph breaks without changing the words:\n#{transcript.text}"
)
puts(response.output_text) テキストモデルは綴りの誤りを修正でき、プロンプトが 224 トークンに制限される Whisper よりも長い用語リストを扱えます。話者の発言内容が変わらないよう、修正結果を元の音声と照合してください。