AI Agent 技能开发实战:从需求到上线的完整流程
引言
在上一篇文章中,我们介绍了 OpenClaw 的基础使用。当你熟悉了基础功能后,下一步就是开发自己的技能(Skill)—— 这才是 AI Agent 真正强大的地方。
技能系统让 AI Agent 可以无限扩展能力:从简单的天气查询到复杂的自动化工作流,从 API 集成到浏览器自动化。本文将以一个实际案例,带你完成从需求分析到上线的完整流程。
🎯 本文目标
开发一个「GitHub 项目分析」技能:用户输入 GitHub 仓库地址,AI 自动分析项目架构、依赖、活跃度,生成分析报告。
需求分析
用户故事
作为一个开发者,我想快速了解一个 GitHub 项目的技术栈和活跃度,以便决定是否使用或贡献这个项目。
功能拆解
- 解析仓库地址:从 URL 提取 owner/repo
- 获取仓库信息:stars、forks、语言、描述
- 分析项目结构:目录结构、技术栈
- 生成报告:格式化输出分析结果
技术选型
- GitHub API:gh CLI(已内置,无需额外配置)
- 技能框架:OpenClaw Skill System
- 输出格式:Markdown(可扩展为 HTML)
技能开发
目录结构
一个标准的 OpenClaw 技能目录:
~/.openclaw/workspace/skills/github-explorer/
├── SKILL.md # 技能描述(必需)
├── scripts/
│ └── analyze.js # 核心逻辑
└── README.md # 文档
1. 创建 SKILL.md
SKILL.md 是技能的「身份证」,告诉 Agent 什么时候使用这个技能:
# GitHub 项目分析技能
## 触发条件
当用户想要了解 GitHub 项目时使用此技能。触发词包括:
- "分析这个项目"
- "帮我看看这个 repo"
- "了解一下 XXX"
- GitHub URL 直接输入
## 功能
- 解析 GitHub 仓库地址
- 获取项目元数据(stars、forks、语言)
- 分析项目结构和依赖
- 生成技术栈分析报告
## 使用方法
```bash
node scripts/analyze.js <repo-url>
```
## 依赖
- GitHub CLI (gh) 已安装并配置
- Node.js 18+
2. 编写核心脚本
创建 scripts/analyze.js:
#!/usr/bin/env node
const { execSync } = require('child_process');
// 解析 GitHub URL
function parseRepoUrl(url) {
const match = url.match(/github\.com\/([^/]+)\/([^/]+)/);
if (!match) throw new Error('Invalid GitHub URL');
return { owner: match[1], repo: match[2].replace('.git', '') };
}
// 获取仓库信息
function getRepoInfo(owner, repo) {
const json = execSync(
`gh repo view ${owner}/${repo} --json name,description,stargazersCount,forksCount,primaryLanguage,updatedAt,createdAt`,
{ encoding: 'utf-8' }
);
return JSON.parse(json);
}
// 分析项目结构
function analyzeStructure(owner, repo) {
try {
const tree = execSync(
`gh api repos/${owner}/${repo}/git/trees/main?recursive=1 --jq '.tree[].path'`,
{ encoding: 'utf-8' }
);
const files = tree.trim().split('\n');
// 检测技术栈
const techStack = [];
if (files.some(f => f.includes('package.json'))) techStack.push('Node.js');
if (files.some(f => f.includes('requirements.txt'))) techStack.push('Python');
if (files.some(f => f.includes('Cargo.toml'))) techStack.push('Rust');
if (files.some(f => f.includes('go.mod'))) techStack.push('Go');
return { fileCount: files.length, techStack };
} catch {
return { fileCount: 0, techStack: ['Unknown'] };
}
}
// 主函数
function main() {
const url = process.argv[2];
if (!url) {
console.error('Usage: analyze.js <github-url>');
process.exit(1);
}
const { owner, repo } = parseRepoUrl(url);
console.log(`\n🔍 正在分析 ${owner}/${repo}...\n`);
const repoInfo = getRepoInfo(owner, repo);
const structure = analyzeStructure(owner, repo);
// 生成报告
console.log('## 📊 项目分析报告\n');
console.log(`**项目**: ${repoInfo.name}`);
console.log(`**描述**: ${repoInfo.description || '暂无描述'}`);
console.log(`**主语言**: ${repoInfo.primaryLanguage?.name || 'Unknown'}`);
console.log(`**⭐ Stars**: ${repoInfo.stargazersCount}`);
console.log(`**🍴 Forks**: ${repoInfo.forksCount}`);
console.log(`**📁 文件数**: ~${structure.fileCount}`);
console.log(`**🛠️ 技术栈**: ${structure.techStack.join(', ')}`);
console.log(`**📅 创建时间**: ${repoInfo.createdAt.split('T')[0]}`);
console.log(`**🔄 最后更新**: ${repoInfo.updatedAt.split('T')[0]}`);
}
main();
3. 测试技能
# 添加执行权限
chmod +x scripts/analyze.js
# 测试运行
node scripts/analyze.js https://github.com/vercel/next.js
输出示例:
🔍 正在分析 vercel/next.js...
## 📊 项目分析报告
**项目**: next.js
**描述**: The React Framework
**主语言**: JavaScript
**⭐ Stars**: 128542
**🍴 Forks**: 27368
**📁 文件数**: ~3245
**🛠️ 技术栈**: Node.js
**📅 创建时间**: 2016-10-05
**🔄 最后更新**: 2026-03-15
集成到 Agent
配置技能路径
确保 Agent 能找到技能目录。在 openclaw.json 中:
{
"skills": {
"paths": [
"~/.openclaw/workspace/skills"
]
}
}
验证技能加载
重启 Gateway 后,Agent 会自动加载 SKILL.md:
openclaw gateway restart
实际使用
在 Discord 或 TUI 中与 Agent 对话:
你:帮我分析一下 https://github.com/vercel/next.js 这个项目
Agent:好的,我来分析这个项目...
[自动调用 github-explorer 技能]
进阶优化
1. 添加更多分析维度
可以扩展脚本,增加:
- 依赖分析:解析 package.json、requirements.txt
- 贡献者统计:获取 contributor 列表
- Issue/PR 活跃度:分析近 30 天的活动
- 安全检查:检测已知漏洞
2. 错误处理和缓存
// 添加错误处理
function safeExec(cmd) {
try {
return execSync(cmd, { encoding: 'utf-8' });
} catch (error) {
console.error(`Command failed: ${cmd}`);
return null;
}
}
// 添加简单缓存
const cache = new Map();
function cached(key, fn) {
if (cache.has(key)) return cache.get(key);
const result = fn();
cache.set(key, result);
return result;
}
3. 输出格式美化
使用模板引擎生成更美观的报告:
const report = `
# 📊 ${repoInfo.name} 分析报告
## 基本信息
| 项目 | 值 |
|------|-----|
| Stars | ⭐ ${repoInfo.stargazersCount} |
| Forks | 🍴 ${repoInfo.forksCount} |
| 语言 | ${repoInfo.primaryLanguage?.name} |
| 文件数 | 📁 ${structure.fileCount} |
## 技术栈
${structure.techStack.map(t => `- ${t}`).join('\n')}
`;
console.log(report);
最佳实践
✅ 技能设计原则
- 单一职责:一个技能只做一件事
- 明确触发:SKILL.md 要描述清楚什么时候用
- 友好输出:输出格式要清晰易读
- 错误处理:优雅处理各种异常情况
⚠️ 避免的坑
- 不要在技能中硬编码敏感信息(API Key 等)
- 不要假设环境(先检查依赖是否存在)
- 不要输出过于冗长的内容(Agent 有 token 限制)
- 不要忘记文档(README.md 很重要)
总结
我们做了什么
- ✅ 需求分析:明确用户故事和功能点
- ✅ 技术选型:选择合适的工具和框架
- ✅ 核心开发:编写 SKILL.md 和分析脚本
- ✅ 集成测试:验证技能能被 Agent 正确调用
- ✅ 进阶优化:错误处理、缓存、格式美化
技能开发的本质
技能开发的核心是让 AI Agent 获得新能力。一个好的技能应该:
- 解决实际问题
- 易于使用和理解
- 输出有价值的信息
- 可扩展和可维护
下一步
- 探索 ClawHub 发现更多技能
- 开发自己的技能并分享到社区
- 组合多个技能创建自动化工作流
参考资源
最后更新:2026-03-15
作者:张小猛