dsh-llm-gate: DeepSeek Harness 单模型提供商并发门控插件

前言

在使用 DeepSeek Harness(DSH)进行模型推理时,如果底层模型服务(例如开启 --parallel 1 的 llama.cpp)无法同时处理多个请求,多余的请求会被服务端直接丢弃。客户端无法区分是“正在等待槽位”还是“服务已死”,导致 Node HTTP 层在 300 秒后报错 terminated。这种问题常在子代理与主代理或压缩与代理请求重叠时发生。

dsh-llm-gate 旨在解决上述问题。它通过在 DSH 进程内部维护一个 FIFO 队列,将多余的请求暂存起来,直到模型服务腾出槽位后再发出 HTTP 请求。这避免了请求在等待期间因超时而被丢弃,确保请求有序处理。

核心功能

  • 按提供商并发控制:针对特定的模型提供商设置并发上限。
  • 请求队列管理:通过 FIFO 队列暂存超出并发上限的请求。
  • 全链路覆盖:挂钩 llm/stream waterfall,覆盖代理、子代理、压缩和标题生成等所有模型请求场景。
  • 错误处理:处理队列满(QUEUE_FULL)和超时(QUEUE_TIMEOUT)等错误状态。

安装与启用

使用官方安装命令将插件添加到指定配置文件(例如 web):

dsh plugin --profile web add dsh-llm-gate

安装完成后,需要重启 dsh web 并打开新会话以使配置生效。可以通过以下命令验证配置是否正确加载:

dsh --profile web --dump-config

配置示例

在 ~/.dsh/profiles/web/cordis.patch.yml 文件中添加配置。这里的 providers 键对应的名称应与你的 llm-pi-ai.providers(或其他适配器)设置中的路由名称一致。未列出的提供商不受此插件控制。

- id: llm-gate
  config:
    providers:
      llamacpp:
        maxConcurrent: 1
        maxQueued: 16
        queueTimeoutMs: 3600000

配置项说明

配置项 必填 说明
maxConcurrent 是 允许同时向该提供商发出的请求数。对于 llama.cpp,请将其值与 --parallel 参数保持一致。
maxQueued 否 允许在队列中等待的请求数。超过此数量,新请求会立即失败,报错 QUEUE_FULL。默认为无限制。
queueTimeoutMs 否 请求等待槽位的最大时长。超过此时间将失败,报错 QUEUE_TIMEOUT。默认为无限等待。

日志输出

该插件会在 DSH 终端输出以下日志,用于监控请求的排队和调度情况:

  • 排队时:显示当前请求进入队列以及队列深度。
    llm-gate: llamacpp session=a61e6e40 queued (depth 1)
  • 调度时:显示请求在等待一段时间后被分发。
    llm-gate: llamacpp session=a61e6e40 dispatched after 5730ms
  • 辅助请求:带有 purpose=compaction 或 purpose=session-title 的请求也会被记录。

注意事项

  • 串行化限制:该插件会对请求进行串行化处理,因此它不会让单槽服务器处理速度变快。若需提升性能,需给 llama.cpp 增加槽位(如 --parallel 2 --kv-unified),并相应提高 maxConcurrent。
  • 超时机制:等待时间不计入适配器的 streamIdleTimeoutMs,因为适配器在获取槽位前不会被调用。仍需根据提示处理时间设置足够的 streamIdleTimeoutMs。
  • 请求取消:队列中的请求通过 abort signal 取消。如果在未取消流的情况下丢弃流,该请求会一直停留在队列中,直到槽位释放后立即分发并关闭。
  • 依赖要求:插件需要 llm 服务,并挂钩 llm/stream waterfall。

生态与许可

DSH 的插件生态强调模块化与可扩展性,dsh-llm-gate 作为其中的一员,为处理高并发下的单槽模型服务提供了可控的队列管理机制。

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

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

小夜