Unix 不是为特工准备的
Unix Isn't for Agents

原始链接: https://pwhite.org/unix-is-not-for-agents

## 在 Unix 系统上运行 AI Agent 的问题 目前,运行像 Claude Code 这样的 AI Agent 常常感觉像是一种权宜之计——依赖于像 `tmux` 这样的工具来维持 SSH 断开连接后的会话。这种变通方法凸显了 Unix 系统处理进程方式与 AI Agent *所需* 之间的根本不匹配。 Unix 传统上将进程定义为交互式(绑定到终端,断开连接后死亡)或守护进程(后台进程,分离且持久)。AI Agent 既不是前者也不是后者;它们需要长时间运行、有状态的交互,*而无需* 假设持续的人工干预。Unix 缺乏一种“持久交互式进程”的基本概念,迫使用户模拟它。 然而,Erlang 虚拟机 (BEAM) 提供了一种潜在的解决方案。BEAM 专为强大的电信系统而设计,将进程视为轻量级、隔离且持久的实体,通过消息进行通信。至关重要的是,BEAM 中的“交互式”意味着接受消息,而不是需要终端连接。 这种模式允许 Agent 作为持续运行的进程存在,无论连接状态如何,都能维护状态并响应来自任何来源(用户、另一个 Agent 或工具)的输入。Phoenix LiveView 等框架展示了这种能力。最终,一个真正适应 Agent 的环境需要将持久交互视为默认状态,超越数十年前的 Unix 交互式/守护进程范例的限制。

## Unix 与“代理性”系统 - Hacker News 讨论 一篇质疑 Unix 是否适合“代理性”人工智能系统(如 Claude/Codex 驱动的系统)的文章,在 Hacker News 上引发了争论。核心论点在于希望实现持久、交互式的会话,*无需*依赖 `tmux` 或 `screen` 等工具。 评论者普遍认为 Unix 在基础层面上表现出色,为创建定制体验提供构建块。缺乏内置持久性并非缺陷,而是一种特性,允许通过套接字、WebSocket 或其他输入/输出流进行灵活组合。 评论对原文关于 Erlang 持久性能力的说法提出了批评,并指出需要手动实现或使用外部数据库进行更正。讨论还强调了文本用户界面 (TUI) 的局限性——特别是它们与管道输入/输出的不兼容性——以及对支持纯文本界面的偏好。最终,共识似乎是 Unix 提供了构建代理性系统的*手段*,但本身并不*提供*所需的应用程序级服务。
相关文章

原文

Or: why tmux is a hack and BEAM might be the answer

I've been running Claude Code from a cloud VM lately. The workflow is: SSH in, start tmux, run Claude, work. When I disconnect, tmux keeps the session alive. When I reconnect, I reattach. It works.

But it's a hack. And the more I think about it, the more I realize the hack is papering over a fundamental mismatch between what AI agents need and what Unix provides.

* * *

Unix has two modes for processes: interactive and daemon.

Interactive means attached to a terminal. A human is present. When the terminal disconnects—when you close the laptop, lose the SSH connection, hang up the phone line (this is where SIGHUP comes from)—the process dies. This is the default. This is what Unix assumes you want.

Daemon means detached from any terminal. The process explicitly orphans itself: double fork, setsid(), close stdin/stdout/stderr. It runs in the background forever, logging to files, never interacting with anyone directly. Think web servers, databases, cron.

These two modes made sense for the world Unix was designed for. You're either a human typing commands, or you're a service running unattended. Interactive or automated. Present or absent.

Agents are neither.

* * *

An AI agent is:

Long-running—like a daemon. It might work on a task for hours. It needs to survive disconnection.

Interactive—like a terminal session. It's not just logging to a file. It's having a conversation. It needs input and produces output that a human (or another agent) will read and respond to.

Stateful—it maintains context. The conversation history, the working state, the plan it's executing. This state is the whole point.

Reconnectable—you should be able to disconnect, go for a walk, reconnect from your phone, and pick up exactly where you left off.

Unix assumes interactive sessions are mortal. Agents need interactive sessions that are immortal.

There's no Unix primitive for "persistent interactive process." The model assumes that if you want interaction, there's a human present, and humans eventually leave. When they leave, the session ends.

* * *

This isn't just convention. It's baked deep into the system.

The kernel tracks "controlling terminals." When you log in, your shell gets a controlling terminal. Processes you spawn inherit it. When the terminal goes away, the kernel sends SIGHUP to the session leader, which propagates to child processes. They die by default.

POSIX standardizes this. Sessions, process groups, controlling terminals, SIGHUP behavior—it's all in the spec. The assumption "interactive means ephemeral" is load-bearing infrastructure.

To make a daemon, you explicitly opt out: detach from the terminal, become a session leader with no controlling TTY, close the standard file descriptors. You're not just running in the background—you're abandoning the entire interactive paradigm.

There's no middle path. No "stay interactive but don't die when the terminal disconnects." The model doesn't have room for it.

* * *

tmux is a hack to create the missing primitive.

It's a daemon that pretends to be a terminal. Your shell thinks it's talking to a TTY, but it's actually talking to tmux, which buffers everything in memory. When you disconnect, tmux keeps running. When you reconnect, it replays the buffer and hands you back control.

This works. I use it every day. But it's a userspace workaround for a kernel-level assumption. You're running a program that fakes the existence of a persistent interactive session because the operating system doesn't believe such a thing should exist.

For AI agents, we're all running tmux. Or screen. Or nohup with tail -f. We're all working around the same missing primitive.

* * *

What would a system designed for agents look like?

Here's the interesting thing: it already exists. It's called BEAM.

BEAM is the Erlang virtual machine. It was designed in the 1980s for telephone switches—systems that needed to run forever, handle millions of concurrent connections, and never go down. The design constraints accidentally produced exactly what agents need.

In BEAM, processes are:

Lightweight—you can have millions of them. Each one costs about 2KB. They're not OS processes; they're VM constructs.

Isolated—each process has its own heap. No shared state. If one crashes, others are unaffected.

Addressable—every process has a PID. You can send it messages from anywhere. There's no concept of "attached to a terminal."

Persistent—processes run until they're done or they crash. There's no "session" that ends when someone disconnects. The process is the session.

Supervised—processes can be organized into supervision trees. If one dies, its supervisor can restart it. The state can be reconstructed.

In BEAM, "interactive" doesn't mean "attached to a terminal." It means "accepting messages."

This is the key inversion. Unix thinks interactivity requires a human present at a terminal. BEAM thinks interactivity is just message passing. You can send messages to a process from a terminal, from another process, from a web socket, from anywhere. The process doesn't care. It just receives messages and responds.

* * *

An "agent shell" built on BEAM might look like this:

Each agent is a process (a GenServer in Elixir terms). It has state—conversation history, current task, memory. It receives messages: user input, tool results, signals from other agents. It sends messages: output to display, requests to tools, coordination with other agents.

The agent process runs indefinitely. It doesn't care if you're connected. You "attach" to an agent by subscribing to its output and sending it your input. You "detach" by unsubscribing. The agent keeps running either way.

Phoenix LiveView—Elixir's real-time web framework—already does most of this for web UIs. You connect, you get a stateful server-side process that pushes updates to your browser. You disconnect, the process can keep running. You reconnect, you reattach to the same process.

The pieces exist. They just haven't been composed for agent use cases yet.

* * *

Why does this matter?

Because we're building the infrastructure for AI agents on a foundation that assumes agents shouldn't exist. Every time you SSH into a server and start tmux to run Claude Code, you're working around a fifty-year-old assumption about what "interactive" means.

The workarounds work. But they're friction. They're complexity. They're another thing to manage, another thing to break, another thing that makes agent usage feel like developer infrastructure instead of just... using a computer.

Someone is going to build the agent-native environment that treats persistent interactive execution as the default, not the exception. It might be built on BEAM. It might be something else. But it won't be built on the Unix interactive/daemon dichotomy, because that dichotomy doesn't have room for what agents actually are.

The computer science is already done. Erlang solved this in 1986. We just need to apply it to the agent problem—to build the shell that treats agents as first-class citizens instead of weird edge cases that need tmux to survive.

联系我们 contact @ memedata.com