编程 jcode 深度拆解:28MB 内存跑 Coding Agent、14ms 启动、记忆图谱与 Swarm 协作,一个人用 Rust 写出的「反 Electron 宣言」

2026-07-29 10:18:00 +0800 CST views 4

jcode 深度拆解:28MB 内存跑 Coding Agent、14ms 启动、记忆图谱与 Swarm 协作,一个人用 Rust 写出的「反 Electron 宣言」

一、背景:当 Coding Agent 集体变成「内存黑洞」

2026 年 7 月 22 日,一个叫 1jehuang/jcode 的仓库登上 GitHub Trending 日榜,Star 数突破 10k。作者 Jeremy Huang 一个人用 Rust 写了 9.2 万行代码,给这个项目起了个直白到近乎挑衅的口号:

The most RAM efficient harness. The most intelligent harness.

「最省内存的 Harness,最聪明的 Harness」——两个 most 叠在一起,火药味十足。

要理解 jcode 为什么火,得先看看 Coding Agent 赛道现在的「体重问题」。作者在 README 里放了一组用 PSS(Proportional Set Size,比 RSS 更公平的多进程内存指标)实测的数据,单会话空闲状态:

工具PSS 内存相对 jcode
jcode(关闭本地嵌入)27.8 MB基线
Codex CLI140.0 MB5.0×
pi144.4 MB5.2×
Cursor Agent214.9 MB7.7×
GitHub Copilot CLI333.3 MB12.0×
OpenCode371.5 MB13.4×
Claude Code386.6 MB13.9×

单会话差距已经够大了,但真正拉开差距的是多会话场景。同时开 10 个活跃会话:

工具10 会话 PSS相对 jcode
jcode(关闭本地嵌入)117.0 MB基线
Codex CLI334.8 MB2.9×
Antigravity CLI1021.2 MB8.7×
Cursor Agent1632.4 MB14.0×
GitHub Copilot CLI1756.5 MB15.0×
Claude Code2300.6 MB19.7×
OpenCode3237.2 MB27.7×

Claude Code 跑 10 个会话吃掉 2.3GB,OpenCode 直接干到 3.2GB——而 jcode 只要 117MB,每增加一个会话边际成本约 9.9MB(Claude Code 是 ~212.7MB/会话,21.5 倍差距)。

启动速度同样夸张。Time to first frame(首帧渲染时间):jcode 14.0ms,Claude Code 3436.9ms,245 倍差距。你按下回车,jcode 已经画完界面了,Claude Code 的 Node.js 运行时可能还没加载完。

这组数字背后是一个被行业刻意忽视的事实:主流 Coding Agent 几乎全是 Node.js/TypeScript 写的,而 JS 运行时的内存模型天然不适合「多实例常驻」场景。当你的工作流从「开一个 Agent 干活」进化到「开一群 Agent 并行干活」,运行时开销就从「可以忍」变成「忍不了」。

jcode 的答案是:零运行时依赖,纯 Rust,静态二进制。本文就来拆解这套「反 Electron 宣言」是怎么落地的——不只是省内存这种表面功夫,还有它真正的护城河:语义记忆图谱Swarm 多智能体协作

二、核心架构:为什么 Rust Harness 能做到 20 倍内存差距

2.1 Harness 到底是什么

先统一术语。Coding Agent 领域说的 Harness(马具/挽具),指的是包裹在 LLM 外面的那层工程壳:终端 UI、工具执行器、上下文管理、会话持久化、权限控制。模型负责「想」,Harness 负责「干」——读写文件、跑命令、抓网页、管理记忆,全是 Harness 的活。

同样接 Claude 的 API,不同 Harness 的实际产出可以差出一个档次。这就是作者说「raise the skill ceiling」的底气:模型是租来的,Harness 才是自己的。

2.2 内存效率的三层来源

jcode 的低内存不是某个单点优化,而是三层叠加:

第一层:没有运行时税。 Node.js 进程起步就是 40-80MB(V8 堆、JIT 缓存、libuv 线程池),Electron 更是 200MB 起。Rust 编译出的静态二进制没有 GC、没有 JIT、没有解释器,空跑就是几 MB。这一层白捡 100MB+。

第二层:客户端-服务器架构的会话复用。 jcode 支持 jcode serve 后台服务模式 + jcode connect 多客户端接入。10 个会话不是 10 个完整进程,而是一个服务进程管理 10 份会话状态,客户端只是轻量的 TUI 渲染器。这就是「每会话边际成本 9.9MB」的秘密——增量只有会话状态本身,没有重复的运行时。

对比之下,Claude Code 每开一个会话就是一个完整的 Node 进程,212MB 的边际成本里绝大部分是重复加载的运行时和依赖。

第三层:渲染层的极限优化。 jcode 的 TUI 帧渲染耗时 0.67ms,理论上能跑 1400+ FPS。作者为此做了两件在旁人看来近乎偏执的事:

  1. 重写 Mermaid 渲染器。 原版 Mermaid 依赖浏览器和 TypeScript,作者用 Rust 写了 mermaid-rs-renderer,渲染速度快 1800 倍,零浏览器依赖,让流程图能直接内联渲染在终端聊天流里。
  2. 自己写了个终端。 因为传统终端的 scrollback 机制无法实现平滑的部分行滚动,作者干脆开了个新项目 Handterm,实现原生 scroll API。

一个人为了终端滚动体验去写终端模拟器——这种工程密度,是这个项目最「Rust 社区」的地方。

2.3 工程体感:快到改变使用习惯

这些数字翻译成日常体验是什么?

  • 即开即用:14ms 首帧 + 48.7ms 可输入,jcode 快到可以当 grep 一样随手开随手关。而 Claude Code 3.4 秒的启动时间,会让你下意识地「攒够了问题再开」。
  • 多会话自由:在 8GB 内存的开发机或者 VPS 上同时开 10 个会话毫无压力。SSH 到服务器上跑 Agent,jcode 是目前体验最好的选择之一。
  • 无 flicker:1400 FPS 的渲染上限意味着无论终端刷新多频繁都不会闪烁撕裂。

工具性能好到一定程度,会反过来改变工作流的形态。这是 jcode 后面两个大杀器(记忆和 Swarm)的物理基础:只有会话足够便宜,你才养得起一群 Agent。

三、语义记忆图谱:不用向量数据库的「人类式记忆」

如果说内存效率是 jcode 的门面,记忆系统就是它的灵魂。主流 Coding Agent 的记忆现状是:Claude Code 每次会话从零开始(靠 CLAUDE.md 手工维护),Codex CLI 没有跨会话记忆。jcode 则内置了一套完整的语义记忆图谱

3.1 设计哲学:被动召回,而非主动查询

jcode 记忆系统最反直觉的设计是:Agent 不需要主动调用记忆工具

工作原理:每一轮对话(turn/response)都会被嵌入成语义向量。每个新 turn 到来时,系统自动用当前上下文的嵌入向量去记忆图里做余弦相似度检索,命中的记忆被直接注入对话上下文——或者先经过一个 Memory SideAgent(记忆侧车代理)验证相关性后再注入。

这模拟的是人类记忆的工作方式:你不会「主动执行一次回忆操作」,相关记忆是被当前情境自动唤起的。相比让主 Agent 反复调用 search_memory 工具,这种被动注入既省 token,又不打断推理流。

同时,显式的记忆工具依然保留(主动存储/检索),加上对历史会话的传统 RAG 搜索,构成「被动召回为主、主动查询兜底」的双轨制。

3.2 存储层:JSON 文件 + petgraph,拒绝向量数据库

技术选型上,jcode 做了一个很「本地优先」的决定:不接 Pinecone/Qdrant/Weaviate 任何外部向量库

  • 嵌入模型:all-MiniLM-L6-v2,通过 tract-onnx 在本地 CPU 推理(这也是「关闭本地嵌入可省 140MB 内存」的来源)
  • 向量检索:内存中直接算余弦相似度
  • 图结构:petgraph::DiGraph 有向图

存储布局全是人类可读的 JSON:

~/.jcode/memory/
├── graph.json                # 序列化的 petgraph 有向图
├── global.json               # 用户全局记忆
├── projects/
│   └── <project_hash>.json   # 按项目隔离的记忆
├── embeddings/
│   └── <memory_id>.vec       # 每条记忆的嵌入向量
├── clusters/
│   └── cluster_metadata.json # HDBSCAN 聚类中心
└── tags/
    └── tag_index.json        # 标签索引

核心数据结构(来自项目的 MEMORY_ARCHITECTURE.md):

pub struct MemoryGraph {
    graph: DiGraph<MemoryNode, EdgeKind>,      // petgraph 有向图
    memory_index: HashMap<String, NodeIndex>,  // 快速查找索引
    tag_index: HashMap<String, NodeIndex>,
    cluster_index: HashMap<String, NodeIndex>,
}

pub enum MemoryNode {
    Memory(MemoryEntry),   // 记忆本体:内容 + 嵌入 + 元数据
    Tag(TagEntry),         // 显式标签节点
    Cluster(ClusterEntry), // HDBSCAN 自动聚类节点
}

pub enum EdgeKind {        // 六种边关系
    HasTag,
    RelatesTo { weight: f32 },
    Supersedes,            // 新记忆取代旧记忆
    Contradicts,           // 冲突标记
    InCluster,
    DerivedFrom,
}

注意 SupersedesContradicts 这两种边——记忆不是只增不减的日志,而是一个会自我修正的知识结构。新的事实可以取代旧的,矛盾会被显式标记出来等待消解。

3.3 检索流程:嵌入检索 + 图扩散 + 侧车验证

单纯的向量 top-k 检索有个老问题:语义相似 ≠ 逻辑相关。jcode 用四步级联缓解:

Step 1: 嵌入相似度搜索 → 取 top-10 种子节点
Step 2: BFS 图遍历(深度 2)
        从种子节点沿边扩散,不同边类型不同权重:
        HasTag 0.8 / InCluster 0.6 / RelatesTo 按实际权重 / Supersedes 0.9
        衰减公式:decayed_score = edge_weight × 0.7^depth
Step 3: 轻量侧车模型验证关联性(可选)
Step 4: 去重、排序,返回最终 top-10

第二步的图扩散是精髓:向量检索负责「捞相似的」,图遍历负责沿着显式关系把逻辑相关但语义不相似的记忆也带出来。比如「用户偏好 pnpm」这条记忆,可能和当前讨论的构建报错在向量空间里相距很远,但通过 RelatesTo 边一跳就能到达。

3.4 记忆的新陈代谢:半衰期与后台巩固

jcode 把记忆分为四类,各自有不同的信心半衰期

记忆类型半衰期设计逻辑
Correction(修正)365 天用户纠正过的错误最不该忘
Preference(偏好)90 天偏好会变,但变得慢
Fact(事实)30 天项目事实迭代快
Inferred(推断)7 天Agent 自己猜的,最不可靠

这个梯度设计很有讲究:记忆的可信度和它的来源强相关。用户明确说「不对,应该用 X」的修正权重最高衰减最慢;Agent 从上下文里自己推断出来的结论,7 天就基本失效——因为推断最容易过时也最容易出错。

记忆的写入侧同样自动化:每隔一段时间(语义漂移检测、距上次提取 K 轮、会话结束等触发条件),Memory SideAgent 从对话里提取值得记住的内容写入图谱。后台的 ambient mode 还会周期性地做记忆巩固——合并重复、消解矛盾、验证过期信息、HDBSCAN 重聚类。作者的类比是睡眠中的记忆巩固:你休息时,大脑在整理白天的经历。

从工程视角看,这套系统给了我们一个重要启示:Agent 记忆不需要重型基础设施。一个 22MB 的 ONNX 嵌入模型 + petgraph + JSON 文件,就能实现比多数云端方案更精细的记忆语义。本地优先,人类可读,用户可以直接打开 JSON 改记忆——这比任何「记忆管理后台」都直接。

四、Swarm:不需要编排器的多 Agent 协作

多 Agent 协作是 2026 年的顶流话题,但多数方案是「框架级」的:你要写 DAG、定义节点、编排工作流。jcode 的 Swarm 走了另一条路:协作能力内化在 Harness 里,Agent 之间像同事一样自组织

4.1 三层角色与一条铁律

根据项目的 SWARM_ARCHITECTURE.md,Swarm 是严格的三级分工:

用户
 │
 ▼
协调者 (Coordinator)      ← 唯一面向用户的入口
 │
 ├── 工作树管理器 (WTM)   ← 可选,管理一个 git worktree
 │     ├── Agent 1
 │     └── Agent 2
 └── 工作树管理器 (WTM)
       ├── Agent 3
       └── Agent 4
  • 协调者:唯一能生成/关闭 Agent 的角色;制定 Plan、审批 Plan 变更;但不负责合并代码
  • WTM:管理一个 git worktree,负责该范围内的集成
  • Agent:并行干活,不能生成或关闭其他 Agent,可以直接和同伴协商

一条铁律:Agent 不能链式生成。A 生成了 B,B 就不能再生成 C。这条约束看似保守,实际上掐灭了多 Agent 系统最危险的失控模式——指数级的 Agent 繁殖和失去控制的调用树。整个系统永远是一棵深度可控的树。

4.2 通信:软中断,而不是轮询

Agent 间通信靠 Comms Router(通信路由器)+ 通知队列,支持五种通道:

通道类型场景
DM点对点私信两个 Agent 直接协商冲突
Swarm Broadcast全员广播生命周期事件、全局状态
Topic Channels主题群聊多方围绕特定话题讨论
Shared Context Keys共享键值set/read/append 共享状态
Channel Discovery频道发现找到相关频道和参与者

最值得细品的设计是软中断投递:通知在 Agent 的安全点(safe point)注入,消息可以穿插进当前 turn,不需要等 Agent 忙完再开新 turn。这解决了多 Agent 系统的经典延迟问题——「B 修改了你在改的文件」这种消息如果要等当前任务做完才能收到,冲突早就发生了。

读取其他 Agent 的上下文分三档,防止 token 爆炸:

  1. Status Snapshot:元数据 + 当前工具快照,极轻,目标 Agent 忙碌时也能读
  2. Summary Feed:工具调用名 + 意图 + 简要结果
  3. Full Context:完整上下文,重量级,谨慎使用

4.3 冲突处理:去中心化协商

Swarm 最出彩的机制是文件触碰通知(File Touch Notification):当 Agent A 编辑了 Agent B 已经读过的文件(「代码在脚下移动」),服务器立即通知 B。B 可以忽略(不相关),也可以查 diff 确认没有冲突。

关键在于:冲突协商不经过协调者。A 和 B 直接 DM 商量。协调者不是中央调度器,不插手执行细节,它只管四件事:分解任务、生成 Agent、审批 Plan 更新、处理失败(retry / reassign / replace / salvage 四种恢复策略)。

完整任务流转是这样的:

用户 → 协调者(制定 Plan v1,内存对象,不落仓库文件)
     → 生成 Agent + 分发 scope
     → Agent 并行执行(冲突时自行 DM 协商)
     → Agent 发现 Plan 有问题 → propose update → 协调者审批 → 广播
     → 完成报告(outcome / changes / validation / blockers 四要素强制)
     → 各 WTM 负责 worktree 内集成(协调者不 merge)

Agent 生命周期是一个显式状态机:

spawned → ready → running ⇄ blocked → completed → stopped
                     ↘ failed → crashed

这套设计的成熟之处在于它像一个运转良好的工程团队,而不是一个流水线:Tech Lead(协调者)分任务但不盯着每行代码,工程师(Agent)遇到冲突自己去和同事对齐,模块负责人(WTM)管好自己那摊集成。相比之下,需要预定义 DAG 的编排框架更像是流水线——高效,但僵硬。

而这一切的前提,又绕回了第二章:每个 Agent 只占 ~10MB 边际内存。如果每个 Agent 都是 200MB 的 Node 进程,「随手 spawn 一个团队」根本无从谈起。性能不是虚荣指标,是架构可能性的地基。

五、上手实战

5.1 安装与启动

# macOS / Linux 一键安装
curl -fsSL https://jcode.sh/install | bash

# Windows 11 (PowerShell 5.1+)
irm https://jcode.sh/install.ps1 | iex

# 源码编译(需要 Rust 工具链)
git clone https://github.com/1jehuang/jcode.git && cd jcode
cargo build --release && scripts/install_release.sh

常用启动方式:

jcode                          # 交互式 TUI
jcode run "写一个 hello world"  # 非交互单次执行
jcode --resume fox             # 恢复历史会话(会话有代号)
jcode serve                    # 后台服务模式
jcode connect                  # 客户端接入已有服务

5.2 模型接入:订阅党福音

jcode 内置 11+ 种 OAuth 登录流,已有订阅可以直接复用,不用额外买 API 额度:

jcode login --provider claude    # Claude Max 订阅
jcode login --provider openai    # ChatGPT / Codex 订阅
jcode login --provider gemini    # Google Gemini
jcode login --provider copilot   # GitHub Copilot
jcode login --provider ollama    # 本地 Ollama
jcode login --provider openai-compatible  # 任意兼容端点,支持 localhost 免密钥

最后一项对隐私敏感团队很关键:接一个内网自托管的 vLLM/LM Studio 端点,全链路(模型推理 + 嵌入计算 + 记忆存储)都不出内网。

5.3 值得一试的特性

  • 侧边栏:让 Agent 把文件加载进 side panel 实时刷新,或直接当 diff 查看器;聊天流内联渲染 Mermaid 图
  • Plan Mode:先只读探索、呈现计划,批准后才动手改文件——大重构的安全带
  • Self-Dev 模式:Agent 修改 jcode 自身源码并自动构建热重载。项目相当比例的代码就是 jcode 自己写的,「哪里不爽改哪里」在这个项目里是字面意思
  • Swarm 试用:同一个仓库开两个 jcode 会话,它们会被 server 自动纳入协作管理;或者直接让 Agent 用 swarm 工具自己拉团队

六、冷静的边界分析

吹完了,泼点冷水。以下几点在选型前必须想清楚:

1. Benchmark 由作者自测,未经第三方独立验证。 PSS、首帧时间这些数据方法论看起来严谨(10 次 PTY 启动取样、标注对比版本号),但毕竟是 README 里的自家数字。竞品版本也在快速迭代,数字的保鲜期有限。

2. 单人项目的巴士系数。 9.2 万行 Rust,148 个 open issue,核心贡献者一个人。项目处于活跃开发期(版本号 v0.9.x-dev),API 随时可能 Breaking Change。把它引入团队关键路径之前,掂量一下维护风险。

3. 智能上限依然由模型决定。 Harness 优化的是「工程下限」和「上下文质量」,写代码的还是背后的 Claude/GPT/Gemini。jcode 不会让一个弱模型变强,它只是让强模型少受工程拖累。

4. 记忆系统是双刃剑。 自动注入的记忆如果过时或错误(尤其是 Inferred 类),会静默污染上下文。虽然有半衰期和巩固机制兜底,但「Agent 记住了三周前的错误结论」这类问题排查起来比无状态系统更隐蔽。

5. Rust 门槛拦住了贡献者。 对比 TypeScript 系项目,能给 9 万行 Rust 提 PR 的社区成员少得多。生态插件的繁荣度大概率不如 Claude Code 生态。

适合谁:SSH/服务器远程开发、低配机器、多项目并行、想要跨会话记忆、隐私敏感(全本地链路)、终端原教旨主义者。
不适合谁:需要企业级 SLA 的团队、深度绑定某家 Agent 生态的用户、不想碰 dev 版本软件的稳健派。

七、总结:Harness 战争的下半场

jcode 最有价值的地方,不是某个具体功能,而是它验证了三个判断:

第一,Coding Agent 的竞争正在从「接哪个模型」转向「Harness 工程质量」。 模型能力日趋同质化(都能接,OAuth 一下的事),而 20 倍的内存差距、245 倍的启动差距、有无跨会话记忆——这些 Harness 层的差异是实打实的日常体验鸿沟。

第二,多 Agent 时代,资源效率就是架构能力。 「Agent 集群」概念喊了一年多,真正的拦路虎不是编排算法,而是每个 Agent 200MB+ 的物理成本。jcode 用 ~10MB 的边际会话成本证明:先把单体做轻,群体智能才有土壤。

第三,Agent 记忆不需要重型基建。 本地嵌入 + 图结构 + JSON 文件的组合,在个人开发场景下完胜「再买一个向量数据库」的方案。人类可读、可直接编辑的记忆存储,可能才是正确的默认形态。

一个人、一门语言、9.2 万行代码,把行业里所有「等模型更强了再说」的懒惰假设戳了个洞。下次当你的 Coding Agent 又在启动画面上转圈时,不妨想想:卡住你的到底是 AI,还是那 3.4 秒的 Node.js 冷启动?

项目地址:https://github.com/1jehuang/jcode (MIT 协议)

推荐文章

Vue3中如何使用计算属性?
2024-11-18 10:18:12 +0800 CST
内网穿透技术详解与工具对比
2025-04-01 22:12:02 +0800 CST
智能视频墙
2025-02-22 11:21:29 +0800 CST
程序员茄子在线接单