Agent stack 终于开始变无聊了。
这听起来像是在骂人,但不是。所谓无聊,是魔法词失效之后,系统里的部件终于开始有名字。
今天我在几个不同项目里反复看到同一个形状:
tmux 能被看见的 runtime
eve 能被恢复的 runtime
lossless-claw 能被展开的 memory
12-factor-agents 自己掌控的 control flow
obscura 能嵌入的 browser surface
它们都不是完整答案。重点也正是这个。
tmux 不是 agent runtime,但它解释了 runtime
tmux 这件事是这个想法的最小版本。
一个 pane 本来只是 pane,直到 agent 能读它。然后它就变成了共享执行上下文。人类看到 server log,agent 看到同一个 server log。没人需要像中世纪仪式一样把 stack trace 复制进 chat。
tmux capture-pane -p -t work:server.0
tmux send-keys -t work:server.0 'pytest -x' Enter
这还不是产品,甚至几乎不是 interface。但它给了一个 invariant:
Work should live somewhere both human and agent can inspect.
Terminal 不够,chat transcript 也不够。真正有用的是它们之间的桥。
Raft 是 delegation 那一侧
Raft 从另一个方向有意思。
它关心的不是 “agent 能不能跑代码”,而是 “agent 作为 teammate 住在哪里”:名字、房间、inbox、held drafts,以及那些是 actions 而不是 dumps 的搜索结果。
大多数 agent products 都错在这里。它们把 agents 建模成永远在线的人类,于是每个 workflow 都变成更焦虑的 Slack。
Agent 不需要一直保持社交存在感。它需要一个放工作的位置,一个请求注意力的方式,以及一个被安全忽略的方式。
反复出现的切分是:
tmux preserves execution context
Raft preserves delegation context
真正有意思的产品是中间的 glue。“agent 还在那边工作”需要变成“我知道自己是否需要介入,以及在哪里介入”。
没有这个 glue,tmux 只是 remote shell,Raft 只是漂亮 inbox。
eve 让 agent execution 变无聊
Vercel 的 eve 并不是想做一个更聪明的 coding agent。它想让 agent apps 可以被部署。
有用的模型很简单:
session -> turn -> step
Session 可以活好几天。Turn 是一次用户触发的 run。Step 是一个可以 checkpoint 的 model/tool 边界。
这很重要,因为真实 agent work 放不进一次干净的 request-response。它会等 OAuth,等人,等 child agent,也会在 deploy 到一半时 crash,因为电脑就是电脑。
我喜欢的词是 parked。
不是 failed,不是 done,是 parked。
running
waiting for approval
waiting for OAuth
waiting for subagent
waiting for human input
resumable later
Agent runtimes 需要这个,多过另一个 prompt trick。Agent 应该可以停下来,同时不丢脑子。
lossless-claw 让 summaries 没那么可疑
大多数 compaction 像是把整本书烧掉,只留下封底简介。
lossless-claw 做得更合理:保留 raw transcript,在上面建 summary DAG,并允许 model 在需要细节时展开 summary。
关键点不是 “更好的 summaries”,而是:
A summary is a navigation index, not a replacement for memory.
这会改变整个 trust model。
Rolling summary 说:相信我,事情是这样的。
Lossless summary 说:大概是这样;如果你需要 exact commands、errors、tool calls 或 source messages,这里有 handle。
这更接近我想要的 agent memory:
raw transcript source of truth
leaf summary local compression
condensed summary higher-level map
expand query drill down when confused
focus brief temporary task lens
focus brief 尤其好。有时候 agent 不需要更多 memory,它只需要一个针对当前任务、当前时刻的临时 view,而且不要污染 canonical memory。
12-factor-agents 说出了安静的部分
12-factor-agents 里最重要的一句话基本是:
Tool calls are structured outputs. You own the control flow.
这听起来很显然,直到你看到多少 agent frameworks 把 loop 藏起来。
Model 不应该执行事情。Model 应该提出 intent。Runtime 决定这个 intent 意味着什么。
fetch_open_issues execute and continue
create_issue hold draft, ask approval
request_human_input pause and notify
repeated_tool_error compact error, maybe repair
third_failure stop pretending, mark blocked
这是 toy agent 和可信系统之间的线。
另一个有用的想法是 event thread as state。不是 chat log,不是一堆 messages,而是一个可以投影成不同 views 的 event log:
event log
-> prompt context
-> task timeline
-> audit trail
-> notification state
-> memory summary
LLM 看到一个 projection,UI 看到另一个,database 保留 source of truth。
这大概就是形状。
Obscura 是更小的 browser surface
Obscura 更 tactical,但也在这个图里。
Headless Chrome 很大。很多 agent work 并不需要 pixels。你需要 DOM、JS、links、text、cookies、network requests,可能还需要一个给 Playwright 用的 CDP endpoint。
Obscura 的问题是:agents 的 browser surface 能不能更小?
obscura fetch https://example.com --dump markdown
obscura serve --port 9222
obscura mcp --stealth
它不做 screenshots,也不会神奇绕过 Cloudflare。很好,这让边界更清楚。
对 agent browsing 来说,“能读页面并点表单”往往比“完美复刻 Chrome”更重要。轻量的 DOM/JS/CDP/MCP browser 是一个有用 primitive。
vibes 下面的 stack
贯穿线是:agents 越来越不像 chatbots,而更像一个里面塞了奇怪 language model 的 operating system。
不是宏大叙事里的 OS,而是无聊意义上的 OS:
process model
state model
memory model
IO model
permission model
human interrupt model
Model 只是一个组件。也许甚至不是最有意思的那个。
今天之后我看到的 stack 是:
human-facing workspace
identity, inbox, held drafts, intervention points
control-flow layer
typed intents, policy, approvals, retries, blockers
durable runtime
session, turn, step, pause, resume, stream
execution surface
terminal panes, browser sessions, logs, tests, files
context layer
raw history, summaries, projections, expansion
如果任何一层假装自己是其它所有层,产品就会变怪。
Chat 试图当 runtime,于是长任务消失。
Runtime 试图当 memory,于是 context 变成上一轮 prompt 里塞得下的东西。
Memory 试图当 truth,于是 summaries 开始自信地撒谎。
UI 试图当 collaboration,于是 agents 变成吵闹的假同事。
修复方式不是一个更好的 agent,而是更好的边界。
我会偷什么
从 tmux 偷:named、inspectable execution surfaces。
从 Raft 偷:agents 需要 delegation context,不需要假的 social presence。
从 eve 偷:parked work 应该是一等状态。
从 lossless-claw 偷:summaries 应该是 expandable indexes。
从 12-factor-agents 偷:own the loop;tool calls 是 pending intent。
从 Obscura 偷:给 agents 的 browser automation 可以比 Chrome 更小。
好笑的是,这些都不像 AGI discourse。它更像 backend engineering、product states,以及一堆终于有名字的烦人 edge cases。
很好。
这说明我们可以开始构建了。