ChatGPTClaudeGrok / X / CursorGemini

dsh headless 怎么跑一次性任务?DeepSeek Harness 输出流与退出码

配置与使用发布于 2026-10-21作者: DeepSeek Plugin 插件市场
DeepSeek HarnessheadlessCI退出码stdout
dsh headless 用一条命令跑一次性任务:stdout 只输出最终文本,reasoning 走 stderr,turn/end 为 completed 才返回 0。它不监听端口,也不挂载浏览器客户端,适合 CI 与脚本。

dsh headless 是一次性任务模式:启动一个全新 Agent,提交任务,等它完全停稳并 flush 会话,然后把最终文本写到 stdout、把推理过程写到 stderr,最后用退出码告诉你这轮有没有正常完成。 它不监听端口,也不挂载浏览器客户端,所以特别适合 CI、定时脚本和“跑完就走”的自动化。真正需要记住的是输出契约:stdout 只有答案,stderr 是过程,退出码看终止原因。

DeepSeek Harness:它和 web、sdk 的边界

headless 不是“没有界面的 web”,而是一条独立的一次性执行路径。 对比如下:(来源)

模式生命周期是否监听端口典型用途
dsh web常驻是,默认 3080人机交互
dsh --profile headless一次任务后退出否CI、脚本、批处理
dsh --profile sdk由客户端控制否,走 stdio程序内嵌
dsh --profile sdk-minimal由客户端控制否,走 stdio极简 SDK 运行时

headless 不挂载浏览器 Connection、HTTP 服务器、Web 运行时或浏览器客户端。也就是说,它不会因为端口被占用而启动失败,也不会留下一个后台服务等你关。

DeepSeek Harness:一次任务跑完发生了什么

headless 的执行顺序是固定的:建 Agent → 提交任务 → 等停稳 → flush → 从持久事件里推导结果。 展开看:(来源)

  1. 创建全新 Agent — 通过核心注册表创建一个持久化 Agent。预期:本次任务有独立的会话记录,不复用上一次的对话。
  2. 提交任务文本 — 位置参数就是任务内容。预期:Agent 开始按正常轮次执行。
  3. 等待完全停稳 — 不是“模型停止输出”就结束,而是等 Agent 生命周期进入空闲。预期:工具调用、子任务与收尾都完成。
  4. flush 会话 — 把持久化缓冲写入磁盘。预期:后续读取到的是完整事件区间,不是内存里的半截状态。
  5. 推导最终结果 — 取最后一个非空 assistant 文本与最后一个 turn/end 原因。预期:stdout 得到答案,退出码反映终止原因。

这也解释了一个常见现象:任务看起来“卡住”时,可能不是模型没回复,而是 Agent 还在等工具或子任务停稳。headless 不会在中途把半成品当最终结果输出。

DeepSeek Harness:stdout、stderr 与退出码的契约

stdout 只放最终答案,stderr 放推理,退出码放完成状态;三者不要混用。 契约如下:(来源)

通道内容使用建议
stdout最后一个非空 assistant 文本直接重定向到文件或管道
stderrdsh: reasoning: 下的推理增量记录日志,不要当答案解析
退出码 0turn/end 原因为 completed视为成功
退出码 1其他终止原因或执行失败视为失败,保留 stderr 排查

调用形态:

sh
dsh --profile headless "run the tests and summarize failures" \
  > /tmp/dsh-answer.txt \
  2> /tmp/dsh-reasoning.log
  1. 先看退出码 — echo $?。预期:0 才继续消费答案;1 时先看 stderr。
  2. 再读 stdout — 只取最终文本。预期:不包含推理标题、工具日志或进度条。
  3. 最后看 stderr — 推理内容与错误都在这里。预期:能区分“模型想了很久”和“工具执行失败”。

不要用 2>&1 把两个流合并后再解析;一旦合并,stdout 就不再是纯答案。

DeepSeek Harness:三种 CI 用法

headless 最适合“一次输入、一次输出、一个退出码”的自动化;不同场景只需要换外层包装。 三种常见写法:(来源)

  1. 直接命令行 — dsh --profile headless "$PROMPT"。预期:适合简单任务,外层用 shell 判断退出码。
  2. 包一层脚本 — 脚本里固定 workspace 与 DSH_HOME,把 stdout 写入制品。预期:不同 CI 任务之间隔离配置与会话。
  3. 定时触发 — 由 cron 或 CI 调度器触发,每次生成独立 session。预期:避免复用同一段对话导致上下文越滚越大。

如果任务需要继续上一段对话,headless 不是合适入口;它每次创建全新 Agent。需要续跑时用 SDK 或显式复用 session 的模式。

DeepSeek Harness:常见坑与排查

headless 的问题大多不是“模型不干活”,而是输出契约被误读。 四个高频坑:(来源)

  1. 把 stderr 当答案 — 推理增量也在 stderr,解析时会混入思考文本。预期:只从 stdout 取答案。
  2. 只看文本不看退出码 — 有输出不代表成功,终止原因可能是取消或错误。预期:退出码非 0 时按失败处理。
  3. 任务文本为空 — 没有位置参数就是用法错误。预期:调用前检查变量是否为空。
  4. 忘记隔离 home — 多次任务共用同一 home 会共享 profile、插件与会话目录。预期:CI 里显式指定 DSH_HOME。

排查顺序建议:先看退出码,再看 stderr 末尾的错误,最后才看 stdout 内容是否符合预期。反过来的话,很容易被一段“看起来像答案”的文本带偏。

DeepSeek Harness:信号、退出与资源释放

headless 收到 SIGINT 或 SIGTERM 时,会先 dispose 挂载的根节点再退出,不是直接杀进程。 这条行为决定了自动化里怎么“优雅取消”:(来源)

  1. 发 SIGTERM — 让进程有机会释放资源、结束在途工具调用。预期:进程退出,会话日志保留到已 flush 的位置。
  2. 不要立刻 SIGKILL — 强杀可能留下未 flush 的会话尾部。预期:需要硬停时,先给一次 SIGTERM 的窗口。
  3. 按退出码判断 — 被信号终止通常不是 0;脚本应把它当失败或“未完成”处理。预期:不会把取消误判成成功。

headless 不挂载 HTTP 服务器与浏览器客户端,所以没有“端口没释放”的问题;它需要释放的是会话持久化与工具子进程。

DeepSeek Harness 常见问题

Q:headless 能不能开 Web UI 端口? 不能。它不挂载 HTTP 服务器,也不打开监听端口;需要界面就用 dsh web。

Q:一次 headless 会不会留下会话文件? 会。它会创建持久化 Agent 并 flush 会话,所以 $DSH_HOME/sessions 下会有记录;需要清理时按会话保留策略处理。

Q:能不能把 headless 当“无界面常驻服务”? 不合适。它是一次性任务模式,跑完就退出;常驻服务应该用 web 或 SDK 客户端。

一句话收束: headless 的价值在于契约清晰——stdout 是答案、stderr 是过程、退出码是结论;按这三条用,它就比“截屏式自动化”可靠得多。

ChatGPTClaudeGrok / X / CursorGemini

常见问题

DeepSeek Harness 的 dsh headless 和 dsh web 有什么区别?

DeepSeek Harness 里,dsh headless 是一次性任务模式:启动、提交任务、等 Agent 完全停稳、flush 会话,然后退出;它不挂载浏览器 Connection、HTTP 服务器或 Web 运行时,也不打开监听端口。dsh web 则是常驻的 Web UI。

dsh headless 的 stdout 和 stderr 分别输出什么?

DeepSeek Harness 里,stdout 只打印最终 assistant 文本;非空的提供方 reasoning 增量会写到 stderr,并带 dsh: reasoning: 标题。没有推理内容的成功响应会让 stderr 保持为空。

为什么 dsh headless 明明输出了答案,退出码还是 1?

DeepSeek Harness 里,退出码看的是最终 turn/end 原因,不是有没有文本。只有原因为 completed 才返回 0;被取消、报错、达到其他终止原因时即使有部分输出也会返回 1。脚本应同时判断退出码与 stdout。

dsh headless 不传任务文本会怎样,在 DeepSeek Harness 中如何处理?

DeepSeek Harness 里,会按用法错误处理。headless 的任务文本是位置参数,没有任务就不是一次有效调用;它不会进入交互式等待,也不会默认读取某个文件。

dsh headless 适合放进 CI 吗,在 DeepSeek Harness 中如何处理?

DeepSeek Harness 里,适合。它不监听端口、只输出最终文本、用退出码表达完成状态,天然适合 CI。需要注意的是每次调用都会创建一个持久化 Agent 会话,反复跑要规划好 session 与 workspace 的隔离。

相关术语

headless
headless 是 DeepSeek Harness 的一次性任务 profile,用 dsh --profile headless <任务> 启动;它运行一个全新持久化 Agent,等待完全停稳并 flush 会话后退出。— DeepSeek Harness 官方参考 - dsh CLI 行为
turn/end
turn/end 是 DeepSeek Harness 会话日志中标记一轮结束的持久事件,带终止原因;headless 用最后一个 turn/end 的原因决定进程退出码。— DeepSeek Harness 官方参考 - dsh CLI 行为
flush
flush 是 DeepSeek Harness 把会话日志与持久化缓冲写到磁盘的动作。headless 在退出前会对会话执行 flush,确保最终文本来自已持久化的事件区间。— DeepSeek Harness 官方参考 - dsh CLI 行为
reasoning 增量
reasoning 增量是模型思考流的分片,与最终可见文本分开。headless 把它们写到 stderr,避免污染只承载最终答案的 stdout。— DeepSeek Harness 官方参考 - dsh CLI 行为

来源