Skill 开发踩坑:相对路径解析问题
在这里分享一下我在 Skill 开发过程中遇到的问题以及解决方案。
我经验有限,这个方案也远非完美,只是希望能为佬友们提供一点参考方向。若有更好的方法,也请佬友不吝赐教,一起交流进步。
问题描述
Claude Code 和 Qoder Cli 中,Skill 无法感知自身目录,导致 Skill 脚本的第一次调用都会出错,然后才会搜索正确目录,影响 scripts/ 和 reference/ 的使用。
测试环境为:
- Claude Code + Qwen3.5-Plus
- Qoder Cli + Auto / Lite 模式
不管 Skill 在用户级目录 (~/.agents/skills/xxx/scripts) 还是项目目录都会出现问题。
[!NOTE] GitHub Issue
直到 2026-04-04 仍未解决:[Bug] Skill plugin scripts fail on first execution with relative path resolution · Issue #11011 · anthropics/claude-code · GitHub
解决思路
在 Skill 调用时,注入 Skill 目录的绝对路径,如 “Base directory for this skill: /xxx/xxx/”。
注入方法通过 PreToolUse Hook 实现。
解决方案
-
修改
~/.claude/settings.json{ "hooks": { "PreToolUse": [ { "matcher": "Skill", "hooks": [ { "type": "command", "command": "bash ~/.claude/hooks/inject-skill-dir.sh" } ] } ] } } -
新增 Hook 脚本
~/.claude/hooks/inject-skill-dir.sh#!/bin/bash # inject skill's base directory when invoke Skill. Aim to solve the relative path resolution issue. set -euo pipefail # resolve the director and find cli name (handle symlinks) HOME_DIR="$(cd ~ && pwd)" SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd -P)" CLI_DIR_NAME="$(basename "$(cd "$SCRIPT_DIR/.." && pwd -P)")" if [[ ! "$CLI_DIR_NAME" =~ ^(\.claude|\.codex|\.qoder)$ ]]; then echo "Unknown cli name detected: '$CLI_DIR_NAME'." exit 2 fi # resolve /dev/stdin INPUT=$(cat) TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name') SKILL_NAME=$(echo "$INPUT" | jq -r '.tool_input.skill') CWD=$(echo "$INPUT" | jq -r '.cwd') # echo "$INPUT" >> $HOME_DIR/$CLI_DIR_NAME/hooks/hook.log # echo "$TOOL_NAME: $CURRENT_DIR / $SKILL_NAME" >> $HOME_DIR/$CLI_DIR_NAME/hooks/hook.log if [ "$TOOL_NAME" != 'Skill' ]; then exit 0 fi # define the directory map # Structure: [CLI_DIR_NAME] -> {local_config_dir, global_dir} case "$CLI_DIR_NAME" in ".claude") LOCAL_DIRS=("$CWD/.claude/skills/$SKILL_NAME") GLOBAL_DIRS=("$HOME_DIR/.claude/skills/$SKILL_NAME") ;; ".codex"|".qoder") LOCAL_DIRS=("$CWD/$CLI_DIR_NAME/skills/$SKILL_NAME" "$CWD/.agents/skills/$SKILL_NAME") GLOBAL_DIRS=("$HOME_DIR/$CLI_DIR_NAME/skills/$SKILL_NAME" "$HOME_DIR/.agents/skills/$SKILL_NAME") ;; *) exit 2 ;; esac # Function to find the directory. Keep it simple. find_dir() { for dir in "$@"; do [ -d "$dir" ] && echo "$dir" && return 0 done return 1 } # Combine lists and resolve. # Order: Project Dir (CWD) first, then Global. CANDIDATES=("${LOCAL_DIRS[@]}" "${GLOBAL_DIRS[@]}") FOUND_DIR=$(find_dir "${CANDIDATES[@]}") echo "Skill dir: $FOUND_DIR" >> $HOME_DIR/$CLI_DIR_NAME/hooks/hook.log if [ -z "$FOUND_DIR" ]; then exit 2 fi # return jq -n '{ "hookSpecificOutput": { "hookEventName": "PreToolUse", "permissionDecision": "allow", "additionalContext": "<IMPORTANT>\nBase directory for this skill: '"$FOUND_DIR"'\nYou MUST find scripts in base directory.\n<IMPORTANT>" } exit 0
测试结果
评估环境:
- Claude Code + Qwen3.5-Plus
- Qoder Cli + Auto / Lite Mode
Prompt:用 xxxx skill 完成 xxx 任务,显式调用
评估指标:路径出错次数
Claude Code 结果:
- 无 Hook:出错次数 9 / 10
- 有 Hook:出错次数 0 / 10
Qoder Cli 结果:
- 无 Hook:出错次数 9 / 10
- 有 Hook:出错次数 6 / 10
[!Note] 结果分析
- 这个问题大概率和模型能力有关。Claude 和 Codex 系列模型不需要显式提示 Skill 目录就会自己主动搜索,但 Qwen 系列模型目前做不到;
- Qoder Cli 通过 Hook 注入上下文的效果很差,没找到原因;
- Agent Cli 仍然以 Claude Code 和 Codex 领先;
