
把OpenCode装好之后大部分人的第一反应是“这玩意儿到底怎么配才顺手”。网上搜一圈资料大多是零散的安装教程和截图真正讨论LSP和SKILL搭配的内容很少。我断断续续用了将近三个月中间推翻重配了好几次踩了无数坑才把一套相对稳定的组合固定下来。这篇就把我实测后的结论和完整思路整理出来供大家参考。1. 先掰开揉碎LSP和SKILL在OpenCode里分别解决什么问题说实话很多人对LSP和SKILL的概念是模糊的。这两样东西虽然都跟“让编辑器/终端更懂代码”有关但它们的运行逻辑完全不同。搞不清楚边界配置起来就会一团糟。1.1 LSP的本质是一个“消息翻译层”LSP全称Language Server Protocol它的核心作用是“定义一套标准协议让语言服务和编辑器/客户端解耦”。简单理解以前你写Java要用Eclipse写TypeScript要用VSCode的对应插件因为每个编辑器都有一套自己的实现方式。而LSP出现之后语言分析能力被打包成一个独立的“语言服务器”任何支持LSP的客户端都能通过标准JSON-RPC消息去调用它获得补全、跳转、诊断、悬停提示等等能力。OpenCode之所以强烈建议配合LSP使用是因为它的主界面虽然是一个交互式终端但它本质上是一个面向开发者的AI编码Agent。Agent要给出靠谱的补全、准确地定位符号、判断代码里的类型错误不能只靠“猜”它需要真实语言服务器的分析结果。这就是LSP在OpenCode里的地位——它不是可选项而是直接影响Agent输出质量的底层设施。1.2 SKILL在OpenCode里扮演的角色SKILL这个词在最近的AI编码工具圈子里被频繁提及。在OpenCode的语境下SKILL可以理解为一组“注入给模型的结构化工作流指令”。不同于LSP那样干的是实时解析代码的活SKILL更偏向于“约束Agent在面对某个任务时按照特定的步骤、上下文收集方式、输出格式去执行”。举个例子你可以给Agent配置一个code-review.skill告诉它当你输入/review的时候它应当先读取git diff、再按团队规范检查、最后用指定格式输出审查意见。没有SKILL的时候你每次都要在对话里反复重申这些要求有了SKILL之后一个命令就能触发一套完整的工作流。1.3 两者如何分工协作简单来说LSP让OpenCode的“眼睛”更清晰SKILL让OpenCode的“大脑”更专业。前者解决的是“看清楚当前代码库的真实状态”后者解决的是“面对特定任务时应该按什么套路干活”。这两个并不冲突反而是一种互补关系。我在配置时最深的体会是如果只配LSP不配SKILLAgent会显得很“呆”它能看懂代码但不知道该用什么节奏给你干活如果只配SKILL不配LSPAgent会显得很“飘”它说得头头是道但代码里的类型错误、符号引用错误全看不见。两样配齐了之后效率才真正上去。2. LSP选型我实测后保留下来的最终清单与选择逻辑2.1 TypeScript/前端项目typescript-language-server 是底座我日常工作里前端项目占一半以上TypeScript几乎绕不开。试过好几个方案最后留下来的是typescript-language-server typescript的组合。这个组合的优势在于它直接调用本地TypeScript编译器来提供语言服务语义补全和类型诊断的准确度是所有LSP里最稳的。配置方式很简单在OpenCode的连接配置里加上{ lsp: { typescript: { command: [typescript-language-server, --stdio], extensions: [.ts, .tsx, .js, .jsx, .vue, .svelte] } } }选择策略上我没有直接选用volar/language-server来统一处理vue和ts原因是它会把诊断速度和稳定性拖得比较慢。对vue项目我更倾向于用volar处理template部分、typescript-language-server处理script部分两个LSP并行服务同一个文件的不同层面实测下来内存占用只多了一点点但响应速度提升明显。如果你用的是npm全局安装记得先跑一次npm ls typescript-language-server确认你已经装了对应版本。很多人配置不生效最后发现是压根没安装成功。2.2 Python项目pyright比pylsp更省心Python这块我先后测过pylsppython-lsp-server和pyright。结论非常明确除非你有很特殊的插件需求否则直接上pyright。原因在于pyright的语义分析能力比pylsp强出一大截特别是在复杂类型注解、泛型推导、跨文件引用这些场景下诊断结果的准确性有明显差距。而OpenCode的Agent在做跨文件重构时非常依赖准确的符号表和类型信息。{ lsp: { python: { command: [pyright-langserver, --stdio], extensions: [.py], settings: { python.analysis.autoSearchPaths: true, python.analysis.useLibraryCodeForTypes: true } } } }这里有个小坑要提醒pyright的useLibraryCodeForTypes这个选项在大型项目里会拖慢初始化速度。如果你项目依赖很多建议第一次启动时先留空让它建立缓存之后再把useLibraryCodeForTypes开起来。2.3 Go、Rust、C等其他语言场景Go项目的选择很清晰官方推荐gopls没什么好纠结的。Rust那边是rust-analyzer稍微需要注意的一点是rust-analyzer首次启动的索引会非常吃CPU和内存项目特别大的时候建议给OpenCode单独设置一个较高的内存上限否则会出现进程被系统杀掉的情况。C/C我一般用clangd。它有两点做得比ccls好一是对现代C标准的支持更及时二是内置了非常实用的重构和代码动作比如extract function、rename symbol等等。不过clangd需要一个compile_commands.json才能发挥完整能力没有这个文件的时候它基本退化成一个带语法高亮的编辑器功能非常有限。我建议在CMake项目里加一句CMAKE_EXPORT_COMPILE_COMMANDSON让它自动生成。另外像JSON、YAML、TOML这类配置文件我装了对应的语言服务器之后才发现原来OpenCode对它们的模糊识别问题有多严重。vscode-json-languageserver和yaml-language-server开起来之后Agent在读取配置时不会再瞎猜结构这对调试项目配置非常有用。2.4 为什么LSP数量“宜少不宜多”这是我踩过的一个比较深的坑。早期我把所有语言服务器一股脑全配上去想着“多多益善”结果OpenCode启动时每个LSP都要拉起进程、初始化工作区光索引就花了半分钟以上而且内存占用高到离谱。后来我把清单删到只剩当前项目实际用到的语言并且给每个LSP设置了enabled标志按项目自动启用。这样做的还有一个额外好处——Agent回答时的上下文里不会掺杂过多无关语言的诊断信息生成结果会更聚焦。一句话总结我的LSP选型思路主流语言用官方维护的服务器小众语言宁可不用也不要乱配LSP的数量以项目实际使用为准不要让大量闲置的服务器常驻内存。3. SKILL推荐让Agent从“懂代码”升级为“懂你的项目”3.1 基础必备型SKILL先把“规矩”立起来最早我用OpenCode的时候总感觉Agent像一个“技术很强但不懂规矩”的新人代码写得挺好但完全不符合项目规范。后来发现SKILL就是用来解决这个问题的。我首先配置了三个基础SKILL。第一个是workflow它规定了日常任务的通用顺序分析需求 → 搜索现有代码 → 设计方案 → 写码 → 自测 → 整理变更。这个SKILL有效避免了Agent一上来就埋头写代码的冲动。第二个是commit-message它定义了commit信息生成规则。之前手写commit message太痛苦Agent又经常写出一堆“update xxx”这种毫无营养的话。配置好这个SKILL之后OpenCode能按照conventional commits规范输出格式统一的提交信息。第三个是code-review它把审查流程固定下来先看diff → 检查明显bug → 检查风格 → 检查安全性 → 输出分级意见。这样我每次执行/review时得到的结果都是结构化的可以直接贴在评审群里。没配这个SKILL之前Agent的review结果经常是一条流水账用起来不是很顺手。3.2 我自己编写的SKILL文件逻辑我用的SKILL结构本质上是一个文件夹里面放一个SKILL.md和若干辅助文件。这个SKILL.md用YAML front matter写元信息正文部分写具体的指令。以我的code-review为例--- name: code-review description: 按团队规范审查代码变更输出结构化意见 --- 当用户执行/review时按以下步骤执行 1. 先运行 git diff main 获取当前分支的全部变更内容 2. 按 severity 分类检查 - High: 可能导致运行时错误、安全问题、数据丢失的逻辑 - Medium: 边界情况未处理、资源未释放、可读性较差 - Low: 风格问题、命名问题、缺少注释 3. 输出格式为 markdown 表格文件/行号/严重级别/问题描述/修改建议 4. 最后根据问题数量给出一个 overall health score这里有个非常重要的细节SKILL里写的步骤一定是Agent能实际执行的不要写“分析用户意图”这类模糊的要求。我第一版写得太抽象结果每次执行出来的review质量忽高忽低。后来我把所有动词都换成了可操作的指令比如“运行git命令”、“读取文件”、“定位到具体行”效果立刻稳定下来。3.3 那些让我眼前一亮的高质量SKILL除了自己写的基础SKILLGitHub上其实有不少社区维护的高质量SKILL可以直接拿来用。比如impeccable它定义了一套非常严格的代码质量标准从输入验证到错误处理再到测试覆盖都有明确要求。个人感觉这套规范用在需要交付“生产级”代码的场景特别有用。grill这个SKILL我也经常用。它设计的是一种“犀利反问”模式Agent会不断对你的方案提出挑战性问题帮你提前发现设计缺陷。一开始被它问得有点烦躁但它确实逼着我把很多模糊的设计决定给想清楚了。还有个比较特殊的book-to-skill它能把一本技术书籍的核心章节提取成可执行的SKILL文件。我拿一本讲设计模式的书试过它把工厂模式、观察者模式的Python示例全部转成了指导Agent生成代码的规则。对于需要大量参考某个特定编程风格的团队来说这种SKILL非常值得一试。3.4 如何管理和复用SKILLSKILL多了之后管理就成问题了。我的做法是把所有SKILL放在一个统一的~/.config/opencode/skills目录下每个SKILL一个子目录再配合OpenCode的全局配置自动加载。不同项目需要特定SKILL的就在项目根目录下建一个.opencode目录覆盖进去。还有一个更实用的技巧用Git管理SKILL库。我把团队共用的SKILL放在一个私有仓库里换机器时直接clone下来再做一个软链接几秒钟就能恢复一整套路基配置。4. 配置落地从零到能跑的完整链路与验证方法4.1 安装OpenCode和基础依赖安装这一步其实没什么特别的先确保Node.js版本在18以上然后执行npm install -g opencode-ai装完先跑一下opencode --version确认安装成功。接着要确认LSP相关的命令行工具是否都装好了。这一步最容易遗漏我建议准备一个检查清单which typescript-language-server→ TypeScriptwhich pyright-langserver→ Pythonwhich gopls→ Gowhich rust-analyzer→ Rustwhich clangd→ C/C哪个命令提示找不到就说明对应LSP还没装。各语言的环境管理器不同我这里不展开但原则是用各语言官方推荐的安装方式不要用Homebrew装一锅炖那样版本容易乱。4.2 OpenCode配置文件的目录层级配置OpenCode有个容易搞混的地方它同时存在用户级配置和项目级配置。用户级配置放在~/.config/opencode/opencode.json影响所有项目项目级配置放在项目根目录下的.opencode/opencode.json只影响当前项目。我自己的习惯是LSP配置全部放用户级因为开发环境是全局统一的SKILL按项目维度配置因为不同项目的规范差异比较大。另外项目级配置里经常会覆盖用户级配置的某些字段如果你发现某个设置没生效优先检查是不是被项目级配置覆盖了。4.3 一个完整的opencode.json示例下面是我在某个前端项目里实际使用的配置注释部分是我后加的说明{ model: { provider: anthropic, model: claude-sonnet-4-5, temperature: 0.2 }, lsp: { typescript: { command: [typescript-language-server, --stdio], extensions: [.ts, .tsx, .js, .jsx, .vue, .svelte] }, css: { command: [vscode-css-language-server, --stdio], extensions: [.css, .scss, .less] } }, skills: { paths: [./.opencode/skills, ~/.config/opencode/skills] }, environment: { OPENCODE_DISABLE_TELEMETRY: true } }有人可能会问temperature: 0.2是不是太低会不会让Agent显得太死板。我实际体验下来编码场景里低temperature带来的稳定性远大于创造性带来的收益。如果你需要Agent做头脑风暴可以在对话里单独追加剧场的指令不用全局调高。4.4 验证配置有没有真正生效配完之后一定要做验证别急着开工。我在每个LSP接入后都会做一个通用的自测找一个项目里的核心文件让OpenCode做一次/definition跳转如果能够准确跳到符号定义处说明LSP基本生效。再开一个诊断检查看看类型报错是否能正常提示。SKILL的验证更简单直接在当前项目执行/skills目录列表确认配置的SKILL都出现在列表里然后挑一个有明确输出格式的SKILL跑一次检查输出是否符合预期。我见过SKILL路径写错却没有报错的场景执行的时候才发现根本没被加载挺浪费时间的。5. 高频问题排查与日常优化5.1 那些“装了但没反应”的LSP问题这类问题排查思路非常固定先确认进程有没有起来。打开系统的进程监视器搜一下对应的LSP进程名。如果进程没有出现大概率是command里写的可执行文件路径不对或者没有安装成功。进程起来了但没反应的情况也很常见此时多半是文件扩展名配置和语言ID不匹配。OpenCode对每种LSP都有特定的extensions白名单我踩过最典型的例子是把.ts文件扩展名配给了volar而不是typescript-language-server结果符号跳转时好时坏一直以为是LSP不够稳定最后定位到是扩展名分配的问题。此外--stdio参数一定不要丢。LSP可以用stdio、socket、pipe等多种传输方式OpenCode默认走stdio你如果生搬硬套其他编辑器的配置把参数漏掉了就建立不了连接。5.2 “错误提示一闪而过”的异常排查如果你在执行某个操作时看到类似“error from provider”的报错我的经验是先看日志。OpenCode有详细的日志文件默认位置在~/.local/share/opencode/log/里面会记录LSP进程的stderr输出。大部分情况下错误根源不是OpenCode本身而是语言服务器启动参数或当前工作目录的问题。其中比较典型的场景是语言服务器在启动时要求当前工作目录必须是一个合法的项目目录如果你在空目录或没有初始化的目录里运行OpenCodeLSP就会启动失败。解决方法是先在项目根目录下初始化好项目结构再启动OpenCode。另外如果配置过代理或网络隔离策略LSP下载依赖阶段也可能报错优先检查你的网络环境能不能访问到对应的包源。5.3 token消耗太高我的实际优化心得OpenCode这类AI编码工具绕不开token消耗问题。我的体感是如果LSP配置不对Agent会反复读取低级信息——比如翻遍整个node_modules来找一个符号定义。正确的LSP配置能让Agent直接用语言服务器拿到精准结果大量减少无效的文件读取token消耗能降不少。另外几个我实测有效的方法给OpenCode设置--ignore参数把node_modules、dist、build这类目录排除出上下文扫描范围。用.opencodeignore精确控制哪些目录允许Agent搜索。在对话中主动使用/memory把项目的核心架构信息固化下来避免Agent每次对话都重新扫描全局。对超大项目建议按功能模块拆分对话而不是在同一个会话里跨多个模块反复询问。这些优化组合下来我目前一个中型前端项目1000文件的日常token消耗比最初减少了大约三成同时响应速度也快了因为Agent无需反复扫描无用目录。5.4 内存与性能问题LSP泄漏内存是大家普遍会遇到的问题。rust-analyzer和pyright这类重量级服务器在工作区索引之后仍然常驻大量内存。我的策略是给OpenCode设置好内存上限并在不需要语言分析的时候及时关闭对应LSP。另外一个容易被忽略的点是LSP的版本更新频率很快特别是typescript-language-server这类紧跟官方协议实现的服务器。每隔一段时间就要做一次全局升级否则新语法特性解析会出错。我的做法是写了一个简陋的升级脚本把所有语言服务器工具统一更新到最新稳定版实测这对减少很多“玄学”问题帮助巨大。说到最后我真心建议不要把LSP和SKILL的配置搞得太复杂。以我目前的习惯日常主力其实就几个TypeScript、Python、Go三个LSP加上自己写的workflow、code-review和一组项目规范类SKILL。这套组合已经稳定跑了相当长的时间基本没再折腾过。剩下的时间不如多花在优化SKILL里的具体指令上因为那才是决定你与Agent协作体验上限的地方。