OpenCode 避雷指南与正确打开方式
本文含 AI 量为 0(如果不算上讲的内容涉及 AI 的话),请放心食用!
前言
在 CodeX 不知道多少次把代码写得稀烂之后,忍无可忍的我最终决定寻找一个新的平替。
技术选型
我先是调研了众多 AI 编程工具,包括 Claude Code、Aider、Deepseek-tui 等,发现它们有着各自的问题:
Claude Code 闭源,且泄漏的代码里有 对第三方模型的干扰,用起来不放心
Aider 使用起来效果较差,对模型本身的智力要求太高
Deepseek-tui 是 纯粹的营销型项目,对 Deepseek 模型的利用率甚至不如其他同类工具
Deepseek-reasonix 自称面向 Deepseek 优化,但还 处于早期开发阶段,且 benchmark 不全看不出效果
最终方案
最终,我翻到了一个被称为 Claude Code 开源平替的项目——OpenCode。它可以 适配市面上通用的 skill 安装方式,还可以 支持插件开发和安装,有着一套自己的完整生态。
OpenCode 自带 用来规划的只读 Plan 和 用来开发的可写 Build 两个 Agent,很符合我每一次开发都要讨论思考半天的性子,再加上它 对 Deepseek 模型支持不错,指令设计上也符合直觉,很对我的胃口,于是便成为了我的最终选择。
当时的我以为这是我选择的结束,没想到还有很多坑等着我去踩,选中 OpenCode 只是在技术选型上的一个开始......
多年以后,面对天价的 Token 账单,我仍然会想起那个从 CodeX 转 OpenCode 的下午。——《百年 Agent》
误区与避雷
这篇博客是要教干货的,因此我也不从头开始写心路历程,而是按条列出吧。请原谅我在撰写的废话过多,我实在是对 OpenCode 及其相关配置积怨已久。为表示歉意,我把所有的 关键点都加粗了,方便读者进行跳读。
AI 全程负责 vs AI 开发 + 人工审核
如果读者只是开发小白,听说了 AI 能全职接管开发过程就跃跃欲试,我的建议是 暂时死了这条心。
Vibe Coding,也就是全程由 AI 开发,已经被证明是灾难性的了。AI 思考出垃圾,AI 写出垃圾,AI 检查出垃圾,这套循环只会恶化而不会自己优化。
这其实是很好理解的事:AI 是由数据训练的,它只对数据负责。放在开发场景就是 只对“是否能运行”这一标准负责。因此如果读者有过 Vibe Coding 的经验,一定对它以各种奇妙手段绕过检查、糊弄 Bug、破坏环境有深刻的体会。
在完全能掌控一切的 AI 出现之前,AI 编程的最佳实践仍然是 AI 写代码 + 开发者自行审核。这确实对开发者的技术功底有所要求,但,这不是应该的吗?
如果读者仍然认为“不懂代码也能搞开发”是正确的结论,那么请不用继续往下看了,下面的内容都是与之唱反调的。
缓存命中率,真的有这么玄乎?
在各大技术社区都能看到不同 Agent 使用者对着缓存命中率辩得面红耳赤。甚至有以缓存命中率决定使用方向的看法。
当然这不是正确的。了解过 KV-Cache 原理的读者都知道,缓存命中,实际上是在 预存前缀键值对 的情况下只算后续的增量输入。这意味着只要是 上下文具有不变性 的输入,基本上前缀内容都是命中了缓存的。
在开发领域,只要脑子没问题的 Agent 框架都不会随便乱动上下文,因此想要命中缓存是一件顺手的事。而命中率低的情况之所以存在,是因为:
主 Agent 启动了多个 SubAgent 分别工作,对它们来说所有输入都是新的,因此不命中缓存
Agent 一次或多次触发了上下文压缩,导致压缩后的内容得从头重新传入,缓存命中完全失效
Agent 一口气干了很多事,收集到了很多新信息,因此把原有的前缀命中率给压下去了,多出现于上下文较短的情况
所以 缓存命中率决定使用体验其实是个伪命题。缓存命中率实际上 只决定了输入的 API 计费,并不应该用于作为衡量框架效果的第一标准。
省 Token 究竟是省什么?
那难道缓存命中率决定 Token 账单量就是个真命题了吗?显然不是。
对 skills 社区有了解的读者可能听说过 caveman 这个 skill。它省 Token 实际上是通过 让输出言简意赅 的方式实现的,而对于输入 Token 数本身其实没有做到太多的优化。
当然不可否认的是,既然模型输出少了,模型对话的上下文也会自然少一些,但这不是重点!
如果读者认真看各大供应商的计费规则,不难发现 输出 Token 的费用大概是同等数量输入的数倍。这是和 LLM 的 prefill 和 decode 计算量不同相关的,此处不赘述。
因此,所谓的省 Token,实际上是省输出 Token 数,而这个效果是十分显著的!作为对照,我遇到过 Agent 让 SubAgent 去查看所有代码,并原封不动地输出,直接给我烧了将近两块钱给我烧红温了。
每次看到 Agent 拿 Token 浪费在在这种蠢事上,都感觉自己在cos金池长老——别烧了!别烧了!这代码我不要了T_T
所以这就是省钱的要点了——再多的缓存命中,不如输出少一点废话。而很幸运的是,这两个优化是可以共存的。
上下文压缩的抉择
当然,除了正常跑缓存命中,还有一个方法减少输入上下文——压缩。想法很简单,就是让 AI 先总结上下文,做一次“省流”,再继续后续的开发。
但是,代价是什么呢?
重建之前,AI 需要 阅读所有上下文并总结,产生较高的输出 Token 开销;重建之后,你 丧失了所有的前缀缓存命中,要从头开始把所有内容都给传进去一遍,这一遍会造成一些额外的不命中缓存的开销。如果很不幸,AI 又比较笨总是要总结,那么对账单的危害将是灾难性的——总结用的输出 Token 和输入 Token 费用都得算上。
当然,计算可知在 上下文较长的情况 下还是能有优化的,毕竟省掉了缓存前缀的费用。因此什么时候该使用上下文压缩这个问题,留给读者作为思考题。
哦对了,caveman 这个 skill 也有个废话少版本的上下文压缩叫 caveman-compress,不过我没用过就是了。
我很喜欢 CodeX 在触发上下文压缩时候的话,大概就是让你开发时 “keep focused”,不要什么事情都放一个 session 里面去做。不同的任务在不同的会话里做,一次对话只做互相有关联的任务,我认为这才是 AI 开发的最佳实践。
对于 Deepseek-v4-pro 模型,个人体验在 200K 到 450K 上下文的时候是效果最好的。如果再长,建议开新的对话。
三个臭皮匠,赛过臭皮匠?
如果读者已经上手去搜 OpenCode 了,很有可能看到各种博客正在鼓吹一个 OpenCode 的插件:oh-my-opencode(现已更名 oh-my-openagent)。
它实际上就是把原本的 OpenCode 的 build 和 plan 两个 Agent,扩展为了架构师、执行者、Reviewer、调度者等若干分工明确的 Agent。
听起来是不是很像回事?并非。
先不提以希腊神话给 Agent 起名给我大脑带来的文化强健,光说效果,这个插件特别喜欢开各种 SubAgent 去煞有介事地跑一堆子任务,不仅每次都 完美避开缓存命中,各个 Agent 的权限不清还导致了 越权执行 的问题。
更离谱的是,它的任务规划者 Agent 在规划了将近 20 个开发步骤之后,一旦开始执行就是把这 20 个全部一口气执行完!面对着将近 40 个改动的文件,我几乎是一瞬间就放弃了手动 review 的想法,并顺手把这个插件迅速卸载了,还得强迫自己不去看将近 10 块的账单......
如果读者不是家里有矿的 vibe coding 重度爱好者,不建议使用这个插件。它会在疯狂烧 token 的同时大幅提高人工 review 的难度,给你带来精神上和物质上的双重困扰。
在浪费了一个上午 + 10 块钱之后,我又回到了 opencode 本体。事实证明,还是 plan 规划 + build 执行 好用!
Skill 与插件推荐
上面废话这么多,都是在说如何避雷。然而,无插件无 Skill 的 OpenCode 仍然是草台班子,要想让账单看起来没那么心痛,而且效果也能好,那么就离不开社区的努力了。
caveman(Skill)
如果读者真的耐着性子读完了我上一章的废话,那么就应该知道我对 caveman 的态度如何了。
caveman 通过约束 Agent 的输出格式,让 Agent 像穴居人(caveman)一样说话,这意味着 AI 不会再动不动就花着你的钱道歉了!
caveman 一共提供了四个子 skill:
caveman:要求模型的说话风格简化caveman-review:要求模型根据要求审查项目,并输出言简意赅的意见caveman-compress:模型以言简意赅的方式极力压缩上下文,降低输入 Token 数caveman-help:caveman 的使用教程
第一次用的时候,我感觉我像是找到了知己——不废话、思维缜密的优秀开发者。当然,随着上下文增长,还是能逐渐暴露出一定智力问题的。
还有,不要学 AI 那样言简意赅地讲话,除非你能保证自己真的“意赅”。大部分时候,详细描述需求是节省 Token 的好方法,毕竟输入 Token 可没那么贵!
gsd-redux(Skill)
GSD(Get Shit Done)这个 skill,听名字就知道是被 AI 困扰依旧的开发者设计的。它打包了一套完整的项目开发 Skill 工具,在各个阶段都能保持较好的表现。
好像 GSD 的源仓库已经归档了,推荐使用还在积极维护的 GSD-Redux 替代,也是同一批人做的。
它包含有建立仓库的代码索引、按阶段规划项目、讨论阶段实现、执行阶段、进行前后端审查等多种功能。其主要思想是通过 把模型的思路写入阶段性规划文件里,代替每次的重复思考。说白了还是减少输出 Token 数和提高准确率。
原仓库已经有很详细的使用教程了,我实际品鉴下来效果也不错,对 SubAgent 没有滥用,仓库索引也几乎是一劳永逸。唯一的缺点是有时候可能讨论确认结束之后直接开始执行,但本来的仓库设计中,这之间应该有一个 plan 过程的(虽然我也不知道这个 plan 的存在意义...)
graphify(Skill)
不记得咋安装的了,好像有的地方叫 graphifyyy。这个 Skiil 只干一件事:生成项目的代码引用关系图。
不过这个图是多种形式的,比如人类可读的 HTML 静态页面,AI 可读的详细架构,还可以通过内部自带的方式去查询两个模块的关系。
它存在的意义主要是通过建图代替直接读文件查引用关系,大部分是减少输入 Token 开销并节省上下文空间。
它可以和 gsd 进行联动,有个专门的 gsd-graphify 子指令,效果也很好。
插件
我插件倒是没装很多,基本上都是装些和 sidebar 相关的美化插件了,大概就是容纳更多信息的。
如果这部分到编写结束时还想不起来,我就先保留这部分的内容吧。读者可根据需要自行安装插件。
结语
写这篇博客的时候,我几乎没怎么思考,洋洋洒洒写了将近一个小时就出来了。因为我对 OpenCode 这些坑印象都太深了,根本都不需要刻意去想,这些坑已经带着我的怨气从记忆里冒出来了。
写这篇博客的目的,还是给有开发经验、积极与慎重拥抱 AI 开发的读者避坑的。这也是我体验下来几周的实际心得体会,希望能对读者有所帮助。
最后,碍于本人知识与能力有限,可能在介绍过程中有些不详尽之处,甚至有些自以为是的暴论,还望读者明辨是非、多多包涵。