Wu Xianzhi API遷移指南
API 轉接站遷移指南:從 OpenAI、OpenRouter 切換至無審查 API
如果你的專案目前使用的是 OpenAI、OpenRouter 或某個 API 轉接站,想換到不會拒答合法需求的無審查 API,其實只需要修改三項設定:base_url、金鑰與模型名稱。本文先釐清轉接站與專用無審查模型的差異,再提供參數對照表、使用環境變數並行運行新旧接口的寫法、上線前的切換清單,以及遷移時最容易遇到的幾個陷阱。
更新於
重點
- 轉接站轉售的仍是原廠模型,內容策略不變;專用無審查模型才能解決拒答問題
- 遷移僅修改三處:base_url 設為 https://api.wuxianzhiapi.com/v1,密钥,模型名 uncensored
- 不支援 embeddings、圖片、音訊與微調,這些功能請繼續使用原服務
- 使用環境變數進行灰度切換,若出現問題,修改一個變數即可回退
API 轉接站與專用無審查模型有何差異
先釐清概念,否則遷移時容易選錯方向。常見的 API 轉接站,本質上是將大廠模型的呼叫額度轉售或聚合,對外提供一個 OpenAI 相容的地址,讓你使用相同的 SDK 切換不同的模型。它解決的是「存取與付費」的問題,例如統一入口、統一帳單,但模型本身仍是原來的那一個,原廠的內容策略一條不少:該拒絕的話題照樣拒絕,換個轉接地址並不會改變這一點。
專用的無審查模型是另一回事。它不是轉發別人的模型,而是一個單獨提供的模型,合法的成人內容、虛構創作與具爭議的話題不會被拒答。Wu Xianzhi API 只提供一個模型,模型名稱為 uncensored,介面相容 OpenAI 格式,因此遷移成本很低,但它也有清楚的邊界:僅處理文字,不支援圖片、音訊、向量與微調;涉及未成年人的性內容無論是否虛構都會被攔截,返回 403。
因此遷移前先問自己:我遇到的問題是「接口不穩、價格貴」,還是「模型總是拒絕我的合法需求」?如果是後者,更換轉接站意義不大,換到專用無審查 API 才對症。許多團隊的做法是兩者並存:通用任務繼續走原接口,需要無審查輸出的請求單獨路由至此,後文會說明具體做法。
從 OpenAI 或 OpenRouter 遷移,需修改的三個地方
無論原用 OpenAI 官方、OpenRouter 或轉接站,只要代碼使用 OpenAI 相容 SDK,只需改三項:base_url 改為 https://api.wuxianzhiapi.com/v1;api_key 換成 /get-api-key/ 取得的金鑰;model 統一寫 uncensored。無其他模型可選,GET /v1/models 僅此一個。
import os
from openai import OpenAI
messages = [{"role": "user", "content": "你好"}]
# 迁移前(示意):
# client = OpenAI(api_key=os.environ["OLD_API_KEY"], base_url="旧地址")
# resp = client.chat.completions.create(model="旧模型名", messages=messages)
# 迁移后:只动 base_url、api_key、model 这三处
client = OpenAI(
base_url="https://api.wuxianzhiapi.com/v1",
api_key=os.environ["WUXIANZHI_API_KEY"],
)
resp = client.chat.completions.create(model="uncensored", messages=messages, max_tokens=100)
print(resp.choices[0].message.content)Node.js 同理,將 new OpenAI({...}) 中的 baseURL 與 apiKey 換掉。如果你的專案是直接發送 HTTP 請求的,將請求地址改為 https://api.wuxianzhiapi.com/v1/chat/completions,請求頭保持 Authorization: Bearer <金鑰> 即可。完整的 Python、Node.js、cURL 寫法可對照 程式碼範例。
curl https://api.wuxianzhiapi.com/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $WUXIANZHI_API_KEY" \
-d '{"model":"uncensored","messages":[{"role":"user","content":"你好"}],"max_tokens":50}'
參數對照:哪些可用,哪些不適用
下表整理遷移時最常碰到的欄位。原則是:對話相關的、OpenAI 格式的核心欄位都可以照常使用;與「其他模型、其他模態」相關的功能,此處沒有。
| 原本的用法 | 在此處如何處理 |
|---|---|
model(如各種 gpt 型號) | 必須改為 uncensored |
messages(system / user / assistant / tool) | 格式一致,直接使用 |
max_tokens | 預設 2048,最大 32,000;超過會報 400 |
stream: true | 支援,最後自動追加一個用量區塊 |
tools / tool_choice | 支援,OpenAI 格式 |
| 上下文長度 | 提示詞加輸出合計 100,000 tokens |
| 請求體大小 | 不超過 8 MB |
| 速率 | 每個金鑰每分鐘 300 次請求 |
| 向量 embeddings | 不支援 |
| 圖片生成 / 識圖、語音、影片 | 不支援,僅處理文字 |
| 微調 fine-tuning | 不支援 |
| 切換多個模型 | 只有一個模型,沒有可切換的清單 |
表格中未列出的其他可選欄位,不要預設它們都會按原廠的方式生效。穩妥的做法是在測試環境裡單獨跑一遍,確認行為符合預期再上線,具體支援情況以 介面文件 為準。
沒有的能力怎麼辦:向量、圖片、語音的替代思路
如果你原本的專案同時用了對話和向量檢索,遷移時不要想著「全部換過來」。這裡只提供文字對話,所以 embeddings 相關的程式碼,比如知識庫檢索、語意去重,需要繼續使用你原本的向量服務,或者換成自己部署的向量方案。對話部分換到這裡,檢索部分保持不動,兩邊互不影響,這是最省事的拆法。
圖片、語音同理。比如你的產品是「文字加配圖」的形態,文字生成可以走這裡,配圖繼續用原本的圖片介面;需要語音播報的,文字生成之後再交給你已有的語音服務。把「生成文字」這一步單獨抽成一個函式,後面無論怎麼組裝其他能力,改動面都會很小。
還有一種情況是你的程式碼裡用了多個模型分工,比如便宜的模型做分類、貴的模型做創作。這裡只有一個模型,分類任務也要由它來做。好在輸入單價是 $0.25 / 百萬 token,做分類這種輸出很短的任務成本很低,把 max_tokens 設小,成本基本可以忽略。價格細節見 價格頁。
並行執行:用環境變數在兩套介面間切換
遷移最怕的是「一刀切」。更穩的做法是在程式碼裡做一層很薄的封裝,用環境變數決定走哪一個介面,這樣可以先讓一小部分流量或者一部分功能走新介面,出了問題改一個變數就能退回去。因為兩邊都是 OpenAI 相容格式,封裝非常簡單。
import os
from openai import OpenAI
PROVIDERS = {
"old": {
"base_url": os.environ.get("OLD_BASE_URL", ""),
"api_key": os.environ.get("OLD_API_KEY", ""),
"model": os.environ.get("OLD_MODEL", ""),
},
"wuxianzhi": {
"base_url": "https://api.wuxianzhiapi.com/v1",
"api_key": os.environ.get("WUXIANZHI_API_KEY", ""),
"model": "uncensored",
},
}
def get_client(name=None):
name = name or os.environ.get("LLM_PROVIDER", "old")
cfg = PROVIDERS[name]
return OpenAI(base_url=cfg["base_url"], api_key=cfg["api_key"]), cfg["model"]
def chat(messages, provider=None, **kwargs):
client, model = get_client(provider)
return client.chat.completions.create(model=model, messages=messages, **kwargs)
# 通用任务走旧接口,需要无审查输出的请求显式指定新接口
resp = chat([{"role": "user", "content": "写一个黑色幽默的短故事"}],
provider="wuxianzhi", max_tokens=800)
print(resp.choices[0].message.content)切換粒度可以有三層:按環境(測試環境先切)、按功能(只把創作類介面切過來)、按使用者(灰度一部分帳號)。無論哪一層,都建議把日誌裡記錄的 provider 欄位留下,出現差異時才能對照排查。對話歷史也建議統一存成標準的 messages 陣列,這樣同一段會話可以在兩邊之間無縫接著聊。
切換清單
上線前按下面的順序過一遍,基本不會漏項:
- 在 /get-api-key/ 註冊,拿到金鑰,用 $0.50 試用額度(7 天內有效)做驗證,不需要先儲值。
- 用
curl /v1/models確認金鑰有效、網路可達。 - 把
base_url、api_key、model三項改成環境變數驅動,金鑰不進程式碼倉庫。 - 搜尋一遍程式碼裡寫死的模型名、
max_tokens數值和 embeddings 呼叫。 - 檢查串流處理程式碼,相容最後一個
choices為空的用量區塊。 - 給 429 和 503 加指數退避重試,給 402 和 403 加明確的提示分支。
- 用你真實的提示詞跑一批回歸範例,重點看原來被拒答的那部分是否正常輸出。
- 先灰度小比例流量,對比用量和延遲,沒問題再擴大。
- 確認產品面向的是成年使用者,並且用途合法,這是使用本介面的前提。
遷移中最常見的幾個坑
模型名忘了改。舊程式碼裡的 gpt 型號或某個聚合平台的模型路徑原樣發過來,會得到錯誤回應。全域搜尋模型名,確保最終發出去的是 uncensored。
max_tokens 超限。有些專案為了讓模型寫得長,把 max_tokens 設到 32000 甚至更大,在這裡單次最大是 32,000,超過會返回 400。另外,提示詞加 max_tokens 不能超過 100,000 token,輸入很長的請求要相應調小輸出上限。
串流用量區塊。串流結束前伺服器會自動追加一個帶 usage 的區塊,它的 choices 是空陣列。如果你的解析程式碼写成 chunk.choices[0] 直接取值,就會在最后一步報錯。有些舊程式碼還會手動傳 stream_options 去要用量,在這裡不需要。
把「無審查」當成「無邊界」。合法的成人內容、虛構和爭議話題不會被拒絕,但涉及未成年人的性內容始終攔截,包括虛構和角色扮演,返回 403 content_blocked。產品需要自己做好成年使用者的准入。
餘額與試用到期。試用額度 7 天後失效,餘額用完后會收到 402,錯誤碼是 no_credit。在應用程式裡把這個錯誤翻譯成使用者能看懂的提示,而不是籠統的「服務出錯」。具體場景設計可以參考 應用場景 一文。
常見問題
遷移之後原本的提示詞還要重寫嗎?
格式不用改,messages 結構完全一致。但原來為了繞過拒答而寫的那些「越獄式」鋪墊可以刪掉,直接寫清楚角色和任務,既省 token 也更穩定。
遷移期間能不能新舊介面同時保留?
可以,而且推薦這樣做。用環境變數決定 base_url、金鑰和模型名,先讓部分功能或部分使用者走新介面,出了問題改一個變數就能退回。
舊介面裡的 embeddings 呼叫換過來會怎樣?
這裡沒有 embeddings 介面,請求會返回 404。向量檢索部分請繼續使用原來的服務,只把對話請求切過來。
怎麼判斷遷移後效果有沒有變好?
取一批原本被拒答或被改寫過的真實提示詞進行回歸對比,記錄拒答率、回覆長度以及 usage 中的 token 數。樣本應來自你自己的業務,而非網路上的通用測試集。