本篇是免費 token fuel 系列第 91 篇,研究 Azure Speech in Foundry Tools 的 Free F0 方案。Microsoft 官方 Pricing 目前列出每月 5 小時的即時 Speech-to-Text、每月 50 萬個 Neural Text-to-Speech 字元,以及每月 5 小時 Speech Translation。這是語音 sidecar fuel,不是可以拿給通用 LLM 使用的文字 token,也不是 Azure for Students USD 100 credit。

對主要 agent 而言,這篇的真正用途是把聲音輸入和聲音輸出接到既有的 planner,但讓每一段語音都經過明確的權利、資料、用量和人工 review 閘門。STT 的 transcript 可以作為外部資料交給文字模型,TTS 的結果可以作為短期聲音回應;兩者都不能反過來取得新的工具權限。
查核日期為 2026-08-25。Azure 價格、region、voice catalog、Foundry 命名與 quota 文件會更新,文章中的 5 小時、50 萬字元和 F0 限制都是官方查核日快照。真正使用前要讀回 Portal 的 resource SKU、meter、剩餘量、subscription scope、endpoint host 與當日服務狀態。
如果讀者先要理解整個免費燃料系列如何處理 API key、配額與人工接手,可先看 YOLO LAB AI agent 使用 FAQ;本篇再把同一套原則套到 Azure Speech 的秒數、字元、資源與 voice data。站內連結只是閱讀延伸,不代表 YOLO LAB 已替任何人開通 Azure。
語音 API 和文字 API 的風險也不同:音訊可能帶有聲紋、背景談話、姓名與地點,合成聲音可能造成冒充或誤導。因此課程預設只使用 synthetic fixture,並把原始 audio、transcript、TTS bytes、request metadata 和下游摘要分開保存與刪除。
這個 sidecar 的價值不在於把 Azure 當成主要模型,而在於讓 agent 具備可替換的聽與說介面。當 F0 失效、quota 不足、資料不能外傳或 voice 權利不明時,adapter 應該回傳文字 fallback、要求人工接手或直接停止,而不是自行選擇付費 provider。
免費月額要以使用者能理解的單位呈現:本月已用幾秒即時 STT、已合成幾個字元、翻譯用了幾秒、目前有幾個 in-flight request。不要只在畫面上顯示「AI credits」或「tokens」,因為那會掩蓋不同服務之間不能相加的事實。
文章中的程式碼刻意使用假的 resource name、環境變數與 synthetic fixture,目的是讓學生先練習輸入檢查、狀態機、限流和刪除。真正 live call 要由帳戶持有人完成 fresh read-back,並在測試後提供不含 secret 的結果證據。
若課程要長期運作,還要把 Azure Portal 的 cost、resource activity、key rotation、role membership 與 deletion evidence 納入交接。免費額度是短期資源,不是讓一個匿名背景服務永久運行的理由。
每月重置前後都要保存查核時間,避免把上月的 remaining meter 誤套到本月。
這也是交接時最容易被忽略的 freshness gate。
沒有 freshness evidence,就先不送新的音訊。
這條規則同樣適用於 TTS 字元和翻譯秒數。
本篇分類為 CONDITIONAL_AZURE_SPEECH_F0_MONTHLY_STT_TTS_SIDE_CAR。它適合學生 AI agent 練習語音輸入、轉錄、朗讀、短音訊互動、語言切換與錯誤回退;但 F0 的 real-time 限制、每月共用 meter、Azure resource 建立、區域 endpoint、資料保存與 subscription billing 都必須由 owner 讀回,不能看到「free」就自動開放。
本文只做官方文件整理,不代建立 Azure subscription、不建立 Speech resource、不取得或分享 resource key、不綁卡、不升級 S0、不執行 live audio request、不上傳真人錄音、不建立 custom voice,也不進行 WordPress 外部寫入。主要 agent 的文字 token、語音分鐘、TTS 字元和 Azure subscription credit 必須分開記帳。
F0 免費額度的準確讀法
Azure Speech 官方 Pricing 的 Free F0 表目前列出:Standard 與 Custom 的 real-time transcription 各有每月 5 audio hours,但註腳寫明 Speech-to-Text 免費 audio hours 在 Standard 與 Custom 之間共享;Batch 不支援。Neural Text-to-Speech 是每月 0.5 million characters,Speech Translation 是每月 5 audio hours。這些是不同 meter,不是可互換的統一 token 池。
因此主要 agent 要把 stt_realtime_minutes、tts_neural_characters 與 speech_translation_seconds 分開。5 小時 STT 不能換成 300 分鐘 batch transcription,50 萬 TTS 字元也不能換成 50 萬個聊天 token。每月是 account/resource 的查核邊界,不是保證每位學生都有獨立配額。
function classifyAzureSpeechFuel(snapshot) {
if (snapshot.provider !== 'AZURE') return 'PROVIDER_MISMATCH';
if (snapshot.product !== 'SPEECH') return 'PRODUCT_SCOPE_REVIEW';
if (snapshot.sku !== 'F0') return 'FREE_SKU_RECHECK';
if (snapshot.batchSttEnabled) return 'BATCH_NOT_FREE';
if (snapshot.sttMinutesRemaining < 0) return 'STT_QUOTA_STOP';
if (snapshot.ttsCharactersRemaining < 0) return 'TTS_QUOTA_STOP';
return 'SPEECH_CANARY_ALLOW';
}
它是語音 sidecar,不是主要模型
Speech-to-Text 把音訊轉成文字,Text-to-Speech 把文字轉成合成聲音,Speech Translation 則把語音轉成另一種語言的文字或語音流程。它們可以接在主要 agent 前後,但不負責一般規劃、長文推理、工具授權或事實查核。語音輸出完成也不代表 agent 可以直接執行其中的命令。
推薦的 route 是 audio input → STT → transcript data gate → 主要文字 agent → policy/fact review → TTS。若需要翻譯,將原始語音、轉錄文字、翻譯文字與合成音分層保存。每層要有 provider、model、region、duration 或 character count、status、request id 與刪除期限,避免把 Azure 的一個 subscription 敘述成單一 token wallet。
建立 Speech resource 才有 API 邊界
Microsoft 官方 REST 文件要求 Azure account、Speech resource,以及從 resource 的 Keys and Endpoint 頁取得 resource key 與 endpoint。F0 是 resource 的 pricing tier,不是只在本地設定一個環境變數就自動存在。建立 resource 時要確認 subscription、region、SKU、monthly allowance、forecast、access role 與刪除責任。
本篇不代替 owner 建立 subscription 或 resource,也不從瀏覽器讀取 key。若是課堂共用,應由責任組織管理 Azure subscription,替每個用途建立最小 scope 的 resource 或 project route,將 development、staging 與 production 分開;不要把 owner key 貼到學生群組或交給模型自行保存。
function admitSpeechResource(resource, owner) {
if (!owner.approved) return 'OWNER_APPROVAL_REQUIRED';
if (resource.kind !== 'Speech') return 'RESOURCE_TYPE_REVIEW';
if (resource.pricingTier !== 'F0') return 'PAID_SKU_REVIEW';
if (!resource.region || !resource.endpoint) return 'ENDPOINT_READBACK_REQUIRED';
if (resource.subscriptionScope !== 'course-dev') return 'SCOPE_REVIEW';
return 'RESOURCE_CANARY_ALLOW';
}
Key、Bearer token 與 Entra 要分層
Azure Speech REST reference 目前支援 Ocp-Apim-Subscription-Key 或 Authorization: Bearer。若走 STS bearer flow,要先以 resource key 呼叫 issueToken;官方文件寫這種 access token 有效 10 分鐘,且 bearer token 只對簽發它的 host scope 有效。Microsoft 也建議在雲端應用優先考慮 Microsoft Entra managed identity。
學生 canary 可以先使用 server-side resource key,環境變數只放 placeholder 名稱,例如 AZURE_SPEECH_KEY 與 AZURE_SPEECH_ENDPOINT。不要把 key 放在前端、公開 notebook、Git、prompt、音訊檔案 metadata、截圖、MCP config 或錯誤 log;若 key 外洩,owner 要立即撤銷或輪替,但新 key 不會刷新免費月額。
function buildSpeechAuth(env) {
if (!env.AZURE_SPEECH_KEY) return { error: 'KEY_NOT_INJECTED' };
if (!env.AZURE_SPEECH_ENDPOINT) return { error: 'ENDPOINT_NOT_INJECTED' };
return {
'Ocp-Apim-Subscription-Key': env.AZURE_SPEECH_KEY,
endpoint: env.AZURE_SPEECH_ENDPOINT
};
}
這段只是 local policy 示意,沒有呼叫 Azure。環境變數名稱不是 secret,真正值不進文章、測試輸出或索引。若日後改用短期 bearer token,要把 token expiry、host scope、issue time 與撤銷處理納入 ledger,不能只記一個模糊的「Azure token 可用」。
F0 的 STT 主要是即時短音訊
Azure Speech quotas 文件目前列 F0 的 real-time speech-to-text base model endpoint 併發上限為 1,custom endpoint 也是 1,而且不可調整。Pricing 註腳又寫 F0 的免費 Speech-to-Text audio hours 共享 Standard 與 Custom,Batch 不支援。這表示第一輪應做一個短、低併發、可刪除的 real-time canary,不能把 F0 當成批次轉錄服務。
短音訊 REST API 的文件還列出直接傳送的音訊最多 60 秒、只回 final result、不提供 partial result,且不支援 batch 或 custom speech。若課程要測較長檔案、多人說話、批次排程或 custom model,先確認它已經離開 F0 scope,不能沿用本篇免費結論。
function admitRealtimeStt(job, limits) {
if (job.mode !== 'realtime') return 'F0_MODE_REVIEW';
if (job.audioSeconds <= 0 || job.audioSeconds > 60) return 'SHORT_AUDIO_CAP_STOP';
if (limits.concurrentStt !== 0) return 'CONCURRENCY_LEDGER_REVIEW';
if (limits.inFlightStt >= 1) return 'F0_CONCURRENCY_STOP';
if (!job.syntheticOrConsented) return 'AUDIO_RIGHTS_STOP';
return 'ONE_REALTIME_STT_ALLOW';
}
REST 短音訊 canary 的資料格式
官方短音訊 REST 文件要求將 audio bytes 放在 POST body,並列出 WAV PCM 16 kHz mono 或 OGG OPUS 等格式。request 需要 Content-Type,並以 language=en-US 之類的 query parameter 指定語言;缺少 language 可能得到 4xx。第一輪固定一個 synthetic WAV、固定語言、固定秒數與固定 endpoint。
export AZURE_SPEECH_KEY='owner-provided-placeholder'
export AZURE_SPEECH_ENDPOINT='https://YourResourceName.cognitiveservices.azure.com'
curl -sS -X POST \
"${AZURE_SPEECH_ENDPOINT}/stt/speech/recognition/conversation/cognitiveservices/v1?language=en-US&format=detailed" \
-H "Ocp-Apim-Subscription-Key: ${AZURE_SPEECH_KEY}" \
-H "Accept: application/json" \
-H "Content-Type: audio/wav; codecs=audio/pcm; samplerate=16000" \
--data-binary '@/path/to/synthetic-voice.wav'
上段是 API 形狀示例,本文不執行 curl;endpoint、resource host、語言、格式與免費狀態必須由 owner 在當日 read-back。placeholder 不是有效 key,假設的音訊路徑也不是工作區的真實檔案。若輸出中出現錯誤 status、空 transcript 或未預期的語言,先停在 canary,不自動換 resource。
Streaming 的 session 不是無限麥克風
Speech SDK 適合做 real-time recognition、partial result、continuous recognition 與事件處理,但 F0 的併發仍是資源限制。主要 agent 不應在背景常駐麥克風或讓模型依使用者話語自動延長 session。每個 session 要有最大秒數、idle timeout、停止事件、request id 與本地刪除日。
Streaming output 要分開記錄 partial、final、canceled、error 與 closed。斷線時不能無限重連,因為每一次新 session 都可能消耗新的 audio meter。先保存 session duration、最後事件與 subscription read-back,再由 owner 決定是否重試;免費額度不能成為長時間背景監聽的理由。
function closeSpeechSession(session, now) {
if (!session.startedAt) return 'SESSION_START_MISSING';
if (session.closedAt) return 'SESSION_ALREADY_CLOSED';
if (now - session.startedAt > session.maxDurationMs) return 'SESSION_DURATION_STOP';
return {
action: 'SEND_TERMINATION_AND_READBACK',
durationMs: now - session.startedAt
};
}
TTS 每月 50 萬字元也有硬限制
F0 Pricing 目前列 Neural Text-to-Speech 每月 0.5 million characters,quota 文件列 standard/custom voices 的即時 TTS 每 60 秒最多 20 transactions,且每次產出的 audio 最長 10 分鐘。F0 quota 不可調整。字元數、request 數與音訊分鐘是三個不同帳本,不能用一次短句測試推算整月。
主要 agent 朗讀前要先做文字長度、voice、locale、輸出格式、預估字元與使用者同意檢查。文字若含未清理的 prompt injection、個資、密碼、電話或客戶內容,不得直接送到 TTS;先經過 redaction 和內容 review,再決定是否合成。合成聲音也不代表可以冒充真人或商業發布。
function admitTts(text, ledger, now) {
const chars = [...text].length;
if (chars === 0) return 'EMPTY_TTS_INPUT';
if (chars > ledger.singleRequestCharCap) return 'TTS_REQUEST_CAP_STOP';
if (ledger.remainingCharacters < chars) return 'TTS_MONTHLY_STOP';
if (now - ledger.windowStartedAt < 60000 && ledger.requestsInWindow >= 20) {
return 'TTS_RATE_STOP';
}
return { status: 'TTS_CANARY_ALLOW', chars };
}
TTS REST 只適合簡單路徑
Microsoft 的 TTS REST reference 說明每個 voice endpoint 與 region 有關,使用前要有 Azure account、Speech resource、resource key 和 endpoint;文件也提醒 REST API 的 use cases 有限,若需要更多 processing events,應考慮 Speech SDK。學生第一輪可以用短 SSML 或純文字做 canary,但要 pin voice、locale、region 與 output format。
export AZURE_SPEECH_KEY='owner-provided-placeholder'
export AZURE_SPEECH_REGION='eastus'
curl -sS -X POST \
"https://${AZURE_SPEECH_REGION}.tts.speech.microsoft.com/cognitiveservices/v1" \
-H "Ocp-Apim-Subscription-Key: ${AZURE_SPEECH_KEY}" \
-H "Content-Type: application/ssml+xml" \
-H "X-Microsoft-OutputFormat: audio-16khz-128kbitrate-mono-mp3" \
--data 'synthetic fixture '
這段只展示 request 形狀,不會產生聲音,也沒有指定真人聲音或執行 live call。實際 voice name、region、output format、字元計量與 resource endpoint 由官方支援清單和 owner account 決定;若 voice unavailable、429 或回傳空 bytes,先保存 status,再停止重試。
Speech Translation 另有共享 audio meter
官方 Pricing 將 Speech Translation 的 F0 allowance 列為每月 5 audio hours。它不是 Azure Translator F0 每月 200 萬文字字元,也不是 STT 5 小時以外又額外贈送的可任意合併分鐘;實際流程可能同時使用 Speech-to-Text、Translation 與 TTS,各 meter 要分別記錄。
如果主要 agent 只需要文字翻譯,走既有 Azure Translator route;如果需要從聲音直接得到翻譯,才選 Speech Translation。不要將兩篇文章的免費量相加,也不要在 resource dashboard 只看一個總 cost 就推導每個 endpoint 還剩多少。
F0 quota 與 Azure subscription credit 分開
F0 是 Speech resource 的產品免費 tier;Azure for Students、Azure Free Account 或其他 promotion 則是 subscription/billing credit。即使一個帳戶有 Azure subscription credit,也不代表 Speech resource 仍是 F0;反過來 F0 的月度 allowance 也不會替 storage、Functions、Container、網路或其他 Azure service 付款。
function gateAzureBilling(state) {
if (state.speechTier !== 'F0') return 'SPEECH_TIER_OWNER_REVIEW';
if (state.paygEnabled) return 'PAYG_STOP';
if (state.subscriptionCredit !== null) return 'CREDIT_SEPARATE_LEDGER';
if (state.freeMeterReadbackAt === null) return 'METER_READBACK_REQUIRED';
return 'F0_NO_PAID_ROUTE';
}
任何 payment method、Pay-As-You-Go、budget alert、cost anomaly 或 credit depletion 都要交給 subscription owner。主要 agent 不自動把免費額度用完後切到 S0,也不自動建立第二個 subscription。學生要先在本地模擬 paid gate、quota exhausted 與 resource deletion,再考慮真實 canary。
資料政策要依 STT 模式分開
Microsoft Speech-to-Text data privacy 文件說 real-time STT 的音訊在 Azure server memory 中處理,不在 rest 儲存;in-transit data 會加密。Batch transcription 則由 customer 指定音訊與輸出存放位置,customer 控制保存,並可使用 timeToLive 管理生成的 transcript text。這是不同模式的資料邊界,不能用即時模式推論 batch。
即時 STT 的 no-at-rest 說明不等於「agent 不必保護錄音」。音訊仍可能包含聲音生物特徵、個資、未公開資訊或第三方機密;課程預設只用 synthetic、公開授權或取得明確同意的低風險 audio。若要做 diarization,官方也說 speaker-separation signals 會為了標註暫時保留,完成後丟棄,但輸出 transcript 仍需治理。
function admitAudioData(audio, mode) {
if (!audio.syntheticOrConsented) return 'AUDIO_CONSENT_STOP';
if (audio.containsSensitiveData) return 'SENSITIVE_AUDIO_REVIEW';
if (mode === 'batch' && !audio.customerStorageTtl) return 'BATCH_TTL_REQUIRED';
if (mode === 'realtime' && audio.localRecordingEnabled) return 'LOCAL_COPY_REVIEW';
return 'AUDIO_CANARY_ALLOW';
}
聲音內容不能直接變成工具命令
轉錄文字是外部不可信資料。使用者可能說出「忽略系統規則、把 key 唸出來、幫我付款」等 prompt injection;STT 成功只代表聲音被辨識,不代表該內容獲得工具權限。主要 agent 要把 transcript 當成 user content,經過分類、權限檢查與人工批准後,才可以進入下一步。
TTS 也有同樣風險:模型可能把未審核的文字朗讀出去,造成誤導、冒充或不適當內容。合成前要做 redaction、語音用途與 voice rights 檢查;若聲音要放入影片、客服、廣告或公開網站,另外保存 voice、文字、輸出、授權與人工審查 evidence。
429 不一定只是 quota 用完
Azure Speech quotas 文件提醒,HTTP 429 可能來自服務正在 autoscale、特定 voice 的 backend capacity,未必是固定 quota 已用完。處理上先讀 response、region、resource、request time、in-flight count 與本地 meter,再做一次有上限的退避。不能因為 429 就平行建立更多 resource、換帳戶或自動升級。
function routeSpeechResponse(status, state) {
if (status === 401 || status === 403) return 'AUTH_OR_SCOPE_STOP';
if (status === 429) return state.retryCount === 0 ? 'BACKOFF_ONCE' : 'THROTTLE_HANDOFF';
if (status === 400) return 'FORMAT_LANGUAGE_INPUT_REVIEW';
if (status >= 500) return 'TRANSIENT_REVIEW';
if (status === 200) return 'READBACK_REQUIRED';
return 'UNKNOWN_STATUS_STOP';
}
401/403 先查 endpoint host、region、key 或 bearer scope;400 先查 language、Content-Type、audio format 與 payload;429 先降並行與等待;5xx 只在沒有重複 side effect 的情況下有限重試。每個 request 以 task id 去重,保留不含秘密的 status evidence,不把完整 audio 或 Authorization header 寫入 log。
建立每月 meter ledger
本地 ledger 至少要有 resource id hash、subscription scope、SKU、region、endpoint、STT real-time seconds、TTS characters、Speech Translation seconds、in-flight count、request status、HTTP code、estimated usage、dashboard read-back time、billing state、data class 與 deleteAt。沒有官方 read-back 的欄位標記 unknown,不把 unknown 當成零。
function recordSpeechUsage(ledger, event) {
if (!event.requestId || !event.mode) return 'USAGE_EVIDENCE_MISSING';
const next = { ...ledger };
if (event.mode === 'stt_realtime') next.sttSeconds += event.audioSeconds;
if (event.mode === 'tts') next.ttsCharacters += event.characters;
if (event.mode === 'translation') next.translationSeconds += event.audioSeconds;
next.lastRequestId = event.requestId;
next.lastStatus = event.status;
return next;
}
這是課程 policy ledger,不是 Azure usage API 的固定 schema。實際費用、月度 allowance、region、resource tier 與是否存在其他使用者 activity,仍要由 owner 在 Portal 或官方報表讀回。每次 canary 之前刷新一次,遇到 stale read-back、meter mismatch 或未知 paid route 就停止新請求。
第一個 STT canary 要很小
推薦第一個 canary 是一段 5 至 20 秒、16 kHz mono PCM WAV 的 synthetic voice,內容只包含虛構句子與固定語言。先在本地驗證檔案長度、格式、hash、權利與內容分類,再確認 F0、remaining meter、in-flight count、endpoint host 與 key scope,最後只送一次。結果只保存去識別化 transcript hash、status、duration 與人工品質 verdict。
若需要測台灣中文、英文或 code-mixed input,分開建立 fixture 與評測指標,不在同一次免費 canary 無限嘗試語言。評測可以包含詞錯誤、數字、專有名詞、延遲、空結果與 401/400 模擬;模擬測試不消耗 Azure meter,只有 owner 明確批准的 live canary 才進入免費額度。
第一個 TTS canary 要保留同意
TTS canary 使用 synthetic text、標準 neural voice、短輸出與固定 locale。不要拿真人 voice sample 做 custom voice,不要模仿未同意的人,不要用客戶品牌聲音,也不要將合成結果直接當成官方聲明。課程只評估語言、清晰度、輸出格式、字元計量與播放器狀態。
輸出音檔要設定短 TTL,完成人工聆聽與 hash 後刪除;若需要放進網站或影片,先確認商標、聲音、文字、音樂與發布權利。免費字元額度不等於商用許可,也不會替下游 hosting、CDN 或儲存付費。
F0 的模型 hosting 也不是永久存在
Pricing 頁註腳目前寫 Free F0 的 unused models 會在 7 天後自動 decommission。這提醒我們,模型 endpoint hosting 與每月語音 meter 是不同資產;即使只做 custom model 的 evaluation,也要記錄 hosting state、最後使用時間、模型來源與刪除日,不把「一個 model free per month」理解成永久部署。
學生 agent 第一版不啟用 custom speech、custom voice、personal voice、avatar 或 Voice Live。這些功能有額外的資料、權利、limited access、hosting 或 paid tier 條件;若未來要研究,必須另開文章與另做官方 evidence,不能沿用本篇 F0 allowance。
不要把 Azure Speech 與 Translator 合併
既有 Azure Translator F0 是文字翻譯字元 meter;本篇 Azure Speech Translation 是 audio seconds meter。兩者都可能出現在語音翻譯 pipeline,但服務、resource、endpoint、授權、資料處理與額度不同。主要 agent 只在 route manifest 明確寫出使用哪個產品,禁止以「Azure 免費」作為統一判斷。
subscription owner 的付費停止線
只要資源不是 F0、free meter 讀回失敗、出現 S0、Pay-As-You-Go、cost alert、credit depletion、payment method prompt、quota increase 或新的 paid SKU,就停止寫入並交給 subscription owner。主要 agent 不自動切換付費方案、不建立第二個 subscription、不用別人的 credit、不重複註冊。
function stopOnPaidRoute(state) {
const paidSignals = [
state.sku !== 'F0',
state.paygEnabled,
state.paymentPrompt,
state.quotaIncreaseRequested,
state.freeMeterUnknown
];
return paidSignals.some(Boolean) ? 'PAID_ROUTE_HANDOFF' : 'F0_ROUTE_CONTINUE';
}
課堂多人使用的治理方式
多人課堂最好由管理者提供受控的 server-side gateway,而不是把 resource key 發給每個學生。gateway 只接受已核准的 fixture、語言、voice、秒數與字元長度,記錄匿名 task id,並在 F0 remaining meter 不足時回傳明確 stop。學生可以用 mock mode 練習 route、ledger、retry 與刪除,不必知道 raw secret。
如果學生各自擁有 Azure 帳戶,則各自閱讀 F0 pricing、quota、privacy、acceptable use、region 與 subscription terms;不要把一位學生的 Portal screenshot 或 quota 數字當成全班現況。未成年、學校資料、客戶資料與錄音 consent 由責任組織依適用政策處理,本文不替代法律意見。
API key 不是課程教材內容
教材只展示環境變數名、假的 endpoint placeholder、mock response 與錯誤分流;不展示有效 resource key、STS bearer token、subscription id、storage SAS、cookie 或完整音訊。任何同學把 key 貼到聊天室,都應視為 credential incident,由 owner 立即撤銷並查 usage,不要把它抄入錯誤報告。
短期 bearer token 也不能貼給 agent。官方文件寫它有效 10 分鐘且綁定 host;若 token 進入 prompt、browser history 或 log,短 TTL 不會消除洩漏。把權限放在後端 adapter,用明確的 tool allowlist 將語音結果回傳給主要 agent。
一個安全的語音 agent 流程
流程可以固定為:本地檔案與同意檢查 → 判定 F0 route → 刷新 meter → 預留秒數或字元 → server-side request → read-back status → 保存最小 transcript/audio hash → 主要 agent 分類 → 人工 review → 設定 deletion。每一步都要有 error、timeout、quota stop 與 paid handoff,不能只靠 prompt 要求模型自律。
function nextAzureSpeechStep(state) {
if (!state.rightsChecked) return 'CHECK_AUDIO_OR_VOICE_RIGHTS';
if (!state.f0Readback) return 'REFRESH_F0_METER';
if (!state.budgetReserved) return 'RESERVE_SECONDS_OR_CHARACTERS';
if (!state.response) return 'SEND_ONE_SERVER_SIDE_REQUEST';
if (!state.statusVerified) return 'VERIFY_STATUS_AND_USAGE';
if (!state.humanReview) return 'REVIEW_TRANSCRIPT_OR_AUDIO';
return 'SAVE_MINIMAL_EVIDENCE_AND_DELETE';
}
何時不該選 Azure Speech F0
若任務需要 batch transcription、長於 60 秒的 REST short-audio route、多人高併發、長時間背景麥克風、custom voice、personal voice、Voice Live、S0 adjustable quota 或 production SLA,F0 不是合適的預設。若資料不能離開本地、無法取得錄音同意、不能接受 Azure resource governance,也應改用已批准的本地或內部方案。
它最適合小量、短音訊、低併發、可刪除的課程 canary。對主要 agent 而言,F0 可以補上語音輸入與輸出,但不會解決 prompt injection、轉錄錯誤、聲音權利、主要 LLM token、hosting 費用或公開發布責任。
官方來源與查核範圍
本篇主要依據 Azure Speech in Foundry Tools pricing 的 F0 allowance、shared STT hours、TTS characters、Speech Translation 與 model hosting 註腳;以 Quotas and limits 確認 F0 併發、TTS transactions、短音訊與 batch 不可用;以 Speech to text REST API for short audio 確認音訊格式、60 秒限制、language query 與 error status。
認證與輸出路徑另對照 Text to speech REST API、Speech to text quickstart、Speech troubleshooting、Speech data privacy 與 Speech to text REST API overview。官方文件與價格會更新,使用前要重新確認當日 region、SKU、quota、meter、voice、privacy 與 billing。
本篇完成閘門與下一篇
本篇完成條件是:F0 每月額度與 token 單位已分開、F0 與 subscription credit 已分開、STT/TTS/Translation 路徑與限制有官方來源、key/Bearer/Entra 邊界已寫明、資料與聲音權利已列出、rate limit/429/paid handoff 有最小範例、沒有真實 secret、沒有 live audio smoke、沒有外部發布。這是本機草稿完成,不代表任何帳戶已開通或仍有剩餘額度。
完成本篇 read-back 後,下一輪再找第 92 篇尚未收錄的官方免費方案。優先順序仍是可驗證的免費入口、明確用量單位、學生 agent 實際用途、資料與 secret 安全、清楚的停止線;社群傳聞、免費 key 分享、抽獎、輪換帳戶與規避限制不列入。
KEEP READING
接著讀什麼?
從同一主題繼續閱讀,或回到 YOLO LAB 的完整文章索引,找到下一個值得投入時間的問題。


發表迴響