第 2 课

opencode.jsonc 权限、AGENTS.md 与接入自己的模型

弄清配置合并顺序,写 opencode.jsonc 固定默认模型、让命令先询问并禁止 git push,写 AGENTS.md 让智能体自动补中文 docstring,实测 deny 与 ask 在 opencode run 里的不同结果,再学会 policies、external_directory,以及接入 OpenAI 兼容接口和本地 Ollama。

图文23 分钟

课程目录第 2 / 3 课

学习位置仅保存在当前浏览器,有效期 180 天。

01 / 图文教材

图文教材

本课依据:OpenCode 2 官方文档「Config」https://opencode.ai/v2/docs/config/ 、「Instructions」https://opencode.ai/v2/docs/instructions/ 、「Permissions」https://opencode.ai/v2/docs/permissions/ 、「Providers」https://opencode.ai/v2/docs/providers/ (2026-10-26 核对,@opencode/cli 2.1.4)。

这一课做完你会得到什么

继续用第 1 课的 hello-opencode 仓库。你会给它配三样东西:

  • 项目配置 opencode.jsonc:固定默认模型,执行命令前先问你,禁止 git push。
  • 项目说明 AGENTS.md:写下规矩,智能体每次都会遵守。
  • 接自己的模型:学会接 OpenAI 兼容接口和本地 Ollama。

第 1 步:配置文件放哪里

OpenCode 会按下面的顺序读取配置并合并,后读的覆盖先读的:

~/.config/opencode/opencode.json(c)    全局,对所有项目生效
<项目>/opencode.json(c)                项目根目录
<项目>/.opencode/opencode.json(c)      项目内的 .opencode 目录

系统级配置(如 /etc/opencode/)优先级最高,公司统一管控时会用到。文件推荐用 .jsonc,可以写注释和尾逗号。开头加上 $schema,编辑器就能自动补全字段。

第 2 步:写项目配置

在仓库根目录新建 opencode.jsonc:

{
  "$schema": "https://opencode.ai/config.json",
  "model": "opencode/deepseek-v4.1-flash-free",
  "permissions": [
    { "action": "shell", "resource": "*", "effect": "ask" },
    { "action": "shell", "resource": "git status *", "effect": "allow" },
    { "action": "shell", "resource": "git diff *", "effect": "allow" },
    { "action": "shell", "resource": "uv run *", "effect": "allow" },
    { "action": "shell", "resource": "git push *", "effect": "deny" },
  ],
}

permissions 是一个有序列表,每条规则有三个字段:

字段含义
action动作,如 shell、edit、read、webfetch
resource作用对象,如命令文本、文件路径、网址
effectallow 放行、ask 先问、deny 拒绝

规则要点:

  • 多条规则同时匹配时,最后一条生效。所以先写宽泛规则,再写例外。
  • 以空格加 * 结尾的命令规则,也匹配不带参数的命令。例如 git status * 同时匹配 git status 和 git status --short。
  • 一条规则都没匹配上时,默认是 ask。

有了 model 字段,后面的命令就不用每次写 -m 了。

第 3 步:写 AGENTS.md

AGENTS.md 是写给智能体的项目说明,适合放构建命令、目录约定和验收标准。建议提交进 Git,团队共用:

# 项目说明
- 这是一个 Python 统计小工具,源码在 stats.py,测试在 test_stats.py。
- 改完代码必须运行 `uv run --with pytest pytest -q`,全部通过才算完成。
- 所有函数都要写中文 docstring。
- 回答一律使用简体中文。

AGENTS.md 放在哪个目录,就对哪个目录生效。还有别的规范文件要一起加载时,用配置里的 instructions 数组列出,支持路径、通配符和网址:

{
  "instructions": ["CONTRIBUTING.md", "docs/guidelines/*.md"],
}

第 4 步:验证说明和权限都生效了

先让它干一件正常的活。这次不写 -m:

opencode run "给 stats.py 新增 mode 函数(返回出现次数最多的值),补测试并跑通。"

对照结果(2026-10-26 实测,约 21 秒,节选):

> build · deepseek-v4.1-flash-free
$ uv run --with pytest pytest -q
...........                                                [100%]
11 passed in 0.01s
已全部跑通(11 passed)。
- 同时给 `mean`、`median` 补了中文 docstring,符合项目规范

可以看到三点:

  • 模型来自配置文件。
  • uv run 在允许名单里,所以没有被拦。
  • 它主动给旧函数补了中文 docstring,因为 AGENTS.md 里这么要求。

再故意试一下被禁止和需要确认的命令:

git add -A && git commit -qm "add mode"
opencode run "依次执行 git push origin main 和 ls -la 两条命令,\
并如实报告每条是否被允许执行。"

对照结果(2026-10-26 实测,节选):

| `git push origin main` | ❌ 未执行 | `Permission denied: shell` |
| `ls -la` | ❌ 未执行 | "This non-interactive run cannot ask the user
  for permission" |

两种拦截要分清:

  • git push 命中 deny,任何情况下都执行不了。
  • ls -la 命中 ask。opencode run 没法弹窗问你,所以直接拒绝。在全屏界面里,会弹出「允许一次 / 总是允许 / 拒绝」三个选项。

CI 里想自动放行所有 ask,可以加 --auto。官方说明它只放行「没有被明确 deny 的」请求,deny 照样生效:

opencode run --auto "跑一遍测试并汇报"

第 5 步:几条常用的安全规则

下面三段都出自官方文档,按需合并进 permissions。

不让它读 .env 一类的密钥文件:

{ "action": "read", "resource": "*.env", "effect": "deny" }

V2 默认允许访问项目外的目录,V1 默认会先问。想恢复 V1 的行为,加这条:

{ "action": "external_directory", "resource": "*", "effect": "ask" }

团队想强制禁止某类命令,用 policies。它在所有规则和已保存的授权之后执行,只能把结果改成拒绝,不能放行:

{
  "policies": [
    { "action": "tool.use", "resource": "shell:sudo *", "effect": "deny" }
  ],
}

第 6 步:接入自己的模型

方式一:/connect。 OpenCode 的提供方目录来自 models.dev。目录里已有的提供方,直接在全屏界面里 /connect 选中、填 Key,再 /models 选模型就行。

方式二:自定义 OpenAI 兼容接口。 目录里没有的接口,在配置里加一个提供方。下面是官方示例的结构,acme 和网址只是示例名称,请换成你所用服务的官方地址和模型 ID:

{
  "$schema": "https://opencode.ai/config.json",
  "providers": {
    "acme": {
      "name": "Acme",
      "env": ["ACME_API_KEY"],
      "package": "@opencode/ai/providers/openai-compatible",
      "settings": { "baseURL": "https://llm.acme.example/v1" },
      "models": {
        "qwen3-coder": { "name": "Qwen 3 Coder" },
      },
    },
  },
}

几个字段的意思:

  • env:从哪个环境变量读 Key。Key 不要写进文件。
  • 提供方 ID:providers 下的键名就是 ID,用这个提供方的模型时写成 acme/qwen3-coder。
  • {env:变量名}:别的字段需要引用环境变量时这样写。JSON 里写 $NAME 不会被展开。

方式三:本地 Ollama。 先在本机启动 Ollama 并拉一个模型。OpenCode 会自动探测 http://127.0.0.1:11434,不用连账号,模型直接出现在 /models 里:

ollama serve
ollama pull qwen3:8b

LM Studio 和 vLLM 同样能自动发现,默认地址分别是 http://127.0.0.1:1234/v1 和 http://127.0.0.1:8000/v1。本机模型越小,调用工具越不稳定,写代码建议用中大型模型。

本课小结

  • 配置合并顺序:全局 → 项目,后读的覆盖先读的。$schema 让编辑器能补全。
  • permissions 按顺序匹配,最后一条生效。deny 谁都绕不过,ask 在 run 里等于拒绝。
  • AGENTS.md 写一次,每次会话都生效。
  • 接自己的模型:/connect、自定义 providers 或本地 Ollama,三选一。