Appearance
一个 skill 有没有效,不能靠"读起来感觉不错"来判断——你需要让 Claude 在没有 skill 的情况下跑一遍任务,记录它在哪里出错,再加上 skill 跑一遍,对比行为变化。Superpowers 提供了一套以 bash 脚本为基础的集成测试框架:在临时目录创建真实项目,用 headless 模式运行 Claude Code,然后解析 .jsonl 会话文件来验证 skill 是否被加载、subagent 是否被正确调度、预期文件是否被创建。
Superpowers 测试框架:如何验证 skill 真的有效
为什么读文档不够
软件工程师测试代码是因为"看起来对"和"运行时确实对"是两回事。skill 文档有同样的问题。
你可以读 100 遍 SKILL.md,觉得逻辑清晰无懈可击,然后让一个 agent 在真实场景下执行任务——它会找到你没想到的解读方式,走出你没预料到的路径。
这就是为什么 Superpowers 的测试方法论不是"读文档审查",而是"让 agent 在压力下执行任务,解析会话记录验证行为"。
测试的核心手段:headless 模式 + 会话记录解析
Headless 模式执行
Claude Code 支持用 -p 参数以非交互模式运行:
bash
claude -p "你的测试提示" \
--allowed-tools=all \
--add-dir "$TEST_PROJECT" \
--permission-mode bypassPermissions \
2>&1 | tee output.txt关键参数:
--add-dir:授权 Claude 访问测试目录(否则会被权限拦截)--permission-mode bypassPermissions:跳过交互式权限确认- 命令要从 superpowers 插件目录运行,skill 才会被加载
会话记录文件
每次 Claude Code 会话都会生成一个 JSONL 文件,存放在 ~/.claude/projects/ 下,路径以工作目录编码命名。以 /Users/jesse/superpowers 为工作目录为例:
bash
SESSION_DIR="$HOME/.claude/projects/-Users-jesse-superpowers"
ls -lt "$SESSION_DIR"/*.jsonl | head -5这个文件里每一行是一个 JSON 对象,包含 assistant 输出、工具调用、工具结果,以及每条消息的 token 用量。
验证 Skill 行为的方法
验证 skill 被加载
bash
if grep -q '"name":"Skill".*"skill":"your-skill-name"' "$SESSION_FILE"; then
echo "[PASS] Skill 被加载"
fi验证 subagent 被调度
bash
TASK_COUNT=$(grep -c '"name":"Task"' "$SESSION_FILE" || true)
if [ "$TASK_COUNT" -ge 3 ]; then
echo "[PASS] $TASK_COUNT 个 subagent 被调度"
fi验证 TodoWrite 被使用
bash
TODO_COUNT=$(grep -c '"name":"TodoWrite"' "$SESSION_FILE" || true)
echo "TodoWrite 调用次数: $TODO_COUNT"验证文件被创建
bash
if [ -f "$TEST_PROJECT/src/math.js" ]; then
echo "[PASS] 实现文件已创建"
fi
if grep -q "function add" "$TEST_PROJECT/src/math.js"; then
echo "[PASS] add 函数存在"
fi验证测试通过
bash
cd "$TEST_PROJECT" && npm test 2>&1
if [ $? -eq 0 ]; then
echo "[PASS] 测试通过"
fi测试脚本结构
一个完整的集成测试脚本框架:
bash
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
source "$SCRIPT_DIR/test-helpers.sh"
# 创建临时测试项目
TEST_PROJECT=$(mktemp -d)
trap "rm -rf $TEST_PROJECT" EXIT
# 写入测试文件
cat > "$TEST_PROJECT/package.json" << 'EOF'
{"name": "test-project", "scripts": {"test": "node test/math.test.js"}}
EOF
# 从 superpowers 插件目录运行 Claude
PROMPT="实现一个 math.js 模块,包含 add 和 multiply 函数,并编写对应测试"
cd "$SCRIPT_DIR/../.." && timeout 1800 claude -p "$PROMPT" \
--allowed-tools=all \
--add-dir "$TEST_PROJECT" \
--permission-mode bypassPermissions \
2>&1 | tee output.txt
# 找到刚才的会话文件
WORKING_DIR_ESCAPED=$(echo "$SCRIPT_DIR/../.." | sed 's|/|-|g' | sed 's|^-||')
SESSION_DIR="$HOME/.claude/projects/$WORKING_DIR_ESCAPED"
SESSION_FILE=$(find "$SESSION_DIR" -name "*.jsonl" -type f -mmin -60 | sort -r | head -1)
# 验证行为
echo "=== 验证结果 ==="
grep -q '"name":"Skill"' "$SESSION_FILE" && echo "[PASS] Skill 被加载" || echo "[FAIL] Skill 未加载"
[ -f "$TEST_PROJECT/src/math.js" ] && echo "[PASS] 实现文件存在" || echo "[FAIL] 实现文件缺失"
# Token 用量分析
python3 "$SCRIPT_DIR/analyze-token-usage.py" "$SESSION_FILE"Token 用量分析
Superpowers 提供了 analyze-token-usage.py 脚本,可以从会话记录里提取每个 subagent 的 token 消耗:
bash
python3 tests/claude-code/analyze-token-usage.py ~/.claude/projects/<project-dir>/<session-id>.jsonl输出示例:
Agent Description Msgs Input Output Cache Cost
main 主协调会话 34 27 3,996 1,213,703 $4.09
3380c209 实现 Task 1: 创建 add 函数 1 2 787 24,989 $0.09
34b00fde 实现 Task 2: 创建 multiply 1 4 644 25,114 $0.09如何读这些数字:
- Cache read 远大于 Input:正常,说明 prompt caching 在工作,成本被大幅压缩
- 每个 subagent 成本在 $0.05-$0.15 之间:典型范围
- main session 的 Input 很低但 cache 很高:协调者复用了大量缓存上下文
不同 Skill 类型的测试侧重
纪律性 Skill(强制流程的)
测试目标是验证在压力下 agent 是否遵守规则。典型场景:
- 给 agent 时间压力("尽快完成")
- 给 agent 已有代码("你已经写了一半了")
- 让 agent 面对权威要求跳过流程("客户说不需要测试")
验证点:agent 是否在这些情况下依然执行了规则要求的步骤。
技术性 Skill(教具体操作的)
测试目标是验证 agent 能正确应用技术。典型场景:
- 给一个真实任务,看 agent 是否用了 skill 里的方法
- 改变任务的边界条件,看 agent 是否处理了 edge case
验证点:实现文件是否正确,测试是否通过,关键 API 或模式是否被使用。
参考性 Skill(API 文档、工具指南)
测试目标是验证 agent 能找到并正确使用信息。典型场景:
- 问 skill 覆盖的某个具体问题
- 询问不常见的用法
验证点:答案是否准确,是否使用了 skill 里的具体示例。
常见问题排查
Skill 没有被加载
检查三件事:是否从 superpowers 插件目录运行(不是临时目录);~/.claude/settings.json 里是否有 "superpowers@superpowers-dev": true;skill 目录是否正确。
权限错误
添加 --permission-mode bypassPermissions 和 --add-dir /path/to/test/dir。
测试超时
默认超时用 timeout 1800 claude ...(30 分钟)。如果 skill 本身有逻辑错误导致无限循环,先排查 skill 逻辑。
找不到会话文件
用这个命令找最近一小时的 jsonl 文件:
bash
find ~/.claude/projects -name "*.jsonl" -mmin -60 | sort -r | head -5测试驱动开发 Skill 的完整循环
这个测试框架服务于一个更大的循环:
- RED:不加载 skill,让 agent 执行任务,用会话记录记录它在哪里出错、用了什么借口
- GREEN:写 skill 针对这些具体的失败点,再跑测试,验证 agent 现在行为正确
- REFACTOR:发现新的绕过方式,在 skill 里加反例,再测试
测试框架是这个循环的基础设施。没有可重复运行的测试,就没有办法知道 skill 的每次修改是变好了还是变坏了。
FAQ
Q: 集成测试要运行多久? A: 对于涉及多个 subagent 的 skill(如 subagent-driven-development),10-30 分钟是正常范围。单 agent 的技术性 skill 通常 5 分钟以内。
Q: 每次修改 skill 都要跑完整集成测试吗? A: 对于关键修改(堵漏洞、改工作流)必须跑。对于小的文字调整(修正语法、加 FAQ),可以只跑关键场景的子集。原则是:改了任何影响 agent 行为的部分,就要测试。
Q: 没有 Superpowers 的情况下能做类似的测试吗? A: 核心手段(headless Claude + jsonl 解析)不依赖 Superpowers。analyze-token-usage.py 脚本是 Superpowers 提供的工具,但自己写一个解析脚本也不难——jsonl 格式是公开的。
Q: Haiku 和 Opus 测试结果有差异时怎么办? A: 根据 Anthropic 的官方建议,skill 应该用你计划实际使用的所有模型测试。如果 Haiku 通不过,说明 skill 提供的信息不够,需要补充;如果 Opus 需要更简洁的指令,说明 skill 存在过度解释。为不同能力的模型找到最优的细节密度,是 skill 设计的重要考量。