为什么我选择做一个"小工具":IntelliAI 插件的设计哲学与 Engine 架构

random-pic-api

写在前面

最近在做 IntelliAI Terminal 这个插件的时候,我被人问得最多的两个问题是:

  • 为什么你做的功能这么少?
  • 为什么不直接做成 Claude Code 或者 Codex 那种大而全的 AI CLI?

这两个问题其实是同一个问题:这个工具到底应该负责到什么程度?

本来我准备写一篇”单一职责”,一篇”为什么不做大而全”,一篇”Engine 架构的思考”,再来一篇”Less is More”。后来自己读了一遍发现,这四件事根本就是一件事,只是切面不同。所以索性合并成一篇,把当时的思路一次性讲清楚。

先把结论放在前面,免得后面聊跑偏:

我不打算做一个”替你思考一切”的工具,只想在你已经在思考的时候,帮你快一步。

下面展开聊。


终端这个场景,到底特殊在哪里

AI 工具这两年发展得很快,从代码生成到全自动 Agent,从 CLI 到 IDE 集成,能力一个比一个猛。但我在真实使用里观察到一个有意思的现象:工具越强,用户在日常使用时反而越谨慎。

尤其是终端。

终端是个很特殊的环境:

  • 直接作用于系统
  • 容错成本极低
  • 错误影响可能不可逆

你在 IDE 里让 AI 改一段代码写歪了,撤销一下就好。但你在终端里让 AI 跑了一个命令把目录删了,那是真的删了。这种差别决定了我在动手写插件之前,必须先回答一个问题:这东西该负责到哪里?

终端操作的真实样子

我自己观察了一下平时在终端里做的事情,发现绝大部分是这种:

  • 查一个进程
  • 看一段日志
  • 清理一批临时文件
  • 跑一次构建

这些命令有几个共同特点:

  • 高频,一天能重复几十次
  • 即时,需要马上出结果
  • 一次性,用完就忘
  • 上下文很短,就是一个简单的意图
  • 失败必须能立刻回滚

拿这种场景去对照 Claude Code、Codex、Gemini CLI 这类工具,其实会发现它们很强,但强的是另一个方向——复杂工程修改、多步骤规划、长时间交互式推理、跨文件操作。真让它们来处理”我就是想看一下某个容器的日志”,流程会变成这样:

  1. 切换到 CLI 工具
  2. 把当前环境描述一遍
  3. 等它输出一堆解释
  4. 从解释里把命令挑出来
  5. 复制回终端
  6. 执行

为了一行命令付出这些成本,换我我也不愿意。

这不是功能强弱的问题

这里我得澄清一下,我不是说大而全的工具不好,它们在复杂任务里很出色。只是设计目标不一样。简单对比一下:

维度大而全 CLI我做的这个插件
目标AI 开发助手 / 平台终端命令生成
场景长任务、复杂交互高频、即时、小动作
侵入性高,要学新工具基本为零
上下文由工具维护来自真实 IDE 和 Terminal
失败成本高,可能跑偏、误操作低,最多不生成命令

如果一个工具需要你”学习它”,那它已经偏离了工程师工具的初衷。这句话我越想越觉得对。


我的选择:单一职责,不是功能少,而是边界清晰

想明白上面这点之后,我给自己的插件定了一个非常克制的边界:

只做一件事

把自然语言变成一条可以直接执行的 Shell 命令。

就这一件事。

不做的事

这个插件刻意不去做的事情,我特意列出来,给自己一个约束:

  • 不自动执行命令
  • 不修改任何系统状态
  • 不接管终端会话
  • 不规划多步骤任务
  • 不试图成为”全能 AI 助手”

这些能力不是没价值,而是不该放在这个位置。

收益在哪里

这么做之后,我自己用下来有三个很明显的变化。

第一个是认知负担。不需要记新命令、不需要进入”AI 模式”,流程就是:

1
描述需求 → Tab → 得到命令

第二个是可预测。输入是什么,输出就是什么,没有隐式副作用。这点在终端里比什么都重要。

第三个是失败模式。插件出问题的时候,最坏情况就是没给出命令,你该自己敲就自己敲。对比一下大而全工具出问题可能带来的结果——改了代码、跑了命令、回滚成本很高——这种”安全失败”让我在推荐别人用的时候能理直气壮。

我在做这件事的时候,脑子里一直转着 Unix 那句老话:

Do one thing, and do it well.


为什么我没选”做一个大而全的 AI CLI”

聊到这里,有人会觉得:那我多做几个功能,也不冲突吧?

我拿自己平时最常遇到的两个场景对比一下,就明白为什么我不愿意走”大而全”那条路了。

场景对比:查 Docker 容器日志

用大而全的 CLI 工具,步骤刚才已经列过了——描述环境、等解释、挑命令、复制、回终端执行。

用我的插件:

1
2
# 查看 docker 容器日志
[Tab]

没有上下文切换,没有角色切换,没有心理切换。

听上去只是差几步,但差的这几步每天发生几十次的时候,感受是完全不同的。

80% 的终端操作其实很简单

我后来给自己估算过一个比例:日常工程里 80% 的终端命令,本质就是”查、看、清、跑”,是一次性的短命令。大而全的工具解决的那 20% 复杂问题,不该拿 80% 的简单场景去迁就。

工程师在终端里最真实的诉求是什么?我的答案是一句很朴素的话:

我现在在敲命令,别打断我。

所以我的插件哲学是:

  • 不接管终端
  • 不重写工作流
  • 不引入新概念
  • 不让用户”进入 AI 模式”

就只是在原本的肌肉记忆上,轻轻推一把。

支付宝的反例

顺便说个题外话。支付宝一开始就是做支付的,现在呢?余额宝、生活缴费、社交、小程序、健康码、出行……功能越来越多,但每次打开我脑子里的想法是:”这个功能在哪里?””我到底要点哪里?”

功能强大不代表好用。功能越多,用户的心理负担越重。工具应该让人专注于任务本身,而不是专注于如何使用工具。


Engine 独立:让插件保持简单

上面聊的都是”插件”的一面。但做到后面我很快发现另一个问题:AI 能力本身不该和具体的业务插件绑死。

如果每个插件都各自维护一遍:

  • 模型接入
  • Prompt 调度
  • Token 统计
  • API 兼容
  • 失败处理

那最后结果一定是代码重复、行为不一致、维护起来很痛苦。这也是我为什么把 AI 能力单独抽出来,叫它 Engine。

Engine 做什么

Engine 是基础设施,不是功能提供者。它的职责是”怎么做”,不是”做什么”。

Engine 负责:

  • 模型与服务商管理(OpenAI / Claude / Gemini / 兼容 API)
  • Prompt 执行与上下文拼装
  • 请求生命周期管理
  • Token / 使用量统计
  • 错误与超时处理
  • 能力抽象与统一接口

Engine 不负责:

  • UI 展示
  • 交互设计
  • 业务决策
  • 用户操作流程

一句话讲:Engine 不知道”用户在做什么”,它只知道”如何正确调用 AI”。

分层结构长这样

1
2
3
4
5
[ Engine ]              稳定、可复用、变更少

[ Focused Plugin ] 小而专注,可以快速迭代

[ User Interaction ] 用户不需要感知 Engine 的存在

每个插件的职责都很明确:

  • Terminal 插件:命令生成
  • Javadoc 插件:文档生成
  • Changelog 插件:变更日志生成

它们共享 Engine,但互不影响。

一个实际的例子

假设我明天要新加一个 Code Review 插件。

如果没有 Engine,每个插件自己管 AI 调用,那我要重新实现模型接入、错误处理、Token 统计、API 兼容、流式响应……一套下来两周是有的。

有 Engine 之后,我只需要写 Code Review 自己的业务逻辑,调一下 engine.generateContent() 就行。开发时间从两周缩短到两天,不是因为我变聪明了,是因为重复的那部分已经被抽干净了。

这说穿了也就是最基本的 DRY 原则,不是什么高深的架构模式。但很多工具开发者做着做着就忘了这回事,因为只盯着一个插件看,会忽略整个系统的形状。

我愿意多花时间做 Engine 的原因

从外部看,用户根本感知不到 Engine 的存在,花力气做这一层像是”技术自嗨”。但我坚持要做,原因是:

  • Bug 只在一个地方修
  • 行为在所有插件里一致
  • 新插件不用重新造轮子
  • 出问题时职责边界清楚——AI 调用的问题找 Engine,业务逻辑的问题找插件

Engine 的存在,是为了让插件保持简单。而插件保持简单,是为了让用户保持信任。


Less is More,不是口号,是选择

聊到最后,回到那个最朴素的问题:什么是好工具?

我自己的答案是:

好的工具,不是让你做得更多,而是让你更少被打断。

简单不等于功能弱

我经常被误会——说”只做一件事”就是能力不够。其实恰恰相反,专注之后往往更强:

  • 只做命令生成的插件,命令质量可以做到更高
  • 只做文档生成的插件,文档结构可以雕得更细
  • 只做变更日志的插件,输出格式可以打磨到很稳定

边界清楚了,用户才知道”它到底擅长什么”,也才敢放心用。

复杂是有代价的

很多人下意识觉得”功能多 = 工具好”,但复杂是会收租的,三笔账:

学习成本。复杂工具你得学怎么用、边界在哪、流程怎么走;简单工具是看一眼就知道怎么用。

维护成本。复杂工具的代码多、边界多、Bug 也多;简单工具代码少、边界清晰、稳定性自然高。

信任成本。复杂工具功能多,不可预测的角落就多,用户得”小心使用”;简单工具的边界就在那里,用户能放心按下去。

我在设计时守的几个原则

整理一下这一路下来,我给自己定的几条原则:

  1. 单一职责:每个工具只做一件事,能组合,不强绑
  2. 最小干扰:不切换窗口、不改变习惯、不强迫学新东西
  3. 安全失败:失败时的最坏情况是”没帮上忙”,而不是”帮倒忙”

这三条规矩我自己反复验证过,值得长期坚持。

对工具开发者的一点建议

如果你也在做工具,三句话:

  • 先从简单开始,不要一上来就奔着”功能全面”去
  • 保持克制,每次想加功能的时候问一句”这个真的有必要吗”
  • 相信组合的力量,与其做一个大而全的工具,不如做多个小而专注的工具

我的理解

把这几件事串起来之后,整个思路其实非常朴素:

  • 终端场景决定了我需要一个”克制”的工具
  • 克制意味着单一职责、边界清晰、失败安全
  • 单一职责的插件需要一个统一的能力底座,那就是 Engine
  • Engine 负责”怎么做”,插件负责”做什么”,用户不需要感知底座的存在
  • 整体哲学是 Less is More,不追求功能全面,只追求”在对的时机帮上对的忙”

我不试图取代任何已有的强大工具,只希望在一个非常具体的时刻,成为最合适的那一个。

不替你思考一切,只在你思考的时候,帮你快一步。

这不是产品定位,是我自己写代码这么多年之后,慢慢长出来的工具观。


我的插件

20260418135900_HdzYlGdU.webp

你也可以访问 Zeka Stack 站点获取在 IntelliAI Engine 中免费使用的 OpenAI API Key, 集成方式 也非常简单, 期待你的 反馈