從 Skill 到 Skill Library:建立組織級能力庫

從個人 Skill 到組織級 Skill Library,涵蓋註冊發現、品質審核、權限治理、發布流程到使用分析。

從 Skill 到 Skill Library:建立組織級能力庫

前面七篇,我們從概念、結構、設計、組合、版本管理、安全邊界到完整實作,建立了一個可運作的 Skill 系統。

但這個系統是為個人設計的。

當團隊有 10 個工程師、20 個 Agent、50 個 Skill 時,會發生什麼事?

  • 有人重複造輪子
  • 有人用了過期的 Skill
  • 有人改了 Skill 卻沒通知其他人

這一篇,我們要談 Skill 的下一個層次:Skill Library(技能庫)
我們會解釋為什麼需要組織級的能力庫、如何設計發現與共享機制、如何治理與審核、如何建立發布流程,並用 Python 實作一個完整的 Skill Library 系統。

Discovery + Sharing + Governance + Analytics = Skill Library

一、從個人到組織:為什麼需要 Skill Library?

問題一:重複造輪子

小明寫了一個 research_topic Skill,用來研究市場趨勢。
小華也寫了一個 research_topic Skill,用來研究技術趨勢。
兩個 Skill 功能幾乎一樣,但各自維護、各自迭代。

小明:research_topic v1.0.0(研究市場)
小華:research_topic v1.0.0(研究技術)

結果:

  • 兩份程式碼要維護
  • 兩份 Prompt 要優化
  • 兩份測試要跑
  • 兩邊的經驗無法累積

問題二:不知道有哪些 Skill 可用

團隊有 50 個 Skill,但沒人知道全部有哪些。
新進成員問:「有沒有翻譯的 Skill?」
老成員回答:「好像有,但我不確定叫什麼名字。」

問題三:用了過期的 Skill

小美用 code_review v1.0.0 審查程式碼。
但她不知道小華已經發布了 v2.0.0,修復了三個重要的安全檢查漏洞。

問題四:改了 Skill 沒人知道

小華優化了 research_topic 的 Prompt,讓準確率提升 20%。
但他只在自己的專案裡用,沒有通知其他人。
團隊其他人還在用舊版本。

問題五:品質參差不齊

有些 Skill 經過充分測試,品質穩定。
有些 Skill 是某個人週五下班前隨手寫的,沒有測試、沒有文件、沒有範例。

問題六:權限與合規無法管理

在金融、醫療等行業,每個 Skill 都必須經過審核才能上線。
但沒人知道哪個 Skill 被誰用了、做了什麼、是否符合合規要求。

問題七:無法衡量價值

團隊花了大量時間開發 Skill,但不知道:

  • 哪些 Skill 最常用?
  • 哪些 Skill 效果最好?
  • 哪些 Skill 應該淘汰?
  • 整體的投資報酬率是多少?

Skill Library 的價值

Skill Library 就是為了解決這些問題:

問題Skill Library 的解法
重複造輪子統一的註冊與發現機制
不知道有什麼搜尋與分類
用了過期版本版本管理與更新通知
改了沒人知道發布流程與變更日誌
品質參差不齊品質標準與審核
權限與合規治理與審計
無法衡量價值使用分析與指標

打個比方:

  • 個人 Skill 系統像個人的工具箱。
  • Skill Library像組織的圖書館——有分類、有檢索、有借閱規則、有版本管理、有品質把關。

Personal Skills → Team Skills → Organization Library

二、Skill Library 的核心組件

一個完整的 Skill Library 包含以下組件:

┌─────────────────────────────────────────────────────────┐
│                   Skill Library                          │
│                                                         │
│  ┌────────────┐  ┌────────────┐  ┌────────────┐        │
│  │  註冊與    │  │  搜尋與    │  │  版本與    │        │
│  │  發現      │  │  分類      │  │  依賴      │        │
│  └────────────┘  └────────────┘  └────────────┘        │
│                                                         │
│  ┌────────────┐  ┌────────────┐  ┌────────────┐        │
│  │  品質與    │  │  權限與    │  │  使用與    │        │
│  │  審核      │  │  治理      │  │  分析      │        │
│  └────────────┘  └────────────┘  └────────────┘        │
│                                                         │
│  ┌────────────────────────────────────────────┐        │
│  │           發布流程 + 通知機制               │        │
│  └────────────────────────────────────────────┘        │
└─────────────────────────────────────────────────────────┘
組件職責
註冊與發現讓 Skill 可以被註冊、查詢、發現
搜尋與分類用標籤、分類、全文檢索找到 Skill
版本與依賴管理版本、解析依賴、避免衝突
品質與審核定義品質標準、審核 Skill
權限與治理控制誰能用什麼、誰能改什麼
使用與分析追蹤使用情況、評估價值
發布流程從開發到上線的標準流程
通知機制版本更新、安全修復的通知

三、Skill 的註冊與發現

註冊中繼資料

每個 Skill 都應該有完整的註冊資訊:

@dataclass
class SkillRegistration:
    """Skill 的註冊資訊"""
    # 基本資訊
    name: str                      # 唯一識別碼
    display_name: str              # 顯示名稱
    description: str               # 簡短描述
    version: str                   # 版本號

    # 分類
    category: str                  # 分類,如 "research", "writing", "analysis"
    tags: list                     # 標籤,如 ["nlp", "web", "report"]

    # 作者與維護
    author: str                    # 作者
    maintainer: str                # 維護者
    created_at: str                # 建立時間
    updated_at: str                # 更新時間

    # 能力
    input_schema: dict             # 輸入格式
    output_schema: dict            # 輸出格式
    required_tools: list           # 需要的工具
    required_permissions: dict     # 需要的權限

    # 品質
    test_coverage: float           # 測試覆蓋率
    success_rate: float            # 成功率
    avg_latency: float             # 平均延遲
    avg_cost: float                # 平均成本

    # 狀態
    status: str                    # draft, testing, active, deprecated
    deprecation_notice: str        # 棄用通知

    # 文件
    documentation_url: str         # 文件連結
    examples: list                 # 範例
    changelog: str                 # 變更日誌

搜尋與分類

Skill Library 應該支援多種搜尋方式:

class SkillSearch:
    """Skill 搜尋引擎"""

    def __init__(self, skills: dict):
        self.skills = skills

    def search_by_name(self, query: str) -> list:
        """按名稱搜尋"""
        query_lower = query.lower()
        return [
            s for s in self.skills.values()
            if query_lower in s.name.lower()
            or query_lower in s.display_name.lower()
        ]

    def search_by_description(self, query: str) -> list:
        """按描述搜尋"""
        query_lower = query.lower()
        return [
            s for s in self.skills.values()
            if query_lower in s.description.lower()
        ]

    def search_by_tags(self, tags: list) -> list:
        """按標籤搜尋"""
        return [
            s for s in self.skills.values()
            if any(tag in s.tags for tag in tags)
        ]

    def search_by_category(self, category: str) -> list:
        """按分類搜尋"""
        return [
            s for s in self.skills.values()
            if s.category == category
        ]

    def search_by_semantic(self, query: str, embedder) -> list:
        """語意搜尋:用嵌入向量找最相關的 Skill"""
        query_embedding = embedder(query)

        scored = []
        for skill in self.skills.values():
            # 把名稱、描述、標籤組合成文字
            text = f"{skill.display_name} {skill.description} {' '.join(skill.tags)}"
            skill_embedding = embedder(text)

            # 計算相似度
            similarity = self._cosine_similarity(query_embedding, skill_embedding)
            scored.append((skill, similarity))

        # 按相似度排序
        scored.sort(key=lambda x: x[1], reverse=True)

        return [skill for skill, score in scored if score > 0.5]

    def _cosine_similarity(self, a: list, b: list) -> float:
        """計算餘弦相似度"""
        dot = sum(x * y for x, y in zip(a, b))
        norm_a = sum(x * x for x in a) ** 0.5
        norm_b = sum(x * x for x in b) ** 0.5
        if norm_a == 0 or norm_b == 0:
            return 0.0
        return dot / (norm_a * norm_b)

    def search_all(self, query: str, embedder=None) -> list:
        """綜合搜尋:名稱、描述、標籤、語意"""
        results = {}
        results["name"] = self.search_by_name(query)
        results["description"] = self.search_by_description(query)
        results["tags"] = self.search_by_tags([query])

        if embedder:
            results["semantic"] = self.search_by_semantic(query, embedder)

        # 合併去重
        seen = set()
        merged = []
        for source, skills in results.items():
            for skill in skills:
                if skill.name not in seen:
                    seen.add(skill.name)
                    merged.append(skill)

        return merged

分類體系

一個好的分類體系能讓 Skill 更容易被發現:

categories:
  - research       # 研究與資訊蒐集
  - analysis       # 分析與推理
  - writing        # 寫作與內容生成
  - coding         # 程式碼相關
  - data           # 資料處理
  - communication  # 通訊與通知
  - automation     # 自動化流程
  - utility        # 通用工具

每個 Skill 可以屬於一個主要分類,並有多個標籤:

research_topic = SkillRegistration(
    name="research_topic",
    category="research",
    tags=["web", "search", "summary", "report"],
    ...
)

四、品質標準與審核

Skill Library 的品質,取決於每個 Skill 的品質。
我們需要定義明確的品質標準,並建立審核機制。

品質標準

@dataclass
class QualityStandards:
    """Skill 的品質標準"""
    # 文件
    has_description: bool = True
    has_input_schema: bool = True
    has_output_schema: bool = True
    has_examples: bool = True
    has_changelog: bool = True

    # 測試
    min_test_coverage: float = 0.7
    min_test_cases: int = 5
    has_edge_cases: bool = True

    # 效能
    max_avg_latency: float = 30.0
    max_avg_cost: float = 0.5
    min_success_rate: float = 0.9

    # 安全
    has_permission_declaration: bool = True
    has_input_validation: bool = True
    has_output_filtering: bool = True

    def check(self, skill: SkillRegistration) -> dict:
        """檢查 Skill 是否符合標準"""
        issues = []

        # 文件檢查
        if not skill.description or len(skill.description) < 20:
            issues.append("描述過短或缺失")
        if not skill.input_schema:
            issues.append("缺少輸入 Schema")
        if not skill.output_schema:
            issues.append("缺少輸出 Schema")
        if not skill.examples:
            issues.append("缺少範例")

        # 測試檢查
        if skill.test_coverage < self.min_test_coverage:
            issues.append(f"測試覆蓋率不足:{skill.test_coverage}")
        if skill.success_rate < self.min_success_rate:
            issues.append(f"成功率不足:{skill.success_rate}")

        # 效能檢查
        if skill.avg_latency > self.max_avg_latency:
            issues.append(f"延遲過高:{skill.avg_latency}")
        if skill.avg_cost > self.max_avg_cost:
            issues.append(f"成本過高:{skill.avg_cost}")

        # 安全檢查
        if not skill.required_permissions:
            issues.append("缺少權限宣告")

        return {
            "passed": len(issues) == 0,
            "issues": issues,
        }

審核流程

Skill 從開發到上線,應該經過以下流程:

1. 提交(Submit)
   ↓ 開發者提交 Skill
2. 自動檢查(Automated Check)
   ↓ 跑測試、檢查品質標準
3. 同儕審核(Peer Review)
   ↓ 其他開發者審查程式碼與 Prompt
4. 安全審核(Security Review)
   ↓ 檢查權限、沙箱、敏感資訊
5. 發布(Publish)
   ↓ 上架到 Skill Library
6. 監控(Monitor)
   ↓ 追蹤使用情況與效能
class SkillReviewWorkflow:
    """Skill 審核流程"""

    def __init__(self, quality_standards: QualityStandards):
        self.standards = quality_standards
        self.pending = {}
        self.approved = {}
        self.rejected = {}

    def submit(self, skill: SkillRegistration, code: str) -> str:
        """提交 Skill"""
        review_id = f"review_{skill.name}_{skill.version}"

        self.pending[review_id] = {
            "skill": skill,
            "code": code,
            "status": "pending",
            "checks": {},
        }

        return review_id

    def run_automated_checks(self, review_id: str) -> dict:
        """執行自動檢查"""
        if review_id not in self.pending:
            return {"error": "找不到審核請求"}

        review = self.pending[review_id]
        skill = review["skill"]

        checks = {
            "quality": self.standards.check(skill),
            "tests": self._run_tests(review["code"]),
            "security": self._check_security(review["code"]),
        }

        review["checks"] = checks

        # 判斷是否通過
        all_passed = all(
            check.get("passed", False)
            for check in checks.values()
        )

        review["status"] = "auto_passed" if all_passed else "auto_failed"

        return checks

    def _run_tests(self, code: str) -> dict:
        """執行測試"""
        # 實作略
        return {"passed": True, "coverage": 0.85, "cases": 10}

    def _check_security(self, code: str) -> dict:
        """安全檢查"""
        issues = []

        # 檢查是否有危險的工具呼叫
        dangerous_tools = ["execute_command", "delete_file", "send_email"]
        for tool in dangerous_tools:
            if tool in code:
                issues.append(f"使用了危險工具:{tool}")

        # 檢查是否有硬編碼的敏感資訊
        import re
        if re.search(r"password\s*=\s*['\"]", code):
            issues.append("發現硬編碼密碼")

        return {
            "passed": len(issues) == 0,
            "issues": issues,
        }

    def peer_review(self, review_id: str, reviewer: str,
                    approved: bool, comments: str = ""):
        """同儕審核"""
        if review_id not in self.pending:
            return

        review = self.pending[review_id]

        if "peer_reviews" not in review:
            review["peer_reviews"] = []

        review["peer_reviews"].append({
            "reviewer": reviewer,
            "approved": approved,
            "comments": comments,
            "timestamp": datetime.now().isoformat(),
        })

        # 檢查是否達到足夠的審核
        approvals = sum(
            1 for r in review["peer_reviews"] if r["approved"]
        )

        if approvals >= 2:
            review["status"] = "peer_approved"

    def publish(self, review_id: str) -> dict:
        """發布 Skill"""
        if review_id not in self.pending:
            return {"error": "找不到審核請求"}

        review = self.pending[review_id]

        if review["status"] not in ("auto_passed", "peer_approved"):
            return {"error": f"審核未通過:{review['status']}"}

        skill = review["skill"]

        self.approved[skill.name] = skill
        del self.pending[review_id]

        return {
            "success": True,
            "skill": skill.name,
            "version": skill.version,
        }

五、權限與治理

在組織層級,權限管理變得更複雜。
我們需要定義誰能做什麼。

角色與權限

from enum import Enum


class Role(Enum):
    VIEWER = "viewer"           # 只能查看
    USER = "user"               # 可以使用 Skill
    CONTRIBUTOR = "contributor" # 可以提交 Skill
    REVIEWER = "reviewer"       # 可以審核 Skill
    ADMIN = "admin"             # 可以管理 Skill Library


class Permission(Enum):
    VIEW_SKILL = "view_skill"
    USE_SKILL = "use_skill"
    SUBMIT_SKILL = "submit_skill"
    REVIEW_SKILL = "review_skill"
    PUBLISH_SKILL = "publish_skill"
    DEPRECATE_SKILL = "deprecate_skill"
    MANAGE_USERS = "manage_users"


ROLE_PERMISSIONS = {
    Role.VIEWER: [Permission.VIEW_SKILL],
    Role.USER: [Permission.VIEW_SKILL, Permission.USE_SKILL],
    Role.CONTRIBUTOR: [
        Permission.VIEW_SKILL,
        Permission.USE_SKILL,
        Permission.SUBMIT_SKILL,
    ],
    Role.REVIEWER: [
        Permission.VIEW_SKILL,
        Permission.USE_SKILL,
        Permission.SUBMIT_SKILL,
        Permission.REVIEW_SKILL,
    ],
    Role.ADMIN: list(Permission),  # 所有權限
}

治理政策

@dataclass
class GovernancePolicy:
    """治理政策"""
    # 誰可以提交 Skill
    submit_roles: list = field(default_factory=lambda: [Role.CONTRIBUTOR, Role.ADMIN])

    # 誰可以審核 Skill
    review_roles: list = field(default_factory=lambda: [Role.REVIEWER, Role.ADMIN])

    # 需要幾位審核者
    min_reviewers: int = 2

    # 哪些 Skill 需要安全審核
    security_review_categories: list = field(
        default_factory=lambda: ["coding", "automation"]
    )

    # 哪些操作需要額外審核
    high_risk_tools: list = field(
        default_factory=lambda: ["execute_command", "delete_file", "send_email"]
    )

    # 自動棄用條件
    auto_deprecate_days: int = 180  # 180 天未更新
    auto_deprecate_success_rate: float = 0.7  # 成功率低於 70%


class GovernanceManager:
    """治理管理器"""

    def __init__(self, policy: GovernancePolicy):
        self.policy = policy
        self.user_roles = {}  # user_id -> Role

    def assign_role(self, user_id: str, role: Role):
        """指派角色"""
        self.user_roles[user_id] = role

    def has_permission(self, user_id: str, permission: Permission) -> bool:
        """檢查使用者是否有權限"""
        role = self.user_roles.get(user_id, Role.VIEWER)
        return permission in ROLE_PERMISSIONS.get(role, [])

    def can_submit(self, user_id: str) -> bool:
        """檢查是否可以提交 Skill"""
        role = self.user_roles.get(user_id, Role.VIEWER)
        return role in self.policy.submit_roles

    def can_review(self, user_id: str) -> bool:
        """檢查是否可以審核 Skill"""
        role = self.user_roles.get(user_id, Role.VIEWER)
        return role in self.policy.review_roles

    def needs_security_review(self, skill: SkillRegistration) -> bool:
        """檢查是否需要安全審核"""
        return skill.category in self.policy.security_review_categories

    def check_deprecation(self, skill: SkillRegistration) -> dict:
        """檢查是否應該棄用"""
        from datetime import datetime, timedelta

        reasons = []

        # 檢查最後更新時間
        if skill.updated_at:
            last_update = datetime.fromisoformat(skill.updated_at)
            days_since = (datetime.now() - last_update).days
            if days_since > self.policy.auto_deprecate_days:
                reasons.append(f"已 {days_since} 天未更新")

        # 檢查成功率
        if skill.success_rate < self.policy.auto_deprecate_success_rate:
            reasons.append(f"成功率過低:{skill.success_rate}")

        return {
            "should_deprecate": len(reasons) > 0,
            "reasons": reasons,
        }

六、發布流程與通知

發布流程

class ReleasePipeline:
    """Skill 發布流程"""

    def __init__(self, library, review_workflow, governance):
        self.library = library
        self.review = review_workflow
        self.governance = governance
        self.subscribers = {}  # skill_name -> [user_ids]

    def publish(self, skill: SkillRegistration, code: str, user_id: str) -> dict:
        """發布 Skill"""
        # 1. 檢查權限
        if not self.governance.can_submit(user_id):
            return {"success": False, "error": "沒有提交權限"}

        # 2. 提交審核
        review_id = self.review.submit(skill, code)

        # 3. 自動檢查
        checks = self.review.run_automated_checks(review_id)
        if not all(c.get("passed") for c in checks.values()):
            return {
                "success": False,
                "error": "自動檢查未通過",
                "checks": checks,
            }

        # 4. 如果需要安全審核
        if self.governance.needs_security_review(skill):
            return {
                "success": False,
                "status": "pending_security_review",
                "review_id": review_id,
            }

        # 5. 等待同儕審核
        return {
            "success": False,
            "status": "pending_peer_review",
            "review_id": review_id,
        }

    def approve_and_publish(self, review_id: str, reviewer: str) -> dict:
        """審核通過並發布"""
        if not self.governance.can_review(reviewer):
            return {"success": False, "error": "沒有審核權限"}

        self.review.peer_review(review_id, reviewer, approved=True)

        # 檢查是否達到足夠的審核
        review = self.review.pending.get(review_id)
        if review and review["status"] == "peer_approved":
            result = self.review.publish(review_id)
            if result.get("success"):
                # 通知訂閱者
                self._notify_subscribers(
                    review["skill"].name,
                    f"新版本 {review['skill'].version} 已發布",
                )
            return result

        return {"success": False, "status": "waiting_for_more_reviews"}

    def subscribe(self, user_id: str, skill_name: str):
        """訂閱 Skill 更新"""
        if skill_name not in self.subscribers:
            self.subscribers[skill_name] = []
        if user_id not in self.subscribers[skill_name]:
            self.subscribers[skill_name].append(user_id)

    def _notify_subscribers(self, skill_name: str, message: str):
        """通知訂閱者"""
        subscribers = self.subscribers.get(skill_name, [])
        for user_id in subscribers:
            # 實際情況:發送 email 或通知
            print(f"[通知] {user_id}: {skill_name} - {message}")

變更通知

class NotificationService:
    """通知服務"""

    def __init__(self):
        self.notifications = []

    def notify_version_update(
        self, skill_name: str, old_version: str, new_version: str,
        changelog: str,
    ):
        """通知版本更新"""
        notification = {
            "type": "version_update",
            "skill": skill_name,
            "old_version": old_version,
            "new_version": new_version,
            "changelog": changelog,
            "timestamp": datetime.now().isoformat(),
        }
        self.notifications.append(notification)
        return notification

    def notify_security_fix(
        self, skill_name: str, version: str, severity: str,
        description: str,
    ):
        """通知安全修復"""
        notification = {
            "type": "security_fix",
            "skill": skill_name,
            "version": version,
            "severity": severity,
            "description": description,
            "timestamp": datetime.now().isoformat(),
        }
        self.notifications.append(notification)
        return notification

    def notify_deprecation(
        self, skill_name: str, version: str, reason: str,
        replacement: str = None,
    ):
        """通知棄用"""
        notification = {
            "type": "deprecation",
            "skill": skill_name,
            "version": version,
            "reason": reason,
            "replacement": replacement,
            "timestamp": datetime.now().isoformat(),
        }
        self.notifications.append(notification)
        return notification

    def get_notifications(self, since: str = None) -> list:
        """取得通知"""
        if since:
            return [
                n for n in self.notifications
                if n["timestamp"] > since
            ]
        return self.notifications

七、使用分析與價值衡量

Skill Library 應該追蹤使用情況,衡量每個 Skill 的價值。

使用指標

@dataclass
class SkillMetrics:
    """Skill 的使用指標"""
    skill_name: str
    version: str

    # 使用量
    total_invocations: int = 0
    unique_users: int = 0
    invocations_last_7_days: int = 0
    invocations_last_30_days: int = 0

    # 效能
    avg_latency: float = 0.0
    p95_latency: float = 0.0
    avg_cost: float = 0.0
    total_cost: float = 0.0

    # 品質
    success_rate: float = 0.0
    error_rate: float = 0.0
    user_satisfaction: float = 0.0

    # 趨勢
    trend: str = "stable"  # growing, stable, declining

使用追蹤

class UsageTracker:
    """使用追蹤器"""

    def __init__(self):
        self.invocations = []
        self.feedback = []

    def track_invocation(
        self, skill_name: str, version: str, user_id: str,
        duration: float, cost: float, success: bool,
    ):
        """追蹤一次呼叫"""
        self.invocations.append({
            "skill": skill_name,
            "version": version,
            "user_id": user_id,
            "duration": duration,
            "cost": cost,
            "success": success,
            "timestamp": datetime.now().isoformat(),
        })

    def track_feedback(
        self, skill_name: str, user_id: str,
        rating: int, comment: str = "",
    ):
        """追蹤使用者回饋"""
        self.feedback.append({
            "skill": skill_name,
            "user_id": user_id,
            "rating": rating,
            "comment": comment,
            "timestamp": datetime.now().isoformat(),
        })

    def get_metrics(self, skill_name: str) -> SkillMetrics:
        """取得 Skill 的指標"""
        from datetime import datetime, timedelta
        from statistics import mean

        invocations = [
            i for i in self.invocations if i["skill"] == skill_name
        ]

        if not invocations:
            return SkillMetrics(skill_name=skill_name, version="unknown")

        now = datetime.now()
        last_7 = [
            i for i in invocations
            if (now - datetime.fromisoformat(i["timestamp"])).days <= 7
        ]
        last_30 = [
            i for i in invocations
            if (now - datetime.fromisoformat(i["timestamp"])).days <= 30
        ]

        durations = [i["duration"] for i in invocations]
        costs = [i["cost"] for i in invocations]
        successes = [i["success"] for i in invocations]

        sorted_durations = sorted(durations)
        p95_index = int(len(sorted_durations) * 0.95)

        # 使用者滿意度
        feedback = [
            f for f in self.feedback if f["skill"] == skill_name
        ]
        satisfaction = mean([f["rating"] for f in feedback]) if feedback else 0.0

        # 趨勢判斷
        if len(last_7) > len(last_30) / 4 * 1.2:
            trend = "growing"
        elif len(last_7) < len(last_30) / 4 * 0.8:
            trend = "declining"
        else:
            trend = "stable"

        return SkillMetrics(
            skill_name=skill_name,
            version=invocations[-1]["version"],
            total_invocations=len(invocations),
            unique_users=len(set(i["user_id"] for i in invocations)),
            invocations_last_7_days=len(last_7),
            invocations_last_30_days=len(last_30),
            avg_latency=round(mean(durations), 3),
            p95_latency=round(sorted_durations[p95_index], 3),
            avg_cost=round(mean(costs), 4),
            total_cost=round(sum(costs), 2),
            success_rate=round(sum(successes) / len(successes), 3),
            error_rate=round(1 - sum(successes) / len(successes), 3),
            user_satisfaction=round(satisfaction, 2),
            trend=trend,
        )

價值報告

def generate_library_report(tracker: UsageTracker, skills: dict) -> dict:
    """產生 Skill Library 的整體報告"""
    all_metrics = []
    for skill_name in skills:
        metrics = tracker.get_metrics(skill_name)
        all_metrics.append(metrics)

    # 排序:最常用的
    most_used = sorted(
        all_metrics, key=lambda m: m.total_invocations, reverse=True
    )[:10]

    # 排序:最高品質
    highest_quality = sorted(
        [m for m in all_metrics if m.total_invocations > 10],
        key=lambda m: m.success_rate * m.user_satisfaction,
        reverse=True,
    )[:10]

    # 需要關注的
    needs_attention = [
        m for m in all_metrics
        if m.success_rate < 0.8 or m.trend == "declining"
    ]

    return {
        "total_skills": len(skills),
        "total_invocations": sum(m.total_invocations for m in all_metrics),
        "total_cost": round(sum(m.total_cost for m in all_metrics), 2),
        "most_used": [
            {"skill": m.skill_name, "invocations": m.total_invocations}
            for m in most_used
        ],
        "highest_quality": [
            {
                "skill": m.skill_name,
                "success_rate": m.success_rate,
                "satisfaction": m.user_satisfaction,
            }
            for m in highest_quality
        ],
        "needs_attention": [
            {
                "skill": m.skill_name,
                "issue": "低成功率" if m.success_rate < 0.8 else "使用量下降",
            }
            for m in needs_attention
        ],
    }

八、實作:完整的 Skill Library

把上述所有組件整合起來。

class SkillLibrary:
    """組織級 Skill Library"""

    def __init__(self, governance: GovernancePolicy = None):
        self.skills = {}                    # name -> SkillRegistration
        self.versions = {}                  # name -> [versions]
        self.search = None
        self.governance = GovernanceManager(governance or GovernancePolicy())
        self.review = SkillReviewWorkflow(QualityStandards())
        self.release = ReleasePipeline(self, self.review, self.governance)
        self.notifications = NotificationService()
        self.tracker = UsageTracker()
        self.standards = QualityStandards()

    # ========== 註冊與發現 ==========

    def register(self, skill: SkillRegistration):
        """註冊 Skill"""
        self.skills[skill.name] = skill

        if skill.name not in self.versions:
            self.versions[skill.name] = []
        self.versions[skill.name].append(skill.version)

        # 更新搜尋引擎
        self.search = SkillSearch(self.skills)

    def get(self, name: str) -> SkillRegistration:
        """取得 Skill"""
        return self.skills.get(name)

    def list_all(self) -> list:
        """列出所有 Skill"""
        return list(self.skills.values())

    def search_skills(self, query: str, embedder=None) -> list:
        """搜尋 Skill"""
        if not self.search:
            self.search = SkillSearch(self.skills)
        return self.search.search_all(query, embedder)

    # ========== 使用 ==========

    def use_skill(
        self, skill_name: str, version: str, user_id: str,
        input_data: dict,
    ) -> dict:
        """使用 Skill"""
        skill = self.skills.get(skill_name)
        if not skill:
            return {"success": False, "error": f"找不到 Skill {skill_name}"}

        if skill.status == "deprecated":
            return {
                "success": False,
                "error": f"Skill {skill_name} 已棄用",
                "notice": skill.deprecation_notice,
            }

        # 檢查權限
        if not self.governance.has_permission(user_id, Permission.USE_SKILL):
            return {"success": False, "error": "沒有使用權限"}

        # 這裡應該實際執行 Skill
        # 簡化:模擬執行
        start = time.time()
        result = {"success": True, "data": input_data}
        duration = time.time() - start

        # 追蹤使用
        self.tracker.track_invocation(
            skill_name, version, user_id,
            duration, 0.01, True,
        )

        return result

    # ========== 治理 ==========

    def assign_role(self, user_id: str, role: Role):
        """指派角色"""
        self.governance.assign_role(user_id, role)

    def check_deprecation(self) -> list:
        """檢查所有 Skill 的棄用狀態"""
        to_deprecate = []
        for skill in self.skills.values():
            result = self.governance.check_deprecation(skill)
            if result["should_deprecate"]:
                to_deprecate.append({
                    "skill": skill.name,
                    "version": skill.version,
                    "reasons": result["reasons"],
                })
        return to_deprecate

    # ========== 報告 ==========

    def generate_report(self) -> dict:
        """產生 Library 報告"""
        return generate_library_report(self.tracker, self.skills)

    def get_skill_health(self, skill_name: str) -> dict:
        """取得 Skill 的健康狀態"""
        skill = self.skills.get(skill_name)
        if not skill:
            return {"error": "找不到 Skill"}

        metrics = self.tracker.get_metrics(skill_name)
        quality = self.standards.check(skill)

        return {
            "skill": skill_name,
            "version": skill.version,
            "status": skill.status,
            "quality_passed": quality["passed"],
            "quality_issues": quality["issues"],
            "metrics": {
                "success_rate": metrics.success_rate,
                "avg_latency": metrics.avg_latency,
                "avg_cost": metrics.avg_cost,
                "trend": metrics.trend,
            },
        }

九、使用範例

# 建立 Library
library = SkillLibrary()

# 指派角色
library.assign_role("alice", Role.ADMIN)
library.assign_role("bob", Role.CONTRIBUTOR)
library.assign_role("carol", Role.REVIEWER)
library.assign_role("dave", Role.USER)

# 註冊 Skill
research_skill = SkillRegistration(
    name="research_topic",
    display_name="主題研究",
    description="研究一個主題並蒐集相關資訊",
    version="1.1.0",
    category="research",
    tags=["web", "search", "summary"],
    author="bob",
    maintainer="bob",
    created_at="2026-01-01T00:00:00",
    updated_at="2026-03-01T00:00:00",
    input_schema={"topic": "string"},
    output_schema={"summary": "string", "sources": "list"},
    required_tools=["search_web", "read_webpage"],
    required_permissions={"network": "read"},
    test_coverage=0.85,
    success_rate=0.95,
    avg_latency=5.2,
    avg_cost=0.05,
    status="active",
    documentation_url="https://wiki.example.com/skills/research_topic",
    examples=[{"input": {"topic": "AI"}, "output": {"summary": "..."}}],
    changelog="加入交叉驗證步驟",
)

library.register(research_skill)

# 搜尋
results = library.search_skills("研究")
print(f"找到 {len(results)} 個 Skill")

# 使用
result = library.use_skill(
    "research_topic", "1.1.0", "dave",
    {"topic": "2026 AI 趨勢"},
)
print(result)

# 檢查棄用
deprecated = library.check_deprecation()
print(f"建議棄用的 Skill:{deprecated}")

# 產生報告
report = library.generate_report()
import json
print(json.dumps(report, indent=2, ensure_ascii=False))

# 健康檢查
health = library.get_skill_health("research_topic")
print(json.dumps(health, indent=2, ensure_ascii=False))

十、最佳實踐

  1. 統一的註冊格式:每個 Skill 都必須有完整的註冊資訊,缺一不可。
  2. 強制品質標準:不符合品質標準的 Skill,不能上架。
  3. 多層審核:自動檢查 + 同儕審核 + 安全審核,三層把關。
  4. 明確的角色與權限:誰能看、誰能用、誰能改、誰能審,都要清楚定義。
  5. 完整的變更通知:版本更新、安全修復、棄用通知,都要主動通知使用者。
  6. 持續追蹤使用情況:沒有使用數據,就無法知道哪些 Skill 有價值。
  7. 定期清理:定期檢查並棄用過時、低品質、低使用率的 Skill。
  8. 建立回饋迴圈:使用者的回饋應該被收集、分析、用於改進。
  9. 文件即程式碼:Skill 的文件應該與程式碼一起版本控制。
  10. 從小事開始:不要一開始就建立龐大的治理體系。先從一個簡單的註冊表開始,隨著 Skill 數量增加,逐步加入治理機制。

十一、常見的陷阱

1. 過度治理

一開始就要求 10 層審核,沒人想提交 Skill。

解法:從輕量開始,隨著規模增加逐步加強。

2. 缺乏發現機制

Skill 註冊了,但沒人找得到。

解法:好的分類、標籤、搜尋。

3. 版本混亂

同一個 Skill 有多個版本在流通,沒人知道哪個是最新的。

解法:明確的版本管理與啟用機制。

4. 沒有淘汰機制

過時的 Skill 一直留在 Library 裡,造成混淆。

解法:定期審查,自動棄用低品質 Skill。

5. 忽略使用數據

不知道哪些 Skill 有用、哪些沒用。

解法:完整的追蹤與分析。

6. 權限太鬆

所有人都能發布 Skill,品質無法控制。

解法:明確的角色與權限,多層審核。

7. 權限太緊

只有少數人能發布 Skill,創新被扼殺。

解法:平衡控制與開放,讓貢獻者能提交,但需要審核。

十二、總結:從個人能力到組織資產

讓我們回顧這一篇的核心:

  • 為什麼需要 Skill Library:重複造輪子、不知道有什麼、用了過期版本、改了沒人知道、品質參差不齊、權限無法管理、無法衡量價值。
  • 核心組件:註冊與發現、搜尋與分類、版本與依賴、品質與審核、權限與治理、使用與分析、發布流程、通知機制。
  • 註冊與發現:完整的註冊資訊、多種搜尋方式、分類體系。
  • 品質與審核:品質標準、自動檢查、同儕審核、安全審核。
  • 權限與治理:角色與權限、治理政策、棄用機制。
  • 發布流程:提交、自動檢查、同儕審核、安全審核、發布、監控。
  • 通知機制:版本更新、安全修復、棄用通知。
  • 使用分析:使用指標、使用追蹤、價值報告。
  • 最佳實踐:統一格式、強制品質、多層審核、明確權限、完整通知、持續追蹤、定期清理、建立回饋、文件即程式碼、從小事開始。
  • 常見陷阱:過度治理、缺乏發現、版本混亂、沒有淘汰、忽略數據、權限太鬆或太緊。

Skill Library 讓 Skill 從個人的能力,變成組織的資產。
它讓知識可以累積、經驗可以共享、品質可以控制、價值可以衡量。
當你的團隊有數十個 Skill 時,Skill Library 就是讓它們協同運作的關鍵基礎設施。

到這裡,我們的 Agent Skills 系列已經涵蓋了從概念、結構、設計、組合、版本管理、安全邊界、完整實作到組織級能力庫的完整脈絡。
你現在已經具備設計、實作、組合、迭代、保護、治理 Skill 的完整能力。


系列完整回顧

篇號主題核心概念
1什麼是 Agent Skill?工具 vs Skill、為什麼需要 Skill
2Skill 的結構指令、工具、資源、範例、漸進式揭露
3設計一個可重用的 Skill以程式碼審查為例,從需求到實作
4Skill 的組合與編排順序、協調者、平行、條件、迭代、階層
5Skill 的版本管理與迭代版本控制、A/B 測試、灰度發布
6Skill 的權限與安全邊界權限控制、沙箱、人類審核、審計
7實作:建立一個 Skill 系統整合所有模組的完整系統
8從 Skill 到 Skill Library組織級能力庫的建立與治理

下一個系列預告

《Agent Harness:從測試到持續改進》

我們會談如何為 Agent 與 Skill 建立完整的測試與評估框架,包括:

  • 測試案例設計
  • 自動化執行
  • 評分機制
  • 回歸測試
  • 成本與延遲評估
  • 失敗模式分析
  • CI/CD 整合
  • 從 Harness 到持續改進