让智能体正确发现和调用技能
检查技能目录、摘要和诊断,区分资源发现、正文加载、自然语言选择与实际遵循。
让智能体正确发现和调用技能
一个技能文件存在,不代表宿主能找到它;宿主能找到,也不代表模型一定会读取正文。定位技能问题时,先把这几步拆开,避免不断改写正文却没有解决路径错误。
沿用第一个 Skill的项目与技能目录。本篇的加载检查不需要模型凭据。
观察提供给模型的内容
创建 src/inspect-skills.ts:
import { readFile } from "node:fs/promises"
import { basename, dirname } from "node:path"
import { fileURLToPath } from "node:url"
import { formatSkillsForPrompt, loadSkillsFromDir } from "@earendil-works/pi-coding-agent"
const dir = process.argv[2] || fileURLToPath(new URL("../skills", import.meta.url))
const result = loadSkillsFromDir({ dir, source: "lesson" })
console.table(result.skills.map((skill) => ({ name: skill.name, path: skill.filePath })))
console.log("诊断:", result.diagnostics)
if (result.skills.length === 0 || result.diagnostics.length > 0) {
process.exitCode = 1
}
for (const skill of result.skills) {
if (skill.name !== basename(dirname(skill.filePath))) {
console.error("为便于移植,名称应与技能目录一致:", skill.name)
process.exitCode = 1
}
const text = await readFile(skill.filePath, "utf8")
if (!text.includes("\n---")) {
throw new Error("请使用带 frontmatter 的目录式技能")
}
}
console.log("提供给模型的技能摘要:\n", formatSkillsForPrompt(result.skills))
console.log("这里只验证发现与摘要,不证明模型已读取或遵循正文。")运行:
node --import tsx src/inspect-skills.ts输出应包含技能名称、实际路径和诊断列表;格式化摘要包含名称、描述与位置,不包含完整执行步骤。脚本还额外检查目录名一致,作为本教程的移植约定,不能把这项额外检查误称为所有宿主相同的行为。
loadSkillsFromDir() 是指定目录检查,不会自动读取所有用户配置,也不是完整 Agent 会话。看到摘要只能证明这部分资源准备正确。
技能可以放在哪里
Pi 支持用户与项目技能位置,也支持 .agents/skills/。项目发现与工作目录、祖先目录和仓库边界有关。入门排查时先用显式 --skill 路径,确认资源本身有效,再检查默认发现。
不要同时把同名样例复制到多个会被发现的目录。当前宿主发生重名时保留先发现的一份并给出诊断;不要把发现顺序当成稳定的业务覆盖规则。
自动选择和显式调用分开测
先使用 /skill:code-inspection 检查名称与文件展开,再用自然语言提出同一任务,观察模型是否读取正文。如果显式调用正常、自然语言没有加载,才重点调整描述与相邻技能的边界。
描述可以写“何时使用”,不应只是“帮助处理代码”;也不要为了提高触发率,把所有任务都写进适用范围。翻译一句话不应该被强行套上代码检查流程。
只允许手动调用时怎么办
Pi 支持 disable-model-invocation: true。它会从提供给模型的自动选择摘要中隐藏技能,但保留显式调用入口。本轮检查覆盖了“仍能加载,但摘要不包含它”的行为,没有把它描述成跨宿主通用权限开关。
其他宿主是否支持该字段,以及显式调用如何实现,需要按各自契约确认。allowed-tools 也不能被假设为普遍生效的权限白名单,实际工具与授权由宿主控制。
修改后怎样确认更新
在活动交互会话编辑技能后使用 /reload,再观察诊断和任务。重新运行目录检查器只会重新读磁盘,不代表已经替运行中的会话完成重载。
排查时依次确认四件事:正确文件被发现、正文可读、模型确实加载、报告遵循了要求。原始工具读取记录、脚本执行记录和输出内容,比一句“已使用技能”更有说服力。
下一篇把长规则和模板从正文拆出去,观察按需读取的资源怎样组织。