dsh-openai-gateway:把 DSH Agent 暴露爲 OpenAI 兼容 API

前言

DSH 的插件生態會把不同能力拆成可安裝的組件。dsh-openai-gateway 解決的是一個很具體的問題:OpenAI 客戶端通常只調用 /v1/chat/completions、/v1/models 這類標準端點,而 DSH Agent 會話背後還帶有工具和工作區。

這個插件把 DeepSeek Harness(DSH)暴露成 OpenAI 兼容 API 服務端:客戶端配置 base_url 和 API key 後,就可以調用 DSH 的真實 Agent 會話。下面介紹它的功能、安裝方式、典型用法和注意事項。

這是什麼

dsh-openai-gateway 是 backrooms-yrc 維護的 DSH 插件,當前介紹版本爲 v0.1.1,許可證爲 MIT。

它提供的核心端點包括:

  • POST /v1/chat/completions,支持流式和非流式
  • GET /v1/models
  • GET /v1/models/:id
  • GET /healthz,免鑑權探活

每次 API 調用背後是帶工具、帶工作區的真實 DSH Agent 會話。插件自帶獨立 HTTP 監聽和 Bearer 鑑權,API key 未配置時,首次啓動會生成一個 key,並以 0600 權限落盤。

安裝與啓用

先安裝插件:

dsh plugin --profile web add github:backrooms-yrc/dsh-openai-gateway#v0.1.1

首次新增包需要重啓一次 dsh web。重啓後,查看實際監聽狀態:

cat $DSH_HOME/openai-gateway/state.json

再查看 API key:

cat $DSH_HOME/openai-gateway/api-keys.json

DSH_HOME 默認是 ~/.dsh;如果通過環境變量自定義了 DSH_HOME,以實際目錄爲準。

API key 未配置時,插件首次啓動會自動生成,並寫入:

$DSH_HOME/openai-gateway/api-keys.json

文件權限爲 0600。

探活端點不需要鑑權:

curl http://127.0.0.1:41540/healthz

端口與監聽

默認監聽地址是:

127.0.0.1:41540

這裏的 41540 是 dsh-openai-gateway 的默認端口,不是 DSH 官方約定。

如果端口被佔用,插件會記錄 FATAL,state.json 不會更新,/healthz 也會不通。此時更換端口即可。

也可以把 port 設爲 0,讓操作系統隨機分配端口。隨機端口分配後,實際端口會寫入:

$DSH_HOME/openai-gateway/state.json

配置參考

下面列出的配置項都以插件默認值爲參考:

鍵 默認值 說明
host 127.0.0.1 默認只綁定迴環地址
port 41540 監聽端口;設爲 0 時隨機分配,實際值見 state.json
sessionMode both 同時支持無狀態會話和粘性會話;設爲 stateless 時拒絕粘性會話請求
maxSessions 16 粘性會話簿記上限,使用 LRU 策略
timeoutSeconds 300 單輪超時時間;超時後取消 Agent,並返回 504
workspace.cwd 空字符串 Agent 工作目錄;爲空時使用 $DSH_HOME/openai-gateway/workspace

發起第一次調用

把 $KEY 替換爲 api-keys.json 中的 key,把 $PORT 替換爲 state.json 中的端口:

curl http://127.0.0.1:$PORT/v1/chat/completions \
  -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -d '{"model":"default","messages":[{"role":"user","content":"你好"}]}'

model 支持三種寫法:

  • default:跟隨 DSH 當前默認模型
  • provider/model:精確路由到指定供應商和模型
  • 裸模型名:對照 DSH 目錄自動匹配供應商

完整模型列表可以通過 GET /v1/models 查詢。

會話模式

默認情況下,插件支持無狀態會話,也支持粘性會話。

無狀態會話的特點是:請求裏的 messages 被拼成一條 prompt,回合結束後會話即銷燬,適合普通 OpenAI 客戶端直接接入。

粘性會話適合多輪連續任務。第一輪請求帶:

X-DSH-Session: new

或者在請求體擴展字段中寫:

"dsh_session": "new"

響應會返回 dsh_session_id。後續請求攜帶這個 id,即可複用同一個 Agent 會話。

示例:

curl -X POST http://127.0.0.1:$PORT/v1/chat/completions \
  -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -H "X-DSH-Session: new" \
  -d '{"model":"default","messages":[{"role":"user","content":"記住一個詞:藍鯨"}]}'

記錄響應中的 dsh_session_id。第二輪只發新的 user 消息:

curl -X POST http://127.0.0.1:$PORT/v1/chat/completions \
  -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -H "X-DSH-Session: openai-..." \
  -d '{"model":"default","messages":[{"role":"user","content":"剛纔讓你記住的詞是什麼?"}]}'

如果 sessionMode 設爲 stateless,粘性會話請求會被拒絕。

OpenAI 客戶端接入

任何 OpenAI 客戶端只需要配置 base_url 和 API key。

Python 示例:

from openai import OpenAI

client = OpenAI(
    base_url="http://127.0.0.1:41540/v1",
    api_key="sk-dsh-...",
)

resp = client.chat.completions.create(
    model="default",
    messages=[{"role": "user", "content": "你好"}],
)

print(resp.choices[0].message.content)

流式響應也支持推理模型的思考增量,字段爲 delta.reasoning_content,風格接近 DeepSeek。

stream = client.chat.completions.create(
    model="default",
    stream=True,
    messages=[{"role": "user", "content": "解釋一下 SSE"}],
)

for chunk in stream:
    delta = chunk.choices[0].delta

    reasoning = getattr(delta, "reasoning_content", None)
    if reasoning:
        print("[思考]", reasoning, end="", flush=True)

    if delta.content:
        print(delta.content, end="", flush=True)

擴展字段與工具調用

插件會在響應中提供擴展字段:

  • dsh_session_id
  • dsh_tool_calls

工具調用在 SSE 流中以註釋幀呈現:

: dsh tool-call <name>

這些擴展字段不破壞標準 OpenAI 客戶端的解析。

反向代理

默認 host 是 127.0.0.1,只綁定迴環地址。如果要對外提供服務,建議通過反向代理暴露,並由反向代理處理 TLS。

以 nginx 爲例,至少需要代理 /v1/,並關閉 SSE 緩衝:

location ^~ /v1/ {
    proxy_pass http://127.0.0.1:41540;
    proxy_buffering off;
}

其中 41540 應以 state.json 中的實際端口爲準。

之後客戶端可以把 base URL 配置爲:

https://你的域名/v1

適用場景與注意

這個插件適合已經在使用 DSH,並希望把 DSH Agent 接入 OpenAI SDK、腳本或其他 OpenAI 兼容客戶端的場景。

使用前需要注意:

  • 插件會加入 dsh web 的運行環境,並以當前 DSH 進程權限運行;安裝前建議先檢查源碼和 MIT 許可證。
  • 默認只監聽迴環地址,對外部署建議走反向代理。
  • 默認端口 41540 是本插件默認值,不是 DSH 官方約定。
  • port 爲 0 時隨機分配端口,實際值以 state.json 爲準。
  • 粘性會話有簿記上限,默認 maxSessions 爲 16。
  • 單輪超時默認 300 秒,超時後會取消 Agent 並返回 504。
  • workspace.cwd 默認爲空,此時使用 $DSH_HOME/openai-gateway/workspace。

當前版本爲 v0.1.1,針對 DSH 0.1.1-rc.2 實現並測試,屬於開發者預覽,暫無兼容承諾。

已知限制包括:

  • tool_calls 不投影爲 OpenAI 工具調用幀
  • 請求體中的 tools 和 tool_choice 會被忽略
  • 沒有按 key 的配額或限速
  • maxSessions 是粘性會話簿記上限,被逐出的舊 Agent 由 DSH 註冊表按自身策略回收

如果通過本地路徑或 link 方式安裝,插件不會自動安裝 peer 依賴。需要自行保證以下包可解析:

@deepseek-ai/dsh-agent
@deepseek-ai/dsh-llm
@deepseek-ai/dsh-session
@deepseek-ai/dsh-home-paths
@deepseek-ai/schemastery

結尾

dsh-openai-gateway 的價值在於:它把 DSH Agent 的會話、工具和工作區能力包裝成標準 OpenAI 端點。只要配置 base_url 和 API key,OpenAI 客戶端就可以發起調用,而每次調用背後是真實的 DSH Agent 會話。

代碼倉庫:

https://github.com/backrooms-yrc/dsh-openai-gateway

插件線索給出的目錄頁:

https://www.skillhub.cn/plugins/backrooms-yrc/dsh-openai-gateway

目錄頁以實際可訪問地址爲準。

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜