
前陣子要在自己的應用里接入 AI 視頻生成能力我本以為最難的是“選哪個模型”結果打開三家視頻生成 API 的文檔發現光是“把請求發出去”這件事就能消耗掉一個下午A 平臺要求x-api-keyB 平臺要求Authorization: BearerC 平臺要求把密鑰放在 query 參數里請求體字段一個叫prompt另一個叫text還有一個叫input返回結果有的直接給視頻 URL有的只給一個 task_id 讓你輪詢。不同平臺的錯誤碼也各成體系一個 400 背后的原因可能差了十萬八千里。這種時候OpenRouter 視頻生成 API 就會顯得很有吸引力它用一套相對統一的協議幫你接多家模型把密鑰、模型路由、計費和大部分錯誤處理收斂到一個入口。但“聚合”不是萬能藥它只是把“接入多家模型”這件事變成“接入一個網關”后面還有配額、超時、異步任務、內容合規和工程化落地這些硬問題。這篇文章我想從代碼接入的角度按“先跑通、再處理異常、最后工程化”的順序把整個過程拆開講一遍。1. 先搞清這類 API 聚合平臺到底幫你省了什么1.1 為什么多模型接入會變成一場適配噩夢如果你只接一個模型直接看那一家文檔就夠了。真正麻煩的是你要在同一個產品里比較兩家、三家的視頻生成效果或者你想做一個“用戶可以選不同模型”的功能。這時候每個模型的接入方式不同會帶來兩倍的重復勞動。我經歷過一個很典型的場景上游供應商臨時說某個模型要下線我需要快速切到另一個模型。如果是直連我得重新讀文檔、改鑒權頭、改請求體字段、改響應解析邏輯、重新測試。如果是走 OpenRouter 這類網關大部分時候只需要換一個model參數其他代碼可以保持不變。這個“改動成本”的差距才是聚合平臺最核心的價值。但這里要說清楚OpenRouter 并不是把每個模型的能力都統一成完全相同的樣子。視頻生成模型天然存在差異有的支持圖生視頻有的只支持文生視頻有的限制了視頻時長有的必須異步輪詢。聚合層可以把“請求如何鑒權、如何計費、如何返回標準錯誤”統一起來但不可能把模型的底層能力差異也抹平。1.2 OpenRouter 的“代碼優先”意味著什么“代碼優先”不是官方術語是我自己更偏愛的一種接入姿勢不做太多圖形界面配置先用 curl 調通一次請求再用 Python 封裝成函數最后再接入業務邏輯。這種姿勢的好處是每一步都能被版本管理、被測試、被回滾。從實際使用看OpenRouter 的 API 風格接近 OpenAI 的 chat completions 協議這讓很多已經寫過 OpenAI 接口的開發者上手非常快。代碼里你需要的核心要素就三樣接口地址、API Key、模型名。其他都是圍繞這三個要素的參數和數據格式。需要注意的是OpenRouter 聚合的是“能通過 API 訪問的模型”如果你在模型列表里沒有看到視頻生成相關模型那可能是賬號權限、地區或模型上架情況導致的。接入前一定要先打開官方模型列表確認而不是憑熱搜詞里的“MiniMax H3”“DeepSeek V4”等名字直接寫進代碼。2. 接入前必須確認的三件事賬號、額度、模型列表2.1 注冊、API Key 和充值的通用路徑OpenRouter 的注冊流程和大多數開發者平臺類似打開官網注冊賬號進入控制臺后創建 API Key。這個 Key 是你調用所有模型的統一憑證和直連各平臺時的“多把鑰匙”相比確實方便但也意味著一旦泄露別人可能拿著它去調用你賬號下的所有模型。所以我建議不要把 API Key 硬編碼在代碼里使用環境變量。在.env文件中保存 Key并確保該文件被.gitignore忽略。創建 Key 時如果平臺支持權限范圍或額度限制盡量開啟。至于充值OpenRouter 很多模型是按量計費的視頻生成模型通常比文本模型更貴。如果你只是測試先充一小筆錢不要一開始就開大額自動充值。不同模型的價格、計費單位按秒還是按次都可能不一樣具體以模型卡片和官方文檔為準。2.2 怎么判斷一個模型是否支持視頻生成OpenRouter 的模型列表頁一般會提供每個模型的說明、標簽和示例。想找視頻生成模型可以先搜索video、gen等關鍵詞。真正的判斷標準不是名字里有沒有“video”而是模型卡片里是否明確寫了輸入輸出支持視頻輸入是否支持prompt、image_url、duration、resolution等字段。輸出返回video_url、video_data還是只返回文字描述。是否異步視頻生成通常耗時較長如果響應里帶task_id說明需要輪詢。舉個例子熱搜詞里出現過 MiniMax H3 在 ComfyUI 里生成視頻時如何保持人物 ID 不變的問題。如果你真的想用某個模型做圖生視頻、保持人物一致性不要只看它“能不能生成視頻”還要關注它支不支持輸入參考圖、支持多少張、以及視頻時長上限。這些信息只能從模型文檔里確認OpenRouter 自身不一定會在統一請求層幫你補齊。2.3 把 Key 放進環境變量而不是硬編碼下面是一個常見的.env示例OPENROUTER_API_KEYsk-or-xxxx在 Python 里讀取import os API_KEY os.environ[OPENROUTER_API_KEY]這樣做的理由很簡單代碼一旦提交到倉庫密鑰就相當于公開了。很多人被自動抓取 GitHub 的爬蟲掃到 Key然后發現賬單暴漲問題往往就是硬編碼造成的。3. 用 curl 跑通第一個視頻生成請求3.1 先搭一個最小請求體我不建議一開始就去看復雜參數。先構造一個最簡單的請求能返回結果就行。下面是一個用 curl 調用的示意結構curl -X POST https://openrouter.ai/api/v1/chat/completions \ -H Authorization: Bearer $OPENROUTER_API_KEY \ -H Content-Type: application/json \ -d { model: some-provider/video-model, messages: [ {role: user, content: 生成一段10秒的短視頻主題是城市夜景} ] }注意上面的model是占位符具體模型 ID 以 OpenRouter 控制臺里實際顯示的為準。如果該模型在 OpenRouter 上使用的是獨立的視頻生成端點那么請求 URL 也可能不同一切以官方文檔為準。這里要解釋一下視頻生成模型可能也復用 chat completions 格式因為這種格式可以傳遞文本指令也可能有專門的/video/generations端點。無論哪種Minimal Request 的原則是一樣的先不要加thinking_budget、resolution、duration這些擴展參數減少變量跑通后再逐步加。3.2 識別同步響應和異步任務視頻生成和文本生成最大的區別在于一個 HTTP 請求很難等完整個視頻渲染過程。所以大概率會遇到兩種響應模式同步模式請求一直掛起直到視頻生成完畢響應中直接包含video_url。異步模式請求很快返回響應中包含一個任務 ID例如task_id你需要輪詢另一個狀態接口直到任務完成。如果你看到響應里返回了一個 URL先判斷它是不是最終視頻地址。有些平臺會先返回一個“占位”任務 URL需要等狀態變為 succeeded 之后才能真正訪問。假設是異步任務輪詢接口的示意結構類似curl -X GET https://openrouter.ai/api/v1/video/generations/{task_id} \ -H Authorization: Bearer $OPENROUTER_API_KEY輪詢時不要每 0.5 秒就請求一次太密集容易觸發速率限制也會給平臺造成不必要的壓力。常見做法是 2 到 5 秒一次配合最大輪詢次數。3.3 第一次跑通后的檢查清單第一次請求返回 200 并不代表完事。我一般會按這個清單檢查HTTP 狀態碼是 200/201還是 2xx 代表已接受響應體有沒有error字段有沒有id或task_id視頻文件如果不是直接給 URL而是給 base64需要確認體積別超過內存限制。視頻可訪問性URL 是否過期是否需要鑒權才能訪問計費字段有些響應當中會帶cost可以用于核對本次調用的費用。記錄下請求時間、模型、任務 ID、狀態碼和耗時這些信息在后續調試時非常關鍵。4. 把 curl 封裝成可復用的 Python 函數4.1 用 requests 寫一個最小的視頻生成函數一旦 curl 跑通就可以用 Python 固化。這里我用requests舉例因為它足夠簡單也容易替換成httpx或異步客戶端。import os import time import requests API_KEY os.environ[OPENROUTER_API_KEY] BASE_URL https://openrouter.ai/api/v1/chat/completions headers { Authorization: fBearer {API_KEY}, Content-Type: application/json, } def generate_video(prompt: str, model: str some-provider/video-model) - dict: payload { model: model, messages: [{role: user, content: prompt}], } response requests.post(BASE_URL, headersheaders, jsonpayload, timeout30) response.raise_for_status() return response.json()這里一個很容易踩的坑是timeout。視頻生成請求可能比普通聊天請求慢很多但也不能因此不設超時否則代碼會無限掛起。更合理的做法是把超時設置得比你的心理預期大一些比如 30 秒同時依賴異步任務機制而不是想著一個請求等到視頻渲染完。4.2 輪詢任務狀態與結果下載如果響應里包含task_id就需要寫一個輪詢函數def poll_generation(task_id: str, max_attempts: int 60, interval: int 5) - dict: status_url fhttps://openrouter.ai/api/v1/video/generations/{task_id} for attempt in range(max_attempts): response requests.get(status_url, headersheaders, timeout10) data response.json() status data.get(status) if status succeeded: return data if status failed: raise RuntimeError(data.get(error, generation failed)) time.sleep(interval) raise TimeoutError(ftask {task_id} timed out)拿到結果后如果里面是視頻 URL可以用requests.get(video_url, streamTrue)下載def download_video(url: str, save_path: str) - None: with requests.get(url, streamTrue, timeout30) as response: response.raise_for_status() with open(save_path, wb) as f: for chunk in response.iter_content(chunk_size8192): f.write(chunk)下載后可以用os.path.getsize(save_path)檢查文件大小避免下到一個空文件或錯誤頁。4.3 不要忽略異常處理與請求日志視頻生成 API 的失敗率往往比文本模型高因為它涉及計算資源調度、長時間任務、冷啟動等。如果只依賴raise_for_status()一旦上游返回 529 或連接中斷調用方只會看到一堆異常堆棧。一個可參考的做法是在調用前記錄一條日志包含模型、prompt 長度、請求時間調用后記錄 task_id、狀態、耗時、費用如果有異常時記錄錯誤類型和 response body。但要注意不要把完整 prompt 寫入日志尤其當 prompt 包含用戶隱私或業務敏感信息時。建議只記錄 prompt 長度或摘要。日志示例: [INFO] generate_video start modelsome-provider/video-model prompt_len42 ts... [INFO] generate_video task_created task_idxxx statuspending [INFO] generate_video success task_idxxx duration12.3 cost0.0002 [ERROR] generate_video failed task_idxxx error529 overloaded這才是代碼接入里真正值錢的部分不是調用成功而是失敗時你能快速定位是哪一層出了問題。5. 視頻生成 API 的典型錯誤和繞過思路5.1 529 overloaded 是什么意思很多 OpenRouter 使用者都遇到過api error: 529 overloaded. this is a server-side issue, usually temporary這樣的報錯。它表示服務端臨時過載不是你請求參數寫錯了也不是 API Key 失效了。處理方式不是立刻重試一萬次而是“后退重試”。常見做法是指數退避import time import random def request_with_retry(func, max_retries5, base_delay1): for attempt in range(max_retries): try: return func() except requests.HTTPError as exc: if exc.response.status_code 529 and attempt max_retries - 1: delay base_delay * (2 ** attempt) random.uniform(0, 1) time.sleep(delay) continue raise注意最大重試次數不要設得太高比如 5 到 6 次就夠了。如果超過這個次數還在 529大概率是平臺或模型提供方正在經歷較大故障再繼續重試只會浪費額度。5.2 connection lost mid-response 怎么辦另一個常見錯誤是api error: connection lost mid-response. the response above may be incomplete。它意味著客戶端和服務端之間的連接在響應過程中斷開了。排查順序應該是是不是網絡不穩定比如公司網絡、跨地域訪問。是不是請求設置了過短的讀取超時。模型生成時間較長網關在中間斷開了連接。是否啟用了流式輸出而流式讀取不穩定。對視頻生成這種長任務我更推薦優先使用異步任務模式而不是同步等待。因為同步等待一旦連接斷開你既拿不到結果也不知道任務是否還在后臺運行狀態變得不可控。異步任務至少能留下一個 task_id方便恢復查詢。5.3 400 參數錯誤先看響應體再改代碼400通常是請求體有問題比如熱搜詞里提到的thinking_budget parameter must be a positive integer就說明模型不支持這個非正整數的值。類似的錯誤還有上下文長度超限比如maximum context length is 1048576 tokens。處理這類參數錯誤時不要只看狀態碼要仔細讀響應體里的error.message。OpenRouter 作為網關往往會把上游模型返回的原始錯誤信息透傳出來這能幫你省很多事。如果確認是模型不支持的參數直接刪除該參數如果是上下文超長就對輸入做截斷或摘要。這里有一個建議盡量把“請求參數構造”和“業務參數”分開。你在代碼里定義自己的prompt、duration、resolution然后到一個適配層把業務參數轉換成模型真正接受的參數。這樣切模型時只需要改適配層而不是改所有業務代碼。5.4 速率限制和費用控制除了平臺可能限流模型提供方也可能有自己的配額。OpenRouter 統一了計費你可以在控制臺看到調用記錄和費用。但正因為“統一”你可能對每個模型的具體消耗沒那么敏感。我的做法是測試階段每個模型只跑少量樣本先估算成本。生產環境設置單次請求的預檢邏輯比如限制 prompt 長度、限制視頻時長。如果響應帶有cost字段記錄到日志定期核對賬單。下面是一個簡化的問題排查表錯誤現象可能原因優先排查項處理建議401 UnauthorizedAPI Key 無效或缺失檢查請求頭中的 Authorization重新生成 Key確認沒有多余空格400 Bad Request參數錯誤或模型不支持某字段讀取響應體 error.message去掉不支持參數裁剪超長輸入429 Too Many Requests觸發速率限制檢查近 1 分鐘請求頻率退避重試降低并發529 Overloaded服務端過載查看平臺狀態頁指數退避必要時切換模型connection lost mid-response連接中斷檢查 timeout 和網絡改用異步任務增加重試6. 適用邊界什么場景適合用 OpenRouter 視頻生成 API6.1 適合的人和團隊OpenRouter 這類聚合 API 最適合以下場景快速原型驗證你想比較三個視頻生成模型的效果不想每家都注冊一遍賬號。內部工具給團隊做一個“輸入描述生成視頻”的內部站點統一 API Key 和計費。個人開發者沒有精力維護多家平臺的 SDK希望用 OpenAI 風格接口快速接入。需要橫跨不同模型做自動切換的自動化流程。在這些場景里統一協議帶來的收益是實打實的代碼結構基本一致切換模型成本低賬單集中。6.2 不適合的場景聚合 API 不是銀彈。下面這些場景我建議你謹慎考慮對延遲極度敏感聚合網關會引入額外一跳而且長任務受排隊影響。數據必須留在內網視頻渲染通常涉及大量數據如果合規要求數據不能出境那就不適合。需要深度定制模型行為某些模型的私有參數、特殊采樣方式或者細粒度的回調不一定能在統一接口里完全暴露。超大批量任務如果每天要生成數萬條視頻聚合平臺的費率和限流可能不如和模型提供方直接簽合同劃算。另外OpenRouter 本身也受上游模型服務條款約束。如果一個模型在特定地區不可用或者上線/下線狀態有變化你可能會在某個時間點突然發現請求失敗。所以不要把聚合平臺當成“永不改變”的基礎設施關鍵業務一定要有模型降級方案。6.3 關于“無限制”“免審核”的誤區在熱搜詞里我留意到一些類似“無限制無審核生成視頻”的說法。這里必須說清楚無論在哪個平臺使用 AI 視頻生成能力都要遵守平臺服務條款、模型使用政策以及當地法律法規。所謂“無限制”“免審核”的軟件很多時候要么是假的要么本身就是違規甚至違法的工具開發者一旦接入風險極高。即使 OpenRouter 作為聚合層幫你屏蔽了部分差異它也不會幫你規避內容安全責任。如果生成內容涉及侵權、色情、暴力、詐騙等黑灰產場景責任始終在調用方。這也是我為什么強調“代碼優先”的另一層含義先把合規邊界寫進代碼比如 prompt 預檢、生成內容標記、用戶舉報機制而不是等出了事再補救。7. 當請求失敗時按這個順序排查7.1 先看現象和響應體遇到失敗第一件事不是改代碼而是記錄現場。你需要確認HTTP 狀態碼是多少。響應體里的error字段寫了什么。有沒有request_id或id可以用于追蹤。是第一次失敗還是穩定復現。如果響應體里只有一句“internal server error”那大概率是平臺側問題如果詳細說明了某個參數不合法那才是自己的問題。7.2 再查請求體和參數一旦確認是客戶端問題重點檢查這些項目model字符串是否和模型列表完全一致。messages或prompt字段是否為空、格式是否正確。是否傳了模型不支持的額外字段。是否少傳了必填字段比如圖片輸入時少了image_url。視頻時長、分辨率是否超出模型限制。這里最容易讓人困惑的是同一個請求換一個模型就能通過。這不是 OpenRouter 的問題而是模型之間的能力邊界不同。遇到 400先對照該模型的文檔做參數裁剪而不是盲目調整重試次數。7.3 然后查環境和網絡如果請求代碼本身沒問題網絡層也要排查。常見情況包括本機無法訪問openrouter.ai可能需要檢查 DNS 和網絡連通性。公司防火墻或安全軟件攔截了長連接。本地代理環境導致請求被路由到異常節點。容器部署時未正確設置網絡代理或HTTPS_PROXY環境變量殘留。排查時可以用一個最簡單的文本模型接口測試如果文本模型接口正常視頻生成接口失敗那可能是視頻生成服務的狀態或參數問題如果連文本模型都失敗那大概率是網絡、Key 或賬戶問題。7.4 最后查賬戶、額度和模型狀態這一步容易被忽略尤其是在“項目昨天還能跑今天突然不行”的時候API Key 是否過期或被重置。賬戶余額是否不足。是否觸發了月度或分鐘的速率限制。模型是否下線、暫停或切換了版本。是否因為內容審核策略命中被平臺標記或限制。如果以上都沒有問題那就把日志里記錄的請求 ID 和錯誤信息發給平臺支持而不是憑感覺“換個 Key 再試一次”。收尾從一次 API 接入到一套可復用流程寫到這里你會發現這篇文章并沒有給出某個具體視頻模型的完整代碼因為 OpenRouter 模型列表和接口細節是會變化的。真正值得沉淀的是一套接入思路第一步最小跑通。用 curl 發一個最簡單的文字轉視頻請求確認鑒權、模型名、響應結構都正常不要在一開始就調一堆參數。第二步補齊異常處理。把 529、超時、參數錯誤、任務失敗這些常見情況逐個寫進代碼讓失敗變得可觀測、可恢復。第三步工程化落地。把 Key 放進環境變量把調用封裝成函數把日志和計費記錄接入你的監控體系再根據業務需求選擇異步隊列、并發控制和模型降級策略。這個框架不只適用于 OpenRouter也適用于任何視頻生成 API。聚合平臺能幫你省去重復適配的麻煩但真正決定一個功能能不能長期跑下去的是你對額度、錯誤、日志和合規邊界的掌控。如果你正在準備接入建議現在就打開模型列表找一個支持視頻生成的模型把第一段 curl 跑通。之后再看結果不遲。