Agent Computer Interface 的终局,不会是 CLI
最近一波 CLI-first 项目很热。
像 CLI-Anything、opencli 这类项目,都在讲同一个故事:终端是 Agent 和软件世界之间最自然、最通用的桥。更大的行业叙事也差不多是这个方向:给模型一个 shell,把一切都包成命令,再把接口标准化,Agent Computer Interface 这件事,好像就差不多解决了。
我不这么看。
不是因为 CLI 没用。
不是因为终端会消失。
更不是因为 Agent 应该重新回去点 GUI。
我不认同,是因为这里有一个很典型的误判:
很多人把 “能发命令”,误当成了 “能构成工作环境”。
这两件事,不是一回事。
CLI 真正的问题,不是 action 不够强。
而是它对 state 的处理太弱了。
CLI 可以执行命令。
但它承载不了一个世界。
这就是我整篇文章真正想说的事。
为什么 CLI 这个故事这么容易让人信
因为它确实很顺。
CLI 的优点摆在那里:
- 通用
- 可组合
- 容易暴露给模型
- 开发者已经很熟
- 天然就是文本输入输出
对人类来说,这通常已经够用了。
对 Agent 来说,这套叙事看起来甚至更顺:
- text in
- text out
- 命令清晰
- 包装成本低
- 还很容易标准化
于是行业就很自然地开始讲一个很顺的故事:
给 Agent 一个 shell。
把一切都变成 CLI。
把接口标准化。
这事就成了。
这个故事很优雅。
但它少了一层。
因为 shell 确实很擅长一件事:
发命令。
但真实工作从来不只是发命令。
真实工作,发生在一个不断变化、持续演化、带状态的环境里。
而 CLI 恰恰是在这里开始露出短板。
说得更直接一点:
CLI 解决的是“怎么发命令”。
但 Agent 真正缺的,往往不是再多一个命令层,
而是一个能把当前状态稳稳托住的工作层。
所以更好的心智模型,不是“给 Agent 一个更聪明的终端”。
而是:
把一个 IDE 装进 Agent 的上下文里。
这才是我觉得整个行业还没真正想透的地方。
真正的问题:CLI 一直在重新看一个已经变了的世界
CLI 的核心弱点,其实非常简单:
它一次又一次地重新看世界,但每次看到的结果,在生成出来的那一刻就已经被冻结了。
而真实环境还在继续变化。
于是模型最后拿到的,不是“当前世界状态”。
而是一串越来越旧的快照。
这不是小瑕疵。
这是 Agent interface 里最核心的结构性问题之一。
Case 1
在 t1,LLM 调用:
ls -la
它看到了当前目录下的文件和文件夹列表。
在 t2,LLM 创建了一个新文件。
这时世界已经变了。
但 t1 那份 ls -la 输出不会自动变化。
它还躺在上下文里,像是“当前状态”一样继续存在。
在 t3,LLM 只能再跑一次 ls -la,才能看到新状态。
这时候问题就出来了:
上下文里同时存在两份同一个目录的快照:
- 一份来自新文件出现之前
- 一份来自新文件出现之后
从“历史上是否发生过”来说,两份都是真的。
但从“现在该以哪份为准”来说,只能有一份是当前有效状态。
于是模型就被迫去做额外工作:
自己判断哪份已经旧了,哪份才代表现在。
Case 2
文件也是同样的问题。
在 t1,LLM 调用:
cat file.txt
它读到了文件内容。
在 t2,LLM 修改了 file.txt。
这时文件已经变了。
但 t1 那份 cat 输出不会消失。
它还在上下文里。
在 t3,LLM 再调一次 cat file.txt。
于是上下文里就同时有了这个文件的两个版本:
- 一个是旧的
- 一个是新的
然后模型还得自己判断:
- 哪个已经过时
- 哪个才是当前版本
- 现在应该基于哪个继续推理和行动
所以问题根本不是 CLI 能不能把事做完。
CLI 当然能。
真正的问题是:
CLI 会把“从一堆静态快照里重建当前世界”这份额外劳动,悄悄甩给模型。
每一次重复 read,本质上都不是“更新状态”。
而是“再追加一份新快照”。
这不是 UX 问题,这是状态问题
很多人听到这里,会很自然地说一句:
“那就再跑一遍命令不就好了?”
问题恰恰就在这里。
再跑一遍,不是解决方案。
它本身就是问题的一部分。
因为你每再跑一次,实际上都是在往上下文里再塞一份观测结果:
- 你没有更新旧状态
- 你没有让旧视图失效
- 你没有移除已经过期的信息
- 你只是继续往上下文里堆一层新快照
人类通常能靠经验把这件事脑补过去。
我们看 terminal history,大脑会自动做这些事:
- 这条是旧的
- 那条是新的
- 这一份已经被后面那份覆盖了
- 中间发生了一次修改
但 LLM 不会天然获得这种能力。
它得自己花:
- 上下文容量
- 注意力预算
- 推理预算
去做状态对齐。
所以 CLI 不是一个“中性的接口”。
它其实偷偷干了一件事:
把状态一致性这个 runtime 层的问题,外包给了模型。
这是一个代价非常高的设计选择。
模型应该负责解决任务。
runtime 应该负责解决状态一致性。
行业真正搞混的地方
现在这波 CLI 热潮,背后其实有一个很典型的 category error:
很多人默认认为:
既然 CLI 是一个很强的命令界面,
那它自然就能成为 Agent Computer Interface 的最终形态。
问题就在于:
命令界面 不等于 工作界面。
一个真正能让 Agent 干活的工作界面,不只是能触发 action。
它还得能做到这些事:
- 让状态持续存在
- 让状态原地更新
- 把过期状态移出去
- 控制当前什么该看、什么不该看
- 让动作和当前上下文对得上
- 保留对象的生命周期
CLI 并不会天然把这些事情当成一等 runtime 问题来处理。
CLI 给你的,是一份 transcript。
而 transcript 不是 workspace。
所以我不认同“CLI 会成为 Agent 最终界面”这个判断。
CLI 最多只是这套栈里的一层。
它不是全部。
更好的心智模型:把 IDE 装进 Agent 的上下文里
真正更对的 framing 不是:
给 Agent 一个更强的 terminal
而是:
把一个 IDE 装进 Agent 的上下文里
这才是关键的一跳。
也就是说,我们不要把 Agent 理解成一个不断通过 shell 去偷窥世界的操作员。
而要把它理解成一个在实时工作环境里持续干活的开发者。
不是人类桌面上的 IDE。
而是一个活在 Agent 上下文内部的 IDE。
这样一来,Agent 就不是不停地通过 terminal output 去重新理解世界。
它面对的是一组还活着的视图。
Case 3:当 app 真的活在上下文里,会发生什么
现在我们来看同样的文件工作流,在 Agent-oriented IDE 里会怎么变。
在 t1,LLM 调用 IDE 的 Read File。
但 tool result 不会把整份文件内容原样 dump 回来。
在 t2,系统会把一个 File View 插入上下文。
这个 File View 是一个可见的状态对象,模型可以直接围绕它工作。
在 t3,LLM 调用 Edit File 去修改 file.txt。
同样,tool result 不会再返回一整份新的文件内容。
在 t4,系统只做一件事:
更新已经存在的那个 File View。
在 t5,当这个文件不再需要时,LLM 调用 Close File。
在 t6,这个 File View 会被直接从上下文里移除。
这就是完全不同的一类接口。
模型不再需要一边看着多个 stale snapshots,一边自己脑补当前状态。
它是在操作一个带生命周期的活对象。
这就是最关键的区别:
CLI 给模型的是对象的快照。
Agent App 给模型的是由 runtime 管理的活对象。
你一旦看清这个差异,整个行业现在围绕 CLI 的很多判断,都会开始松动。
为什么 Agent Apps 才是缺的那一层
Agent App 不是“给工具包了一层更好看的壳”。
它也不是“格式更漂亮的 prompt engineering”。
它是一个更高一级的抽象。
一个好的 Agent App,至少应该给模型这些东西:
1. 原地更新的状态
CLI 的默认模式,是不断追加新观测。
Agent App 的模式,是更新当前对象本身。
这意味着:
- 更少重复
- 更少歧义
- 更少 stale context
2. 生命周期
一个文件可以被打开、更新、关闭。
一个搜索视图可以出现、变化、消失。
一个 workspace 可以跨多步操作保留局部状态。
这才是真正工作环境该有的样子。
3. 上下文卫生
CLI 的老问题是:旧观测会不断堆积。
Agent App 的优势是:不相关状态可以被明确移除。
这一点比很多人以为的重要得多。
因为很多 Agent 的失败,不是因为“工具不够多”。
而是因为:
上下文太脏了。
4. 状态和动作的对齐
在 shell 里,模型看到的是一堆输出,再去别处调命令。
在 Agent App 里,当前视图和当前合法动作可以天然绑在一起。
这会更安全,也更连贯。
5. 少把认知债务甩给模型
这可能才是最关键的一点。
CLI-first 的设计,默认要求模型自己完成这些额外劳动:
- 识别过期观测
- 对齐冲突快照
- 判断哪个动作该作用在哪个对象上
- 跟踪哪些信息还相关
- 在脑子里维护当前世界状态
这不是什么“模型更聪明”。
说得更直白一点:
本来应该由界面和 runtime 解决的脏活,最后全甩给模型了。
更好的 interface,应该把这部分负担拿走。
这也意味着:CLI 并不会“取代 MCP”
现在讨论里另一个常见误区,是把 CLI 和 MCP 当成同一层东西的对手。
其实不是。
它们压根不在同一个层级。
- MCP 更像能力接入层
- CLI 更像命令层
- Agent Apps 解决的是带状态的工作层
所以我不认同“CLI 会取代 MCP”这个说法。
因为这个 framing 从一开始就歪了。
哪怕你把全世界所有工具都包成 CLI,
你还是绕不开那个真正的问题:
Agent 到底是在什么地方工作?
是在一串不断变长的命令 transcript 里?
还是在一个能承载状态、视图、对象生命周期的工作环境里?
这才是真正的分叉点。
人类开发者其实早就给过答案了
人类开发者不是靠不断把文件快照塞进自己脑子里工作的。
人类开发者工作在 IDE 里。
为什么?
因为 IDE 不是“更好看的 shell”。
IDE 真正的价值在于,它能持续托住一个活着的工作世界:
- 打开的文件
- 当前视图
- 搜索结果
- diagnostics
- 正在进行中的修改
- 一直活着的上下文
这也是为什么“把 IDE 装进 Agent 的上下文里”这个心智模型这么重要。
因为它直接点破了今天很多系统缺的到底是什么:
我们给了 Agent 命令。
但我们没有给它真正的 workspace。
我的判断
CLI 很真实。
CLI 很有用。
CLI 在 Agent 系统里肯定会长期存在。
但现在这波热潮,明显高估了它。
现在的问题在于,CLI 正在被很多人当成 Agent Computer Interface 的终局形态。
我不这么看。
因为 Agent 最核心的问题,不只是:
怎么调 action
而是:
怎么在一个持续变化、带状态、会不断演化的世界里工作,而不让模型一遍又一遍地从旧快照里重建当前现实。
这正是 CLI 的短板。
所以我觉得下一层真正重要的东西,不会只是另一个 shell wrapper。
而会是 Agent Apps:
- 活在 Agent 上下文里的 app
- 能持有状态的 app
- 能原地更新视图的 app
- 能移除 stale context 的 app
- 让模型操作对象,而不是淹死在 transcript 里的 app
更可能的未来,不是“CLI everywhere”。
更像是:
- CLI 作为命令层
- MCP 作为能力接入层
- Agent Apps 作为真正的工作层

这才是现在真正缺的那层抽象。
你一旦看清这一点,就会发现当下这波 CLI hype 更像什么:
它不是终点。
它更像是通往终点路上一个很好用、但远远不够的中转站。
真正会赢的 Agent interface,不会是那个“能暴露最多命令”的接口。
它会是那个最能把世界状态维持得连贯的接口。