4.2 精细控制——触发时机与权限边界
引言
小王的项目是一个全栈应用——前端用 Vue,后端用 Python FastAPI。他给项目装了一堆技能包:Vue 规范、Python 规范、部署流程、代码审查……
问题是:他在改 Python 文件时,Vue 规范也被加载了。他在写前端代码时,Python lint 自动触发了。
每个技能包都有它的舞台,不该在别人的舞台上抢戏。
通用概念:触发控制与权限边界
触发控制
触发控制解决的问题是:什么时候该激活技能包?
| 工具 | 触发依据 | 配置方式 |
|---|---|---|
| Claude Code | description 内容匹配 + paths 路径匹配 | 用户对话内容 + 文件路径 |
| Windsurf | globs 路径匹配 | 文件路径自动发现 |
| Cursor | 无自动触发 | 需手动调用 |
| 通用理解 | 概念迁移 | 不同类型文件使用不同规则 |
权限控制
权限控制解决的问题是:技能包能做什么不能做什么?
| 工具 | 权限方式 | 配置方式 |
|---|---|---|
| Claude Code | allowed-tools 预授权 | 白名单特定命令 |
| Cursor/Windsurf | 对话框确认 | 每次敏感操作需确认 |
| 通用理解 | 概念迁移 | 在团队规范中明确哪些操作需要确认 |
Claude Code 精细控制(详细示例)
⚠️ Claude Code 特有功能
paths 和 allowed-tools 是 Claude Code 的特有功能。其他工具无直接等价物,但概念可迁移:
- 触发控制:Windsurf 用
globs实现类似的路径匹配 - 权限控制:其他工具通过对话框确认,Claude Code 可预授权减少提示
paths:技能包的舞台(Claude Code)
paths 用 Glob 模式限定技能包何时激活——只在处理匹配文件时触发。
yaml
---
name: python-lint
description: Python 代码质量检查
paths:
- "src/**/*.py"
- "tests/**/*.py"
allowed-tools:
- Bash(ruff check *)
- Bash(mypy *)
- Bash(pytest *)
---
检查 Python 代码质量:
1. 用 ruff 检查代码风格
2. 用 mypy 检查类型
3. 用 pytest 运行相关测试效果:只有当小王在编辑 .py 文件时,Claude 才会自动加载 Python lint 技能包。改 .vue 文件?Python 规范完全不存在。
Windsurf 等效做法
yaml
python-lint:
globs: "src/**/*.py, tests/**/*.py"
instructions: |
Python 代码质量检查规则:
- 用 ruff 检查代码风格
- 用 mypy 检查类型
- 用 pytest 运行相关测试适合用路径匹配的场景
| 场景 | 路径设置(Claude Code paths / Windsurf globs) |
|---|---|
| 语言特定技能包 | "src/**/*.py"、"src/**/*.ts" |
| 框架特定技能包 | "src/**/*.vue"、"src/**/*.svelte" |
| 子项目特定技能包 | "packages/frontend/**" |
| 配置文件技能包 | "**/*.yaml"、"**/*.toml" |
allowed-tools:技能包的工具箱(Claude Code)
allowed-tools 预授权特定工具,减少权限提示——让技能包运行更流畅。
基本用法
yaml
allowed-tools:
- Bash(npm test) # 精确匹配
- Bash(npm run lint) # 精确匹配
- Bash(git add *) # 通配符匹配MCP 工具也能预授权
yaml
allowed-tools:
- mcp__postgres__query # MCP 工具
- mcp__postgres__list_tables通配符规则
Bash(npm test)— 只匹配npm test这一个命令Bash(npm run *)— 匹配npm run开头的所有命令Bash(git *)— 匹配所有 git 命令
两个常见错误
错误一:授权太宽
yaml
# ❌ 太宽泛——给了所有 git 操作的权限
allowed-tools:
- Bash(git *)修复 Issue 需要 git add 和 git commit,但不需要 git push --force。用 * 时要意识到它匹配了所有子命令。
错误二:授权太少
yaml
# ❌ 太少——Claude 无法完成完整流程
allowed-tools:
- Bash(npm test)
# 忘了授权 npm run buildClaude 跑完测试后想构建项目,但没权限——又回到权限提示了。
React 项目的参考
Facebook 的 React 项目展示了最佳实践:
json
{
"permissions": {
"allow": [
"Skill(test)",
"Skill(flow)",
"Bash(yarn test:*)",
"Bash(yarn flow:*)",
"Bash(yarn prettier)"
],
"deny": [
"Bash(npm:*)",
"Bash(pnpm:*)",
"Bash(bun:*)"
]
}
}允许什么和拒绝什么同样重要。React 项目明确拒绝 npm/pnpm/bun——因为团队只使用 yarn。
paths + allowed-tools 组合
最精细的控制是两者组合:
yaml
---
name: vue-component
description: Vue 组件开发规范
paths:
- "src/**/*.vue"
- "src/**/*.ts"
allowed-tools:
- Bash(npm run test:unit *)
- Bash(npm run lint *)
---
开发 Vue 组件时遵循:
1. 使用 Composition API + script setup
2. Props 使用 defineProps 并添加类型
3. 组件不超过 200 行,复杂逻辑抽取为 composable
4. 每个组件有对应的测试文件效果:只有编辑 Vue/TS 文件时才激活,且自动授权测试和 lint 命令。
本节小结
📌 本节核心要点
- 触发控制(通用概念):决定什么时候激活技能包
- 权限控制(通用概念):决定技能包能做什么不能做什么
- Claude Code paths:Glob 模式控制激活时机,防止不相关时抢占上下文
- Claude Code allowed-tools:预授权减少权限提示,提升流畅度
- Windsurf globs:等效的路径匹配机制
- 最小权限原则(通用):只授权必需的命令,用
*时要谨慎
思考题
- 如果你的项目同时有前端和后端代码,你会怎么区分前端技能包和后端技能包的触发时机?
- (Claude Code 用户)
Bash(git *)授权了所有 git 命令。如果你想授权大部分 git 命令但禁止git push --force,你会怎么设计? - (其他工具用户)你使用的工具如何控制"不同文件类型使用不同规则"?有没有类似 paths/globs 的机制?
- 为什么 Python lint 技能包不设
disable-model-invocation: true?它和 deploy 技能包的区别在哪?
下一节预告
技术细节掌握了,接下来看团队层面——如何在团队中共享技能包?如何保证安全?技能包提交到仓库时需要审查什么?