Skip to content
预计 1 分钟右侧目录可快速定位

进程怎样启动、退出并留下可观测输出:Linux Process、Signal 与 stdout/stderr ​

前置:v0.12 可运行、可恢复、可观测;基本 Linux CLI
核心问题:Worker 或 Shell Tool 收到 SIGTERM 后,哪些进程和输出要先收束,哪些 Runtime 事实必须在退出前提交?

Harness 最终仍然运行在操作系统进程里。只要系统会启动 Worker、Shell Tool 或 Sandbox child process,就必须能回答三个问题:进程属于谁、怎样被终止、退出前哪些 Runtime 事实必须先持久化。

Mental Model ​

text
Image/config → container/process start → network/filesystem/resource boundary → health → signal → graceful shutdown

最终 Agent 服务仍运行在 OS process 中:signal、stdio、file permission、network、resource limit 决定它能否正确启动、观测和退出。

Linux Process ​

进程是 Runtime 的资源与生命周期边界。API、Worker 和 Sandbox child process 都要管理 PID、父子关系、process group、退出码与僵尸回收;容器里的主进程语义也建立在这些 OS primitive 上。Shell Tool 尤其不能只记住一个命令字符串,否则取消时可能只杀掉父进程,却把真正工作的子进程留在后台。

Signal ​

Signal 是操作系统通知进程生命周期变化的机制。对服务进程来说,SIGTERM 通常表示“开始有序退出”,SIGKILL 则不给应用清理机会。

这里先记住一个边界:Signal 只通知进程,Run 是否完成、checkpoint 还是取消仍由 Runtime policy 决定。 完整 draining、lease、flush 和 rollout 顺序放到 20-05 的 Graceful Shutdown 统一讲。

stdout / stderr ​

在容器环境里,stdout/stderr 是进程与日志采集平台的接口,而不是持久化存储。结构化事件可以写标准流;大体积 Tool 输出、完整 trace artifact 或需要长期保留的证据应进入专门的 artifact/store。日志还需要大小限制和敏感字段 redaction,避免把 secret/raw prompt 当调试文本永久外泄。

最小实现 / 数据结构 ​

dockerfile
FROM python:3.14-slim
WORKDIR /app
COPY pyproject.toml uv.lock ./
RUN uv sync --locked --no-dev
COPY src ./src
CMD ["uv", "run", "python", "-m", "shadow_harness"]

在 Shadow Harness 中怎么落地 ​

最终 Harness 至少要区分 API process、Worker process 和 Sandbox child process。API 负责接收命令/事件流;Worker claim 并推进 Run;Sandbox child 只执行受限 Tool/command。

ProcessManager/Runner 应记录 PID/process group、exit code 和 cancellation handle,使“停止一个 Tool”能真正终止它的子进程树。至于 Worker 收到 SIGTERM 后怎样 draining 并保护 active Run,由 20-05 统一负责,避免在两篇重复一套 shutdown 协议。

Failure Modes ​

Shell Tool 只杀父进程,子进程继续运行 ​

症状: Runtime cancel command 后父 shell 退出,但测试服务/编译器子进程仍占 CPU、端口或文件。

处理: 管理 process group/tree,并把 exit/cancel result 归一化成 ToolExecution fact;服务级 SIGTERM/Graceful Shutdown 由 20-05 处理。

如何验证 ​

Case断言
Shell Tool 产生 child processcancel 后整个 process group 按 policy 收束,不留下 orphan process。

自测 ​

  1. 容器收到 SIGTERM 后直接被杀,与应用捕获信号开始 drain 有什么区别?
  2. stdout/stderr 没有结构化关联信息时,为什么容器“有日志”仍不足以定位某个 Run 的退出原因?

Sources ​

AI Engineering · Agent · Harness · Backend Systems