▶ 听文章
■ 停止
语速
0.75x 1.0x 1.25x 1.5x 2.0x
这个仓库的代码稍后上传。
项目里用 uv 管理 Python 依赖,但 Claude Code 总是习惯性地用 python 或 pip install。试了下用 Skill 和 Hook 来强制规范,踩了不少坑。
目标 创建 Skill:告诉 Claude 项目用 uv 创建 Hook:拦截 python/pip 命令 验证生效 踩坑过程 第一版:Skill 文件结构错了(提交 8a05759) 1
2
❌ .claude/skills/python-uv.md
✅ .claude/skills/python-uv/SKILL.md
cc 生成了错误的 frontmatter。因此,Frontmatter 要改:
1
2
3
4
5
6
7
8
9
---
# 错误
description : Python dependency and execution management using uv
location : project
# 正确
name : python-uv
description : Python dependency and execution management using uv. Use when adding Python packages, running Python scripts, or managing Python dependencies. Enforces uv instead of pip/python commands.
---
关键点:
文件名必须是 SKILL.md,放在对应目录下 frontmatter 需要 name 字段 description 要详细,帮助 Claude 识别何时触发第二版:Hook 只警告不阻止(提交 d250c3b) 最开始用 Bash 写 Hook,只显示警告但不阻止执行。还尝试配置 environment.PATH,结果不生效。
第三版:Hook 退出码用错了(提交 d3790a4) 改用 exit 1 想阻止命令,结果还是不管用。
正确的退出码 :
exit 0: 允许执行exit 1: Hook 失败,但不阻止 工具exit 2: 真正阻止 工具执行 ✅第四版:修正 Skill 格式(提交 2595b68) 发现文件结构不对,改成正确的 skills/xxx/SKILL.md 格式。
第五版:用 Python 重写 Hook(提交 dcc726d) Bash 解析 JSON 太脆弱,最终改用 Python:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#!/usr/bin/env python3
"""
Hook to block python/python3 commands and enforce uv usage.
"""
import json
import sys
import re
try :
# 正确解析 JSON 输入
input_data = json . load ( sys . stdin )
except json . JSONDecodeError as e :
print ( f "Error: Invalid JSON input: { e } " , file = sys . stderr )
sys . exit ( 1 )
# 获取工具名称和命令
tool_name = input_data . get ( "tool_name" , "" )
tool_input = input_data . get ( "tool_input" , {})
command = tool_input . get ( "command" , "" )
# 只处理 Bash 工具
if tool_name != "Bash" or not command :
sys . exit ( 0 )
# 检查是否使用 python/python3
if re . search ( r '\bpython3?\b' , command ):
# 白名单:允许版本检查等
if re . search ( r '(--version|--help|which python)' , command ):
sys . exit ( 0 )
# 阻止命令
error_msg = (
f " \n ❌ BLOCKED: This project requires using 'uv' \n\n "
f "Original command: \n { command } \n\n "
f "Suggested replacement: \n { suggested } \n "
)
print ( error_msg , file = sys . stderr )
sys . exit ( 2 ) # 使用 exit 2 阻止工具调用
# 允许其他命令
sys . exit ( 0 )
配置文件(.claude/settings.json):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
"hooks" : {
"PreToolUse" : [
{
"matcher" : "Bash" , // 简化的 matcher 格式
"hooks" : [
{
"type" : "command" ,
"command" : "$CLAUDE_PROJECT_DIR/.claude/hooks/pre-bash"
}
]
}
]
}
// 移除无效的 environment.PATH 配置
}
注意:
matcher 直接写工具名就行,不用搞表达式用 $CLAUDE_PROJECT_DIR 引用项目路径 environment.PATH 配置在 Hook 里不生效,别浪费时间最终文件结构 1
2
3
4
5
6
7
.claude/
├── skills/
│ └── python-uv/
│ └── SKILL.md
├── hooks/
│ └── pre-bash # Python 脚本
└── settings.json
测试 ✅ 阻止普通命令:
1
2
$ python test.py
❌ BLOCKED: Use 'uv run' instead
✅ 允许版本检查:
1
2
$ python --version
Python 3.11.0
✅ Skill 生效:
问"怎么运行 Python 脚本",Claude 会主动说用 uv run。
要点 Claude Code 有时不会主动查询规范
我明确要求创建 Hook 和 Skill,但 Claude Code 没有先查官方文档就开始写代码。导致:
文件结构错了好几次 退出码用错了 JSON 解析方式不对 如果它能在动手前先用 WebFetch 读一下官方的 Hook 和 Skill 文档,这些坑都能避免。
这不是用户要读文档的问题,而是 AI agent 在执行不熟悉的任务时,应该先查规范再动手。
** skills 和 hook 确实可以强制 claude code 的行为**
hook 可以通过约束 python 命令来给出正确的命令。kilo code 中也是这么做的。
参考