周一回归通过,周三同一个 Agent、同一段 Prompt、同一份仓库,突然开始调用另一套参数。
我们先怀疑模型,再怀疑上下文,最后才发现真正的变量:Skill 更新了,MCP 的工具 Schema 变了,App 的写权限被收回,但指导 Agent 执行写操作的 Skill 仍在。
这不是一次 Prompt 调优能解决的问题。Agent 的实际能力是一张依赖图,而大多数项目只保存了"依赖意图",没有保存"解析结果"。
软件依赖管理已经给出一个成熟类比:Manifest 说明想安装什么,Lockfile 记录最终装了什么。Agent 也需要这两层。
能力包正在变成多生命周期组件
AWS 8 月 26 日介绍 Agent Toolkit for AWS 时,把 Skill 与 MCP Server 作为不同组件:Skill 由服务团队维护、会更新;CLI 可以搜索、安装、更新和移除;MCP Server 负责文档、资源和 API 工具连接。
OpenAI 截至 8 月 29 日更新的 Plugin 说明又拆出 Skills、Connected Apps 和 App Templates。官方明确,安装 Plugin 不会绕过 App 授权;Plugin 安装、App 访问和同步是不同控制。禁用 App,也不一定移除仍可独立工作的 Skill。
它们不是同一套标准,但都不支持"装了一个东西,所以所有能力同步生效"这种想象。
对工程系统而言,下面这些状态必须分开:
ts
type CapabilityState = {
discovered: boolean;
installed: boolean;
loaded: boolean;
connected: boolean;
authorizedActions: Array<"read" | "write" | "delete">;
approvalRequired: boolean;
};
installed: true 和 authorizedActions: ["read"] 可以同时成立。Skill 也可能已加载,但依赖的 App 不可用。把所有状态压成一个绿色开关,问题只会延迟到运行时出现。

Lockfile 锁的不是文件名,而是行为边界
一个可用的 Agent Lockfile 至少要包含:
json
{
"agent": "content-researcher",
"skills": [
{
"name": "source-verification",
"version": "3.4.1",
"sha256": "7d8a..."
}
],
"mcpTools": [
{
"server": "web-research@1.8.0",
"name": "open_page",
"inputSchemaSha256": "4a99..."
}
],
"apps": [
{
"name": "document-store",
"required": ["read"],
"connectionType": "workspace-managed"
}
],
"policySha256": "22cd...",
"modelRoute": "research-balanced/v3",
"evalSuite": "content-research/2026-08",
"fingerprint": "0dc8..."
}
这里不保存 Token 或 Cookie。Lockfile 的任务是复现能力边界,不是复制凭证。
为什么还要保存哈希?因为版本号只是发布者的承诺。有的 Skill 内容改了却没升版本,有的 MCP 后端改了 Tool Schema 但 Server 版本没动。用规范化内容和 Schema 计算摘要,可以发现这种"静默变化"。
启动时做一次 capability resolution
不要让 Agent 在任务中途才发现依赖缺失。启动或部署时解析整张图:
ts
async function resolveCapabilities(manifest: Manifest) {
const skills = await resolveSkills(manifest.skills);
const tools = await discoverTools(manifest.mcpServers);
const apps = await inspectAppActions(manifest.apps);
const policy = await loadPolicy(manifest.policyRef);
rejectDuplicateToolNames(tools);
rejectMissingActions(skills, apps, policy);
rejectWriteToolWithoutControls(tools, policy);
const lock = buildLock({ skills, tools, apps, policy });
lock.fingerprint = sha256(canonicalJson(lock));
return lock;
}
三个错误应该在这里就失败:
- 两个 MCP Server 暴露同名工具,却没有命名空间;
- Skill 要求发布,App 只有读取权限;
- 新增写工具,却没有审批、幂等和审计规则。
这些不是模型应该"灵活处理"的情况,而是配置不能进入生产。

升级先看 diff,再决定跑多少测试
ts
const diff = compareLocks(currentLock, candidateLock);
if (diff.permissionExpanded || diff.writeToolAdded) {
requireSuite("high-risk-tooling");
}
if (diff.toolSchemaChanged) {
requireSuite("tool-contract");
}
if (diff.skillContentChanged) {
requireSuite("representative-tasks");
}
一段只读说明更新和新增 send_invoice 不该走同一条发布流水线。最小升级流程可以是:
resolve → diff → regress → dry-run → canary → promote/rollback
灰度也不需要复杂流量平台。小团队可以复制一个 Agent,给它 5 个无副作用样本或一个内部任务窗口,对比通过率、返工阶段、工具选择和耗时。通过后再把新 Lockfile 标记为当前版本。
自动发现不是免记录
Agent 自动发现相关 Skill 很方便,尤其当目录越来越大时。但"用户不需要知道有哪些 Skill"不等于"系统不需要记录用了哪些 Skill"。
运行记录应保存:
ts
type RunMetadata = {
taskId: string;
agentVersion: string;
capabilityFingerprint: string;
loadedSkills: string[];
availableTools: string[];
policyVersion: string;
startedAt: string;
};
出现异常时,先比较 capabilityFingerprint。不同,优先查依赖 Diff;相同,再查输入、外部状态与模型非确定性。排查顺序会清楚很多。
这也是我们做 Tipkay 时的一个取舍
我们在 Tipkay 里按岗位配置独立的 Skill、MCP、经验和流程,并允许助手复制、定制和版本化。这个拆分除了让岗位助手能直接开始工作,也让配置变化有隔离边界:试验版内容助手不应覆盖正在工作的版本,更不应影响财务或视频岗位。
熟练工不是"装了最多工具的人"。它应该拥有一套稳定、可验证、可升级的岗位能力。一个人的生意,也能有一支专业团队;但团队里的每个岗位,都应该能说清今天用的是哪一版方法和工具。
四个文件就能起步
text
agent.manifest.yaml # 想要什么
agent.lock.json # 实际解析到什么
evals/ # 升级必须通过什么
upgrades.md # 为什么变、如何回退
Agent 的配置税不会消失。Lockfile 的价值,是让这笔税从反复排查和重新培训,变成一次可以审阅、测试和回退的工程变更。
参考资料
- AWS Developer Tools Blog, Get started with the Agent Toolkit for AWS in the AWS CLI, 2026-08-26.
- AWS Documentation, Getting started - Agent Toolkit for AWS, accessed 2026-08-29.
- OpenAI Help Center, Plugins in ChatGPT and Codex, accessed 2026-08-29.