很多 Agent 工具默认以交互会话的方式运行——使用者需要等它一步步提问、确认、输出,像实时对话。但真实场景里,往往只想发一条命令,让它自己后台跑完、把结果落到文件里,甚至配合定时任务每天自动跑一套工作流。本教程讲解如何在 不进入交互会话 的前提下,让 DeepSeek Harness(DSH)、Codex、Claude Code 后台自主执行任务,核心机制是 no-tty(无终端)与 headless(无头)模式,并以 ZCode 为延伸案例剖析 harness 内建的后台执行体系。全文配套可运行的示例项目 agent-dispatcher,把三种方式串成一条完整的下发与编排链路。

前置教程

如想快速开始学习本教程,你可能需要先完成以下前置教程:

资源下载

1. 为什么需要"后台自主执行"

交互式会话适合学习和调试,但它有两个天然限制:

  • 必须有人守着:每一步都需要人工确认,无法无人值守。
  • 无法编排:难以塞进定时任务、CI/CD 或自动化流水线。

而很多真实需求恰恰相反——只想"甩一条指令,让它自己干完"。例如:

  • 每天定时让 Agent 审查项目代码并提交修复
  • 后台批量处理一批文件或生成报告
  • 在服务器、容器、脚本里触发一次性的编码任务

这类需求的共同点:只管下发任务,不关心也不想要交互过程。实现它们的关键,是让 Agent 工具进入 no-tty(无终端输入)或 headless(无界面)模式——一旦检测到没有交互式终端,它们会自动从"对话模式"切换到"任务模式":跑完即止、结果存留、可被后台调度。

1.1 延伸概念:CI/CD 与自动化流水线

前面限制里提到的 CI/CD 是软件工程里的一对标准概念,这里在首次出现处把它解释清楚。

CI(Continuous Integration,持续集成):开发者频繁把代码合并到主干,每次合并自动触发一套检查流程——自动构建、自动跑测试,尽早发现冲突和 bug。CI 只负责到"测试通过"为止,不会自动上线。

graph LR A[开发者提交代码] --> B[CI 自动触发] B --> C[自动构建] C --> D[自动跑测试] D --> E{测试通过?} E -->|是| F[合并成功] E -->|否| G[报错, 通知作者修复] style A fill:#e8f4f8,stroke:#1a6b8a,stroke-width:2px style B fill:#ffecd6,stroke:#e67e22,stroke-width:2px style C fill:#d5f5e3,stroke:#27ae60,stroke-width:2px style D fill:#ebdef0,stroke:#8e44ad,stroke-width:2px style E fill:#ebdef0,stroke:#8e44ad,stroke-width:2px style F fill:#fdebd0,stroke:#b7950b,stroke-width:2px style G fill:#fadbd8,stroke:#c0392b,stroke-width:2px

CD(Continuous Deployment / Continuous Delivery,持续部署 / 持续交付):把"发布上线"也自动化。两者名字相近,区别在最后一步是否需要人工确认:

类型 是否自动上线 人的角色
持续交付(Delivery) 不自动,准备好发布包,人工点确认 人工把关最后一步
持续部署(Deployment) 全自动,测试通过就自动发 人只管维护规则
graph LR A[CI 测试通过] --> B[自动打包] B --> C[部署到测试环境] C --> D{发布方式?} D -->|持续交付| E[人工确认后上线] D -->|持续部署| F[全自动直接上线] style A fill:#ebdef0,stroke:#8e44ad,stroke-width:2px style B fill:#d5f5e3,stroke:#27ae60,stroke-width:2px style C fill:#fdebd0,stroke:#b7950b,stroke-width:2px style D fill:#ebdef0,stroke:#8e44ad,stroke-width:2px style E fill:#e8f4f8,stroke:#1a6b8a,stroke-width:2px style F fill:#ffecd6,stroke:#e67e22,stroke-width:2px

与本教程的关系:后文介绍的 no-tty 命令正是 CI/CD 流水线的执行单元——CI 在每次代码提交后触发一次 codex -p 审查,或在发布前自动跑一遍检查;而 7.2 节讲的"无人值守与人工确认的平衡",对应的就是持续交付(自动化到最后一步、人工放行发布)与持续部署(全自动)的分界。

2. 核心概念:no-tty 与 headless

no-ttyheadless 是两回事,但目标一致——都为了让任务脱离交互。

概念 含义 触发条件 典型场景
no-tty(无终端) 程序检测不到交互式终端输入 被重定向、管道、后台进程调用时 脚本、cron、CI 流水线
headless(无头) 程序在无人值守、无图形界面的模式下运行 显式参数开启或环境无界面时 服务器、容器、自动化测试

no-tty 强调的是"没有交互输入设备",headless 强调的是"没有图形界面"。对编码 Agent 而言,前者决定它"进不进对话循环",后者决定它"看不看得见页面"。

2.1 任务模式与交互模式的区别

Agent 工具通常区分两种运行状态:

graph LR A[一条命令下发] --> B{是否有交互终端?} B -->|是| C[交互会话模式: 逐步提问确认] B -->|否| D[任务模式: 跑完即止, 结果存留] D --> E[后台/定时任务可调度] style A fill:#e8f4f8,stroke:#1a6b8a,stroke-width:2px style B fill:#ebdef0,stroke:#8e44ad,stroke-width:2px style C fill:#ffecd6,stroke:#e67e22,stroke-width:2px style D fill:#d5f5e3,stroke:#27ae60,stroke-width:2px style E fill:#fdebd0,stroke:#b7950b,stroke-width:2px

当命令被放入后台、重定向到文件、或没有终端时,工具检测到"无交互终端",就会走下面的任务模式——这是无人值守调度的前提。

3. Codex:最纯粹的"命令即任务"

Codex 的 CLI 从设计上就支持脚本化、非交互运行,是三者中最适合"一条命令后台执行"的。

3.1 --print 模式:不进会话直接出结果

-p(或 --print)是 Codex 的招牌非交互模式:给一条指令,直接打印结果,完全不进入交互会话,非常适合管道和脚本。

# 直接输出结果,不进交互界面
codex -p "用 try/except 包裹 src/main.py 里所有文件读取调用"

# 配合重定向,把结果存留
codex -p "给本项目加一份 README,说明安装步骤" > README.md 2>&1

3.2 后台执行:命令立刻返回

用操作系统的后台能力,让 Codex 在后台跑,命令本身立刻返回:

# Windows PowerShell
Start-Process codex -ArgumentList "-p","重构 src/ 的异常处理" -WindowStyle Hidden

# Linux / macOS(bash)
codex -p "重构 src/ 的异常处理" > result.md 2>&1 &

3.3 无 TTY 自动适配

没有交互式终端时,Codex 自动走非交互逻辑:

# 强制无 stdin,确保非交互
codex "给 config.py 补全注释" < /dev/null > out.md 2>&1

4. Claude Code:headless + 结构化输出

Claude Code 的 CLI 同样区分交互会话与一次性任务。当它检测到没有交互式 TTY 时,会自动走任务模式——跑完即止。

4.1 任务模式:跑完即止

在脚本或非交互环境下直接给指令:

# 没有交互式 TTY 时,跑完任务即退出
claude "审查 src/ 的代码质量并给出修复建议"

4.2 headless 模式:无人值守

配合后台重定向,让 Claude Code 在无界面下运行并把日志存留:

# 后台运行,日志存留,命令立即返回
claude "批量重构 utils/ 目录" > log.txt 2>&1 &

4.3 结构化输出:便于脚本解析

--output-format 指定输出为 JSON,方便后续脚本处理:

# 以 JSON 输出结果
claude "检查 src/ 是否有未捕获的异常" --output-format json > report.json

5. DeepSeek Harness:调度层 + 后台代理

DSH 的机制与前面两个工具不同:它是 Agent 宿主 / 调度层,本身不直接跑代码任务,而是通过调用底层引擎(Codex、Claude Code 等)来完成。因此"后台执行"在 DSH 里分两层理解。

5.1 DSH 的后台代理(background job)

DSH 可以直接创建后台子代理执行任务,无需在会话中守候,这是调度 node main.js 等脚本类任务时的常见用法。后台任务完成后,DSH 会主动通知结果。

# 在 DSH 会话中触发一个后台任务
(由 DSH 的 subagent / background job 机制承接,跑完即止)

5.2 DSH 调度底层引擎

DSH 作为调度层,可以把"一条命令后台执行"的活儿交给底层引擎。结合第 3、4 节的 --print / headless 模式,就能实现"DSH 发令、底层引擎后台跑"的组合。

graph LR A[DSH 调度层] --> B[后台代理: 内部编排] A --> C[Codex: --print 模式] A --> D[Claude Code: headless 模式] B --> E[结果存留 / 通知] C --> E D --> E style A fill:#e8f4f8,stroke:#1a6b8a,stroke-width:2px style B fill:#ffecd6,stroke:#e67e22,stroke-width:2px style C fill:#d5f5e3,stroke:#27ae60,stroke-width:2px style D fill:#d5f5e3,stroke:#27ae60,stroke-width:2px style E fill:#fdebd0,stroke:#b7950b,stroke-width:2px

关键理解:Codex 和 Claude Code 是"引擎",负责真正执行任务;DSH 是"调度层",负责编排和承接。"后台默认执行"这一需求,在 DSH 里由它的后台代理能力 + 底层引擎的 no-tty / headless 模式协同实现。

6. 实战示例:agent-dispatcher 任务下发与工作流编排

前面讲了三种工具各自的后台执行方式,本节把它们串成一个可运行的示例项目 agent-dispatcher:前端页面提交任务后,后端立即返回任务编号并在后台线程自主执行;执行过程按 Workflow 方式编排为四个节点(解析任务、引擎执行、质量校验、生成报告);引擎层以 no-tty 方式调用 Codex / Claude Code CLI,未安装时回退到模拟引擎。整体链路如下:

graph LR A[前端页面 提交任务] --> B[POST 接口 立即返回] B --> C[后台线程 自主执行] C --> D[工作流四节点 顺序编排] D --> E[引擎适配层 codex -p 与 claude] D --> F[结果写入 任务表] F --> G[前端轮询 展示进度与产出] style A fill:#e8f4f8,stroke:#1a6b8a,stroke-width:2px style B fill:#fdebd0,stroke:#b7950b,stroke-width:2px style C fill:#ffecd6,stroke:#e67e22,stroke-width:2px style D fill:#d5f5e3,stroke:#27ae60,stroke-width:2px style E fill:#ffecd6,stroke:#e67e22,stroke-width:2px style F fill:#fadbd8,stroke:#c0392b,stroke-width:2px style G fill:#fdebd0,stroke:#b7950b,stroke-width:2px

6.1 项目结构

示例项目 agent-dispatcher 直接放在本教程目录下,通过资源下载区获取后解压即可使用:

agent-dispatcher/
├── main.py           # FastAPI 入口:提交任务、查询状态、托管页面
├── workflow.py       # 工作流引擎:四节点线性流水线
├── engines.py        # 引擎适配层:no-tty 调用 codex -p 与 claude
├── config.py         # 配置:引擎顺序、超时、端口
├── requirements.txt  # 依赖清单
└── index.html        # 前端界面

6.2 工作流引擎:四节点线性流水线

workflow.py 定义了四个节点的执行顺序——这是整个编排的"剧本":

# 工作流定义:节点按列表顺序执行,构成一条线性流水线
WORKFLOW_STEPS = [
    {"id": "parse", "name": "解析任务", "desc": "确认引擎与输入,生成执行计划"},
    {"id": "execute", "name": "引擎执行", "desc": "以 no-tty 方式调用底层 CLI 处理任务"},
    {"id": "validate", "name": "质量校验", "desc": "检查产出是否有效"},
    {"id": "report", "name": "生成报告", "desc": "汇总各节点结果与耗时"},
]

每个节点执行时记录状态(running / success / failed)与耗时。流水线的推进逻辑包含一个关键控制流——失败即截断,任一节点失败后剩余节点标记为 skipped:

pipeline = [parse, execute, validate, report]
for index, fn in enumerate(pipeline):
    self._run_step(index, fn)
    if self.status == "failed":
        # 失败截断:剩余节点全部标记 skipped
        for rest in self.steps[index + 1:]:
            rest["status"] = "skipped"
        return
self.status = "success"
self.result = self.steps[-1]["output"]

这正是 Workflow 的典型形态:步骤固定、顺序明确、有分支控制流。完整代码请查看 agent-dispatcher/workflow.py

6.3 引擎适配层:以 no-tty 方式调用底层 CLI

engines.py 负责把任务真正交给底层引擎,核心是 subprocess.run 的单次调用——被调进程没有交互终端,CLI 自动进入任务模式,stdout 即产出:

def run_engine(engine: str, prompt: str) -> str:
    argv = ENGINE_COMMANDS[engine] + [prompt]  # codex -> ["codex", "-p", prompt]
    result = subprocess.run(
        argv,
        capture_output=True,
        text=True,
        timeout=ENGINE_TIMEOUT,
    )
    if result.returncode != 0 or not result.stdout.strip():
        raise RuntimeError(f"{engine} 调用失败或无输出")
    return result.stdout.strip()

ENGINE_COMMANDS 来自 config.py,对应第 3、4 节的非交互命令前缀:codex 为 codex -p,claude 为 claude。本机两者都未安装时自动回退到 mock 引擎,保证示例在任何环境都能跑通完整工作流。完整代码请查看 agent-dispatcher/engines.py

6.4 后端接口:下发即返回,后台自主执行

main.py 提供提交、列表、详情三个接口,并托管前端页面。关键在 create_task:任务对象创建后交给后台线程,接口立即返回 task_id,不阻塞等待结果——这就是"下发"与"执行"的分离:

@app.post("/api/tasks")
def create_task(req: TaskRequest):
    wf = TaskWorkflow(req.prompt, req.engine)
    TASKS[wf.task_id] = wf
    # 下发到后台线程后立即返回,接口不阻塞(自主执行的关键)
    threading.Thread(target=wf.run, daemon=True).start()
    return {"task_id": wf.task_id, "engine": wf.engine}

前端随后轮询详情接口,即可看到四个节点从 pending 到 success 的实时推进。完整代码请查看 agent-dispatcher/main.py

6.5 前端界面

index.html 是单文件页面,功能分两块:顶部表单提交任务(任务描述 + 目标引擎选择),下方任务队列每 2 秒轮询刷新,展示每个任务的总体状态徽标、四节点进度条(含各节点耗时)以及最终产出或错误信息。

样式遵循 frontend-style 规范:主题色 #16baaa 及衍生色全部收敛为 CSS 变量;组件采用 BEM 命名(.card__title.badge--success.step--running 等);间距遵循 8px 网格系统;按钮与输入框均带 hover / focus / active 交互态和过渡动画;卡片标题使用主题色装饰线;表单校验色采用成功绿、警告黄、错误红三态;并针对移动端做了响应式断点。完整代码请查看 agent-dispatcher/index.html

6.6 运行与验证

conda create -n agent-dispatcher python=3.10
conda activate agent-dispatcher

uv pip install -r requirements.txt

uvicorn main:app --host 127.0.0.1 --port 8888

浏览器打开 http://127.0.0.1:8888,输入任意任务描述并下发:

  • 选择「模拟引擎」:无需安装任何 CLI,几秒内可见四节点依次点亮,产出为模拟输出;
  • 本机已安装 Codex 或 Claude Code:选择对应引擎(或保持自动探测),「引擎执行」节点会真实调用 CLI 的非交互模式完成处理。

观察两个要点:其一,提交后接口立刻返回,页面不卡顿(下发不阻塞);其二,「解析任务」节点先行点亮、其余节点依次推进直至报告产出——这正是"后台自主执行 + 工作流编排"的直观呈现。

7. 进阶:定时循环工作流

把上面的"一条命令后台执行"放进定时任务,就能实现无人值守的每日循环工作流——这也正是"个人 AI 工作流"的核心形态。

7.1 定时触发:让 Agent 每天自动干活

Linux / macOS 用 crontab,Windows 用"任务计划程序",都能做到定时触发一个后台 Agent 任务:

# crontab 示例:每天凌晨 2 点让 Codex 审查代码
0 2 * * * codex -p "审查 src/ 本周改动,报告潜在问题" >> /path/to/log.txt 2>&1
graph LR A[定时任务触发] --> B[后台执行 Agent 命令] B --> C[结果存留到日志/文件] C --> D{需要人工确认?} D -->|否| E[自动完成循环] D -->|是| F[通知人工,人工确认后继续] F --> E style A fill:#e8f4f8,stroke:#1a6b8a,stroke-width:2px style B fill:#ffecd6,stroke:#e67e22,stroke-width:2px style C fill:#fdebd0,stroke:#b7950b,stroke-width:2px style D fill:#ebdef0,stroke:#8e44ad,stroke-width:2px style E fill:#d5f5e3,stroke:#27ae60,stroke-width:2px style F fill:#e8f4f8,stroke:#1a6b8a,stroke-width:2px

7.2 无人值守与人工确认的平衡

完全无人值守适合低风险任务(审查、整理、生成草稿);涉及写入或发布的高风险操作,建议停在确认页,人工过一遍再放行。

任务类型 推荐模式 说明
代码审查、日志分析 全自动后台跑 只读操作,结果存留即可
生成文档、报告草稿 后台生成 + 通知 产出文件,人工审阅
提交代码、发布内容 后台执行 + 人工确认 停在确认页,人工放行

8. 延伸:ZCode 如何在 harness 内实现后台自主执行

前面几节分别讲了引擎(Codex、Claude Code)与调度层(DSH)的做法。本节以 ZCode 为例做一次机制剖析,它的特别之处在于:教程中分散在三处的机制——引擎的 no-tty 入口、调度层的后台代理、操作系统层的定时任务——在 ZCode 中被全部收进自身的 harness(宿主框架)内部,并做了一个关键下沉:后台化的不是 Agent 进程本身,而是会话内的"子任务",由事件通知驱动模型继续工作。整体链路如下:

graph LR A["no-tty 入口: --prompt 一次性调用"] --> B["任务模式: 跑完即止"] B --> C["权限预授权: mode yolo"] C --> D["子任务后台 detach 运行"] D --> E["完成事件注入对话"] E --> F["唤醒模型继续处理"] G["内建定时器: 到点触发"] --> H["拉起新会话执行任务"] H --> D style A fill:#e8f4f8,stroke:#1a6b8a,stroke-width:2px style B fill:#d5f5e3,stroke:#27ae60,stroke-width:2px style C fill:#ffecd6,stroke:#e67e22,stroke-width:2px style D fill:#ffecd6,stroke:#e67e22,stroke-width:2px style E fill:#ebdef0,stroke:#8e44ad,stroke-width:2px style F fill:#fdebd0,stroke:#b7950b,stroke-width:2px style G fill:#e8f4f8,stroke:#1a6b8a,stroke-width:2px style H fill:#fdebd0,stroke:#b7950b,stroke-width:2px

8.1 入口层:--prompt 一次性调用与 no-tty 判定

codex -p、Claude Code headless 是同一设计思路:ZCode CLI(随桌面端内置的 zcode.cjs)在检测到无交互终端或收到 --prompt 参数时进入任务模式——跑完即止、结构化输出。

# 一次性调用:不进交互界面,直接输出 JSON 结果
zcode --prompt "审查 src/ 的代码质量" --json --no-color

# 无界面续接已有会话,并指定工作目录
zcode --prompt "继续修复剩余告警" --resume <会话ID> --cwd <项目目录>
  • --prompt 对应 3.1 节 Codex 的 -p:一条指令直接出结果,不进会话
  • --json 对应 4.3 节 Claude Code 的 --output-format json:脚本从 JSON 的 response 字段取结果
  • --resume 是它多出的能力:会话历史持久化在本地,无界面下也能续接既有上下文

a4phone 开源项目的"远程续聊"功能就是这条链路的生产级用法——手机端发消息,服务器后台以 headless 方式续聊指定会话,再把回复推回手机。

8.2 授权层:--mode yolo 预授权

headless 模式下没有人可以点确认按钮,权限必须事前解决,这是"自主"的前提:

# 预授权模式下无人值守执行
zcode --prompt "整理 logs/ 并生成日报" --mode yolo --json

--mode yolo 表示工具调用跳过逐步人工审批直接执行;桌面端交互会话中,对应的机制是用户选定的权限模式与自动维护的预授权记录。7.2 节"无人值守与人工确认的平衡"在 ZCode 中的落地方式就是权限模式的选择,而不是执行中途弹窗。

8.3 会话内后台:子任务 detach 与事件唤醒

这是 ZCode 与 3.2 节 & 方案差异最大的一层。3.2 节的后台是把整个 Agent 进程扔给操作系统,输出要手动重定向,跑完没有任何通知;ZCode 把"后台"做进了 harness:

  • 后台运行选项:执行命令或派生子代理时可标记为后台任务,进程被 detach 成独立进程,立即返回输出文件路径与任务 ID,当前对话不被阻塞
  • 跨回合存活:后台任务不随当前回合结束而终止,模型可以先结束回合等待结果
  • 完成时反向唤醒:任务退出时 harness 生成一条通知注入对话流,把模型重新唤起继续处理结果——push 推送模型,无需任何人轮询
  • 控制通道:等待接口可阻塞查询结果(有超时上限),也可按任务 ID 随时取消
对比项 3.2 节 & 方案 ZCode harness 后台
后台化对象 整个 Agent 进程 会话内的子任务
输出存留 手动重定向到文件 harness 自动托管到输出文件
完成感知 无通知,需人工查看 事件通知自动唤醒模型
过程控制 kill 进程 任务 ID 级查询与取消

关键理解:ZCode 的"后台自主执行"本质是模型会话成为常驻的调度中枢——子任务在 harness 里跑,完成事件把模型再叫醒。

8.4 子代理并行:事件驱动替代轮询

与后台命令同理,子代理也可以后台并行:每个子代理拥有独立上下文,多个同时下发,完成时逐个通知父代理。对照第 6 节的 agent-dispatcher:示例项目用后台线程实现"下发即返回",前端每 2 秒轮询任务表,是 pull 拉取模型;ZCode 用"后台子代理 + 完成通知"把轮询省掉,是 push 推送模型。工作流编排也一样——agent-dispatcher 靠写死的四节点流水线推进,ZCode 则由模型按任务清单自主多回合推进。

8.5 调度层:harness 内建定时器

7.1 节用 crontab 定时触发,ZCode 把这一层也收进了 harness:内建持久化定时任务,支持 cron 表达式与"N 分钟后"两种表达,任务定义存放在工作区、跨应用重启存活,到点自动拉起新会话执行一段自然语言任务描述。与 crontab 的本质差别:crontab 调度的是一条 shell 命令,ZCode 调度的是一个带完整上下文的 Agent 任务

8.6 机制对照表

教程机制 工具 ZCode 对应实现
codex -p 一次性出结果 Codex --prompt + --json
无 TTY 自动切任务模式 Codex / Claude Code CLI 启动时 TTY 判定
headless 结构化输出 Claude Code --json 输出
续接会话 教程未涉及 --resume + 本地会话记录
后台代理 DSH 子任务后台 detach + 完成事件唤醒
& 扔后台 + 手动重定向 操作系统 harness 托管输出与通知
前端轮询任务表 agent-dispatcher 事件通知 push,免轮询
crontab 定时触发 操作系统 内建持久化定时器拉起新会话
无人值守的权限问题 教程未展开 --mode yolo / 权限模式预授权

一句话总结:教程里的"后台"指 Agent 进程脱离终端;ZCode 把"后台"下沉为 harness 的事件系统——入口靠 no-tty 判定进入任务模式,执行靠子任务 detach 与完成事件唤醒,调度靠内建定时器拉起新会话,自主性靠权限模式事前授权,四者闭环。

9. 总结

9.1 核心内容回顾

  • no-tty 与 headless:是让 Agent 脱离交互、后台执行的两个关键机制。no-tty 决定"进不进对话循环",headless 决定"看不看得见界面"。
  • 任务模式 vs 交互模式:Agent 工具检测到无交互终端时,会自动从"逐步确认"切到"跑完即止"的任务模式,这是无人值守调度的前提。
  • 四者对比:DSH 是调度层,通过后台代理 + 调度底层引擎实现后台执行;Codex 的 --print 模式最纯粹,适合单条命令直出结果;Claude Code 支持 headless + 结构化 JSON 输出;ZCode 把三层机制收进 harness 内部,后台子任务完成时由事件通知自动唤醒模型。
  • 定时循环:配合 crontab / 任务计划程序,一行命令即可实现每日自动工作的无人值守流程。
  • 实战示例:agent-dispatcher 项目演示了任务下发、后台线程自主执行、四节点工作流编排的完整闭环,前端可视化查看各节点进度。

9.2 常见问题与解答

问:后台执行时任务出错了怎么办?

答:把标准错误重定向到日志文件(2>&1 >> log.txt),方便事后排查;高风险任务建议停在确认页而非全自动。

问:no-tty 和 headless 必须同时用吗?

答:不必。编码 Agent 主要看 no-tty(决定是否进对话循环);只有涉及图形界面时才需要 headless。对 Codex、Claude Code 这类命令行工具,no-tty 通常就够了。

问:DSH 本身能像 Codex 那样用 --print 吗?

答:DSH 是调度层,不是直接执行引擎。它通过后台代理和调用底层引擎(Codex、Claude Code)来实现后台执行,因此"一条命令后台跑"最终由底层引擎的 no-tty / headless 模式承接。

问:ZCode 的后台执行与 DSH 的后台代理有何区别?

答:机制同构——都是"调度中枢派活、后台跑完通知"。差别在发起方式与粒度:DSH 的后台代理由调度层面向整个任务发起;ZCode 把后台化做成了对话内的执行选项,模型运行中随时可把一条命令或一个子代理放入后台,完成事件自动注入对话唤醒模型继续处理,无需人工查看输出。