4부·13장 스킬 시스템의 작동 원리
스킬을 이해하는 순간, OpenClaw는 갑자기 다른 물건이 된다. 전에는 남이 만들어 둔 기능을 설치해서 쓰는 사용자였다면, 이제부터는 내 일하는 방식을 에이전트에게 가르치는 설계자가 된다. 이 차이는 생각보다 크다. 챗봇을 잘 쓰는 사람과 에이전트 운영을 잘하는 사람의 갈림길이 바로 여기 있다.
많은 초보자는 스킬을 "플러그인 비슷한 것"으로 이해한다. 반쯤은 맞고, 반쯤은 틀리다. 플러그인이 엔진에 가깝다면, 스킬은 운전 매뉴얼에 더 가깝다. OpenClaw의 스킬은 대개 코드 그 자체라기보다, 에이전트가 어떤 도구를 언제 어떤 순서로 써야 하는지 알려 주는 구조화된 지침이다.1 이 원리를 잡아두면, 다음 장에서 직접 커스텀 스킬을 만들 때 훨씬 덜 헤맨다.

스킬은 기능 추가가 아니라 행동 설계다
OpenClaw에서 스킬은 보통 하나의 폴더다. 그 안에 핵심 파일인 SKILL.md가 있고, 필요하면 예시 문서, 템플릿, 스크립트, 참고 자료 같은 보조 파일이 함께 들어간다.1 즉, 스킬은 단일 파일이라기보다 작은 작업 패키지에 가깝다.
이 패키지는 세 겹으로 생각하면 이해가 쉽다.
첫 번째 층은 메타데이터다. 이름, 설명, 호출 방식, 의존 조건 같은 정보가 여기에 들어간다.
두 번째 층은 본문 지침이다. 에이전트가 실제로 따라야 할 절차와 판단 기준이 여기에 적힌다.
세 번째 층은 번들 리소스다. 템플릿, 예시 출력, 체크리스트, 별도 문서처럼 필요할 때만 읽어도 되는 보조 재료다.
핵심은 첫 번째 층과 두 번째 층의 역할을 분리하는 것이다. 메타데이터는 "이 스킬이 언제 필요하냐"를 알려 주고, 본문은 "선택된 뒤에 무엇을 하느냐"를 알려 준다. 번들 리소스는 "긴 설명을 다 본문에 밀어 넣지 말고, 필요할 때 꺼내 읽자"는 발상이다.
가장 작은 스킬의 형태는 이 정도다.1
---
name: weekly-report
description: Create a concise weekly business report from task logs and metrics.
---
# Instructions
When the user asks for a weekly report, collect the relevant facts,
separate facts from guesses, and produce a short Korean summary.이 정도만 있어도 스킬은 성립한다. 하지만 실전에선 여기에 사용자 호출 여부, 모델 프롬프트에 노출할지 여부, 직접 툴로 우회 실행할지 여부 같은 제어 정보가 붙는다. 다시 말해 스킬은 글처럼 보여도, 사실은 꽤 정교한 운영 규칙 파일이다.
SKILL.md의 구조를 읽는 눈
SKILL.md는 겉으로 보면 평범한 마크다운이지만, 앞부분의 YAML frontmatter가 방향타 역할을 한다. OpenClaw는 여기서 스킬의 이름과 설명을 읽고, 어떤 환경에서 이 스킬을 살릴지 말지를 결정한다.1
실무에서 자주 보는 항목은 다음과 같다.
name: 스킬의 식별자다. 같은 이름이 여러 곳에 있으면 우선순위 규칙에 따라 하나가 선택된다.description: 에이전트가 이 스킬의 용도를 빠르게 이해하는 문장이다. 이 한 줄이 너무 모호하면 스킬은 잘 안 불리고, 너무 장황하면 토큰만 먹는다.user-invocable: 사용자가 슬래시 명령처럼 직접 부를 수 있게 할지 정한다.disable-model-invocation: 모델이 자동으로 이 스킬을 고려하지 않게 만든다. 사람이 명시적으로 호출할 때만 쓰고 싶은 유틸리티에 유용하다.command-dispatch,command-tool: 슬래시 명령을 모델 추론 없이 바로 특정 툴로 보내고 싶을 때 쓴다.1
조금 더 고급으로 가면 metadata.openclaw 아래에 로딩 조건을 적는다. 예를 들어 어떤 스킬이 uv 바이너리와 GEMINI_API_KEY가 있어야만 의미가 있다면, 그 사실을 스킬에 적어 둘 수 있다. 그러면 OpenClaw는 세션 시작 시점에 환경을 보고, 조건을 만족하는 스킬만 후보에 올린다.1
예시는 이런 느낌이다.
---
name: image-lab
description: Generate or edit images via a provider-backed workflow
metadata:
{ "openclaw": { "requires": { "bins": ["uv"], "env": ["GEMINI_API_KEY"] }, "primaryEnv": "GEMINI_API_KEY" } }
---여기서 중요한 디테일이 하나 있다. OpenClaw의 내장 파서는 frontmatter의 키를 한 줄 단위로 읽는 방식이어서, metadata는 한 줄짜리 JSON 객체로 적는 편이 안전하다.1 YAML인데 왜 JSON처럼 보이냐고 당황할 수 있는데, 이건 문법 미학보다 파서 호환성을 우선한 결과라고 보면 된다.
번들 리소스는 본문을 가볍게 만드는 숨은 기술
초보자가 스킬을 처음 만들면 흔히 저지르는 실수가 있다. 모든 설명, 모든 예시, 모든 출력 형식을 SKILL.md 한 장에 다 몰아넣는 것이다. 그러면 읽기는 편해 보여도 금세 비대해진다. 에이전트에게는 친절한 설명서가 아니라 두꺼운 참고서가 되어 버린다.
이럴 때 번들 리소스가 빛난다. 스킬 폴더 안에 다음처럼 보조 파일을 둘 수 있다.
skills/
weekly-report/
SKILL.md
templates/
executive-summary.md
examples/
sample-output.md
rubrics/
quality-checklist.md그리고 본문에서는 필요할 때 {baseDir}를 써서 이 파일들을 참조하게 만든다.1 예를 들어 "경영진 요약 형식이 필요하면 {baseDir}/templates/executive-summary.md를 읽어라"처럼 적어 둘 수 있다. 이렇게 하면 평소에는 짧은 설명만 노출하고, 정말 필요한 순간에만 보조 자료를 가져오게 설계할 수 있다.
이 방식의 장점은 세 가지다.
스킬의 핵심 목적이 선명해진다.
긴 예시를 본문에서 분리해 유지보수가 쉬워진다.
토큰 비용을 아낄 수 있다.
한마디로, 좋은 스킬은 모든 걸 한 장에 욱여넣지 않는다. 본문은 길 안내 표지판이고, 리소스는 필요할 때 여는 서랍이다.
OpenClaw는 어떤 스킬을 실제로 고를까
스킬이 폴더에 있다고 해서 무조건 쓰이는 것은 아니다. OpenClaw는 로딩 시점에 스킬을 걸러낸다. 운영체제, 바이너리 존재 여부, 환경 변수, 설정값, 명시적 비활성화 여부를 확인해서 "지금 이 기계와 이 에이전트가 쓸 수 있는 스킬"만 남긴다.1
예를 들어 macOS 전용 스킬인데 현재 게이트웨이가 Linux에서 돌고 있다면, 그 스킬은 처음부터 후보에서 빠진다. requires.bins에 적힌 실행 파일이 PATH에 없으면 역시 빠진다. requires.env가 필요한데 API 키가 제공되지 않았어도 빠진다.1
여기서 실무 감각 하나를 익혀 두자. 설치됨과 사용 가능함은 다르다. 스킬이 폴더에 있어도 의존성이 없으면 비활성 상태일 수 있다. 반대로 잘 설계한 스킬은 필요한 조건이 명확하게 적혀 있어서, 왜 안 뜨는지 원인을 바로 짐작할 수 있다.
또 하나 자주 막히는 지점은 샌드박스다. 호스트에서 바이너리가 보인다고 끝이 아니다. 에이전트를 샌드박스 컨테이너 안에서 돌린다면, 그 바이너리가 컨테이너 안에도 있어야 실제 실행이 된다.1 설치 확인은 통과했는데 실행은 실패하는 묘한 상황의 상당수가 여기서 나온다.
어디에 둔 스킬이 이기나: 로딩 우선순위
OpenClaw의 스킬 시스템은 "같은 이름이면 누가 이기느냐"가 매우 중요하다. 공식 문서 기준으로는 우선순위가 꽤 세분화되어 있다. 가장 위에는 워크스페이스 스킬이 있고, 그 아래에 프로젝트 에이전트 스킬, 개인 에이전트 스킬, 전역 managed/local 스킬, 번들 스킬, 마지막으로 extraDirs가 온다.1
하지만 처음 배울 때는 이렇게 단순화해도 충분하다.
내 현재 작업공간의
skills/가 최우선이다.그다음은 공용으로 쓰는
~/.openclaw/skills다.맨 아래는 OpenClaw가 기본 제공하는 bundled skills다.1
이 규칙이 왜 좋을까. 기본 제공 스킬을 그대로 믿고 쓰다가, 내 프로젝트에 맞는 버전으로 살짝 고쳐서 같은 이름으로 덮어쓸 수 있기 때문이다. 마치 교과서 위에 형광펜과 포스트잇을 붙이듯이, 기본 기능을 버리지 않고도 맥락 맞춤형으로 바꿀 수 있다.
예를 들어 bundled weekly-report 스킬이 있다고 하자. 그런데 당신은 한국어 요약, KST 기준 날짜, 매출·활성 사용자·콘텐츠 지표만 묶는 버전이 필요하다. 이때 workspace/skills/weekly-report를 만들어 같은 이름으로 올리면, 내 버전이 공식 버전을 이긴다.1 이게 바로 "소비자에서 제작자로 넘어가는 첫 번째 경험"이다.
멀티 에이전트 환경에서는 더 재미있다. 각 에이전트는 자기 워크스페이스를 갖기 때문에, 어떤 스킬은 특정 에이전트에게만 보이게 할 수 있고, 어떤 스킬은 ~/.openclaw/skills에 넣어서 여러 에이전트가 공용으로 쓰게 만들 수 있다.1 전략 에이전트와 실행 에이전트가 같은 도구를 쓰더라도, 똑같은 스킬 설명이 꼭 필요한 것은 아니다.
우선순위와 가시성은 같은 문제가 아니다
여기서 하나 더 구분해야 할 것이 있다. 어느 복사본이 선택되느냐와 그 스킬을 그 에이전트가 실제로 쓸 수 있느냐는 별개의 문제다.1
우선순위는 파일 위치가 결정한다. 반면 가시성은 에이전트 allowlist가 결정할 수 있다. 즉, 워크스페이스에 스킬이 있어도 해당 에이전트의 허용 목록에 없으면 안 보이게 만들 수 있다.1
이 차이를 이해하면 설계가 훨씬 깔끔해진다. 예를 들어 리포팅 에이전트는 weather, session-logs, weekly-report만 쓰게 하고, 실행 에이전트는 github, browser, shell-helper만 쓰게 제한할 수 있다. 같은 컴퓨터 안에 온갖 스킬이 깔려 있어도, 각 에이전트는 자기 일에 필요한 도구만 본다.
이건 보안뿐 아니라 비용에도 이롭다. 에이전트가 볼 스킬이 적을수록 선택 부담이 줄고, 프롬프트에 들어가는 스킬 설명도 줄어든다. 마치 서랍 정리를 해 두면 양말 찾는 데 시간이 덜 걸리는 것과 비슷하다.
세션이 시작되면 스킬은 어떻게 준비되나
OpenClaw는 에이전트 실행이 시작될 때 몇 가지 일을 순서대로 한다. 먼저 스킬 메타데이터를 읽고, 설정 파일의 skills.entries.<key>.env나 apiKey 값을 현재 실행에 한해 process.env에 주입한다. 그다음 조건을 만족한 스킬만 골라 시스템 프롬프트를 구성하고, 실행이 끝나면 원래 환경으로 되돌린다.1
이때 중요한 점이 두 가지 있다.
첫째, 이 환경 주입은 현재 에이전트 실행 단위다. 전역 셸 환경을 영구히 바꾸는 것이 아니다.1 그래서 상대적으로 안전하고, 특정 스킬에만 필요한 비밀값을 제한적으로 넣을 수 있다.
둘째, OpenClaw는 세션 시작 시점에 eligible skills 스냅샷을 만들어 이후 턴에서 재사용한다.1 그래서 스킬 파일을 막 수정했는데 즉시 반영되지 않는 일이 생긴다. 대개는 새 세션을 열어야 하고, watcher가 켜져 있으면 중간 갱신이 일어날 수도 있다.1
이 동작을 모르면 초보자는 종종 이렇게 말한다. "분명히 SKILL.md를 고쳤는데 왜 계속 예전 방식으로 일하지?" 답은 대개 단순하다. 스킬이 틀린 게 아니라, 세션이 아직 새 스냅샷을 안 쓴 것이다.
토큰 비용은 스킬 개수보다 스킬 설계가 결정한다
스킬을 많이 설치했다고 해서 곧바로 비용 폭탄이 터지는 것은 아니다. 진짜 중요한 것은 무엇이 프롬프트에 항상 들어가고, 무엇이 필요할 때만 읽히느냐다.
OpenClaw는 시스템 프롬프트를 만들 때 스킬의 전체 본문을 통째로 밀어 넣는 대신, 우선은 스킬 목록과 짧은 메타데이터만 넣고, 실제 지침 본문은 필요할 때 읽어 오는 방식으로 설계되어 있다.2 게다가 이 compact skills block은 skills.limits.maxSkillsPromptChars로 길이 제한도 걸 수 있다.2
이 말은 곧, 스킬 설계가 곧 비용 설계라는 뜻이다. 같은 기능이라도 어떻게 적느냐에 따라 토큰 사용량이 크게 달라진다.
좋은 원칙은 의외로 단순하다.
첫째, description은 짧지만 구체적으로 쓴다. "도움이 되는 범용 스킬" 같은 설명은 최악이다. 너무 넓어서 자주 잘못 선택되고, 읽는 값어치도 낮다. 반대로 "지난 7일간의 Notion 작업 로그와 Google Sheets 지표를 합쳐 한국어 주간 보고서를 작성한다" 같은 설명은 길어 보여도 훨씬 효율적이다. 선택 조건이 선명하기 때문이다.
둘째, 본문에는 절차만 적고, 장문의 예시와 템플릿은 번들 리소스로 뺀다. 설명서는 얇게, 참고서는 서랍에 넣는 방식이다.
셋째, 거대한 만능 스킬 하나보다 역할이 분리된 작은 스킬 여러 개가 낫다. 만능 스킬은 설명도 길어지고, 호출 조건도 흐려지고, 유지보수도 어려워진다. 반면 작은 스킬은 특정 상황에서만 읽히므로 비용과 혼선을 함께 줄인다.
넷째, 자동 선택이 필요 없는 스킬은 disable-model-invocation: true를 고려한다. 사람이 슬래시 명령으로만 부를 유틸리티라면, 굳이 모델의 기본 후보 목록에 계속 올려둘 이유가 없다.1
다섯째, 에이전트별 허용 스킬을 최소화한다. 모든 에이전트가 모든 스킬을 보는 구조는 편해 보이지만, 결국 프롬프트 세금(prompt tax)을 늘린다.12
여섯째, 긴 예시 출력이나 대용량 도구 결과를 습관적으로 스킬 본문에 붙이지 않는다. OpenClaw의 전체 컨텍스트 비용은 시스템 프롬프트, 대화 기록, 도구 결과, 메모리, 첨부물까지 모두 합쳐져 계산되므로, 스킬이 조금만 비대해져도 다른 비용과 합쳐져 체감이 커진다.2
요약하면 이렇다. 짧게 소개하고, 정확히 선택되게 하고, 자세한 것은 필요할 때 읽게 하라. 이것이 OpenClaw식 토큰 절약의 핵심이다.
나쁜 스킬은 대개 두 가지 냄새가 난다
첫 번째 냄새는 설명이 모호한 스킬이다. 예를 들어 description: Help with productivity and work tasks 같은 문장은 사실상 아무 말도 하지 않는다. 이런 스킬은 여기저기 끼어들 가능성만 높다.
두 번째 냄새는 본문이 과하게 비대한 스킬이다. 20개의 예시, 15개의 예외 규칙, 8개의 대체 출력 형식을 한 파일에 다 넣으면 처음엔 든든해 보인다. 하지만 실제로는 스킬이 아니라 백과사전이 된다.
좋은 스킬은 반대다. 한 줄 소개가 날카롭고, 본문은 절차 중심이며, 부속 자료는 따로 빠져 있다. 사람으로 치면 말이 많은 동료보다, 필요할 때 정확한 체크리스트를 꺼내 주는 동료에 가깝다.
스킬을 설계할 때 바로 써먹는 체크리스트
처음 커스텀 스킬을 만들기 전에, 아래 질문만 통과해도 실패 확률이 크게 줄어든다.
이 스킬의
description만 읽고도 언제 불러야 할지 알 수 있는가?본문은 절차와 판단 기준에 집중하고 있는가?
긴 예시나 템플릿은 별도 파일로 뺐는가?
필요한 바이너리, 환경 변수, 설정 조건을 메타데이터로 밝혔는가?
이 스킬이 모든 에이전트에 보여야 하는가, 아니면 특정 에이전트만 보면 되는가?
사람이 직접 부를 유틸리티라면 자동 모델 호출을 굳이 허용해야 하는가?
이 질문에 답하다 보면 스킬은 자연스럽게 작고 선명해진다. 그리고 그런 스킬이 결국 오래 살아남는다.
이제부터는 설치가 아니라 제작이다
여기까지 이해했다면, 스킬은 더 이상 "커뮤니티 마켓에서 받아 쓰는 확장팩"이 아니다. 당신의 일 방식을 언어로 압축해 에이전트에게 주입하는 방법론이다.
좋은 스킬 시스템의 매력은 화려한 자동화가 아니라 재현성에 있다. 한 번 잘 정리한 절차는 다음 주에도, 다음 프로젝트에도, 다른 에이전트에도 다시 쓸 수 있다. 그리고 바로 그 순간 OpenClaw는 그냥 똑똑한 챗봇이 아니라, 당신의 업무 운영체제가 된다.
다음 장에서는 이 원리를 손에 잡히는 형태로 바꿔 본다. 말로만 이해한 스킬을, 실제로 내 워크스페이스 안에 태어나게 해보자.
참고
이 노트는 보도·비평·교육·연구 목적으로 작성되었습니다. 저작권 문의가 있으시면 에서 알려주세요.