CH 14 · Skill과 Workflow
본장 목표
이전까지는 Agent에게 일을 시킬 때마다 요구사항을 매번 설명해야 했습니다. 그런데 어떤 작업은 절차가 고정되어 있습니다 — CH 05에서 돌렸던 "리포지토리 요약하고 문서로 출력" 같은 것이나, 주간 보고, 데이터 정리 같은 일상적인 작업. 매번 처음부터 과정을 반복하는 것은 너무 낭비입니다. 이런 작업은 "하나의 지시문"으로 만들어 둘 가치가 있습니다. Agent에게 "이런 종류의 작업을 만나면 이 단계들을 따라라"라고 알려 두는 것. 그것이 Skill입니다. 이번 장에서는 dsh의 Skill이 무엇인지, 어디서 오는지, 모델이 어떻게 사용하는지를 명확히 한 다음, 이미 만들어진 Skill을 그대로 설치해 바로 사용해 봅니다 — Agent에게 한마디만 하면 Agent가 스스로 설치합니다 — 그것을 당신의 개인 "재사용 가능한 역량"으로 만들어 봅니다.
하나의 사실: Skill 역시 플러그인
MCP와 서브에이전트와 마찬가지로, dsh에서 Skill은 별도의 진입점이 아니라, 플러그인의 조합입니다. 설정 트리를 보면, skill 능력 패밀리는 네 조각으로 구성됩니다.
| 플러그인 | 하는 일 | 역할 |
|---|---|---|
dsh-skill | 레지스트리: 여러 출처의 skill 디렉터리를 합치고, 이름으로 "이기는" 것을 해소 | 창고 관리인 |
dsh-skill-filesystem | 프로젝트와 사용자 디렉터리에서 로컬 skill을 발견하고, 파일 변경을 감시 | 바이어 |
dsh-tool-skill | 사용 가능한 skill 목록을 모델에 보여 주고, skill 로딩 도구를 제공 | 프론트 데스크 |
dsh-skill-badge | 기본으로 함께 제공되는 공식 배지 skill, 기본 비활성 | 장식 |
이 네 개 모두 web 설정에 기본으로 설치되어 있습니다 — 지금 바로 쓸 수 있고, 따로 설치할 것은 없습니다. 이는 다시 CH 08의 "모든 것은 플러그인"입니다 — "재사용 가능한 역량"조차 플러그인이 조립합니다.
Skill이란 무엇인가: 쓰여진 "일을 하는 방법"
도구는 Agent가 "부르는" "동작"이고 (파일 읽기/쓰기, 웹 검색), Skill은 Agent를 위해 쓰여진 "지시문"입니다 — "이런 종류의 작업을 만나면 이 단계들을 따라라"라는 작업별 지시 묶음입니다.
가장 큰 차이는 재사용성입니다. 도구는 시스템이 제공하는 것이고, Skill은 사용자가 쌓아 올리는 것입니다. 어떤 작업에 쓸만한 방법을 알아 냈다면, 그것을 Skill로 써 두면, 이후 Agent가 같은 종류의 작업을 만날 때 더 이상 요구사항을 반복할 필요가 없습니다. 그리고 skill은 그 위치에 따라 동작합니다 — 프로젝트의 .dsh/skills에 두면 프로젝트 레벨로 그 프로젝트에서만 적용되고, 사용자 디렉터리 ~/.dsh/skills에 두면 전역 레벨로 어느 프로젝트에서나 쓸 수 있습니다 — 다음 절 "다섯 개의 선반"에서 전체 계층을 보여 줍니다.
"Workflow"는 어떤가: Skill이 가장 단순한 Workflow
한 줄 기억법입니다. Skill이 가장 단순한 workflow입니다. Workflow의 본질은 "인간의 경험을 과정으로 굳히는 것"이고, Skill이 바로 그것입니다 — 입력이 분명하고, 출력이 분명하고, 단계가 고정되어 있으며, 단독으로 재사용할 수 있습니다. 한 가지 작업으로 압축된 작은 과정입니다.
차이는 세분화입니다. Skill은 "한 가지 일을 어떻게 하는가"를 다루고 (한 가지 요리 레시피), Workflow는 "여러 작업을 어떤 순서로 이을 것인가"를 다룹니다 (식재료 사러 가기, 채소 씻기부터 접시 내기까지 전체 파이프라인이며, 분기와 인계, 누가 먼저인지를 관리). dsh의 Standard 프리셋에서 "Skills"와 "Workflows"는 나란히 두 도구입니다 — 한 단계 고정 루틴이면 Skill이면 충분하고, 여러 단계 사슬을 이을 때만 Workflow가 필요합니다.
두 가지를 나란히 놓으면 차이가 더 분명해집니다.
| 차원 | Skill | Workflow |
|---|---|---|
| 다루는 것 | 한 가지 일을 하는 법 | 여러 작업을 어떤 순서로 이을지 |
| 세분화 | 한 단계 고정 루틴 | 다단계 파이프라인 |
| 분기와 인계 | 담당하지 않음 | 담당 (조건, 인계, 순서) |
| 재사용 | 개별적으로 재사용 | 필요에 따라 다시 오케스트레이션 |
| 비유 | 한 가지 요리 레시피 | 식재료 사러 가기부터 접시 올리기까지의 전체 파이프라인 |
따라서 단 하나의 고정된 작업을 위해 Skill 하나를 쓴다면, 실제로는 "가장 단순한 workflow"를 만든 셈입니다.
Skill은 어떤 모습인가
Skill은 frontmatter가 붙은 Markdown 파일이며, 표준 형태는 디렉터리 번들입니다. 폴더 이름이 skill 이름이고, 그 안에 반드시 SKILL.md가 있어야 합니다 — 동반 리소스(스크립트, 참고 문서, 자산)를 함께 가져오는 skill에 적합합니다.
이름은 소문자 kebab-case여야 하며(^[a-z0-9]+(?:-[a-z0-9]+)*$), 예: code-review, weekly-report.
표준 디렉터리 번들은 이런 모습입니다.
code-review/
├── SKILL.md # 필수: frontmatter + 지시 본문
├── scripts/ # 선택: 동반 스크립트 (.py / .sh 등)
├── references/ # 선택: 참고 문서, 리뷰 체크리스트 템플릿
└── assets/ # 선택: 자산, 샘플 파일SKILL.md가 유일한 필수 파일이며, 본문은 번들 안의 스크립트와 참고 문서를 상대 경로로 참조할 수 있습니다. 최소 구조는 이런 모습입니다.
---
name: code-review
description: 통합 체크리스트에 따라 코드 조각을 리뷰하고 구조화된 리뷰 코멘트를 출력
whenToUse: 사용자가 "code review"를 요청할 때
---
# Code Review
다음 순서를 따릅니다.
1. 먼저 관련 README를 읽어 이 코드가 어떤 문제를 푸는지 이해한다.
2. 공개 export와 주요 함수를 나열하고, 각 함수가 무엇을 하는지 적는다.
3. 명백한 위험 지점을 찾는다: 오류 처리, 엣지 케이스, 민감 정보.
4. 표로 출력한다: 파일 / 이슈 / 심각도 / 제안.frontmatter에서는 name과 description만 필수이며, 나머지 필드는 모두 선택입니다.
| 필드 | 용도 |
|---|---|
name | skill의 고유 이름 (kebab-case, 필수) |
description | 한 줄 설명; 모델이 "이 작업이 내 일인가" 판단하는 데 사용 (필수) |
whenToUse | 추가적인 사용 시점 힌트 (선택) |
disable-model-invocation | true로 두면: 사용자만 /이름으로 호출할 수 있고, 모델은 자동으로 로드하지 않음 (선택) |
user-invocable | false로 두면: 모델만 호출할 수 있고, 사용자의 /이름은 무효 (선택) |
두 개의 스위치: 누가 호출할 수 있는가
frontmatter의 두 필드가 "누가 호출할 수 있는지"를 다룹니다.
| 조합 | 효과 |
|---|---|
| 둘 다 없음 | 모델과 사용자 모두 호출 가능 (기본값) |
disable-model-invocation: true | 사용자가 /이름으로만 호출; 모델의 디렉터리와 skill 도구에는 보이지 않음 — 민감하거나 비용이 큰 흐름에 적합, 모델이 함부로 작동시키지 못하도록 |
user-invocable: false | 모델만 호출 가능; 사용자의 /이름은 무효 |
| 둘 다 off | 신뢰할 수 있는 코드만 호출 가능; 모델과 사용자 모두 건드릴 수 없음 |
Skill은 어디에서 오는가: 다섯 개의 "선반"
먼저 두 가지를 구분합니다. 이 절은 dsh가 skill을 어디에서 읽는가, 즉 어떤 로컬 디렉터리에 두어야 발견되는지를 다룹니다. dsh는 dsh-skill-filesystem 플러그인을 사용해 여러 루트 디렉터리를 고정된 순서로 스캔하고, 그 결과를 레지스트리에 모읍니다. "새 skill을 설치한다"는 별개의 일입니다 — 커뮤니티 skill 마켓(예: Tencent의 SkillHub)이나 dsh의 Plugin Market에 가서 남의 SKILL.md를 받아 이 선반 디렉터리들에 설치하면 됩니다 — 아래의 "바로 쓸 수 있는 Skill 설치하기" 절이 정확히 그것을 합니다.
dsh-skill-filesystem은 여러 루트 디렉터리를 고정된 순서로 스캔해 skill들을 레지스트리에 모읍니다. 위쪽에 있을수록 우선순위가 높습니다 — 같은 이름의 skill이 여러 선반에 나타나면 앞선 쪽이 이깁니다.
| 우선순위 | 디렉터리 | 누가 여기에 두나 |
|---|---|---|
| 1 | <project-root>/.dsh/skills | 프로젝트를 따라 다니며, 리포와 함께 배포 |
| 2 | <project-root>/.agents/skills | 다른 도구(예: Claude Code)와 공유하는 호환 위치 |
| 3 | 설정 customSkillDirs의 커스텀 디렉터리 | 사용자가 수동으로 지정한 다른 위치 |
| 4 | <dshHome>/skills (~/.dsh/skills) | 사용자 레벨, 어느 워크스페이스에서나 사용 가능 |
| 5 | <agentsHome>/skills (~/.agents/skills) | 다른 Agent 도구와 공유되는 사용자 레벨 디렉터리 |
모델이 Skill을 "어떻게 보는가"
Skill은 모델이 보도록 쓰여 있습니다. 모델은 어떤 것이 존재하는지 어떻게 알까요? 이 메커니즘은 dsh-tool-skill 플러그인이 제공하며, web 설정에 기본으로 설치되어 있습니다 (dsh --profile web --dump-config로 확인할 수 있습니다). 세 가지 메커니즘으로 작동합니다.
- 세션 디렉터리: 세션이 시작되고 첫 요청 전에, 모델은 사용 가능한 모든 skill의 이름과 한 줄 설명을 나열하는 영속 메시지를 받으며, "행동하기 전에 매칭되는 skill을 먼저 로드하고, 요약으로 추측하지 말라"는 안내를 받습니다.
skill도구: 모델이 skill이 관련 있다고 판단하면skill({ name })로 전체 지시 본문을 로드합니다 — 본문은<skill_content>블록으로 반환되며, 도구 결과로서 히스토리에 남습니다. 아래 그림은 실제 트래젝토리입니다. 모델이 먼저skill도구를 호출해aihot의 전체 지시를 로드한 다음pwsh를 호출해 검증 요청을 수행합니다. 트래젝토리에서 두 도구 호출이 또렷이 보입니다.

- 사용자 제스처
/이름: 입력창에 직접/code-review를 입력하면, 그 skill의 지시가 사용자 메시지로 그 라운드에 주입되며, 모델은 그대로 따릅니다. 참고: 이 이름은 반드시 워크스페이스 선반에 실제로 존재하며 사용자 호출을 허용해야 합니다 — 존재하지 않는 skill 이름을 입력하면 평범한 텍스트로 취급되어 아무 효과가 없습니다.
한 가지 디테일이 있습니다. 사용자의 /이름 주입 이후에는 모델이 같은 지시가 두 번 들어가지 않도록 skill 도구로 다시 로드하지 않습니다.
모델에게 "지금 어떤 skill이 있냐"고 물었는데 대답하지 못한다면, 우선 web 설정에 @deepseek-ai/dsh-tool-skill 플러그인이 있는지 확인합니다 (dsh --profile web --dump-config로 한 번에 확인).
직접 해보기: 바로 쓸 수 있는 Skill 설치 (그대로 사용)
바로 쓸 수 있는 skill을 설치한다는 본질은, 남의 만들어 둔 SKILL.md를 dsh의 "선반" 디렉터리(보통 프로젝트 레벨의 .dsh/skills)에 두는 것입니다 — 커뮤니티에는 이미 가져다 쓸 수 있는 skill이 잔뜩 있습니다.
여기서는 aihot을 예로 듭니다. 잘 알려진 AI 테크 블로거 "디지털 라이프 카즈크"의 검색형 skill로, 매일의 AI 뉴스와 업계 동향을 스크레이핑하는 데 능합니다.
1단계: Agent에게 한마디 해서 직접 설치하게 하기
스스로 파일을 찾고 디렉터리를 만들 필요가 없습니다. 대화로 돌아가 이렇게 말합니다.
다음 AIHOT Skill을 설치해 주세요: https://aihot.virxact.com/aihot-skill/README.md 설치 후 새 세션을 시작해야 하는지 알려 주세요. 설치기가 지원한다면 다음을 덧붙여 주세요: --actor your-Actor-ID
--actor 뒤의 ID는 AIHOT 플랫폼에 등록한 뒤 부여되며, 설치 후 로컬의 .aihot-actor-id에 기록됩니다. Agent가 요청할 때 자신을 식별하기 위해 함께 들고 갑니다.
Agent가 직접 합니다 — 공식 사이트에 가서 AIHOT의 SKILL.md와 동반 파일을 받아, DSH의 표준 발견 위치(~/.agents/skills/aihot/)에 두고, 파일마다 SHA-256 무결성 검사를 하고, actor 설정을 적고, .gitignore를 생성하고, 결과를 보고합니다. 설치 후 새 세션을 시작할 필요 없습니다 — 이미 현재 세션의 <available_skills>에 들어가 있어 바로 사용할 수 있습니다.

2단계: 모델에게 새 Skill을 보고하게 하기
대화로 돌아가 이렇게 묻습니다.
지금 어떤 skill을 가지고 있나요? aihot skill은 무엇을 하나요?
모델이 보고할 것입니다 — 코드 한 줄도 쓰지 않고 재사용 가능한 역량을 얻었습니다. 그리고 이 skill이 구체적으로 무엇을 하는지도 알려 줍니다 (aihot은 AIHOT의 익명 읽기 전용 API를 통해 현재 실재하는 중국어 AI 뉴스를 조회하며, 학습 기억에서 뉴스를 "지어내지" 않습니다).

3단계(선택): 모델이 사용하게 하기
그냥 "aihot을 사용해 오늘의 AI 뉴스를 스크레이핑해"라고 하면, 모델이 이 skill을 로드해 스크레이핑합니다. 누군가 다듬은 검색 흐름이 이제 당신의 역량이 되었습니다 — 이것이 "그대로 사용"입니다.

흔한 함정
| 함정 | 회피법 |
|---|---|
description을 빠뜨림 | 필수 필드가 빠지면 경고와 함께 전체 skill이 폐기됨 |
| 디렉터리 단계를 잘못 둠 | <루트>/<이름>/SKILL.md 또는 <루트>/<이름>.md만 인식되며, 한 단계이며 더 깊게 중첩하지 않는다 |
| 모델이 능동적으로 사용하지 않음 | description에 "언제 사용하는지"를 분명히 쓴다 (whenToUse도 도움); 정말 걱정되면 /이름으로 직접 주입 |
| 본문을 수정했는데 모델이 반응하지 않음 | 본문 수정은 디렉터리 요약에 영향을 주지 않는다; 모델이 "다시 로드"해야 한다; description 같은 요약 필드만 수정하면 즉시 디렉터리에 반영 |
이번 장에서 배운 것
다음 항목들을 스스로 완수할 수 있으면 합격입니다.
- [ ] Skill이 "Agent를 위해 쓰여진 재사용 가능한 지시문"임을 말할 수 있고, 도구와의 차이가 재사용성임을 안다
- [ ] dsh에서 Skill 역시 플러그인임을 안다 (skill 레지스트리 + 파일시스템 발견 + 도구 소비자)
- [ ] Skill의 구조를 말할 수 있다 (frontmatter에
name/description필수,whenToUse선택) - [ ] 다섯 개 선반의 우선순위를 안다 (프로젝트
.dsh/skills가 가장 높고, 사용자 디렉터리가 그 다음이며, 프로젝트를 가로질러 사용 가능) - [ ] "Agent에게 한마디 → skill을 설치 → 모델이 보고 → 모델이 로드하여 사용"을 한 번 돌려 봤다
- [ ] 두 스위치
disable-model-invocation와user-invocable를 구분한다
