用 deepseek-harness-acp 把 DeepSeek Harness 接到 Zed 等 ACP 客户端

前言

DeepSeek Harness(dsh)把智能体运行时拆成插件:模型、工具、技能、会话、沙箱、存储和界面都可以换。日常入口多半是 Web UI,例如 npx @deepseek-ai/dsh web。写代码时人却待在编辑器里,于是会出现一个具体问题:会话、工具调用、权限询问和 diff 审查都发生在浏览器,编辑器这边还要另开一套流程。

Agent Client Protocol(ACP)就是为这件事准备的协议。它由 Zed 发起,现在和 JetBrains 一起开放维护,定位接近「智能体版 LSP」:编辑器当客户端,智能体当子进程,双方用 JSON-RPC 走标准输入输出。Gemini CLI、Claude Agent、Codex CLI 已经能按这套协议接到编辑器里。DeepSeek Harness 自己也有一份官方包 @deepseek-ai/dsh-acp,但源码注释写得很清楚:那是给受信任程序客户端用的自动化通道,展示层和人机交互仍留在 Harness 自己的 UI。

社区插件 deepseek-harness-acp 走的是另一条路:把完整的 Harness 组合进程内拉起来,再把会话事件映射成编辑器能渲染的 ACP 词表。下面按插件目录页、GitHub README、package.json、LICENSE 和 npm 登记信息核对后整理:它是什么、和官方 ACP 包差在哪、怎么装、怎么接到 Zed。

这是什么

deepseek-harness-acp 是一款「开发与运行时」类 DeepSeek Harness 插件,维护者是 GitHub 组织 openma-ai。npm 包名是 @openma/deepseek-harness-acp,命令行入口是 dsh-acp。目录页一句话介绍是:「DeepSeek Harness 的 ACP(Agent Client Protocol)服务端实现。」仓库 README 写得更具体:从 Zed、Backchat 这类 ACP 客户端里使用 DeepSeek Harness。

它解决的不是「再做一个聊天窗口」,而是把已经在 dsh web 里配好的同一套运行时接到编辑器:

  • 适配器在进程内组装 Harness,而不是在外面再包一层 HTTP 代理。
  • 凭证不进编辑器配置。它复用 Web UI 写进 $DSH_HOME 的密钥,或用 dsh-acp login 写到同一份存储。
  • 会话、设置、预设和日志跟 dsh web 共用 $DSH_HOME。Web 里开过的对话,编辑器侧可以列出并加载。

许可证以仓库为准:LICENSEpackage.json 和 npm 登记都是 Apache-2.0。目录页把许可证标成 NOASSERTION,那是 GitHub 许可证探测没有识别出来,不是另有一份未声明协议。主要语言是 TypeScript,engines 要求 Node.js >=22.15。核对当日 GitHub 仓库显示 9 星,目录页显示 7 星;仓库仍在快速迭代,星标只作参考。

需要先分清两套名字相近的东西:

  1. 官方 @deepseek-ai/dsh-acp:DeepSeek Harness 源码树里的自动化 ACP 服务,面向程序客户端,能力刻意收窄。
  2. 社区 @openma/deepseek-harness-acp:面向编辑器的完整适配器,把流式文本、推理、工具 diff、权限请求、会话模式、斜杠命令、技能和 MCP 都投影到 ACP。

另外还有一个同名缩写干扰:Agentic Control Plane 也叫 ACP,和 Agent Client Protocol 不是一回事。本文只讨论后者。

社区插件目录 deepseek-harness-plugin.com 是独立站点,与 DeepSeek / 幻方没有官方从属关系,不要把它理解成官方应用商店。DeepSeek Harness 本身仍处于 developer preview,官方仓库明确写了会有破坏性变更。

核心功能

仓库 README 把能力写成「把 harness 的 session-event 日志映射到完整 ACP 词表」。下面只列已经在 README 和 cordis.patch.yml 里写明的部分。

流式输出与工具调用

助手文本和推理增量会按 ACP 推给客户端;客户端若收不到增量,适配器会退回拼好的整段消息。工具调用带 ACP kind、可读标题、文件位置,以及从 fs-tool hunk 得到的真实 diff。客户端支持 display terminal 时,命令输出走终端面板;否则用围栏代码块。

session/cancel 会穿过 Harness 的 agent 打断当前回合,不是只在协议层丢一个标志。

权限预设当成会话模式

会话默认从 workspace-write 开始:bash 和文件改动限制在会话 cwd(外加共享临时目录)。三个命名预设与 Web UI 一致,每个都是 {sandbox, approval} 的固定搭配:

  • read-only
  • workspace-write
  • danger-full-access

模型若请求更宽的权限,会弹出 ACP 权限请求。「Always allow (this session)」会把该会话的审批策略改成 neverdanger-full-access 会同时关掉沙箱和提示,README 写明只适合一次性检出或容器。

组合、模型目录与斜杠命令

profile 挂了 agentPresets 时,会出现未分类配置项 id: "agent",名单包括 standard / code / minimal / cordis 以及用户自己的副本。切换会现场重建 agent,历史保留。复制和删除预设仍在 Web 设置页完成,没有 /preset 斜杠命令。

模型列表来自正在运行的组合:在 Web UI 里加的第三方供应商会立刻出现。推理力度跟随产品默认值。适配器内置 /status/model,同时执行 Harness 命令注册表里的 /compact/goal/permission/plan 等,以及技能调用(/skill-name)。这些命令不走模型回合。登录和登出是 ACP 方法,不是聊天命令。

会话、计划、用量与 MCP

todo_write 快照会变成 ACP plan;token 记账走 usage_update 和按回合用量。session/load 会重放完整历史,session/list 可列出会话;agent 重启后客户端若仍对旧会话发 prompt,适配器会静默恢复。标题通过 session_info_update 同步。

每个会话的 mcpServers 会挂上 @deepseek-ai/dsh-mcp-client 实例(stdio 和 streamable HTTP),工具名形如 mcp__<server>__<tool>。单个 MCP 服务器失败不会把整个会话打挂。

图片与凭证

组合挂了 ctx.attachmentsdsh-base 会挂)时,适配器会声明 promptCapabilities.image。ACP image 块会校验、用 saveImage 保存,并与周围文本保持线上顺序。resource_link 只当作文本文件指针。

凭证有两层,编辑器配置里都不放密钥:

  1. Harness 凭证库:$DSH_HOME/.credentials.yaml(权限 600),与 Web UI 写入的是同一份,支持热加载。
  2. 进程环境:DEEPSEEK_API_KEY / DEEPSEEK_BASE_URL,以及对应路由上的 ANTHROPIC_API_KEY / OPENAI_API_KEY

凭证门禁看的是当前供应商路由。只有 Anthropic 密钥时,开不了 DeepSeek 会话,反过来也一样。缺少凭证时,session/newsession/prompt 会以 auth_required-32000)失败。

ACP initialize 会声明三种 Agent Auth:

  1. API key:方法名 api-key;多条路由并存时写成 api-key: <route>。客户端可传 _meta["api-key"].apiKey
  2. Browser:打开本机登录页,密钥不走 ACP。设置了 NO_BROWSER 时隐藏。
  3. Custom gateway:仅当客户端声明 clientCapabilities.auth._meta.gateway === true 时出现,客户端发送 { baseUrl, headers, providerName? }

安装与启用

先确认本机已有 Node.js 22.15 或更高版本,并且能运行 DeepSeek Harness。官方快速入口是:

npx @deepseek-ai/dsh web

Web UI 默认在 http://127.0.0.1:3080。也可以先全局安装:

npm install -g @deepseek-ai/dsh
dsh web

DeepSeek Harness 仍是 developer preview,核心插件和 API 还会变。

目录页给出的安装命令

社区目录页上的原文命令如下,在 DeepSeek Harness 终端里运行即可:

dsh plugin add github:openma-ai/deepseek-harness-acp

需要可复现安装时,按目录页说明固定 commit 哈希:

dsh plugin add github:openma-ai/deepseek-harness-acp#<commit>

<commit> 换成仓库里的真实哈希。目录页同时提醒:插件以当前 dsh 进程的权限运行,安装时可能执行代码;装之前应检查源码仓库和许可证。

仓库 README 的两种用法

目录页那条命令解决的是「把插件加进当前配置」。真正接到编辑器时,README 给出两条路径。

A. 独立服务端,适合先跑通:

npm install -g @openma/deepseek-harness-acp
dsh-acp login

dsh-acp login 是交互式的,输入不会回显;密钥也可以只在 Web UI 的 Settings → Models 里保存一次。核对当日 GitHub package.json 版本是 0.4.10-beta.2,npm latest0.4.9。用 npm 安装时以登记处实际版本为准,不要把未发布的 beta 号写进脚本。

独立进程会按 --dsh-path / DSH_PATH、自身目录、./node_modules、PATH 上的 dshnpm root -g 寻找 Harness,最后才用 npm 安装的 peer。已经存在 $DSH_HOME/profiles/acp 时,由该 profile 负责组合。

Zed 的 settings.json 示例:

{
  "agent_servers": {
    "DeepSeek Harness": { "command": "dsh-acp" }
  }
}

B. dsh profile 插件,适合长期放在自己的 dsh 配置里:

npm install -g @deepseek-ai/dsh
dsh web
dsh plugin --profile acp add -w @openma/deepseek-harness-acp

这会创建 $DSH_HOME/profiles/acp,并注册包里的 dsh.bundle 补丁。桥接挂在 @deepseek-ai/dsh-base 上,产品基线与 dsh web 相同,模块热重载是关掉的。之后可以像普通 profile 一样改 $DSH_HOME/profiles/acp/cordis.patch.yml

对应的 Zed 配置:

{
  "agent_servers": {
    "DeepSeek Harness": { "command": "dsh", "args": ["--profile", "acp"] }
  }
}

两种形态共用 $DSH_HOME:凭证、设置、预设和会话日志都是同一套。

典型用法

下面的命令和配置都来自仓库 README,可以按原文复现。

在 Zed 里启动一次会话

  1. 用上面 A 或 B 装好适配器。
  2. 在 Web UI 或 dsh-acp login 里写入当前要用的供应商密钥。
  3. 把对应的 agent_servers 写进 Zed settings.json
  4. 在 Zed 的 Agent 面板里选「DeepSeek Harness」,新开会话。

独立服务端启动后,stdout 只承载 ACP JSON-RPC,不要在这个进程上再挂普通日志到 stdout。cordis.patch.yml 因此关掉了 HMR 监视。

覆盖模型、权限和推理力度

标志优先于环境变量,环境变量优先于默认值。不传任何标志时,会话跟随产品默认(settings.yaml)。常用项:

标志 环境变量 默认 作用
--dsh-path DSH_PATH 自动探测 DeepSeek Harness 安装位置
--provider DSH_PROVIDER 产品默认 供应商路由
--model DSH_MODEL 产品默认 模型
--max-tokens DSH_MAX_TOKENS 供应商默认 单次输出 token 上限
--permission-mode DSH_PERMISSION_MODE workspace-write 初始权限预设
--reasoning-effort DSH_REASONING_EFFORT 产品默认 off / high / max

永久覆盖应写进 profile 的 cordis.patch.yml(按 id 覆盖,后写生效),不要把密钥写进编辑器 JSON。

子命令还有 dsh-acp login [api-key]dsh-acp update(经 npm 自更新)。

会话里直接用的命令

登录完成后,不必再在聊天里贴密钥。会话内可用:

  • /status/model:适配器内置
  • /compact/goal/permission/plan 等:Harness 命令注册表
  • /skill-name:调用已安装技能

需要换 agent 预设时,走客户端的配置项 agent,不要找 /preset

本地改插件时的双 profile

README 建议:编辑器继续用已发布包,另开一个 profile 用 pnpm 的 link: 指到工作树(file: 会被当成拷贝安装,同版本 tarball 还会走缓存):

dsh plugin --profile acp add -w @openma/deepseek-harness-acp
dsh plugin --profile acp-test add -w "link:$PWD"

开发循环是 npm run build 之后重启进程。Zed 可以同时挂稳定版和开发版:

{
  "agent_servers": {
    "DeepSeek Harness": { "command": "dsh", "args": ["--profile", "acp"] },
    "DeepSeek Harness (dev)": { "command": "dsh", "args": ["--profile", "acp-test"] }
  }
}

适用场景与注意事项

比较适合这几类人:

  • 已经在用 dsh web,希望同一套凭证和会话出现在 Zed 等 ACP 客户端里。
  • 需要在编辑器里看工具 diff、权限请求、计划和终端输出,而不是只拿一段纯文本回复。
  • 想把 DeepSeek Harness 的技能、斜杠命令和 MCP 带到编辑器侧,又不想给编辑器单独配一套密钥。

不太适合的情况也要说清楚:

  • 只要程序里调一轮 prompt / 取消 / 一次性权限,官方 @deepseek-ai/dsh-acp 才是那个自动化通道;不要把两套包混装混用。
  • 需要把智能体接到没有 ACP 客户端的编辑器时,这个插件帮不上忙。协议本身支持的编辑器可以看 Zed 的 ACP 页agentclientprotocol.com
  • DeepSeek Harness 和本插件都还在快速变动。npm 的 0.4.9 与仓库 0.4.10-beta.2 不一致,安装后以实际解析到的版本和 commit 为准。

安全方面按目录页和 README 的原文执行:

  • 插件以当前 dsh 进程的权限运行,安装时可能执行代码。装之前阅读源码和 Apache-2.0 许可证。
  • 不要把 API 密钥写进 settings.json。优先用 Web UI 或 dsh-acp login
  • 默认 workspace-write 已经把改动限制在会话工作目录;danger-full-access 会关掉沙箱和询问,只用于一次性目录或容器。
  • 凭证门禁按供应商路由生效,缺密钥时会话会直接 auth_required,这是预期行为,不是客户端坏了。

小结

deepseek-harness-acp 做的事情很具体:让 DeepSeek Harness 作为 ACP 服务端跑在编辑器旁边,会话事件、工具 diff、权限和凭证仍然以 Harness 为准。它不是 DeepSeek 官方应用商店里的一款「认证插件」,而是 openma-ai 维护的社区开源适配器;和仓库里那份自动化专用的 @deepseek-ai/dsh-acp 也不是同一个包。

目录页:https://deepseek-harness-plugin.com/zh-CN/plugins/deepseek-harness-acp/

GitHub:https://github.com/openma-ai/deepseek-harness-acp

装之前看源码,固定 commit,密钥留在 $DSH_HOME。这三件事比多装一个编辑器插件更重要。

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

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

小夜