用本指南安装、配置和运维 dsh-superagent。内容覆盖账号、启动检查、升级与故障排查,建立在 001 领域模型到 005 面板之上。
运行什么
- 一个专用的 DeepSeek Harness profile,本指南称之为
superagent。从 Web profile 模板创建。它加载 bundle 并在127.0.0.1上提供面板。让它与你日常工作的 profile 分开:插件会改动进程级的PATH与 git 配置,其进程需要独立的重启与升级。 - 一个 agent 的 GitHub 账号。agent 以该账号评论、推送分支、开启 pull request,通过一个只以该账号登录的 GitHub CLI。
- 可选:一个用于聊天请求的飞书 bot。
插件配置保存状态目录与机器级限额。其余一切用面板完成:Source(来源)设置仓库与账号,Policy(策略)设置允许列表,Execution(执行)设置 worker 目录与命令。
权限与隔离
bundle 为 Executor(执行器)定义 dsh-superagent-worker,为主 Session 定义 dsh-superagent-router。它们出现在 DeepSeek Harness 预置列表中,但只服务于 dsh-superagent。不要为个人 Session 选择它们,也不要禁用它们的配置行。应用需要它们来创建和恢复自己的 Session。
在 Web UI 里打开空白受管 Session 时可能选中 profile 的默认预置。dsh-superagent 会在第一回合之前恢复其角色专属预置。
两个预置都以 danger-full-access、以操作者的 OS 用户运行,并读取已订阅 Thread 上的消息。账号包装器默认选择 agent 的凭据;它们不隔离进程。worker 可以按路径执行程序、读取操作者的主目录。要隔离,请使用一个只包含 agent 凭据的专用 OS 账号。
前置条件
- Node.js 22.19+ 或 24+、pnpm、git 2.32+、Python 3.8+ 与 tmux
- GitHub CLI(
gh)2.48 或更高。Source 的 CLI 字段必须指向gh或lark-cli包装器;宿主依赖其子命令与输出格式 - github.com 上的一个仓库;不支持 GitHub Enterprise Server。要为每个 Ticket(工单)创建检出,保留一个本地克隆,供 prepare 命令从中添加 worktree。仓库使用 Git LFS 时安装
git-lfs - 为 DeepSeek Harness 配置好的模型供应商。除非 Eval 或 Execution 设置指定了别的模型,dsh-superagent 使用 profile 的默认模型
- 飞书:需要
lark-cli(在 1.0.90 上测试)与一个带 bot 能力的飞书 / Lark 应用
账号
agent 的 GitHub 账号
- 为 agent 创建一个 GitHub 用户账号,并授予它仓库的写权限。GitHub App 不能充当 agent,因为 dsh-superagent 要读取账号的通知。
- 给它一个只使用自己凭据的 GitHub CLI:
以 agent 账号登录;最后一条命令打印其登录名。dsh-superagent 以同样方式读取登录名。mkdir -p ~/.local/bin cat > ~/.local/bin/gh-agent <<'EOF' #!/bin/sh GH_CONFIG_DIR="$HOME/.config/gh-agent" exec gh "$@" EOF chmod +x ~/.local/bin/gh-agent gh-agent auth login gh-agent api user --jq .login
飞书 bot(可选)
- 创建一个带 bot 能力的自建应用。授予它接收消息事件、读取与发送会话消息、读取会话成员的权限,然后发布应用版本。
- 为 bot 准备一套独立的
lark-cli配置——限定为 bot 身份——以及一个包装器:
第一条命令从标准输入读取应用 secret。请使用单独的配置目录:LARKSUITE_CLI_CONFIG_DIR="$HOME/.lark-cli-dsh-superagent" lark-cli config init --app-id <cli_…> --app-secret-stdin LARKSUITE_CLI_CONFIG_DIR="$HOME/.lark-cli-dsh-superagent" lark-cli config strict-mode bot --global cat > ~/.local/bin/lark-bot <<'EOF' #!/bin/sh export LARKSUITE_CLI_CONFIG_DIR="$HOME/.lark-cli-dsh-superagent" exec lark-cli "$@" EOF chmod +x ~/.local/bin/lark-botlark-cli每个 app id 只允许一个 profile,而你的个人配置可能已经包含该应用的一个用户登录。
宿主拒绝可以用用户身份行动的 CLI。它从 bot 配置读取 app id、飞书 / Lark 品牌与 bot 的 open_id。
两套配置共享同一个钥匙串条目(应用 secret)。只想移除 bot 配置时,删除它的目录即可;不要运行 lark-cli config remove,那会影响共享的 secret。
安装
在一台还没有 superagent profile 的机器上运行一次这个块:
npm install -g @deepseek-ai/dsh@0.2.1-rc.3
git clone <this repository> dsh-superagent && cd dsh-superagent
pnpm install && pnpm build
dsh superagent --from-default-profile web --dump-config > /dev/null
dsh plugin --profile superagent add "link:$PWD"
上面固定的版本是公开的;其他版本必须满足 package.json 里的 engines.dsh。
第四条命令从 DeepSeek Harness Web 模板创建 ~/.dsh/profiles/superagent。第五条安装这个 bundle。设置 DSH_HOME 可以迁移默认的 ~/.dsh 目录。
profile 创建命令只用于全新安装。如果 profile 已存在,该命令会替换它并删除其 cordis.patch.yml(包括机器配置)。不要用它来升级。
机器配置
把 examples/profile.cordis.patch.yml 复制为 ~/.dsh/profiles/superagent/cordis.patch.yml(覆盖原文件),替换所有 <placeholder>。使用飞书时,还要在那里启用 dsh-superagent-feishu 条目。webserver 条目设置面板端口。
| 键 | 必填 | 含义 |
|---|---|---|
stateDir | 是 | 绝对路径:数据库、锁、worker-bin 中的命令 shim、agent 的 git 配置,以及默认在 work 下的 Ticket 目录。升级前先备份 |
promptMaxChars、admissionContextMaxPages、admissionContextTimeoutMs | 否 | 已保存 prompt 配置的最大尺寸;一次研判在多长时间内读取多少页 Thread |
首次启动后,在 Settings → Deployment 或 DeepSeek Harness 插件管理器中编辑机器限额。改动无需重启即生效。stateDir 不能在那里修改。无效值或未知配置键会阻止启动;日志会指明是哪个键。
启动与停止
scripts/dsh-superagent start
scripts/dsh-superagent status
start 在 tmux 会话 dsh-superagent(其他 profile 为 dsh-<profile>)中运行 dsh --profile superagent。它最多等待一分钟,直到运行时就绪或报告 setup 需求。首次运行会打印缺失的 setup 信息。它拒绝重复实例,包括本脚本之外启动的实例。
stop 与 restart 请求优雅关闭,并最多等待 Executor 五分钟。它们绝不强杀进程,也不触碰其他 tmux 会话。
status 打印进程 id、健康状态与 setup 问题。换 profile 或端口时使用 --profile 与 --url,或设置 DSH_SUPERAGENT_PROFILE 与 DSH_SUPERAGENT_URL。
status、start 与 restart 以四种退出码之一结束:
| 码 | 含义 |
|---|---|
| 0 | 服务正常运行 |
| 1 | 未运行、运行了两份、无应答,或其运行时报错;重启可能修复 |
| 2 | 在运行,但运行时以外的某个部分(例如某个 Source 或 Policy 同步 sync:<source id>)报错;重启不能修复 |
| 3 | 在运行并等待 setup;重启不能修复 |
仍在启动中的 Source 视为正常。setup 无法检查的飞书 bot 同样视为正常。
status 在 errors 下返回失败的部分及其细节,在 setup 下返回 setup 需求。start 与 restart 把这些问题按行打印;服务始终起不来时它们以 1 退出。只有主动 stop 会暂停自动恢复。
每个 profile 把日志与控制文件保存在 .artifacts/ 下:
- 启动日志:
dsh-superagent-<profile>-<date>-<time>-<pid>.log,pid 属于脚本本身。保留最新 20 份。 - 控制文件:
control/profiles/<profile>/,含停止标记、锁与进程 id。
打开日志中打印的 URL,然后在侧边栏选择 Superagent。
每小时检查
在你日常使用的 DeepSeek Harness profile(而不是 superagent)中创建每小时检查。agent 服务宕机时它必须仍在运行。让那个 profile 里的一个 agent 用下面的 prompt 创建一个每小时日程(填入检出路径):
Check dsh-superagent: run `scripts/dsh-superagent --profile superagent status` in <checkout>. Exit 0: do nothing and say nothing. Exit 2: do not restart; tell me each part under `errors` with its detail, unless you already told me about the same ones. Exit 3: do not restart; tell me what `setup` says setup needs, unless you already told me. If it reports manually_stopped: true, leave it stopped. Otherwise (exit 1) run `scripts/dsh-superagent --profile superagent --respect-stop restart`, which exits the same way: 0 means it recovered, so say nothing; 2 and 3 are reported as above; if it exits 1 or fails otherwise, read the newest .artifacts/dsh-superagent-superagent-*.log and the Troubleshooting section of docs/006-deployment.md, fix what you can, and tell me what was wrong and what you did.
--respect-stop 保留一次主动的停止。只有 stop 写入标记;start 清除它。restart 不写标记,因此该检查还能恢复一个关闭超时的重启。
设置
轮询或工作开始之前,setup 必须先成功。总览列出缺失项并链接到其设置。设置变更会再次运行 setup。如果你在应用之外修好了某件事(例如 CLI 认证),选择 Check again。
- Source。设置 GitHub 仓库(
owner/name)与 agent CLI,例如/home/me/.local/bin/gh-agent。请求通常经 agent 账号的通知到达。提到该账号的新 Issue 或评论在下一次轮询到达;通过编辑既有 Issue 正文追加的提及不会到达,请改发一条新评论。飞书侧设置 bot CLI、各会话、每个会话的「全部消息 / 仅提及」模式,以及是否接收直接消息。 - Policy。两条示例规则可编辑或删除。在 On each Source 下,加入可以请求工作的 GitHub 账号与飞书用户;名单为空时任何请求都无法成为 Ticket。使用飞书时,可以选定一个会话用于同步名单(启动时与点 Sync now 时)。
- Execution。目录根与 prepare 命令。为每个 Ticket 提供一个仓库检出:
把你个人的 CLI(例如登录了你本人账号的那个)列入被封禁命令。git -C /home/me/src/widgets fetch --no-tags "https://github.com/$DSH_SUPERAGENT_GITHUB_REPOSITORY.git" "${DSH_SUPERAGENT_GITHUB_PR_HEAD:-HEAD}:refs/dsh-superagent/$DSH_SUPERAGENT_TICKET" && git -C /home/me/src/widgets worktree add -b "agent/$DSH_SUPERAGENT_NAME" "$DSH_SUPERAGENT_DIR" "refs/dsh-superagent/$DSH_SUPERAGENT_TICKET" - Prompt。设置团队段落:GitHub 披露行、审查 bot、commit 作者与自动合并条件。
管理 API
面板使用一个本地 HTTP API,agent 也可以调用。SETUP.md 用它保存设置,服务脚本读取 GET state。
向 http://127.0.0.1:<port>/orchestrator/api/ 发送请求并带 x-orchestrator-request: 1。Host 必须是 127.0.0.1:<port> 或 localhost:<port>。缺少头或来自其他站点的 Origin 会收到 403。
API 保存拥有面板的权限。它们可以更改执行环境与 setup 账号字段——这是经主 Session 工具的保存做不到的。
agent 可以依赖这些路由与字段。src/app/api.ts 中的其他路由服务于面板,并随其变化。
| 请求 | 应答 |
|---|---|
GET state | 每个页面读取的内容:setup,含 problem 与 feishuProblem(为 null 或一个带 place、code、values、detail 的 setup 问题),以及 setup 解析后的 accounts;health,每个部分一项(见下),含 state(starting、ready、paused 或 error)、detail 与 at;load,运行中的 Executor Session、排队中的 Ticket 与 maxWorkers;paused;以及 masterId |
GET settings | blocks:policy、eval 与 executor,各含其 value 与 revision;sources:各 Source 实例,含 id、kind、installed、其块的 value({"enabled": …, "config": {…}})与 revision、其种类的表单,以及有问题是它的 setup problem;policyVersion;以及 environment——执行环境的 root 与 variables |
GET sources | 每个 Source 的状态:state(missing、off、error、setup、starting、paused 或 ready)、其各部分的 health、其 setup problem、最近一天的 stats、当天被 filtered 的 Trigger,以及当天被 dropped 的消息(最新在前;每条含 channel、preview、属于某个 Ticket 时的 ticket(id 与 title)、存储里有时的 thread,以及 dropped.at 与 dropped.reason——channelGone 或 channelIgnored) |
PUT settings/<block>,body 为 {"value": …, "revision": n} | 保存一个块:saved、该块的新 revision、policy_changed 与 restarting。value 是整个块,与 GET settings 中的一致;缺失的键取默认值 |
POST executor/pause,body 为 {"paused": true} 或 false | 暂停或恢复处理:paused |
POST setup/check | 通过重启 dsh-superagent 再次运行 setup:restarting: true。setup 无事可修时被拒绝 |
POST policy-sync/<source id> | 立即同步该 Source 的允许列表:policy,即已保存的该 Source 部分 |
GET prompts、PUT prompts({"config", "baseRevision"}) | 读取 prompt 配置:current(含 revision 与 config)、defaults、sections(Session 读取顺序中的团队段落)、skillName(团队技能名的模式)、builtin(团队技能不能取的名字)与 skillPrefix(Session 加载技能名所用的前缀);或保存它:新的 revision |
POST tickets/<id>/retry、POST tickets/<id>/stop | 与面板一样重试或停止一个 Ticket |
健康项按职责分组:
| 项 | 报告 |
|---|---|
runtime | 应用本身 |
models | 等待模型预算重试的 Session |
evals | 最近一小时没有后续判定或消除的 unavailable Eval |
assessment、launch、delivery、relay、notice、reply | 003 执行所述的已存储工作;delivery 统计等待中的工作,reply 覆盖 Channel 消息 |
worker | Executor Session 事件处理;首次失败后出现 |
github、feishu、history | Source 轮询、事件与历史恢复 |
sync:<source id> | 允许列表同步 |
拒绝应答带状态码与 error(英文原文):
- 400:无效值(
issues,各含其path)、账号检查失败(setup)、固定拒绝(code与values),或不是 JSON / 过大的 body。 - 404:不存在的东西。
- 409:过期的 revision。
- 500:其余一切。
各块:
source:github、source:feishu:{"enabled": true, "config": {…}}。GitHub 的 config 有repository与cli,以及默认关闭的开关observeIssues、observePulls、observeComments与observeCi——开启后接收仓库内每个新 Issue、新 pull request、评论与默认分支的 CI;飞书的有cli、chats(形如[{"chatId": "oc_…", "name": "…", "listen": "mentions"}]或"all")、directMessages,以及otherChats("none"或"mentions")。policy:{"rules": […], "sources": {"github": {"allowed": [{"id": "<login>"}], "bots": [{"id": "dependabot[bot]"}]}, "feishu": {"allowed": [{"id": "ou_…", "name": "…"}], "syncChat": "oc_…", "admission": {"oc_…": {"unlistedAddressed": "explicit"}}}}}。bots列出其消息可成为 inferred 候选的 bot。admission行以会话 id、飞书的other/direct,或 GitHub 的issues/pulls/comments/ci为键;未设置的格子取默认值(见 002 授权)。eval:mode、timeoutSeconds与model。executor:model、maxWorkers、directory、prepare与blockedCommands。处理暂停是单独的设置paused,由POST executor/pause设置。
更换仓库或 CLI 会先运行相应的 setup 检查。检查失败返回 400,细节在 setup 中。账号变更成功、或 setup 待定期间的任何保存,返回 restarting: true。应用重启期间 API 暂不可用。
api=http://127.0.0.1:3082/orchestrator/api
rev=$(curl -s -H 'x-orchestrator-request: 1' $api/settings | jq '.sources[] | select(.id == "github") | .revision')
curl -s -X PUT -H 'x-orchestrator-request: 1' -H 'content-type: application/json' $api/settings/source:github \
-d "{\"value\": {\"enabled\": true, \"config\": {\"repository\": \"acme/widgets\", \"cli\": \"$HOME/.local/bin/gh-agent\"}}, \"revision\": $rev}"
Setup 检查
setup 使用 DeepSeek Harness 子进程服务,与 worker shell 相同。它会移除名称包含 KEY、PASSWORD、SECRET 或 TOKEN 的环境变量。
setup 校验 GitHub 仓库与 agent 的推送权限,写入 worker 环境,并检查 git 对 github.com 只使用 agent 凭据。飞书 setup 失败只禁用飞书 Source。
setup 写入的进程环境:
- 命令 shim,在
<stateDir>/worker-bin,位于PATH最前:gh运行 agent 的 CLI;lark-cli运行 bot 的 CLI;被封禁命令直接失败。shim 在运行目标前会把自己的目录从PATH移除。 - git 配置,在
<stateDir>/worker-gitconfig:替换操作者的全局与系统 git 配置。它把 agent CLI 选为 github.com 的凭据助手,把 GitHub SSH 地址改写为 HTTPS,并定义 Git LFS 过滤器。HTTP 代理之类的个人 git 设置不再生效。这里不设置 commit 身份;git 永不提示输入凭据;GH_TOKEN与GITHUB_TOKEN被移除。
worker-bin 或 worker-gitconfig 中存在 dsh-superagent 未写入的文件会阻止 setup。Ticket 目录若位于一个自身配置添加了凭据的 git 仓库内,该 Ticket 会失败。
试运行
从允许列表上的 GitHub 账号,开启一个 Issue 或发一条包含 @<agent 登录名> <请求> 的评论。一个轮询间隔(默认一分钟)内,总览应显示一个 Ticket。agent 确认请求,在自己的 Session 与目录中工作,并在原始会话中交付。飞书侧,在已配置的会话中提及 bot。
升级
- 等待没有 Executor 正处于回合中。
- 备份
<stateDir>/orchestrator.sqlite。 - 运行
git pull && pnpm install && pnpm build。 - 运行
scripts/dsh-superagent restart并检查其状态。
重启会结束运行中的 Assignment,并带恢复备注启动替代者。团队文本与有覆盖的 prompt 部分保留;无覆盖的部分跟随新的默认值。升级后检查标记为 Default updated 的部分。
被更新版本迁移过的数据库无法被旧版本打开,因此回滚需要升级前的备份。升级 DeepSeek Harness 本体之后,重启运行中的实例,使面板加载匹配的产物。
agent 预置
worker 与 router 预置在 5 秒后把 shell 命令转入后台。Session 没有它的预置就无法加载。在它们的 Session 使用期间,保留 cordis.patch.yml 里的 dsh-superagent-worker 与 dsh-superagent-router 行;否则恢复会以 agent-preset/not-found 失败。
故障排查
setup 问题以面板语言显示在总览上并附修复链接;日志与 API 显示下面的英文原文。
| 症状 | 原因与修复 |
|---|---|
The agent GitHub CLI is not set. | 在 GitHub 卡片上设置 agent 的 CLI |
The agent GitHub CLI was not found. | 设置包装器的绝对路径,或 PATH 上的命令名 |
The agent GitHub CLI cannot read its account | 用 auth login 登录该包装器 |
@… cannot read … 或 @… cannot push to … | 授予 agent 账号仓库写权限 |
The GitHub Source names no repository. | 在 GitHub 卡片上设置仓库 owner/name |
Ticket 失败,The prepare command failed: … | 输出指明原因(例如克隆路径错误);修好命令后重试 Ticket |
git does not read the github.com credential configuration dsh-superagent writes | 安装 git 2.32 或更高 |
Ticket 失败,The git configuration of the repository in … sets … | 从克隆的 .git/config 中移除指名的凭据或 http.*.extraheader 设置 |
… was not written by dsh-superagent | 把指名的文件移出 <stateDir>/worker-bin 或 <stateDir>/worker-gitconfig,或换一个 stateDir |
The bot lark-cli allows user identities | 让飞书 Source 指向一个仅限 bot 的配置,见上文「飞书 bot」 |
The bot lark-cli does not work. 或 The bot identity of app … is … | 检查配置的 app id 与 secret |
The Feishu bot is not a member of the chat. | 在会话设置里把 bot 加进会话;下一次尝试即成功 |
status 以 2 退出 | 某部分报错且重启修不好:errors 按管理 API 下的清单点名每个部分及其细节;各部分恢复后自行清除条目 |
status 以 3 退出 | setup 在等待:setup 说明缺什么,总览链接到修复它的设置 |
status 以 1 退出 | 服务未运行、运行了两份、无应答,或运行时报错;输出与最新日志指明是哪种 |
… timed out after 90 s、… was stopped by …、… exited with code … 或 … could not run: … | 某个 CLI 失败且没有打印原因;以操作者用户手动运行指名的程序查看其自身报错 |
| 面板说 dsh-superagent 无应答 | 它正在重启,或因配置问题没有启动;DeepSeek Harness 日志指明原因 |
dsh-superagent configuration has keys it does not use(日志) | 移除指名的键;消息说明每个值现在存放在哪里 |
| 日志说插件与运行中的 dsh 不兼容 | 安装 engines.dsh 范围内的 DeepSeek Harness 版本 |
| DeepSeek Harness 升级后面板显示 "Failed to load plugins" | 重启运行中的实例 |
| 提及之后没有任何反应 | 检查作者在 Source 的允许列表上、Source 已开启、处理未暂停。GitHub 上,通过编辑 Issue 正文追加的提及不会被收到;请在评论中提及 agent |