OpenCode 的核心价值不仅在于其强大的 AI 模型,更在于其高度可扩展的架构。通过内置工具、自定义工具、插件、Hooks 和 SDK,你可以将 OpenCode 的能力延伸到几乎任何场景。本文将完整覆盖这五大扩展机制。
OpenCode 内置了 13 个核心工具,AI Agent 通过这些工具与你的代码世界交互:
| 工具 | 功能 | 典型用法 |
|------|------|----------|
| read | 读取文件或目录 | 阅读代码、查看配置 |
| write | 创建或覆写文件 | 创建新文件、生成代码 |
| edit | 精确替换文件内容 | 修改代码片段 |
| bash | 执行 Shell 命令 | 运行测试、构建、Git 操作 |
| glob | 按模式匹配文件 | 查找特定类型的文件 |
| grep | 按正则搜索内容 | 搜索代码中的关键词 |
| task | 启动子代理 | 并行执行子任务 |
| webfetch | 获取网页内容 | 查阅文档、搜索信息 |
| question | 向用户提问 | 需要决策时与用户交互 |
| todowrite | 管理任务列表 | 跟踪多步骤任务进度 |
| skill | 加载技能模块 | 激活领域专业知识 |
| websearch | 网络搜索 | 查找技术资料 |
{
"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 让你可以为 AI 创建专属的工具函数,扩展其能力。
// .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
};
}
});
插件是比 Custom Tool 更重量级的扩展方式,可以添加多个工具、命令和 Hooks。
my-plugin/
├── plugin.json # 插件清单
├── index.ts # 插件入口
├── tools/ # 自定义工具
│ └── hello.ts
├── commands/ # 自定义命令
│ └── greet.md
└── skills/ # 技能模块
└── custom-skill/
└── SKILL.md
{
"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 让你在 OpenCode 的关键生命周期节点上插入自定义逻辑:
| Hook | 触发时机 |
|------|----------|
| onStart | OpenCode 启动时 |
| onMessage | 收到用户消息时 |
| onResponse | AI 生成回复后 |
| onFileEdit | 文件被修改时 |
| onCommand | 命令执行前后 |
| onToolCall | 任何工具被调用时 |
| onError | 发生错误时 |
| onExit | OpenCode 退出时 |
{
"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"
]
}
}
#!/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
{
"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
}
]
}
}
OpenCode 提供了 SDK,让你可以用编程方式控制 AI 编程助手:
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);
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 确保 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
}
{
"formatOnSave": true,
"formatOnEdit": true
}
formatOnSave:AI 保存文件后格式化formatOnEdit:每次编辑后立即格式化从内置工具到自定义工具,从插件到 Hooks,从 SDK 到 Formatters——OpenCode 的扩展系统形成了一个完整的能力构建体系。无论你想让 AI 访问公司的内部 API,还是在每次代码修改后自动运行代码检查,都有对应的扩展机制可以实现。
下一篇我们将深入 OpenCode 的项目协作与工作流集成,涵盖 GitHub/GitLab、LSP、Code Review、References、上下文管理和团队协作。