Zapmyco
进阶

项目思考

记录 Zapmyco 开发过程中的设计决策和个人思考

本文档记录我在开发 Zapmyco 过程中的一些设计决策思考和个人见解。内容会持续扩展。

为什么用 Rust?

选择 Rust 作为 Zapmyco 的开发语言,并不是一开始就决定的。在最终选定 Rust 之前,我们经历了一个逐步探索和淘汰的过程。

1. Python — 最先被排除

最开始考虑过 Python。虽然 Python 在 LLM 领域使用广泛,但它作为 CLI 工具的语言有一些根本性问题:

  • 版本和环境 — Python 的版本管理(2 vs 3)和虚拟环境碎片化严重,用户本地不一定有合适的运行环境
  • 分发困难 — CLI 工具的理想形态是单一二进制文件,但 Python 不容易打包成二进制分发

2. TypeScript / Node.js — 推进最远,但最终放弃

我们甚至已经用 TypeScript 完成了核心 Agent 能力的开发,但仍然遇到了问题:

  • 运行时依赖 — 和 Python 一样,用户本地需要安装 Node.js 才能运行
  • 打包方案不理想
    • pkg — 可以将 Node.js 打包成二进制,但已停止维护,且打包体积很大
    • Node.js 自带的 SEA(Single Executable Application) — 目前还不够成熟
  • 最终结论:TypeScript 本身很优秀,但 Node.js 的生态和打包现状不适合 CLI 分发

3. Bun — 考察后放弃

我们知道 Claude Code 就是用 Bun 打包的,Bun 的优势很明显:

  • 打包体积比 pkg 小很多
  • 对 npm 包的兼容性不错

但当时 Bun 正在从 Zig 迁移到 Rust,这是一个非常激进的底层重构——意味着在相当长一段时间内稳定性存疑。另外,Bun 使用了 WebKit 内核(这也是体积小的原因),可能对 Windows 的兼容性不够好。而 Zapmyco 从设计之初就希望在跨平台上有很好的表现,所以我们放弃了。

4. Deno — 已迁移过去,因体积问题放弃

Deno 宣传为比 Node.js 更现代化的运行时,工具链集中、由 Rust 编写性能足够、新版本也逐渐提升了对 Node 生态的兼容性。我们当时认为 Deno 是一个很好的选择,甚至已经将代码从 Node.js 迁移到了 Deno,重新实现了 Agent 核心能力。

但问题出在打包上。即使我们的核心代码很少,Deno 打包出来的二进制体积也达到了 70-100MB。如果未来项目扩大、变得更加复杂,用户下载我们的 CLI 可能需要占据 100MB 以上的空间——这对分发来说不可接受。

5. Rust — 最终选择

最终我们把目光放在了 Rust 上。以下是它的核心优势:

优势说明
现代化工具链有自己完整的工具链(cargo、rustfmt、clippy),不像 Node 那样碎片化
编译期严格编译时检查极其严格,明确的报错信息,对 AI 开发 Agent 的反馈机制非常友好
跨平台在 Windows、macOS、Linux 上都能很好地运行
二进制体积小打包后约 5-10MB,压缩后甚至只有 3MB,用户下载很快
无运行时开销纯二进制编译,没有捆绑 V8 之类的运行时,运行效率高
包管理生态有类似 npm 的 crates.io,生态丰富

当然,Rust 也有缺点。目前它的生态系统不如 npm 那样完善和庞大,很多 SDK 不够成熟,有时甚至需要自己维护。但这不妨碍我们选择 Rust——整体收益远大于缺陷。

为什么选择 Web 而不是 TUI?

Zapmyco 最终选择 Web 而非 TUI 作为交互界面。这同样是一个经过权衡的决策。

TUI 的优势(为什么不选它是有代价的)

TUI 确实很不错,很多优秀的 Agent CLI 都在使用——比如 Claude Code、Codex 等。选择 Web 意味着我们放弃了 TUI 的一些天然优势,比如启动快、终端内闭环操作等。

为什么还是放弃了 TUI

1. 终端表现不一致

不同终端(Terminal)的表现差异很大,很像早期不同浏览器的兼容性问题:

  • 有些终端支持鼠标交互,有些不支持
  • 有些支持图像渲染,有些不支持
  • 不同终端对字符编码的表现也不尽相同

这些问题很难从根本上解决,因为终端没有像 Web 那样有统一的标准化组织推动。而 Web 经过多年的标准演进,主流浏览器的表现已经基本趋同,不太会出现明显的兼容性差异。

2. 远程终端的场景局限——以图片上传为例

给 LLM 发送图片是一项常见且刚需的功能。在本地终端中这很容易——图片就在本地文件系统中。但如果是远程终端(比如云服务器的 SSH 终端),问题就来了:

  • 图片在本地,但终端在远端,路径不互通
  • 服务器终端不太可能支持类似本地上传图片的形式

这种场景下 TUI 的使用就很有局限性,而 Web 可以天然地通过文件上传解决这个问题。

3. Rust TUI 生态的兼容性成本

我们尝试了 Rust 生态中一些主流的 TUI 方案,发现仍然存在不少兼容性问题。如果自己去打磨这些兼容性问题,会非常耗时。但 Zapmyco 的本质不是打磨 TUI,而是做好 Agent 核心的 Loop、工具调用、工程约束等事情。

4. 人力约束下的优先级选择

团队人力比较有限。在当下的场景中,我们需要集中精力在 Agent 核心能力上,而非 UI 打磨。Web 端有足够成熟的交互范式,可以让我们更轻装上阵。

5. 降低使用门槛

Web 界面对于非极客用户(不太熟悉终端的用户)更友好,有助于降低 Zapmyco 的使用门槛。

总结

TUI 是很酷的技术方案,但它面临的终端碎片化、远程场景局限、以及 Rust 生态的兼容性成本,让我们决定把有限的精力放在 Agent 核心能力上。Web 是一个更务实、更普适的选择。

On this page