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

这里的 41540dsh-openai-gateway 的默认端口,不是 DSH 官方约定。

如果端口被占用,插件会记录 FATALstate.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 客户端的解析。

反向代理

默认 host127.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 官方约定。
  • port0 时随机分配端口,实际值以 state.json 为准。
  • 粘性会话有簿记上限,默认 maxSessions16
  • 单轮超时默认 300 秒,超时后会取消 Agent 并返回 504
  • workspace.cwd 默认为空,此时使用 $DSH_HOME/openai-gateway/workspace

当前版本为 v0.1.1,针对 DSH 0.1.1-rc.2 实现并测试,属于开发者预览,暂无兼容承诺。

已知限制包括:

  • tool_calls 不投影为 OpenAI 工具调用帧
  • 请求体中的 toolstool_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

目录页以实际可访问地址为准。

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

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

Xiaoye