最近这段时间,我基本把日常的编码辅助从各种图形化 IDE 插件迁回到了终端里,主力工具是 OpenCode,一个大模型驱动的开源编程智能体。它的特别之处在于模型层完全开放,你可以把后端接到任何支持工具调用的模型上。折腾了一圈之后,我把模型固定在了 GLM 系列——不是因为它最贵,而是它在长上下文的代码理解和多文件修改这类实际场景里,表现足够稳,而且成本可控。
这篇东西主要记录我怎么在 OpenCode 里接入 GLM、踩了哪些坑、最终稳定的配置长什么样。适合三类人看:一是想从默认模型切到 GLM 但不知道配置文件怎么写的;二是想低成本跑 agent 但受够了按次计费的人;三是想在自己机器上部署开源权重、把代码数据留在本地的开发者。我尽量把每一步都讲清楚,包括配置字段的含义和报错排查链路,照着抄基本能跑通。
1. 为什么把模型换成 GLM:一次终端 Agent 的供电改造
1.1 OpenCode 到底是个什么样的工具
OpenCode 是一个跑在终端里的 AI 编程工具,跟那种聊天框里生成一段代码然后你自己粘贴的不一样。它更像你请了一个会用命令行、会读项目、会自己改文件的实习生:你给它一个任务,它会自己打开代码文件、定位相关函数、修改多处代码、执行测试命令,然后把结果汇报给你。整个过程发生在你的终端里,所以它天然适合 Git 工作流、SSH 远程开发、以及所有你平时用命令行能完成的操作。
这个工具的特别之处在于,它的“大脑”不是写死的。OpenCode 本身只负责调度:决定下一步该读哪个文件、该执行哪条命令、该问用户什么问题。真正做判断的是背后的大模型。这就意味着你可以把 Anthropic 的模型换掉,可以接 OpenAI 兼容的任意端点,也可以接本地 Ollama。我在实际使用中最大的感受是,模型的选择直接决定了这个 agent 的上限和下限,工具本身反而很稳定。
1.2 GLM 在编程场景里真正能打的地方
GLM 系列模型在纯聊天场景的口碑可能没那么炸裂,但在 agent 编程场景里,有几个点恰恰是刚需。
第一是工具调用(function calling)的稳定性。OpenCode 这种 agent 工具几乎每一步都在做工具调用:打开文件、读取目录、编辑文件、执行命令,这些全靠模型输出的结构化 tool call 来驱动。如果模型在这个环节偶尔抽风,哪怕正确率只有 99%,在长任务里也会出现灾难性的卡顿和误操作。我实测下来 GLM 系列在这块的稳定性是够用的,尤其是 GLM-4.6 这一档,工具调用的格式遵循度很高,很少出现“模型回答了一段话但没有输出任何工具调用”的尴尬情况。
第二是长上下文的代码理解能力。OpenCode 会把整个项目的代码结构、文件内容、Git 状态、终端输出全部塞进上下文。一个中型项目跑几轮之后,上下文轻松超过几万 token。GLM 的长上下文窗口足够大,而且在长上下文状态下对代码片段的定位和理解能力没有明显衰减,这一点直接决定了多文件重构能不能顺利进行。
第三是成本的灵活性。GLM 有免费档、有轻量档、有高性能档,你可以根据任务类型切换模型。相同预算下,GLM 在 agent 这种高频请求场景里比很多国际大厂的 API 耐用得多。
1.3 什么人适合这套组合
我自己总结下来,适合 OpenCode + GLM 组合的人大概有三类:第一类是开发者个人,不想绑定某一个模型供应商,希望在同一个工具里自由切模型的人;第二类是有一定本地部署条件、希望代码不要外发、在内部环境里跑 agent 的团队;第三类是预算敏感、需要一个能用又不会月底账单爆炸的 agent 方案的人。如果你只是想体验一下 AI 编程助手,其实随便一个在线工具就够,未必需要 OpenCode 这个组合。但如果你希望一个智能体真正参与代码库的日常维护,那模型的可控性和成本就是绕不开的话题。
2. 安装 OpenCode 与准备 GLM 凭据:先跑通再折腾
2.1 安装环节最容易卡住的三个点
OpenCode 的安装本身不复杂,大多数情况一条命令就完事,但我实际遇到不少朋友卡在三个细节上。
第一个是 Node.js 版本。OpenCode 对运行时版本有要求,建议 Node 20 或更高版本。我在一台老机器上装过,当时 Node 还是 18.x,装完启动就直接崩,报错信息还不太直观。所以先跑node -v确认版本,不够就先升级,别急着装 OpenCode。
第二个是包名。OpenCode 的 npm 包名是opencode-ai,不是opencode,也不是@opencode/cli。第一次装的时候如果拼错了会安装一个完全不相关甚至同名冲突的包,装完发现命令不存在,特别浪费时间。正确的全局安装命令是:
npm install -g opencode-ai装完之后在终端里输入opencode就能启动。
第三个是首次启动的模型选择界面。OpenCode 第一次启动会让你选一个默认模型,这时候 GLM 还没配置,你随便选一个能用的先用着,或者直接选一个最小的临时模型,后面我们通过改配置文件把 GLM 加进去,不用在意这个初始选择。有个朋友在这里纠结了半天,以为选错了就要重装,其实完全不用。
2.2 申请 GLM API Key 时值得注意的权限细节
GLM 的 API Key 在官方开放平台的控制台里申请,一般是在“API Key”或“密钥管理”这个栏目下创建。这个过程本身不难,但有几个细节会影响后面的使用。
一是注意免费模型的速率限制。GLM 系列里有免费的模型档位,日常聊天随便用没问题,但 agent 场景是一个任务几十次请求,频率很容易撞上限。我一开始用免费档跑一个中等规模的重构任务,跑到一半开始报限流错误。所以如果你计划用 OpenCode 干正经活儿,建议至少开一个付费档位,或者接受免费档只适用于轻量实验。
二是确认你的账号能访问哪些模型。不同渠道开通的模型权限不完全一样,平台控制台的模型列表里能看到你能用哪些 ID。后面配置 OpenCode 的时候,model字段填的 ID 必须以这个列表为准,不是网上搜到一个模型名就一定能用。
三是 API Key 的管理习惯。不要把 Key 直接硬编码在配置文件里,更不要提交到 Git 仓库。我建议用环境变量管理,在 shell 配置里加一行:
export GLM_API_KEY="你的key"然后在 OpenCode 配置文件里通过env:前缀引用,这样既安全,换 key 也不用改配置。
3. 我的 OpenCode + GLM 实测配置:config.json 逐行拆解
3.1 配置文件到底放哪里
OpenCode 的配置分成全局和项目两种。全局配置影响所有项目,通常放在~/.config/opencode/config.json(macOS 和 Linux 路径),Windows 用户一般会在%APPDATA%\opencode\config.json这个位置。项目级配置放在项目根目录的opencode.json,它会和全局配置合并,适合团队或特定项目单独定制模型。
不同版本的 OpenCode 在配置文件的解析上可能略有差异,最靠谱的做法是启动 OpenCode 之后在交互界面里查看当前版本的配置路径提示。我第一次找配置文件的时候,凭经验去找~/.opencode,结果找了半天没有,后来才意识到是~/.config/opencode这个路径。这里也提醒一下,不同版本之间配置结构可能有调整,下面的配置以我当前使用的版本为准,如果你用的版本解析报错,优先查官方文档里的 schema。
3.2 一个能直接跑的 provider 配置
下面这段配置是我目前正在用的,接入的是 GLM 官方开放平台的 OpenAI 兼容接口,配置里没有任何多余字段,可以直接复制使用:
{ "$schema": "https://opencode.ai/config.json", "provider": { "bigmodel": { "type": "openai", "name": "GLM", "baseURL": "https://open.bigmodel.cn/api/paas/v4", "apiKey": "env:GLM_API_KEY", "models": { "glm-4.6": { "name": "GLM 4.6", "limit": { "context": 128000 } }, "glm-4-flash": { "name": "GLM 4 Flash", "limit": { "context": 128000 } } } } } }逐行解释一下关键字段。provider下面的大括号里的bigmodel是 provider 的名字,你可以随便起,它只是 OpenCode 内部用来标识模型来源的标签。type必须填openai,因为我们要走的是 OpenAI 兼容协议,GLM 官方接口、以及后面讲的本地推理服务,都兼容这个协议。baseURL是请求的根地址,特别注意不要手动拼上/chat/completions,OpenCode 会自动拼接,你只需要写到/v4这一层。apiKey用env:GLM_API_KEY的方式引用环境变量,这样 key 不会出现在配置文件里。
models字段下面声明的每一个键,就是这个模型在 OpenCode 里实际会用到的模型 ID。limit.context是告诉 OpenCode 这个模型的上下文窗口有多大,方便它决定什么时候压缩或截断历史记录。这个字段如果填错了会出现“上下文明明还有很大空间但工具提前开始丢信息”或者反过来“当 OpenCode 以为还能继续塞结果把请求打出 400”的情况,所以尽量按官方标称值填。
3.3 模型名与请求体的隐性换算
这里有一个容易懵的点:你在models里写的键名,会原封不动地作为model字段放进请求体里发给 GLM 接口。也就是说,如果你填的是glm-4.6,请求体里的model就是glm-4.6;如果你错误地填了显示名比如“GLM 4.6”或者“GLM-4.6(中文括号)”,请求就会直接 404。
所以我的建议是:先在 GLM 平台的模型列表里把准确的模型 ID 复制出来,再粘贴到配置里。宁可多花十秒钟核对,也不要等 OpenCode 报错之后再回头猜。
另外,OpenCode 在请求时可能会附带一些额外的参数,比如temperature、max_tokens,以及不同 agent 行为控制相关的字段。GLM 的兼容层对未知参数的处理是“能解析就解析,不认识的直接忽略”,所以一般来说不会有问题,但如果你在配置里看到某个参数是给别的模型专用的、而 GLM 不支持,最稳妥的做法是直接删掉。
4. 两种接入链路怎么选:远程 API 与本地推理服务
4.1 远程 API:五分钟上手的轻量方案
远程 API 是我最先使用的方案,也就是上一节那段配置直接生效。它的优点很直接:不需要显卡、不用管推理服务是不是在跑、模型版本由平台方维护、容量大,跑复杂的代码生成任务也不用担心本地显存爆掉。配置完之后,在 OpenCode 里新开一个会话,命令后跟上你的任务,就能看到它自己开始操作文件了。
这个方案也有代价。请求要发到外部服务,代码内容相关的敏感信息会经过别人的服务器,对数据安全有要求的团队需要多掂量。另外,API 调用有并发和频率限制,agent 任务大量并行时容易触发限流。我的个人建议是,远程 API 适合个人开发者和中小团队,尤其是你还在验证“OpenCode 这个工具到底好不好用”的阶段,先用远程 API 跑通再谈其他,成本最低。
4.2 本地部署:把 GLM 权重拉到自己的机器上跑
如果你的场景要求代码绝对不离开本机,或者你的请求量大到远程 API 的费用吃不消,那就需要考虑本地部署。GLM 系列有开源权重,可以用 Ollama、vLLM 这类推理框架跑起来,然后让 OpenCode 把它当作一个本地 OpenAI 兼容服务来用。
用 Ollama 的话,先拉取你需要的权重,以模型库当前实际可用的名为准:
ollama pull glm4拉取完成之后,确认服务在本地监听,然后修改 OpenCode 配置,把baseURL指到本地推理服务:
{ "provider": { "localglm": { "type": "openai", "name": "Local GLM", "baseURL": "http://localhost:11434/v1", "apiKey": "not-needed", "models": { "glm4": { "name": "GLM 4 Local" } } } } }这里apiKey随便填一个非空字符串就行,本地服务基本不校验。用 vLLM 起服务也是一样的思路,只要它对外暴露的是 OpenAI 兼容接口,OpenCode 这边的配置逻辑完全一样。
不过本地部署要有一个清醒的预期:能跑不代表跑得好。几个 B 的轻量模型在简单代码解释、单文件修改上还能应付,但到了多文件重构、跨模块排查这种复杂任务,能力跟远程顶级模型有明显差距。跑 32B 级别的模型需要比较大的显存,通常还得用量化版本,速度也会打折扣。我把本地模型用在两类场景上:一类是隐私敏感、绝对不能外发的任务,另一类是高频简单的请求,比如格式化、写单测、改注释,本地模型完全够用,还能把远程账单压得很低。
4.3 我的建议组合
折腾了一段时间之后,我现在的用法是“双轨制”:远程 API 放主力模型,负责复杂的架构调整、多文件重构和代码审查;本地推理服务放轻量模型,负责批量小任务和隐私敏感的操作。在同一条交付链路里,OpenCode 是允许你在对话中切换模型的,所以我会根据任务性质临时指定用哪个模型跑,而不是让每个任务都吃满最大的模型。这套组合的好处是,日常任务的单价被压得很低,而真正需要强模型的关键步骤,也都是用最强的那一档去跑。
5. 实测遇过的坑与排查链路:模型能跑不等于跑得好
5.1 404 / model not found:模型 ID 没对上
这个是我遇到概率最高的报错。现象是 OpenCode 一启动、一发消息就报类似model not found或404的错误,而且你会发现在 OpenCode 界面里甚至看不到你想要的模型名。
排查链路很有代表性。第一步,用 curl 直接打一遍 GLM 的兼容接口,看返回结果是什么。不要跳进配置里瞎猜,先把模型 ID 和请求链路验证了再说:
curl https://open.bigmodel.cn/api/paas/v4/chat/completions \ -H "Authorization: Bearer $GLM_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "glm-4.6", "messages": [{"role": "user", "content": "hi"}] }'如果 curl 返回正常,说明接口和 key 都没问题,问题大概率出在 OpenCode 配置里models的键名和平台实际的模型 ID 不一致。我犯过的错是把平台显示名里的点和横线看混了,以及在后面多打了一个空格,这个空格在 JSON 里是严格区分的,当然不行。如果 curl 本身就返回模型不存在的错误,那就直接去平台控制台把正确的模型 ID 复制出来,再回去改配置。
5.2 工具调用不稳定:OpenCode 要的工具 GLM 没给
第二类高频问题是工具调用失败。现象是 OpenCode 看起来在正常工作,模型也回了话,但它始终不执行下一步操作,或者一直卡在一个“等待模型返回工具调用”的状态。如果打开日志,你会发现模型返回的内容里根本没有结构化的工具调用。
这个问题的原因一般有三个。第一个是baseURL拼接错误,如果你配置的地址末尾多加了/chat/completions,OpenCode 会自动再拼一个,最终请求就打到不存在的路径上去了,表现就是各种奇奇怪怪的失败。第二个是模型本身不支持工具调用,这在本地部署的某些小模型上也出现过。第三个是上下文过长导致模型在生成工具调用时被截断,工具调用字段被切掉了一半。
排查的时候先看请求日志里有没有tools字段发给 GLM,再确认返回的finish_reason是不是tool_calls或者stop。如果 GLM 确实支持工具调用但 OpenCode 没有传tools,那大概率是配置解析出了问题;如果传了但模型没有正确返回,那就优先检查是不是上下文爆了。
5.3 回答到一半断掉:超时与流式问题
第三个让人烦躁的问题是长任务跑到一半突然报错中断。OpenCode 在执行一次大型重构时,会发起很多次连续的模型请求,每一条请求的上下文都很长,模型生成一轮回复的时间自然也会变长。
很多默认配置的超时时间是按普通聊天场景设计的,对 agent 这种“每次请求要思考很久”的工作模式来说偏短。解决思路是调大超时阈值,同时确认你是不是在某个环节手动关闭了流式输出。OpenCode 这么大的模型请求基本都是靠流式输出保持连接的,如果你在配置里硬把流式关掉,长请求容易直接超时断开。这里注意,流式参数交给 OpenCode 自己管理就好,不需要手动干预。
5.4 上下文一长就丢信息
这是一个比较隐蔽的坑。现象是:会话刚开始的时候一切正常,跑了二三十轮之后,模型开始答非所问,明明刚才已经改过某个文件,它却说没看见,甚至自己重新生成了一遍完全不同的实现。
这事儿的根因多半出现在limit.context配置不准确。如果你在models里没有声明这个值,OpenCode 会按一个默认值来估算,可能比模型实际支持的窗口小,也可能比实际的大。前者会让 OpenCode 过早地压缩或裁剪上下文,后者会让它不断往里塞东西,最终撑爆模型窗口。填的时候建议按官方标称值来,同时给一点余量,不要把 128k 填成 131072 这类边缘数字。遇到会话已经明显变“笨”的情况,优先考虑开一个新会话,或者手动触发上下文压缩/清理,而不是硬着头皮继续聊。
5.5 鉴权失败:401、403 的快速自查
鉴权失败算是最直白的报错,但原因也有好几层。401 一般是 API Key 没有被 OpenCode 读到,先确认全局配置里引用环境变量的语法是不是写对了,然后单独在终端里echo $GLM_API_KEY看看变量存不存在,如果 shell 里没有,OpenCode 进程自然更读不到。403 则是说你没有这个模型的访问权限,通常是模型 ID 本身没问题,但账号权限没开通,回到平台控制台确认一下。
我把这几个典型报错整理成了一张自查表,方便你快速定位:
| 报错现象 | 可能原因 | 优先排查动作 |
|---|---|---|
| 404 / model not found | 模型 ID 拼写或大小写错误 | 用 curl 直接验证接口,复制平台上的准确 ID |
| 请求一直转圈、无工具调用 | baseURL 拼接错误 / 模型不支持 tools / 上下文被截断 | 看请求日志中的 tools 字段,检查 finish_reason |
| 长任务中途断连 | 超时时间过短 / 流式被关闭 | 调大超时阈值,确认流式参数由 OpenCode 控制 |
| 越聊越笨、丢失已改内容 | context 配置不准确 | 修正 models.limit.context,必要时开新会话 |
| 401 / 403 | Key 未生效 / 账号无权限 | echo 检查环境变量,平台控制台确认模型权限 |
这张表基本覆盖了我 90% 的日常排错需求。
6. 让 GLM 在 OpenCode 里跑得更顺手:几个生效的小配置
6.1 给不同 GLM 版本分配不同任务
GLM 系列有多个档位,把它们全部放进同一个配置文件里是值得的,这样你可以在任务过程中随时切换。下面是我目前的分配方式,供参考:
| 模型 ID | 适合场景 | 注意事项 |
|---|---|---|
| GLM-4-Flash | 快速解释代码、写注释、起单测框架 | 免费档限流频繁,不适合大批量任务 |
| GLM-4.5-Air 这类轻量档 | 单文件修改、常规 bug 定位 | 速度快、成本低,能力够用但别指望处理复杂重构 |
| 能力更强的 4.6 等档位 | 多文件重构、架构设计、代码审查 | 上下文长、质量高,建议留给真正复杂的任务 |
在 OpenCode 里切换模型很简单,对话中指定用哪个模型即可,不需要每个任务都重开。我的使用习惯是:默认用轻量档跑所有人话,遇到具体复杂步骤时明确切换到强档,这样账单和体验能平衡得很好。
6.2 显式控制请求参数与并发
OpenCode 的配置里可以控制一些请求行为参数,比如温度、超时、并发数等。agent 编程这种场景,温度我建议调低,避免模型在代码生成时“发挥”出一些莫名其妙的变体。并发方面,如果你用的是远程 API,太高并发很容易触发限流,适当降低并发数反而更稳定。
这些参数并不是越多越好、越大越好。我见过有人把所有能加的参数全加上,结果 OpenCode 反而表现变得奇怪。我的原则是:保持最小有效配置,只有遇到具体问题才去调整对应的参数。很多默认值其实已经过调优,你只需要关注模型 ID、上下文窗口、超时、并发这几项就够了。
6.3 后续可以继续扩展的方向
把 GLM 接入 OpenCode 只能算是万里长征第一步。跑稳之后,你还可以做很多扩展:第一个是配置多个 provider,把不同模型来源都放进同一个 OpenCode 里,随时对比效果;第二个是给 OpenCode 配自定义提示词,让它以你团队的习惯去写代码、提交 PR;第三个是接 MCP 工具,让 GLM 通过 OpenCode 去访问外部系统,比如内网文档、数据库、构建平台,把这些服务变成模型可以调用的“工具”,这个扩展空间比单纯换模型要大得多。
我现在最常用的动作,其实是在 OpenCode 里维护一个“模型路由”的思维:简单任务走轻量本地模型,复杂任务走远程强模型,敏感任务走本地全流程。这套体系不是一个配置文件就能固定下来的,而是在使用过程中不断根据任务类型、成本、响应速度去微调。你会发现,当模型选择自由之后,agent 工具才真正变成了自己的生产资料,而不只是另一个厂商送你的聊天窗口。
最后分享一个我在这么多天操作里觉得最值回票价的习惯:每次在 OpenCode 里接入一个新模型前,永远先用 curl 把接口、鉴权、模型 ID 三件事验证一遍,再动配置文件。这样,几乎所有配置错误都能在三十秒内暴露出来,而不是让 OpenCode 帮你兜底排错。模型能跑起来只是起点,真正好用的组合一定是跑过实际项目、踩过具体坑之后沉淀出来的。GLM 接进 OpenCode 只是第一步,后面的平滑切换、成本权衡、任务分流,才是一个 agent 工作流真正值钱的部分。