快速摘要
SkillHub 是由科大讯飞开源的一款企业级 Agent Skill(AI 技能包)注册与管理平台,采用 Apache 2.0 协议发布。 它允许团队在自有服务器上进行私有化部署,实现技能包的发布、版本控制、审核治理、搜索发现和多平台分发。核心架构为 Spring Boot + React 19 的三层体系,后端基于 Java 21,前端使用 TypeScript + Vite 构建,数据层由 PostgreSQL 16、Redis 7 和 S3 兼容存储组成。 部署方式支持 Docker Compose 一键拉起和 Kubernetes 集群部署。目前已兼容 OpenClaw、AstronClaw、Loomy、astron-agent 等多个 Agent 平台。如果你的团队正在大量使用 AI 技能包,却苦于缺少统一的管理和分发手段,这篇文章会帮你从原理到实操全面吃透 SkillHub。往下看,有更详细的架构拆解、部署步骤和使用指南。
一、从 Agent Skills 说起:AI 为什么需要"技能包"
在正式介绍 SkillHub 之前,我们先来聊聊它所管理的对象——Agent Skills,也就是常说的"AI 技能包"。
很多人对 AI 助手的印象还停留在"你问我答"的对话模式上。但在实际工作中,你会发现一个反复出现的痛点:每次让 AI 帮你做一份报告或者写一段代码,你都要把格式要求、代码规范、业务流程从头说一遍。说完这次,下次还得再说。这就好比你招了一个非常聪明的实习生,但他没有记忆,每天上班都要重新培训一次。
Agent Skills 就是为了解决这个问题而诞生的机制。它的核心思路是把专业知识、工作流程、脚本工具打包成一个标准化的"技能目录",AI 加载后就能按照预设的规范来执行任务,不需要你每次都重复指令。
一个标准的 Skill 技能包,在文件系统层面是这样组织的:
my-skill/
├── SKILL.md # 必需:技能说明文档和元数据
├── manifest.json # 可选:文件清单
├── references/ # 可选:参考资料
├── scripts/ # 可选:可执行脚本
└── assets/ # 可选:模板和静态资源
其中最关键的是 SKILL.md 文件。它的开头包含一段 YAML 格式的元数据,定义了技能的名称和触发描述;正文部分则是具体的执行指令和使用示例。AI 在启动时会预先加载所有已安装技能的元数据(通常只有几十个 token),当用户的请求与某个技能的描述匹配时,才会读取该技能的完整内容。这种"渐进式披露"的设计非常巧妙——即使你安装了上百个技能,也不会把 AI 的上下文窗口撑爆。
我们来具体看一下这三层加载是怎么工作的。
第一层:技能发现。当 AI 启动时,它会预加载所有已安装技能的元数据——也就是 SKILL.md 开头那段 YAML 中的 name 和 description 字段。这两个字段加起来通常不超过 100 个 token,所以即使安装了几百个技能,也不会给上下文窗口造成负担。AI 利用这些元数据来判断"当前用户的请求和哪些技能相关"。
第二层:加载核心指令。当 AI 判断某个技能与当前任务相关后,它会进一步读取该技能 SKILL.md 的正文内容——也就是具体的执行步骤、注意事项和规范要求。按照官方的建议,这部分内容最好控制在 5000 个 token 以内,既要足够详细地指导 AI 完成任务,又不能过于冗长占用宝贵的上下文空间。
第三层:按需加载资源。技能目录中除了 SKILL.md 之外的其他文件——比如辅助脚本(scripts/ 目录下的 Python 或 Shell 脚本)、参考文档(references/ 目录下的详细说明)和模板资源(assets/ 目录下的文件模板)——只有在 SKILL.md 正文中被引用且当前任务确实需要时,AI 才会去读取或执行。这避免了不必要的资源消耗。
举一个实际的场景来帮助理解。假设你安装了一个名为"PDF 处理"的技能,它的 description 写着"从 PDF 文件中提取文本和表格,填写表单,合并文档"。当你对 AI 说"帮我把这个 PDF 里的表格提取出来",AI 首先在元数据层发现"PDF 处理"技能与当前请求匹配,于是读取该技能的完整指令(第二层)。指令中列出了提取文本、填写表单、合并文档三个工作流程。AI 判断当前任务只需要"提取表格"的流程,因此只加载相关的辅助脚本(第三层),而不会去读取表单填写的参考文件。
这种渐进式披露的设计哲学非常值得学习,它实现了"知识的按需供给"——让 AI 在任何时候都只持有完成当前任务所必需的信息,既保证了执行质量,又控制了 token 开销。
目前 Agent Skills 这套标准已经被 Claude、Claude Code、OpenClaw 等多个平台和工具支持,逐渐成为 AI 能力扩展的主流方式。但问题也随之而来。
二、公开平台解决不了的问题:为什么需要私有技能管理
随着越来越多的团队开始把核心工作流封装成技能包,一些深层次的管理需求浮出了水面。
首先是版本管理的问题。技能包不像普通文档那样写完就完事了,它需要随着业务流程的变化不断迭代。你上个月写的数据分析技能,这个月可能就要适配新的数据库字段。没有版本控制,就无法回溯、无法对比、无法平滑升级。
其次是权限管控的问题。一个技术团队开发的部署运维技能、一个产品团队维护的竞品分析技能、一个安全团队编写的代码审查技能——这些技能的使用范围和访问权限天然是不同的。如果所有技能都堆在同一个地方,没有任何隔离机制,管理混乱几乎是必然的。
然后是质量把控的问题。任何人都可以写一个技能包,但不是所有技能包都能稳定运行。一个编写不当的技能包甚至可能引导 AI 做出错误的操作。团队内部需要有审核机制,确保上线的技能经过验证。
最后是数据安全的问题。很多企业的技能包里包含了内部的 API 地址、业务逻辑、甚至部分代码规范,这些内容不适合上传到任何公开的技能分享平台。企业需要把数据完全掌握在自己手中。在一些对数据合规要求严格的行业(如金融、医疗、政务等),这更是硬性要求。技能包虽然通常不直接包含用户数据,但其中描述的工作流程和代码规范可能涉及商业机密或者内部安全策略,一旦泄露可能被利用来针对性地攻击企业的系统。
还有一个容易被忽视的问题是跨团队复用与一致性。一个大型组织内部可能有几十个不同的团队都在使用 AI 技能包,如果没有一个统一的平台来管理,各团队之间很容易出现"各自为战"的情况——同样功能的技能被不同团队重复开发,彼此的实现标准不一致,甚至存在互相冲突的规范。这种碎片化不仅浪费资源,还会在团队协作时制造摩擦。
公开的技能共享平台比如 ClawHub、skills.sh 已经验证了技能共享这件事的价值,但上述这些问题,它们天然覆盖不到。这个缺口,和十年前代码管理面临的问题非常相似——代码有 Git 仓库管理,容器镜像有 Docker Hub 分发,而团队自己的 AI 技能库管理,在很长一段时间内都处于空白状态。
SkillHub 正是瞄准了这个空白。
在进入具体的技术分析之前,有必要先说明一下 SkillHub 诞生的技术背景。Agent Skills 作为一种开放标准,它的设计初衷是"创建一次,到处使用"。无论是在 Claude 的 Web 界面中通过上传 ZIP 包来使用,还是在 Claude Code 的命令行中通过文件系统加载,又或者在 OpenClaw 这样的 Agent 框架中通过 CLI 安装,技能包的格式和规范是统一的。这就为集中化的注册和分发打下了基础——既然大家都遵循同一套格式标准,那么只要有一个中心化的"仓库"来存放和分发这些技能包,各个平台和工具就可以从同一个源头获取技能。SkillHub 扮演的正是这个"中心仓库"的角色,只不过它是私有的、部署在你自己服务器上的。
三、SkillHub 到底是什么:定位与核心能力
SkillHub 是一个可以在自有服务器上私有化部署的 AI 技能包注册与管理平台。你可以把它理解成一个"团队专属的技能商店"——和你在手机上用的应用商店类似,只不过这里上架的不是 App,而是 AI 技能包。
项目由科大讯飞技术团队开发并开源,托管在 GitHub 上(地址:https://github.com/iflytek/skillhub),采用 Apache 2.0 许可证,这意味着无论是个人还是企业,都可以免费使用和修改。
从功能维度来看,SkillHub 覆盖了技能包管理的完整生命周期。这里莫潇羽@无忆研习社 帮大家梳理一下它的核心能力矩阵:
发布与版本控制。支持通过 Web 界面或 CLI 命令行上传技能包(ZIP 格式),自动进行语义化版本号管理,支持 beta、stable 等自定义标签,并且会自动追踪 latest 版本。每次发布的技能包都会计算 SHA-256 哈希值用于完整性校验。
命名空间与权限体系。每个团队可以拥有自己的命名空间,在里面独立管理技能包。命名空间内支持三种角色——所有者(Owner)、管理员(Admin)和普通成员(Member),不同角色的操作权限各不相同。技能的可见性可以设置为公开(PUBLIC)、仅命名空间可见(NAMESPACE_ONLY)或私有(PRIVATE)三个级别。
审核工作流。普通成员发布的技能包需要经过命名空间管理员审核后才能上线。如果希望将技能提升到全局范围(让所有团队都能看到),还需要平台管理员进行二次审核。所有的审核操作都会记录审计日志。
搜索与发现。基于 PostgreSQL 全文检索引擎实现技能搜索(未来可扩展为 Elasticsearch 或向量搜索),支持按相关性、下载量、最新发布等维度排序,搜索结果会根据用户的命名空间成员关系和技能可见性设置自动过滤。
API Token 与 CI/CD 集成。提供 Token 管理机制,支持生成带作用域的 API Token(sk_ 前缀),可以接入持续集成/持续部署流水线,实现代码合并后自动触发技能发布。
多平台分发。发布到 SkillHub 的技能包可以被 OpenClaw、AstronClaw、Loomy、astron-agent 等多个 Agent 平台直接调用,做到一次发布、多端复用。
四、技术架构深度拆解
了解一个开源项目,光看功能列表是不够的,还得摸清楚它的技术底座。SkillHub 的架构设计在同类项目中算是比较成熟的,下面莫潇羽@无忆研习社 来做一个深入的拆解。
4.1 整体架构:三层分离的模块化单体
SkillHub 采用经典的三层架构——展示层、应用逻辑层和数据存储层,整体以模块化单体(Modular Monolith)的形式组织,通过容器化进行部署。
展示层是一个基于 React 19 构建的单页应用(SPA),使用 Vite 作为构建工具,TanStack Router 处理路由,TanStack Query 管理数据请求,样式方面采用 Tailwind CSS 配合 Radix UI 组件库。前端通过 OpenAPI TypeScript 自动生成类型安全的 API 客户端,保证前后端接口契约的一致性。国际化支持则通过 i18next 实现。
应用逻辑层是一个基于 Spring Boot 3.2.3 和 Java 21 的后端服务,采用整洁架构(Clean Architecture)的思路,将代码拆分为六个 Maven 模块:
server/
├── skillhub-app # 应用入口和组装根,暴露 REST 端点
├── skillhub-domain # 核心领域实体、业务逻辑和仓储接口
├── skillhub-auth # 认证与授权子系统(OAuth2、API Token、会话、RBAC)
├── skillhub-search # 搜索抽象层(当前实现为 PostgreSQL 全文检索)
├── skillhub-storage # 存储抽象层(支持本地文件系统和 S3 兼容存储)
└── skillhub-infra # 基础设施层,实现领域层定义的仓储接口
这种分层的关键在于 skillhub-domain 模块只定义接口和领域实体,不依赖任何基础设施代码;而 skillhub-infra 模块则通过 Spring Data JPA 提供接口的具体实现。这样做的好处是业务逻辑和持久化技术完全解耦——如果将来想从 JPA 切换到其他 ORM 框架,只需要替换 infra 层的实现就行了。
数据存储层由三个组件组成:PostgreSQL 16 作为主数据库,使用 Flyway 管理数据库迁移脚本,在应用启动时自动执行;Redis 7 用于会话管理(基于 Spring Session,会话 Cookie 名为 SESSION)和缓存;S3 兼容的对象存储用于技能包文件的持久化(开发环境可以使用本地文件系统,生产环境建议使用 MinIO 或 S3)。
在数据库设计方面,SkillHub 有一些值得关注的技术细节。所有用户标识符(包括 UserAccount.id、PlatformPrincipal.userId 和 API 参数)都采用字符串类型而非整数类型。这个看似不起眼的决定其实考虑得很周到——因为在实际的企业环境中,用户 ID 可能来自外部身份源(SSO、OIDC 等),这些系统生成的标识符往往是非数字的字符串(比如 UUID 或者邮箱前缀),使用字符串类型可以天然兼容各种身份来源,避免了类型转换带来的麻烦。
审核任务表(review_task)上有一个巧妙的部分唯一索引:ON (skill_version_id) WHERE status = 'PENDING'。这意味着同一个技能版本在同一时间只能有一个处于"待审核"状态的记录,从数据库层面杜绝了重复提交审核的可能性。技能文件表中还存储了每个文件的 SHA-256 哈希值,用于下载时的完整性校验。
技能包文件本身不存储在数据库中,而是通过对象存储进行持久化。存储层通过 SPI 模式抽象为 StorageService 接口,目前提供了两种实现:本地文件系统存储(开发环境下文件存储在 Docker Volume skillhub_storage 的 /var/lib/skillhub/storage 路径下)和 S3 兼容存储(生产环境推荐,通过 SKILLHUB_STORAGE_PROVIDER=s3 配置启用)。切换存储后端只需要修改配置文件,不需要改动任何代码。
用一段伪架构图来表示整体的调用关系:
┌─────────────┐ ┌─────────────┐ ┌──────────────┐
│ Web UI │ │ CLI Tools │ │ REST API │
│ (React 19) │ │ (OpenClaw) │ │ (外部调用) │
└──────┬──────┘ └──────┬──────┘ └──────┬───────┘
│ │ │
└───────────────────┼───────────────────┘
│
┌──────▼──────┐
│ Nginx │ 反向代理 + 静态资源
└──────┬──────┘
│
┌──────▼──────┐
│ Spring Boot │ 认证 · RBAC · 核心业务
│ (Java 21) │ OAuth2 · Token · 审计
└──────┬──────┘
│
┌────────────┼────────────┐
│ │ │
┌──────▼───┐ ┌─────▼────┐ ┌────▼─────┐
│PostgreSQL │ │ Redis │ │ Storage │
│ 16 │ │ 7 │ │ S3/MinIO │
└──────────┘ └──────────┘ └──────────┘
4.2 认证体系:OAuth2 + API Token 双轨制
SkillHub 的认证机制值得单独拿出来说,因为它直接关系到团队成员的接入方式。
Web 端登录基于 OAuth2 协议,默认以 GitHub 作为身份提供方。用户在浏览器中发起登录请求后,系统会跳转到 GitHub 进行授权,授权成功后 GitHub 回调到 SkillHub 的 /login/oauth2/code/github 端点,后端的 CustomOAuth2UserService 会加载用户信息、检查访问策略、绑定或创建账户,最终在 Redis 中创建会话。整个流程基于 Spring Security 的 OAuth2 Client 实现。
CLI 端和 API 端则使用 Token 认证。用户在 Web 控制台生成 API Token 后(以 sk_ 为前缀),在命令行工具中通过 Bearer Token 方式进行身份验证。CLI 端还支持 OAuth2 Device Flow——运行认证命令后,CLI 会显示一个 URL 和短码(比如 ABCD-1234),用户在浏览器中打开 URL 并输入短码完成授权,CLI 就能获得访问令牌了。
此外 SkillHub 还支持账户合并功能,可以将多个 OAuth 身份和 API Token 归并到同一个用户账户下,这在一些使用多种身份源的企业环境中非常实用。
对于本地开发环境,系统启用了 Mock 认证模式(local profile),自动创建两个测试用户——local-user(普通用户)和 local-admin(超级管理员),通过请求头 X-Mock-User-Id 来切换身份,方便开发和调试。
4.3 搜索引擎:基于 PostgreSQL FTS 的可扩展设计
技能包的搜索功能在日常使用中非常高频,SkillHub 在这里做了一个比较聪明的设计——没有一开始就引入 Elasticsearch 这样的重型搜索引擎,而是基于 PostgreSQL 自带的全文检索(Full-Text Search)实现了第一版搜索。
这个选择有几个好处:减少了外部依赖的运维成本、PostgreSQL 16 的中文全文检索已经有了比较好的支持、对于绝大多数中小团队来说性能完全够用。
但更重要的是,搜索模块通过 SPI(Service Provider Interface)模式进行抽象,SearchQueryService 只是一个接口,当前的 PostgreSQL FTS 是它的一个实现。如果将来团队规模增长,需要引入 Elasticsearch 甚至向量搜索来支持语义级别的技能匹配,只需要提供一个新的实现并通过配置切换,不用改动任何业务代码。存储模块同样采用了这种 SPI 设计——开发环境用本地文件系统,生产环境切换到 S3,都只是一个配置项的差别。
4.4 领域事件驱动:异步副作用处理
在 SkillHub 的业务逻辑中,很多操作会产生连锁反应。比如一个技能包审核通过后,需要更新搜索索引、刷新下载计数器、可能还要发送通知。如果把这些逻辑都写在主流程里,代码会变得臃肿且难以维护。
SkillHub 采用了领域事件(Domain Events)的方式来处理这类异步副作用。业务操作在完成核心逻辑后发出事件,由事件监听器异步触发搜索索引重建、计数器更新等操作。这种解耦设计让每个模块只关心自己的事情,扩展新功能时也不会影响已有流程。
五、手把手部署教程
理解了架构之后,我们来看看怎么把 SkillHub 跑起来。项目提供了多种部署方式,下面按照从简单到复杂的顺序逐一讲解。在这里莫潇羽@无忆研习社 会尽量把每一步都说清楚,即使你是第一次接触 Docker 部署,也能跟着操作。
5.1 前置条件
不管选择哪种部署方式,你的机器上都需要预先安装 Docker 和 Docker Compose。如果你还没有安装,各操作系统的安装方法如下(以主流 Linux 发行版为例):
# Ubuntu / Debian
sudo apt-get update
sudo apt-get install docker.io docker-compose-plugin
# CentOS / RHEL
sudo yum install -y docker docker-compose-plugin
# 安装完成后启动 Docker 服务
sudo systemctl start docker
sudo systemctl enable docker
# 验证安装
docker --version
docker compose version
macOS 和 Windows 用户建议直接安装 Docker Desktop,它已经内置了 Docker Compose。
5.2 方式一:一键脚本部署(推荐新手使用)
SkillHub 提供了一个一键部署脚本,它会自动下载配置文件和 Docker Compose 编排文件,然后拉取镜像并启动所有服务。这是上手最快的方式。
使用官方镜像源:
rm -rf /tmp/skillhub-runtime
curl -fsSL https://raw.githubusercontent.com/iflytek/skillhub/main/scripts/runtime.sh | sh -s -- up
由于官方镜像托管在 GitHub Container Registry(ghcr.io),国内访问可能较慢。如果你在国内环境部署,可以使用阿里云镜像源的快捷方式:
rm -rf /tmp/skillhub-aliyun
curl -fsSL https://imageless.oss-cn-beijing.aliyuncs.com/runtime.sh | sh -s -- up --home /tmp/skillhub-aliyun --aliyun --version latest
脚本执行完毕后,打开浏览器访问 http://localhost 就能看到 SkillHub 的首页了。首页上会展示已发布的技能包列表和搜索入口。
如果部署过程中遇到问题(比如端口冲突或者镜像拉取失败),可以清除运行时目录后重试:
# 停止服务
curl -fsSL https://raw.githubusercontent.com/iflytek/skillhub/main/scripts/runtime.sh | sh -s -- down
# 清除数据后重新启动
rm -rf /tmp/skillhub-runtime
curl -fsSL https://raw.githubusercontent.com/iflytek/skillhub/main/scripts/runtime.sh | sh -s -- up
5.3 方式二:Docker Compose 手动部署(推荐生产环境)
对于需要自定义配置的生产环境部署,建议直接使用项目提供的 Docker Compose 编排文件。
第一步,克隆仓库并准备配置文件:
git clone https://github.com/iflytek/skillhub.git
cd skillhub
# 从模板创建配置文件
cp .env.release.example .env.release
第二步,编辑 .env.release 配置文件。这一步非常重要,生产环境 务必 修改以下几个关键配置:
# 你的域名(不要带末尾斜杠)
SKILLHUB_PUBLIC_BASE_URL=https://skillhub.your-company.com
# 数据库密码(务必修改默认值)
POSTGRES_PASSWORD=your-strong-password-here
# 管理员密码(如果启用了 Bootstrap Admin)
BOOTSTRAP_ADMIN_PASSWORD=another-strong-password
# 镜像版本(推荐使用固定版本号)
SKILLHUB_VERSION=v0.1.0
# 存储配置(生产环境建议使用 S3)
SKILLHUB_STORAGE_PROVIDER=s3
SKILLHUB_STORAGE_S3_ENDPOINT=https://your-s3-endpoint
SKILLHUB_STORAGE_S3_BUCKET=skillhub
SKILLHUB_STORAGE_S3_ACCESS_KEY=your-access-key
SKILLHUB_STORAGE_S3_SECRET_KEY=your-secret-key
第三步,验证配置并启动服务:
# 验证配置文件的有效性
make validate-release-config
# 启动所有服务
docker compose --env-file .env.release -f compose.release.yml up -d
# 查看服务状态
docker compose --env-file .env.release -f compose.release.yml ps
启动完成后的默认端口分配是:Web UI 在 80 端口,后端 API 在 8080 端口。
生产环境的一些重要建议需要注意。在网络层面,PostgreSQL(5432)和 Redis(6379)的端口应该绑定到 127.0.0.1,不要暴露到公网;Web 服务通过 Nginx 反向代理,建议配置 HTTPS 证书。在存储层面,开发环境可以使用本地文件系统(存储在 Docker Volume skillhub_storage 中),但生产环境强烈建议使用 S3 兼容的对象存储。在安全层面,BOOTSTRAP_ADMIN_ENABLED 默认为 false,如果需要初始化管理员账户,临时开启后应尽快关闭或轮换管理员凭据。
停止服务的命令是:
docker compose --env-file .env.release -f compose.release.yml down
5.4 方式三:Kubernetes 部署(大规模团队)
对于使用 Kubernetes 的团队,SkillHub 在 deploy/k8s/ 目录下提供了基础的 K8s 部署清单文件,包含 ConfigMap、Secret、Deployment、Service 和 Ingress 等资源定义。
部署步骤如下:
# 先根据模板创建 Secret 文件
cp deploy/k8s/secret.yaml.example deploy/k8s/secret.yaml
# 编辑 secret.yaml,填入实际的密码和密钥
# 依次应用资源清单
kubectl apply -f deploy/k8s/configmap.yaml
kubectl apply -f deploy/k8s/secret.yaml
kubectl apply -f deploy/k8s/backend-deployment.yaml
kubectl apply -f deploy/k8s/frontend-deployment.yaml
kubectl apply -f deploy/k8s/services.yaml
kubectl apply -f deploy/k8s/ingress.yaml
需要注意的是,K8s 清单假设你已经有外部的 PostgreSQL 和 Redis 实例,需要在 ConfigMap 和 Secret 中配置对应的连接信息。如果没有现成的数据库实例,你需要另外部署或使用托管数据库服务。
5.5 本地开发环境搭建
如果你是想参与 SkillHub 的开发贡献,或者需要在本地进行二次开发,可以使用源码级别的开发环境。
git clone https://github.com/iflytek/skillhub.git
cd skillhub
# 一键启动开发环境(会自动启动 PostgreSQL、Redis、MinIO 容器)
make dev-all
开发环境启动后:
Web UI: http://localhost:3000(Vite 热重载)
Backend API: http://localhost:8080(Spring Boot)
开发环境启用了 Mock 认证(local profile),自动预设两个测试账户。local-user 是普通用户角色,用于测试发布和命名空间操作。local-admin 拥有 SUPER_ADMIN 权限,用于测试审核和管理功能。通过在请求头中添加 X-Mock-User-Id: local-user 或 X-Mock-User-Id: local-admin 来切换身份。
其他常用的开发命令:
# 停止开发环境
make dev-all-down
# 重置开发环境(清除所有数据重新开始)
make dev-all-reset
# 运行后端测试
make test-backend-app
# 构建后端
make build-backend-app
# 重新生成前端 API 类型(当后端接口变更时)
make generate-api
# 查看所有可用命令
make help
这里有一个官方特别提醒的坑需要注意:不要在 server/ 目录下直接运行 ./mvnw -pl skillhub-app clean test。因为 skillhub-app 依赖仓库内的其他同级模块,单独进行 clean build 可能会使用本地 Maven 仓库中的过期构件,导致出现莫名其妙的编译错误(比如 cannot find symbol)。正确的做法是使用 -am 参数,或者直接使用上面提到的 make 命令。
5.6 监控体系搭建
SkillHub 还提供了可选的 Prometheus + Grafana 监控栈,位于项目的 monitoring/ 目录下。
cd monitoring
docker compose -f docker-compose.monitoring.yml up -d
启动后可以访问:
Prometheus: http://localhost:9090
Grafana: http://localhost:3001(默认账号 admin / admin)
监控栈默认会抓取后端 Spring Boot Actuator 暴露的 Prometheus 指标端点(http://host.docker.internal:8080/actuator/prometheus)。在 Linux 上部署时,如果 host.docker.internal 不可用,可能需要替换为宿主机的实际网络 IP 地址。
六、平台使用全流程详解
服务部署好之后,接下来就是日常使用了。这一章莫潇羽@无忆研习社 会按照一个团队从入驻到日常使用的真实流程,带你走完所有关键操作。
6.1 账户注册与首次登录
SkillHub 部署完成后,管理员可以将平台地址发送给团队成员。成员打开浏览器访问后,通过 GitHub OAuth 进行注册登录(如果你的组织有自己的 OAuth 提供方,也可以通过修改配置来接入)。
对于初始管理员账户的创建,有两种方式:如果配置了 BOOTSTRAP_ADMIN_ENABLED=true,系统会在首次启动时自动创建一个本地管理员账户(默认用户名 admin),你可以用这个账户登录后进行后续的配置操作。如果使用 OAuth 登录,第一个登录的用户可以在后台被手动设置为超级管理员。
6.2 创建命名空间:给你的团队划一块专属地盘
登录成功后,第一件要做的事就是创建团队的命名空间。命名空间是 SkillHub 中组织技能的核心单位,你可以把它类比为 GitHub 上的 Organization——每个命名空间有自己的成员列表、角色体系和技能仓库。
创建步骤是这样的:点击页面右上角的用户头像,在下拉菜单中选择"我的命名空间"(My Namespaces),然后点击"创建命名空间"(Create Namespace)。在弹出的表单中填写两个字段——标识(slug,用于 URL 和 CLI 引用,只能包含小写字母、数字和连字符)和显示名称(Display Name,可以用中文)。比如你可以创建一个标识为 backend-team、显示名称为"后端团队"的命名空间。
创建完成后,你默认成为这个命名空间的所有者(Owner),拥有最高权限。
6.3 管理成员与角色分配
有了命名空间之后,就可以把团队成员加进来了。在命名空间管理页面,点击"管理成员"(Manage Members),可以通过搜索用户名或直接输入 userId 来添加成员。
SkillHub 的命名空间支持三种角色权限模型。所有者(Owner)拥有完全控制权,可以管理命名空间设置、添加/移除成员、审核技能、删除命名空间。管理员(Admin)可以审核命名空间内提交的技能包、管理普通成员、发布技能。普通成员(Member)可以向命名空间发布技能(需要经过审核)、搜索和下载命名空间内的技能。
这种分层的角色设计让不同职责的团队成员各司其职。比如团队 Leader 作为所有者负责整体管控,资深工程师作为管理员负责技能审核,其他成员作为普通成员进行技能的创建和使用。
值得一提的是,命名空间之间的隔离是比较彻底的。不同命名空间的成员默认无法看到彼此的私有技能和仅命名空间可见的技能。只有标记为"公开"的技能才会出现在全局搜索结果中。这就意味着,你的后端团队可以在自己的命名空间中放心地维护包含数据库连接规范和部署流程的技能包,不用担心被不相关的团队看到。
如果某个技能确实需要跨命名空间共享,可以通过"提升到全局"的功能来实现。这个过程需要经过平台管理员的额外审核,确保共享出去的技能不包含特定团队的敏感信息。这种"默认隔离、按需共享"的设计思路,在安全性和便利性之间取得了不错的平衡。
在实际运营中,命名空间的划分方式可以根据组织结构灵活调整。有些团队按业务线划分(比如 payment-team、user-growth-team),有些按技术栈划分(比如 frontend-skills、backend-skills、devops-skills),还有些按项目划分(比如 project-alpha、project-beta)。没有标准答案,选择最适合你们团队协作模式的方式就好。
6.4 打包与发布技能
接下来就是整个平台最核心的操作——发布一个技能包。
首先你需要在本地准备好技能包的文件。如前文所述,一个合格的技能包至少要包含一个 SKILL.md 文件,其开头必须有 YAML 格式的元数据。这里给出一个实际的例子:
---
name: code-review-standard
description: 当用户要求进行代码审查时,按照团队的代码规范进行检查,包括命名规范、错误处理、日志标准和安全检查清单。
---
# 代码审查技能
## 审查流程
### 第一步:结构检查
检查代码的整体结构是否符合项目架构规范...
### 第二步:命名规范检查
变量、函数、类名是否遵循 camelCase / PascalCase 规范...
### 第三步:安全审查
检查是否存在硬编码的密钥、SQL 注入风险、XSS 漏洞...
## 参考资料
详细的安全检查清单参见 [SECURITY_CHECKLIST.md](SECURITY_CHECKLIST.md)
然后把技能目录打包成 ZIP 文件:
cd my-skill
zip -r ../code-review-standard.zip .
接着在 SkillHub 的 Web 界面点击顶部的"发布"(Publish)按钮,在发布页面中选择目标命名空间,设置可见性级别(公开 / 仅命名空间可见 / 私有),然后上传打包好的 ZIP 文件并提交。
后端在接收到上传后,会自动执行以下验证操作:验证 ZIP 包的结构是否合法、检查 SKILL.md 的 YAML 前置元数据格式、扫描文件内容中是否包含 Token 或密钥(预检查)、如果一切正常则创建一个审核任务。
需要注意的是,同一个技能的同一个版本只会有一个待审核记录(通过数据库的部分唯一索引 review_task(skill