1. 为什么要在 GitLab 的 Issue 和合并请求里塞进 OpenCode
很多团队已经把代码托管迁到 GitLab,日常协作几乎都发生在 Issue 评论区和合并请求(Merge Request,简称 MR)的讨论串里。问题也正好出在这里:一个 Issue 描述写得含糊,得有人先去读代码、翻日志、把上下文拼起来;一个 MR 改动涉及五六个文件,审查的人要来回跳转才能看懂意图。这些活儿本身不难,但特别占时间,而且重复度极高。
OpenCode 是一个跑在终端里的 AI 编码助手,它能读你仓库里的文件、执行命令、按提示词改代码,最后把改动整理成提交。把它接到 GitLab 上,本质上是让它在 GitLab Runner 里跑起来,然后通过 Issue 评论或 MR 描述去触发它。触发之后,它读上下文、干活、回帖或者直接开分支提 MR。对团队来说,这相当于在评论区多了一个随时待命的同事。
适合谁用?三类人最划算。第一类是维护开源项目或者内部平台的团队,Issue 量大、重复问题多,想让 AI 先做一轮分诊和解释。第二类是中小研发团队,没有专职的代码审查人力,希望 MR 提交后能自动过一遍基础检查。第三类是已经在用 TaoToken 统一 Key 的团队,因为 OpenCode 需要一个模型提供方的 API 通道,而 TaoToken 的 endpoint 和 Key 可以直接复用,不用再单独申请一套凭证。
这里要区分两种集成路径。一种是走 GitLab CI/CD 组件,把 OpenCode 当成管道里的一个 job 来跑,适合自定义程度要求高的场景,比如你想控制它用哪个配置目录、跑什么命令、输出到哪里。另一种是走 GitLab Duo 的 CLI agent 集成,在评论里 @ 一下触发词,OpenCode 就在后台的管道里执行,适合想要“评论区喊一声就干活”的轻量用法。两条路最后都是跑在 GitLab 自己的 Runner 上,权限边界清晰,代码不出自己的基础设施。
我试过把这两种方式都搭了一遍,踩的坑主要集中在认证配置和触发词识别上。下面按可复制的步骤来写,重点放在 TaoToken 的 endpoint 怎么填、auth.json 怎么写、以及怎么验证请求确实走了统一通道。
2. TaoToken 前置准备:endpoint、Key 与 auth.json 的对应关系
在把 OpenCode 塞进 GitLab 之前,得先把模型通道准备好。OpenCode 本身不绑定某一家模型,它通过配置文件读取 API 地址和密钥。TaoToken 提供的是统一的 API 通道,你拿到一个 Base URL 和一个 Key,就能在 OpenCode 里指向它。
先明确三个东西的对应关系,这是后面所有配置的基础:
| 配置项 | 在 TaoToken 里的位置 | 在 OpenCode 里的字段 |
|---|---|---|
| Base URL | API 地址,形如 https://taotoken.net/api | provider 的 baseURL |
| API Key | 控制台生成的密钥 | auth.json 里的 apiKey |
| Model ID | 模型列表里的标识 | 配置里的 model 字段 |
Base URL 用https://taotoken.net/api,注意不要在后面多加斜杠或者拼错路径。Key 在控制台的 API Keys 页面生成,生成后只显示一次,复制下来存好。Model ID 根据你实际要用的模型填,比如做代码解释和审查,选一个上下文窗口够大的就行。
OpenCode 读取认证信息的方式是读一个 auth.json 文件。这个文件的结构大致是这样,你可以直接复制改:
{ "taotoken": { "type": "api", "apiKey": "sk-你的TaoToken密钥", "baseURL": "https://taotoken.net/api" } }注意type字段写api,apiKey填你生成的 Key,baseURL就是上面那个地址。这个文件在本地跑的时候放在 OpenCode 的配置目录里,在 GitLab CI 里则要转成环境变量,后面会讲怎么处理。
如果你用的是 Coding Plan 这类长期编码场景,Key 的权限和额度策略可能不一样,建议在控制台里确认一下这个 Key 能访问哪些模型。生成 Key 的入口在 API Keys 页面,接入文档里有更细的字段说明,遇到字段对不上的时候去翻一下文档比猜要快。
还有一个容易忽略的点:OpenCode 的 provider 名字要和 auth.json 里的顶层 key 对应上。上面我写的是taotoken,那在 OpenCode 的配置文件里引用 provider 时也要写taotoken。名字本身可以自定义,但两处必须一致,否则会出现找不到凭证的报错。
准备好这三样之后,本地可以先跑一次验证,确认 Key 和地址是通的,再去动 GitLab 的配置。本地验证的命令很简单,装好 OpenCode 后直接跑一个最小请求,看它能不能返回内容。这一步过了,后面 CI 里的问题基本就只剩环境变量和触发逻辑了。
3. 可复制配置:.gitlab-ci.yml 与 auth.json 的完整片段
这一节给两份可以直接抄的配置。第一份是走 CI 组件的方式,第二份是走 GitLab Duo 触发的方式。两份都围绕同一个 auth.json 结构,区别在于触发入口和变量传递方式。
先说 CI 组件方式。社区里有一个现成的组件nagyv/gitlab-opencode,它会在管道里自动把 OpenCode 环境搭好,你只需要提供认证 JSON 和提示词。第一步是把 auth.json 的内容存成 GitLab CI 变量。路径是:项目设置 → CI/CD → 变量(Variables),新建一个变量,类型选 “File”,勾上 “Masked and hidden”。变量名比如叫OPENCODE_AUTH_JSON,值就是上面那段 JSON 的完整内容。
然后在项目根目录的.gitlab-ci.yml里加上这段:
include: - component: $CI_SERVER_FQDN/nagyv/gitlab-opencode/opencode@2 inputs: config_dir: ${CI_PROJECT_DIR}/opencode-config auth_json: $OPENCODE_AUTH_JSON command: optional-custom-command message: "请解释这个 Issue 的核心问题,并给出可能的修复方向"这里几个 input 的含义要清楚。config_dir指向你仓库里存放 OpenCode 配置的目录,不同 job 可以用不同目录来启用或禁用不同功能。auth_json填的是存放认证 JSON 的那个变量名,注意这里写的是变量名本身,不是 JSON 内容。command是可选的自定义命令,message就是给 AI 的提示词。
如果你想让不同任务用不同配置,可以在仓库里建多个目录,比如opencode-config/triage和opencode-config/review,然后在不同的 job 里分别指向它们。这样分诊用的提示词和审查用的提示词就不会互相干扰。
再说 GitLab Duo 触发方式。这种方式下,OpenCode 跑在 CI/CD 管道里,你在 Issue 或 MR 评论里 @ 触发词,它就会执行。配置步骤大致是:先把 CI/CD 跑通,拿到模型 API 密钥(这里就是 TaoToken 的 Key),创建一个服务账号,配置好 CI/CD 变量,最后写一个流程配置文件。
流程配置文件是这种方式的核心,它决定了触发词是什么、触发后执行什么动作。一个简化的配置结构如下:
name: opencode-agent trigger: "@opencode" actions: explain: prompt: "阅读当前 Issue 的全部内容,用简洁的语言解释问题所在" fix: prompt: "分析问题并修复,创建新分支,提交合并请求" review: prompt: "审查当前合并请求的改动,指出潜在问题和改进点"触发词不一定是@opencode,你可以改成团队习惯的词。三个动作分别对应解释 Issue、修复 Issue、审查 MR。实际配置里还要指定用哪个 provider 和 model,这部分和 auth.json 里的 provider 名字对应。
无论走哪条路,auth.json 的结构都是一样的,Base URL 都是https://taotoken.net/api。区别只是 CI 组件方式把 JSON 存成 File 类型变量,Duo 方式可能通过服务账号的凭证注入。两种方式都建议把 Key 设为 Masked,避免在日志里泄露。
4. 验证请求:在 Issue 评论和 MR 描述里触发并确认返回
配置写完之后,最关键的一步是验证请求真的发出去了,而且走的是 TaoToken 的统一通道。这一步不能只看“有没有回复”,还要确认回复内容符合预期、没有报认证错误。
先验证 Issue 评论触发。打开一个测试用的 Issue,在评论区写:
@opencode explain this issue如果触发词配置的是@opencode,管道会被拉起,OpenCode 在 Runner 里读这个 Issue 的内容,然后回一条评论解释问题。你看到回复之后,去管道的 job 日志里翻一下,确认请求的 endpoint 是https://taotoken.net/api,而不是别的地址。日志里通常会打印 provider 和 baseURL,这是最直接的证据。
再验证 MR 描述触发。新建一个合并请求,在描述里写:
@opencode review this merge requestOpenCode 会读取这个 MR 的 diff,然后给出审查意见。审查意见一般会以评论形式出现,指出改动里可能的问题。同样去日志里确认请求地址。
修复类动作的验证稍微复杂一点,因为涉及创建分支和提交 MR。在 Issue 里写:
@opencode fix this它会切一个新分支,改代码,然后提一个 MR 出来。验证的时候重点看两件事:一是新分支和 MR 确实被创建了,二是 MR 里的改动和 Issue 描述的问题对得上。如果 MR 创建了但改动是空的,多半是提示词不够具体,或者 OpenCode 没读到相关文件。
验证成功的标志有三个:评论或 MR 里有 AI 生成的回复内容;管道 job 状态是 passed;日志里的请求地址是 TaoToken 的 endpoint。三个都满足,说明统一通道是通的。
如果回复内容出现了但明显答非所问,先别急着改配置,去看日志里实际发给模型的提示词是什么。有时候是触发词后面的文本没被正确捕获,导致提示词是空的,模型只能瞎猜。
5. 常见报错排查:401、local proxy failed 与 reading choices
配置过程中最容易撞上的几类报错,这里逐个拆开说。
第一类是 401 认证失败。日志里出现401 Unauthorized或者invalid api key,基本就是 auth.json 里的 Key 不对,或者环境变量没传进去。排查顺序:先确认 GitLab CI 变量里OPENCODE_AUTH_JSON的值是完整的 JSON,不是只有 Key 字符串;再确认变量类型选的是 File,不是 Variable;最后确认 auth.json 里的apiKey字段名没写错。如果 Key 是从控制台复制的,注意有没有多复制了空格或者换行。
第二类是local proxy failed或者连接超时。这类报错通常指向 Base URL 写错,或者 Runner 的网络策略不允许访问外部地址。先检查 auth.json 里的baseURL是不是https://taotoken.net/api,有没有多写路径或者少写协议头。如果地址没问题,去看 Runner 的网络配置,确认它能出网。有些自建 Runner 默认只允许访问内网,需要单独放行。
第三类是reading choices相关的报错,比如error reading choices: unexpected end of JSON input。这通常意味着模型返回的内容不是预期的 JSON 结构,可能是请求被中途截断,或者 provider 配置和实际返回格式不匹配。排查时先确认 model 字段填的是 TaoToken 支持的模型 ID,再确认 provider 类型写的是api。如果模型 ID 写错,有些通道会返回一个非标准响应,解析时就报这个错。
第四类是触发词没反应。评论发出去了,但管道没被拉起。先确认触发词和流程配置文件里写的一致,大小写敏感。再确认服务账号有权限触发管道。如果是 Duo 方式,还要确认 CLI agent 功能在项目里是开启状态。
第五类是 MR 创建了但内容是空的。这多半是提示词太模糊,OpenCode 不知道要改哪个文件。把提示词写具体一点,比如指明文件路径或者函数名,命中率会高很多。
排查的时候有一个通用技巧:把 CI job 的日志级别调高,让 OpenCode 打印出完整的请求和响应。这样能直接看到发出去的 endpoint、model 和提示词,比猜要快得多。
6. 把统一 Key 用顺之后的日常用法与 CTA
配置跑通之后,日常用法其实很轻。Issue 分诊的时候,让 OpenCode 先读一遍,把问题归类、指出可能的原因,人工再接手就快很多。MR 审查的时候,让它先过一遍基础检查,比如有没有明显的逻辑漏洞、有没有漏掉边界条件,人工审查聚焦在业务逻辑上。小 Bug 修复可以直接让它开分支提 MR,人工只需要 review 那个 MR 就行。
几个实用技巧。触发词可以按团队习惯改,不用死守@opencode,改成@ai或者@helper都行,只要流程配置文件里同步改。提示词尽量具体,带上文件路径或者函数名,比泛泛地说“修一下”有效得多。不同任务用不同的 config_dir,把分诊、审查、修复的提示词分开管理,避免互相污染。Key 的额度要留意,审查大 MR 的时候上下文消耗会比较大,可以在控制台里看用量。
如果你还没配好 Key,去 API Keys 页面生成一个,接入文档里有字段说明和示例。想先试试模型对话的效果,可以直接在模型对话里发一条请求,确认通道是通的。长期做编码和 Agent 场景的话,Coding Plan 的额度策略更适合高频调用。
整套流程跑下来,最花时间的其实是第一次把 auth.json 和环境变量对齐。对齐之后,后面加新的触发动作就是改改流程配置文件的事。