ACP 大模型應(yīng)用開(kāi)發(fā) | 注冊(cè)加載生成skill與社區(qū)復(fù)用skill(下)

承接上篇:從審查痛點(diǎn)到高質(zhì)量 Skill

?? 前言

上篇你已手動(dòng)完成 Skill 從設(shè)計(jì)到「雙 Agent」迭代的全過(guò)程。但 Skill 仍像躺在磁盤(pán)里的一組 Markdown——Agent 怎么發(fā)現(xiàn)它、加載它、在真實(shí)任務(wù)里調(diào)用它? 推廣到團(tuán)隊(duì)后,如何避免 「一個(gè)人的成功,十個(gè)人的混亂」?

4 讓你的 Agent 使用和生成 Skill

到目前為止,你手動(dòng)完成了 Skill 從設(shè)計(jì)到迭代的全過(guò)程:用審查經(jīng)驗(yàn)提煉檢查清單,封裝成 course-review/ 目錄,又通過(guò)「雙 Agent」模式反復(fù)打磨指令。但這個(gè) Skill 還只是 一組 Markdown 文件——Agent 怎么發(fā)現(xiàn)它、加載它、在真實(shí)任務(wù)中調(diào)用它?

4.1 在 AgentScope 中加載 Skill

好消息是,你不需要自己寫(xiě)完整的加載邏輯。AgentScope JavaClasspathSkillRepository 解析 SKILL.mdSkillBox 注冊(cè) Skill 并生成 Agent 可見(jiàn)的提示。

Python 課件 vs AgentScope Java

Python 課件 AgentScope Java
toolkit.register_agent_skill("course-review") skillBox.registerSkill(agentSkill)
toolkit.get_agent_skill_prompt() skillBox.getSkillPrompt()
按需讀子文件 load_skill_through_path(框架內(nèi)置)+ read_file
ReActAgent(..., toolkit=toolkit) ReActAgent.builder().skillBox(skillBox).toolkit(toolkit)

準(zhǔn)備工作:SKILL.md + YAML frontmatter

框架要求入口文件名為 SKILL.md(不是 README.md),并從 YAML frontmatter 提取 name、description。上篇已完成升級(jí);course-review 入口示例:

---
name: course-review
description: |
  審查課程內(nèi)容的技術(shù)準(zhǔn)確性、代碼正確性和教學(xué)質(zhì)量。當(dāng)用戶要求審查、審計(jì)或評(píng)估現(xiàn)有的課程或培訓(xùn)材料(含 Jupyter Notebook)時(shí)使用此技能。
owner: 教學(xué)設(shè)計(jì)團(tuán)隊(duì)
maintainers:
  - course-quality-lead
version: 2.1.0
last-reviewed: 2026-01-15
---

# CourseReviewSkill

## 審查流程
1. 使用 extract_notebook_toc 提取目錄
2. 按需加載 code-quality.md、content-accuracy.md 等
3. 調(diào)用 validate_notebook_dependencies 做結(jié)構(gòu)化檢查
4. 按模板輸出審查報(bào)告

裝配 SkillBox(只注冊(cè) course-review)

package com.baoma.ai.debug.support;

import io.agentscope.core.ReActAgent;
import io.agentscope.core.memory.InMemoryMemory;
import io.agentscope.core.model.Model;
import io.agentscope.core.skill.AgentSkill;
import io.agentscope.core.skill.SkillBox;
import io.agentscope.core.skill.repository.ClasspathSkillRepository;
import io.agentscope.core.tool.Toolkit;

import java.io.IOException;
import java.nio.file.Path;
import java.util.List;

public final class CourseReviewSkillSupport {

    private CourseReviewSkillSupport() {
    }

    public static List<AgentSkill> loadSkillsFromClasspath(String skillsRoot) throws IOException {
        try (ClasspathSkillRepository repo = new ClasspathSkillRepository(skillsRoot)) {
            return repo.getAllSkills();
        }
    }

    public static SkillBoxAndToolkit createSkillBox(Path workspace) throws IOException {
        Toolkit toolkit = new Toolkit();
        SkillBox skillBox = new SkillBox(toolkit);

        AgentSkill courseReview = null;
        for (AgentSkill skill : loadSkillsFromClasspath("skills")) {
            if (!"course-review".equals(skill.getName())) {
                continue;
            }
            skillBox.registerSkill(skill);
            courseReview = skill;
        }

        if (courseReview != null) {
            skillBox.registerSkill(courseReview);
            // 注意:registration().tool() 每次賦值會(huì)覆蓋前一個(gè),不能鏈?zhǔn)綊靸蓚€(gè) @Tool 類(lèi)
            toolkit.registerTool(new CourseReviewFileTools(workspace));
            toolkit.registerTool(new CourseReviewValidateNotebookTool(workspace));
        }

        return new SkillBoxAndToolkit(skillBox, toolkit);
    }

    public static ReActAgent createSkillBoundReviewer(
        String apiKey,
        String modelName,
        Toolkit toolkit,
        SkillBox skillBox,
        int maxIters) {

        Model model = AgentScopeDashScopeModels.buildDashScopeChatModel(apiKey, modelName);

        return ReActAgent.builder()
            .name("CourseReviewer")
            .sysPrompt("你是教程審查員。根據(jù)系統(tǒng)注入的 Skill 元數(shù)據(jù)與 load_skill 工具完成審查,輸出結(jié)構(gòu)化報(bào)告。")
            .model(model)
            .toolkit(toolkit)
            .skillBox(skillBox)
            .memory(new InMemoryMemory())
            .maxIters(maxIters)
            .build();
    }

    public record SkillBoxAndToolkit(SkillBox skillBox, Toolkit toolkit) {
    }
}

具體路徑:


image.png

第一步:注冊(cè) Skill 并查看生成的 Prompt

package com.baoma.ai.debug;

import com.baoma.ai.debug.support.CourseReviewSkillSupport;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import java.nio.file.Path;

class CourseReviewSkillPromptAgentScopeTest {

    @Test
    @DisplayName("SkillBox.getSkillPrompt 包含 course-review 的 name 與 description")
    void skillPromptContainsMetadata() throws Exception {
        var box = CourseReviewSkillSupport.createSkillBox(Path.of("."));

        String prompt = box.skillBox().getSkillPrompt();
        System.out.println("=== Skill Prompt(節(jié)選)===\n");
        System.out.println(prompt.length() > 2000
            ? prompt.substring(0, 2000) + "\n...(truncated)"
            : prompt);

        Assertions.assertTrue(prompt.contains("course-review") || prompt.contains("course_review"));
        Assertions.assertFalse(prompt.contains("反模式清單") && prompt.length() < 500,
            "完整 SKILL body 不應(yīng)全部塞進(jìn) prompt(漸進(jìn)式披露)");
    }
}

執(zhí)行。

框架讀取 frontmatter,生成類(lèi)似結(jié)構(gòu)(節(jié)選):

<available_skills>
  <skill>
    <name>course-review</name>
    <description>審查課程內(nèi)容的技術(shù)準(zhǔn)確性……</description>
    <owner>教學(xué)設(shè)計(jì)團(tuán)隊(duì)</owner>
    <version>2.1.0</version>
  </skill>
</available_skills>

提示告訴 Agent「這里有一個(gè) Skill,要用時(shí)再讀詳情」——而不是把整個(gè) SKILL.md 和所有子文件塞進(jìn) system prompt。

第二步:集成 ReActAgent 并執(zhí)行審查

package com.baoma.ai.debug;

import com.baoma.ai.debug.support.CourseReviewScopeTestSupport;
import com.baoma.ai.debug.support.CourseReviewSkillSupport;
import io.agentscope.core.ReActAgent;
import io.agentscope.core.message.Msg;
import io.agentscope.core.skill.SkillBox;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;

import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Objects;

class CourseReviewSkillBoxAgentScopeTest {

    @TempDir
    Path workspace;

    @BeforeEach
    void prepareWorkspace() throws Exception {
        try (var in = getClass().getClassLoader()
            .getResourceAsStream("agentscope-skill-demo/sample-course.ipynb")) {
            Assertions.assertNotNull(in);
            Files.copy(in, workspace.resolve("sample-course.ipynb"));
        }
    }

    @Test
    @DisplayName("AgentScope:SkillBox 加載 course-review 并審查 Notebook")
    void skillBoxCourseReview() throws Exception {
        String apiKey = CourseReviewScopeTestSupport.requireDashScopeApiKey();
        String modelName = CourseReviewScopeTestSupport.reviewModelName();
        CourseReviewScopeTestSupport.printApiKeyLoaded(apiKey);

        var box = CourseReviewSkillSupport.createSkillBox(workspace);
        SkillBox skillBox = box.skillBox();

        System.out.println("=== Skill 注入 Prompt 預(yù)覽(節(jié)選)===\n");
        String skillPrompt = skillBox.getSkillPrompt();
        System.out.println(skillPrompt.length() > 1200
            ? skillPrompt.substring(0, 1200) + "\n...(truncated)"
            : skillPrompt);

        ReActAgent agent = CourseReviewSkillSupport.createSkillBoundReviewer(
            apiKey, modelName, box.toolkit(), skillBox, 28);

        Msg user = Msg.builder()
            .textContent("""
                請(qǐng)審查工作區(qū)中的 sample-course.ipynb,評(píng)估能否發(fā)布。
                使用 course-review 技能;按需加載子規(guī)則文件;輸出結(jié)構(gòu)化審查報(bào)告。
                """)
            .build();

        System.out.println("\n[user]: " + user.getTextContent());
        Msg reply = Objects.requireNonNull(agent.call(user).block(), "Agent 返回為空");
        String text = Objects.requireNonNullElse(reply.getTextContent(), "");
        System.out.println("\n=== 審查報(bào)告(SkillBox)===\n" + text);
        Assertions.assertFalse(text.isBlank());
    }
}

執(zhí)行以上java

這次 Agent 不應(yīng)再給出「整體不錯(cuò),建議發(fā)布」的敷衍結(jié)論。它會(huì)按需加載 code-quality.md、content-accuracy.md、style-guide.md,并調(diào)用 validate_notebook_dependencies,點(diǎn)出 openpyxl 依賴(lài)、眾數(shù)填充不一致、風(fēng)格問(wèn)題等。

三個(gè)設(shè)計(jì)決策

  • 為什么只注入 description 而非全文?
    上下文窗口是公共資源??蚣苤话?description(約數(shù)十 token)注入可見(jiàn)提示;工作流程、反模式清單等內(nèi)容,由 Agent 決定使用 Skill 后再通過(guò) load_skill / read_file 按需加載。

  • 為什么 Agent 需要文件讀取工具?
    Agent 先從 description 判斷是否需要這個(gè) Skill,再讀 SKILL.md 獲取詳細(xì)指令,需要更細(xì)節(jié)時(shí)再讀子文件——漸進(jìn)式披露在框架層的落地

  • 為什么 description 字段的質(zhì)量關(guān)鍵?
    當(dāng) Agent 裝備了多個(gè) Skill 時(shí),它根據(jù) description 判斷當(dāng)前任務(wù)應(yīng)該使用哪一個(gè)。模糊描述(如「處理課程相關(guān)任務(wù)」)會(huì)導(dǎo)致匹配失??;具體描述(說(shuō)明做什么、什么時(shí)候觸發(fā))才能確保正確激活。


4.2 讓 Agent 自動(dòng)生成 Skill

手動(dòng)編寫(xiě) Skill 是必要的學(xué)習(xí)過(guò)程。熟練之后,可以讓 Agent 輔助完成初稿:本倉(cāng)庫(kù)提供 skill-creator 元 Skill(保留意圖捕獲、SKILL.md 規(guī)范、漸進(jìn)式披露;去掉與 Java 環(huán)境無(wú)關(guān)的 CLI 鏈)。

元 Skill:skill-creator.md 的具體內(nèi)容

---
name: skill-creator
description: 幫助用戶創(chuàng)建新的 Agent Skill,包括需求分析、SKILL.md 編寫(xiě)和結(jié)構(gòu)設(shè)計(jì)。當(dāng)用戶想要從零創(chuàng)建一個(gè) Skill、改進(jìn)現(xiàn)有 Skill 的結(jié)構(gòu)或內(nèi)容時(shí)使用。
---

# Skill Creator

一個(gè)幫助你創(chuàng)建高質(zhì)量 Agent Skill 的工具。

創(chuàng)建 Skill 的核心流程:

1. 明確 Skill 的目標(biāo)和觸發(fā)場(chǎng)景
2. 收集需求細(xì)節(jié)和邊界條件
3. 編寫(xiě) SKILL.md 初稿
4. 創(chuàng)建測(cè)試用例驗(yàn)證效果
5. 根據(jù)反饋迭代改進(jìn)

你的職責(zé)是判斷用戶當(dāng)前處于哪個(gè)階段,然后幫助他們推進(jìn)。如果用戶已經(jīng)有了初稿,可以直接進(jìn)入改進(jìn)階段。

---

## 創(chuàng)建 Skill

### Capture Intent(捕獲意圖)

首先理解用戶的意圖。當(dāng)前對(duì)話中可能已經(jīng)包含了用戶想要封裝的工作流(比如他們說(shuō)"把這個(gè)流程變成一個(gè) Skill")。如果是這樣,先從對(duì)話歷史中提取信息——使用了哪些工具、步驟順序、用戶做了哪些修正、觀察到的輸入輸出格式。用戶可能需要補(bǔ)充細(xì)節(jié),確認(rèn)后再進(jìn)入下一步。

1. 這個(gè) Skill 要讓 Agent 完成什么任務(wù)?
2. 什么情況下應(yīng)該觸發(fā)這個(gè) Skill?(哪些用戶提問(wèn)/場(chǎng)景)
3. 期望的輸出格式是什么?
4. 是否需要設(shè)置測(cè)試用例來(lái)驗(yàn)證 Skill 的效果?有客觀可驗(yàn)證輸出的 Skill(文件轉(zhuǎn)換、數(shù)據(jù)提取、代碼生成、固定流程步驟)適合測(cè)試用例;主觀輸出的 Skill(寫(xiě)作風(fēng)格、設(shè)計(jì))通常不需要。根據(jù) Skill 類(lèi)型建議合適的默認(rèn)方案,但讓用戶決定。

### Interview and Research(訪談與調(diào)研)

主動(dòng)詢(xún)問(wèn)邊界情況、輸入輸出格式、示例文件、成功標(biāo)準(zhǔn)和依賴(lài)關(guān)系。在搞清楚這些之前,不要急著寫(xiě)測(cè)試用例。

如果有可用的工具(搜索文檔、查找類(lèi)似 Skill、查閱最佳實(shí)踐),先做調(diào)研,帶著充分的上下文來(lái)減輕用戶的負(fù)擔(dān)。

### Write the SKILL.md(編寫(xiě) SKILL.md)

基于用戶訪談,填寫(xiě)以下組成部分:

- **name**:Skill 標(biāo)識(shí)符
- **description**:觸發(fā)條件和功能描述。這是主要的觸發(fā)機(jī)制——既要說(shuō)明 Skill 做什么,也要說(shuō)明何時(shí)使用。所有"何時(shí)使用"的信息都放在這里,而不是放在正文中。注意:為了確保觸發(fā)率,description 應(yīng)該適度"積極"。例如,與其寫(xiě)"構(gòu)建數(shù)據(jù)可視化面板",不如寫(xiě)"構(gòu)建數(shù)據(jù)可視化面板。當(dāng)用戶提到儀表盤(pán)、數(shù)據(jù)展示、指標(biāo)監(jiān)控,或想要展示任何類(lèi)型的數(shù)據(jù)時(shí)都應(yīng)使用此 Skill,即使他們沒(méi)有明確要求'面板'。"
- **compatibility**:所需工具、依賴(lài)(可選,很少需要)
- **正文內(nèi)容**

---

## Skill 編寫(xiě)指南

### Skill 的結(jié)構(gòu)


skill-name/
├── SKILL.md (必需)
│   ├── YAML frontmatter (name, description 必填)
│   └── Markdown 指令
└── Bundled Resources (可選)
    ├── scripts/    - 用于確定性/重復(fù)性任務(wù)的可執(zhí)行代碼
    ├── references/ - 按需加載到上下文中的文檔
    └── assets/     - 輸出中使用的文件(模板、圖標(biāo)、字體)


### Progressive Disclosure(漸進(jìn)式披露)

Skill 使用三級(jí)加載系統(tǒng):

1. **元數(shù)據(jù)**(name + description)- 始終在上下文中(約 100 詞)
2. **SKILL.md 正文** - Skill 觸發(fā)時(shí)加載(理想情況 <500 行)
3. **捆綁資源** - 按需加載(不限大小,腳本可以在不加載的情況下執(zhí)行)

這些字?jǐn)?shù)是近似值,如果需要可以更長(zhǎng)。

**關(guān)鍵模式:**
- 保持 SKILL.md 在 500 行以?xún)?nèi);如果接近這個(gè)限制,添加層級(jí)結(jié)構(gòu)并指明下一步應(yīng)該閱讀哪些文件
- 在 SKILL.md 中清晰引用文件,并說(shuō)明何時(shí)應(yīng)該讀取它們
- 對(duì)于大型參考文件(>300 行),包含目錄

**領(lǐng)域組織**:當(dāng) Skill 支持多個(gè)領(lǐng)域/框架時(shí),按變體組織:


cloud-deploy/
├── SKILL.md (工作流 + 選擇邏輯)
└── references/
    ├── aws.md
    ├── gcp.md
    └── azure.md


Agent 只讀取相關(guān)的參考文件。

### 安全原則

Skill 不得包含惡意軟件、利用代碼或任何可能危害系統(tǒng)安全的內(nèi)容。Skill 的內(nèi)容在被描述時(shí)不應(yīng)讓用戶感到意外。不要?jiǎng)?chuàng)建誤導(dǎo)性的 Skill 或旨在促進(jìn)未授權(quán)訪問(wèn)的 Skill。

### 編寫(xiě)模式

在指令中優(yōu)先使用祈使句。

**定義輸出格式**——可以這樣做:

markdown
## 報(bào)告結(jié)構(gòu)
始終使用這個(gè)模板:
# [標(biāo)題]
## 摘要
## 關(guān)鍵發(fā)現(xiàn)
## 建議


**示例模式**——包含示例很有用:

markdown
## Commit 消息格式
**示例 1:**
Input: Added user authentication with JWT tokens
Output: feat(auth): implement JWT-based authentication


### 編寫(xiě)風(fēng)格

盡量向模型解釋"為什么"事情很重要,而不是堆砌強(qiáng)硬的 MUST/NEVER。利用心智理論,讓 Skill 通用化而非局限于特定示例。先寫(xiě)初稿,然后用新鮮的眼光審視并改進(jìn)。

---

## 迭代改進(jìn)

### 如何思考改進(jìn)方向

1. **從反饋中泛化。** 我們創(chuàng)建的 Skill 將被在各種不同的場(chǎng)景中使用。不要針對(duì)測(cè)試用例過(guò)度擬合,而是理解用戶反饋背后的通用模式。與其添加僵硬的限制條件,不如嘗試不同的表達(dá)方式或工作模式。

2. **保持指令精簡(jiǎn)。** 移除沒(méi)有發(fā)揮作用的內(nèi)容。如果 Agent 在執(zhí)行 Skill 時(shí)浪費(fèi)時(shí)間在無(wú)用的步驟上,考慮刪除導(dǎo)致這種行為的指令部分。

3. **解釋為什么。** 盡量解釋每條指令背后的原因。當(dāng)前的大模型很聰明,給出好的上下文后能超越機(jī)械執(zhí)行。如果你發(fā)現(xiàn)自己在寫(xiě) ALWAYS 或 NEVER(全大寫(xiě)),這是一個(gè)信號(hào)——重新表述,解釋推理過(guò)程,讓模型理解為什么這很重要。

4. **尋找重復(fù)工作。** 如果多個(gè)測(cè)試用例中 Agent 都獨(dú)立編寫(xiě)了類(lèi)似的輔助腳本,這強(qiáng)烈暗示 Skill 應(yīng)該捆綁該腳本。寫(xiě)一次,放在 `scripts/` 中,讓 Skill 指引 Agent 使用它。

---

## 測(cè)試用例

編寫(xiě) Skill 初稿后,構(gòu)思 2-3 個(gè)真實(shí)的測(cè)試提示——真正的用戶會(huì)實(shí)際說(shuō)的話。與用戶分享:"這是我想測(cè)試的幾個(gè)用例,看起來(lái)合理嗎?需要補(bǔ)充嗎?"

好的測(cè)試用例是具體的、有細(xì)節(jié)的,而不是抽象的請(qǐng)求。

不好:`"格式化這個(gè)數(shù)據(jù)"`, `"從 PDF 中提取文本"`

好:`"我老板剛發(fā)了一個(gè) xlsx 文件給我(在我的下載目錄里,叫'Q4銷(xiāo)售數(shù)據(jù)_最終版v2.xlsx'),她讓我加一列利潤(rùn)率百分比。營(yíng)收在 C 列,成本在 D 列。"

write_file 工具(與 read_file 對(duì)稱(chēng))

package com.baoma.ai.debug.support;

import io.agentscope.core.tool.Tool;
import io.agentscope.core.tool.ToolParam;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;

public class CourseReviewWriteFileTools {

    private final Path workspaceRoot;

    public CourseReviewWriteFileTools(Path workspaceRoot) {
        this.workspaceRoot = workspaceRoot;
    }

    @Tool(name = "write_file", description = "將內(nèi)容寫(xiě)入工作區(qū)相對(duì)路徑;目錄不存在則自動(dòng)創(chuàng)建")
    public String writeFile(
        @ToolParam(name = "path", description = "相對(duì)路徑,如 skills/api-doc-review/SKILL.md")
        String path,
        @ToolParam(name = "content", description = "文件全文")
        String content) throws IOException {

        Path target = workspaceRoot.resolve(path).normalize();
        if (!target.startsWith(workspaceRoot.normalize())) {
            return "錯(cuò)誤:路徑越界";
        }
        if (target.getParent() != null) {
            Files.createDirectories(target.getParent());
        }
        Files.writeString(target, content);
        return "已寫(xiě)入 " + path;
    }
}

裝配 skill-creator + 創(chuàng)建 Agent

package com.baoma.ai.debug.support;

import io.agentscope.core.ReActAgent;
import io.agentscope.core.memory.InMemoryMemory;
import io.agentscope.core.model.Model;
import io.agentscope.core.skill.AgentSkill;
import io.agentscope.core.skill.SkillBox;
import io.agentscope.core.skill.repository.ClasspathSkillRepository;
import io.agentscope.core.tool.Toolkit;

import java.io.IOException;
import java.nio.file.Path;

public final class SkillCreatorSupport {

    private SkillCreatorSupport() {
    }

    public static SkillBoxAndToolkit createCreatorSkillBox(Path workspace) throws IOException {
        Toolkit toolkit = new Toolkit();
        SkillBox skillBox = new SkillBox(toolkit);

        AgentSkill creator = null;
        try (ClasspathSkillRepository repo = new ClasspathSkillRepository("skills")) {
            for (AgentSkill skill : repo.getAllSkills()) {
                if ("skill-creator".equals(skill.getName())) {
                    creator = skill;
                    skillBox.registerSkill(skill);
                }
            }
        }

        if (creator != null) {
            skillBox.registerSkill(creator);
            toolkit.registerTool(new CourseReviewFileTools(workspace));
            toolkit.registerTool(new CourseReviewWriteFileTools(workspace));
        }

        return new SkillBoxAndToolkit(skillBox, toolkit);
    }

    public static ReActAgent createSkillCreatorAgent(
        String apiKey,
        String modelName,
        Toolkit toolkit,
        SkillBox skillBox) {

        Model model = AgentScopeDashScopeModels.buildDashScopeChatModel(apiKey, modelName);

        return ReActAgent.builder()
            .name("SkillCreator")
            .sysPrompt("你是一個(gè) Agent Skill 設(shè)計(jì)師。遵循 skill-creator 技能指引生成符合規(guī)范的 Skill 目錄。")
            .model(model)
            .toolkit(toolkit)
            .skillBox(skillBox)
            .memory(new InMemoryMemory())
            .maxIters(16)
            .build();
    }

    public record SkillBoxAndToolkit(SkillBox skillBox, Toolkit toolkit) {
    }
}

加載 skill-creator 并生成新 Skill

package com.baoma.ai.debug;

import com.baoma.ai.debug.support.CourseReviewScopeTestSupport;
import com.baoma.ai.debug.support.SkillCreatorSupport;
import io.agentscope.core.ReActAgent;
import io.agentscope.core.message.Msg;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;

import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Objects;

class SkillCreatorAgentScopeTest {

    @TempDir
    Path workspace;

    @Test
    @DisplayName("AgentScope:skill-creator 生成 api-doc-review Skill 目錄")
    void generateApiDocReviewSkill() throws Exception {
        String apiKey = CourseReviewScopeTestSupport.requireDashScopeApiKey();
        String modelName = CourseReviewScopeTestSupport.reviewModelName();
        CourseReviewScopeTestSupport.printApiKeyLoaded(apiKey);

        var box = SkillCreatorSupport.createCreatorSkillBox(workspace);
        ReActAgent creator = SkillCreatorSupport.createSkillCreatorAgent(
            apiKey, modelName, box.toolkit(), box.skillBox());

        Msg user = Msg.builder()
            .textContent("""
                幫我創(chuàng)建一個(gè)審核 REST API 文檔的 Skill,目錄名 api-doc-review。
                要檢查:1. 所有端點(diǎn)是否有示例請(qǐng)求和響應(yīng);
                2. 錯(cuò)誤碼是否有說(shuō)明;3. 參數(shù)是否有類(lèi)型標(biāo)注。
                請(qǐng)用 write_file 寫(xiě)入 skills/api-doc-review/SKILL.md 及必要的子文件。
                """)
            .build();

        System.out.println("[user]: " + user.getTextContent());
        Msg reply = Objects.requireNonNull(creator.call(user).block());
        System.out.println("\n=== Skill Creator 回復(fù) ===\n" + reply.getTextContent());

        Path skillMd = workspace.resolve("skills/api-doc-review/SKILL.md");
        if (Files.isRegularFile(skillMd)) {
            System.out.println("\n=== 已生成 SKILL.md ===\n" + Files.readString(skillMd));
            Assertions.assertTrue(Files.readString(skillMd).contains("api-doc-review")
                || Files.readString(skillMd).contains("API"));
        } else {
            System.out.println("\n[提示] 模型可能未調(diào)用 write_file;請(qǐng)檢查回復(fù)或重跑。");
            Assertions.assertFalse(Objects.requireNonNullElse(reply.getTextContent(), "").isBlank());
        }
    }
}

執(zhí)行上面的最終方法。

Agent 可能生成完整的 api-doc-review/ 目錄;也可能只回復(fù)計(jì)劃而未調(diào)用 write_file——可多跑幾次。

這是加速,不是替代。 你仍需理解上篇五步編寫(xiě)法,才能判斷 Agent 生成的內(nèi)容是否合理。專(zhuān)家用 skill-creator 快速產(chǎn)出高質(zhì)量 Skill;不理解設(shè)計(jì)原則的新手,即使有元 Skill 的創(chuàng)建的skill也很難產(chǎn)出可用結(jié)果。

小貼士:生成的 Skill 初稿一定要配合上篇 「雙 Agent」評(píng)測(cè) + 本篇中的skill的規(guī)范。自動(dòng)生成只解決「寫(xiě)出來(lái)」;評(píng)測(cè)解決「寫(xiě)得對(duì)不對(duì)」。


4.3 Skill 市場(chǎng):復(fù)用社區(qū)的專(zhuān)家知識(shí)

前兩節(jié)介紹了注冊(cè)和生成自建 Skill。在更廣的 Coding Agent 生態(tài)中,社區(qū)已形成 Skill 共享平臺(tái)。

發(fā)現(xiàn) Skill

# 按關(guān)鍵詞搜索
npx skills find typescript

# 輸出示例:
# Install with npx skills add <owner/repo@skill>
# vercel-labs/agent-skills@typescript-best-practices

不帶參數(shù)運(yùn)行 npx skills find 可進(jìn)入交互式模糊搜索。找到感興趣的 Skill 后,在平臺(tái)詳情頁(yè)查看完整內(nèi)容與安全審計(jì)評(píng)級(jí)。

安裝和使用

npx skills add vercel-labs/agent-skills --skill vercel-react-best-practices
npx skills update

安裝后,Skill 就是一組 Markdown 文件,與上篇結(jié)構(gòu)一致。Java 側(cè)將目錄放入工程的 skills/ 資源,用 ClasspathSkillRepository(開(kāi)發(fā))或 FileSystemSkillRepository(部署)加載。

社區(qū) Skill 與自建 Skill 的分工

場(chǎng)景 推薦方式
通用技術(shù)最佳實(shí)踐(React 性能、代碼規(guī)范) 社區(qū) Skill
成熟的行業(yè)標(biāo)準(zhǔn)流程(安全審計(jì)、SEO) 社區(qū) Skill
企業(yè)內(nèi)部業(yè)務(wù)流程和質(zhì)量標(biāo)準(zhǔn) 自建 Skill
團(tuán)隊(duì)特有的代碼規(guī)范和架構(gòu)約定 自建 Skill
領(lǐng)域?qū)<业碾[性知識(shí)(如課程審核) 自建 Skill

使用時(shí)的注意事項(xiàng)

  • 避免 Skill 過(guò)多:過(guò)多 Skill 會(huì)撐滿 system prompt,稀釋核心指令
  • 注意版本匹配:依賴(lài)的工具或框架更新后,Skill 內(nèi)命令可能過(guò)時(shí)
  • 合理預(yù)期:Skill 提升的是下限(少犯低級(jí)錯(cuò)誤),不是無(wú)限抬高上限

4.4 本節(jié)回顧

本節(jié)圍繞 Skill 的「用起來(lái)」展開(kāi)三個(gè)層次:

層次 要點(diǎn)
注冊(cè)與加載(§4.1) SkillBox + getSkillPrompt 只注入 description;Agent 按需讀詳細(xì)指令——漸進(jìn)式披露在框架層的落地
自動(dòng)生成(§4.2) skill-creator 元 Skill + write_file 生成初稿;仍需評(píng)測(cè)驗(yàn)證
社區(qū)復(fù)用(§4.3) npx skills 發(fā)現(xiàn)/安裝;與自建 Skill 互補(bǔ)

5 當(dāng) Skill 遇上團(tuán)隊(duì)

5.1 一個(gè)人的成功,十個(gè)人的混亂

你在 §4 中成功構(gòu)建了 course-review,把課程審核時(shí)間從 2 小時(shí)縮短到約 20 分鐘。主管很滿意,讓你把這個(gè) Skill 推廣給整個(gè)教學(xué)設(shè)計(jì)團(tuán)隊(duì)——10 個(gè)人。你把 SKILL.md 發(fā)到群里,附了一段簡(jiǎn)短的使用說(shuō)明。

一個(gè)月后,問(wèn)題接踵而至。

版本混亂:你根據(jù)最新的課程標(biāo)準(zhǔn)更新了評(píng)分權(quán)重,但有 3 位同事還在用舊版 Skill。同一門(mén)課程被審出矛盾的結(jié)論——你的報(bào)告說(shuō)「結(jié)構(gòu)合理」,同事的報(bào)告說(shuō)「章節(jié)劃分不當(dāng)」。團(tuán)隊(duì)不得不花半天時(shí)間排查,才發(fā)現(xiàn)是 Skill 版本不一致。

誤修改:實(shí)習(xí)生覺(jué)得 SKILL.md 中「避免使用 print() 進(jìn)行調(diào)試」這條規(guī)則太嚴(yán)格,自行改成了「允許在開(kāi)發(fā)階段使用 print()」。結(jié)果 Agent 開(kāi)始把所有 print() 調(diào)試代碼標(biāo)記為「符合規(guī)范」,三周后才被發(fā)現(xiàn)。

知識(shí)斷檔:你休假兩周,團(tuán)隊(duì)遇到 3 個(gè)審核邊界問(wèn)題——「代碼示例中的注釋算不算教學(xué)內(nèi)容?」「引用外部 API 文檔需不需要檢查鏈接有效性?」——沒(méi)人能回答,因?yàn)檫@些判斷邏輯只存在于你的經(jīng)驗(yàn)中,沒(méi)有寫(xiě)進(jìn) Skill。

這三個(gè)問(wèn)題有一個(gè)共同點(diǎn):CourseReviewSkill 作為一個(gè)人的作品運(yùn)轉(zhuǎn)良好,但它沒(méi)有為團(tuán)隊(duì)協(xié)作而設(shè)計(jì)。


5.2 樸素修補(bǔ):為什么「群里發(fā)一下」行不通

面對(duì)這些問(wèn)題,你可能會(huì)想到幾個(gè)直覺(jué)性的修補(bǔ)方案。

統(tǒng)一存放位置 — 把 Skill 放到共享網(wǎng)盤(pán)。但誰(shuí)有權(quán)修改?如果 10 個(gè)人都能改,就等于沒(méi)人負(fù)責(zé)。

發(fā)一份使用說(shuō)明文檔 — 文檔和 Skill 分離,兩周后 Skill 迭代了,文檔還停留在舊版本。

由你一個(gè)人負(fù)責(zé)所有修改 — 你成了瓶頸,且你不是所有審核領(lǐng)域的專(zhuān)家。

這些修補(bǔ)失敗的根本原因在于:Skill 不是普通配置文件,而是封裝了專(zhuān)家知識(shí)的可執(zhí)行資產(chǎn)。管理它需要明確的所有權(quán)工程化的生命周期。

換一個(gè)角度:Skill 是能力放大器——資深設(shè)計(jì)師一周審 10 門(mén)課,封裝成 Skill 后,10 名初級(jí)成員都能調(diào)用。但要讓放大器在團(tuán)隊(duì)中穩(wěn)定運(yùn)轉(zhuǎn),需要解決 所有權(quán)、協(xié)作流程、質(zhì)量保障

image.png


5.3 領(lǐng)域團(tuán)隊(duì)所有權(quán):讓最懂業(yè)務(wù)的人管 Skill

誰(shuí)最有能力定義和維護(hù) course-review?教學(xué)設(shè)計(jì)團(tuán)隊(duì)——他們最了解「什么樣的課程才算好」。

新的分工模式

角色 職責(zé)
專(zhuān)家 (Expert) 定義標(biāo)準(zhǔn)、封裝 Skill、審核變更
團(tuán)隊(duì)成員 (Member) 調(diào)用 Skill、反饋問(wèn)題、提交改進(jìn)建議

專(zhuān)家從「親自執(zhí)行每一次審核」轉(zhuǎn)變?yōu)椤妇S護(hù)審核標(biāo)準(zhǔn)」,影響力從線性增長(zhǎng)變?yōu)榭蓮?fù)制的規(guī)?;?。

不同領(lǐng)域的 Skill 由對(duì)應(yīng)業(yè)務(wù)團(tuán)隊(duì)負(fù)責(zé)

領(lǐng)域 所有權(quán)團(tuán)隊(duì) 維護(hù)的 Skill 示例
課程質(zhì)量 教學(xué)設(shè)計(jì)團(tuán)隊(duì) CourseReviewSkill
數(shù)據(jù)分析 數(shù)據(jù)團(tuán)隊(duì) DataCleaningSkill
安全合規(guī) 安全團(tuán)隊(duì) CodeSecurityScanSkill

業(yè)務(wù)專(zhuān)家 + 技術(shù)人員協(xié)作

角色 職責(zé)
業(yè)務(wù)專(zhuān)家 (SOP Owner) 制定流程標(biāo)準(zhǔn)與邊界條件
技術(shù)人員 (Agent Architect) Skill 結(jié)構(gòu)調(diào)優(yōu)與工具掛載

協(xié)作流程分三步:

  • 1、業(yè)務(wù)專(zhuān)家用自然語(yǔ)言描述"一個(gè)優(yōu)秀的審核員會(huì)怎么做"
  • 2、技術(shù)人員將其轉(zhuǎn)化為結(jié)構(gòu)化的 Skill 格式
  • 3、雙方一起測(cè)試、迭代、根據(jù) Agent 實(shí)際產(chǎn)出調(diào)整指令

為了在 Skill 文件中明確所有權(quán)信息,可以在 YAML frontmatter 中添加管理元數(shù)據(jù):
在 frontmatter 中明確所有權(quán)

---
name: course-review
description: |
  審核課程內(nèi)容的質(zhì)量和結(jié)構(gòu)完整性。當(dāng)用戶要求檢查、審核或評(píng)估課程材料時(shí)觸發(fā)。
owner: 教學(xué)設(shè)計(jì)團(tuán)隊(duì)
maintainers:
  - zhang-wei
  - li-na
version: 2.1.0
last-reviewed: 2026-01-15
---

這些字段讓任何人打開(kāi)文件就能知道:有問(wèn)題找誰(shuí)、當(dāng)前是什么版本、上次審查是什么時(shí)候。

小貼士:GitHub 可配置 CODEOWNERS,例如 /skills/course-review/ @teaching-design-team,對(duì)該路徑的修改自動(dòng)要求教學(xué)設(shè)計(jì)團(tuán)隊(duì)審批。

/skills/course-review/    @org/course-quality
/skills/skill-creator/    @org/agent-platform

5.4 Skills-as-Code:用工程方法管理 Skill 資產(chǎn)

所有權(quán)明確后,下一個(gè)問(wèn)題是:團(tuán)隊(duì)如何協(xié)作迭代 Skill?答案是把 Skill 當(dāng)作代碼來(lái)管理——version control、code review、CI/CD。這些軟件工程的成熟實(shí)踐同樣適用于 Skill。

Skills-as-Code 生命周期

image.png

階段 說(shuō)明
1、本地迭代 維護(hù)者在本地修改 Skill,用幾個(gè)代表性案例快速驗(yàn)證效果
2、PR / Review 提交 Pull Request,由團(tuán)隊(duì)其他成員(尤其是業(yè)務(wù)專(zhuān)家)審查變更
3、CI 評(píng)測(cè) 自動(dòng)化流水線運(yùn)行評(píng)測(cè)用例,確保修改沒(méi)有引入回歸問(wèn)題
4、部署上線 合并到主分支后,所有使用該 Skill 的 Agent 自動(dòng)獲取最新版本
5、反饋收集 跟蹤使用情況,驅(qū)動(dòng)改進(jìn)

將 classpath 中的 skills 部署到磁盤(pán)(模擬 CI 構(gòu)建拷貝)

package com.baoma.ai.debug.support;

import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;

public final class SkillsAsCodeDeploySupport {

    private SkillsAsCodeDeploySupport() {
    }

    public static Path deployClasspathSkillsTo(Path targetSkillsRoot) throws IOException {
        Files.createDirectories(targetSkillsRoot);
        ClassLoader cl = SkillsAsCodeDeploySupport.class.getClassLoader();
        deploySkillDir(cl, targetSkillsRoot, "course-review");
        deploySkillDir(cl, targetSkillsRoot, "skill-creator");
        return targetSkillsRoot;
    }

    private static void deploySkillDir(ClassLoader cl, Path targetRoot, String skillName) throws IOException {
        Path skillDir = targetRoot.resolve(skillName);
        Files.createDirectories(skillDir);
        String prefix = "skills/" + skillName + "/";
        copyResource(cl, prefix + "SKILL.md", skillDir.resolve("SKILL.md"));
        copyIfExists(cl, prefix + "code-quality.md", skillDir.resolve("code-quality.md"));
        copyIfExists(cl, prefix + "content-accuracy.md", skillDir.resolve("content-accuracy.md"));
        copyIfExists(cl, prefix + "style-guide.md", skillDir.resolve("style-guide.md"));
        copyIfExists(cl, prefix + "outdated-api.md", skillDir.resolve("outdated-api.md"));
    }

    private static void copyResource(ClassLoader cl, String cp, Path dest) throws IOException {
        try (InputStream in = cl.getResourceAsStream(cp)) {
            if (in == null) {
                throw new IOException("classpath 資源不存在: " + cp);
            }
            Files.copy(in, dest, StandardCopyOption.REPLACE_EXISTING);
        }
    }

    private static void copyIfExists(ClassLoader cl, String cp, Path dest) throws IOException {
        try (InputStream in = cl.getResourceAsStream(cp)) {
            if (in != null) {
                Files.copy(in, dest, StandardCopyOption.REPLACE_EXISTING);
            }
        }
    }

    public static void copyDirectoryFromClasspath(Path targetSkillsRoot) throws IOException {
        deployClasspathSkillsTo(targetSkillsRoot);
    }
}

從磁盤(pán)加載:FileSystemSkillRepository

package com.baoma.ai.debug;

import com.baoma.ai.debug.support.SkillsAsCodeDeploySupport;
import io.agentscope.core.skill.AgentSkill;
import io.agentscope.core.skill.repository.FileSystemSkillRepository;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;

import java.nio.file.Path;

class FileSystemSkillRepositoryAgentScopeTest {

    @TempDir
    Path skillsRoot;

    @Test
    @DisplayName("FileSystemSkillRepository 從磁盤(pán)加載 course-review")
    void loadSkillFromFilesystem() throws Exception {
        SkillsAsCodeDeploySupport.deployClasspathSkillsTo(skillsRoot);

        try (FileSystemSkillRepository repo = new FileSystemSkillRepository(skillsRoot)) {
            Assertions.assertTrue(repo.skillExists("course-review"));

            AgentSkill skill = repo.getSkill("course-review");
            Assertions.assertEquals("course-review", skill.getName());
            Assertions.assertTrue(skill.getDescription().contains("審查"));
            Assertions.assertTrue(skill.getSkillContent().contains("審查流程"));

            System.out.println("Repository source: " + repo.getSource());
            System.out.println("Skill version metadata: " + skill.getMetadataValue("version"));
        }
    }
}

frontmatter CI 校驗(yàn)器

package com.baoma.ai.debug.support;

import io.agentscope.core.skill.util.MarkdownSkillParser;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

public final class SkillFrontmatterValidator {

    private static final Set<String> REQUIRED_FIELDS = Set.of(
        "name", "description", "owner", "version", "last-reviewed"
    );

    private SkillFrontmatterValidator() {
    }

    public static List<String> validateSkillFile(Path skillMdPath) throws IOException {
        List<String> errors = new ArrayList<>();
        if (!Files.isRegularFile(skillMdPath)) {
            errors.add("文件不存在: " + skillMdPath);
            return errors;
        }
        String content = Files.readString(skillMdPath);
        var parsed = MarkdownSkillParser.parse(content);
        Map<String, Object> meta = parsed.getMetadata();
        for (String field : REQUIRED_FIELDS) {
            if (!meta.containsKey(field) || meta.get(field) == null
                || meta.get(field).toString().isBlank()) {
                errors.add("缺少必需字段: " + field);
            }
        }
        if (parsed.getContent() == null || parsed.getContent().isBlank()) {
            errors.add("Markdown body 為空");
        }
        return errors;
    }
}

單測(cè):PR 階段 frontmatter 門(mén)禁

package com.baoma.ai.debug;

import com.baoma.ai.debug.support.SkillFrontmatterValidator;
import com.baoma.ai.debug.support.SkillsAsCodeDeploySupport;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;

import java.nio.file.Path;
import java.util.List;

class SkillFrontmatterValidationTest {

    @TempDir
    Path skillsRoot;

    @Test
    @DisplayName("course-review SKILL.md 通過(guò) frontmatter 校驗(yàn)")
    void courseReviewSkillPassesValidation() throws Exception {
        SkillsAsCodeDeploySupport.deployClasspathSkillsTo(skillsRoot);

        Path skillMd = skillsRoot.resolve("course-review/SKILL.md");
        List<String> errors = SkillFrontmatterValidator.validateSkillFile(skillMd);

        System.out.println("校驗(yàn)結(jié)果: " + (errors.isEmpty() ? "通過(guò)" : errors));
        Assertions.assertTrue(errors.isEmpty(), () -> String.join("; ", errors));
    }
}

GitHub Actions 示例(Maven 評(píng)測(cè))

name: validate-skills
on:
  pull_request:
    paths:
      - 'module-ai/src/test/resources/skills/**'
      - 'skills/**'
jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-java@v4
        with:
          java-version: '21'
          distribution: 'temurin'
      - name: Check SKILL.md metadata
        run: mvn -pl module-ai test -Dtest=SkillFrontmatterValidationTest
      - name: Run skill evaluation
        env:
          DASHSCOPE_API_KEY: ${{ secrets.DASHSCOPE_API_KEY }}
        run: mvn -pl module-ai test -Dtest=CourseReviewSkillBoxAgentScopeTest

廢棄與清理(建議每季度)

  • 過(guò)去 3 個(gè)月未被調(diào)用 → 考慮歸檔
  • 對(duì)應(yīng)的業(yè)務(wù)流程已取消 → 立即刪除
  • 與其他 Skill 功能重疊 → 合并精簡(jiǎn)

核心度量

指標(biāo) 定義 意義
復(fù)用率 Skill 被不同成員調(diào)用的頻次 只有被反復(fù)調(diào)用的 Skill 才是有效資產(chǎn)
交付標(biāo)準(zhǔn)一致性 新手使用 Skill 后的產(chǎn)出 vs 專(zhuān)家基線 衡量 Skill 是否真正傳遞了專(zhuān)家能力

5.5 落地路徑:從種子團(tuán)隊(duì)到全面推廣

理解了所有權(quán)和工程化管理之后,推薦 「種子 Skill」 策略,不要一步全員鋪開(kāi):

步驟 動(dòng)作
1 選 3~5 人先鋒隊(duì)
2 聚焦一個(gè)高價(jià)值痛點(diǎn)(課程審核、Code Review、數(shù)據(jù)清洗)
3 跑通閉環(huán):識(shí)別專(zhuān)家知識(shí) → 封裝 Skill → 評(píng)測(cè)驗(yàn)證 → 團(tuán)隊(duì)試用
4 用數(shù)據(jù)說(shuō)服其余團(tuán)隊(duì)(審核時(shí)間縮短 X%、質(zhì)量達(dá)專(zhuān)家水平 Y%)

4 周落地清單

周次 動(dòng)作 產(chǎn)出
W1 課程審查場(chǎng)景 course-review + 至少 1 個(gè) @Tool
W2 frontmatter + CODEOWNERS frontmatter 單測(cè)進(jìn) CI
W3 2 個(gè)黃金 Notebook 樣例 SkillBox 審查回歸門(mén)禁
W4 skill-creator 第二個(gè) Skill api-doc-review 初稿 + 人審 + 評(píng)測(cè)

治理演進(jìn)

維度 試點(diǎn)期 推廣期
誰(shuí)寫(xiě) 技術(shù)骨干 + 業(yè)務(wù)專(zhuān)家 任何成員可提交
誰(shuí)審 同行 Code Review Skill 審核組 / CODEOWNERS
誰(shuí)批準(zhǔn) 團(tuán)隊(duì)負(fù)責(zé)人 領(lǐng)域負(fù)責(zé)人

引入 Skill 初期(1~3 個(gè)月)效率可能不升反降——學(xué)習(xí)規(guī)范、調(diào)試 Agent、建評(píng)測(cè)都需要時(shí)間。讓管理層有預(yù)期,用試點(diǎn)數(shù)據(jù)建立信心。

責(zé)任歸屬:Agent 調(diào)用 Skill 產(chǎn)出經(jīng)人合并上線時(shí),Merge 即負(fù)責(zé)——點(diǎn)合并的人對(duì)結(jié)果承擔(dān)最終責(zé)任。

小結(jié)回顧:

1、推廣困境:個(gè)人構(gòu)建的 Skill 在團(tuán)隊(duì)中使用時(shí),會(huì)遇到版本混亂、誤修改和知識(shí)斷檔三類(lèi)問(wèn)題.
2、能力放大器:Skill 的核心價(jià)值是將專(zhuān)家能力規(guī)?;瘡?fù)制,但需要所有權(quán)和工程化流程來(lái)保障
3、領(lǐng)域團(tuán)隊(duì)所有權(quán):最有度量能力的團(tuán)隊(duì)擁有并維護(hù)對(duì)應(yīng)領(lǐng)域的 Skill,通過(guò) YAML 元數(shù)據(jù)和 CODEOWNERS 明確權(quán)責(zé)。

4、Skills-as-Code:將 Skill 當(dāng)作代碼管理,走 PR → Review → CI 評(píng)測(cè) → 部署的完整工程生命周期。
5、落地策略:從種子團(tuán)隊(duì)開(kāi)始,聚焦高價(jià)值痛點(diǎn),用數(shù)據(jù)說(shuō)話,逐步推廣到全組織。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容