【OpenCode- 使用】
OpenCode 进阶使用指南
序章:从一个想法说起
你有没有想过,如果有一个程序员,它不仅能理解你的需求,还能自己动手写代码、改 bug、做测试,甚至能操作浏览器、操作 GitHub、操作数据库……那会是什么体验?
这就是 OpenCode 想要做的事情。它不是一个简单的问答工具,而是一个真正的"AI 程序员"。
OpenCode 是什么
OpenCode 是一个开源的 AI 编程助手,运行在终端里。它能:
- 理解代码:读代码、分析代码、解释代码
- 生成代码:写新功能、改旧代码、重构架构
- 执行操作:运行命令、操作文件、连接外部工具
- 自动化:批量处理、多步骤任务、持续集成
简单来说,它就是一个能听懂你说话的"程序员同事"。
OpenCode 的核心价值
对于个人开发者:
- 提高编码效率 2-5 倍
- 减少重复性劳动
- 快速学习新技术
- 降低 bug 率
对于团队:
- 统一代码规范
- 沉淀团队经验
- 加速新人上手
- 提升代码质量
对于企业:
- 降低开发成本
- 加速项目交付
- 确保代码安全
- 满足合规要求
OpenCode 的架构
要理解 OpenCode 的强大之处,我们先看看它的整体架构:
┌─────────────────────────────────────────┐
│ 用户界面层 (CLI/TUI) │
│ - 命令行交互 / 终端界面 / Web 界面 │
├─────────────────────────────────────────┤
│ AI 引擎层 (LLM) │
│ - Claude / GPT / Gemini / Ollama │
├─────────────────────────────────────────┤
│ 核心能力层 │
│ - Agent 系统 / Skills 系统 / MCP 系统 │
├─────────────────────────────────────────┤
│ 工具集成层 │
│ - 文件系统 / Git / 浏览器 / API / DB │
└─────────────────────────────────────────┘
用户界面层:你输入命令的地方,可以是命令行、终端界面或者 Web。
AI 引擎层:真正"思考"的地方,支持多种大语言模型。
核心能力层:OpenCode 的核心竞争力,包括 Agent、Skills、MCP 三大系统。
工具集成层:连接外部世界的能力,让 AI 能操作真实的环境。
为什么需要进阶学习
基础使用 OpenCode,就像是你刚认识一个新同事,只会让他"帮我看看这段代码"。进阶学习,则是学会如何让这个同事真正参与到你的工作中:
- Agent 模式:让 AI 自主完成复杂任务
- Skills 系统:让 AI 拥有你的团队经验
- MCP 集成:让 AI 能使用各种专业工具
- 企业级功能:让 AI 能安全地服务整个团队
这篇文章,就是带你从"会用"走向"用好"的完整指南。
第一章:Agent 模式——AI 能自己干活了
1.1 什么是 Agent 模式
1.1.1 传统模式 vs Agent 模式
我们先来对比一下两种使用方式。
传统模式(对话模式):
你:这段代码有 bug,帮我看看
AI:问题在第 15 行,应该改成 xxx
你:(复制粘贴)改好了吗?
AI:还有第 23 行
你:(复制粘贴)现在呢?
AI:第 37 行也有问题
你:(内心崩溃)...
Agent 模式:
你:把项目里所有 bug 都修好
AI:好的,我来处理
↓
AI:(自动读取文件 → 分析问题 → 修改代码 → 验证修复 → 提交结果)
↓
AI:已修复 23 处问题,这是修改摘要...
看出区别了吗?
传统模式是"你指挥,AI 建议"。你得一步步告诉 AI 做什么,它才能帮你。
Agent 模式是"你定目标,AI 执行"。你只需要说"把项目里所有 bug 都修好",AI 会自己规划步骤、执行操作、验证结果。
1.1.2 Agent 模式的核心能力
Agent 模式之所以强大,是因为它具备以下能力:
自主决策能力:
- 分析任务复杂度
- 规划执行步骤
- 选择最佳方案
- 处理异常情况
多步骤执行能力:
- 连续执行多个操作
- 根据中间结果调整策略
- 自动验证每一步的结果
- 失败时自动重试或报告
工具使用能力:
- 读取文件系统
- 执行 shell 命令
- 运行测试
- 操作 Git
上下文感知能力:
- 理解项目结构
- 记住之前的操作
- 保持任务连贯性
- 处理依赖关系
1.1.3 Agent 模式的底层原理
OpenCode 的 Agent 系统是如何工作的?我们来看看它的内部机制:
ReAct 框架(Reasoning + Acting):
Agent 模式的核心是一个叫做 ReAct 的框架。ReAct = Reasoning(推理)+ Acting(行动)。
工作流程是这样的:
- 思考(Thought):AI 分析问题,决定下一步做什么
- 行动(Action):AI 执行具体的操作(读文件、改代码、运行命令)
- 观察(Observation):AI 观察执行结果
- 循环:根据观察结果,再次思考、行动、观察
这个过程会不断循环,直到任务完成。
工具调用机制:
OpenCode 给 AI 提供了一系列"工具",每个工具都有:
- 名字(name)
- 描述(description)
- 参数(parameters)
- 返回值(return value)
比如"读文件"工具:
{
"name": "read_file",
"description": "读取指定文件的内容",
"parameters": {
"path": {
"type": "string",
"description": "文件路径"
}
}
}
AI 想读文件时,会生成这样的调用:
{
"tool": "read_file",
"params": {
"path": "src/utils.ts"
}
}
OpenCode 收到调用后,执行实际的操作,把结果返回给 AI。
上下文管理:
Agent 模式需要管理大量的上下文信息:
- 任务目标
- 执行历史
- 当前状态
- 中间结果
- 错误信息
OpenCode 通过精心设计的提示词(Prompt)和上下文压缩技术,确保 AI 能在有限的上下文窗口内高效工作。
1.2 如何开启 Agent 模式
1.2.1 tab 切换
最简单的方式是在启动 OpenCode
opencode
当前是 plan 模式,只能对话

按 tab 切换 build 模式

1.3 Agent 模式的实际应用场景
1.3.1 场景一:批量重构代码
背景:你接手了一个老项目,里面到处都是 var,你想全部改成 let 或 const。
传统做法:
- 用 IDE 的全局搜索替换
- 手动检查每个替换是否正确
- 发现有的地方不该改,手动恢复
- 测试有没有引入新 bug
耗时:2-4 小时
Agent 模式做法:
> 帮我把项目中所有 var 改成 let 或 const。要求:
> 1. 只改 src 目录下的 .ts 和 .js 文件
> 2. 对于可能被重新赋值的变量用 let,其他的用 const
> 3. 改完后运行测试,确保没有引入新 bug
> 4. 生成一个修改报告,告诉我改了哪些文件
AI 的执行过程:
- 扫描 src 目录,找到所有 .ts 和 .js 文件
- 逐个文件分析,识别所有 var 声明
- 分析每个变量的使用情况,判断用 let 还是 const
- 执行替换
- 运行测试套件
- 如果有失败,回滚并报告
- 生成修改报告
耗时:5-10 分钟(你喝茶的时间)
修改报告示例:
✅ 批量重构完成
📊 统计信息:
- 扫描文件:127 个
- 修改文件:34 个
- 替换 var:156 处
- 改为 let:89 处
- 改为 const:67 处
🧪 测试结果:
- 测试通过:156 项
- 测试失败:0 项
📁 修改的文件(部分):
- src/utils/helper.ts: 12 处
- src/components/Button.tsx: 8 处
- src/pages/Home/index.tsx: 15 处
...
💡 建议:
已自动提交到 git 分支 "refactor/var-to-let-const"
建议人工复查后合并到主分支
1.3.2 场景二:自动生成测试用例
背景:你写了一个核心函数 calculateTotal,需要补测试用例。
传统做法:
- 理解函数逻辑
- 想各种边界情况
- 手写测试代码
- 运行测试,发现漏了某些情况
- 补充测试
耗时:30-60 分钟
Agent 模式做法:
> 为 src/utils/calculateTotal.ts 中的 calculateTotal 函数生成完整的 Jest 测试用例。
> 要求:
> 1. 覆盖正常输入、边界情况、异常输入
> 2. 测试用例要有清晰的描述
> 3. 使用 describe 和 it 组织测试结构
> 4. 运行测试确保能通过
AI 的执行过程:
- 读取 calculateTotal.ts,理解函数逻辑
- 分析函数参数和返回值
- 设计测试用例:
- 正常情况:常规输入
- 边界情况:空数组、极大值、负数
- 异常情况:非数字输入、null、undefined
- 生成测试文件 calculateTotal.test.ts
- 运行测试,确保通过
生成的测试代码示例:
import { calculateTotal } from './calculateTotal';
describe('calculateTotal', () => {
describe('正常输入', () => {
it('应该正确计算一组正数的总和', () => {
expect(calculateTotal([1, 2, 3])).toBe(6);
expect(calculateTotal([10, 20, 30])).toBe(60);
});
it('应该正确处理小数', () => {
expect(calculateTotal([0.1, 0.2])).toBeCloseTo(0.3);
});
});
describe('边界情况', () => {
it('空数组应该返回 0', () => {
expect(calculateTotal([])).toBe(0);
});
it('单元素数组应该返回该元素', () => {
expect(calculateTotal([42])).toBe(42);
});
it('应该正确处理负数', () => {
expect(calculateTotal([-1, -2, 3])).toBe(0);
});
it('应该正确处理极大值', () => {
expect(calculateTotal([Number.MAX_SAFE_INTEGER])).toBe(
Number.MAX_SAFE_INTEGER,
);
});
});
describe('异常输入', () => {
it('传入非数组应该抛出错误', () => {
expect(() => calculateTotal('not an array')).toThrow(
'Input must be an array',
);
});
it('数组中包含非数字应该抛出错误', () => {
expect(() => calculateTotal([1, 'two', 3])).toThrow(
'All elements must be numbers',
);
});
it('传入 null 应该抛出错误', () => {
expect(() => calculateTotal(null)).toThrow('Input cannot be null');
});
});
});
耗时:2-3 分钟
1.3.3 场景三:自动化 Bug 修复
背景:项目里 ESLint 报了一堆错误,有些是代码风格问题,有些是潜在 bug。
传统做法:
- 运行 ESLint,看到一堆错误
- 逐个文件手动修复
- 有些问题不知道怎么修,查文档
- 修了 2 小时后,发现还有 100 多个错误
耗时:数小时,且很痛苦
Agent 模式做法:
> 修复项目中所有 ESLint 错误。要求:
> 1. 优先修复潜在 bug(如 unused-vars, no-undef)
> 2. 代码风格问题(如 indentation, quotes)自动修复
> 3. 对于无法自动修复的,列出文件和行号,并说明原因
> 4. 修复后运行测试,确保没有破坏功能
> 5. 生成修复报告
AI 的执行过程:
- 运行 ESLint,获取所有错误列表
- 分类错误:
- 潜在 bug(高优先级)
- 代码风格(中优先级)
- 其他(低优先级)
- 逐个文件修复:
- 对于简单问题(如缺少分号),直接修改
- 对于复杂问题(如逻辑错误),生成修复建议
- 运行测试套件
- 生成详细报告
修复报告示例:
🔧 ESLint 自动修复完成
📊 统计信息:
- 总错误数:234
- 已修复:198
- 需人工确认:36
✅ 已修复的问题:
- unused-vars: 45 处
- no-trailing-spaces: 67 处
- quotes: 34 处
- semi: 52 处
⚠️ 需人工确认的问题:
1. src/core/payment.ts:23
问题:no-undef 'processPayment'
说明:使用了未定义的变量,可能拼写错误或缺少导入
2. src/utils/encryption.ts:45
问题:security/detect-object-injection
说明:动态对象属性访问,可能存在安全风险
🧪 测试结果:
- 测试通过:156 项
- 测试失败:0 项
💾 已保存到分支:fix/eslint-issues-20260115
耗时:5-10 分钟
1.3.4 场景四:多步骤复杂任务
背景:你需要实现一个新功能:用户上传头像,系统自动压缩、生成缩略图、保存到云存储、更新数据库。
传统做法:
- 写图片处理代码
- 集成云存储 SDK
- 更新数据库逻辑
- 写测试
- 联调测试
- 发现各种问题,反复修改
耗时:1-2 天
Agent 模式做法:
> 帮我实现用户头像上传功能。需求:
> 1. 前端:支持拖拽上传,显示预览,限制 5MB
> 2. 后端:接收文件,验证格式(jpg/png),压缩到 500KB 以下
> 3. 生成缩略图(100x100)
> 4. 上传到 AWS S3
> 5. 更新数据库 users 表的 avatar_url 字段
> 6. 返回图片 URL
> 7. 写完整的单元测试
>
> 技术栈:React + Node.js + TypeScript + AWS SDK + Jest
AI 的执行过程:
- 分析需求,规划实现步骤
- 创建前端组件:AvatarUploader.tsx
- 创建后端接口:uploadAvatar.ts
- 实现图片处理逻辑
- 集成 AWS S3
- 更新数据库操作
- 生成单元测试
- 创建接口文档
生成的主要文件:
├── src/
│ ├── components/
│ │ └── AvatarUploader/
│ │ ├── index.tsx # 上传组件
│ │ ├── styles.module.css # 样式
│ │ └── index.test.tsx # 组件测试
│ ├── api/
│ │ └── uploadAvatar.ts # 上传接口
│ ├── utils/
│ │ ├── imageProcessor.ts # 图片处理
│ │ └── s3Client.ts # S3 客户端
│ └── database/
│ └── userRepository.ts # 用户数据操作
├── tests/
│ └── uploadAvatar.test.ts # 接口测试
└── docs/
└── avatar-upload-api.md # API 文档
耗时:15-30 分钟(AI 生成代码,你审查代码)
1.4 Agent 模式的高级配置
1.4.1 执行策略配置
你可以配置 Agent 的执行策略:
{
"agent": {
"execution": {
"mode": "step_by_step",
"max_steps": 50,
"auto_confirm": false,
"rollback_on_error": true
}
}
}
mode:执行模式
step_by_step:每步都询问确认batch:批量执行,完成后汇报auto:全自动,只在关键点询问
max_steps:最大执行步数,防止无限循环
auto_confirm:是否自动确认低风险操作
rollback_on_error:出错时是否自动回滚
1.4.2 工具权限控制
控制 Agent 可以使用哪些工具:
{
"agent": {
"tools": {
"read_file": "allow",
"write_file": "ask",
"execute_shell": "deny",
"git_commit": "ask"
}
}
}
权限级别:
allow:直接允许ask:每次询问deny:禁止使用
1.4.3 上下文管理
配置上下文窗口的使用策略:
{
"agent": {
"context": {
"max_files": 20,
"max_lines_per_file": 100,
"compression": true,
"preserve_history": true
}
}
}
max_files:同时加载的最大文件数
max_lines_per_file:每个文件加载的最大行数
compression:是否压缩上下文
preserve_history:是否保留完整执行历史
1.5 Agent 模式的最佳实践
1.5.1 任务拆解原则
大任务拆小任务:
❌ 不好:
> 帮我把这个老项目全部重构了
✅ 好:
> 第一步:把项目中所有 var 改成 let/const
> 第二步:给所有函数加上类型定义
> 第三步:把类组件改成函数组件
每个任务要有明确的目标和验收标准:
> 给 src/utils 目录下所有工具函数添加 JSDoc 注释。
> 验收标准:
> 1. 每个函数都要有 @param 和 @returns
> 2. 复杂逻辑要有 @example
> 3. 运行 npm run docs:check 不报错
1.5.2 风险控制策略
原则一:备份先行
让 AI 大改之前,确保代码已提交:
git add .
git commit -m "backup before AI refactoring"
或者创建新分支:
git checkout -b ai-refactor-branch
原则二:逐步确认
对于重要操作,使用 step_by_step 模式:
> /agent config mode step_by_step
> 帮我把数据库操作封装成 Repository 模式
这样 AI 每做一步都会问你确认。
原则三:review 机制
养成看 git diff 的习惯:
git diff --stat
git diff src/utils/helper.ts
原则四:测试驱动
让 AI 改完代码后必须跑测试:
> 修改代码并确保所有测试通过
> 如果测试失败,回滚修改并报告问题
1.5.3 常见问题与解决方案
问题一:AI 执行太慢
原因:
- 任务太大,需要很多步骤
- 网络延迟,API 调用慢
- 上下文太长,处理慢
解决:
- 拆分任务,减少步骤数
- 使用本地模型(如 Ollama)
- 精简上下文,只加载必要文件
问题二:AI 理解错需求
原因:
- 需求描述不清楚
- 缺少上下文
- 歧义性语言
解决:
- 写更详细的需求文档
- 提供示例代码
- 使用更精确的术语
问题三:AI 改了不该改的代码
原因:
- 范围限制不明确
- 模式匹配太宽泛
- 缺少约束条件
解决:
- 明确指定修改范围(文件、目录、函数)
- 使用白名单/黑名单
- 设置保护目录(如 node_modules, .git)
问题四:AI 陷入死循环
原因:
- 任务目标不清晰
- 依赖关系复杂
- 错误处理不当
解决:
- 设置
max_steps限制 - 使用
/stop强制停止 - 简化任务目标
1.6 Agent 模式的底层实现细节
1.6.1 提示词工程(Prompt Engineering)
OpenCode 的 Agent 系统使用精心设计的提示词来引导 AI:
系统提示词(System Prompt):
你是一个专业的软件开发助手。你可以使用以下工具:
1. read_file(path): 读取文件内容
2. write_file(path, content): 写入文件
3. execute_shell(command): 执行 shell 命令
4. run_test(pattern): 运行测试
5. git_operation(action, ...): Git 操作
工作流程:
1. 理解用户需求
2. 制定执行计划
3. 逐步执行
4. 验证结果
5. 报告完成情况
约束:
- 每次只执行一个操作
- 等待操作结果后再继续
- 遇到错误立即报告
- 不确定时询问用户
任务提示词(Task Prompt):
任务:批量修改代码
目标:把项目中所有 var 改成 let/const
范围:src/目录下的.ts文件
约束:
- 不改 node_modules
- 不改配置文件
- 保持原有功能
请按以下步骤执行:
1. 扫描 src/目录,列出所有.ts文件
2. 逐个文件分析 var 的使用情况
3. 生成修改方案
4. 执行修改
5. 运行测试验证
1.6.2 工具调用协议
OpenCode 使用 JSON-RPC 风格的协议进行工具调用:
请求格式:
{
"id": "req-001",
"method": "read_file",
"params": {
"path": "src/utils.ts",
"offset": 1,
"limit": 50
}
}
响应格式:
{
"id": "req-001",
"result": {
"content": "export function add(a: number, b: number) {\n return a + b;\n}",
"lines": 3,
"path": "src/utils.ts"
},
"error": null
}
错误响应:
{
"id": "req-001",
"result": null,
"error": {
"code": "FILE_NOT_FOUND",
"message": "文件不存在: src/utils.ts"
}
}
1.6.3 状态机模型
Agent 的执行过程可以用状态机来描述:
[Start]
↓
[Analyzing] ← 分析任务
↓
[Planning] ← 制定计划
↓
[Executing] ← 执行操作
↓
[Observing] ← 观察结果
↓
├─ 成功 → [Executing] (继续下一步)
├─ 失败 → [ErrorHandling] → [Executing] (重试) 或 [Reporting] (放弃)
└─ 完成 → [Reporting]
↓
[End]
每个状态都有明确的进入条件和退出动作。
1.6.4 记忆机制
Agent 需要记住之前的信息:
短期记忆:当前会话的上下文
{
"session_id": "sess-abc123",
"current_task": "refactor codebase",
"steps_completed": 5,
"steps_total": 12,
"modified_files": ["src/utils/helper.ts", "src/components/Button.tsx"],
"errors": []
}
长期记忆:跨会话的学习
{
"user_preferences": {
"code_style": "standard",
"test_framework": "jest",
"max_line_length": 100
},
"common_patterns": {
"api_endpoint_structure": "...",
"error_handling_pattern": "..."
}
}
1.7 小结
Agent 模式是 OpenCode 最强大的功能之一。它让 AI 从"建议者"变成了"执行者",真正参与到开发工作中。
核心要点:
- Agent 模式 = AI 自主执行多步骤任务
- 开启方式:tab 切换致 build 模式
- 适合场景:批量操作、复杂任务、重复性劳动
- 风险控制:备份、逐步确认、review、测试
- 底层原理:ReAct 框架 + 工具调用 + 上下文管理
下一步学习:掌握 Agent 模式后,建议学习 Skills 系统,把常用的 Agent 任务封装成可复用的技能。
第二章:Skills 系统
想象一个场景:你刚入职一家新公司,发现团队的代码审查流程非常规范——每次提交都要检查代码风格、潜在 bug、性能问题、安全漏洞。这些检查点有十几条,每次审查都要一条条过。
刚开始你觉得这个流程很好,能保证代码质量。但几周后,你开始觉得烦了。每次审查都要重复同样的检查项,写同样的评论格式,提同样的修改建议。
你会想:"如果能把这个流程自动化就好了。"
Skills 系统就是来解决这个问题的。
Skills 是一套可复用的指令模板。
当你发现自己在重复做某类任务时,你可以:
- 把这类任务的步骤、标准、注意事项整理出来
- 写成 SKILL.md 文件
- 放到特定目录
- 以后让 AI 自动按照这个模板执行
简单来说,Skills 就是把"你的经验"变成"AI 的能力"。
Skills vs Agent 模式的区别
很多人问:"Skills 和 Agent 模式有什么区别?"
| 维度 | Agent 模式 | Skills 系统 |
|---|---|---|
| 定位 | 执行能力 | 知识封装 |
| 作用 | 让 AI 能动手 | 让 AI 懂规则 |
| 使用方式 | 临时指令 | 预定义模板 |
| 复用性 | 每次都要说 | 一次定义多次使用 |
| 适用场景 | 具体任务 | 标准化流程 |
举例说明:
Agent 模式就像你让一个程序员"去重构代码"。他会自己思考怎么做。
Skills 系统就像你给程序员一本《代码重构手册》,告诉他:"以后重构都按这个手册来"。
两者可以结合使用:用 Skills 定义流程,用 Agent 模式执行流程。
Skills 能做什么
代码质量类:
- 代码审查检查清单
- 重构标准流程
- 性能优化指南
- 安全审计规范
开发流程类:
- 新功能开发流程
- Bug 修复标准流程
- 测试用例生成规范
- 文档编写模板
团队协作类:
- 代码提交规范
- PR 审查标准
- 发布流程检查
- 新人入职指南
领域专业类:
- 前端组件开发规范
- API 设计最佳实践
- 数据库操作规范
- 微服务拆分原则
Skills 的核心概念
2.2.1 技能发现机制
OpenCode 是如何找到 Skills 的?这涉及到一个"发现机制"。
搜索路径:
当你启动 OpenCode 时,它会从当前目录开始,向上查找所有包含 .opencode/skills/ 或 .claude/skills/ 的目录。
搜索顺序:
当前工作目录/.opencode/skills/
当前工作目录/.claude/skills/
父目录/.opencode/skills/
父目录/.claude/skills/
...
直到 git 仓库根目录
~
~/.config/opencode/skills/ (全局)
~/.claude/skills/ (全局兼容)
为什么要向上查找?
考虑一个 monorepo 项目结构:
my-project/ ← git 根目录
├── .opencode/skills/ ← 项目级 Skills
│ ├── code-review/
│ └── api-design/
├── packages/
│ ├── frontend/
│ │ └── .opencode/skills/ ← 前端专属 Skills
│ │ └── react-component/
│ └── backend/
│ └── .opencode/skills/ ← 后端专属 Skills
│ └── express-route/
如果你在 packages/frontend/ 目录下工作,OpenCode 会加载:
packages/frontend/.opencode/skills/- 前端专属my-project/.opencode/skills/- 项目级~/.config/opencode/skills/- 全局
这样设计的好处:子项目可以覆盖或扩展父项目的 Skills。
2.2.2 技能加载过程
当一个 Skill 被发现后,OpenCode 会:
- 读取 SKILL.md:解析 YAML frontmatter 和 Markdown 内容
- 验证格式:检查必填字段、格式规范
- 解析依赖:如果有依赖其他 Skills,先加载依赖
- 注入上下文:将 Skill 信息注入到 AI 的上下文中
- 注册工具:如果 Skill 定义了自定义工具,注册到工具集
加载时机:
- 启动时:加载所有发现的 Skills
- 运行时:可以动态加载新 Skills(通过
/skill reload) - 按需加载:某些 Skills 可以设置 lazy loading
2.2.3 技能匹配机制
OpenCode 怎么知道什么时候该用哪个 Skill?
关键词匹配:
Skill 的 description 字段包含关键词,AI 会根据用户输入匹配最合适的 Skill。
例如:
- 用户说"帮我审查代码" → 匹配 code-review Skill
- 用户说"生成 API 文档" → 匹配 api-doc Skill
显式调用:
用户可以直接指定使用某个 Skill:
> /skill use code-review
> 开始审查 src/components/Button.tsx
自动推荐:
OpenCode 会分析当前上下文,主动推荐可能相关的 Skills:
看起来你正在写 React 组件。
可用的 Skills:
1. react-component - React 组件开发规范
2. code-review - 代码审查检查清单
3. testing - 测试用例生成
要使用哪个?(输入编号或名称)
2.2.4 技能生命周期
一个 Skill 从创建到使用,经历以下阶段:
1. 开发阶段:
- 编写 SKILL.md
- 本地测试
- 迭代优化
2. 发布阶段:
- 提交到 Git
- 版本标记
- 文档更新
3. 分发阶段:
- 团队成员拉取
- 全局安装(可选)
- 内部 npm 包(可选)
4. 使用阶段:
- 自动匹配
- 显式调用
- 结果反馈
5. 维护阶段:
- 收集反馈
- 更新优化
- 版本迭代
创建你的第一个 Skill
2.3.1 准备工作
环境要求:
- OpenCode 0.1.40+
- 一个 Git 仓库(推荐)
- 基本的 Markdown 知识
选择技能类型:
第一次创建 Skill,建议从简单的开始。比如:
- 代码风格检查
- 提交信息规范
- 简单的代码生成
2.3.2 实战:创建一个代码提交规范 Skill
场景:团队要求所有提交信息都要遵循 Conventional Commits 规范,但新人总是记不住格式。
目标:创建一个 Skill,帮助生成符合规范的提交信息。
Step 1:创建目录结构
mkdir -p .opencode/skills/conventional-commit
cd .opencode/skills/conventional-commit
Step 2:编写 SKILL.md
创建文件 SKILL.md:
---
name: conventional-commit
description: 帮助生成符合 Conventional Commits 规范的提交信息
version: 1.0.0
author: your-name
tags:
- git
- workflow
- automation
---
# Conventional Commit 助手
## 什么时候用
当你需要写 Git 提交信息时,使用这个 Skill 来生成符合团队规范的提交信息。
## 规范说明
我们团队使用 Conventional Commits 规范,格式如下:
### Type 类型
- **feat**: 新功能
- **fix**: 修复 bug
- **docs**: 文档修改
- **style**: 代码格式修改(不影响功能)
- **refactor**: 重构
- **perf**: 性能优化
- **test**: 测试相关
- **chore**: 构建过程或辅助工具变动
### Scope 范围
根据修改的内容选择:
- **api**: API 相关
- **ui**: 界面相关
- **db**: 数据库相关
- **config**: 配置相关
- **deps**: 依赖相关
## 使用步骤
1. 询问用户本次修改的主要内容
2. 分析修改的文件,判断 type 和 scope
3. 生成多个提交信息选项
4. 让用户选择或修改
5. 输出最终的提交命令
## 示例
**示例 1:新功能**
用户:添加了用户登录功能
生成:
git commit -m "feat(auth): 添加用户登录功能
- 实现 JWT token 验证
- 添加登录页面 UI
- 集成后端登录接口
Closes #123"
**示例 2:Bug 修复**
用户:修复了登录按钮点击无响应的问题
生成:
git commit -m "fix(ui): 修复登录按钮点击无响应
问题原因:事件监听器未正确绑定
解决方案:使用 useEffect 确保 DOM 加载完成后再绑定
Fixes #456"
**示例 3:文档更新**
用户:更新了 API 文档
生成:
git commit -m "docs(api): 更新用户认证接口文档
- 添加 JWT 认证说明
- 补充错误码列表
- 添加请求示例"
## 注意事项
1. subject 首字母不要大写
2. subject 末尾不要加句号
3. body 每行不超过 72 个字符
4. 如果有关联的 issue,在 footer 中引用
Step 3:测试 Skill
在 OpenCode 中测试:
> /skill list
可用的 Skills:
- conventional-commit: 帮助生成符合 Conventional Commits 规范的提交信息
> 我要提交代码,帮我写提交信息
[AI 会使用 conventional-commit Skill]
AI:请描述一下本次修改的主要内容:
> 修复了用户列表页面分页不生效的问题
AI:分析修改内容...
↓
AI:为你生成了以下提交信息选项:
选项 1:
git commit -m "fix(ui): 修复用户列表分页不生效
- 修正分页参数传递错误
- 添加分页边界检查
Fixes #789"
选项 2:
git commit -m "fix(api): 修复用户列表接口分页参数处理
问题原因:page 参数未正确解析
解决方案:使用 parseInt 转换并添加默认值
Fixes #789"
请选择一个(输入 1 或 2),或告诉我修改建议:
> 1
AI:好的,使用选项 1。请复制以下命令执行:
git commit -m "fix(ui): 修复用户列表分页不生效
- 修正分页参数传递错误
- 添加分页边界检查
Fixes #789"
2.3.3 进阶:添加智能分析
上面的 Skill 还需要用户手动描述修改内容。我们可以让它更智能——自动分析修改的文件。
更新 SKILL.md:
---
name: conventional-commit
description: 智能生成符合 Conventional Commits 规范的提交信息
version: 1.1.0
author: your-name
tags:
- git
- workflow
- automation
- smart-analysis
---
# Conventional Commit 助手(智能版)
## 新增功能
### 自动分析修改
使用以下命令自动分析工作区的修改:
git diff --name-only # 查看修改了哪些文件
git diff # 查看具体修改内容
git status # 查看文件状态
### 文件类型映射
根据修改的文件自动推断 type 和 scope:
**文件路径 → Type 推断**:
- `src/**/*.test.ts` → test
- `docs/**/*.md` → docs
- `package.json`, `package-lock.json` → chore
- 其他 → 需要人工判断(feat 或 fix)
**文件路径 → Scope 推断**:
- `src/components/**/*.tsx` → ui
- `src/api/**/*.ts` → api
- `src/db/**/*.ts` → db
- `src/utils/**/*.ts` → utils
- `config/**/*.js` → config
## 使用步骤(智能版)
1. 执行 `git status` 和 `git diff --name-only`,了解修改了哪些文件
2. 执行 `git diff`,了解具体的修改内容
3. 根据文件路径和修改内容,自动推断 type 和 scope
4. 生成提交信息草稿
5. 询问用户确认或修改
6. 输出最终的提交命令
## 示例流程
用户:帮我生成提交信息
AI:[执行 git status]
修改的文件:
- src/components/UserList.tsx
- src/api/users.ts
- src/components/UserList.test.tsx
AI:[执行 git diff]
UserList.tsx: 添加了分页功能
users.ts: 添加了分页参数支持
UserList.test.tsx: 添加了分页测试
AI:分析结果:
- Type: feat (新功能)
- Scope: ui (主要是 UI 组件)
- 涉及 API 修改,需要在 body 中说明
生成提交信息:
git commit -m "feat(ui): 添加用户列表分页功能
- 实现前端分页组件和交互
- 后端 API 添加分页参数支持
- 添加单元测试覆盖
涉及文件:
- src/components/UserList.tsx
- src/api/users.ts
- src/components/UserList.test.tsx
Closes #234"
请确认或修改:
2.3.4 提交到团队仓库
创建好 Skill 后,记得提交到 Git:
git add .opencode/skills/conventional-commit/
git commit -m "feat(devtools): 添加 Conventional Commit 助手 Skill
- 自动生成符合规范的提交信息
- 支持智能分析修改内容
- 提供多种选项供选择"
git push
团队成员拉取代码后就能使用这个 Skill 了。
SKILL.md 文件详解
2.4.1 YAML Frontmatter 完整字段
SKILL.md 文件以 YAML frontmatter 开头,放在 --- 之间。
必需字段:
| 字段 | 类型 | 说明 | 示例 |
|---|---|---|---|
| name | string | 技能名称,必须唯一,只能用小写字母、数字和连字符 | code-review |
| description | string | 技能描述,用于匹配和展示 | 自动进行代码审查 |
可选字段:
| 字段 | 类型 | 说明 | 示例 |
|---|---|---|---|
| version | string | 版本号,遵循 semver | 1.2.3 |
| author | string | 作者信息 | 张三 <zhangsan@example.com> |
| license | string | 许可证 | MIT |
| tags | array | 标签,用于分类和搜索 | ["testing", "automation"] |
| compatibility | string | 兼容性标识 | opencode>=0.1.40 |
| dependencies | array | 依赖的其他 Skills | ["base-coding", "testing-utils"] |
| metadata | object | 自定义元数据 | { "team": "frontend", "priority": "high" } |
完整示例:
---
name: react-component-review
description: 针对 React 组件的代码审查,检查 hooks 使用、性能优化、可访问性等
version: 2.1.0
author: 前端团队 <frontend@company.com>
license: MIT
tags:
- react
- review
- performance
- a11y
compatibility: opencode>=0.1.40
dependencies:
- base-code-review
metadata:
team: frontend
priority: high
review_level: strict
---
2.4.2 Markdown 内容结构
YAML frontmatter 之后是 Markdown 内容,用来详细说明技能的使用方法。
推荐结构:
# 技能标题
## 什么时候用
描述使用场景和触发条件。
## 前置条件
列出使用这个技能前需要满足的条件。
## 输入参数
如果技能需要参数,说明参数格式和示例。
## 使用步骤
详细说明执行步骤,可以包含:
1. 第一步做什么
2. 第二步做什么
3. ...
## 检查清单
列出需要检查的项目,用复选框表示。
## 示例
提供具体的使用示例。
### 示例 1:场景 A
详细说明...
### 示例 2:场景 B
详细说明...
## 输出格式
说明执行结果的格式。
## 注意事项
列出常见问题和注意事项。
## 相关资源
- 链接 1
- 链接 2
2.4.3 特殊语法
变量替换:
可以在 Skill 中使用变量,这些变量会在执行时被替换:
## 使用步骤
1. 读取文件 {{file_path}}
2. 检查 {{check_item}}
3. 输出结果到 {{output_path}}
使用时:
> /skill use code-review file_path=src/App.tsx check_item=performance
条件逻辑:
可以使用条件注释:
<!-- if: framework == "react" -->
## React 特定检查
- 检查 hooks 规则
- 检查 JSX 语法
<!-- endif -->
<!-- if: framework == "vue" -->
## Vue 特定检查
- 检查模板语法
- 检查生命周期使用
<!-- endif -->
代码块:
使用代码块展示示例代码:
// 示例代码
function example() {
return "Hello";
}
表格:
使用表格展示对照信息:
| 情况 | 处理方式 | 示例 |
|---|---|---|
| 正常 | 直接通过 | - |
| 警告 | 提示但允许 | console.log |
| 错误 | 必须修复 | eval() |
高级技能编写技巧
2.5.1 条件技能
根据不同的条件执行不同的逻辑。
示例:根据项目类型使用不同的检查规则
---
name: project-lint
description: 根据项目类型自动选择合适的代码检查规则
---
# 项目类型检测
## 检测项目类型
1. 检查 package.json 中的依赖:
- 如果有 react → 前端项目
- 如果有 express → 后端项目
- 如果有 pytest → Python 项目
2. 根据类型加载对应的检查规则:
<!-- if: project_type == "frontend" -->
## 前端项目检查规则
### JavaScript/TypeScript
- ESLint 规则
- Prettier 格式
- TypeScript 类型检查
### React 特定
- Hooks 规则检查
- JSX 语法检查
- 组件命名规范
<!-- endif -->
<!-- if: project_type == "backend" -->
## 后端项目检查规则
### Node.js
- 异步处理检查
- 错误处理检查
- 安全问题检查
### API 设计
- RESTful 规范
- 参数校验
- 错误码规范
<!-- endif -->
2.5.2 组合技能
一个 Skill 可以调用其他 Skills。
示例:完整的代码提交流程
---
name: complete-code-submit
description: 完整的代码提交流程:检查 → 测试 → 生成提交信息 → 提交
dependencies:
- code-review
- conventional-commit
- pre-commit-check
---
# 完整代码提交流程
## 流程步骤
1. **代码检查**(调用 code-review Skill)
- 运行 linter
- 类型检查
- 安全检查
2. **测试验证**(调用 pre-commit-check Skill)
- 运行单元测试
- 运行集成测试
- 检查测试覆盖率
3. **生成提交信息**(调用 conventional-commit Skill)
- 分析修改内容
- 生成符合规范的提交信息
4. **执行提交**
- git add
- git commit
- (可选)git push
## 失败处理
如果某一步失败:
- 停止后续步骤
- 报告失败原因
- 提供修复建议
2.5.3 交互式技能
让 Skill 支持交互式输入。
示例:交互式项目初始化
---
name: interactive-init
description: 交互式项目初始化,根据用户选择生成项目结构
---
# 交互式项目初始化
## 步骤 1:选择项目类型
询问用户:
"你要创建什么类型的项目?"
选项:
1. React 前端应用
2. Node.js 后端 API
3. Python 脚本
4. 其他
根据选择进入不同分支。
## 步骤 2:收集项目信息
<!-- if: project_type == "react" -->
询问:
- 项目名称?
- 使用 TypeScript 吗?
- 使用哪个 UI 库?(Ant Design / Material-UI / Tailwind)
- 需要路由吗?
- 需要状态管理吗?
<!-- endif -->
## 步骤 3:确认配置
展示将要生成的配置:
项目:my-app 类型:React + TypeScript UI 库:Ant Design 路由:是状态管理:Redux Toolkit
确认生成吗?(y/n)
## 步骤 4:生成项目
根据确认的配置生成项目文件。
## 步骤 5:安装依赖并启动
cd {{project_name}}
npm install
npm run dev
2.5.4 模板技能
使用模板引擎生成代码。
示例:组件生成器
---
name: component-generator
description: 根据模板生成 React 组件
templates:
- name: functional-component
path: ./templates/FunctionalComponent.tsx
- name: class-component
path: ./templates/ClassComponent.tsx
---
# React 组件生成器
## 使用方法
> /skill use component-generator name=Button type=functional props="onClick: () => void; children: ReactNode"
## 模板变量
模板中可以使用以下变量:
- `{{component_name}}` - 组件名(大驼峰)
- `{{component_name_lower}}` - 组件名(小写)
- `{{props}}` - 属性定义
- `{{imports}}` - 导入语句
- `{{today}}` - 当前日期
## 生成的文件
- `src/components/{{component_name}}/index.tsx` - 组件主体
- `src/components/{{component_name}}/index.test.tsx` - 测试文件
- `src/components/{{component_name}}/index.stories.tsx` - Storybook 文档
- `src/components/{{component_name}}/styles.module.css` - 样式文件
模板文件示例(templates/FunctionalComponent.tsx):
import React from 'react';
import styles from './styles.module.css';
export interface {{component_name}}Props {
{{props}}
}
/**
* {{component_name}} 组件
*
* @example
* ```tsx
* <{{component_name}} {{example_props}} />
* ```
*/
export const {{component_name}}: React.FC<{{component_name}}Props> = (props) => {
const { {{prop_names}} } = props;
return (
<div className={styles.container}>
{/* 组件内容 */}
</div>
);
};
{{component_name}}.displayName = '{{component_name}}';
export default {{component_name}};
技能调试与优化
2.6.1 调试技巧
本地测试:
在提交 Skill 前,先在本地测试:
# 创建测试目录
mkdir /tmp/skill-test
cd /tmp/skill-test
# 复制 Skill
cp -r /path/to/your/skill ./.opencode/skills/
# 启动 OpenCode 测试
opencode --agent
# 测试 Skill
> /skill list
> /skill use your-skill-name
日志输出:
在 Skill 中添加调试信息:
## 调试模式
如果设置环境变量 `DEBUG_SKILL=true`,输出详细的执行日志。
DEBUG_SKILL=true opencode --agent
逐步执行:
使用 step_by_step 模式查看每一步的执行:
> /agent config mode step_by_step
> /skill use your-skill
2.6.2 性能优化
减少上下文大小:
- 只加载必要的文件
- 使用摘要而非完整内容
- 压缩历史记录
---
name: optimized-skill
description: 优化过的技能,只加载必要信息
---
# 优化执行
## 文件读取优化
不要读取整个文件:
❌ cat src/large-file.ts
只读取相关部分:
✅ head -n 50 src/large-file.ts
✅ grep -n "function target" src/large-file.ts
## 上下文管理
- 使用 `max_lines_per_file: 100` 限制每文件读取行数
- 使用 `compression: true` 启用上下文压缩
缓存机制:
对于重复使用的数据,可以缓存:
## 缓存配置
缓存以下数据以提高性能:
- 项目结构(5 分钟)
- 依赖列表(1 小时)
- 检查规则(24 小时)
2.6.3 错误处理
优雅降级:
## 错误处理
如果某一步失败:
1. 尝试备用方案
2. 如果备用方案也失败,报告错误
3. 提供手动操作指南
### 示例:文件读取失败
错误:无法读取 src/config.ts
可能原因:
- 文件不存在
- 权限不足
- 文件被占用
解决方案:
- 检查文件是否存在:ls src/
- 检查权限:ls -la src/config.ts
- 手动创建文件(提供模板)
重试机制:
## 网络操作重试
对于网络请求(如 API 调用):
- 失败时自动重试 3 次
- 每次重试间隔 1 秒
- 如果都失败,报错并退出
2.6.4 版本管理
语义化版本:
遵循 semver 规范:
- MAJOR(主版本):不兼容的修改
- MINOR(次版本):新增功能,向后兼容
- PATCH(修订):Bug 修复,向后兼容
示例:
1.0.0 - 初始版本
1.1.0 - 添加自动分析功能
1.1.1 - 修复 scope 检测 bug
2.0.0 - 重构 API,不兼容 1.x
变更日志:
维护 CHANGELOG.md:
# Changelog
## [2.0.0] - 2026-01-15
### 重大变更
- 重构 API,使用新的配置格式
- 不再支持 OpenCode < 0.1.40
### 新功能
- 支持 Vue 项目
- 添加自定义规则
### 修复
- 修复了 Windows 路径问题
团队协作与技能共享
2.7.1 团队 Skills 仓库
集中管理:
创建一个专门的仓库管理团队 Skills:
company-opencode-skills/
├── README.md
├── skills/
│ ├── code-review/
│ │ └── SKILL.md
│ ├── commit-message/
│ │ └── SKILL.md
│ └── pr-template/
│ └── SKILL.md
├── templates/
│ └── component/
├── scripts/
│ └── install.sh
└── package.json
安装脚本(scripts/install.sh):
#!/bin/bash
# 安装团队 Skills 到全局
SKILLS_DIR="$HOME/.config/opencode/skills"
REPO_URL="https://github.com/yourcompany/opencode-skills.git"
# 克隆或更新
if [ -d "$SKILLS_DIR/.git" ]; then
cd "$SKILLS_DIR" && git pull
else
git clone "$REPO_URL" "$SKILLS_DIR"
fi
echo "✓ 团队 Skills 已安装到 $SKILLS_DIR"
echo "可用的 Skills:"
ls "$SKILLS_DIR/skills/"
2.7.2 项目级 Skills
与项目代码一起管理:
将项目特定的 Skills 放在项目仓库中:
my-project/
├── .opencode/
│ └── skills/
│ ├── domain-specific/ # 领域特定
│ ├── framework-specific/ # 框架特定
│ └── team-conventions/ # 团队约定
├── src/
├── package.json
└── README.md
Git 子模块(可选):
如果多个项目共享同一套 Skills,可以使用 Git 子模块:
# 添加 Skills 子模块
git submodule add https://github.com/yourcompany/opencode-skills.git .opencode/skills
# 克隆项目时递归克隆子模块
git clone --recursive https://github.com/yourcompany/my-project.git
2.7.3 Skills 市场(未来规划)
虽然目前 OpenCode 还没有官方的 Skills 市场,但可以预见未来的发展方向:
社区共享:
- 类似 npm 的 Skills 仓库
- 版本管理和依赖解析
- 评分和评论系统
企业内部市场:
- 私有 Skills 仓库
- 权限管理
- 审计日志
实战案例集
2.8.1 案例一:前端代码审查 Skill
---
name: frontend-code-review
description: 针对前端项目的全面代码审查,包括 React/Vue、性能、安全、可访问性
tags:
- frontend
- review
- react
- vue
---
# 前端代码审查
## 审查范围
### 1. 代码规范
- ESLint 规则合规性
- Prettier 格式
- 命名规范
- 文件组织
### 2. React 特定检查
- Hooks 使用规范
- 不要在循环、条件中调用 Hooks
- 依赖数组完整性
- useEffect 清理函数
- 组件设计
- 单一职责原则
- Props 类型定义
- 默认 Props
- 性能优化
- useMemo/useCallback 使用
- 不必要的重渲染
- 代码分割
### 3. Vue 特定检查
- Composition API 使用
- Props/Emits 类型定义
- 生命周期使用
- 响应式数据
### 4. 样式检查
- CSS-in-JS 规范
- 样式隔离
- 响应式设计
- 浏览器兼容性
### 5. 可访问性 (a11y)
- 语义化 HTML
- ARIA 属性
- 键盘导航
- 屏幕阅读器支持
### 6. 安全检查
- XSS 防护
- 不安全的 innerHTML
- 敏感信息泄露
## 输出格式
## 代码审查报告
### 概览
- 审查文件:{{file_count}} 个
- 问题总数:{{issue_count}} 个
- 严重:{{critical_count}} 个
- 警告:{{warning_count}} 个
- 建议:{{suggestion_count}} 个
### 详细问题
#### 1. [严重] src/components/UserForm.tsx:45
**问题**:useEffect 缺少依赖项
**代码**:
useEffect(() => {
fetchUser(userId);
}, []); // ❌ userId 未在依赖数组中
**修复**:
useEffect(() => {
fetchUser(userId);
}, [userId]);
#### 2. [警告] src/utils/api.ts:12
**问题**:缺少错误处理 ...
### 建议改进
1. ...
2. ...
## 使用示例
> /skill use frontend-code-review path=src/components/
2.8.2 案例二:API 设计审查 Skill
---
name: api-design-review
description: RESTful API 设计审查,包括规范、安全性、性能
tags:
- backend
- api
- rest
---
# API 设计审查
## 审查清单
### 1. RESTful 规范
- [ ] URL 设计是否符合资源导向
- [ ] HTTP 方法使用是否正确
- [ ] 状态码返回是否恰当
- [ ] 版本控制策略
### 2. 请求/响应设计
- [ ] 请求参数校验
- [ ] 响应格式统一
- [ ] 错误信息规范
- [ ] 分页设计
### 3. 安全性
- [ ] 认证机制
- [ ] 权限控制
- [ ] 输入验证
- [ ] 防注入
- [ ] 敏感数据保护
### 4. 性能
- [ ] 响应时间
- [ ] 缓存策略
- [ ] 并发处理
- [ ] 数据库查询优化
### 5. 文档
- [ ] OpenAPI/Swagger 文档
- [ ] 示例请求/响应
- [ ] 错误码说明
## 示例审查
**待审查 API**:
GET /api/getUserData?id=123
**问题**:
1. URL 不符合 RESTful 规范(动词 getUserData)
2. 使用 query 参数传递 ID(应该是路径参数)
3. 缺少版本号
**建议**:
GET /api/v1/users/123
2.8.3 案例三:数据库迁移 Skill
---
name: database-migration
description: 安全的数据库迁移流程,包括备份、迁移、验证、回滚
tags:
- database
- migration
- devops
---
# 数据库迁移
## 流程
### 1. 迁移前检查
- [ ] 确认迁移脚本已测试
- [ ] 检查数据库连接
- [ ] 验证磁盘空间
- [ ] 通知相关人员
### 2. 备份
# 创建备份
mysqldump -u root -p database_name > backup_$(date +%Y%m%d_%H%M%S).sql
# 验证备份
mysql -u root -p -e "source backup_xxx.sql" test_db
### 3. 执行迁移
# 使用迁移工具
npx prisma migrate deploy
# 或
npm run migration:up
### 4. 验证
- [ ] 检查表结构
- [ ] 验证数据完整性
- [ ] 运行关键查询
- [ ] 检查应用日志
### 5. 回滚准备
如果失败,执行:
# 方式1:使用迁移工具回滚
npx prisma migrate rollback
# 方式2:从备份恢复
mysql -u root -p database_name < backup_xxx.sql
## 迁移脚本模板
-- 迁移:添加用户表
-- 作者:张三
-- 日期:2026-01-15
-- 开始事务
BEGIN;
-- 检查表是否存在
DROP TABLE IF EXISTS users;
-- 创建表
CREATE TABLE users (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
email VARCHAR(255) UNIQUE NOT NULL,
name VARCHAR(100) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB;
-- 创建索引
CREATE INDEX idx_users_email ON users(email);
-- 验证
SELECT COUNT(*) FROM users;
-- 提交事务
COMMIT;
底层原理剖析
2.9.1 Skills 加载机制
发现阶段:
// 伪代码
function discoverSkills(startPath) {
const skills = [];
let currentPath = startPath;
while (currentPath !== root) {
// 检查项目级 Skills
if (exists(join(currentPath, '.opencode/skills'))) {
skills.push(...loadSkillsFromDir(join(currentPath, '.opencode/skills')));
}
// 检查兼容的 Claude Skills
if (exists(join(currentPath, '.claude/skills'))) {
skills.push(...loadSkillsFromDir(join(currentPath, '.claude/skills')));
}
currentPath = parent(currentPath);
}
// 加载全局 Skills
skills.push(...loadSkillsFromDir('~/.config/opencode/skills'));
return skills;
}
解析阶段:
function parseSkill(skillPath) {
const content = readFile(skillPath + '/SKILL.md');
// 解析 YAML frontmatter
const { frontmatter, body } = parseFrontmatter(content);
// 验证必填字段
validateRequiredFields(frontmatter, ['name', 'description']);
// 解析 Markdown
const ast = parseMarkdown(body);
return {
meta: frontmatter,
content: body,
ast: ast,
path: skillPath,
};
}
注入阶段:
function injectSkillToContext(skill, context) {
// 将 Skill 信息添加到 AI 上下文
context.availableSkills.push({
name: skill.meta.name,
description: skill.meta.description,
});
// 如果 Skill 定义了工具,注册工具
if (skill.tools) {
for (const tool of skill.tools) {
context.registerTool(tool);
}
}
}
2.9.2 技能匹配算法
关键词匹配:
function matchSkill(userInput, skills) {
const scores = skills.map((skill) => {
let score = 0;
// 名称匹配
if (userInput.includes(skill.meta.name)) {
score += 10;
}
// 描述匹配
const descriptionWords = skill.meta.description.toLowerCase().split(' ');
const inputWords = userInput.toLowerCase().split(' ');
const commonWords = intersection(descriptionWords, inputWords);
score += commonWords.length * 2;
// 标签匹配
if (skill.meta.tags) {
for (const tag of skill.meta.tags) {
if (userInput.includes(tag)) {
score += 5;
}
}
}
return { skill, score };
});
// 按分数排序
scores.sort((a, b) => b.score - a.score);
// 返回分数最高的
return scores[0]?.score > threshold ? scores[0].skill : null;
}
上下文感知:
function contextualMatch(userInput, skills, context) {
// 根据当前上下文调整匹配权重
const currentFile = context.currentFile;
const projectType = detectProjectType(context.projectRoot);
return skills.map((skill) => {
let score = baseMatchScore(userInput, skill);
// 文件类型匹配
if (skill.fileTypes && skill.fileTypes.includes(currentFile.extension)) {
score += 3;
}
// 项目类型匹配
if (skill.projectTypes && skill.projectTypes.includes(projectType)) {
score += 5;
}
return { skill, score };
});
}
2.9.3 技能执行流程
[用户输入]
↓
[意图识别] ← 使用 LLM 分析用户意图
↓
[技能匹配] ← 根据意图匹配 Skills
↓
[技能加载] ← 读取 SKILL.md 内容
↓
[参数提取] ← 从输入中提取参数
↓
[提示词构建] ← 构建执行提示词
↓
[LLM 执行] ← AI 执行 Skill 指令
↓
[结果输出] ← 返回执行结果
2.9.4 提示词工程
系统提示词片段:
你是一名专业的软件开发助手。你可以使用以下 Skills 来帮助用户:
<available_skills>
{{#each skills}}
<skill>
<name>{{this.name}}</name>
<description>{{this.description}}</description>
</skill>
{{/each}}
</available_skills>
当用户需要执行特定任务时,你可以选择最合适的 Skill 来帮助他们。
使用 Skill 的方式:
1. 分析用户需求
2. 匹配最合适的 Skill
3. 调用 skill({ name: "skill-name" }) 加载 Skill
4. 根据 Skill 的指引执行任务
5. 报告执行结果
约束:
- 只在用户需要时使用 Skill
- 不要主动推荐不相关的 Skill
- 执行过程中可以询问用户确认
任务提示词构建:
function buildSkillPrompt(skill, userInput, context) {
return `
# 当前任务
用户输入:${userInput}
当前上下文:
- 项目类型:${context.projectType}
- 当前文件:${context.currentFile}
- 相关文件:${context.relatedFiles.join(', ')}
# 使用的 Skill
名称:${skill.meta.name}
描述:${skill.meta.description}
## Skill 内容
${skill.content}
# 执行要求
请根据上述 Skill 的指引,帮助用户完成任务。
如果需要更多信息,可以向用户提问。
`;
}
常见问题与解决方案
2.10.1 Skill 不生效
问题:创建了 Skill,但 OpenCode 没发现。
检查清单:
-
路径是否正确
- 必须在
.opencode/skills/<name>/或.claude/skills/<name>/ - 文件名必须是
SKILL.md(全大写)
- 必须在
-
YAML 格式是否正确
- 必须用
---包裹 name和description必须存在- 缩进必须用空格,不能用 Tab
- 必须用
-
名字是否符合规范
- 只能用小写字母、数字和连字符
- 必须和文件夹名完全一致
-
是否重新加载
- 重启 OpenCode
- 或执行
/skill reload
2.10.2 Skill 匹配错误
问题:OpenCode 总是匹配到错误的 Skill。
解决方案:
-
优化 description
- 使用更具体、独特的描述
- 包含关键词
-
使用显式调用
/skill use skill-name
-
调整标签
- 添加更多标签帮助匹配
-
上下文感知
- 在 Skill 中指定
fileTypes或projectTypes
- 在 Skill 中指定
2.10.3 Skill 执行失败
问题:Skill 匹配成功,但执行时报错。
排查步骤:
- 检查 YAML 语法
- 检查 Markdown 格式
- 查看 OpenCode 日志
- 简化 Skill 内容,逐步测试
- 检查依赖的 Skills 是否存在
2.10.4 性能问题
问题:使用 Skill 后,响应变慢。
优化建议:
-
减少上下文大小
- 限制加载的文件数量
- 使用文件摘要而非完整内容
-
使用缓存
- 缓存不变的数据
- 设置合理的缓存时间
-
延迟加载
- 只在需要时加载大型资源
- 使用
lazy: true标记
-
优化提示词
- 减少不必要的说明
- 使用更简洁的语言
相关资源
created: 2026-04-13T14:19:16 (UTC +08:00)
tags: []
source: https://juejin.cn/post/7615279476437221427?from=search-suggest
author: gyx_这个杀手不太冷静
第三章:MCP 集成
什么是 MCP
3.1.1 从一个实际问题说起
想象这样一个场景:你在开发一个电商网站,需要测试购物车功能。测试流程是:
- 打开网站首页
- 搜索商品
- 选择商品加入购物车
- 进入购物车查看
- 修改数量
- 结算
传统的测试方式是:
- 手动点击(费时费力)
- 写自动化测试脚本(需要学习 Selenium/Playwright)
- 找 QA 帮忙(沟通成本高)
如果能让 AI 直接操作浏览器帮你测试,是不是就很方便?
这就是 MCP 要解决的核心问题:让 AI 能操作外部工具和系统。
3.1.2 MCP 的定义
MCP(Model Context Protocol) 是一个开放的协议标准,它定义了 AI 模型如何与外部工具、数据源、服务进行交互。
你可以把 MCP 理解为 AI 世界的"USB 接口":
- 就像 USB 统一了各种外设的连接方式
- MCP 统一了 AI 与各种工具的连接方式
核心特点:
- 标准化:统一的接口定义,不同工具遵循相同规范
- 安全性:细粒度权限控制,可审计可追溯
- 扩展性:支持任意类型的工具和服务
- 灵活性:本地和远程服务都能连接
3.1.3 MCP 能解决什么问题
场景一:浏览器自动化
- 自动测试 Web 应用
- 截图生成文档
- 数据抓取
场景二:数据库操作
- 查询数据
- 生成报表
- 数据迁移
场景三:API 集成
- 调用第三方服务
- 内部系统集成
- 自动化工作流
场景四:文件系统
- 批量文件处理
- 文档转换
- 代码生成
场景五:版本控制
- 自动化 Git 操作
- PR 审查
- 发布管理
3.1.4 MCP 的生态系统
官方 MCP:
- Playwright MCP:浏览器自动化
- GitHub MCP:GitHub 操作
- Filesystem MCP:文件系统访问
- SQLite MCP:SQLite 数据库
社区 MCP:
- Figma MCP:设计稿操作
- Notion MCP:笔记管理
- Slack MCP:消息通知
- AWS MCP:云服务操作
企业 MCP:
- 内部 API MCP
- 数据库 MCP
- 业务系统 MCP
MCP 的核心概念
3.2.1 MCP 架构
┌─────────────────────────────────────────┐
│ OpenCode │
│ ┌──────────────────┐ │
│ │ MCP Client │ │
│ └────────┬─────────┘ │
└──────────────────┼──────────────────────┘
│
┌────────┴────────┐
│ MCP Protocol │
│ (stdio / sse) │
└────────┬────────┘
│
┌───────────┼───────────┐
│ │ │
┌──────┴──────┐ ┌─┴────────┐ ┌┴──────────┐
│ MCP Server │ │ MCP │ │ MCP │
│ (Playwright)│ │ Server │ │ Server │
│ │ │ (GitHub) │ │ (Filesystem)
└─────────────┘ └──────────┘ └───────────┘
MCP Client:OpenCode 内置的 MCP 客户端,负责管理 MCP 连接。
MCP Server:独立的进程或服务,实现 MCP 协议,提供具体功能。
传输层:Client 和 Server 之间的通信方式:
- stdio:标准输入输出(本地进程)
- sse:Server-Sent Events(远程服务)
3.2.2 资源(Resources)
什么是资源:资源是 MCP 中的数据对象,可以是文件、数据库记录、API 响应等。
资源标识:每个资源都有唯一的 URI:
file:///home/user/project/README.md
database://localhost:5432/mydb/users/123
github://repos/owner/repo/issues/456
browser://page/current-url
资源操作:
resources/list:列出可用资源resources/read:读取资源内容resources/subscribe:订阅资源变化
3.2.3 工具(Tools)
什么是工具:工具是 MCP 提供的功能接口,可以被AI调用执行操作。
工具定义:每个工具都有明确的输入输出定义:
{
"name": "browser_navigate",
"description": "导航到指定 URL",
"inputSchema": {
"type": "object",
"properties": {
"url": {
"type": "string",
"description": "目标 URL"
}
},
"required": ["url"]
},
"outputSchema": {
"type": "object",
"properties": {
"success": { "type": "boolean" },
"title": { "type": "string" },
"url": { "type": "string" }
}
}
}
工具调用:
{
"tool": "browser_navigate",
"params": {
"url": "https://example.com"
}
}
3.2.4 提示词(Prompts)
什么是提示词: MCP Server 可以预定义一些提示词模板,供 AI 使用。
示例:
{
"name": "analyze_page",
"description": "分析当前网页的性能和可访问性",
"template": "请分析当前页面的以下方面:\n1. 加载性能\n2. SEO 优化\n3. 可访问性\n4. 最佳实践"
}
MCP 与 Skills 的区别
3.3.1 核心区别
| 维度 | MCP | Skills |
|---|---|---|
| 定位 | 外部工具连接 | 内部知识封装 |
| 作用 | 扩展 AI 能力 | 规范 AI 行为 |
| 实现 | 独立进程/服务 | Markdown 文件 |
| 范围 | 跨项目通用 | 项目/团队特定 |
| 权限 | 需要显式授权 | 默认允许 |
3.3.2 协作关系
MCP 和 Skills 不是竞争关系,而是互补关系:
┌─────────────────────────────────┐
│ 用户请求 │
└──────────────┬──────────────────┘
│
┌──────┴──────┐
│ Skills │ ← 决定"做什么"
└──────┬──────┘
│
┌──────┴──────┐
│ MCP │ ← 决定"用什么做"
└──────┬──────┘
│
┌──────┴──────┐
│ 外部工具 │
└─────────────┘
示例流程:
- 用户说"测试登录功能"
- Skills 系统匹配到"e2e-testing" Skill
- Skill 指导 AI 使用 Playwright MCP
- Playwright MCP 操作浏览器执行测试
3.3.3 选择指南
使用 MCP 的场景:
- 需要操作外部系统(浏览器、数据库、API)
- 需要访问外部数据
- 需要执行特定领域的专业工具
使用 Skills 的场景:
- 定义团队规范和流程* 封装重复性的开发任务
- 沉淀领域知识和最佳实践
组合使用的场景:
- 用 Skills 定义测试流程,用 MCP 执行浏览器测试
- 用 Skills 定义代码规范,用 MCP 操作 Git
- 用 Skills 定义数据迁移流程,用 MCP 操作数据库
配置你的第一个 MCP
3.4.1 查看可用 MCP
# 列出已配置的 MCP
opencode mcp list
# 输出示例:
已配置的 MCP Servers:
1. playwright (enabled)
- 浏览器自动化测试
- 状态: 运行中
2. github (disabled)
- GitHub 操作
- 状态: 未启用
3.4.2 添加 MCP
方式一:交互式添加
opencode mcp add
# 交互提示:
? 选择 MCP 类型:
▸ Playwright (浏览器自动化)
GitHub (GitHub 操作)
Filesystem (文件系统)
SQLite (SQLite 数据库)
Custom (自定义)
? Playwright MCP 配置:
可执行文件路径: /usr/local/bin/npx
启动参数: @anthropic-ai/playwright-mcp-server
? 是否启用: Yes
✓ Playwright MCP 已添加并启动
方式二:配置文件添加
编辑 ~/.config/opencode/mcp.json:
{
"mcpServers": {
"playwright": {
"command": "npx",
"args": ["@anthropic-ai/playwright-mcp-server"],
"env": {
"DISPLAY": ":1"
}
},
"github": {
"command": "npx",
"args": ["-y", "@anthropic-ai/github-mcp-server"],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN}"
}
}
}
}
3.4.3 配置参数详解
基本参数:
| 参数 | 类型 | 说明 | 示例 |
|---|---|---|---|
| command | string | 启动命令 | "npx", "node", "python" |
| args | array | 命令参数 | ["@anthropic-ai/playwright-mcp-server"] |
| env | object | 环境变量 | |
| cwd | string | 工作目录 | "/path/to/project" |
高级参数:
| 参数 | 类型 | 说明 | 示例 |
|---|---|---|---|
| timeout | number | 超时时间(毫秒) | 30000 |
| restartOnError | boolean | 出错时重启 | true |
| allowedTools | array | 允许的工具列表 | ["browser_navigate"] |
| deniedTools | array | 禁止的工具列表 | ["browser_evaluate"] |
3.4.4 测试 MCP
添加 MCP 后,测试是否正常工作:
# 查看 MCP 状态
opencode mcp status playwright
# 输出:
Playwright MCP 状态:
- 状态: 运行中
- PID: 12345
- 运行时间: 5 分钟
- 可用工具: 12 个
- browser_navigate
- browser_click
- browser_screenshot
...
# 测试工具调用
opencode mcp test playwright browser_navigate '{"url": "https://example.com"}'
# 输出:
✓ 工具调用成功
结果: {
"success": true,
"title": "Example Domain",
"url": "https://example.com"
}
3.4.5 在 OpenCode 中使用 MCP
配置好 MCP 后,在对话中直接使用:
> 使用 Playwright 打开百度并搜索"OpenCode"
AI:[调用 playwright MCP]
- browser_navigate: https://www.baidu.com
- browser_click: [搜索框]
- browser_type: OpenCode
- browser_click: [百度一下按钮]
- browser_screenshot: 保存结果
AI:已完成操作,截图保存在 /tmp/baidu_search.png
常用 MCP 详解
3.5.1 Playwright MCP(浏览器自动化)
功能概述:基于 Playwright 框架,提供完整的浏览器自动化能力。
主要工具:
| 工具名 | 功能 | 示例 |
|---|---|---|
| browser_navigate | 导航到 URL | 打开网页 |
| browser_click | 点击元素 | 点击按钮 |
| browser_type | 输入文本 | 填写表单 |
| browser_screenshot | 截图 | 保存页面截图 |
| browser_evaluate | 执行 JS | 获取页面数据 |
| browser_go_back | 后退 | 返回上一页 |
| browser_go_forward | 前进 | 前进一页 |
实战示例:
> 帮我测试登录功能:
> 1. 打开 http://localhost:3000/login
> 2. 填写用户名"admin"、密码"123456"
> 3. 点击登录按钮
> 4. 验证是否跳转到首页
> 5. 截图保存
AI 执行过程:
// 伪代码
async function testLogin() {
// 1. 打开页面
await browser_navigate({ url: 'http://localhost:3000/login' });
// 2. 填写表单
await browser_type({
selector: 'input[name="username"]',
text: 'admin',
});
await browser_type({
selector: 'input[name="password"]',
text: '123456',
});
// 3. 点击登录
await browser_click({ selector: 'button[type="submit"]' });
// 4. 等待跳转并验证
await browser_wait_for_selector({ selector: '.dashboard' });
const url = await browser_evaluate({
script: 'window.location.href',
});
// 5. 截图
await browser_screenshot({ path: '/tmp/login_result.png' });
return { success: url.includes('/dashboard') };
}
3.5.2 GitHub MCP(GitHub 操作)
功能概述:提供 GitHub API 的封装,可以操作仓库、Issue、PR 等。
主要工具:
| 工具名 | 功能 | 示例 |
|---|---|---|
| github_create_issue | 创建 Issue | 提交 bug 报告 |
| github_create_pull_request | 创建 PR | 提交代码变更 |
| github_list_issues | 列出 Issues | 查看待办事项 |
| github_get_file_contents | 获取文件内容 | 读取代码 |
| github_create_or_update_file | 创建/更新文件 | 提交修改 |
实战示例:
> 帮我创建一个 Issue:
> 标题:修复登录页面的响应式布局问题
> 内容:在移动端 375px 宽度下,登录按钮被截断
> 标签:bug, ui
> 分配给张三
AI 执行过程:
await github_create_issue({
owner: 'mycompany',
repo: 'my-project',
title: '修复登录页面的响应式布局问题',
body: `## 问题描述
在移动端 375px 宽度下,登录按钮被截断。
## 复现步骤
1. 打开登录页面
2. 使用 Chrome DevTools 切换到 iPhone SE 视图
3. 可以看到登录按钮右侧被截断
## 期望结果
登录按钮应该完整显示
## 实际结果
登录按钮右侧被截断约 20px
## 环境
- 浏览器:Chrome 120
- 设备:iPhone SE (375x667)`,
labels: ['bug', 'ui'],
assignees: ['zhangsan'],
});
3.5.3 Filesystem MCP(文件系统)
功能概述:提供安全的文件系统访问,可以读取、写入、搜索文件。
主要工具:
| 工具名 | 功能 | 示例 |
|---|---|---|
| read_file | 读取文件 | 查看代码 |
| write_file | 写入文件 | 保存修改 |
| list_directory | 列出目录 | 浏览文件 |
| search_files | 搜索文件 | 查找代码 |
| get_file_info | 获取文件信息 | 查看元数据 |
安全配置:
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@anthropic-ai/filesystem-mcp-server"],
"env": {
"ALLOWED_PATHS": "/home/user/projects:/tmp/workspace"
}
}
}
}
权限控制:
- 只能访问
ALLOWED_PATHS指定的目录 - 默认禁止访问
~/.ssh,~/.config等敏感目录 - 可以配置只读或读写权限
3.5.4 SQLite MCP(SQLite 数据库)
功能概述:提供 SQLite 数据库的查询和操作能力。
主要工具:
| 工具名 | 功能 | 示例 |
|---|---|---|
| sqlite_query | 执行查询 | SELECT * FROM users |
| sqlite_execute | 执行语句 | INSERT, UPDATE, DELETE |
| sqlite_list_tables | 列出表 | 查看数据库结构 |
| sqlite_get_schema | 获取表结构 | 查看字段定义 |
实战示例:
> 查询过去 7 天注册的用户数量,按天分组
AI 执行:
SELECT
date(created_at) as date,
COUNT(*) as user_count
FROM users
WHERE created_at >= date('now', '-7 days')
GROUP BY date(created_at)
ORDER BY date;
开发自定义 MCP
3.6.1 MCP 开发基础
技术栈选择:
| 语言 | 适用场景 | 示例 |
|---|---|---|
| TypeScript/Node.js | 大多数场景 | 官方 MCP 多为此 |
| Python | 数据科学、AI | 机器学习相关 |
| Go | 高性能服务 | 企业级部署 |
| Rust | 系统级工具 | 性能敏感场景 |
官方 SDK:
# TypeScript SDK
npm install @modelcontextprotocol/sdk
# Python SDK
pip install mcp
3.6.2 最小 MCP Server 示例
TypeScript 版本:
// server.ts
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import {
CallToolRequestSchema,
ListToolsRequestSchema,
} from '@modelcontextprotocol/sdk/types.js';
// 创建服务器
const server = new Server(
{
name: 'my-custom-mcp',
version: '1.0.0',
},
{
capabilities: {
tools: {},
},
},
);
// 定义可用工具
const tools = [
{
name: 'hello',
description: 'Say hello to someone',
inputSchema: {
type: 'object',
properties: {
name: {
type: 'string',
description: 'Name of the person to greet',
},
},
required: ['name'],
},
},
];
// 处理工具列表请求
server.setRequestHandler(ListToolsRequestSchema, async () => {
return { tools };
});
// 处理工具调用请求
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
if (name === 'hello') {
const greeting = `Hello, ${args.name}!`;
return {
content: [
{
type: 'text',
text: greeting,
},
],
};
}
throw new Error(`Unknown tool: ${name}`);
});
// 启动服务器
const transport = new StdioServerTransport();
server.connect(transport);
console.error('Custom MCP Server running on stdio');
运行 MCP:
# 编译 TypeScript
npx tsc server.ts
# 添加到 OpenCode 配置
在 mcp.json 中添加:
{
"mcpServers": {
"my-custom": {
"command": "node",
"args": ["/path/to/server.js"]
}
}
}
3.6.3 MCP 协议详解
消息格式:
MCP 使用 JSON-RPC 2.0 协议通信。
请求消息:
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "hello",
"arguments": {
"name": "World"
}
}
}
响应消息:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "Hello, World!"
}
]
}
}
错误消息:
{
"jsonrpc": "2.0",
"id": 1,
"error": {
"code": -32602,
"message": "Invalid params",
"data": {
"details": "Missing required parameter: name"
}
}
}
3.6.4 实战:开发公司内部 API MCP
场景:公司有一套内部 API,想让 AI 能调用这些 API。
Step 1:定义 API 接口
// 公司内部 API 定义
interface InternalAPI {
// 获取用户信息
getUser(userId: string): Promise<User>;
// 创建工单
createTicket(data: CreateTicketRequest): Promise<Ticket>;
// 查询订单
listOrders(params: ListOrdersParams): Promise<Order[]>;
// 发送通知
sendNotification(userId: string, message: string): Promise<void>;
}
Step 2:实现 MCP Server
// internal-api-mcp.ts
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import {
CallToolRequestSchema,
ListToolsRequestSchema,
} from '@modelcontextprotocol/sdk/types.js';
// 公司内部 API 客户端
class InternalAPIClient {
private baseURL: string;
private token: string;
constructor(baseURL: string, token: string) {
this.baseURL = baseURL;
this.token = token;
}
async getUser(userId: string) {
const response = await fetch(`${this.baseURL}/users/${userId}`, {
headers: { Authorization: `Bearer ${this.token}` },
});
return response.json();
}
async createTicket(data: any) {
const response = await fetch(`${this.baseURL}/tickets`, {
method: 'POST',
headers: {
Authorization: `Bearer ${this.token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
});
return response.json();
}
// ... 其他方法
}
// 创建 MCP Server
const apiClient = new InternalAPIClient(
process.env.INTERNAL_API_URL!,
process.env.INTERNAL_API_TOKEN!,
);
const server = new Server(
{ name: 'internal-api', version: '1.0.0' },
{ capabilities: { tools: {} } },
);
// 定义工具
const tools = [
{
name: 'get_user',
description: '获取用户信息',
inputSchema: {
type: 'object',
properties: {
userId: { type: 'string', description: '用户 ID' },
},
required: ['userId'],
},
},
{
name: 'create_ticket',
description: '创建工单',
inputSchema: {
type: 'object',
properties: {
title: { type: 'string', description: '工单标题' },
description: { type: 'string', description: '工单描述' },
priority: {
type: 'string',
enum: ['low', 'medium', 'high'],
description: '优先级',
},
},
required: ['title', 'description'],
},
},
];
server.setRequestHandler(ListToolsRequestSchema, async () => {
return { tools };
});
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
try {
switch (name) {
case 'get_user': {
const user = await apiClient.getUser(args.userId);
return {
content: [{ type: 'text', text: JSON.stringify(user, null, 2) }],
};
}
case 'create_ticket': {
const ticket = await apiClient.createTicket(args);
return {
content: [
{
type: 'text',
text: `工单创建成功!\n工单号: ${ticket.id}\n标题: ${ticket.title}`,
},
],
};
}
default:
throw new Error(`未知工具: ${name}`);
}
} catch (error) {
return {
content: [{ type: 'text', text: `错误: ${error.message}` }],
isError: true,
};
}
});
const transport = new StdioServerTransport();
server.connect(transport);
Step 3:配置到 OpenCode
{
"mcpServers": {
"internal-api": {
"command": "node",
"args": ["/path/to/internal-api-mcp.js"],
"env": {
"INTERNAL_API_URL": "https://api.company.com",
"INTERNAL_API_TOKEN": "${INTERNAL_API_TOKEN}"
}
}
}
}
Step 4:使用
> 查询用户 ID 为 12345 的信息
AI:[调用 internal-api MCP]
- get_user: { userId: "12345" }
AI:用户信息:
- 姓名:张三
- 部门:技术部
- 邮箱:zhangsan@company.com
- 入职时间:2023-06-01
> 为他创建一个工单,标题是"申请显示器",高优先级
AI:[调用 internal-api MCP]
- create_ticket: {
title: "申请显示器",
description: "申请一台 27 寸 4K 显示器",
priority: "high"
}
AI:工单创建成功!
- 工单号:TICKET-2026-001234
- 标题:申请显示器
MCP 安全实践
3.7.1 网络安全
传输加密:
- 远程 MCP 服务必须使用 HTTPS
- 本地 stdio 传输无需加密(进程间通信)
网络隔离:
{
"mcpServers": {
"internal-api": {
"command": "node",
"args": ["internal-mcp.js"],
"network": {
"allowedHosts": ["api.company.com"],
"blockedHosts": ["*"],
"proxy": "http://proxy.company.com:8080"
}
}
}
}
3.7.2 凭证管理
环境变量:
# 不要将凭证硬编码在配置文件中
# 使用环境变量
export GITHUB_TOKEN="ghp_xxxxxxxx"
export DATABASE_PASSWORD="secret"
# 然后在 mcp.json 中引用
{
"mcpServers": {
"github": {
"env": {
"GITHUB_TOKEN": "${GITHUB_TOKEN}"
}
}
}
}
密钥管理服务:
企业环境建议使用专业的密钥管理:
{
"mcpServers": {
"database": {
"command": "node",
"args": ["db-mcp-server.js"],
"env": {
"DB_PASSWORD_CMD": "aws secretsmanager get-secret-value --secret-id db-password"
}
}
}
}
3.7.3 审计日志
启用审计:
{
"mcpServers": {
"database": {
"command": "node",
"args": ["db-mcp-server.js"],
"env": {
"DB_PASSWORD_CMD": "aws secretsmanager get-secret-value --secret-id db-password"
}
}
}
}
日志格式:
{
"mcp": {
"audit": {
"enabled": true,
"logPath": "~/.opencode/logs/mcp-audit.log",
"logLevel": "info" // debug, info, warn, error
}
}
}
实战案例集
3.8.1 案例一:自动化端到端测试
场景:电商网站的完整购物流程测试。
涉及 MCP:
- Playwright MCP:浏览器操作
- SQLite MCP:验证数据库状态
测试流程:
> 执行完整的购物流程测试:
> 1. 访问首页,验证页面加载
> 2. 搜索商品"iPhone",选择第一个结果
> 3. 加入购物车
> 4. 进入购物车,修改数量为 2
> 5. 结算,填写收货信息
> 6. 选择支付方式,完成支付
> 7. 验证订单在数据库中
> 8. 截图每个关键步骤
AI 执行过程:
// 步骤 1: 访问首页
await browser_navigate({ url: 'https://shop.example.com' });
await browser_wait_for_selector({ selector: '.product-list' });
await browser_screenshot({ path: '/tmp/test/step1_home.png' });
// 步骤 2: 搜索商品
await browser_type({
selector: '[data-testid="search-input"]',
text: 'iPhone',
});
await browser_click({ selector: '[data-testid="search-button"]' });
await browser_wait_for_selector({ selector: '.search-results' });
await browser_click({ selector: '.product-item:first-child' });
await browser_screenshot({ path: '/tmp/test/step2_product.png' });
// 步骤 3: 加入购物车
await browser_click({ selector: '[data-testid="add-to-cart"]' });
await browser_wait_for_selector({ selector: '.cart-notification' });
// 步骤 4: 进入购物车
await browser_click({ selector: '[data-testid="cart-icon"]' });
await browser_clear({ selector: '[data-testid="quantity-input"]' });
await browser_type({ selector: '[data-testid="quantity-input"]', text: '2' });
await browser_click({ selector: '[data-testid="update-cart"]' });
await browser_screenshot({ path: '/tmp/test/step4_cart.png' });
// 步骤 5: 结算
await browser_click({ selector: '[data-testid="checkout"]' });
await browser_type({ selector: '#name', text: '张三' });
await browser_type({ selector: '#phone', text: '13800138000' });
await browser_type({ selector: '#address', text: '北京市朝阳区xxx' });
await browser_screenshot({ path: '/tmp/test/step5_checkout.png' });
// 步骤 6: 支付
await browser_click({ selector: '[data-testid="payment-alipay"]' });
await browser_click({ selector: '[data-testid="place-order"]' });
await browser_wait_for_selector({ selector: '.order-success' });
await browser_screenshot({ path: '/tmp/test/step6_payment.png' });
// 步骤 7: 验证数据库
const orderResult = await sqlite_query({
query: `
SELECT * FROM orders
WHERE customer_name = '张三'
ORDER BY created_at DESC
LIMIT 1
`,
});
// 验证
assert(orderResult.quantity === 2);
assert(orderResult.status === 'paid');
3.8.2 案例二:自动化文档生成
场景:根据代码自动生成 API 文档。
涉及 MCP:
- Filesystem MCP:读取代码文件
- GitHub MCP:发布到 GitHub Pages
工作流程:
> 帮我生成 API 文档:
> 1. 扫描 src/api 目录下的所有接口文件
> 2. 解析 JSDoc 注释
> 3. 生成 Markdown 格式的 API 文档
> 4. 创建 GitHub Pages 分支
> 5. 部署文档
3.8.3 案例三:智能运维助手
场景:自动排查服务器问题。
涉及 MCP:
- SSH MCP:连接服务器
- Filesystem MCP:读取日志
- Slack MCP:发送通知
工作流程:
> 服务器报警了,帮我排查一下:
> 1. 连接到生产服务器
> 2. 查看最近 1 小时的错误日志
> 3. 检查 CPU、内存、磁盘使用情况
> 4. 如果发现问题,尝试自动修复
> 5. 发送报告到 Slack #ops 频道
底层原理剖析
3.9.1 MCP 协议栈
┌─────────────────────────────────┐
│ 应用层 (AI) │
│ 调用工具、处理结果 │
├─────────────────────────────────┤
│ MCP 协议层 │
│ JSON-RPC、资源定义、工具定义 │
├─────────────────────────────────┤
│ 传输层 │
│ stdio / SSE / WebSocket │
├─────────────────────────────────┤
│ 实现层 (MCP Server) │
│ Playwright / GitHub / Custom │
└─────────────────────────────────┘
3.9.2 连接管理
stdio 传输:
OpenCode (MCP Client) MCP Server
| |
|--- fork() --------------->|
| |
|<-- stdout (JSON-RPC) -----|
|--- stdin (JSON-RPC) ----->|
| |
特点:
- 适用于本地 MCP Server
- 进程间通信,安全可靠
- 自动管理进程生命周期
SSE 传输:
OpenCode (MCP Client) MCP Server (Remote)
| |
|--- HTTP GET /events ----->|
|<-- SSE stream ------------|
| |
|--- HTTP POST /invoke ---->|
|<-- JSON response ---------|
| |
特点:
- 适用于远程 MCP Server
- 支持跨网络通信
- 需要处理连接稳定性
3.9.3 工具发现与调用
发现流程:
// 1. Client 发送 tools/list 请求
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list"
}
// 2. Server 返回可用工具列表
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"tools": [
{
"name": "browser_navigate",
"description": "Navigate to a URL",
"inputSchema": { ... }
}
]
}
}
// 3. Client 缓存工具列表
// 4. AI 调用时,Client 发送 tools/call
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "browser_navigate",
"arguments": {
"url": "https://example.com"
}
}
}
3.9.4 错误处理机制
错误分类:
- 连接错误:无法连接到 MCP Server
- 协议错误:JSON-RPC 格式错误
- 工具错误:工具不存在或参数错误
- 执行错误:工具执行失败
错误处理策略:
// Client 端错误处理
try {
const result = await callTool(server, toolName, params);
} catch (error) {
if (error.code === -32000) {
// 服务器错误,尝试重启
await restartServer(server);
} else if (error.code === -32602) {
// 参数错误,修正参数重试
const correctedParams = fixParams(params, error.data);
return await callTool(server, toolName, correctedParams);
} else {
// 其他错误,向上抛出
throw error;
}
}
故障排查与优化
3.10.1 常见问题
问题 1:MCP Server 启动失败
症状:
Error: Failed to start MCP server 'playwright'
Error: spawn npx ENOENT
解决:
- 检查 Node.js 是否安装:
node --version - 检查 npx 是否可用:
npx --version - 安装 MCP Server:
npm install -g @anthropic-ai/playwright-mcp-server
问题 2:工具调用超时
症状:
Error: Tool call timeout after 30000ms
解决:
{
"mcpServers": {
"playwright": {
"command": "npx",
"args": ["@anthropic-ai/playwright-mcp-server"],
"timeout": 60000 // 增加超时时间
}
}
}
问题 3:权限拒绝
症状:
Error: Access denied to /etc/passwd
解决:
- 检查
ALLOWED_PATHS配置 - 确认操作权限
- 使用 sudo(不推荐)
3.10.2 性能优化
优化 1:连接池
对于频繁使用的 MCP,保持长连接:
{
"mcpServers": {
"database": {
"command": "node",
"args": ["db-mcp.js"],
"keepAlive": true, // 保持连接
"maxIdleTime": 300000 // 5 分钟空闲超时
}
}
}
优化 2:并行调用
// 并行调用多个工具
const results = await Promise.all([
callTool(server1, 'tool1', params1),
callTool(server2, 'tool2', params2),
callTool(server3, 'tool3', params3),
]);
优化 3:缓存结果
// 缓存工具列表
const toolCache = new Map();
async function getTools(server) {
if (toolCache.has(server)) {
return toolCache.get(server);
}
const tools = await listTools(server);
toolCache.set(server, tools);
return tools;
}
3.10.3 调试技巧
启用调试日志:
# 设置环境变量
export MCP_DEBUG=true
export MCP_LOG_LEVEL=debug
# 启动 OpenCode
opencode --agent
使用 MCP Inspector:
# 安装 Inspector
npm install -g @anthropic-ai/mcp-inspector
# 测试 MCP Server
mcp-inspector --server "npx @anthropic-ai/playwright-mcp-server"
查看原始通信:
# 使用 socat 查看 stdio 通信
socat -v EXEC:"npx @anthropic-ai/playwright-mcp-server" STDIO
相关资源
- MCP 官方文档:modelcontextprotocol.io
第四章:企业级功能
为什么需要企业级功能
4.1.1 个人使用 vs 企业使用
个人开发者使用 OpenCode:
- 安装简单,一行命令搞定
- 配置灵活,想怎么配就怎么配
- 数据存在本地,自己负责
- 出问题自己解决
企业使用 OpenCode:
| 维度 | 个人 | 企业 |
|---|---|---|
| 用户数 | 1 人 | 10-10000+ 人 |
| 安全要求 | 低 | 高(合规、审计) |
| 稳定性 | 能跑就行 | SLA 99.9%+ |
| 支持需求 | 社区支持 | 7x24 技术支持 |
| 成本敏感度 | 低 | 高(预算控制) |
| 集成需求 | 少 | 多(SSO、内部系统) |
4.1.2 企业面临的挑战
安全挑战:
- 代码是核心资产,不能泄露
- AI 会接触到敏感信息(密钥、密码)
- 需要满足 SOC2、ISO27001 等认证
管理挑战:
- 员工入职/离职,权限如何管理?
- 不同团队有不同的使用规范
- 如何统一配置和升级?
合规挑战:
- 金融/医疗行业有严格的合规要求
- 数据不能出境
- 操作需要留痕审计
成本挑战:
- AI 调用费用怎么控制?
- 如何评估 ROI?
- 预算如何分配?
4.1.3 企业级功能的价值
安全价值:
- 数据隔离,保护代码资产
- 细粒度权限控制
- 完整的审计日志
效率价值:
- 统一配置,快速 onboarding
- 共享 Skills,沉淀团队经验
- 自动化流程,减少重复工作
管理价值:
- 集中管控,降低风险
- 可观测性,了解使用情况
- 成本可视化,优化支出
企业级功能概览
4.2.1 功能矩阵
| 功能模块 | 社区版 | 企业版 | 说明 |
|---|---|---|---|
| 基础 AI 功能 | ✅ | ✅ | 代码生成、分析等 |
| Agent 模式 | ✅ | ✅ | 自动化执行 |
| Skills 系统 | ✅ | ✅ | 自定义技能 |
| MCP 集成 | ✅ | ✅ | 外部工具连接 |
| SSO 集成 | ❌ | ✅ | SAML/OIDC |
| 审计日志 | ❌ | ✅ | 完整操作记录 |
| RBAC 权限 | ❌ | ✅ | 角色权限控制 |
| 私有部署 | ❌ | ✅ | 本地/私有云部署 |
| SLA 保障 | ❌ | ✅ | 99.9% 可用性 |
| 7x24 支持 | ❌ | ✅ | 专属技术支持 |
| 成本管控 | ❌ | ✅ | 配额和预算 |
| 高级分析 | ❌ | ✅ | 使用分析和洞察 |
4.2.2 企业版架构
┌─────────────────────────────────────────────────────────┐
│ 企业级 OpenCode │
├─────────────────────────────────────────────────────────┤
│ 管理控制台 │ 开发者门户 │ 运维监控 │ 计费系统 │
├─────────────────────────────────────────────────────────┤
│ API 网关 (Kong/AWS API Gateway) │
│ 认证中心 (SSO) │ 限流 │ 负载均衡 │ 日志 │
├─────────────────────────────────────────────────────────┤
│ AI 服务集群 │ Skills 服务 │ MCP 服务 │ 存储服务 │
│ - Claude │ - Skill Store │ - Registry │ - PostgreSQL
│ - GPT-4 │ - Skill Exec │ - Server │ - Redis
│ - 本地模型 │ │ │ - S3/MinIO│
├─────────────────────────────────────────────────────────┤
│ 基础设施层 │
│ Kubernetes │ Docker │ 虚拟机 │ 裸金属 │
└─────────────────────────────────────────────────────────┘
安全与合规
4.3.1 数据安全
数据隔离策略:
-
逻辑隔离
- 每个团队/项目独立命名空间
- 基于角色的资源访问控制
- 数据加密存储(AES-256)
-
物理隔离(可选)
- 独立的数据库实例
- 独立的 AI 服务集群
- 网络层面的隔离
数据生命周期:
数据产生 → 传输加密(TLS 1.3) → 存储加密 → 使用脱敏 → 定期清理 → 安全销毁
敏感信息处理:
// 自动检测和脱敏
const sensitivePatterns = [
{ type: 'api_key', regex: /sk-[a-zA-Z0-9]{48}/ },
{ type: 'password', regex: /password["\s]*[=:]["\s]*[^\s]+/i },
{ type: 'token', regex: /eyJ[a-zA-Z0-9_-]*\.eyJ[a-zA-Z0-9_-]*/ },
{ type: 'credit_card', regex: /\d{4}[\s-]?\d{4}[\s-]?\d{4}[\s-]?\d{4}/ },
];
function sanitizeData(data) {
let sanitized = data;
for (const pattern of sensitivePatterns) {
sanitized = sanitized.replace(
pattern.regex,
`[${pattern.type.toUpperCase()}]`,
);
}
return sanitized;
}
4.3.2 访问控制
RBAC(基于角色的访问控制)模型:
roles:
admin:
description: 系统管理员
permissions:
- '*:*' # 所有权限
team_lead:
description: 团队负责人
permissions:
- 'user:read'
- 'user:write'
- 'project:*'
- 'skill:read'
- 'skill:write'
- 'mcp:read'
- 'mcp:write'
- 'audit:read'
developer:
description: 普通开发者
permissions:
- 'user:read_self'
- 'project:read'
- 'project:write' # 仅限自己参与的项目
- 'skill:read'
- 'mcp:read'
- 'mcp:use'
viewer:
description: 只读用户
permissions:
- 'project:read'
- 'skill:read'
权限控制粒度:
| 粒度 | 示例 | 说明 |
|---|---|---|
| 功能级 | mcp:use |
能否使用 MCP |
| 资源级 | project:write:project-123 |
能否修改特定项目 |
| 操作级 | skill:delete |
能否删除 Skill |
| 字段级 | user:read:email |
能否查看用户邮箱 |
实现示例:
// 权限检查中间件
function checkPermission(requiredPermission: string) {
return async (req: Request, res: Response, next: NextFunction) => {
const user = req.user;
const resource = req.params.resourceId;
// 展开角色权限
const userPermissions = await expandRoles(user.roles);
// 检查权限
const hasPermission = userPermissions.some((perm) => {
// 完全匹配
if (perm === requiredPermission) return true;
// 通配符匹配
if (perm === '*:*') return true;
// 资源级匹配
const [permResource, permAction, permId] = perm.split(':');
const [reqResource, reqAction, reqId] = requiredPermission.split(':');
if (permResource === reqResource && permAction === '*') return true;
if (permResource === reqResource && permAction === reqAction) {
if (!permId || permId === reqId || permId === resource) return true;
}
return false;
});
if (!hasPermission) {
return res.status(403).json({ error: 'Permission denied' });
}
next();
};
}
// 使用
app.delete(
'/api/projects/:id',
checkPermission('project:delete'),
deleteProjectHandler,
);
4.3.3 合规认证
SOC 2 Type II:
- 安全性(Security)
- 可用性(Availability)
- 处理完整性(Processing Integrity)
- 保密性(Confidentiality)
- 隐私性(Privacy)
ISO 27001:
信息安全管理体系认证,包括:
- 安全策略
- 资产管理
- 访问控制
- 密码学
- 物理安全
- 操作安全
- 通信安全
- 系统开发
- 供应商关系
- 事件管理
- 业务连续性
- 合规性
GDPR(欧盟通用数据保护条例):
- 数据主体权利(访问、更正、删除、可携带)
- 数据处理合法性基础
- 数据保护影响评估
- 数据泄露通知(72 小时内)
等保 2.0(中国):
- 物理安全
- 网络安全
- 主机安全
- 应用安全
- 数据安全
团队协作与权限管理
4.4.1 组织架构集成
LDAP/AD 集成:
# 配置 LDAP 同步
ldap:
enabled: true
url: ldap://ldap.company.com:389
bindDN: cn=admin,dc=company,dc=com
bindPassword: ${LDAP_PASSWORD}
baseDN: dc=company,dc=com
userSearch:
base: ou=users,dc=company,dc=com
filter: (objectClass=person)
mapping:
username: uid
email: mail
name: cn
department: department
groupSearch:
base: ou=groups,dc=company,dc=com
filter: (objectClass=groupOfNames)
mapping:
name: cn
members: member
组织架构同步:
公司
├── 技术部
│ ├── 前端组
│ ├── 后端组
│ └── 测试组
├── 产品部
│ ├── 产品设计
│ └── 用户研究
└── 运营部
├── 内容运营
└── 用户运营
同步到 OpenCode:
interface Organization {
id: string;
name: string;
type: 'company' | 'department' | 'team' | 'group';
parentId?: string;
members: Member[];
roles: Role[];
}
// 自动映射组织架构到权限组
const orgMapping = {
技术部: ['developer', 'devops'],
'技术部/前端组': ['frontend', 'developer'],
产品部: ['product', 'designer'],
};
4.4.2 团队配置管理
统一配置仓库:
opencode-enterprise-config/
├── README.md
├── global/
│ ├── settings.yaml # 全局设置
│ ├── roles.yaml # 角色定义
│ └── permissions.yaml # 权限定义
├── teams/
│ ├── frontend/
│ │ ├── settings.yaml # 前端团队设置
│ │ ├── skills/ # 团队 Skills
│ │ └── mcp.yaml # 团队 MCP 配置
│ ├── backend/
│ │ └── ...
│ └── mobile/
│ └── ...
├── policies/
│ ├── security.yaml # 安全策略
│ ├── usage.yaml # 使用策略
│ └── cost.yaml # 成本控制策略
└── scripts/
├── install.sh # 安装脚本
└── sync.sh # 同步脚本
配置继承机制:
# global/settings.yaml
opencode:
version: "0.1.40"
ai:
defaultModel: "claude-3-opus"
fallbackModel: "gpt-4"
maxTokens: 4000
temperature: 0.7
agent:
mode: "step_by_step"
maxSteps: 50
requireApproval: true
security:
allowedMCPs:
- filesystem
- github
blockedTools:
- "filesystem:write:/etc/*"
- "filesystem:delete"
# teams/frontend/settings.yaml
# 继承 global 配置,可以覆盖
opencode:
ai:
defaultModel: "claude-3-haiku" # 前端用轻量级模型
skills:
required:
- frontend-code-review
- react-component-gen
mcp:
allowed:
- playwright # 前端需要浏览器测试
配置分发:
#!/bin/bash
# scripts/sync.sh
# 同步配置到所有团队成员
for user in $(get_team_members); do
echo "Syncing config for $user..."
# 获取用户角色和团队
roles=$(get_user_roles $user)
team=$(get_user_team $user)
# 合并配置
opencode config merge \
--global global/settings.yaml \
--team teams/$team/settings.yaml \
--user ~/.opencode/config.yaml \
--output /tmp/config-$user.yaml
# 分发到用户机器
scp /tmp/config-$user.yaml $user@$user-machine:~/.opencode/config.yaml
# 通知用户
notify_user $user "配置已更新,请重启 OpenCode"
done
4.4.3 共享资源管理
Skills 共享仓库:
# 企业级 Skills 仓库
enterprise-skills/
├── README.md
├── .github/
│ └── workflows/
│ ├── ci.yaml # 自动化测试
│ └── publish.yaml # 自动发布
├── skills/
│ ├── company-standards/ # 公司规范
│ ├── security-review/ # 安全审查
│ ├── performance-check/ # 性能检查
│ └── deployment-guide/ # 部署指南
├── templates/
│ ├── react-component/
│ ├── vue-component/
│ └── api-endpoint/
└── docs/
├── contribution-guide.md
└── best-practices.md
MCP 共享注册中心:
# enterprise-mcp-registry.yaml
mcp_servers:
company-internal:
- name: jira
description: 内部 Jira 系统
endpoint: https://mcp.company.com/jira
auth: sso
- name: gitlab
description: 内部 GitLab
endpoint: https://mcp.company.com/gitlab
auth: sso
- name: confluence
description: 知识库系统
endpoint: https://mcp.company.com/confluence
auth: sso
approved-third-party:
- name: playwright
description: 浏览器自动化
source: anthropic
verified: true
- name: github
description: GitHub 集成
source: anthropic
verified: true
部署方案
4.5.1 部署模式对比
| 模式 | 适用场景 | 优点 | 缺点 | 成本 |
|---|---|---|---|---|
| SaaS 托管 | 小团队/快速启动 | 零运维、即时可用 | 数据在云端、依赖网络 | 按用量计费 |
| 私有云 | 中型企业 | 数据自主、灵活配置 | 需要运维团队 | 中等 |
| 本地部署 | 大型企业/强合规 | 完全控制、离线可用 | 高运维成本 | 高 |
| 混合部署 | 特殊需求 | 灵活组合 | 架构复杂 | 视组合而定 |
4.5.2 SaaS 托管方案
适用场景:
- 10-100 人团队
- 无特殊合规要求
- 希望快速上线
- 预算有限
架构:
┌─────────────────────────────────────────┐
│ OpenCode Cloud │
│ (opencode.ai Enterprise) │
│ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ Team A │ │ Team B │ │ Team C │ │
│ │ (隔离) │ │ (隔离) │ │ (隔离) │ │
│ └─────────┘ └─────────┘ └─────────┘ │
│ │
│ Shared: AI Cluster │ MCP Registry │
└─────────────────────────────────────────┘
↑
Internet
↑
┌──────┴──────┐
│ 企业防火墙 │
└──────┬──────┘
↑
┌──────┴──────┐
│ 开发者电脑 │
└─────────────┘
配置:
# 企业账号配置
enterprise:
tenant_id: 'company-abc-123'
plan: 'business' # starter/professional/business/enterprise
billing:
payment_method: 'corporate_card'
billing_email: 'billing@company.com'
security:
sso:
provider: 'okta'
metadata_url: 'https://company.okta.com/app/xxx/sso/saml/metadata'
data_residency: 'us-west' # 数据存储区域
encryption: 'customer_managed' # 客户管理密钥
成本估算(100 人团队):
| 项目 | 月费用 | 说明 |
|---|---|---|
| 基础订阅 | $2,000 | Business Plan |
| AI 调用 | $1,500 | 约 500K tokens/月 |
| 存储 | $200 | 100GB |
| 支持 | $500 | 商业支持 |
| 总计 | $4,200/月 | 约 $50K/年 |
4.5.3 私有云部署方案
适用场景:
- 100-1000 人团队
- 需要数据主权
- 有运维能力
- 中等预算
技术栈:
# 基础设施
infrastructure:
platform: kubernetes
provider: aws # aws/azure/gcp/私有云
compute:
ai_cluster:
instance_type: g4dn.xlarge # GPU 实例
count: 5
app_servers:
instance_type: c5.2xlarge
count: 3
database:
type: rds
engine: postgres
instance_class: db.r5.xlarge
storage:
object: s3
block: ebs
networking:
vpc: company-vpc
subnets:
- private-a
- private-b
- private-c
load_balancer: alb
部署配置:
# helm values.yaml
opencode:
image:
repository: registry.company.com/opencode/enterprise
tag: v2.0.0
replicas: 3
resources:
requests:
cpu: 2000m
memory: 4Gi
limits:
cpu: 4000m
memory: 8Gi
env:
DATABASE_URL: 'postgresql://opencode:${DB_PASSWORD}@postgres:5432/opencode'
REDIS_URL: 'redis://redis:6379'
AI_PROVIDER: 'anthropic'
ANTHROPIC_API_KEY: '${ANTHROPIC_API_KEY}'
ingress:
enabled: true
host: opencode.company.com
tls:
enabled: true
secretName: opencode-tls
persistence:
enabled: true
storageClass: ebs-gp3
size: 100Gi
部署步骤:
# 1. 创建命名空间
kubectl create namespace opencode
# 2. 添加 Helm 仓库
helm repo add opencode https://charts.opencode.ai
helm repo update
# 3. 安装
helm install opencode opencode/enterprise \
--namespace opencode \
--values values.yaml \
--set global.postgresql.auth.password=$(openssl rand -base64 32)
# 4. 验证
kubectl get pods -n opencode
kubectl get svc -n opencode
# 5. 配置 DNS
# 将 opencode.company.com 指向 Load Balancer IP
4.5.4 本地部署方案
适用场景:
- 1000+ 人团队
- 强合规要求(金融、政府、医疗)
- 完全离线环境
- 充足预算
物理架构:
┌─────────────────────────────────────────────────────────┐
│ 企业数据中心 │
│ ┌─────────────────────────────────────────────────┐ │
│ │ 核心交换区 │ │
│ │ (防火墙 │ IDS/IPS │ DLP │ VPN 网关) │ │
│ └──────────────────┬──────────────────────────────┘ │
│ │ │
│ ┌──────────────────┴──────────────────────────────┐ │
│ │ OpenCode 集群 │ │
│ │ │ │
│ │ ┌──────────────┐ ┌──────────────┐ │ │
│ │ │ 管理节点 x3 │ │ AI 节点 x5 │ │ │
│ │ │ (K8s Master) │ │ (GPU Server) │ │ │
│ │ └──────────────┘ └──────────────┘ │ │
│ │ │ │
│ │ ┌──────────────┐ ┌──────────────┐ │ │
│ │ │ 数据库 x3 │ │ 存储阵列 │ │ │
│ │ │ (PostgreSQL) │ │ (SAN/NAS) │ │ │
│ │ └──────────────┘ └──────────────┘ │ │
│ │ │ │
│ └─────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
硬件配置:
| 角色 | 数量 | 配置 | 用途 |
|---|---|---|---|
| 管理节点 | 3 | 32C/128GB/2TB SSD | K8s 控制平面 |
| AI 节点 | 5 | 64C/256GB/A100x2 | AI 推理服务 |
| 数据库 | 3 | 32C/128GB/4TB SSD | PostgreSQL 集群 |
| 存储 | 1 | 24 盘位/192TB | 对象存储 |
| 网络 | 2 | 100Gbps 交换机 | 核心网络 |
软件栈:
# 软件版本
software_stack:
os: ubuntu_22_04_lts
kubernetes: v1.28
container_runtime: containerd
opencode:
version: v2.0.0
license: enterprise-perpetual
ai_models:
- name: claude-3-opus
source: anthropic_license
deployment: local_api_server
- name: codellama-34b
source: huggingface
deployment: vllm
middleware:
database: postgresql_15
cache: redis_7
message_queue: kafka_3
search: elasticsearch_8
离线安装:
# 1. 在有网络的机器上准备离线包
./scripts/prepare-offline-package.sh \
--version 2.0.0 \
--output /mnt/usb/opencode-offline/
# 2. 将离线包复制到内网
# 使用加密 U 盘或专用文件传输系统
# 3. 在内网环境安装
cd /opt/opencode-offline/
./install.sh \
--mode offline \
--config local-config.yaml
# 4. 验证安装
opencode doctor
监控与审计
4.6.1 可观测性体系
监控维度:
┌─────────────────────────────────────────┐
│ 可观测性三大支柱 │
├─────────────┬─────────────┬─────────────┤
│ Metrics │ Logs │ Traces │
│ (指标) │ (日志) │ (链路追踪) │
├─────────────┼─────────────┼─────────────┤
│ • AI 调用 │ • 操作日志 │ • 请求链路 │
│ • 响应时间 │ • 错误日志 │ • 服务依赖 │
│ • 资源使用 │ • 审计日志 │ • 性能瓶颈 │
│ • 错误率 │ • 安全日志 │ • 异常定位 │
└─────────────┴─────────────┴─────────────┘
监控指标体系:
metrics:
ai_service:
- name: opencode_ai_requests_total
type: counter
labels: [model, operation, status]
- name: opencode_ai_latency_seconds
type: histogram
buckets: [0.1, 0.5, 1, 2, 5, 10]
- name: opencode_ai_tokens_total
type: counter
labels: [model, type] # type: input/output
application:
- name: opencode_api_requests_total
type: counter
labels: [endpoint, method, status]
- name: opencode_active_users
type: gauge
- name: opencode_skills_executed_total
type: counter
labels: [skill_name, status]
infrastructure:
- name: opencode_cpu_usage_percent
type: gauge
- name: opencode_memory_usage_bytes
type: gauge
- name: opencode_disk_usage_percent
type: gauge
监控大盘:
// Grafana Dashboard 配置
dashboard:
title: "OpenCode Enterprise Overview"
panels:
- title: "AI 调用量"
type: graph
queries:
- sum(rate(opencode_ai_requests_total[5m])) by (model)
- title: "响应时间 P99"
type: graph
queries:
- histogram_quantile(0.99,
sum(rate(opencode_ai_latency_seconds_bucket[5m])) by (le))
- title: "Token 使用量"
type: graph
queries:
- sum(opencode_ai_tokens_total) by (model, type)
- title: "活跃用户"
type: stat
queries:
- opencode_active_users
- title: "错误率"
type: graph
queries:
- sum(rate(opencode_ai_requests_total{status="error"}[5m]))
/ sum(rate(opencode_ai_requests_total[5m]))
4.6.2 审计日志
日志格式:
{
"timestamp": "2026-01-15T10:30:00.000Z",
"event_id": "evt-1234567890",
"event_type": "skill_execution",
"severity": "info",
"actor": {
"type": "user",
"id": "user-001",
"name": "张三",
"email": "zhangsan@company.com",
"department": "技术部/前端组",
"ip_address": "192.168.1.100"
},
"resource": {
"type": "skill",
"id": "code-review",
"path": ".opencode/skills/code-review"
},
"action": {
"name": "execute",
"parameters": {
"file_path": "src/components/Button.tsx",
"check_items": ["style", "performance", "security"]
},
"result": "success",
"duration_ms": 2500
},
"context": {
"project_id": "proj-123",
"project_name": "电商平台",
"session_id": "sess-abc-123",
"mcp_servers": ["playwright"],
"ai_model": "claude-3-opus"
},
"metadata": {
"user_agent": "OpenCode/2.0.0",
"version": "2.0.0",
"region": "cn-north-1"
}
}
审计查询:
-- 查询某用户的所有操作
SELECT * FROM audit_logs
WHERE actor_id = 'user-001'
AND timestamp >= '2026-01-01'
ORDER BY timestamp DESC;
-- 查询敏感操作
SELECT * FROM audit_logs
WHERE event_type IN ('mcp_execution', 'file_write')
AND severity = 'warning'
AND timestamp >= NOW() - INTERVAL '24 hours';
-- 统计各团队使用情况
SELECT
actor_department,
COUNT(*) as operation_count,
COUNT(DISTINCT actor_id) as unique_users,
SUM(CASE WHEN action_result = 'success' THEN 1 ELSE 0 END) as success_count
FROM audit_logs
WHERE timestamp >= '2026-01-01'
GROUP BY actor_department
ORDER BY operation_count DESC;
审计告警:
alerts:
- name: suspicious_file_access
condition: |
event_type = 'file_read'
AND resource_path LIKE '%/etc/passwd%'
severity: critical
notification:
- security@company.com
- slack:#security-alerts
- name: high_cost_usage
condition: |
event_type = 'ai_request'
AND tokens_total > 100000
AND timestamp > NOW() - INTERVAL '1 hour'
severity: warning
notification:
- cost-control@company.com
- name: privilege_escalation_attempt
condition: |
event_type = 'permission_denied'
AND COUNT(*) > 5
GROUP BY actor_id
severity: critical
notification:
- security@company.com
4.6.3 成本分析
成本模型:
总成本 = 基础设施成本 + AI 调用成本 + 人力成本 + 其他
基础设施成本 = 计算资源 + 存储 + 网络
AI 调用成本 = Token 数量 × 单价
人力成本 = 运维人员 + 培训成本
其他 = 许可证 + 支持费用
成本分摊:
# 成本分摊策略
cost_allocation:
method: 'usage_based' # usage_based / equal / custom
dimensions:
- name: team
weight: 0.4
source: actor.department
- name: project
weight: 0.3
source: context.project_id
- name: user
weight: 0.2
source: actor.id
- name: model
weight: 0.1
source: context.ai_model
成本优化建议:
-
模型选择优化
- 简单任务使用轻量级模型(Claude Haiku)
- 复杂任务使用强力模型(Claude Opus)
- 建立模型选择指南
-
缓存策略
- 缓存常用查询结果
- 复用已生成的代码片段
- 避免重复 AI 调用
-
配额管理
- 设置团队配额上限
- 设置个人配额上限
- 超额预警和审批流程
-
用量分析
- 识别低效使用模式
- 优化 Skills 减少不必要的调用
- 培训用户高效使用
集成与扩展
4.7.1 CI/CD 集成
GitHub Actions 集成:
# .github/workflows/opencode-review.yaml
name: AI Code Review
on:
pull_request:
types: [opened, synchronize]
jobs:
ai-review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup OpenCode
uses: opencode-ai/setup-opencode@v1
with:
version: '2.0.0'
api-key: ${{ secrets.OPENCODE_API_KEY }}
- name: Run AI Code Review
run: |
opencode review \
--skill company-code-review \
--diff ${{ github.event.pull_request.diff_url }} \
--output review-result.md
- name: Post Review Comment
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const review = fs.readFileSync('review-result.md', 'utf8');
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: review
});
GitLab CI 集成:
# .gitlab-ci.yml
ai_review:
stage: test
image: opencode/enterprise-cli:latest
variables:
OPENCODE_API_KEY: $OPENCODE_API_KEY
script:
- opencode review --skill company-code-review --merge-request
only:
- merge_requests
4.7.2 IDE 集成
VS Code 扩展:
// OpenCode VS Code Extension
export function activate(context: vscode.ExtensionContext) {
// 注册命令
let disposable = vscode.commands.registerCommand(
'opencode.reviewFile',
async () => {
const editor = vscode.window.activeTextEditor;
if (!editor) return;
const document = editor.document;
const code = document.getText();
// 调用 OpenCode API
const result = await opencode.review({
code: code,
language: document.languageId,
skill: 'company-code-review',
});
// 显示审查结果
const panel = vscode.window.createWebviewPanel(
'opencodeReview',
'Code Review',
vscode.ViewColumn.Beside,
{},
);
panel.webview.html = generateReviewHtml(result);
},
);
context.subscriptions.push(disposable);
}
JetBrains 插件:
// OpenCode IntelliJ Plugin
class OpenCodeReviewAction : AnAction("Review with OpenCode") {
override fun actionPerformed(e: AnActionEvent) {
val editor = e.getData(CommonDataKeys.EDITOR) ?: return
val document = editor.document
val code = document.text
// 调用 OpenCode
val review = OpenCodeClient.review(code)
// 显示结果
ReviewToolWindow.showReview(review)
}
}
4.7.3 内部系统集成
Jira 集成:
// OpenCode Jira MCP Server
class JiraMCPServer {
async createTicket(data: CreateTicketRequest) {
const issue = await jira.addNewIssue({
fields: {
project: { key: data.project },
summary: data.title,
description: data.description,
issuetype: { name: data.type },
priority: { name: data.priority },
assignee: { name: data.assignee },
},
});
return {
id: issue.key,
url: `https://jira.company.com/browse/${issue.key}`,
};
}
async getTicket(ticketId: string) {
const issue = await jira.findIssue(ticketId);
return {
id: issue.key,
title: issue.fields.summary,
status: issue.fields.status.name,
assignee: issue.fields.assignee?.displayName,
description: issue.fields.description,
};
}
}
Confluence 集成:
// 自动生成文档并发布到 Confluence
async function generateAndPublishDocs() {
// 1. 分析代码变更
const changes = await analyzeCodeChanges();
// 2. 生成文档
const docs = await opencode.generate({
task: 'generate_api_documentation',
context: changes,
skill: 'api-doc-generation',
});
// 3. 发布到 Confluence
await confluence.createPage({
space: 'DEV',
title: `API Changes - ${new Date().toISOString()}`,
content: docs.markdown,
parentId: '12345',
});
}
迁移与升级
4.8.1 从社区版迁移到企业版
迁移步骤:
# 1. 备份社区版数据
opencode export --all --output backup-$(date +%Y%m%d).zip
# 2. 部署企业版
# 按照企业版部署文档进行部署
# 3. 导入数据
opencode-enterprise import backup-20260115.zip
# 4. 验证迁移
opencode-enterprise verify
# 5. 切换 DNS/配置
# 更新用户客户端指向企业版
数据迁移清单:
- 用户配置
- Skills 定义
- MCP 配置
- 历史会话
- 自定义模板
- 权限设置
4.8.2 版本升级策略
蓝绿部署:
# 零停机升级
strategy: blue-green
steps: 1. 部署新版本(绿环境) - 独立部署 v2.1.0 - 运行冒烟测试
2. 切换流量 - 将 5% 流量切到绿环境 - 监控错误率和性能 - 确认无误后全量切换
3. 保留蓝环境 - 保留 24 小时 - 紧急情况下快速回滚
4. 清理 - 确认稳定后删除蓝环境
数据库迁移:
-- 版本化数据库迁移
-- migrations/V2.1.0__add_audit_table.sql
CREATE TABLE audit_logs (
id BIGSERIAL PRIMARY KEY,
timestamp TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
event_type VARCHAR(100) NOT NULL,
actor_id VARCHAR(100),
actor_name VARCHAR(200),
resource_type VARCHAR(100),
resource_id VARCHAR(100),
action VARCHAR(100),
result VARCHAR(50),
metadata JSONB,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
CREATE INDEX idx_audit_timestamp ON audit_logs(timestamp);
CREATE INDEX idx_audit_actor ON audit_logs(actor_id);
CREATE INDEX idx_audit_event ON audit_logs(event_type);
成本与 ROI 分析
4.9.1 成本构成
直接成本:
| 项目 | 年度成本 | 占比 |
|---|---|---|
| AI 调用费用 | $60,000 | 40% |
| 基础设施 | $30,000 | 20% |
| 许可证费用 | $25,000 | 17% |
| 运维人力 | $20,000 | 13% |
| 培训支持 | $10,000 | 7% |
| 其他 | $5,000 | 3% |
| 总计 | $150,000 | 100% |
间接成本:
- 迁移成本:$10,000(一次性)
- 学习成本:$15,000(前 6 个月效率损失)
4.9.2 收益分析
效率提升:
| 指标 | 提升 | 年度价值 |
|---|---|---|
| 编码效率 | +30% | $180,000 |
| Bug 减少 | -25% | $75,000 |
| 文档生成 | 自动化 | $30,000 |
| 代码审查 | 加速 50% | $45,000 |
| 总计 | $330,000 |
ROI 计算:
ROI = (收益 - 成本) / 成本 × 100%
= (330,000 - 150,000) / 150,000 × 100%
= 120%
投资回收期 = 12 个月 × 成本 / 年度收益
= 12 × 150,000 / 330,000
= 5.5 个月
4.9.3 风险评估
| 风险 | 可能性 | 影响 | 应对措施 |
|---|---|---|---|
| AI 质量不稳定 | 中 | 高 | 建立人工复核机制 |
| 数据泄露 | 低 | 极高 | 严格的安全措施 |
| 员工抵触 | 中 | 中 | 培训和激励 |
| 供应商锁定 | 低 | 中 | 保持 Skills 独立性 |
实施路线图
4.10.1 阶段规划
Phase 1: 试点阶段(1-2 个月)
目标:验证价值,建立信心
- 选择 1-2 个试点团队(10-20 人)
- 部署 SaaS 版或小型私有部署
- 创建基础 Skills(代码审查、提交规范)
- 培训试点团队
- 收集反馈,优化配置
Phase 2: 推广阶段(3-6 个月)
目标:扩展到更多团队
- 扩展到 5-10 个团队(50-100 人)
- 建立企业级部署
- 完善权限和审计
- 开发更多内部 Skills
- 集成 CI/CD 和内部系统
Phase 3: 规模化阶段(6-12 个月)
目标:全公司推广
- 全公司部署(100+ 人)
- 建立 Skills 市场
- 完善监控和成本管控
- 建立内部支持团队
- 持续优化和迭代
4.10.2 成功指标
技术指标:
- AI 调用成功率 > 95%
- 平均响应时间 < 3s
- 系统可用性 > 99.9%
业务指标:
- 开发者满意度 > 80%
- 代码审查时间减少 50%
- Bug 率降低 25%
- 新员工上手时间减少 30%
成本指标:
- AI 调用成本控制在预算内
- 基础设施利用率 > 70%
- ROI > 100%
第五章:最佳实践
高效提示词编写
5.1.1 提示词的核心原则
提示词(Prompt)是你与 AI 沟通的桥梁。好的提示词能让 AI 准确理解你的意图,给出高质量的结果。
原则一:具体明确
❌ 差的提示词:
帮我优化代码
✅ 好的提示词:
优化 src/utils/dataProcessor.ts 中的 processData 函数:
- 输入数据量可能达到 10 万条记录
- 当前实现使用双重循环,时间复杂度 O(n²)
- 目标是降到 O(n log n) 或更低
- 保持现有接口不变
- 添加适当的类型定义
原则二:提供上下文
❌ 差的提示词:
这个报错怎么解决?
[截图]
✅ 好的提示词:
在运行测试时遇到错误:
错误信息:
TypeError: Cannot read property 'map' of undefined at UserList.render (src/components/UserList.tsx:45)
相关代码(src/components/UserList.tsx:40-50):
const UserList: React.FC = () => {
const { users } = useUsers();
return (
<div>
{users.map(user => ( // 第 45 行报错
<UserCard key={user.id} user={user} />
))}
</div>
);
};
useUsers hook(src/hooks/useUsers.ts):
export const useUsers = () => {
const [users, setUsers] = useState<User[]>();
useEffect(() => {
fetchUsers().then((data) => setUsers(data));
}, []);
return { users };
};
问题:组件渲染时 users 还未加载完成,为 undefined。
请给出修复方案,要求:
1. 处理加载状态
2. 处理错误状态
3. 保持 TypeScript 类型安全
原则三:结构化输出
明确要求 AI 的输出格式:
请分析这段代码的性能问题,按以下格式输出:
## 问题列表
1. [问题描述] - [严重程度:高/中/低]
- 位置:[文件:行号]
- 影响:[性能/内存/可读性]
- 建议:[具体优化方案]
## 优化优先级
按影响程度和实现难度排序
## 代码示例
提供优化后的代码片段
原则四:迭代优化
不要期望一次提示就得到完美结果。采用迭代方式:
第一轮:基本功能实现
第二轮:添加错误处理
第三轮:优化性能
第四轮:完善文档
5.1.2 提示词模板库
模板一:代码审查请求
请审查以下代码,关注:
1. 代码规范和风格
2. 潜在 bug 和安全问题
3. 性能优化机会
4. 可维护性和可读性
文件:{{file_path}}
代码:{{code}}
请以清单形式列出所有问题,按严重程度排序。对于每个问题,提供:
- 问题描述
- 具体位置
- 修复建议
- 代码示例
模板二:功能开发请求
请实现以下功能:
## 需求描述
{{feature_description}}
## 技术要求
- 技术栈:{{tech_stack}}
- 接口定义:{{api_spec}}
- 数据模型:{{data_model}}
## 验收标准
{{acceptance_criteria}}
## 约束条件
- 不要修改现有接口
- 保持向后兼容
- 添加单元测试
请按以下步骤执行:
1. 分析需求,提出实现方案
2. 等我确认后再开始编码
3. 实现功能
4. 编写测试
5. 生成文档
模板三:Bug 修复请求
请修复以下 Bug:
## Bug 描述
{{bug_description}}
## 复现步骤
1. {{step_1}}
2. {{step_2}}
3. {{step_3}}
## 期望行为
{{expected_behavior}}
## 实际行为
{{actual_behavior}}
## 环境信息
- 浏览器:{{browser}}
- 版本:{{version}}
- 相关代码:{{file_path}}
## 错误日志
{{error_log}}
请:
1. 分析根本原因
2. 提供修复方案(先不执行)
3. 等我确认后执行修复
4. 验证修复结果
5.1.3 上下文管理技巧
引用文件:
# 引用单个文件
@src/components/Button.tsx 帮我审查这个组件
# 引用多个文件
@src/utils/helpers.ts @src/types/index.ts 分析类型定义
# 引用特定函数
@formatDate 函数帮我优化性能
# 引用代码行范围
@src/App.tsx:100-150 这段逻辑有问题
保持上下文连贯:
# 第一次请求
> 分析 src/api/users.ts 的接口设计
# AI 分析完成...
# 第二次请求(基于之前的分析)
> 基于刚才的分析,帮我重构这些接口
> 要求保持 RESTful 规范
# AI 理解上下文,基于之前的分析进行重构
清理上下文:
当对话太长,上下文混乱时:
> /context clear
上下文已清理。之前的对话历史将不再影响后续回答。
> /context summary
当前上下文摘要:
- 正在处理:用户管理系统重构
- 相关文件:src/api/users.ts, src/services/userService.ts
- 上次操作:接口分析
工作流设计
5.2.1 日常开发工作流
标准开发流程:
┌─────────────────────────────────────────────────────────┐
│ 开发流程(AI 辅助) │
├─────────────────────────────────────────────────────────┤
│ 1. 需求理解 │
│ ↓ 使用对话模式讨论需求 │
│ - 与 AI 讨论业务逻辑 │
│ - 确定技术方案 │
│ - 识别潜在风险 │
│ │
│ 2. 技术设计 │
│ ↓ 生成设计文档 │
│ - 让 AI 帮助设计架构 │
│ - 生成接口定义 │
│ - 定义数据模型 │
│ │
│ 3. 编码实现 │
│ ↓ 切换 Agent 模式 │
│ - 生成代码框架 │
│ - 实现业务逻辑 │
│ - 编写单元测试 │
│ │
│ 4. 代码审查 │
│ ↓ 使用 Skills │
│ - 自动代码审查 │
│ - 人工复核 │
│ - 修复问题 │
│ │
│ 5. 测试验证 │
│ ↓ 运行测试套件 │
│ - 单元测试 │
│ - 集成测试 │
│ - AI 辅助调试 │
│ │
│ 6. 文档更新 │
│ ↓ 自动生成文档 │
│ - API 文档 │
│ - 更新 README │
│ - 添加变更日志 │
└─────────────────────────────────────────────────────────┘
详细示例:
# ========== 步骤 1: 需求理解 ==========
> 我要实现一个用户注册功能,需求如下:
> 1. 支持邮箱注册
> 2. 需要邮箱验证
> 3. 密码要求:8位以上,包含大小写字母和数字
> 4. 防止机器人注册
>
> 请帮我分析这个需求,包括:
> - 涉及哪些模块
> - 可能的技术方案
> - 需要注意的安全问题
AI:分析完成,建议...
# ========== 步骤 2: 技术设计 ==========
> 基于刚才的分析,帮我设计技术方案:
> 1. 生成 API 接口文档(OpenAPI 格式)
> 2. 设计数据库表结构
> 3. 设计前端表单组件
AI:生成设计文档...
# ========== 步骤 3: 编码实现 ==========
> /agent on
> 请按照设计文档实现用户注册功能:
> 1. 先实现后端 API(Node.js + Express)
> 2. 再实现前端表单(React + TypeScript)
> 3. 最后实现邮箱验证逻辑
>
> 每完成一个模块告诉我,我确认后再继续
AI:[实现后端 API]
用户:确认,继续
AI:[实现前端表单]
用户:确认,继续
AI:[实现邮箱验证]
用户:确认,完成
# ========== 步骤 4: 代码审查 ==========
> /skill use code-review
> 审查刚才实现的用户注册功能
AI:[自动审查报告]
# ========== 步骤 5: 测试验证 ==========
> 运行所有测试,确保通过
AI:✓ 所有测试通过
# ========== 步骤 6: 文档更新 ==========
> 更新相关文档:
> 1. 更新 API 文档
> 2. 更新 README 的使用说明
> 3. 添加变更日志
AI:文档已更新
5.2.2 代码审查工作流
自动化审查流程:
# 1. 提交代码前自动审查
pre-commit:
- id: opencode-review
name: AI Code Review
entry: opencode review --skill company-code-review --staged
language: system
pass_filenames: false
# 2. PR 创建时自动审查
.on:
pull_request:
types: [opened, synchronize]
jobs:
ai-review:
steps:
- uses: opencode-ai/review-action@v1
with:
skill: company-code-review
notify: slack://#code-review
# 3. 人工复核
# 审查报告会作为 PR 评论
# Reviewer 人工确认后合并
审查清单模板:
# .opencode/review-checklist.yaml
checklist:
code_quality:
- name: 代码风格
description: 是否符合团队代码规范
severity: warning
- name: 命名规范
description: 变量、函数、类命名是否清晰
severity: warning
functionality:
- name: 边界处理
description: 是否处理了边界情况
severity: error
- name: 错误处理
description: 是否有完善的错误处理
severity: error
performance:
- name: 算法复杂度
description: 时间/空间复杂度是否合理
severity: warning
- name: 资源泄漏
description: 是否有内存/连接泄漏
severity: error
security:
- name: 输入验证
description: 用户输入是否经过验证
severity: error
- name: 敏感信息
description: 是否泄露了敏感信息
severity: critical
5.2.3 重构工作流
安全重构流程:
# 1. 准备阶段
# 1.1 确保代码已提交
git add .
git commit -m "chore: backup before refactoring"
# 1.2 创建重构分支
git checkout -b refactor/extract-service
# 2. 分析阶段
> 分析 src/modules/order 模块,识别需要重构的代码:
> 1. 找出重复代码
> 2. 找出过长函数
> 3. 找出圈复杂度过高的代码
> 4. 生成重构建议报告
AI:[生成分析报告]
# 3. 规划阶段
> 基于分析报告,制定重构计划:
> 1. 按优先级排序重构项
> 2. 制定每步的验证方案
> 3. 估算工作量
AI:[生成重构计划]
用户:确认计划,开始执行
# 4. 执行阶段(分步进行)
> /agent on
> /agent config mode step_by_step
> 执行重构计划第 1 步:提取重复代码到工具函数
AI:[执行中...]
AI:第 1 步完成,修改了:
- src/modules/order/utils.ts: 新增 3 个工具函数
- src/modules/order/service.ts: 删除重复代码,调用工具函数
用户:查看 git diff,确认无误
用户:运行测试,全部通过
用户:继续下一步
AI:[执行第 2 步...]
...
# 5. 验证阶段
> 运行完整测试套件,确保没有破坏功能
AI:✓ 所有测试通过
✓ 代码覆盖率未下降
✓ 没有新的 ESLint 错误
# 6. 完成阶段
> 生成重构总结报告
git add .
git commit -m "refactor(order): 重构订单模块
- 提取 3 个重复工具函数
- 拆分 2 个过长的处理函数
- 降低平均圈复杂度从 15 到 8
- 所有测试通过
Refactoring guided by OpenCode AI"
git push origin refactor/extract-service
# 7. 创建 PR,请求审查
性能优化
5.3.1 AI 调用优化
减少 Token 消耗:
# ❌ 低效:提供整个大文件
> 分析 src/App.tsx 的问题
[AI 读取 500 行代码,消耗大量 token]
# ✅ 高效:只提供相关部分
> 分析 src/App.tsx 第 100-150 行的 useEffect
[AI 只读取 50 行,token 消耗减少 90%]
使用缓存:
> /context cache enable
# 缓存常用查询结果
> 记住这个项目的架构:MVC + Repository + Service
[AI 缓存架构信息,后续询问时直接使用]
# 后续对话
> 基于我们项目的架构,新功能应该放在哪一层?
[AI 使用缓存的架构信息,无需重复解释]
批量处理:
# ❌ 低效:逐个文件处理
> 审查 src/components/Button.tsx
> 审查 src/components/Input.tsx
> 审查 src/components/Modal.tsx
# ✅ 高效:批量处理
> 审查 src/components/*.tsx,生成汇总报告
[AI 一次性处理所有文件,复用上下文]
5.3.2 响应速度优化
模型选择策略:
| 任务类型 | 推荐模型 | 说明 |
|---|---|---|
| 简单问答 | Claude Haiku | 响应快,成本低 |
| 代码生成 | Claude Sonnet | 平衡速度和质量 |
| 复杂分析 | Claude Opus | 质量最高,较慢 |
| 快速审查 | GPT-3.5 Turbo | 响应极快 |
| 深度重构 | GPT-4 | 质量最高 |
并发执行:
# 并行执行独立任务
> 同时执行:
> 1. 生成组件代码
> 2. 生成测试代码
> 3. 生成 Storybook 文档
[AI 并行执行 3 个任务,总时间减少 60%]
预热机制:
# 对于企业部署,保持 AI 连接池
# 避免冷启动延迟
opencode serve --keep-alive --min-instances 2
5.3.3 资源使用优化
上下文窗口管理:
{
"context": {
"max_tokens": 4000,
"compression": true,
"summary_threshold": 2000,
"eviction_policy": "lru"
}
}
文件加载策略:
# 只加载必要的文件
> 分析时只加载:
> - src/api/users.ts
> - src/services/userService.ts
> - src/types/user.ts
> 不加载其他无关文件
# 使用文件摘要
> 加载 src/large-file.ts 的摘要(前 50 行 + 函数列表)
安全实践
5.4.1 代码安全
敏感信息保护:
# 自动检测敏感信息
> /security scan
扫描中...
⚠️ 发现潜在敏感信息:
- src/config.ts:15 - 疑似 API Key
- src/utils/auth.ts:23 - 硬编码密码
建议:
1. 使用环境变量
2. 添加到 .gitignore
3. 轮换已泄露的凭证
安全编码规范:
# .opencode/skills/secure-coding/SKILL.md
security_rules:
input_validation:
- rule: '所有用户输入必须验证'
severity: error
- rule: '防止 SQL 注入,使用参数化查询'
severity: error
- rule: '防止 XSS,转义输出内容'
severity: error
authentication:
- rule: '密码必须哈希存储(bcrypt/Argon2)'
severity: error
- rule: '使用 JWT 时设置过期时间'
severity: warning
authorization:
- rule: '所有接口必须验证权限'
severity: error
- rule: '实施最小权限原则'
severity: warning
5.4.2 数据安全
本地数据处理:
# 优先使用本地模型处理敏感数据
opencode config ai.provider local
opencode config ai.model codellama-34b
# 敏感数据脱敏后再发送给云端 AI
> /security mask
已启用数据脱敏:
- API Keys: sk-***...***
- 邮箱: ***@***.com
- 手机号: 138****8888
审计日志:
# 记录所有 AI 操作
opencode config audit.enabled true
opencode config audit.level verbose
# 查看审计日志
opencode audit log --user zhangsan --since 2026-01-01
5.4.3 权限控制
最小权限原则:
{
"permissions": {
"read": ["src/**", "docs/**"],
"write": ["src/components/**", "src/utils/**"],
"deny": ["src/config/secrets/**", ".env*", "**/node_modules/**"]
}
}
操作确认:
# 危险操作需要确认
> /agent config confirm_destructive true
> 删除 src/old-module(危险操作)
⚠️ 即将删除 src/old-module 目录及其所有内容
确认执行吗?(y/N):
团队协作规范
5.5.1 代码规范
提交信息规范:
# 使用 Skill 规范提交信息
> /skill use conventional-commit
> 我要提交刚才的用户注册功能
AI:生成提交信息:
git commit -m "feat(auth): 实现用户注册功能
- 添加邮箱注册接口
- 实现邮箱验证流程
- 添加密码强度校验
- 集成 reCAPTCHA 防机器人
Closes #123"
代码风格统一:
# .opencode/config.yaml
code_style:
formatter: prettier
linter: eslint
rules:
printWidth: 100
tabWidth: 2
useTabs: false
semi: true
singleQuote: true
5.5.2 知识共享
Skills 共享规范:
skills/
├── README.md # Skills 说明文档
├── CONTRIBUTING.md # 贡献指南
├── CODE_OF_CONDUCT.md # 行为准则
└── skills/
├── skill-name/
│ ├── SKILL.md # 技能定义
│ ├── CHANGELOG.md # 变更日志
│ └── examples/ # 使用示例
文档模板:
# Skill: {{name}}
## 功能描述
{{description}}
## 维护者
- 主维护者:{{primary_maintainer}}
- 备份维护者:{{backup_maintainer}}
## 使用场景
{{usage_scenarios}}
## 版本历史
| 版本 | 日期 | 变更内容 | 作者 |
| ----- | ---------- | -------- | ---------- |
| 1.0.0 | 2026-01-15 | 初始版本 | {{author}} |
## 反馈渠道
- Issue: {{issue_url}}
- 讨论: {{discussion_url}}
5.5.3 培训与推广
新人入职培训:
# 第 1 天:基础使用
> 欢迎使用 OpenCode!让我带你快速上手:
> 1. 基础对话功能
> 2. Agent 模式使用
> 3. 常用 Skills 介绍
# 第 3 天:进阶功能
> 今天学习进阶功能:
> 1. 自定义 Skills
> 2. MCP 集成
> 3. 工作流设计
# 第 7 天:实践项目
> 完成一个小项目,实际应用所学
定期分享会:
- 每周:使用技巧分享
- 每月:最佳实践案例
- 每季度:效率提升复盘
常见问题解决方案
5.6.1 AI 理解错误
症状:AI 没有理解需求,给出错误的结果
解决方案:
# 1. 补充更多上下文
> 补充说明:
> - 这个函数用于处理用户上传的 Excel 文件
> - 文件可能包含 1-10 万行数据
> - 需要处理中文表头
> - 输出格式是 JSON
# 2. 提供示例
> 输入示例:
> ```csv
> 姓名,年龄,城市
> 张三,25,北京
> 李四,30,上海
> ```
>
> 期望输出:
> ```json
> [{"name": "张三", "age": 25, "city": "北京"}, ...]
> ```
# 3. 分步说明
> 请按以下步骤实现:
> 步骤 1:读取文件
> 步骤 2:解析表头
> 步骤 3:转换数据
> 步骤 4:输出 JSON
5.6.2 代码质量问题
症状:AI 生成的代码有 bug 或不符合规范
解决方案:
# 1. 添加约束条件
> 生成代码时请注意:
> - 必须处理所有错误情况
> - 使用 TypeScript 严格模式
> - 添加完整的类型定义
> - 遵循团队 ESLint 规则
# 2. 要求测试
> 生成代码后,同时生成:
> 1. 单元测试(覆盖所有分支)
> 2. 集成测试
> 3. 运行测试并确保通过
# 3. 代码审查
> /skill use code-review
> 审查刚才生成的代码
# 4. 迭代改进
> 基于审查意见,修复以下问题:
> 1. 缺少错误处理
> 2. 变量命名不清晰
> 3. 重复代码需要提取
5.6.3 性能问题
症状:AI 响应慢,或者生成的代码性能差
解决方案:
# 优化 AI 响应
> /context clear # 清理上下文
> /model set haiku # 切换到更快的模型
# 优化生成代码
> 优化这段代码的性能:
> - 当前时间复杂度 O(n²)
> - 目标是 O(n log n)
> - 数据量:100万条记录
> - 使用空间换时间策略
5.6.4 安全问题
症状:担心代码安全或数据泄露
解决方案:
# 1. 启用安全检查
> /security enable
# 2. 扫描代码
> /security scan src/
# 3. 使用本地模型
> /model use local
# 4. 脱敏处理
> /security mask enable
进阶技巧
5.7.1 自定义指令
创建快捷指令:
# ~/.opencode/aliases.yaml
aliases:
review: skill use code-review
test: agent run "运行所有测试"
fix: agent run "修复所有 ESLint 错误"
doc: skill use generate-docs
commit: skill use conventional-commit
使用:
> /review src/components/Button.tsx
> /test
> /fix
> /doc
> /commit
5.7.2 管道操作
链式调用:
# 生成代码 → 审查 → 测试
> /agent run "生成用户管理功能" \
| /skill use code-review \
| /agent run "修复审查发现的问题" \
| /agent run "运行测试"
5.7.3 条件执行
智能工作流:
> /workflow run deploy
检查条件:
- 代码审查通过?是
- 所有测试通过?是
- 安全检查通过?是
执行部署:
✓ 构建成功
✓ 测试通过
✓ 部署到生产
✓ 健康检查通过
部署完成!
5.7.4 批量操作
多项目处理:
# 为所有项目添加相同的配置
> /batch run --projects "proj1,proj2,proj3" \
"添加 .editorconfig 文件"
# 批量审查
> /batch review --pattern "src/**/*.ts" \
--output report.md
案例研究
5.8.1 案例:前端团队效率提升
背景:
- 团队规模:15 人
- 技术栈:React + TypeScript
- 痛点:代码审查耗时、重复性工作多
实施过程:
-
Week 1-2:工具部署
- 部署 OpenCode 企业版
- 配置团队 Skills
- 培训团队成员
-
Week 3-4:流程优化
- 建立代码审查 Skill
- 配置 CI/CD 集成
- 创建组件生成模板
-
Week 5-8:全面使用
- 所有成员日常使用
- 收集反馈优化
- 沉淀更多 Skills
效果:
| 指标 | 实施前 | 实施后 | 提升 |
|---|---|---|---|
| 代码审查时间 | 2 小时/PR | 30 分钟/PR | 75% ↓ |
| 组件开发时间 | 4 小时 | 1.5 小时 | 62% ↓ |
| Bug 率 | 5% | 2% | 60% ↓ |
| 文档覆盖率 | 40% | 85% | 112% ↑ |
5.8.2 案例:遗留系统重构
背景:
- 10 年老系统,代码债务严重
- 技术栈:jQuery + PHP
- 目标:迁移到 React + Node.js
实施策略:
-
分析阶段(1 个月)
- AI 分析现有代码结构
- 识别核心业务逻辑
- 制定迁移计划
-
重构阶段(3 个月)
- 使用 Agent 模式批量重构
- 逐步替换旧模块
- 保持功能兼容
-
验证阶段(1 个月)
- 自动化测试覆盖
- 灰度发布
- 监控和回滚
成果:
- 代码量减少 40%
- 性能提升 3 倍
- 维护成本降低 60%

浙公网安备 33010602011771号