跳到主要内容
Engineering Notes2026年6月9日· Deskmate Team

从工具爆炸到 app 伪 shell

为什么 CLI 范式对 LLM 友好,以及 Deskmate 如何用 app 伪 shell 渐进披露能力。

给 Agent 接上几十个工具,听起来是能力的胜利,实际上常常是一场退化。当工具数量越过某个阈值,模型不再“会用更多东西”,而是开始在相似的工具之间犹豫、误用参数、把简单任务拆成错误的步骤。我们最后选择了一条看起来“复古”的路:把一整套能力收敛成一个 app 伪 shell。

LLM 面对几十个工具的问题

每暴露一个工具,模型的决策空间就要膨胀一次。它需要在每一步回答两个问题:现在该用哪个工具,以及这个工具的参数到底长什么样。工具列表里塞了三十个函数时,这两个问题都会变难。

具体的失败模式很一致:

换句话说,工具不是越多越好,而是越多越需要结构。问题不在能力,而在能力的呈现方式。

CLI 是 LLM 熟悉的接口

我们没有发明新范式,而是借用了一个模型早已见过无数次的接口:命令行。预训练语料里有海量的 shell 会话、--help 输出、man page 和 README 片段,CLI 的形状对 LLM 来说是熟悉且可预测的。

把能力组织成子命令,模型就能复用它对 CLI 的直觉:动词在前、子命令分层、选项用 --flag、状态码非零代表失败。于是工具系统只需要暴露一个入口:

app --help

app 之下挂着 mcpagentschedule 等子命令,每一类能力是一个命名空间,而不是顶层工具列表里又一个扁平的函数。

app –help 的渐进披露

渐进披露(progressive disclosure)是这套设计的核心。模型一开始只需要知道 app 存在,以及顶层有哪些子命令;具体某条命令的参数,等真要用时再问。

这正是 --help 天然提供的:

app agent list
app schedule list

需要更细的用法时,模型可以追加 --help 拿到该子命令的选项说明,而不必把所有定义预先塞进上下文。能力是“按需展开”的——这让常驻 token 大幅下降,也让模型的每一步决策都落在一个更小、更清晰的范围里。

–json / –dry-run / –yes 的统一语义

零散工具的另一个隐性成本是语义不一致:这个返回 JSON、那个返回自然语言;这个会直接执行、那个先要确认。模型必须为每个工具单独记住脾气。

伪 shell 让我们可以把一组横切语义统一成全局约定:

app mcp status --json

一旦这些约定在所有子命令里一致成立,模型就不必逐个工具地学习例外。它学会的是一套语法,而不是几十个特例。这里要诚实地说明:Deskmate 仍处于 early access,子命令的覆盖面和这些 flag 的一致程度还在补齐,个别命令可能尚未支持全部约定。

和 MCP 的关系

伪 shell 不是要取代 MCP,而是和它分工。MCP 负责把外部世界——文件系统、浏览器、第三方服务、你自己的脚本——接入 Agent;app 则负责把这些接入后的能力,以及 Deskmate 自身的内建能力,统一成一致的调用界面。

你可以把 MCP 理解成“插上更多能力”,把 app 理解成“用同一种语法去驱动它们”。app mcp status 这类命令本身就是用伪 shell 去观察和管理 MCP 的状态——两层是协作关系,而非二选一。

未来扩展方向

这套设计最让我们满意的一点,是它的扩展成本几乎恒定。新增一类能力,就是新增一个子命令,而不是往工具列表里再塞一个需要模型重新认识的函数。顶层接口不变,渐进披露的机制不变,--json / --dry-run / --yes 的语义也不变。

接下来的方向大致有几条:让 --help 输出更适合模型消费,补全更多子命令的横切 flag,让 --dry-run 的预演结果更结构化。它们都不需要重做接口,只是在同一个形状里继续填充。

工具不是越多越好。真正的杠杆,是给模型一个它早就认识的接口,然后把能力按需、按一致的语义交到它手上。

继续阅读

把这些想法变成你的桌面 Agent

下载 Deskmate,连接模型与工具,开始处理真实任务。