1. 工具(Tools):先把 Agent 的“手”摸清楚
opencode 真正跟普通聊天客户端拉开差距的地方,不在界面好看,而在它真的会动手。你让它“看一下这个报错是什么意思”,它不是只给你一段泛泛而谈的回答,而是会自己打开项目、定位日志、复现问题,然后直接给你改代码。要做到这一步,靠的就是它内置的那一整套工具系统。这篇下篇既然要聊工具、服务面、外壳和实战集成,那就得先从工具说起——这是整个 Agent 能力的物理基础,不把它搞明白,后面聊 MCP 和集成都是空中楼阁。
1.1 内置工具全家桶:模型到底能摸到什么
以我手头当前版本为例,opencode 暴露给模型调用的核心工具大概是这么几类:执行命令的 bash、读写文件的 read/write/edit、搜索文件的 glob、搜内容的 grep,还有抓取网页内容的 browse/fetch。这些东西单看都挺朴素,但它们组合起来就是 Agent 的手脚——模型每走一步,本质上都是在“看一眼文件 → 想一下 → 改一行 → 跑一下命令验证”这个循环里打转。
我实际用下来的感受是,其中 bash 这个工具最关键,也最危险。它给了模型在当前工作目录里执行任意命令的能力,从ls、git diff到npm test、python manage.py migrate都能跑。model 本身不碰真实环境,它只是生成工具调用的参数,由 opencode 在本地进程里真正执行,再把标准输出和退出码喂回给模型。这就是整个 Agent 循环最核心的机制:模型是大脑,工具是手,opencode 是那根连接大脑和手的神经。
在工具调用的呈现上,opencode 做得比较贴心。你在 TUI 里能看到它每一步调用了哪个工具、传了什么参数、输出是什么,而不是像某些产品那样把中间过程糊成一个黑盒。这对于排查问题特别有用——比如它哪一步改坏了,你能直接看到是哪个文件的哪一行出了问题,而不是等它跑完再人肉 review 一遍 diff。
1.2 权限与确认机制:不能让它“想跑就跑”
工具既然这么强,权限控制就必须跟上。opencode 默认情况下很多操作是自动执行的,这个设计取舍我很理解——如果一个操作还要你每一步都点“允许”,那就跟普通问答没区别了,Agent 的“自主性”就废了。但在真实工程环境里,全自动执行 bash 和写文件是相当冒险的,尤其是你在生产目录、数据库脚本或者线上服务器上操作的时候。
opencode 的做法是提供配置层级的权限策略,你可以针对不同工具设置“直接执行 / 需要确认 / 禁止”。我自己的习惯配置大致是:
{ "permission": { "bash": "ask", "write": "allow", "edit": "allow" } }大意是:写代码、改代码这类高频操作放行,但执行命令必须经过我确认。这样既保住了效率,又没把门完全敞开。关于这个配置我要提醒一句:字段名和取值以你装的版本为准,opencode 迭代非常快,文档里的 schema 隔一阵就可能微调,我这边遇到的版本和网上教程不一致的情况不止一次。
实际踩坑后的教训是:如果你在容器或者沙箱里跑 opencode,权限可以放开一点;如果在宿主机上直接跑,尤其是涉及rm、git push、docker这类高危命令,一定要让 bash 走确认模式。另外它还支持在特定目录下自动放行脚本,比如测试命令就不用每次问,这块属于进阶玩法,等你自己把基础跑顺了再慢慢调。
1.3 自定义工具:把业务能力也交给 Agent
内置工具覆盖了通用场景,但真实项目总有它够不着的地方。比如我司内部有个发版工具,命令行参数极其复杂,还有一套自己的权限校验逻辑。这种场景你没法指望模型凭空知道怎么用,这时候就得走自定义工具这条路。
自定义工具在我看来有两条路。一条是走 MCP,把内部服务包成一个标准接口给 Agent 调,这个我在下一章详细说。另一条更轻量:写一个普通脚本,然后通过 AGENTS.md 或者项目文档告诉模型“这个脚本是用来干嘛的、什么时候该调、参数怎么传”。比如我在一个项目里放过scripts/deploy/test.sh,然后在 AGENTS.md 里写清楚它接收什么参数、输出什么格式、调用前需要检查哪些环境变量。结果就是 Agent 在处理“帮我发个测试环境”这类需求时,真的会自己找到这个脚本、按文档拼好参数、执行完再把结果总结给你。
这个事让我意识到,自定义工具的核心不在于“能不能跑”,而在于“模型知不知道在什么场景下用、怎么用”。你把脚本写得再完美,如果文档里没说明触发场景,模型大概率会在真正需要它的时候视而不见,反而绕远路去干一些更笨的事。所以我的建议是:每个自定义脚本的注释里,一定要写清楚“这个脚本解决什么问题,什么情况下不应该用”,这比写一万行代码注释都管用。
2. 服务面(Servers):把外部世界拉进对话
工具解决了 Agent 跟本地文件系统的交互,但真实工程不可能只活在本地。你要查生产数据库、要开 GitHub Issue、要看监控平台的数据,这些全都跑在外部系统里。如果 Agent 够不到它们,那它干活的能力就还停留在“单机版小助手”的水平。这时候就该服务面上场了。
2.1 MCP 是什么,以及为什么值得关心
MCP 的全称是 Model Context Protocol,我通常跟人这样解释:它相当于给 AI 客户端装了一堆“USB 外设驱动”,每个外设就是一种能力——数据库查询、GitHub 操作、文件系统访问、公司内部 API,统统可以做成一个 MCP Server,让 Agent 像调用本地工具一样去调用它们。这种思路本质上跟浏览器扩展很像:核心浏览器做通用事,扩展负责接不同网站的能力。
在 opencode 里,MCP Server 是你配置进去的“服务面”——它向外连接真实世界的数据源和服务端。这跟前面说的内置工具不一样:内置工具是 opencode 自己实现的,MCP 则是社区和团队自定义生态。我见过有人给自己团队接了个 ClickHouse 查询服务,让 Agent 能直接查埋点数据来辅助排障;也有人接了一整套内部工单系统,Agent 可以在排查问题时自动创建工单、补充上下文。这些能力要是单靠内置工具,几乎不可能实现。
从成本角度看,MCP 还有一个容易被忽略的价值——它把“数据接入”这件事标准化了。以前你想让 AI 读某个系统,得靠工程师给那个系统单独写插件、做适配;现在只要这个系统提供 MCP Server,任何支持 MCP 的客户端都能直接复用。同一套服务面,今天给 opencode 用,明天给其他兼容 MCP 的工具用,投入一次,受益很久。
2.2 接入一个 MCP Server 的完整操作
接入 MCP Server 的实际操作并不复杂。你可以直接通过命令添加,比如:
opencode mcp add my-pg -- npx @my-org/pg-mcp-server也可以直接改配置文件,在opencode.json里的 mcp 字段加一段:
{ "mcp": { "my-pg": { "type": "stdio", "command": "npx", "args": ["-y", "@my-org/pg-mcp-server"], "env": { "DATABASE_URL": "${DB_URL}" } } } }这里的${DB_URL}是引用环境变量的写法,强烈建议你都用这种方式,别把真实连接串直接怼进配置文件里。配置好之后重启会话,Agent 就能感知到这个服务面提供的工具集合了。
我接入的第一个服务面是本地数据库查询,当时给它的任务是“查一下订单表里昨天支付成功但回调失败的记录”。你猜怎么着?Agent 自己决定调用那个查询工具,拼好 SQL,执行完把结果整理成一份问题清单给我,全程我没碰一下数据库客户端。那种“原来这玩意儿真的能打通外部系统”的感觉,确实挺震撼的。
需要说明的是,MCP 有两种常见连接方式:stdio 和 SSE/HTTP。stdio 适合本地起子进程的场景,比如上面那个用 npx 拉起 Node 包的例子;SSE/HTTP 适合跑在远程的服务,比如部署在公司内网里的一台机器上。两者在配置里的区别就是type字段从stdio换成sse,再加一个url指向服务地址。如果你用的是远程模式,注意确认认证方式,常见的有在 header 里带 token 的写法,具体以你那个 MCP Server 的文档为准。
2.3 服务面避坑:MCP 不是配完就完事
接入 MCP 之后我也踩过不少坑,挑几个最值得说的:
第一个坑是启动超时。很多基于 Node 的 MCP Server 用 npx 启动,首次运行要现场拉包,慢的时候几十秒都有可能,Agent 那边等不及就直接超时报错了。我的解决办法是提前把依赖装到全局,或者干脆编译成二进制再配置,启动时间能压到一两秒内。这个问题在 CI 或非交互模式里尤其致命,因为没人会守在屏幕前帮它等。
第二个坑是凭据泄漏。MCP Server 的 env 配置里经常要放 token 或连接串,如果你把opencode.json提交进 git 仓库,这些秘密就等于裸奔了。我见过不止一次有人把写死的数据库密码提交到公司代码库,后续不得不批量轮换凭据。正确做法一律是环境变量引用,配置文件里只保留占位符。
第三个坑是“一次别接太多”。MCP Server 的工具会全部塞进模型可用的工具列表里,接五六个服务面之后,工具数量能到几十个。这会让模型在频繁决策时犯迷糊,同时也会吃掉大量上下文窗口,因为每次请求都要把工具定义完整带过去。我的经验是,项目里按需接两三个核心服务面就足够了,别的用的时候再临时加载,别一股脑全堆上。
另外注意:服务面挂了之后,模型不会自动知道“这个工具不可用”,它会反复尝试调用然后反复失败,白白烧掉一大把 token。遇到工具调用异常,建议直接中断会话,修好 MCP 服务再继续,别让它硬着头皮重试。
3. 外壳(Shells):决定你每天用什么姿势用 opencode
工具和服务面决定了模型能干多少活,而“外壳”决定了你作为一个人类,每天怎么跟它打交道。opencode 这一点做得比较聪明——它不锁死你只能用它的 TUI,编辑器扩展、远程终端、容器环境、第三方终端软件都能跑。这章聊聊我试过的几种姿势,以及各自适合什么人。
3.1 原生 TUI:颜值和效率都在线
opencode 最出圈的就是它的终端界面。基于 Ink 渲染的 TUI,看起来非常现代,左侧会话列表、主区消息流、底部输入框,整个走的是简洁路线。我第一次打开的时候确实愣了一下,因为印象里的命令行 AI 工具界面都挺朴素的,它这个细节完善程度更像是一个成熟的桌面应用。
日常使用的话,有几个操作比较顺手。一是通过@符号引用文件或目录,把指定内容作为上下文喂给模型,不用手动复制粘贴大段代码。二是在对话流和事件流两个视图之间切换,对话流干净只留消息,事件流能看到工具调用细节,相当于一个是面向结果的,一个是面向过程的。三是快捷键切换侧栏和管理会话,用熟了之后基本可以不碰鼠标。
TUI 的另外一层好处是浸泡在终端环境里。我在终端里能同时开着 opencode、日志跟踪、Git 面板和测试监听器,一个问题从发现到修复全程不用切窗口。这种“一个界面干完所有事”的体验,对于常年泡在命令行里的开发者来说,效率收益是肉眼可见的。
3.2 VS Code 扩展:编辑器里直接干活
不是每个人都喜欢终端的,很多人日常都在 VS Code 里面工作。opencode 提供了 VS Code 扩展,装完之后可以直接在编辑器侧边栏打开会话面板,选中代码片段后一键发给 Agent,上下文自动带上。
这个集成方式跟原生 TUI 的感受很不一样。TUI 更像是“我主动去找 Agent 干活”,VS Code 扩展则更像是“代码写到一半,顺手叫它帮个忙”。比如你正在改一个函数,突然想重构一下,选中那段代码,呼出 opencode,让它给个方案或者直接改,它改完你能立刻在 diff 视图里确认。这种感觉更像是在和一个结对程序员配合,不需要离开编辑上下文。
VSCode 扩展和 CLI 共用同一套配置和会话历史,所以两边切换不会精神分裂。我自己的搭配是:日常写代码用 VS Code 扩展做轻量交互,大批量重构或需要 Agent 自主跑长任务的时候切到终端用 TUI。两边各司其职,体验会舒服很多。
3.3 远程环境:SSH、容器与第三方终端
还有一类场景是远程开发。我经常要连到服务器或者开发容器里干活,这时候 opencode 也能用得起来。最简单的方式是 SSH 到远程机器后在终端里直接启动 TUI,本地终端软件负责渲染。选对终端软件很重要,我用过的几款里,iTerm2、Windows Terminal 对它的渲染支持都算可靠,tabby 也挺好用,但某些细节渲染偶尔会抽风,比如界面闪烁或者焦点错乱——遇到这种兼容性问题,果断换终端,别硬扛。
如果跑的是批处理任务,不需要交互界面,那就更简单了。远程机器上装好 opencode 之后,直接用它自带的非交互模式跑:
opencode run "扫描这个目录下的所有 TODO 注释,汇总成一份清单"任务跑完它会输出结果,你可以重定向到文件里慢慢看。配合 tmux 的话还能实现“断开 SSH 任务照跑”,非常适合在服务器上做代码审查、批量改配置这类不需要人盯着的任务。
这里提醒一句:老旧的终端软件对 TUI 渲染支持普遍不好,Win10 自带的旧版控制台、某些精简版终端模拟器都会出现布局错乱的问题。如果你在 Windows 上遇到界面异常,优先试一下 Windows Terminal 或者 WSL 里的终端,大部分问题都能解决。
4. 实战集成:从“玩具”到“生产力”
工具、服务面、外壳这三层都聊完了,接下来是真正的考验——怎么把它们组合起来,塞进真实的研发流程里。这一章我会用几个实际场景来拆解,包括让 Agent 独立完成一次重构、多模型接入与额度管理、以及如何通过 Skill 沉淀团队经验。
4.1 让 Agent 独立完成一次代码重构
我最推荐的切入方式是选一个边界清晰、可以验证的小任务。比如“把 utils/time.ts 里的日期格式化逻辑统一改成 dayjs 封装,并补上对应的单元测试”。这种任务规模不大,不会失控;但链路完整,能体现 Agent 干活的全过程。
实际操作时,Agent 的行动序列大概是这样的:先列出目录看看项目结构,然后读目标文件和相关调用方,接着列一个简短计划,开始改代码,跑测试,如果测试挂了还会自己看报错修 bug,最后把改动汇总成一段说明。全程你只需要在关键时刻给确认,剩下的它能自己推进。
这里有一条非常关键的经验:任务边界描述得越清晰,Agent 的表现越可靠。你说“帮我优化一下时间处理”,它可能纠结半天方案;你说“改用 dayjs 封装并保持现有 API 不变”,它整个执行过程就会果断得多。所以我的建议是,无论你想让它干什么,至少要在任务描述里明确三件事:要改哪个模块、约束是什么、怎么算完成。
另外一个容易被忽略的杠杆是 AGENTS.md。这个文件放在项目根目录,相当于给 Agent 写的项目协作手册。我一般会在里面写清楚代码风格要求、目录结构说明、测试命令、禁区目录等。放了这个文件之后,Agent 生成的代码明显更贴合团队习惯,不会动不动就给你整出跟现有风格格格不入的东西。它相当于团队新人的入职手册,只不过读者是 AI。
4.2 多模型接入与额度管理:国产模型也能当主力
opencode 的另一个实用特性是支持多个模型提供商,而且配置起来非常直接。以兼容 OpenAI 协议的服务为例,你只需要在配置里指定 baseURL 和 API key,就能把国内模型提供商接入进来。我现在的环境里就同时配了 DeepSeek、通义和智谱的入口,日常按任务难度分配模型。
配置大概长这样:
{ "provider": { "deepseek": { "npm": "@ai-sdk/deepseek", "apiKey": "${DEEPSEEK_API_KEY}" } } }不同提供商的字段可能不同,但套路类似。这套多模型配置对我的价值在于成本控制:简单问答、格式整理这类轻任务用便宜的小模型,复杂架构设计和长链路重构才动用更强的模型。同样的任务,用不同模型跑,费用能差出一个数量级,这个账算一算还是很值得的。
提到多模型,就绕不开“opencode go”这类网关服务。我个人的理解是,它相当于一个模型接入代理层,把多家模型收敛成一个统一入口,配一个 key 就能在会话里随时切换模型,省去了每条 provider 单独维护密钥的麻烦。实际用下来确实方便,但有一个坑值得大家注意:套餐额度是不是按模型分开计算的,一定要提前看清楚。我之前误以为套餐内所有模型共享同一个额度池子,结果某个模型单独计费,月底一看账单超了不少。后来学乖了,每次都先到网关后台查用量明细和剩余额度,确认清楚再选套餐,不再想当然。
4.3 Skill 搭建:把团队经验沉淀进工具
再往深走一步,opencode 支持 Skill 机制,这让团队的隐性知识有了落地的载体。Skill 本质上就是一份 Markdown 文档,里面描述某个场景的触发条件、执行步骤和注意事项,放在约定的 skills 目录下。Agent 遇到匹配场景时,会自动读取这份文档并按里面的流程执行,相当于给 AI 装上了老师的教案。
比如我在一个项目里写过一份“性能问题排查”的 Skill,内容大致是:收到性能反馈时,第一步先看入口接口的耗时分布,第二步用 profiler 抓热点,第三步按数据库慢查询、外部服务依赖、代码热点三个方向排查,最后把结论写成固定格式的文档。有了这份 Skill 之后,新人让 Agent 排查性能问题,走的就是老手沉淀下来的路径,不会东一榔头西一棒子。
Skill 模板的写法大致是:
--- name: perf-triage description: 当用户反馈页面或接口性能问题时使用 --- 1. 找到对应接口的入口文件,检查耗时日志 2. 用 profiler 抓取热点,输出火焰图 3. 分别检查 SQL 慢查询、外部依赖耗时、代码热点 4. 将结论按模板写入 docs/perf-report.md这件事的长期价值在于,团队的经验不再只存在老员工的脑子里。有人离职,经验能留在 Skill 里;新人上手,等于带着一个按团队方法论训练的助手在干活。队的效率曲线会因此变得平滑很多。
4.4 常见报错与排查记录
实战集成到这里,顺带把我遇到频率最高的一些问题整理成速查表,方便大家对照排查。这些坑很多都是配置和环境层面的,跟模型本身能力关系不大,但一旦撞上,确实很影响使用心情。具体的处理思路我放在下一章单独展开,这里先给你一张总览。
| 现象 | 常见原因 | 处理方式 |
|---|---|---|
| Windows 下安装失败 | 脚本或依赖链问题 | 换官方二进制安装方式,或直接上 WSL2 |
| MCP Server 连接超时 | npx 冷启动拉包太慢、依赖缺失 | 提前全局安装或编译成二进制;检查路径 |
| 模型不调用任何工具 | 当前模型不支持 tool calling,或提示词限制了工具使用 | 换成支持函数调用的模型;检查系统提示词 |
| 中文路径或文件名乱码 | 路径编码处理不完善 | 避免在纯中文目录下运行,项目路径保持 ASCII |
| TUI 渲染出现错乱或闪烁 | 终端模拟器兼容性问题 | 换 Windows Terminal / iTerm2 / tabby 等新式终端 |
| 会话 Token 消耗异常快 | 接了过多 MCP Server,工具定义撑爆上下文 | 按需加载服务面,精简工具数量 |
5. 常见报错与避坑记录
最后一个部分,我想重点聊聊我实际遇到的几个典型案例,不光是给结论,更想让你看看排查思路是什么样子的。毕竟“知其所以然”比“背答案”重要得多。
5.1 那个“free tier can only be used from within opencode”的报错
这个报错我印象很深,因为涉及我踩过的坑。现象是在一个第三方脚本里调用某套模型接口时,持续报错error from provider (console): opencode's free tier can only be used from within opencode,看起来像是在限制使用场景。
我当时的排查思路是沿着凭证链路走:先看配置文件里这个 provider 的 baseURL 和 apiKey 是从哪来的,再看环境变量里有没有覆盖项,最后确认了是在外部客户端引入了不属于它的免费额度凭证。也就是说,这套免费额度被限定在 opencode 自身环境中使用,我在外部脚本里复用,自然就被拦截了。
解决方式是换掉这个限制性凭证,或者调整调用链路让它走合法的通道。这里也给大家提个醒:如果你在别处看到这类免费额度,先确认它的使用边界,别图省事把同一个 key 到处复制。免费额度通常是用来体验和试用门槛的,不是给你当前后端接口的万能钥匙。遇到这种报错,先检查 key 的来源和使用范围,再考虑是不是要换正式的接入方式。
5.2 安装、环境与性能相关的坑
安装这块,macOS 和 Linux 一条 curl 脚本通常就搞定了,我基本没有再遇到过问题。Windows 相对麻烦一点,老版本安装脚本偶尔会卡在依赖下载环节。我这边后来是用官方编译好的二进制包解决的,如果你在 Windows 上安装反复失败,建议优先找二进制发布版本,而不是跟脚本较劲。如果跑下来的 TUI 渲染不对,就检查一下是不是老控制台,尽量用 Windows Terminal 或 WSL2。
性能方面,我遇到过 opencode 在 tabby 里滚动长日志时 CPU 占用明显升高的情况,后来发现是渲染刷新频率的问题。这种问题一般跟终端软件对 Ink 渲染的支持程度有关,换到渲染优化更好的终端就顺畅了。根据我不太精确的经验,TUI 类工具在渲染密集场景下对终端实现的依赖远高于普通命令行工具,所以别在终端兼容性上死磕,换工具往往比改配置更快。
5.3 一点更完整的想法
工具也好,服务面也好,外壳也好,它们单独拿出来看都只是某个层面的能力。只有当它们被串起来——让 Agent 通过服务面够到外部数据,通过工具改写本地代码,在外壳里被人控制和观察——opencode 才真正从“会话式问答工具”变成一个可以嵌入研发流程的生产力组件。
我现在的日常是:VS Code 里写代码,终端里跑长任务,团队仓库里躺着那套 AGENTS.md 和 Skill 文件,新机器上同步一下配置就能获得完整的 Agent 能力。这一整套搭起来之后,最大的感受不是“AI 什么都能干”,而是“人终于可以把精力从琐碎的执行细节里解放出来,专心做判断和决策”。我觉得这才是这类工具真正的价值所在。
如果你也想搭一套自己的环境,我最后的一点建议是:先从一个小项目开始,只接一个 MCP 服务面,写好 AGENTS.md,让 Agent 帮你完成一件真实的小事,跑通了再加复杂度。别一上来就追求全家桶,工具再多,用不上的都是负担。