最初發佈在我的部落格:https://lazy.bearblog.dev/go-mime-wtf/
一個週末,我決定為自己寫一個 Telegram 機器人來自動化待辦事項或購物清單。
這個想法很簡單。我向機器人發送了要購買的商品列表,它會創建一個帶有復選框的網頁,我可以在一手拿著手機、另一隻手拿著購物籃的情況下勾選這些複選框。
機器人寫得很快,但後來我想嘗試 OpenAI 的 Whisper 模型。因此,我決定在我的應用程式中添加語音識別。
現在,程式運作如下:
現在,關於這篇文章。在 go-openai 中,您可以使用 openai.AudioRequest 結構發送音頻,該結構允許您在 Reader 欄位中指定音訊資料流或在 FilePath 欄位中指定檔案路徑。好吧,我認為這些欄位是互斥的,但事實證明,即使使用音訊串流也需要指定 FilePath。 API 可能使用它來決定流類型。
在 Telegram 端,我們收到一個 tgbotapi.Voice 結構,其中有一個 MimeType 欄位。對於語音訊息,它是audio/ogg,但將來很容易改變。
因此,我們有了音訊串流的 MIME 類型,我們需要從中確定檔案副檔名,建立一個檔案名稱以確保 OpenAI API 不會抱怨未知的檔案類型。
程式碼看起來很簡單:
在本地測試 - 它有效:
部署到雲端 - 不起作用:
檢查本地和用於構建的 CI/CD 中的 Go 版本 - 它們是相同的。
事實證明,mime 套件的行為不是確定性的,並且在運行時取決於作業系統中是否存在 /etc/mime.types 檔案及其內容。
這就是 mime 套件讀取 MIME 類型到檔案副檔名映射的運行時表的地方。
我是認真的:你編譯一個二進位文件,運行所有測試,一切看起來都很棒,但是這個二進位檔案將在不同的環境中以不同的方式確定相同 MIME 類型的假定檔案副檔名。
讓我們取得已知的 MIME 類型的音訊檔案及其副檔名,並使用 mime.AddExtensionType 手動將它們新增至 init 函數。
這將使我們的應用程式的行為在其將使用的網域(在我的例子中是音訊檔案)方面具有確定性。
這個經驗表明,Go 中的事物並不總是確定性的。如果有些事情看起來很奇怪,請不要猶豫,深入研究庫的源代碼,看看它是如何實現的。從長遠來看,這可以為您節省大量時間和麻煩。
以上是Go 中「mime」包的不確定性:信任但驗證的詳細內容。更多資訊請關注PHP中文網其他相關文章!