返回

oh-my-claudecode 教程 7:Skills 系统 - 自定义技能与自动学习

Skills 系统让你可以从成功的问题解决方案中提取可复用的技能,自动注入到未来的会话中。本文详解技能创建、自动学习和技能管理。

教程概述

Skills 系统是 oh-my-claudecode 的知识积累机制。它可以从你成功的调试经验中提取可复用的模式,保存为技能文件,然后在未来的会话中自动激活。

你将学到

  • ✅ Skills 系统架构
  • ✅ 创建自定义技能
  • /learner 自动提取模式
  • ✅ 技能自动注入机制
  • ✅ 技能管理命令

Skills 系统概述

为什么需要 Skills?

flowchart LR
    A[问题解决] --> B[经验积累]
    B --> C[下次遇到类似问题]
    C --> D{有技能?}
    D -->|是| E[自动应用技能]
    D -->|否| F[重新探索]
    F --> A

    E --> G[快速解决]

    style E fill:#e8f5e9
    style F fill:#ffebee

技能的价值

场景 无技能 有技能
调试相同问题 重新探索 30 分钟 自动应用 2 分钟
团队知识共享 口头传授 技能文件分发
新项目启动 从零学习 导入技能库

Skills 架构

技能存储位置

flowchart TD
    A[Skills 存储位置] --> B[项目级 .omc/skills/]
    A --> C[用户级 ~/.omc/skills/]

    B --> D[团队共享]
    C --> E[个人复用]

    D --> F[版本控制]
    E --> G[跨项目使用]

    style B fill:#e8f5e9
    style C fill:#fff3e0

优先级规则

位置 优先级 用途
.omc/skills/ 项目特定技能,覆盖用户级
~/.omc/skills/ 用户通用技能,跨项目共享

技能文件结构

# .omc/skills/fix-proxy-crash.md

---
name: Fix Proxy Crash
description: aiohttp proxy crashes on ClientDisconnectedError
triggers: ["proxy", "aiohttp", "disconnected"]
source: extracted
---

## Problem

When using aiohttp as a reverse proxy, the server crashes on ClientDisconnectedError
when clients disconnect unexpectedly.

## Solution

Wrap the handler in a try/except block:

\`\`\`python
from aiohttp import ClientDisconnectedError

async def proxy_handler(request):
    try:
        # Your proxy logic here
        response = await fetch_upstream(request)
        return response
    except ClientDisconnectedError:
        # Client disconnected, just log and return
        logger.info("Client disconnected during proxy")
        return Response(status=499)  # Client Closed Request
\`\`\`

## Why This Works

The ClientDisconnectedError is raised when the client closes the connection
before we finish sending the response. By catching this exception, we prevent
the server from crashing and return a clean 499 status code.

## Related

- aiohttp documentation on exception handling
- Nginx 499 status code convention

创建自定义技能

手动创建

步骤 1:创建技能文件

mkdir -p .omc/skills
touch .omc/skills/my-skill.md

步骤 2:编写技能内容

# .omc/skills/my-skill.md

---
name: My Skill Name
description: Brief description of what this skill does
triggers: ["keyword1", "keyword2", "keyword3"]
source: manual
---

## Problem
Describe the problem this skill solves.

## Solution
Provide the solution with code examples.

## Why This Works
Explain the reasoning behind the solution.

## Related
List related resources or references.

技能 Frontmatter 字段

字段 必填 说明
name 技能名称
description 简短描述
triggers 触发关键词列表
source 来源:manualextracted

自动学习:/learner

什么是 /learner?

/learner 命令可以从当前会话中提取可复用的模式,自动生成技能文件。

触发方式

# 在问题解决后调用
/learner

# 或者显式调用
/oh-my-claudecode:learner

工作流程

flowchart TD
    A[问题解决] --> B["/learner"]
    B --> C[分析会话]
    C --> D[识别模式]
    D --> E{质量门槛?}
    E -->|通过| F[生成技能文件]
    E -->|不通过| G[提示手动补充]
    F --> H[保存到 .omc/skills/]
    G --> I[用户编辑]
    I --> H

    style F fill:#e8f5e9
    style G fill:#fff3e0

质量门槛

自动生成的技能必须满足:

  1. 问题描述清晰 - 明确的问题场景
  2. 解决方案具体 - 可执行的代码或步骤
  3. 触发词合理 - 能被正确识别
  4. 可复用性 - 适用于类似场景

实际案例

会话内容

User: 我的 aiohttp 代理服务在客户端断开时崩溃了

Assistant: 让我检查一下错误日志...
发现是 ClientDisconnectedError 导致的。

解决方案是在处理函数中添加 try/except:

[提供了代码解决方案]

User: 问题解决了!

Assistant: 太好了!让我提取这个解决方案作为技能。

调用 /learner

/learner

生成的技能文件

# .omc/skills/fix-aiohttp-disconnect.md

---
name: Fix Aiohttp Disconnect Crash
description: Handle ClientDisconnectedError in aiohttp proxy handlers
triggers: ["aiohttp", "disconnect", "crash", "proxy"]
source: extracted
---

## Problem
aiohttp proxy server crashes when clients disconnect unexpectedly.

## Solution
Wrap handler in try/except ClientDisconnectedError...

[自动提取的内容]

技能自动注入

注入机制

当新会话开始时,OMC 会检查当前上下文是否匹配任何技能的触发词:

flowchart TD
    A[新会话开始] --> B[分析用户输入]
    B --> C[检查触发词]
    C --> D{匹配技能?}
    D -->|是| E[注入技能内容]
    D -->|否| F[正常处理]

    E --> G[技能成为上下文]
    G --> H[AI 应用技能]

    style E fill:#e8f5e9
    style H fill:#fff3e0

触发示例

场景:用户在新会话中说 “我的 aiohttp 服务又崩溃了”

系统检测

  • 关键词 aiohttp 匹配触发词
  • 关键词 崩溃 匹配触发词 crash

结果:自动加载 fix-aiohttp-disconnect.md 技能

注入效果

[系统自动注入]

## 技能激活:Fix Aiohttp Disconnect Crash

检测到相关技能已加载到上下文中:
- 技能名称:Fix Aiohttp Disconnect Crash
- 触发关键词:aiohttp, disconnect, crash, proxy

[技能内容已准备好供 AI 参考]

技能管理命令

列出技能

# 列出所有技能
/skill list

# 列出项目级技能
/skill list --project

# 列出用户级技能
/skill list --user

搜索技能

# 按关键词搜索
/skill search aiohttp

# 按名称搜索
/skill search "disconnect"

添加技能

# 从文件添加
/skill add ./my-skill.md

# 从 URL 添加
/skill add https://example.com/skills/my-skill.md

编辑技能

# 编辑技能
/skill edit fix-aiohttp-disconnect

删除技能

# 删除技能
/skill remove fix-aiohttp-disconnect

技能最佳实践

1. 精准的触发词

# ✅ 好:具体且有区分度
triggers: ["aiohttp", "ClientDisconnectedError", "proxy crash"]

# ❌ 坏:过于宽泛
triggers: ["error", "bug", "fix"]

2. 完整的上下文

## Problem
# ✅ 好:描述具体场景和错误信息
When using aiohttp 3.8+ as a reverse proxy, clients that disconnect
mid-response cause the server to crash with:

aiohttp.client_exceptions.ClientDisconnectedError


# ❌ 坏:模糊描述
The server crashes sometimes.

3. 可执行的解决方案

## Solution
# ✅ 好:提供完整代码
```python
from aiohttp import ClientDisconnectedError

async def proxy_handler(request):
    try:
        response = await fetch_upstream(request)
        return response
    except ClientDisconnectedError:
        logger.info("Client disconnected")
        return Response(status=499)

❌ 坏:只说概念

Handle the exception properly.


### 4. 解释原因

```markdown
## Why This Works
# ✅ 好:解释机制
ClientDisconnectedError is raised when the client closes the TCP connection
before the server finishes sending the response. This is common with:
- Users closing browser tabs
- Mobile apps going to background
- Network interruptions

By catching this exception, we prevent it from propagating up and crashing
the server.

团队协作

共享技能库

# 将技能纳入版本控制
git add .omc/skills/
git commit -m "Add aiohttp disconnect handling skill"

技能市场(规划中)

未来版本将支持:

  • 技能市场浏览
  • 一键安装社区技能
  • 技能评分和评论

常见问题

Q1:技能没有被触发?

检查清单:

  1. 触发词是否匹配?
  2. 技能文件是否在正确位置?
  3. Frontmatter 格式是否正确?
# 验证技能格式
/skill validate my-skill

Q2:如何禁用某个技能?

# 临时禁用
mv .omc/skills/my-skill.md .omc/skills/my-skill.md.disabled

# 或者删除
/skill remove my-skill

Q3:技能可以调用其他技能吗?

当前版本不支持技能间调用。每个技能独立工作。

小结

Skills 系统让经验可以积累和复用:

关键要点

  • ✅ 从成功解决方案提取技能
  • ✅ 精准的触发词确保正确激活
  • ✅ 完整的上下文帮助 AI 理解
  • ✅ 团队共享技能库

技能生命周期

flowchart LR
    A[问题解决] --> B["/learner 提取"]
    B --> C[技能文件]
    C --> D[版本控制]
    D --> E[团队共享]
    E --> F[新会话触发]
    F --> G[自动应用]

    style A fill:#ffebee
    style G fill:#e8f5e9

系列导航