본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 05. 27. 00:43

Superpowers가 스킬 실행을 강제하는 방식

요약

Superpowers가 SessionStart hook을 통해 AI 에이전트의 스킬 실행률을 높이는 메커니즘을 분석합니다. 세션 시작 시 스킬 컨텍스트를 강제로 주입하여 모델이 스킬 사용을 인지하도록 유도하는 기술적 원리를 설명합니다.

핵심 포인트

  • SessionStart hook을 통한 스킬 컨텍스트 강제 주입
  • 스킬 실행률을 10%에서 66%까지 향상시키는 메커니즘
  • 모델이 스킬을 명시적 호출 없이도 인지하게 만드는 설계
  • Claude Code의 스킬 스캔 경로 및 동작 방식 분석

Superpowers가 스킬 실행을 강제하는 방식

이 포스트는 약 한 달 전에 작성된 노트를 바탕으로 합니다. Superpowers와 각 CLI의 hook/skill 동작은 빠르게 변화하고 있으므로, 일부 구현 세부 사항은 현재 버전과 다를 수 있습니다.

요약 (TL;DR)

AI 에이전트 (AI agents)를 충분히 오래 사용하다 보면, 스킬 (skills)이 항상 기대만큼 안정적으로 활성화되지 않는다는 사실을 결국 깨닫게 됩니다. Superpowers는 다르게 느껴집니다. 그 비밀은 바로 _SessionStart hook_에 있습니다. 세션이 시작될 때, 이 hook은 using-superpowers 스킬 전체를 컨텍스트 (context)에 강제로 주입하여, 모델이 첫 번째 응답을 하기 전부터 "나는 스킬을 사용해야 한다"는 것을 이미 알게 합니다. 이는 단순한 플러그인 설정처럼 보이지만, 실제로는 스킬 실행률을 10%에서 66%까지 끌어올릴 수 있는 상당히 의도적인 메커니즘입니다.

왜 스킬은 자동으로 활성화되지 않는가?

오늘날 AI 도구를 사용하는 대부분의 사람들은 아마 스킬이 무엇인지 알고 있을 것입니다. 하지만 이를 한동안 사용해 보면 한 가지 사실이 분명해집니다. 명령어를 직접 호출하거나 스킬의 이름을 명시적으로 언급하지 않는 한, 스킬은 종종 기대하는 대로 동작하지 않습니다.

우리가 원하는 것은 모델이 타이틀 (title)과 설명 (description) frontmatter를 읽고, 99%의 확신으로 적절한 스킬을 추론하여 자동으로 실행하는 것입니다. 하지만 현실은 다릅니다. GSD나 gstack 같은 스킬들은 직접 호출하지 않으면 제대로 작동하지 않는 경우가 많습니다.

나는 동료에게 Superpowers를 추천하며, 어떤 명령어 나 스킬을 알아야 하느냐는 질문에 "그냥 자연스럽게 사용하세요"라고 말했습니다. 그러다 문득 궁금해졌습니다. 만약 여러 스킬이 섞여 있다면, 모델이 필요한 스킬을 놓칠 수도 있지 않을까? 그렇다면 왜 Superpowers는 유난히 신뢰할 수 있게 느껴지는 걸까? 나는 코드를 열어 살펴보았습니다.

내가 발견한 것은 커스텀 hook (custom hook)과 스크립트였으며, 이는 에이전트가 스킬셋 (skillset) 내에서 훨씬 더 높은 확률로 올바른 스킬을 사용하도록 효과적으로 강제합니다. 이 패턴은 다른 서비스에도 충분히 유용해 보였기에, 나는 사용자 입력부터 hook 실행, 스킬 발견 (skill discovery), 그리고 최종 스킬 실행에 이르기까지 Superpowers가 어떻게 작동하는지 추적해 보기로 했습니다.

기본적으로 스킬 시스템이 작동하는 방식

A clay-paper style image of a small robot confused by scattered skill cards while trying to choose which skill to load

세션 시작 시, Claude Code는 세 곳의 위치에서 스킬 (skills)을 스캔합니다: 조직 단위 (/etc/claude-code/.claude/skills/), 사용자 수준 (~/.claude/skills/), 그리고 프로젝트 수준 (.claude/skills/)입니다.

스캔이 완료되면, 모델은 각 스킬의 name (이름)과 한 줄짜리 description (설명)만을 전달받습니다. 전체 스킬 내용은 모델이 명시적으로 Skill 도구 (tool)를 호출할 때만 컨텍스트 (context)에 들어옵니다. 즉, 실행이 일어나기 전에 모델 스스로가 "이 작업에는 이 스킬이 필요해"라고 결정해야 한다는 뜻입니다.

이것이 문제의 근원입니다. 이름과 한 줄짜리 설명만으로 올바른 결정을 내리는 것은 생각보다 훨씬 덜 신뢰할 수 있습니다. 실험 데이터에 따르면, 스킬 실행률은 멀티턴 (multi-turn) 세션에서 10%, 싱글턴 (single-turn) 세션에서 6%에 불과했습니다.

Superpowers가 문제를 우회하는 방식

A clay-paper style image of a synchronous hook device injecting a glowing context package into a robot before it responds

Superpowers는 스킬 시스템 자체에 의존하지 않습니다. 대신 훅 (hook)을 사용하여 해당 단계를 완전히 건너뜁니다. 흐름은 다음과 같습니다.

1단계: 훅 등록 (hooks/hooks.json)

hooks.jsonSessionStart 이벤트에 대한 훅을 등록합니다. 실제 코드에서 matcherstartup|clear|compact라는 세 가지 트리거 (trigger)를 다룹니다. 그런 다음 run-hook.cmd를 통해 session-start 스크립트를 실행합니다. 훅은 async: false로 설정되어 있어, 스크립트가 완료될 때까지 모델의 첫 번째 응답이 시작되지 않습니다.

{
  "SessionStart": [
    {
...

2단계: 스크립트 실행 (hooks/session-start)

2단계: 스크립트 실행 (hooks/session-start)

session-start 스크립트가 실행될 때, ${PLUGIN_ROOT}/skills/using-superpowers/SKILL.md 파일 전체를 읽어 변수에 저장합니다. 그런 다음 해당 내용을 <EXTREMELY_IMPORTANT> 태그로 감싸서 JSON 형식으로 출력합니다. 실제 출력 형태는 다음과 같습니다.

{
  "hookSpecificOutput": {
    "hookEventName": "SessionStart",
...

v5.x 버전의 현재 코드는 플랫폼별로 출력 형식을 분기합니다. Claude Code는 hookSpecificOutput.additionalContext를 기대하고, Cursor는 additional_context를 기대하며, Copilot CLI는 최상위 레벨의 additionalContext를 기대하므로, 스크립트는 환경 변수를 확인하여 적절한 형태를 생성합니다.

3단계: 컨텍스트 주입 (Inject context)

Claude Code는 hookSpecificOutput.additionalContext<system-reminder> 메시지로 변환하여 컨텍스트 (context)에 주입합니다. 모델의 첫 번째 응답이 나오기 전에, using-superpowers 스킬의 전체 내용이 이미 컨텍스트 윈도우 (context window) 안에 들어있게 됩니다.

4단계: 스킬 인지 상태로 대화 시작

모델은 어떤 스킬이 존재하는지, 언제 사용해야 하는지, 그리고 왜 반드시 사용해야 하는지를 이미 알고 있는 상태에서 대화를 시작합니다. 모델은 이제 행동하기 전에 스스로 해당 규칙들을 찾아낼 필요가 없습니다.

using-superpowers가 규칙을 강제하는 방식

A clay-paper style image of a rule beacon and branching paths symbolizing the robot's skill-call flow and remaining limitations

주입된 콘텐츠는 단순한 친절한 가이드가 아닙니다. 이는 <EXTREMELY_IMPORTANT>로 감싸진 지시 블록 (instruction block)이며, using-superpowers/SKILL.md에는 스킬 실행 흐름을 위한 결정 그래프 (decision graph)까지 포함되어 있습니다. 대략적인 흐름은 다음과 같습니다:

  1. 사용자 메시지 수신
  2. 만약 Plan Mode (계획 모드)에 진입하려 한다면 → 브레인스토밍 (brainstorming) 스킬 확인
  3. 스킬이 적용될 가능성이 단 1%라도 있다면 → Skill 도구 (tool)를 사용하여 전체 내용 로드
  4. 스킬을 따르고, 만약 체크리스트가 있다면 TodoWrite 항목 생성

그 후 Superpowers는 "규칙(The Rule)": 어떠한 응답이나 행동을 하기 전에 관련 스킬을 호출할 것—이라고 명시적으로 선언합니다. 심지어 모델이 스킬을 건너뛰기 위해 사용할 수 있는 내부적 합리화(rationalizations)의 종류를 나열하고, 각각을 위험 신호(red flag)로 규정하여 차단합니다.

  • "이것은 단순한 질문일 뿐이다" → 합리화 (Rationalization)
  • "이 스킬은 과하다" → 합리화 (Rationalization)
  • "먼저 더 많은 문맥이 필요하다" → 합리화 (Rationalization)

플랫폼별 호출 (Platform-specific invocation)

Superpowers는 Claude Code, Cursor, Codex, OpenCode, Copilot CLI, 그리고 Gemini CLI를 지원합니다. 하지만 각 플랫폼마다 서로 다른 훅 시스템(hook system)을 가지고 있으므로, session-start가 호출되는 방식은 플랫폼마다 다릅니다.

Claude Code / Cursor / Copilot CLI: 이들은 훅 기반의 문맥 주입(hook-based context injection)을 사용합니다. 각 플랫폼의 hooks.json 또는 hooks-cursor.jsonSessionStart 이벤트를 등록하며, session-start 스크립트는 CURSOR_PLUGIN_ROOT, CLAUDE_PLUGIN_ROOT, 또는 COPILOT_CLI와 같은 환경 변수를 감지하여 플랫폼별 JSON 형식을 출력합니다. Claude Code는 hookSpecificOutput.additionalContext를 사용하고, Cursor는 additional_context를 사용하며, Copilot CLI는 SDK 표준인 additionalContext를 사용합니다.

Codex: Codex는 훅 시스템이 없습니다. 대신 네이티브 스킬 발견(native skill discovery) 방식을 사용합니다. 설치는 단순히 심볼릭 링크(symlink)를 생성하는 것만으로 완료됩니다.

gh repo clone obra/superpowers ~/.codex/superpowers
mkdir -p ~/.agents/skills
ln -s ~/.codex/superpowers/skills ~/.agents/skills/superpowers

Codex는 시작 시 ~/.agents/skills/ 디렉토리를 자동으로 스캔하며, 프론트매터(frontmatter) 메타데이터를 기반으로 SKILL.md 파일들을 로드합니다. plugin.json이나 hooks.json은 존재하지 않습니다. 대신, using-superpowers 메타 스킬의 description 필드가 Codex의 자동 활성화 트리거(auto-activation trigger) 역할을 합니다.

Gemini CLI: Gemini는 activate_skill 도구 (tool)를 사용합니다. 세션 시작 시 스킬 메타데이터를 로드한 다음, 모델이 activate_skill을 호출할 때 요청에 따라 전체 내용을 활성화합니다.

플랫폼 간의 차이점은 다음과 같이 요약할 수 있습니다.

플랫폼 간의 차이점은 다음과 같이 요약할 수 있습니다.

플랫폼메커니즘트리거
Claude CodeHook + additionalContext 주입SessionStart 이벤트
...
They all use the same skill library, but the entry point is implemented differently on each platform. So if Codex나 Gemini가 스킬 활성화에 능숙하게 느껴진다면, 그것은 Superpowers hook 때문이 아니라 플랫폼 자체의 스킬 발견 기능이 더 적극적이기 때문일 수 있습니다.

강제 메커니즘의 배경

릴리스 노트와 커밋 히스토리를 보면 현재 구조가 완전히 갖춰진 형태로 나타나지 않았다는 것을 알 수 있습니다.

초기 버전: hook은 단순히 getting-started/SKILL.md 경로만 전달하고 모델에게 이를 읽으라고 요청했습니다. 주입된 session-start 내용은 대략 다음과 같았습니다.

<EXTREMELY_IMPORTANT>
You have Superpowers. RIGHT NOW, go read:
@/path/to/skills/getting-started/SKILL.md
...

이 접근 방식은 모델에게 파일을 읽으라고 지시했습니다. 하지만 때때로 모델은 단순히 그렇게 하지 않았습니다.

중간 단계: getting-startedusing-superpowers로 이름이 변경되면서 접근 방식이 바뀌었습니다. 파일 경로를 전달하는 대신, 스크립트 자체가 전체 SKILL.md 내용을 읽어와 additionalContext를 통해 전체 콘텐츠를 주입했습니다. 이는 모델이 읽을지 말지를 결정해야 했던 단계를 제거했습니다.

지속적인 강화: 모델이 스킬을 건너뛰는 사례가 여전히 나타났기 때문에, 각 버전에서 지침을 더욱 강화했습니다.

  • <EXTREMELY_IMPORTANT> 블록 추가: 더 강력한 절대적 언어와 추론 패턴을 미리 나열하는 Red Flags 테이블 추가

이것은 통제된 수치적 증명은 아닙니다. 하지만 패치 이력 자체가 정직한 증거입니다. 이 프로젝트는 "이것을 읽어주세요"에서 "이것을 반드시 호출해야 합니다"로 진화해 왔으며, 모델이 스스로 스킬 (skills)을 신뢰성 있게 선택하도록 만드는 것이 버전별로 얼마나 어려운지를 보여줍니다.

남은 한계점들

이 접근 방식이 완벽한 것은 아닙니다. SessionStart 훅 (hooks)이 서브에이전트 (subagent) 세션에서는 실행되지 않을 수 있으므로, 서브에이전트가 주입된 컨텍스트 (context) 없이 실행되어 일반적인 모델처럼 동작할 수 있습니다. GitHub 이슈 #237에서는 SubagentStart 훅을 추가하는 것에 대해 논의하고 있습니다. 또한, 컨텍스트 압축 (context compaction) 이후에는 주입된 콘텐츠가 누락될 수 있으므로, 긴 세션의 경우 규칙을 다시 로드해야 할 수도 있습니다.

훅 (Hook) 실행은 Windows 환경에서 불안정할 수도 있습니다. 이 프로젝트는 버전에 따라 .sh 파일을 직접 실행하는 방식에서 run-hook.cmd 래퍼 (wrapper)를 사용하는 방식으로 접근 방식을 변경해 왔으며, 관련 이슈들이 여전히 열려 있습니다.

맺음말

Superpowers의 핵심 아이디어는 보기보다 단순합니다. 모델이 스스로 스킬을 발견하게 만드는 대신, 세션이 시작되는 순간 규칙을 컨텍스트 (context) 안으로 밀어 넣는 것입니다. 이러한 강제 방식이 공격적으로 느껴질 수 있지만, 실행률 (execution-rate) 데이터는 이것이 효과가 있음을 시사합니다.

이는 다른 스킬 기반 워크플로우 (skill-based workflows)에서도 재사용할 수 있는 패턴입니다. 반복적으로 적용되는 베스트 프랙티스 (best practices)는 CLAUDE.md에 두고, 상황별 절차는 스킬 (skills)에 유지하며, 만약 스킬 실행이 여전히 신뢰할 수 없다면 SessionStart 훅을 통해 핵심 지침을 주입함으로써 비교적 적은 장치로 유사한 효과를 얻을 수 있습니다.

참고 문헌

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0