本指南介紹 Azure OpenAI 內容串流體驗與選項。 客戶可以在 API 生成時接收內容,而不必等待已驗證的內容區塊通過內容篩選。
註
非同步過濾設定需要在 Foundry 入口網站中修改內容過濾政策的權限。
選擇正確的串流模式
以下情況下使用預設串流:
- 必須達到最高的安全性與合規性
- 你需要在顯示任何內容前立即進行篩選
- 您的應用程式無法處理追溯性內容移除
- 範例:受管制產業中的面向客戶的聊天機器人
在以下情況下使用非同步濾波器:
- 低延遲對使用者體驗至關重要
- 你可以實作用戶端內容編修
- 您的應用程式有額外的安全控制措施
- 你願意接受延遲濾波訊號
- 範例:內部開發工具、創意寫作助理
預設過濾行為
內容護欄系統已整合並預設啟用給所有客戶。 在預設串流情境中,完成內容會被緩衝,內容護欄系統會對緩衝的內容進行檢測。根據護欄配置,若內容未違反護欄政策(Microsoft 的預設或自訂使用者配置),則會返回給使用者;否則會立即被封鎖,並返回護欄錯誤。 這個過程會重複到串流結束。 內容會在返還給使用者前,依照護欄政策進行全面審核。 此時內容不是逐個標記回傳,而是以相應緩衝區大小的「內容區塊」回傳。
非同步過濾
用戶可選擇非同步過濾器作為額外選項,帶來全新的串流體驗。 在此情況下,內容過濾器以非同步方式運行,完成內容會立即以順暢的代幣逐代幣串流體驗返回。 沒有任何內容被緩衝,這讓串流體驗快速且不會因內容過濾而產生延遲。
客戶必須明白,雖然此功能能改善延遲,但這是在安全性與即時審查較小模型輸出區塊之間的取捨。 由於內容過濾是非同步執行的,內容審核訊息和違反政策的訊號會被延遲,這意味著某些原本會立即過濾的有害內容區塊可能會顯示給使用者。
註解:註解與內容審核訊息會在直播過程中持續回傳。 我們強烈建議您在應用程式中使用註解,並實施其他 AI 指引與控制機制,例如遮蔽內容或回傳其他安全資訊給使用者。
內容過濾訊號:內容過濾錯誤訊號會被延遲。 如果發生原則違規,其會在可提供時立即傳回,並且串流也會停止。 內容過濾訊號會在政策違反內容的約 1,000 字元範圍內被保證。
客戶著作權承諾:被追溯標記為受保護資料的內容,可能不符合客戶著作權承諾保障的資格。
成本考量
重要
串流中內容過濾的計費
當串流過程中觸發內容過濾時,提示與完成代幣都會被收費:
- 狀態 400 (提示已篩選):針對提示評估收費
- 狀態 200,finish_reason:「content_filter」:在過濾之前生成的提示和完成代幣均收費。
這適用於預設模式和非同步濾波器模式。 詳情請參見 Azure OpenAI 價格。
要在
註
非同步過濾器可在 API 版本 2024-02-01 及更高版本中使用。 使用 OpenAI Python SDK v1.0+ 或 Azure OpenAI SDK 並搭配相容的 API 版本。
內容過濾模式比較
| 比較 | 串流 - 預設 | 串流 - 非同步濾波器 |
|---|---|---|
| 現況 | GA | GA |
| 資格 | 所有客戶 | 所有客戶 |
| 如何啟用 | 預設啟用,無需操作 | 客戶可直接在 Foundry 入口網站 中設定(作為內容過濾配置的一部分,於部署層級應用) |
| 模式與可用性 | 文字;所有 GPT 模型 | 文字;所有 GPT 模型 |
| 串流體驗 | 內容會被緩衝並以區塊回傳 | 零延遲(無緩衝,濾波器非同步執行) |
| 內容過濾訊號 | 即時濾波訊號 | 延遲的篩選訊號 (最多 ~1,000 字元的增量) |
| 內容過濾配置 | 支援預設及任何客戶自訂的過濾器設定(含選配型號) | 支援預設及任何客戶自訂的過濾器設定(含選配型號) |
註解與範例回應
提示註釋訊息
此訊息與預設註解相同。
data: {
"id": "",
"object": "",
"created": 0,
"model": "",
"prompt_filter_results": [
{
"prompt_index": 0,
"content_filter_results": { ... }
}
],
"choices": [],
"usage": null
}
完成詞元訊息
完成訊息會立即轉發。 該服務一開始不會進行審核或註解。
data: {
"id": "chatcmpl-7rAJvsS1QQCDuZYDDdQuMJVMV3x3N",
"object": "chat.completion.chunk",
"created": 1692905411,
"model": "gpt-35-turbo",
"choices": [
{
"index": 0,
"finish_reason": null,
"delta": {
"content": "Color"
}
}
],
"usage": null
}
註解訊息
文字欄位總是空字串,表示沒有新的標記。 註解只適用於已經寄出的標記。 多個註解訊息可以指向相同的標記。
"start_offset" 及 "end_offset" 是文字中低粒度的偏移量(從提示的開頭開始為 0),用來標示註解應用到的文字。
"check_offset" 顯示有多少文字是完全審核的。 它是未來的 "end_offset" 註解值的唯一下限。 它從未減少。
data: {
"id": "",
"object": "",
"created": 0,
"model": "",
"choices": [
{
"index": 0,
"finish_reason": null,
"content_filter_results": { ... },
"content_filter_raw": [ ... ],
"content_filter_offsets": {
"check_offset": 44,
"start_offset": 44,
"end_offset": 198
}
}
],
"usage": null
}
重點領域說明:
-
check_offset:內容已完全審核的字元位置 (永不減少) -
start_offset: 這個註解批次開始的字元位置 -
end_offset: 這個註解批次結束的字元位置
所有偏移量從原始提示文字開頭的 0 開始計算。
取樣響應流(通過篩選器)
以下範例顯示了使用非同步篩選器的真實聊天完成回應。 提示註解不變,完成標記未帶標記傳送,新的註解訊息則不包含標記。 相反地,這些新的註解訊息會連結到特定的內容篩選偏移量。
{"temperature": 0, "frequency_penalty": 0, "presence_penalty": 1.0, "top_p": 1.0, "max_tokens": 800, "messages": [{"role": "user", "content": "What is color?"}], "stream": true}
data: {"id":"","object":"","created":0,"model":"","prompt_annotations":[{"prompt_index":0,"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}}}],"choices":[],"usage":null}
data: {"id":"chatcmpl-7rCNsVeZy0PGnX3H6jK8STps5nZUY","object":"chat.completion.chunk","created":1692913344,"model":"gpt-35-turbo","choices":[{"index":0,"finish_reason":null,"delta":{"role":"assistant"}}],"usage":null}
data: {"id":"chatcmpl-7rCNsVeZy0PGnX3H6jK8STps5nZUY","object":"chat.completion.chunk","created":1692913344,"model":"gpt-35-turbo","choices":[{"index":0,"finish_reason":null,"delta":{"content":"Color"}}],"usage":null}
data: {"id":"chatcmpl-7rCNsVeZy0PGnX3H6jK8STps5nZUY","object":"chat.completion.chunk","created":1692913344,"model":"gpt-35-turbo","choices":[{"index":0,"finish_reason":null,"delta":{"content":" is"}}],"usage":null}
data: {"id":"chatcmpl-7rCNsVeZy0PGnX3H6jK8STps5nZUY","object":"chat.completion.chunk","created":1692913344,"model":"gpt-35-turbo","choices":[{"index":0,"finish_reason":null,"delta":{"content":" a"}}],"usage":null}
...
data: {"id":"","object":"","created":0,"model":"","choices":[{"index":0,"finish_reason":null,"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"content_filter_offsets":{"check_offset":44,"start_offset":44,"end_offset":198}}],"usage":null}
...
data: {"id":"chatcmpl-7rCNsVeZy0PGnX3H6jK8STps5nZUY","object":"chat.completion.chunk","created":1692913344,"model":"gpt-35-turbo","choices":[{"index":0,"finish_reason":"stop","delta":{}}],"usage":null}
data: {"id":"","object":"","created":0,"model":"","choices":[{"index":0,"finish_reason":null,"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"content_filter_offsets":{"check_offset":506,"start_offset":44,"end_offset":571}}],"usage":null}
data: [DONE]
取樣響應流(被濾波器阻擋)
{"temperature": 0, "frequency_penalty": 0, "presence_penalty": 1.0, "top_p": 1.0, "max_tokens": 800, "messages": [{"role": "user", "content": "Tell me the lyrics to \"Hey Jude\"."}], "stream": true}
data: {"id":"","object":"","created":0,"model":"","prompt_filter_results":[{"prompt_index":0,"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}}}],"choices":[],"usage":null}
data: {"id":"chatcmpl-8JCbt5d4luUIhYCI7YH4dQK7hnHx2","object":"chat.completion.chunk","created":1699587397,"model":"gpt-35-turbo","choices":[{"index":0,"finish_reason":null,"delta":{"role":"assistant"}}],"usage":null}
data: {"id":"chatcmpl-8JCbt5d4luUIhYCI7YH4dQK7hnHx2","object":"chat.completion.chunk","created":1699587397,"model":"gpt-35-turbo","choices":[{"index":0,"finish_reason":null,"delta":{"content":"Hey"}}],"usage":null}
data: {"id":"chatcmpl-8JCbt5d4luUIhYCI7YH4dQK7hnHx2","object":"chat.completion.chunk","created":1699587397,"model":"gpt-35-turbo","choices":[{"index":0,"finish_reason":null,"delta":{"content":" Jude"}}],"usage":null}
data: {"id":"chatcmpl-8JCbt5d4luUIhYCI7YH4dQK7hnHx2","object":"chat.completion.chunk","created":1699587397,"model":"gpt-35-turbo","choices":[{"index":0,"finish_reason":null,"delta":{"content":","}}],"usage":null}
...
data: {"id":"chatcmpl-8JCbt5d4luUIhYCI7YH4dQK7hnHx2","object":"chat.completion.chunk","created":1699587397,"model":"gpt-35-
turbo","choices":[{"index":0,"finish_reason":null,"delta":{"content":" better"}}],"usage":null}
data: {"id":"","object":"","created":0,"model":"","choices":[{"index":0,"finish_reason":null,"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"content_filter_offsets":{"check_offset":65,"start_offset":65,"end_offset":1056}}],"usage":null}
data: {"id":"","object":"","created":0,"model":"","choices":[{"index":0,"finish_reason":"content_filter","content_filter_results":{"protected_material_text":{"detected":true,"filtered":true}},"content_filter_offsets":{"check_offset":65,"start_offset":65,"end_offset":1056}}],"usage":null}
data: [DONE]
故障排除
串流因內容篩選完成原因而停止
症狀:串流意外以finish_reason: "content_filter"結束。
原因:模型產生的內容違反了內容過濾政策。 在非同步濾波模式下,這個訊號可能會在部分內容已經顯示完畢之後才到達。
解決:
- 在最後一段檢查
content_filter_results,以識別觸發過濾的類別(仇恨、暴力、性、自殘、受保護的材料文本) - 如果使用非同步過濾器,請在您的應用程式中實作內容遮蔽功能,以移除已顯示的內容
- 請檢視 Foundry 入口網站的內容過濾設定,如適用時調整嚴重性閾值
- 考慮重新表述提示,以避免觸發過濾器
註解未出現在串流中
症狀:串流成功完成,但 content_filter_results 總是空或為空。
原因:你的部署可能沒有啟用內容過濾註解,或你使用的 API 版本不支援註解。
解決:
- 請確認你使用的是 2024-02-01 或更新的 API 版本
- 請檢查 Foundry 入口網站的內容過濾設定
- 確保你選擇的濾鏡已啟用註解
- 請參閱護 欄註解文件 以了解設定步驟
非同步濾波模式下的延遲濾波訊號
症狀:應該被過濾的內容會暫時出現,然後被追後標記。
原因:這是非同步濾波器模式下預期的行為。 過濾以非同步方式執行,保證訊號長度在 ~1,000 字元內。
解決:
- 這是非同步篩選模式的預期運作方式。
- 收到延遲過濾信號時,請實作客戶端內容編輯
- 監控
check_offset數值以追蹤調節進度 - 如果你的使用情境需要立即過濾,可以考慮使用預設串流模式
了解 content_filter_offsets
症狀:不清楚如何解讀 check_offset、 、 start_offset和 end_offset 數值。
說明:
-
check_offset:內容已完全審核的字元位置 (永不減少) -
start_offset: 此註解適用的文字範圍起始 -
end_offset:此註解適用的文字範圍結束
所有位移皆為字元位置,提示開頭為 0。