从opencode源码到skills的编写建议
更新 part 状态为 "completed"调用包装的 tool.execute()tools (包含 skill 工具)包装工具为 ai.tool()包含 tool-call 事件。继续 streamText。返回包装后的 tools。检查 doom loop。
·
为什么要从opencode源码入手
- OpenCode 作为开源 Coding Agent 的代表,直观展示了业界主流的 Skills 开发规范与调用逻辑。分析其源码,是理解以 ClaudeCode 为代表的新一代 Agent 核心工作流的最短路径之一,也方便我们编写高效准确的skills提高工作效率。
https://github.com/anomalyco/opencode
opencode中skills相关架构和流程
- 三层架构
- 客户端/界面层(Client/UI Layer):负责用户交互界面
- 智能体内部组件(Agent Internal Components):OpenCode核心功能模块
- 外部LLM服务(External LLM Service):对接第三方大语言模型
- 执行流程
- 技能发现与注册:识别并注册可用功能
- LLM决策调用:由大语言模型选择合适技能执行
- 内容延续生成:基于技能输出结果进行后续内容创作
Skills 流程技术难点和编写建议
| 技术难点 | 难点原因 | 解决方案(代码位置) | Skills 编写建议 |
|---|---|---|---|
| 1. 工具与 LLM 的双向通信协议 | LLM 需要理解工具能力,Agent 需要理解 LLM 意图,需要标准化数据格式 | 采用 Vercel AI SDK 标准协议,使用 JSON Schema 定义参数@session/prompt.ts:696-725 |
• 在 description 中明确说明输入输出格式 • 使用结构化输出(Markdown/JSON),避免自然语言式模糊描述 |
| 2. 多源技能文件的扫描与去重 | 支持多目录(.opencode/skill/, .claude/skills/),向上遍历目录树,同名冲突 | 使用 Filesystem.up() 向上查找,Record 自动覆盖,记录警告不阻止@skill/skill.ts:78-123 |
• 使用唯一且描述性的 name(如 myproject-api-design)• 在 description 中说明适用范围,避免过于通用的命名 |
| 3. YAML Frontmatter 解析容错 | YAML 语法严格,冒号/缩进/引号易出错,需要友好错误提示 | 预处理自动修复(冒号转块标量),使用 gray-matter 解析,自定义错误类型@config/markdown.ts:17-66 |
• 避免在 frontmatter 值中使用冒号 • 复杂值使用引号包裹,测试 frontmatter 解析 |
| 4. 权限控制的灵活性与安全性 | 需要细粒度控制(allow/deny/ask),不同 agent 不同规则,初始化过滤 vs 运行时检查 | 双层检查(初始化过滤+执行验证),支持通配符,默认 “*”: “allow”@tool/skill.ts:12-18, 59-64 |
• 在 skill 开头说明需要的权限 • 明确说明副作用,提供只读版本的 skill |
| 5. 流式处理中的状态管理 | LLM 流式输出时机不确定,需跟踪多个并发工具调用,状态转换和错误恢复 | 使用 Map 跟踪每个工具调用,清晰状态机(pending→running→completed/error)@session/processor.ts:32-44, 126-221 |
• 将复杂任务拆分为多个步骤 • 在每个步骤后提供检查点,提供明确的完成标志 |
| 6. Doom Loop 检测与防护 | LLM 可能重复调用相同工具,需要不影响正常重试的检测,何时介入询问 | 阈值 3 次,比较工具名和参数完全一致性,触发后请求用户确认@session/processor.ts:146-168 |
• 避免模糊的成功条件,提供明确的标准 • 限制重试次数,包含明确的退出条件 |
| 7. 工具执行的插件化扩展 | 需要支持插件在执行前后插入逻辑,统一日志和错误处理,不影响核心功能 | 包装模式添加 before/after 钩子,标准化接口,支持异步插件@session/prompt.ts:700-724 |
• 使用标准 Markdown 结构 • 在关键位置添加标记(如 <!-- plugin:before -->) |
Skills编写样例
核心设计原则
| 原则 | 说明 |
|---|---|
| 明确性优于灵活性 | 具体指令比灵活描述更有效(如 “ESLint 无错误” 而非 “代码质量好”) |
| 结构化优于自然语言 | 使用标准格式(Markdown、JSON Schema)而非散文式描述 |
| 防御性设计 | 考虑失败场景、边界条件、退出机制 |
| 双层验证 | 初始化过滤 + 运行时检查,提高安全性和用户体验 |
编写实践示例
---
name: api-endpoint-implementation
description: Implement REST API endpoint with validation and tests. Returns file paths and test results.
permissions:
read: allow
write: allow
bash: allow
max_retries: 2
---
# API Endpoint Implementation
## Permissions Required
- Read: API design docs
- Write: Create route and test files
- Bash: Run test suite
## Steps
### Step 1: Create Route Handler ✓
- [ ] Create file in `src/routes/`
- [ ] Add input validation with Zod
**Checkpoint**: File created and compiles
### Step 2: Write Tests ✓
- [ ] Create test file
- [ ] Write unit tests
**Checkpoint**: Tests written
### Step 3: Validate ✓
- [ ] Run test suite
- [ ] Check coverage > 80%
**Checkpoint**: All tests pass
## Success Criteria (MUST meet ALL)
- [ ] Route handler implemented
- [ ] Input validation added
- [ ] Tests pass with >80% coverage
- [ ] No ESLint errors
## Failure Handling
If tests fail after 2 attempts:
1. STOP retrying
2. Report error details
3. Suggest manual review
## Output Format
Returns structured Markdown with:
- File paths created
- Test results summary
- Coverage report
更多推荐

所有评论(0)