znlgis 博客

GIS开发与技术分享 — GDAL · GeoServer · PostGIS · QGIS · OpenLayers · Cesium · FreeCAD · NPOI

第七章:自定义命令、规则与上下文

本章讲解三类「让 OpenCode 更懂你的项目、更少重复劳动」的定制:自定义命令(Commands)规则文件(AGENTS.md / instructions)、以及 Agent Skills。它们都是纯文本、可提交进 Git、可团队共享,并且对省 Token 大有帮助——因为高质量的上下文能减少来回澄清与返工。


7.1 自定义命令(Commands)

自定义命令把「常用提示词」固化为 /命令名,在 TUI 里一键触发。它们与内置命令并列,同名时覆盖内置命令

用 Markdown 定义(推荐)

放在 .opencode/commands/(项目)或 ~/.config/opencode/commands/(全局),文件名即命令名:

```markdown title=”.opencode/commands/test.md”

description: 运行测试并生成覆盖率报告 agent: build model: anthropic/claude-haiku-4-5 —

运行完整测试套件并生成覆盖率报告,列出所有失败项。 聚焦失败的测试并给出修复建议。


之后在 TUI 输入 `/test` 即可。frontmatter 是配置,正文是发给 LLM 的模板。

### 用 JSON 定义

```jsonc title="opencode.jsonc"
{
  "$schema": "https://opencode.ai/config.json",
  "command": {
    "test": {
      "template": "运行完整测试套件并生成覆盖率报告,列出所有失败项。\n聚焦失败的测试并给出修复建议。",
      "description": "运行测试并生成覆盖率报告",
      "agent": "build",
      "model": "anthropic/claude-haiku-4-5"
    },
    "component": {
      "template": "创建一个名为 $ARGUMENTS 的 React 组件,支持 TypeScript,包含正确的类型与基础结构。",
      "description": "创建新组件"
    }
  }
}

命令模板的特殊语法

1)参数占位符

  • $ARGUMENTS:替换为命令后的全部参数。
  • $1 $2 $3 …:按位置取参。

```markdown title=”.opencode/commands/create-file.md”

description: 创建带内容的新文件 —

在目录 $2 下创建名为 $1 的文件,内容如下:$3


调用:`/create-file config.json src "{ \"key\": \"value\" }"`。

**2)注入 Bash 输出**

用 反引号包裹命令并在前面加 `!`(即 `!` + 反引号命令反引号)把命令输出注入提示。命令在项目根目录执行:

```markdown title=".opencode/commands/review-changes.md"
---
description: 审查最近的改动
---

最近的 git 提交:
!`git log --oneline -10`

请审查这些改动并给出改进建议。

3)引用文件内容

@ 加文件名,把文件内容自动并入提示:

```markdown title=”.opencode/commands/review-component.md”

description: 审查组件 —

审查 @src/components/Button.tsx 这个组件,检查性能问题并给出改进建议。


### 命令配置项

| 字段 | 必填 | 说明 |
|------|------|------|
| `template` | 是 | 发给 LLM 的提示模板 |
| `description` | 否 | TUI 中显示的描述 |
| `agent` | 否 | 指定执行该命令的 Agent;若是子代理则默认以子任务方式触发 |
| `subtask` | 否 | 设 `true` 强制以子代理(子任务)方式运行,**不污染主上下文** |
| `model` | 否 | 覆盖该命令使用的模型 |

> `subtask: true` + 便宜的 `model` 是命令级省 Token 的黄金组合:把「跑测试并分析」「审查改动」这类重读取、重输出的任务丢进子会话用小模型完成,主会话只拿结论。

---

## 7.2 规则文件 `AGENTS.md`

`AGENTS.md` 类似 Cursor 的 rules,是注入到 LLM 上下文、用于定制其在你项目中行为的指令文件。

### 初始化

在 TUI 运行 `/init`:它扫描仓库关键文件,必要时问几个问题,然后创建/更新 `AGENTS.md`,聚焦未来会话最常需要的信息:

- 构建、lint、测试命令;命令顺序与关键验证步骤;
- 仅看文件名看不出的架构与目录结构;
- 项目专属约定、环境怪癖、操作「坑」;
- 对既有规则源(Cursor / Copilot rules)的引用。

若已有 `AGENTS.md`,`/init` 会就地改进而非粗暴替换。**建议把它提交进 Git 与团队共享。**

### 示例

```markdown title="AGENTS.md"
# SST v3 Monorepo 项目

这是一个使用 TypeScript 的 SST v3 monorepo,用 bun workspaces 管理包。

## 项目结构
- `packages/` - 所有 workspace 包(functions、core、web 等)
- `infra/` - 基础设施定义,按服务拆分(storage.ts、api.ts、web.ts)
- `sst.config.ts` - SST 主配置,使用动态导入

## 代码规范
- TypeScript 开启 strict 模式
- 共享代码放 `packages/core/`,配置正确的导出
- 函数放 `packages/functions/`

## Monorepo 约定
- 用 workspace 名导入共享模块:`@my-app/core/example`

多位置与优先级

AGENTS.md 可来自多个位置,用途不同:

  • 项目级:项目根 AGENTS.md,只在该目录及子目录生效,随项目共享。
  • 全局级~/.config/opencode/AGENTS.md,对所有会话生效,适合放个人规则(不入 Git)。

启动时按此顺序查找,每类「首个命中者生效」:

  1. 从当前目录向上回溯的本地文件(AGENTS.mdCLAUDE.md);
  2. 全局 ~/.config/opencode/AGENTS.md
  3. Claude Code 文件 ~/.claude/CLAUDE.md(除非禁用)。

兼容 Claude Code

从 Claude Code 迁移者可直接复用其约定作为回退:项目 CLAUDE.md(无 AGENTS.md 时)、全局 ~/.claude/CLAUDE.md、以及 ~/.claude/skills/。可用环境变量关闭:

export OPENCODE_DISABLE_CLAUDE_CODE=1          # 关闭全部 .claude 支持
export OPENCODE_DISABLE_CLAUDE_CODE_PROMPT=1   # 仅关闭 ~/.claude/CLAUDE.md
export OPENCODE_DISABLE_CLAUDE_CODE_SKILLS=1   # 仅关闭 .claude/skills

7.3 复用既有规则:instructions

不想把规则都搬进 AGENTS.md?用 instructions 引用既有文件(支持路径、glob、甚至远程 URL),它们会与 AGENTS.md 合并:

```json title=”opencode.json” { “$schema”: “https://opencode.ai/config.json”, “instructions”: [ “CONTRIBUTING.md”, “docs/guidelines.md”, “.cursor/rules/.md”, “packages//AGENTS.md”, “https://raw.githubusercontent.com/my-org/shared-rules/main/style.md” ] }


远程指令以 5 秒超时拉取。对 monorepo 或有共享规范的项目,用 glob(如 `packages/*/AGENTS.md`)比手写引用更易维护。

### 按需加载外部文件(省 Token 技巧)

OpenCode 不会自动解析 `AGENTS.md` 里的文件引用,但你可以在 `AGENTS.md` 里**教**它「按需懒加载」,避免一次性把所有规则塞进上下文:

```markdown title="AGENTS.md"
## 外部文件加载

关键:当遇到形如 @rules/general.md 的文件引用时,用 Read 工具按需加载它们,
它们只与当前具体任务相关。

- 不要预先加载所有引用——按实际需要懒加载
- 加载后将内容视为强制指令,覆盖默认行为
- 必要时递归跟随引用

## 开发指南
TypeScript 风格与最佳实践:@docs/typescript-guidelines.md
React 组件架构与 hooks:@docs/react-patterns.md

这样既能模块化、复用规则,又能让 AGENTS.md 保持精简、只在需要时才消耗 Token。


7.4 Agent Skills(SKILL.md

Skills 让 OpenCode 从仓库或主目录按需发现可复用的操作流程。它们通过原生 skill 工具被「看到」,只有在需要时才加载完整内容——天然省 Token。

存放位置

每个技能一个文件夹,内含 SKILL.md。搜索位置包括:

  • 项目:.opencode/skills/<name>/SKILL.md
  • 全局:~/.config/opencode/skills/<name>/SKILL.md
  • Claude 兼容:.claude/skills/<name>/SKILL.md~/.claude/skills/<name>/SKILL.md
  • agents 兼容:.agents/skills/<name>/SKILL.md~/.agents/skills/<name>/SKILL.md

frontmatter 规范

```markdown title=”.opencode/skills/git-release/SKILL.md”

name: git-release description: 规范化的 Git 发版流程:打 tag、生成 changelog、推送 release —

执行发版时,按以下步骤…… ```

仅识别这些字段:name(必填)、description(必填)、licensecompatibilitymetadata(字符串映射),其它字段被忽略。name 必须为 1–64 字符、小写字母数字、用单个连字符分隔、不以 - 开头或结尾、不含连续 --,且与所在目录名一致;description 为 1–1024 字符,要写得足够具体,方便 Agent 正确选用。

Skill 与「直接把所有流程写进 AGENTS.md」相比,最大优势是延迟加载:平时不占上下文,用到才加载,对长流程/多技能场景省 Token 效果明显。


7.5 小结

本章你学会了三种把项目知识注入 OpenCode 的方式:自定义命令(含参数、Bash 注入、文件引用、子任务分流)、规则文件(AGENTS.md + instructions + 懒加载技巧)、以及按需加载的 Skills。它们共同让模型「少问、少错、少返工」,本质上也是一种 Token 优化。下一章进入工具、权限与 MCP 扩展。