Organizing and Distributing: Plugins and Marketplaces, Versioning and Team Sharing, and the Division of Labor Between Function Calling, MCP, and Skills
Go from one person's folder to a team's capability pack: how to organize a plugin, how to publish to a marketplace, how to version it, and exactly what function calling, MCP, and Skills each handle and when to reach for which.
Today's Goals
- Package a group of skills into a plugin with a manifest and a version, and load it locally to verify it
- Explain the three paths for sharing skills across a team and when each fits
- Use a comparison table to explain the division of labor between function calling, MCP, and Skills, and give selection criteria
Everything you built over five days still lives only on your own machine. Today you hand it over: how a set of skills becomes one package, how it is published, how versions get bumped, and how a dozen people share one copy. Then we settle the debt this course has owed you since day one — what function calling, MCP, and Skills each actually govern. Once you have read the walkthrough and finished the lab, scroll back to the top and tick off the three goals.
Plain-Language Walkthrough
From one folder to a package
Back to the filing cabinet. You now hold five or six sets of work instructions, and leaving them loose is workable. But the moment you hand them to the department next door, problems appear: they have a folder called "quarterly report" too, so the names collide; you later changed two of the pages and they have no idea whether to update; they only want three of the folders and the other two are irrelevant to them.
Those three problems — namespacing, versioning, boundaries — are everything packaging solves. A package is not a zip of some folders; it is a declaration that these ones are a set, handed over together and upgraded together.
When should things merge into one package? The criterion is whether they are adopted together and retired together. Three of them orbiting the same set of team conventions, where anyone installing one must install all, are one package. One team convention plus one personal debugging habit thrown together only forces somebody to accept the half they did not want.
Conversely, when should one skill split into two? The criterion came on day three, and here is only its package-level corollary: if two parts' trigger situations do not overlap, they should not share one description. Packaging cannot rescue a skill with a blurry boundary; it only amplifies the blur across the whole team.
A plugin's directory layout and manifest
The spec itself defines only that a skill is a folder containing a SKILL.md, and it says nothing about distribution. So the package layer is each client's own mechanism, with different names and details, and you have to follow whichever you actually use. Below uses Claude Code's plugins as the example, because it is currently the most fully documented, and understanding it makes the others quick to read.
A plugin is a directory with a manifest at its root and component directories laid out by convention:
team-conventions/
├── .claude-plugin/
│ └── plugin.json # the manifest: name, description, version, author
├── skills/
│ ├── commit-message/SKILL.md
│ ├── code-review/SKILL.md
│ └── release-report/SKILL.md
├── agents/ # optional: subagent definitions
├── hooks/hooks.json # optional: event hooks
├── .mcp.json # optional: MCP server configuration shipped with the package
└── README.mdThe manifest itself is extremely short, with four fields:
{
"name": "team-conventions",
"description": "A team's commit, review, and release conventions; effective as soon as installed",
"version": "1.2.0",
"author": { "name": "Platform Team" }
}Two of those four fields carry rules that are easy to trip over.
First, name is the namespace. Skills in the package get prefixed as package-colon-skill, such as team-conventions:commit-message. That solves the collision from the opening: two packages each carrying a commit-message can be installed together without fighting. Changing the package name changes every skill's invocation name, so decide it once and properly.
Second, component directories must sit at the plugin root and cannot go inside the manifest's directory. skills/, agents/, and hooks/ all live at the root, and .claude-plugin/ holds only plugin.json. The official documentation flags this as the most common error, so check it first when something will not install.
Both are structural problems, and structural problems are exactly what a dozen lines of script should block at the door. The self-check below does three things: confirms the manifest is in its dedicated directory, confirms no component directory got misplaced inside it, and confirms every skill has a description. Run it before shipping and it saves far more effort than diagnosing after installation.
import { readFileSync, readdirSync, existsSync } from 'node:fs'
import { join } from 'node:path'
const COMPONENT_DIRS = ['skills', 'agents', 'hooks', 'commands']
export function checkPack(root: string): string[] {
const errors: string[] = []
const manifestPath = join(root, '.claude-plugin', 'plugin.json')
if (!existsSync(manifestPath)) return [`manifest does not exist: ${manifestPath}`]
const manifest = JSON.parse(readFileSync(manifestPath, 'utf8')) as Record<string, unknown>
for (const key of ['name', 'description', 'version']) {
if (!manifest[key]) errors.push(`the manifest is missing ${key}`)
}
// The most common error: a component directory placed inside the manifest's directory
for (const dir of COMPONENT_DIRS) {
if (existsSync(join(root, '.claude-plugin', dir))) {
errors.push(`${dir}/ must sit at the plugin root and cannot go inside .claude-plugin/`)
}
}
const skillsDir = join(root, 'skills')
if (!existsSync(skillsDir)) return [...errors, 'there is no skills/ directory']
for (const name of readdirSync(skillsDir)) {
const file = join(skillsDir, name, 'SKILL.md')
if (!existsSync(file)) {
errors.push(`${name}/ has no SKILL.md, so it will not be treated as a skill`)
continue
}
// A skill without a description can never be triggered, so shipping it ships nothing
if (!/^description:\s*\S/m.test(readFileSync(file, 'utf8'))) {
errors.push(`${name} is missing a description`)
}
}
return errors
}import json
import re
from pathlib import Path
COMPONENT_DIRS = ["skills", "agents", "hooks", "commands"]
def check_pack(root: Path) -> list[str]:
errors: list[str] = []
manifest_path = root / ".claude-plugin" / "plugin.json"
if not manifest_path.exists():
return [f"manifest does not exist: {manifest_path}"]
manifest = json.loads(manifest_path.read_text(encoding="utf-8"))
for key in ("name", "description", "version"):
if not manifest.get(key):
errors.append(f"the manifest is missing {key}")
# The most common error: a component directory placed inside the manifest's directory
for name in COMPONENT_DIRS:
if (root / ".claude-plugin" / name).exists():
errors.append(f"{name}/ must sit at the plugin root and cannot go inside .claude-plugin/")
skills_dir = root / "skills"
if not skills_dir.exists():
return errors + ["there is no skills/ directory"]
for entry in sorted(skills_dir.iterdir()):
skill_md = entry / "SKILL.md"
if not skill_md.exists():
errors.append(f"{entry.name}/ has no SKILL.md, so it will not be treated as a skill")
continue
# A skill without a description can never be triggered, so shipping it ships nothing
if not re.search(r"^description:\s*\S", skill_md.read_text(encoding="utf-8"), re.M):
errors.append(f"{entry.name} is missing a description")
return errorsDuring development you neither publish nor install: one command-line flag mounts a local directory so you can try it, and a reload command after an edit avoids a restart. That development mode is today's lab's main thread — the first thing to do with a finished package is load it locally, trigger each skill once, and confirm the namespace lines up.
Marketplaces and versions
The package is built, so how do others get it? Through a marketplace. A marketplace sounds like a shop and is far plainer than that: a repository with a marketplace.json at its root, listing which packages this marketplace offers and where each comes from.
{
"name": "acme-tools",
"owner": { "name": "Platform Team" },
"plugins": [
{ "name": "team-conventions", "source": "./plugins/team-conventions", "version": "1.2.0" },
{ "name": "deploy-tools", "source": { "source": "github", "repo": "acme/deploy-plugin" } }
]
}A source can be a relative path inside the marketplace repository, or another Git repository, an npm package, or an archive URL. Which means a marketplace is an index layer and need not hold the content — you can treat a repository containing only a manifest as a marketplace while the package bodies stay where they were.
On the user's side there are only two steps: add the marketplace, then install by package-at-marketplace.
Versioning is the only part here that needs thought, and the rules are worth memorizing precisely:
With a version written, that value governs, and users receive an update only when it changes. Without one, a Git source uses the resolved commit hash as the version, so every push you make updates every user. The former is controllable and the latter is convenient; the latter is fine inside a team, and an external release must pin the version.
Do not write the version in two places. The package's own manifest takes precedence, and a disagreement between the two leaves you in a state you cannot explain to yourself.
Which changes warrant a version bump? The criterion is not whether a file changed but whether users' behavior changes as a result. A changed description, a changed step in the body, a changed script argument — bump. A typo fix, an added comment — no. It is the same reasoning as releasing a library, except the interface here is not a function signature but the description and the body.
Three paths for sharing across a team
For a dozen people to share one set of skills there are three paths, chosen by who installs, who maintains, and who may edit.
First, ride along with the repository. Put the skills straight into the project's .agents/skills/ and commit them with the code. The upside is zero infrastructure, everyone has them as soon as they pull, and review goes through the same pull request flow. The downside is that it holds only for this repository, so five repositories mean maintaining five copies. For conventions tied to one codebase, pick this without hesitating.
Second, go through a marketplace. Create a marketplace repository, have team members add it once each, then install on demand and receive updates automatically. The upside is one place maintained and many places affected, with versions and upgrade notes. The downside is the extra cost of persuading everyone to add the marketplace. For cross-repository team conventions, pick this.
Third, go through organization management. Pushed down centrally, with members not needing to add it and not able to switch it off casually. The upside is guaranteed coverage and auditability for compliance. The downside is a heavy process and slow iteration. Only conventions that must be mandatory and cause incidents when absent are worth this path — the security and compliance ones.
The three paths are not exclusive. A common stable combination: security and compliance through organization management, cross-repository team conventions through a marketplace, and a project's own quirks riding along with that repository.
Function calling, MCP, and Skills compared in full
This course has owed you this table since day one. First, a division you can memorize: MCP handles the wiring, Skills handle the experience, and context engineering handles the trade-offs; and function calling is the shortest wire, before any wiring standard.
| Dimension | Function calling | MCP | Skills |
|---|---|---|---|
| Which gap it fills | Capability: the model cannot do it | The wiring of capability: tools and data reaching any agent through one protocol | Experience: the model can do it but does not know how it is done here |
| Concrete form | A parameter schema plus a piece of your own code | A process or an HTTP endpoint exposing tools, resources, and prompt templates | A folder containing a SKILL.md |
| Who actually executes | Your application | The server | The model itself, per the instructions, running a script from the package when needed |
| Fixed cost per turn | All tool definitions resent every turn | The same, and several servers stack up | Only names and descriptions, with bodies loaded on demand |
| Reuse boundary | Locked to this one application | Across agents and clients; wire once, use in many places | Across clients; copy one folder |
| Who writes and maintains it | Application engineers | The server's author | Whoever holds the experience, who need not write code |
| What happens when it cannot be installed | The capability is simply absent | The capability is simply absent | It degrades to Markdown a human can read |
| Typical use | A handful of actions only this application needs | Data living in another system, or one capability serving several agents | Team conventions, multi-step workflows, domain practice |
The last two rows are the ones most worth pulling out.
The what-happens-when-it-cannot-be-installed row explains why a skill is cheap. Tools and protocols are binary: wired up and you have it, not wired up and you do not. A skill that cannot be installed is still a clearly written Markdown file that a person can read and another client can read. That is the fundamental reason it spread sideways across dozens of clients — it requires the host to implement no protocol, only to read files.
The who-writes-it row decides where each sits in an organization. Functions and servers can only be produced by engineers, while a skill can be written by the person who genuinely understands the business, with an engineer at most reviewing it. The holder of the experience and the holder of the code are often not the same people, and a skill lets the former deliver directly for the first time.
Finally, to be clear: these three do not replace each other, and combining them is the norm. A typical combination: an MCP server brings the company's ticketing system in as a callable tool; and a skill's body says "first pull this week's tickets with the ticket query tool, then classify them against the template below, and note that tickets in the merged state are excluded." The tool gives it hands and the skill gives it method. How that protocol side is designed and how prompt injection is defended against is covered from the beginning in the sister course, MCP in 7 Days.
Selection criteria: a flow you can run on the spot
Asked in an interview when to use which, the best answer is not reciting the table above but giving a decision flow you can run on the spot.
Mermaid source
flowchart TB
A[The model handles this poorly today] --> B{Is it missing capability<br/>or missing method}
B -- Missing capability, cannot do it --> C{Does only this one<br/>application need it}
C -- Yes --> D[Write function calling<br/>the shortest path, do not over-design]
C -- No, several agents need it --> E[Build an MCP server<br/>wire once, use everywhere]
B -- Missing method, can do it but breaks convention --> F{Does this method need<br/>deterministic execution}
F -- No, instructions suffice --> G[Write a skill<br/>the body states steps and pitfalls]
F -- Yes, results must match to the letter --> H[Write a skill with a script<br/>determinism goes to code]Three lines you can memorize outright:
Separate capability from method first. Get that cut wrong and everything after is wrong. The test is plain: hand this to a contractor clever enough but unfamiliar with your company — if they cannot do it, capability is missing; if they can do it but not to your conventions, method is missing.
On the capability side, choose by breadth of reuse. If only this application needs it, function calling is the end of it and building a server for it is over-design; only when several agents or clients need it is the protocol worth the trip.
On the method side, choose by determinism. What can be settled with clear instructions goes in the body; what must match to the letter gets a script the moment any of day four's three criteria hits.
Source Reading
Hands-On Lab
Today is a documentation-style lab: the deliverable is a plugin package and a delivery document, not code. The easiest ones to fudge are criteria 2 and 5 — with a blurry boundary, somebody will ask within two weeks why it does not handle their situation. When you are done, extract the three descriptions and run them through day three's positive-and-negative apparatus again to confirm they do not steal from each other.
- Read the solution's plugin package and see by what standard the three skills' boundaries were drawn.
- Complete the plugin manifest's name, description, and version fields in the starter.
- Arrange the three skills you wrote on earlier days per the plugin directory convention, with one line of boundary statement each.
- Load the package locally in development mode, trigger each of the three skills, and record the namespaces.
- Write upgrade notes for the package, stating which changes warrant a version bump and which do not.
Interview Questions
Today's 3 questions are in the question bank below, weighted toward organizing and distributing skills, versioning and team governance, and choosing among the three extension mechanisms. Expand each one and read the analysis before the key points — practicing the derivation beats memorizing bullets. The high-frequency labels for the domestic and overseas markets are there so you can pick by target market.
Checklist and Tomorrow
- Package a group of skills into a plugin with a manifest and a version, and load it locally to verify it
- Explain the three paths for sharing skills across a team and when each fits
- Use a comparison table to explain the division of labor between function calling, MCP, and Skills, and give selection criteria
- State that every change to a description is a behavioural change, and explain why it is the most easily missed
- All 5 acceptance criteria of the lab pass
- Answer at least 2 of the 3 interview questions without looking at the key points
Tomorrow (D7) closes the course: split a real team convention document into three skills, hand a real task to a clean subagent to execute, and use a set of assertions to prove it really beats going without the skills — not that it feels better, but by how many percentage points the pass rate rose. Finally, compress the delivery into one portfolio entry that survives follow-up questions.
Interview questions
How do function calling, MCP and Agent Skills relate, and when do you use which?函数调用、MCP 和 Skills 三者的关系是什么?什么时候用哪个?
Common in ChinaCommon overseasIntermediate#agent-skills#mcp#tool-calling#architectureHow to reason about it · think before answering
- The most common question in this course. The classic mistake is framing the three as competitors and saying skills are lighter than MCP, when they do not solve the same problem.
- Lead with the one-line division: MCP handles wiring, Skills handle experience, and function calling is the shortest wire of all.
- Then name the gaps. Function calling and MCP supply capability: the model cannot reach your database or file a ticket until you give it a tool. Skills supply experience: the model can already write a commit message, it just does not know your format.
- Give the two most informative contrasts. Context cost: tool definitions are resent every turn, while a skill costs only its name and description per turn with the body loaded on demand. Degradation: tools and protocols are binary, but a skill that fails to install is still readable Markdown, which is exactly why the format spread across dozens of clients. It requires the host to read files, not to implement a protocol.
- For selection give a runnable decision path. First separate missing capability from missing method. For capability, choose by reuse surface: one application means function calling, several agents justify an MCP server. For method, choose by determinism: instructions go in the skill body, byte-identical results go in a bundled script.
- Close on composition. The normal case stacks them: an MCP server exposes the ticket system as a tool, and a skill body says to pull this week's tickets with that tool and then group them by a template. Tools give hands, skills give procedure.
- Expected follow-up: when should you not use MCP? When only one application needs it and there are just two or three actions. Standing up a server is over-engineering.
分析过程 · 先想清楚再作答
- 这是本课最高频的一题。答错的典型是把三者摆成竞争关系,说「Skills 比 MCP 更轻量所以更好」——它们解决的根本不是同一个问题。
- 先给一句能背下来的分工:**MCP 管接线,Skills 管经验**,而函数调用是接线之前那根最短的线。
- 再落到缺口上。函数调用与 MCP 补的是**能力**:模型本来读不到你的数据库、发不出工单,给它工具它就能了。Skills 补的是**经验**:模型本来就会写提交信息,只是不知道你们这儿的格式。能力的缺口用工具补,经验的缺口用技能补。
- 然后给两条对比里最有信息量的差异。第一,上下文成本:工具定义每一轮都要重发,而 skill 每轮只有名字与描述,正文按需加载。第二,装不上时的降级:工具与协议是二值的,接不上就没有;**一个 skill 装不上仍然是一份人能读的 Markdown**,这正是它能在几十家客户端铺开的原因——它不要求宿主实现协议,只要求宿主会读文件。
- 选型给一条能当场走的流程:先分缺能力还是缺做法。缺能力时按复用面选,只有这一个应用要用就写函数调用,多个 Agent 都要用才值得做成 MCP 服务端。缺做法时按确定性选,靠指令说清楚就写进 skill 正文,结果必须逐字一致就配脚本。
- 最后一定要说配合。三者常态是叠着用:MCP 服务端把工单系统接进来成为工具,skill 的正文里写「先用工单查询工具拉出本周工单,再按这份模板归类」。**工具给它手,skill 给它章法。**
- 可预期的追问是「那什么时候不该用 MCP」。答案是只有一个应用要用、动作又只有两三个的时候——为它起一个服务端是过度设计,直接写函数调用更短。
Key points
- MCP is wiring, Skills are experience, function calling is the shortest wire.
- Capability gaps need tools or a protocol; experience gaps need skills. They do not compete.
- Tool definitions cost every turn; a skill costs only name and description until activated.
- A skill that fails to install is still readable Markdown, which is why it spread across clients.
- Choose by capability versus method: capability by reuse surface, method by determinism, and expect to combine all three.
答题要点
- 分工是 MCP 管接线、Skills 管经验,函数调用是接线之前最短的线。
- 能力的缺口用工具或协议补,经验的缺口用技能补,三者不是竞争关系。
- 工具定义每轮重发,skill 每轮只有名字与描述,正文按需加载。
- skill 装不上仍是一份人能读的 Markdown,这是它跨客户端铺开的根本原因。
- 选型先分缺能力还是缺做法:能力按复用面选,做法按确定性选;常态是三者叠着用。
A team needs to share more than a dozen skills. How would you organize and distribute them?一个团队要共享十几个 skill,你会怎么组织和分发?
Common in ChinaCommon overseasIntermediate#agent-skills#distribution#team-governanceHow to reason about it · think before answering
- This tests governance, not commands. The interviewer wants your criteria for splitting packages and choosing a distribution path.
- Organization first. The criterion is whether they are adopted and retired together. Skills orbiting the same team convention belong in one package; a team convention and your personal habit do not, because bundling forces people to take the half they did not want. A dozen skills usually becomes three or four packages.
- Name two hard rules. The package name is the namespace, so skills are prefixed as package colon skill, which is where collisions are resolved; pick the name once. And component directories must sit at the plugin root, never inside the manifest directory, which is the documented top mistake.
- Then the three distribution paths with criteria. Ship with the repository: commit the skills alongside code, zero infrastructure, reviewed through the existing pull request flow, but scoped to that repository. Choose it for conventions tied to one codebase.
- Use a marketplace: a repository plus a catalog JSON, added once per person, then installed on demand with automatic updates. One place to maintain, real versions and upgrade notes, at the cost of getting everyone to add it. Private simply means a private repository; there is no central server.
- Organization-managed distribution: pushed centrally and not easily disabled, with guaranteed coverage and auditability, but heavy process and slow iteration. Reserve it for rules that must be enforced, such as security and compliance.
- Close by noting the three combine: compliance centrally managed, cross-repository conventions via a marketplace, project quirks with the repository.
- Expected follow-up: will a dozen skills blow up the catalog? Discovery cost scales with total description length, so governance means auditing description length and mutual exclusivity, not capping the count.
分析过程 · 先想清楚再作答
- 这题考工程治理,不是考命令。面试官想听的是你按什么切包、按什么选分发路径,而不是背几条安装命令。
- 先讲组织。判据是**它们是否一起被采纳、一起被淘汰**:都围着同一套团队规范转、谁装了都得装全套,那就是一个包;一个是团队规范一个是你的个人习惯,凑在一起只会逼别人接受不想要的那半边。十几个 skill 通常应该切成三四个包,不是一个巨包也不是十几个碎包。
- 包的两条硬规矩要点出来:**包名就是命名空间**,包里的技能会被前缀成「包名冒号技能名」,撞名问题在这一层解决,所以包名要一次想好;组件目录必须在插件根下,不能塞进放清单的那个目录里,这是官方标出来的最常见错误。
- 再讲分发,给三条路径和各自的判据。随仓库走:直接放进项目目录跟着代码提交,零基础设施、评审走原来的流程,但只对这个仓库成立——**只跟某一个代码库有关的规范就选它**。
- 走市场:一个仓库加一份清单 JSON,成员各自添加一次,之后按需安装并自动收更新。一处维护多处生效、有版本、有升级说明,代价是要推动每个人添加一次。跨仓库的团队规范选它。**私有就是把市场仓库设成私有,没有中心服务器这回事。**
- 走组织托管:管理侧统一下发,不能随便关掉,覆盖率有保证、可审计,但流程重迭代慢,只有必须强制且不装就出事的规范才值得,比如安全合规那几条。
- 最后说三条不互斥,稳定组合是安全合规走托管、跨仓库规范走市场、项目独有的怪癖随仓库走。
- 可预期的追问是「十几个 skill 会不会把目录撑爆」。答案是发现阶段的开销只和描述总长有关,所以治理重点是**审描述的长度与互斥性**,而不是限制数量。
Key points
- Split by whether skills are adopted and retired together; a dozen usually becomes three or four packages.
- The package name is the namespace where collisions are resolved, and component directories live at the plugin root.
- Repository-scoped conventions ship with the repository: no infrastructure, no cross-repository reuse.
- Cross-repository conventions go through a marketplace, which is just a repository plus a catalog JSON; private repo means private marketplace.
- Mandatory compliance rules go through organization-managed distribution, and the three paths combine.
答题要点
- 切包的判据是它们是否一起被采纳、一起被淘汰,十几个通常切成三四个包。
- 包名就是命名空间,撞名在这一层解决;组件目录必须在插件根下。
- 只跟一个仓库有关的规范随仓库走,零基础设施但不跨仓库复用。
- 跨仓库的团队规范走市场,市场就是一个仓库加一份清单 JSON,私有仓库即私有市场。
- 必须强制的合规规范走组织托管,三条路径可以组合使用。
Should a skill package be versioned, and what goes wrong most often on upgrade?skill 包要不要做版本管理?升级时最容易出什么问题?
Common in ChinaCommon overseasDeep dive#agent-skills#versioning#distributionHow to reason about it · think before answering
- It looks procedural but really asks what a skill's interface is. Answer that and the rest follows.
- Should you version? Internally you can be loose; for public distribution you must pin a version. With a version, users update only when it changes. Without one, git sources use the resolved commit, so every push updates everyone, which is tolerable inside a team and out of control outside it.
- Add an easily missed detail: do not set the version in both the plugin manifest and the marketplace catalog. The plugin manifest wins, and a mismatch leaves a state you cannot explain.
- Then the criterion. What requires a bump is not whether a file changed but whether user-visible behavior changes. A changed description, changed body steps, or changed script flags all require a bump; typos and comments do not. It is the same as releasing a library, except the interface is not a function signature.
- The scoring point: a skill's interface is its description and body. Everyone remembers to bump for script changes but treats a slightly sharper description as cosmetic. The description is the only trigger surface: widen it and the skill starts stealing tasks, narrow it and it silently stops firing. Every description change is a behavior change and belongs in the upgrade notes.
- Give two concrete upgrade traps. Renaming the package changes the namespace, so every skill's invocation name changes and any hard-coded reference breaks. Moving a skill between packages looks to users like a capability disappearing, so the upgrade notes must spell out the migration.
- Expected follow-up: how do you know an upgrade did not break things? Run the day-three trigger tests as a regression, comparing hit rates on the same labeled queries before and after.
分析过程 · 先想清楚再作答
- 这题看着像流程题,实际考的是「skill 的接口到底是什么」。想清楚这一点,答案自然出来。
- 先答要不要:对内可以宽松,**对外发布必须写死版本**。写了版本,用户只在这个值变化时才收到更新,这是可控的;不写的话 Git 来源会拿提交哈希当版本,你每推一次内容用户就更一次,团队内部尚可,对外就是失控。
- 补一条容易忽略的细节:版本不要在包清单和市场清单两处都写,包自己的清单优先级更高,两边不一致会得到一个你自己都解释不清的状态。
- 接着答判据。什么改动要升版本?不是「改没改文件」,而是「**用户的行为会不会因此变化**」。描述改了、正文步骤改了、脚本参数改了都要升;修错别字、补注释不用。这跟给库发版一个道理,只不过这里的接口不是函数签名。
- 本题的拿分点在这里:**skill 的接口是描述与正文**。大家都记得改脚本要升版本,却常觉得「我就是把描述改得更准了一点」不算变更。但描述是唯一的触发面,改宽了会开始抢别的任务,改窄了会突然不触发。**描述的每一次改动都是行为变更**,都要在升级说明里单独写一行。
- 再给两个升级期的具体坑。一是改包名:包名是命名空间,改名等于把包里所有技能的调用名全改了,用户那边所有写死调用名的地方一起断。二是拆包与合包:一个 skill 从 A 包挪到 B 包,对用户来说是「装了 A 的人突然少了一个能力」,必须在升级说明里显式写迁移步骤。
- 可预期的追问是「怎么知道升级没升坏」。答案是把第三天那套触发测试当回归跑:改描述前后各跑一次同一组正负例,比触发率而不是凭感觉。
Key points
- Loose internally, pinned for public release; without a version, git sources update on every commit.
- Never set the version in both the plugin manifest and the marketplace catalog; the plugin manifest wins.
- Bump when user-visible behavior changes, not when a file changes.
- A skill's interface is its description and body, and every description change is a behavior change.
- Renaming the package rewrites every invocation name, moving a skill across packages needs migration notes, and trigger tests serve as upgrade regression.
答题要点
- 对内可宽松,对外发布必须写死版本;不写版本时 Git 来源按提交更新,等于失控。
- 版本不要在包清单与市场清单两处都写,包清单优先。
- 升不升版本看用户行为会不会变,不看改没改文件。
- skill 的接口是描述与正文,描述的每一次改动都是行为变更,最容易被漏掉。
- 改包名会改掉全部调用名,跨包挪动 skill 要写迁移步骤;用触发测试做升级回归。