iT邦幫忙

2026 iThome 鐵人賽

DAY 14
0
AI Engineering

《矽墟》:我把一部科幻小說當成軟體專案來管系列 第 14

Day 14|參考圖怎麼傳給外部服務:我選了看起來比較笨的那條

  • 分享至 

  • xImage
  •  

模組三|AI 生圖與生片產線(Day 10–19)

昨天講內容審核誤判。今天講一個更基礎、但每個人接圖像 API 都會遇到的問題:

你的圖在本機,服務在雲端。中間那一步怎麼走?

問題:兩條路,第一直覺會選錯的那條

我要把兩張參考圖(角色三視圖 + 立繪)交給生成服務。它提供兩種方式:

方式 做法
media_upload 跟服務要一組上傳憑證/簽名 URL,把 binary 傳上去,拿到一個 media id
media_import_url 你給一個公開可存取的圖片 URL,服務自己去抓

第一直覺是選 media_upload。它「比較正式」:檔案直接從我這裡到它那裡,不經過第三方,看起來比較乾淨。

我最後選了 media_import_url:把圖丟到自己的靜態站部署上當圖床,然後給 URL。

理由有兩個,第二個才是重點。

理由一:簽名上傳流程的步驟比較多

media_upload 的典型流程是三段:

  1. 呼叫 API 要一組簽名上傳位址
  2. 把 binary PUT 上去
  3. 拿回 media id,再帶進生成請求

三個步驟、三個可能失敗的地方,而且簽名通常有時效。中間任何一步出錯,你要判斷是憑證過期、還是傳輸中斷、還是 id 沒對上。

media_import_url 只有一步:把 URL 字串放進請求裡。

我本來就有一個靜態站部署(那是專案的角色頁),圖放進去 push 一下就有公開網址。這個基礎設施已經存在,所以邊際成本是零。

理由二:我可以先驗證服務會拿到什麼

我把長柄鏡伸到牆的另一邊,先看它會拿到什麼,才決定放不放手

這才是真正的差別。

用 URL 的話,我可以在送出生成請求之前做這件事:

# 本地檔案的 hash
shasum -a 256 assets/turnarounds/char-chenger-turnaround.png

# 服務將會抓到的東西的 hash
curl -sL "https://<我的靜態站>/char-chenger-turnaround.png" | shasum -a 256

兩個 hash 一樣,我就知道:服務去抓的時候,拿到的跟我本機這張是同一個 byte 序列。

不一樣的話,我立刻知道問題在傳輸/部署/快取,而不是在生成階段。

media_upload 就很難做這件事。圖傳上去之後變成一個 media id,你沒有辦法簡單地把它抓回來比對,它進了一個你看不到的地方。

為什麼這件事值得在意

因為圖像生成是一個回饋很慢、很貴、而且結果本來就有隨機性的操作。

假設生成結果不對。可能的原因有:

  1. 參考圖根本沒傳對(傳錯檔、傳到舊版、傳輸截斷)
  2. 參考圖傳對了,但 prompt 沒寫好
  3. 兩者都對,模型就是這樣

這三種的處理方式完全不同,而第 1 種是最蠢、最容易發生、也最容易被忽略的。

hash 比對可以在花錢之前把第 1 種完全排除掉。剩下的排查範圍就小很多。

昨天 Day 13 那個 NSFW 誤判,我繞了四次遠路的原因就是輸入清單沒被逐項確認。能夠事前驗證的輸入,就該事前驗證掉。

這是一個很常見的取捨模式

我把看得見裡面的那個箱子舉過頭,同時一腳把黑箱踢到旁邊

回頭看,這個選擇的形狀在別的地方一直出現:

封閉通道 開放通道
例子 簽名上傳、私有 bucket、二進位協定 公開 URL、明文設定檔、REST + JSON
好處 安全邊界清楚、不需要對外曝露 中間狀態可以被檢查
壞處 出事時你看不到中間發生什麼 東西是公開的

可觀測性和封閉性是互相衝突的。

我選開放通道,是因為在這個場景裡我最痛的是排查成本,而不是保密。但這個判斷會隨場景反轉,下面就講它的代價。

代價

代價一:那些圖是公開的。

這是最實在的代價,必須講清楚。

media_import_url 要求 URL 公開可存取,服務端要能匿名抓到它。也就是說,任何拿到網址的人都看得到那張圖。

對我來說這可以接受,因為那些角色圖本來就會出現在公開的角色頁上。但如果是還沒公開的設計、客戶的素材、或任何有保密需求的東西,這條路直接出局。

判準很簡單:這張圖如果現在被陌生人看到,會不會有問題? 會的話,走簽名上傳,接受排查困難。

代價二:多了一個依賴。

生成請求現在依賴我的靜態站活著。部署掛了、網址改了、檔案被清掉,生成就會失敗,而且錯誤訊息會是生成服務那邊回報的「抓不到圖」,不是我這邊。

我把一個單向的操作,變成了一個需要兩個系統同時正常的操作。

代價三:快取。

我踩過一次:換了圖但沿用同一個檔名,CDN 還在服務舊的那張,於是生成結果一直是舊角色。

hash 比對正好抓得到這件事,這也是我後來養成先比對的習慣的原因。但如果沒比對,這種錯誤會偽裝成「模型不聽話」。

帶走什麼

一、接外部服務時,優先選「中間狀態可以被檢查」的通道

尤其是當這個操作很貴、很慢、或結果有隨機性的時候。

因為在這種操作裡,「輸入到底對不對」的排查成本特別高,你不能靠重跑幾次來確認。

判斷句:如果結果不如預期,我能不能證明輸入是對的?

證明不了的話,你每次排查都要把「輸入可能沒傳對」放在可能性清單裡,而它會污染你所有的推論。

二、能事前驗證的,不要留到事後排查。

hash 比對只要一行 curl | shasum,但它把一整類問題永久排除了。

一般化:任何「送出去之前可以確認」的東西,都值得花那三十秒。 送出去之後才發現,你要付的是整趟往返的成本。

三、可觀測性 vs 封閉性是真的要選一個。

不要以為有兩全其美的方案。封閉的通道就是看不到裡面,開放的通道就是東西會曝露。

選的方法是問:在這個專案裡,我比較常付哪一種代價?

  • 常常在排查「到底傳了什麼」→ 選可觀測
  • 資料一旦外流就完蛋 → 選封閉,然後另外投資在日誌與校驗上

我這個專案是前者,所以選了看起來比較笨的那條。換一個保密要求高的專案,我會選相反的。


明天 Day 15,講換模型之後留下的爛攤子:不同模型的輸出解析度不一樣,怎麼統一。 我的鏈是「先超過再縮回去」:1k 出圖 → 放大到 2k(實出遠超過)→ 本地縮到統一規格。以及一個維護技巧:檔名沿用舊名,讓下游的 HTML 一行都不用改。


上一篇
Day 13|同一個 prompt 連 4 次被判 NSFW,改寫措辭完全沒用
下一篇
Day 15|先放大再縮小的解析度補齊鏈,以及它其實沒解到問題
系列文
《矽墟》:我把一部科幻小說當成軟體專案來管16
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言