OpenCode 工具、插件与扩展系统完全指南

OpenCode 的核心价值不仅在于其强大的 AI 模型,更在于其高度可扩展的架构。通过内置工具、自定义工具、插件、Hooks 和 SDK,你可以将 OpenCode 的能力延伸到几乎任何场景。本文将完整覆盖这五大扩展机制。

一、内置工具系统

OpenCode 内置了 13 个核心工具,AI Agent 通过这些工具与你的代码世界交互:

| 工具 | 功能 | 典型用法 |
|------|------|----------|
| read | 读取文件或目录 | 阅读代码、查看配置 |
| write | 创建或覆写文件 | 创建新文件、生成代码 |
| edit | 精确替换文件内容 | 修改代码片段 |
| bash | 执行 Shell 命令 | 运行测试、构建、Git 操作 |
| glob | 按模式匹配文件 | 查找特定类型的文件 |
| grep | 按正则搜索内容 | 搜索代码中的关键词 |
| task | 启动子代理 | 并行执行子任务 |
| webfetch | 获取网页内容 | 查阅文档、搜索信息 |
| question | 向用户提问 | 需要决策时与用户交互 |
| todowrite | 管理任务列表 | 跟踪多步骤任务进度 |
| skill | 加载技能模块 | 激活领域专业知识 |
| websearch | 网络搜索 | 查找技术资料 |

配置 Agent 可用的工具

{
  "agents": {
    "reader": {
      "description": "只读分析 Agent",
      "tools": ["read", "glob", "grep"],
      "permissions": {
        "edit": false,
        "bash": false
      }
    },
    "developer": {
      "description": "全功能开发 Agent",
      "tools": ["*"],
      "permissions": {
        "edit": true,
        "bash": true,
        "network": true
      }
    }
  }
}

二、自定义工具 (Custom Tools)

Custom Tools 让你可以为 AI 创建专属的工具函数,扩展其能力。

用 JavaScript/TypeScript 编写自定义工具

// .opencode/tools/get_weather.ts

import { defineTool } from "opencode";

export default defineTool({
  name: "get_weather",
  description: "Get current weather for a city",
  parameters: {
    type: "object",
    properties: {
      city: {
        type: "string",
        description: "City name"
      }
    },
    required: ["city"]
  },

  async handler({ city }) {
    const response = await fetch(`
      https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${process.env.WEATHER_API_KEY}
    `);
    const data = await response.json();
    return {
      temperature: data.main.temp - 273.15,
      humidity: data.main.humidity,
      description: data.weather[0].description
    };
  }
});

配置自定义工具

{
  "tools": {
    "custom": {
      "weather": {
        "path": ".opencode/tools/get_weather.ts",
        "enabled": true
      },
      "deploy": {
        "path": "~/.config/opencode/tools/deploy.ts",
        "enabled": true,
        "requireConfirmation": true
      }
    }
  }
}

实战工具示例

// .opencode/tools/check_deps.ts
import { defineTool } from "opencode";
import { execSync } from "child_process";

export default defineTool({
  name: "check_dependencies",
  description: "Check for outdated npm dependencies and security vulnerabilities",
  parameters: {
    type: "object",
    properties: {
      severity: {
        type: "string",
        enum: ["low", "moderate", "high", "critical"],
        description: "Minimum severity level to report"
      }
    }
  },

  async handler({ severity = "high" }) {
    const outdated = execSync("npm outdated --json", { encoding: "utf8" });
    const audit = execSync("npm audit --json", { encoding: "utf8" });

    const auditData = JSON.parse(audit);
    const vulnerabilities = auditData.vulnerabilities || {};

    const filtered = Object.entries(vulnerabilities)
      .filter(([_, info]: [string, any]) => {
        const levels = ["low", "moderate", "high", "critical"];
        return levels.indexOf(info.severity) >= levels.indexOf(severity);
      })
      .map(([name, info]: [string, any]) => ({
        package: name,
        severity: info.severity,
        recommendation: info.fixAvailable ? "Update available" : "Manual review needed"
      }));

    return {
      outdated: JSON.parse(outdated),
      vulnerabilities: filtered
    };
  }
});

三、插件系统 (Plugins)

插件是比 Custom Tool 更重量级的扩展方式,可以添加多个工具、命令和 Hooks。

插件结构

my-plugin/
├── plugin.json        # 插件清单
├── index.ts           # 插件入口
├── tools/             # 自定义工具
│   └── hello.ts
├── commands/          # 自定义命令
│   └── greet.md
└── skills/            # 技能模块
    └── custom-skill/
        └── SKILL.md

plugin.json 清单

{
  "name": "my-custom-plugin",
  "version": "1.0.0",
  "description": "My custom OpenCode plugin",
  "author": "Your Name",
  "main": "index.ts",
  "openCodeVersion": ">=0.1.0",
  "tools": ["hello"],
  "commands": ["greet"],
  "skills": ["custom-skill"]
}

插件入口

// index.ts
import { definePlugin } from "opencode";

export default definePlugin({
  name: "my-custom-plugin",

  async onInit(config) {
    console.log("Plugin initialized with config:", config);
  },

  async onToolCall(toolName, args) {
    console.log(`Tool called: ${toolName}`, args);
  },

  async onShutdown() {
    console.log("Plugin shutting down");
  }
});

安装和配置插件

{
  "plugins": {
    "my-plugin": {
      "path": "~/.config/opencode/plugins/my-plugin",
      "config": {
        "apiKey": "${PLUGIN_API_KEY}",
        "endpoint": "https://api.example.com"
      }
    },
    "community-plugin": {
      "path": "git+https://github.com/user/opencode-plugin.git"
    }
  }
}

四、Hooks 系统

Hooks 让你在 OpenCode 的关键生命周期节点上插入自定义逻辑:

可用的 Hook 事件

| Hook | 触发时机 |
|------|----------|
| onStart | OpenCode 启动时 |
| onMessage | 收到用户消息时 |
| onResponse | AI 生成回复后 |
| onFileEdit | 文件被修改时 |
| onCommand | 命令执行前后 |
| onToolCall | 任何工具被调用时 |
| onError | 发生错误时 |
| onExit | OpenCode 退出时 |

配置 Hooks

{
  "hooks": {
    "onStart": [
      "echo 'OpenCode started at $(date)' >> ~/.opencode/logs/sessions.log"
    ],
    "onFileEdit": [
      "npx prettier --write $FILE_PATH"
    ],
    "onResponse": [
      "bash .opencode/hooks/check-secrets.sh"
    ],
    "onExit": [
      "bash .opencode/hooks/cleanup.sh"
    ]
  }
}

自定义 Hook 脚本

#!/bin/bash
# .opencode/hooks/check-secrets.sh

FILE="$1"
if [ -z "$FILE" ]; then
  exit 0
fi

# 检查是否有潜在的密钥泄露
if grep -qP '(?:ghp_|sk-ant-|AKIA)[A-Za-z0-9_\-]{20,}' "$FILE" 2>/dev/null; then
  echo "⚠️  警告:文件 $FILE 中检测到可能的 API 密钥!"
fi

高级 Hook 示例

{
  "hooks": {
    "onFileEdit": [
      {
        "command": "npx eslint --fix $FILE_PATH",
        "extensions": [".js", ".ts", ".jsx", ".tsx"],
        "async": false,
        "continueOnError": true
      },
      {
        "command": "npx prettier --write $FILE_PATH",
        "extensions": [".js", ".ts", ".json", ".md", ".css"],
        "async": false
      },
      {
        "command": "git add $FILE_PATH",
        "async": true
      }
    ]
  }
}

五、SDK 开发

OpenCode 提供了 SDK,让你可以用编程方式控制 AI 编程助手:

安装 SDK

npm install opencode-ai

基础用法

import { OpenCode } from "opencode-ai";

const opencode = new OpenCode({
  model: "claude-sonnet-4-20250514",
  provider: {
    id: "anthropic",
    apiKey: process.env.ANTHROPIC_API_KEY
  },
  cwd: "/path/to/project"
});

// 发送消息并获取回复
const response = await opencode.send("分析这个项目的架构");
console.log(response.text);

// 获取当前上下文
const context = await opencode.getContext();
console.log("当前打开的文件:", context.files);

// 执行命令并获取结果
const result = await opencode.exec("npm test");
console.log("测试结果:", result.stdout);

// 获取会话 Token 使用量
const usage = await opencode.getUsage();
console.log("已用 Token:", usage.totalTokens);

高级 SDK 用法

import { OpenCode, OpenCodeEvents } from "opencode-ai";

const opencode = new OpenCode({
  model: "claude-sonnet-4-20250514",
  provider: {
    id: "anthropic",
    apiKey: process.env.ANTHROPIC_API_KEY
  }
});

// 监听事件
opencode.on(OpenCodeEvents.TOOL_CALL, (data) => {
  console.log(`工具调用: ${data.tool}`, data.args);
});

opencode.on(OpenCodeEvents.FILE_EDIT, (data) => {
  console.log(`文件修改: ${data.path} (行 ${data.startLine}-${data.endLine})`);
});

opencode.on(OpenCodeEvents.ERROR, (error) => {
  console.error("错误:", error.message);
});

// 任务完成回调
const task = await opencode.send("重构 src/utils.ts 中的工具函数");
task.onProgress((progress) => {
  console.log(`进度: ${progress.percent}%`);
});

await task.wait();
console.log("任务完成,修改的文件:", task.modifiedFiles);

批量处理

import { OpenCode } from "opencode-ai";

async function batchRefactor() {
  const opencode = new OpenCode();

  const tasks = [
    opencode.send("优化 src/api/users.ts 的性能"),
    opencode.send("为 src/components/ 添加错误边界"),
    opencode.send("更新 README.md 中的 API 文档")
  ];

  const results = await Promise.all(tasks);
  for (const result of results) {
    console.log(result.summary);
  }
}

六、代码格式化器 (Formatters)

Formatters 确保 AI 生成的代码自动符合团队的格式规范:

{
  "formatters": {
    "prettier": {
      "command": "npx",
      "args": ["prettier", "--write"],
      "extensions": [".js", ".ts", ".jsx", ".tsx", ".json", ".md", ".css", ".html"]
    },
    "rustfmt": {
      "command": "rustfmt",
      "args": [],
      "extensions": [".rs"]
    },
    "black": {
      "command": "black",
      "args": ["--quiet"],
      "extensions": [".py"]
    },
    "gofmt": {
      "command": "gofmt",
      "args": ["-w"],
      "extensions": [".go"]
    },
    "php-cs-fixer": {
      "command": "php",
      "args": ["vendor/bin/php-cs-fixer", "fix"],
      "extensions": [".php"]
    }
  },
  "formatOnSave": true
}

Formatter 执行时机

{
  "formatOnSave": true,
  "formatOnEdit": true
}
  • formatOnSave:AI 保存文件后格式化
  • formatOnEdit:每次编辑后立即格式化

小结

从内置工具到自定义工具,从插件到 Hooks,从 SDK 到 Formatters——OpenCode 的扩展系统形成了一个完整的能力构建体系。无论你想让 AI 访问公司的内部 API,还是在每次代码修改后自动运行代码检查,都有对应的扩展机制可以实现。

下一篇我们将深入 OpenCode 的项目协作与工作流集成,涵盖 GitHub/GitLab、LSP、Code Review、References、上下文管理和团队协作。