有段时间没正经写 OpenCode 的配置总结了,结果这周被问得最多的问题居然是“OpenCode 配什么 LSP 和 SKILL 最好用”。说实话,这问题问得挺到位的,因为 OpenCode 这工具现在有点特殊:它既不是传统 IDE,也不是那种只能聊天的纯 AI 面板,而是把 AI agent、语言服务器、技能包全揉在终端里的编程环境。很多人装上 OpenCode 之后发现补全不够准、报错不够清、上下文老跑偏,十有八九不是模型选错了,而是 LSP 和 Skill 没配明白。
这篇文章就围绕 OpenCode 实际使用中的 LSP 选型、Skill 装配、模型搭配和典型报错排查来讲,给出一套可以直接照着抄的配置方案。无论你刚安装完 OpenCode 还在观望,还是已经用了一段但总感觉差点意思,这篇都值得花五分钟读完。顺便,开头先说结论:现阶段最省心的组合是“按语言挑一个稳定的 LSP + 两三个高密度 Skill + 一个好模型”,三者缺一不可,下面展开细说。
1. 先把话说清楚:LSP 和 Skill 在 OpenCode 里到底管什么
很多人一看到 LSP 就条件反射想到 VS Code、Neovim,觉得那是给编辑器用的东西,和 AI 编程工具有什么关系。这个理解不能说错,但放在 OpenCode 的场景里有点低估它了。OpenCode 本质上是一个运行在终端里的 coding agent,它能不能精准地读懂代码、定位符号、处理重构,靠的不是模型自己瞎猜,而是 LSP 提供的结构化信息。
1.1 LSP 不是给 IDE 用的吗,终端里的 AI 为什么也要它
LSP,全称 Language Server Protocol,就是一套语言服务器和编辑器之间的通信协议。传统用法是 VS Code 跑一个 TypeScript 语言服务器,你敲代码的时候它负责告诉你哪里有类型错误、哪个变量能跳转、哪些引用被修改了。OpenCode 这类 agent 工具引入 LSP,思路也是一样的,只是消费方从“编辑器 UI”换成了“AI 模型”。
我举个实际例子:你在 OpenCode 里让它改一个复杂函数,如果没有 LSP,模型只能读取文件里的文本,然后基于训练知识猜这个函数的调用关系,猜错的概率不低。一旦配好 LSP,OpenCode 可以实时查询某个符号的定义位置、当前文件的诊断信息、引用列表,模型拿到的就不是一堆死文字,而是经过解析的代码语义。这个差别在项目一大、文件一多的时候非常明显,复杂度上去了之后,模型靠硬读源码猜结构和靠 LSP 喂结构化数据,准确率差距能到两三个档次。
所以我的建议是,OpenCode 装完第一件事就是配置语言服务器,而不是急着搞 Skill。LSP 是地基,Skill 是上层建筑。地基没打好,模型对你的项目永远隔着一层纱。
1.2 Skill 与 Agent 有什么不一样
Skill 和 Agent 这两个概念在 OpenCode 生态里容易被混着说,其实分得很清楚。Agent 是一个能独立执行任务的执行者,它有上下文、有工具调用能力、可以在终端里跑命令、读写文件。而 Skill 更像是一份“领域知识包”或者“工作流说明书”,它把某个专业场景下的经验、规则、最佳实践打包起来,让 Agent 在特定任务里直接调用。
举个例子你就懂了,比如你给 OpenCode 装了一个“前端重构 Skill”,这个 Skill 内部定义了拆分组件的检查清单、命名规范、常见反模式判断条件。当 Agent 接到“重构这个 Page”的任务时,它先加载这个 Skill,按照里面的流程一步步分析,而不是凭模型本能自由发挥。简单说,Agent 是执行力的来源,Skill 是执行质量的保障。
顺着这个逻辑你也可以构思自己的 Skill。观点可能有点个人化,但我觉得 Skill 最核心的价值并不是增加多少新功能,而是约束 Agent 的行为方式。不带 Skill 的 Agent 像一个聪明但散漫的实习生,带了一堆好 Skill 的 Agent 就像一个熟悉团队规范的老手,做出来的东西可能更稳、更符合项目预期。
1.3 什么时候优先配 LSP,什么时候优先配 Skill
我的经验是分场景看。如果主要工作是改 bug、重构、跨文件定位符号,LSP 优先级最高,没有它模型干活等于盲人摸象。如果主要工作集中在特定领域,比如 React 组件开发、论文写作辅助、数学建模、语言学习、数据分析,那么 Skill 的收益更直接,因为它把专家经验直接灌给了模型。
一般建议初始配置顺序是:先给常用语言配上合适的 LSP,再安装两到三个和工作流紧密相关的 Skill,最后根据实际使用反馈持续调整。这套流程基本覆盖了大多数人的核心需求,下面的章节我会按这个顺序逐步展开。
2. LSP 配置实操:不同语言怎么选、怎么配
LSP 选配这件事,最怕的就是一上来装一堆服务器,结果项目里根本用不到,反而拖慢启动速度、增加 CPU 占用。OpenCode 的 LSP 配置是按项目走的,你完全可以每个项目只开当前语言需要的那个服务器。
2.1 LSP 的选型逻辑
先说我选 LSP 的几条硬标准:第一,对应语言官方维护或社区公认活跃的,尽量不选三五年没更新的;第二,能吃下完整的项目上下文,而不是只对单个文件生效;第三,启动速度快、内存占用别太夸张。
拿几个典型场景举例:写 TypeScript 首选 TypeScript 官方出的 typescript-language-server,它和 tsserver 同源,对类型推导、跳转、引用的支持最准;Python 项目我更推荐基于 Pyright 的 pyright-language-server,而不是 pylsp,因为前者对类型标注的理解明显更强,配合 Agent 做重构时给出的诊断信息更可靠;Go 基本没有悬念,gopls 就是官方标准;Rust 用 rust-analyzer,这一点也不需要讨论。
这里有个容易被忽略的细节:LSP 的“诊断能力”对 AI Agent 的帮助,比“补全能力”重要得多。编辑器里的 LSP 主要靠补全和跳转提升写码速度,但 Agent 需要的是错误定位、类型不匹配、引用断链这类诊断信息。配置的时候优先看语言服务器的诊断质量,别被补全手感骗了。
2.2 项目级配置怎么写
OpenCode 的 LSP 配置主要写在项目根目录的配置文件里。以 opencode.json 为例,一个最简单的 TypeScript + Python 双语言项目可以像下面这样配:
{ "lsp": { "typescript": { "server": "typescript-language-server", "args": ["--stdio"], "extensions": [".ts", ".tsx", ".js", ".jsx"], "project": "." }, "python": { "server": "pyright-language-server", "args": ["--stdio"], "extensions": [".py"], "project": "." } } }配置项看着不多,实际上有几个点值得细说。extensions决定哪些文件后缀会触发出对该 LSP 的请求,建议精准一些,比如 TypeScript 配.ts、.tsx、.js、.jsx,没必要混入.vue或.svelte,因为那些文件通常也有自己的语言服务器;project字段指定项目根目录,这决定了 LSP 在哪个范围里索引代码,如果项目比较大,建议指向子目录或者用 monorepo 包级别定位,避免把所有无关代码都索引一遍,否则首次启动会慢到你怀疑人生。
2.3 按语言推荐的 LSP 清单
为了让你直接抄作业,我把常见语言的推荐配置整理成一个表,这些组合我现在还在用,实测稳定度都很高。
| 语言 | 推荐 LSP | 启动方式 | 备注 |
|---|---|---|---|
| TypeScript / JavaScript | typescript-language-server | --stdio | 官方 tsserver,类型诊断最准 |
| Python | pyright-language-server | --stdio | 类型标注支持好,重构友好 |
| Go | gopls | --stdio | 官方工具链自带,稳定 |
| Rust | rust-analyzer | --stdio | 复杂项目最佳选择 |
| Java | eclipse-jdtls | --stdio | 启动慢但分析完整 |
| Lua | lua-language-server | --stdio | 单独 Lua 项目用,启动快 |
| C/C++ | clangd | --stdio | 需要 compile_commands.json |
表格里特别提醒一下 Java 的 eclipe-jdtls,之前有几次我图省事用了别的轻量方案,结果大型项目里类路径全部解析失败,诊断信息基本没法用,最后换回 jdtls 才正常。Java 生态的 LSP 没有捷径,省那点启动时间不值得。
2.4 配置时的禁忌与细节
配置 LSP 有几个坑,我逐个踩过,现在基本形成了条件反射。
第一个坑是同一语言装了多个 LSP。有的 LSP 之间有地址冲突,比如同时起 tsserver 和通过其它方式代理的 TS 补全,Agent 收到两份诊断信息之后上下文会被干扰。如果你发现模型改代码的时候总在纠结“另一个工具提醒的类型错误”,多半是这个原因。解决方案很简单:每种语言只保留一个 LSP。
第二个坑是忽略了 LSP 的启动时机。有些配置写完,OpenCode 不会立即拉起语言服务器,需要重新打开项目或者执行一次重载命令。判断 LSP 到底起没起来,最简单的方法是查看启动日志里有没有language server started之类字样,再就是观察 Agent 对自己代码的描述是否突然变得具体了——比如能直接说出“第 37 行的接口定义”而不是含含糊糊说“那个地方”。
第三个坑是 monorepo 场景下没搞清楚 LSP 的 project 根。monorepo 里如果直接指到仓库根,LSP 会把所有包全部索引一遍;如果只指到当前包,又可能拿不到跨包引用的完整信息。我的做法是先用仓库根配,测试之后如果发现索引太慢,再缩小范围加一份针对核心包的配置。灵活调整比一步到位靠谱。
3. Skill 推荐与实战:按需求挑技能包
LSP 解决的问题是“让模型看得准”,Skill 解决的问题是“让模型做得对”。两者定位完全不同,但配合起来效果叠加。这一节我把 Skill 的安装、编写和推荐一次性讲完。
3.1 Skill 的本质与安装方式
在 OpenCode 里,Skill 本质上是一个包含说明文档和可选脚本的目录,通过一个描述文件告诉 Agent“这个技能是什么、什么时候用、怎么用”。和传统插件不同的地方在于,Skill 的内容高度可读、可编辑,你完全可以用纯文本把它写出来,并在使用的过程中不断迭代。
安装 Skill 通常有两种途径:一是使用现成的 Skill 市场或仓库,把对应目录克隆到 OpenCode 的 skill 路径下;二是自己建一个目录手动写。我个人强烈建议学会第二种,因为现成 Skill 往往针对通用场景,属于基本盘,真正能提升效率的往往是你们自己项目需求的定制 Skill。
举个例子,我给自己写了一个“Code Review Skill”,要求 Agent 在收到 review 任务时先检查改动文件是否涉及核心模块、是否存在明显的错误处理缺失、是否遵循了项目的命名规范,最后按严重程度输出问题清单。这个 Skill 描述文件不长,但它在每次代码审查任务里强制模型走了一遍检查流程,效果比我每次在 prompt 里重复叮嘱要好得多。
3.2 核心 Skill 目录和描述怎么写
一个最小可用的 Skill 目录结构大概长这样:
my-skill/ SKILL.md scripts/ run.shSKILL.md 是灵魂文件,它负责描述技能的元信息和调用逻辑。里面可以包含 YAML 风格的前置信息,也可以包含大段的 Markdown 说明。我习惯这么写:
--- name: code-review description: 用于代码审查场景,按项目规范逐项检查改动质量 --- # Code Review Skill 当收到 review 或 代码审查 相关任务时,按以下步骤执行: 1. 读取 git diff,列出所有变更文件 2. 逐个检查变更是否涉及核心模块 3. 检查错误处理、边界条件是否合理 4. 检查命名和代码风格是否符合项目规范 5. 输出问题清单,按严重程度排序这里的description字段特别重要,因为 Agent 判断什么时候加载这个 Skill,主要就是靠它。描述写得越具体,匹配准确率越高。比如“用于代码审查场景”就比“审查代码”好用,因为它把触发场景点得更明确。
如果你想让 Skill 在真实 Agent 环境里更强大,还可以加上 Action 定义,给 Skill 绑定可执行的工具或脚本。这样 Skill 不只是静态规则,还能驱动 Agent 调用命令去拉取 git 状态、运行自动化检查,算是一个进阶玩法。
3.3 值得装的几类 Skill
Skill 不能乱装,装少了没用,装多了模型每次都要在大量候选里做筛选,反而拖慢响应。按我的实操经验,普通用户保留三到五个高质量 Skill 是最舒服的状态。下面这些方向是我实际用下来认为性价比最高的:
- 前端最佳实践类:适合 React、Vue 项目,内置组件拆分规范和常见反模式清单;
- 论文与研究辅助类:对于做学术写作的特别友好,能强制 Agent 按“摘要-引言-方法-实验-结论”的结构去组织内容;
- 数学建模类:让 Agent 在建模任务里优先考虑模型选择、假设条件、参数敏感性,适合竞赛和课题;
- 语言学习类:用于口语练习、语法纠错、造句训练,要求 Agent 扮演陪练而不是直接给答案;
- 代码规范类:类似我的 code-review Skill,但侧重风格约束和提交信息规范。
有一个搜索热度很高的词叫“仓颉 skill”,说的是为仓颉这门较新的编程语言专门做的技能包。如果你在学新语言或者公司内部有类似的自研语言,完全可以参照这个思路,把语言语法要点、常见坑位、惯用法写进 Skill,效果非常直接。Skill 这个东西最大的特点就是“可定制”,别把它当成一成不变的成品插件。
4. 模型与运行环境的搭配:好的 LSP 和 Skill 也需要靠谱的“大脑”
配好了 LSP,装好了 Skill,如果模型本身太弱,前面这些努力还是白搭。现实中很多人问“为什么我配了这些感觉没啥用”,排查到最后往往发现是模型选错了或者环境出问题了。这一节单独讲模型与运行环境,尤其是几个高频问题。
4.1 常见报错:opencode free tier can only be used from within opencode
先说一个几乎所有人都会碰到的报错,命令行里会冒出一句类似error from provider (console): opencode's free tier can only be used from within opencode。这个报错的意思是:你试图在 OpenCode 终端环境之外调用它的免费额度接口,比如在脚本里直接 curl 了某个 API,或者在另一个应用里把它当普通接口来用,而 OpenCode 的免费额度限定只能在它自己的终端会话内使用。
我刚遇到这个报错时也愣了一下,第一反应是网络问题,后面仔细读了提示才知道是上下文问题。解决方式一般不复杂:确认你在 OpenCode 的交互终端里运行而不是外部进程,重新登录或重启会话基本就好;如果你是集成到别的地方调它的接口,那就该换个思路了,要么用官方推荐的认证方式,要么直接配置自己的模型 API Key,别盯着免费额度薅。
这个报错其实侧面说明了 OpenCode 产品的定位:它想把完整的 agent 体验闭环在自己终端里,而不是变成一个人人可调用的开放 API。出现这个报错不用慌,先检查使用场景是否合规,再考虑换个接入方式。
4.2 模型选择与 OpenCode Go
OpenCode 本身并不绑定某一家模型,可以在配置里指定多种模型供应商。根据我的测试体验,代码生成、重构类任务,Claude 系列和 GPT 系列的表现都足够好;如果你更看重响应速度、上下文长度、成本控制,也可以接一些更轻量的模型跑简单任务,再在复杂任务切换到大模型。
最近被问得比较多的还有 OpenCode Go,很多人好奇它到底是什么。OpenCode Go 可以理解成官方提供的托管运行环境和模型网关,你本地起一个会话之后,可以把一些长任务丢到 Go 模式里跑,这样不用一直开着终端盯着。如果你是跨设备使用,比如白天在办公室电脑上开了一个会话,晚上回家想接着干,OpenCode Go 的云端会话能力就很有用。它的核心价值是让任务不依赖单台机器的持续在线。
这里想多说一句:在 OpenCode 里,模型和 Skill 的关系有点像“大脑”和“肌肉记忆”。模型负责理解和推理,Skill 负责提供稳定路径。用再好的模型,如果没有 Skill 约束行为,效果可能很飘;反过来,Skill 写得再好,模型太弱也执行不出质量。所以我的建议是模型选主流旗舰级,Skill 选真正贴合工作的那两三套,别贪多。
4.3 查看 Token 消耗与成本控制
用 OpenCode 这种 agent 工具,最怕的就是不知道钱花在哪了。模型每次读写文件、调用工具、生成回复都会消耗 token,一个复杂任务可能轻松烧掉几万 token。
在 OpenCode 里查看 token 消耗一般有两个入口:一是会话结束后的统计区域,会列出本次会话的输入输出 token 和各模型用量;二是在配置里打开 debug 或 verbose 日志模式,让每次请求的 token 数直接打到日志里。建议每次跑完长任务都扫一眼消耗,时间久了你会对自己项目的 token 成本有一个大致的感觉。
成本控制方面有几个实操技巧:给长文档类的 Skill 编辑描述时精简一些,不要每次任务都加载一堆用不上的内容;尽量让 Agent 少做无意义的全量文件扫描,能用 git diff 就看 diff,别让它通读整个仓库;简单任务明确指定轻量模型,重活才切旗舰模型。这些细节看上去很小,乘以每天几十次调用之后,节省的成本非常可观。
5. 常见问题与排查技巧实录
最后把这段时间里被反复问到的问题整理一下,基本都是安装、配置、运行层面的。整体做成一个可快速查阅的清单,比看长篇文档方便。我也顺带把排查思路写进去了。
5.1 安装与扩展问题
问得最多的是 OpenCode 怎么安装。这个要根据系统来选方式,macOS 或 Linux 用安装脚本就能拉起来,Windows 则可以用包管理器安装或者跑官方提供的安装命令。安装完成后一般会自动把opencode加到 PATH 里,如果出现找不到命令的情况,大概率是 PATH 没生效,重开一个终端窗口基本能解决。
还有朋友问“cursor 的扩展搜不到 opencode”,这大概率是把 OpenCode 当成了某个编辑器插件。OpenCode 本身是一个独立的终端工具,不是 VS Code 或 Cursor 的插件体系。虽然有人写了一些第三方集成让两者联动,但那属于额外玩法,不是标配。如果你就是想和编辑器配合,建议先跑通终端版的 OpenCode,再考虑扩展联动。
5.2 运行与连接问题
“opencode 归档后去哪了”这个问题我一开始也没看懂,后来确认了:这里说的归档不是文件归档,而是会话归档。OpenCode 的老会话会被归档起来,你可以通过历史列表把它们重新调出来继续用。如果找不到归档入口,大概率是版本差异问题,更新到 v2 之后界面和命令都有所调整,归档功能的位置也变过。
另一个高频问题是 token 消耗怎么看,在第 4.3 节已经讲过。还有一个不算问题但很多人会犯迷糊的:OpenCode 装了桌面版之后还要不要命令行版。其实桌面版和命令行版可以共存,桌面版给不习惯终端的用户一个图形入口,命令行版适合脚本化和远程场景。两者共享会话数据,实际使用中建议选一个当主力,另一个备用。
5.3 问得最多的问题速查
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
| 补全/跳转没反应 | LSP 没正确加载 | 检查语言服务器是否安装、配置 extensions 是否正确 |
| Agent 总读不准代码结构 | LSP 缺失或配置错误 | 按 2.2 节项目级配置重新设置 |
| free tier 报错 | 在 OpenCode 外调用免费额度 | 在 OpenCode 终端内使用,或配置自己的 API Key |
| Skill 不生效 | 描述不匹配,或路径不对 | 检查 SKILL.md 的 description 字段,确认目录位置 |
| 会话档案找不到 | 版本差异或入口变更 | 升级到新版后用历史列表查找,或执行对应命令 |
| 模型回复质量飘 | 模型过弱或 Skill 过载 | 切换旗舰模型,精简 Skill 到核心三到五个 |
表里这些场景都是真实高频问题,你可以当成排查手册用。遇到新问题的时候,我的通用排查顺序是:先看日志、再看配置、最后怀疑模型。日志里通常记录了 Agent 每一步的思考过程和工具调用情况,能快速还原现场,比反复试配置高效得多。
最后再分享一个小技巧:配置完 LSP 和 Skill 之后,别急着跑复杂任务,先让 OpenCode 自己总结一下当前项目的结构和已经加载的能力。如果它能准确说出项目有哪些目录、哪些核心依赖、装了几个 Skill 以及每个 Skill 的用途,说明环境基本没问题了。这个“自检式”的验证方法,能帮你节省大量排查时间,也是我最近用得最顺手的一个习惯。