SimpleCode
轻量编码 agent。VS Code 侧边栏与终端各有一份入口,共用同一条连续上下文。
English
简介
SimpleCode(以下简称 SC)是一个编码 agent:接收需求,读取代码、执行命令、修改文件,并报告改动内容。
功能层面与同类工具相近,差异在于两条贯穿始终的设计哲学——其余取舍均由此推导而来。
设计哲学
One session
整个产品只有一条连续的上下文,不提供「新建会话」。
新建会话并不解决问题,只是将问题隐藏:需要新建,恰恰是因为原有会话过长、过乱或已偏离主题;而新建之后,此前得出的结论、遇到的问题、确立的约定,都留在了无法访问的另一侧。SC 的做法是让上下文自行代谢——历史对话自动摘要、降低分辨率、卸载至磁盘,需要时再行检索。降低的是分辨率,而非数据本身。
支撑这一机制的是 file system is memory:记忆不存放于向量数据库或私有格式中,而是磁盘上的普通文件。对话按轮次写入 JSONL,摘要为 markdown,结论、教训、事件档案各自对应一个目录下的 .md 文件。agent 检索记忆所用的正是 grep、sed、cat——无需为「记忆」另造机制,文件系统本身即是一套久经检验的记忆系统。这同时意味着全部内容可随时直接查看与修改。
向模型暴露的工具只有一个:bash。(严格而言是一个半——另有 view_image 用于读图,因为二进制像素无法经由管道进入上下文。)
bash only 的要点不在于「工具数量少」,而在于工具面本身即应为命令行:网页抓取、补丁应用、记忆检索、符号查询、MCP 调用,在 SC 中均为 bash 内的命令,而非逐条注入上下文的工具定义。由此三项特性自然成立:可管道串联、可自由组合、新增命令无需改动模型的工具表。
更根本的理由在于,命令行是模型最为熟悉的接口。为 agent 另行发明一套工具协议,模型需要重新学习;而提供一个 shell,模型已然掌握。
安装
支持 macOS 与 Linux;Windows 建议在 WSL 内使用(工具链按 POSIX 设计,原生 Windows 未支持)。
VS Code 扩展:在扩展面板中搜索 SimpleCode 安装。首次使用需先完成模型配置(见下节)。
无需单独安装 Node.js:apply_patch、网络检索、记忆等工具脚本优先使用宿主编辑器(VS Code / Cursor)内置的 Node 运行,系统未安装 Node 亦可正常使用;装有 Node 时作为兜底。
终端命令 sc(可选):扩展激活时会在 ~/.simple-code/bin/ 下建立命令入口(含 sc),把该目录加入 PATH 即可:
export PATH="$HOME/.simple-code/bin:$PATH" # 写进 ~/.zshrc 持久生效
入口是几个由扩展在每次激活时重写的小脚本(同样以内置 Node 运行),扩展目录随版本变化,无需手动维护。
终端环境不继承 VS Code 的设置,因此配置中以 ${ENV_VAR} 形式引用的密钥需要在 shell 中导出,否则首次执行即报错:
export ZHIPU_API_KEY=...
配置
配置文件位于 ~/.simple-code/settings.json。没有默认模型,五项必填,缺失任一项将在启动时报错,不作推测:
{
"provider": "zhipu",
"model": "glm-5.3",
"providers": {
"zhipu": {
"protocol": "anthropic-messages",
"baseUrl": "https://open.bigmodel.cn/api/anthropic",
"apiKey": "${ZHIPU_API_KEY}",
"models": {
"glm-5.3": { "contextWindow": 1000000 },
"glm-5.3-flash": { "contextWindow": 1000000, "capabilities": { "images": true } }
}
}
}
}
apiKey 填写 ${环境变量名} 形式将读取环境变量,其余内容按字面量处理
- 支持三种协议:
anthropic-messages、openai-responses、openai-chat
- 每个模型必须声明
contextWindow,上下文卸载的触发点由该值推算
完整示例(含推理档位、超时、记忆参数)见 settings.example.json,文件顶部的 $comment 逐项说明了各配置项的含义与取舍。审批白名单在 ~/.simple-code/approval.json,MCP server 在 ~/.simple-code/mcp.json,都不进 settings.json。
终端用法
sc # 交互式对话,/exit 退出
sc "把 utils.ts 的测试补齐" # 执行一轮后退出,适用于脚本
sc -m zhipu/glm-5.3 -e high "重构这个模块"
cat error.log | sc "这个报错什么原因"
sc --models # 列出可用模型
--models 同样需要展开配置中的 ${ENV} 引用,因此也要求密钥已导出。
一次性模式下审批恒为拒绝(无人在场放行),因此活动范围限于工作区内。这一特性也使 sc 适合作为子 agent 使用:新建目录、写入任务书、执行 sc > result.md & 即可。
上下文与记忆:One session 的落地方式
对话增长时,历史部分会被压缩,且压缩是分级的:
| 分区 |
状态 |
可用操作 |
| 热 |
原文位于上下文内 |
直接读取 |
| 温 |
摘要在上下文内,原文已卸载至磁盘 |
依摘要中的线索检索回原文 |
| 冷 |
归入事件档案 |
按事件名或关键词检索 |
温区摘要携带原文位置,冷区档案携带事件名称——上下文中保留的始终是「如何找回」的线索,而非内容本身。
上述内容均存放于项目目录内,绝大多数为纯文本:
.simple-code/
├── memory/
│ ├── turns/000/turn-000123.jsonl # 逐轮原文,全量,不截断
│ ├── summaries/ # 分段摘要,markdown
│ └── state.db # SQLite:运行时索引与全文检索
├── events/ # 事件档案,一事一文件
├── notes/ # 结论记忆:决策、约定、一次性事实
├── lessons/ # 教训:一个症状一个文件
└── approval.json # 审批规则
其中的 SQLite 仅为加速层,分页与全文检索经由它完成。同一份内容同时按轮次写入 JSONL,纯文本副本才是供人与 agent 读取的正本:agent 宽范围检索直接 grep turns 目录,人可用编辑器直接打开。数据库可以重建,可读性并不依赖于它。
多文件夹工作区
VS Code 工作区可挂载多个文件夹,SC 为每个文件夹运行一条独立的 agent:经顶部标签栏切换,各自拥有独立的对话历史、记忆目录、模型选择与后台进程。
关键在于切出的 agent 不会停止。非当前文件夹的 agent 继续运行,仅其 UI 增量不再推送;历史保存在磁盘上,切回时重新装载衔接。因此可在 A 文件夹启动长任务,切至 B 处理其他工作,稍后返回查看结果。
隔离是彻底的:后台文件夹的审批卡不会弹至当前界面,而是在原处等待,其所属标签上以角标提示待批数量,切换过去方可查看内容并答复(超过 5 分钟无人答复则自动拒绝,该条命令中止,其余照常执行)。后台进程状态同理,仅显示当前文件夹的内容。这是有意的取舍——审批需要结合对话上下文才能判断,将卡片搬至缺少上下文的界面只会降低判断质量,因此仅传递「有事待处理」这一信号。
.simple-code/ 每个文件夹各有一份,记忆天然隔离;模型选择亦按文件夹记录(simpleCode.model:<路径>),前端项目与核心项目可分别配置不同模型,互不干扰。
图片
截图往往比文字描述更为准确——报错的具体形态、按钮错位的位置、图表的异常点,提供一张图远快于三段描述。因此尽管设计哲学为文本进、文本出,图片通路仍予保留:
- 用户提供:在输入框中直接粘贴(Cmd+V)。从资源管理器拖入文件属于另一机制,会转为一行路径文本,由 agent 自行读取
- agent 主动读取:
view_image <路径> 读取磁盘上的图片,截图后交由其检查渲染效果属于常规用法
- 网页中的图片:
webfetch 抓取的图片一并进入上下文
发送前统一压缩至长边 2048、5MB 以内;格式依文件头识别而非扩展名(foo.png 内实为 jpeg 的情形并不罕见,媒体类型错误将直接导致 4xx)。
若所用模型不具备视觉能力——这是常见情形,编码能力强的模型未必支持读图,上述配置中的 glm-5.3 即为纯文本模型。为其配置一个视觉模型即可:
{ "visionModel": "glm-5.3-flash" }
(跨 provider 时写完整形式:"visionModel": { "provider": "provider 名", "model": "模型名" }。)
图片先送至视觉模型转述为文字(逐字转写图中所有文字、说明布局与几何关系、不推断不可见内容),再将文字交予主模型。主模型一侧因此仍是纯文本进、纯文本出——设计哲学并未被打破,只是在边界处增设了一层转译。
审批
默认规则:工作区内自由执行,越界须经确认。
- 项目内普通文件读写:直接执行,不作打扰
- 项目外:读与写均需确认。其他项目源码、
~/.ssh、/etc 的泄露面在读取一侧,并非只有写入才构成风险
- 隐藏路径(
.env、.ssh,以及 src/.env 这类位于中间层级的):需确认。.git 除外,整树放行
- 网络命令及含
$() 的命令:需确认。npm、pnpm、yarn、git、node 等日常命令除外
.simple-code/ 自身适用独立规则:读取放行、写入确认,且不区分是否位于项目内。理由在于两侧代价并不对称——检索历史与事件档案是产品本身引导的日常操作,拦截将与产品机制相冲突;而向 turn 文件植入虚假记忆构成真实的攻击面,写入必须经用户确认。两项例外:settings.json 写入需确认(apiKey 存放于此),lessons/ 写入放行(教训库是 agent 的自助成长区)。
审批卡片可选择「总是允许」,按命令形态记录,规则保存于 .simple-code/approval.json。
开发
pnpm install
pnpm test
pnpm run build
node scripts/deploy.mjs # 安装至 ~/.vscode/extensions
License
MIT