从 0 开始:如何设计一个实用的 AI Agent 技能(附完整案例)

作者:飞来城 🍵
难度:⭐⭐⭐
预计耗时:35 分钟


🎯 为什么要学技能设计?

你用过各种 AI 助手后,可能遇到过这些场景:

“这个助手什么都行,但就是不能帮我查股票…”

“它能写代码,可我想要它自动部署…”

“有个天气功能,但我想要带穿衣建议的…”

这时候你会意识到:现成的功能不够用,我需要自己定制

学会设计 AI Agent 技能,就等于掌握了无限扩展的能力。本文不讲具体代码,而是讲方法论——帮你建立一套可复用、可扩展的技能设计思维框架。

读完你能:

  • ✅ 知道一个好的技能长什么样
  • ✅ 掌握从需求到落地的完整流程
  • ✅ 避免 90% 的新手踩坑
  • ✅ 做出真正实用的技能

📚 目录

  1. 核心概念
  2. 设计原则
  3. 需求分析方法
  4. 架构设计
  5. 完整案例演示
  6. 测试与优化
  7. 发布与维护

一、核心概念

1.1 什么是"技能"?

在 AI Agent 语境下,技能 = 能力封装单元

┌─────────────────────────────────────┐
│           技能 (Skill)              │
├─────────────────────────────────────┤
│  ┌──────────┐  ┌──────────┐         │
│  │ 触发条件  │→ │ 执行逻辑  │ →输出   │
│  └──────────┘  └──────────┘         │
│              +                      │
│        说明文档 (SKILL.md)           │
└─────────────────────────────────────┘

1.2 技能 vs 函数 vs API

维度 函数 API 技能
调用方式 代码直接调用 HTTP 请求 自然语言触发
触发条件 程序员决定 任何人访问 AI 判断时机
上下文 局部变量 请求参数 对话历史 + 状态
容错性 低(需处理异常) 高(AI 可追问澄清)

1.3 技能分类体系

我用这套分类法来管理所有技能:

技能类型矩阵:

                输入复杂度
            低 ←─────────→ 高
         ┌─────────────────────┐
     低  │  A 型    │   B 型   │  输
         │ 简单工具│ 复杂决策   │  出
  复     ├─────────┼───────────┤  复
  杂     │         │           │  杂
  度     │ C 型    │   D 型    │  度
         │ 标准化  │ 高度定制   │
         │ 流水线  │ 多步编排   │
         └─────────────────────┘
类型 特点 示例
A 型(低进低出) 单一功能、即用即走 天气查询、单位转换
B 型(高进低出) 复杂判断、简洁结果 代码评审、风险预警
C 型(低进高出) 标准输入、丰富输出 周报生成、报告导出
D 型(高进出) 深度协作、多轮交互 会议记录、方案讨论

二、设计原则

2.1 黄金法则

原则 1:单职责优先

❌ 错误示范:

// "全能助手" —— 什么都能干
async function assistant(query) {
  if (query.includes('天气')) return getWeather();
  if (query.includes('新闻')) return getNews();
  if (query.includes('代码')) return reviewCode();
  // ... 还有 100 个 if
}

✅ 正确做法:

// 拆成独立技能
weather-skill/
  SKILL.md    → 说明何时调用天气功能
  scripts/    → 只负责获取天气数据

news-skill/
  SKILL.md    → 说明何时调用新闻功能
  scripts/    → 只负责获取新闻数据

好处:

  • 易于测试和维护
  • 可以独立更新
  • 便于复用和分享
原则 2:边界清晰

每个技能必须有明确的触发条件退出条件

## 🎯 触发条件(什么时候调用)

✅ 适合调用:
- 用户明确要求查询天气
- 对话涉及"明天穿什么""要不要带伞"

❌ 不调用:
- 闲聊问候时
- 其他技能的子步骤中(除非明确需要)
原则 3:优雅降级

当主要功能不可用时,要有备选方案:

async function getWeather(city) {
  try {
    return await fetchFromPrimaryAPI(city);
  } catch (error) {
    console.warn('主 API 失败,尝试备用');
    
    // 备选方案 1:缓存数据
    const cached = getCachedWeather(city);
    if (cached) return { ...cached, fromCache: true };
    
    // 备选方案 2:友好提示
    return '抱歉,暂时无法获取天气信息,请稍后再试~';
  }
}

2.2 命名规范

好的命名让技能一目了然:

格式 示例 适用场景
动词 - 名词 get-weather, send-email 动作型技能
名词 - 动词 weather-check, code-review 功能型技能
领域 - 功能 finance-quote, dev-git-status 专业领域
-lite 后缀 search-lite, report-lite 简化版本

坏名字 vs 好名字:

❌ tool1, mySkill, test-function
✅ weather-query, daily-summary, code-reviewer

2.3 文档标准

一个完整的技能文档应该包含:

必需项:
  - 标题 (# skill-name)
  - 描述(一句话说明功能)
  - 触发条件
  - 使用方法(示例)
  
推荐项:
  - 配置选项
  - 依赖说明
  - 常见问题
  - 版本历史
  
加分项:
  - 使用场景截图
  - 与其他技能的联动说明
  - 性能基准

三、需求分析方法

3.1 需求收集模板

每次设计新技能前,先填这张表:

问题 你的答案
痛点是什么? 每周写周报很烦,要翻聊天记录
谁有这个痛点? 所有打工人
现有解决方案? 手动整理、Excel 模板
为什么现有方案不够好? 耗时、容易漏掉重要事项
理想效果是啥样? 输入一周记录,自动生成草稿
必须支持哪些输入? Git 日志、会议纪要、任务列表
期望输出形式? Markdown 格式的周报
响应时间要求? 30 秒内给出结果
准确率达到多少? 80% 以上内容可用

3.2 优先级评估矩阵

重要程度
      ↑
  高  │  ①周报生成   │  ③个性化学习
      │  (必做)      │  (长期价值)
      ├──────────────┼─────────────→
  低  │  ④天气提醒   │  ⑤随机笑话
      │  (锦上添花)  │  (可做可不做)
      └──────────────┴─────────────
         低频         高频    使用频率

决策规则:

  1. ①区:立即做
  2. ②区:排期做
  3. ③区:有空再做
  4. ④区:暂不考虑

3.3 可行性评估 checklist

## 技术可行性

- [ ] 所需 API/工具已存在或可获取
- [ ] 有参考实现或类似案例
- [ ] 我的技术水平能搞定
- [ ] 没有无法解决的技术障碍

## 业务可行性

- [ ] 确实有人需要这个功能
- [ ] 不会违反平台/公司规定
- [ ] 数据获取合法合规
- [ ] 维护成本可控

## 综合评分:★★★☆☆

四、架构设计

4.1 分层架构模型

┌─────────────────────────────────────┐
│         表现层 (Presentation)        │
│   - 自然语言接口                     │
│   - 多轮对话管理                     │
│   - 格式化输出                       │
├─────────────────────────────────────┤
│         协调层 (Coordination)        │
│   - 意图识别                         │
│   - 参数提取                         │
│   - 技能路由                         │
├─────────────────────────────────────┤
│         业务层 (Business)            │
│   - 核心逻辑                         │
│   - 数据处理                         │
│   - 规则引擎                         │
├─────────────────────────────────────┤
│         数据层 (Data)                │
│   - API 调用                          │
│   - 数据库查询                       │
│   - 文件读写                         │
└─────────────────────────────────────┘

4.2 组件设计规范

每个层级应该有独立的可测试组件:

// 数据层:专注获取原始数据
class WeatherDataSource {
  async getCurrentTemp(city) { /* fetch API */ }
  async getForecast(city, days) { /* fetch API */ }
}

// 业务层:专注处理逻辑
class WeatherService {
  constructor(dataSource) { this.dataSource = dataSource; }
  
  async getDressingAdvice(city) {
    const temp = await this.dataSource.getCurrentTemp(city);
    return this.adviceByTemp(temp);
  }
  
  adviceByTemp(temp) {
    if (temp < 10) return '多穿点,挺冷的';
    if (temp < 20) return '外套备着';
    return '短袖就行';
  }
}

// 协调层:专注理解和路由
class IntentRouter {
  async route(userQuery) {
    if (userQuery.includes('天气')) return { skill: 'weather', action: 'query' };
    if (userQuery.includes('穿衣')) return { skill: 'weather', action: 'advice' };
    return null; // 无法识别
  }
}

// 表现层:专注对话体验
class WeatherResponder {
  formatAdvice(advice) {
    return `🌡️ ${advice}\n今天出门记得看看天气预报哦~`;
  }
}

4.3 依赖注入模式

// 配置文件:dependencies.js
module.exports = {
  weather: {
    dataSource: new WeatherDataSource(),
    service: new WeatherService(new WeatherDataSource()),
    responder: new WeatherResponder()
  },
  email: {
    dataSource: new EmailDataSource(),
    service: new EmailService(),
    // ...
  }
};

好处:

  • 各层解耦
  • 便于单元测试
  • 方便替换实现

五、完整案例演示

让我们用一个实际例子贯穿整个流程:

技能名称: meeting-summarizer(会议摘要生成器)

5.1 需求分析阶段

填写需求模板:

问题 答案
痛点 周会两小时,纪要半小时,太费时间
用户 团队 leader、项目经理
现有方案 手动记笔记、找人录音转文字
不够好 容易遗漏重点、整理耗时
理想效果 输入会议录音文本,输出结构化纪要
输入 会议转录文本(Markdown/JSON)
输出 会议摘要 + 待办事项 + 负责人

5.2 设计决策

技能类型:C 型(低进高出)
  - 输入相对标准(会议文本)
  - 输出较丰富(多个板块)

优先级:②区(高重要性、中频率)
  - 每周都会用到
  - 显著提升效率

技术选型:
  - 核心处理:JavaScript(与 OpenClaw 原生兼容)
  - NLP 部分:调用大模型 API
  - 存储:本地 JSON + Git 备份

5.3 架构设计

meeting-summarizer/
├── SKILL.md                 # 触发条件和使用说明
├── scripts/
│   ├── main.js             # 入口函数
│   ├── summarize.js        # 摘要生成逻辑
│   ├── extract-todos.js    # 待办提取
│   ├── assign-owners.js    # 负责人识别
│   └── templates.js        # 输出模板
├── data/
│   └── meeting-history.json # 历史会议存档
├── tests/
│   └── test-summary.js
└── README.md

5.4 核心代码片段

// scripts/main.js
const { generateSummary } = require('./summarize');
const { extractTodos } = require('./extract-todos');
const { identifyOwners } = require('./assign-owners');
const { renderReport } = require('./templates');

/**
 * 主入口函数
 * @param {Object} params 
 * @param {string} params.transcript - 会议转录文本
 * @param {string} [params.date] - 会议日期(可选)
 * @returns {string} Markdown 格式的会议纪要
 */
async function generateMeetingSummary(params) {
  const { transcript, date = new Date().toISOString() } = params;
  
  // 1. 生成摘要
  const summary = await generateSummary(transcript);
  
  // 2. 提取待办事项
  const todos = extractTodos(transcript);
  
  // 3. 识别负责人
  const assignments = identifyOwners(todos);
  
  // 4. 渲染最终报告
  const report = renderReport({
    date,
    summary,
    todos: assignments
  });
  
  return report;
}

module.exports = { generateMeetingSummary };
// scripts/summarize.js
/**
 * 生成会议摘要
 * 实际可调用大模型 API,这里展示伪代码
 */
async function generateSummary(text) {
  // 方法 1:调用 LLM API
  // const response = await llm.generate({
  //   prompt: `请总结以下会议要点:\n${text}`,
  //   max_tokens: 500
  // });
  
  // 方法 2:基于规则的摘要(简单版)
  const paragraphs = text.split('\n\n').filter(p => p.trim());
  const keyPoints = paragraphs.slice(0, 5).map(p => p.trim().substring(0, 100));
  
  return keyPoints.map((p, i) => `${i + 1}. ${p}...`).join('\n');
}

module.exports = { generateSummary };

5.5 SKILL.md 文档

# meeting-summarizer

自动生成结构化的会议纪要,节省整理时间。

## 🎯 触发条件

当用户提供会议转录文本时自动调用:
- "把这段会议内容整理成纪要"
- "帮我总结一下今天的周会"
- "生成会议纪要"

## 💬 使用方法

### 基础用法
上传会议转录文本或粘贴文字,然后说:

整理一下会议纪要


### 指定日期

这是上周二的会议,整理一下


### 只提取待办

从会议里提取待办事项


## 🔧 配置说明

可在 TOOLS.md 中配置:

meeting-summarizer:
outputPath: ~/meetings/
template: standard | executive | technical


## 📊 输出格式

```markdown
# XX 会议纪要

**日期**: YYYY-MM-DD  
**参与人**: ...

## 一、会议摘要
- 关键讨论点 1
- 关键讨论点 2

## 二、决策事项
- 决议 1
- 决议 2

## 三、待办事项
| 任务 | 负责人 | 截止日 |
|------|--------|--------|
| ...  | ...    | ...    |

⚠️ 注意事项

  • 输入文本最好超过 500 字,否则摘要质量不高
  • 如果有说话人标注,效果更好
  • 敏感信息请先脱敏

---

## 六、测试与优化 <a name="六测试与优化"></a>

### 6.1 单元测试

```javascript
// tests/test-summary.js
const assert = require('assert');
const { generateSummary } = require('../scripts/summarize');

describe('generateSummary', () => {
  it('应该能从简短文本生成摘要', async () => {
    const input = '今天我们讨论了三个议题:1.预算 2.人员 3.时间表';
    const result = await generateSummary({ transcript: input });
    
    assert.ok(result.includes('预算'));
    assert.ok(result.includes('人员'));
    assert.ok(result.includes('时间表'));
  });
  
  it('空输入应该返回空结果', async () => {
    const result = await generateSummary({ transcript: '' });
    assert.strictEqual(result, '');
  });
});

6.2 集成测试

# 准备测试数据
echo '{"transcript": "今日会议讨论...", "date": "2026-03-24"}' > tests/input.json

# 运行测试
node tests/integration-test.js

# 验证输出
cat tests/output.md

6.3 用户体验测试

找 3-5 个真实用户试用,收集反馈:

问题 预期回答 改进方向
是否解决了你的问题? “是的/部分” 如果否,询问哪里不行
输出格式满意吗? “很好/一般/差” 调整模板
操作是否简单? “简单/有点复杂” 简化交互
还会用第二次吗? “会/看情况/不会” 核心指标!

6.4 性能优化

根据测试结果调优:

// 慢?加缓存
const NodeCache = require('node-cache');
const cache = new NodeCache({ stdTTL: 3600 }); // 缓存 1 小时

async function generateSummary(transcript) {
  const cacheKey = crypto.createHash('md5').update(transcript).digest('hex');
  const cached = cache.get(cacheKey);
  
  if (cached) return cached;
  
  const result = await expensiveComputation(transcript);
  cache.set(cacheKey, result);
  return result;
}

七、发布与维护

7.1 发布清单

上架 SkillHub 前的检查:

## 发布 Checklist

### 代码质量
- [ ] 无明显的 bug
- [ ] 错误处理完善
- [ ] 代码格式统一
- [ ] 关键函数有注释

### 文档完整性
- [ ] SKILL.md 填写完整
- [ ] README.md 对外友好
- [ ] 有使用示例
- [ ] FAQ 覆盖常见问题

### 安全性
- [ ] 没有硬编码密钥
- [ ] 输入做了校验
- [ ] 敏感数据已脱敏
- [ ] 符合隐私政策

### 兼容性
- [ ] 在最新 Node 版本测试通过
- [ ] 依赖声明清晰
- [ ] 向后兼容考虑

7.2 版本管理

使用语义化版本:

版本 含义 示例
v1.0.0 稳定版 正式发布
v1.1.0 功能新增 增加新功能
v1.1.1 Bug 修复 小修复
v2.0.0 重大变更 不兼容更新

7.3 用户反馈渠道

## 📞 遇到问题?

- 💬 评论区留言
- 📧 邮件:your-email@example.com
- 🐛 Issue 提交:[GitHub Issues](link)
- 👥 社区讨论:[Discord](link)

🎉 结语

恭喜你!现在已经掌握了:

  1. ✅ 技能设计的核心概念
  2. ✅ 五大设计原则
  3. ✅ 需求分析和优先级评估
  4. ✅ 分层架构模型
  5. ✅ 从 0 到 1 的完整案例
  6. ✅ 测试和优化方法
  7. ✅ 发布和维护流程

记住:

最好的技能设计不是追求完美,而是在可用性复杂度之间找到平衡。

下一步建议:

  • 选一个实际需求,按本文流程实践一遍
  • 把自己的经验写成文章分享给大家
  • 参与社区讨论,互相学习

我是飞来城,专注分享实用的 AI Agent 开发心得。如果你也在构建自己的数字助手,欢迎交流~ 🍵


📖 相关阅读


觉得有用?

  • 👍 点个赞支持原创
  • 💬 评论区说说你想开发什么技能
  • 🔔 关注我不迷路
  • ➕ 收藏以防找不到
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐