Codex · 확장점: Skills (SKILL.md + progressive disclosure)

한 줄 요약

Skill은 “이런 작업은 이렇게 처리하라”를 적어둔 폴더 하나이고, Codex는 평소엔 그 목차만 보다가 필요할 때만 본문을 펼쳐 읽는다. 왜 배우나: 새 작업 절차를 코드 수정 없이 AI에게 안전하게 가르치는 가장 표준적인 방법이고, 컨텍스트를 아끼는 “점진 공개” 원리를 그대로 보여주기 때문이다.

그림

flowchart TD
  A["스킬 루트들<br/>Repo · User · Admin · System 캐시"] --> B["로더: 폴더 스캔<br/>SKILL.md + agents/openai.yaml 파싱"]
  B --> C["스킬 목록<br/>(이름·설명·경로)"]
  C --> D["예산 적용<br/>강등/alias 정리"]
  D --> E["초기 카탈로그(목차)<br/>모델에게 한 줄씩 보여줌"]
  E --> F["모델: 요청 vs 설명 매칭<br/>또는 사용자가 $이름 명시"]
  F --> G["고른 스킬의 SKILL.md 전체 읽기"]
  G --> H["본문 절차대로 실행<br/>scripts 실행 / references 읽기"]

쉽게 풀기

스킬을 요리 레시피 카드라고 생각하면 쉽다.

  1. 레시피 카드 = 폴더 하나. 폴더 안에는 반드시 SKILL.md라는 설명서 한 장이 있다. 여기에 “언제 쓰는 요리인지”와 “어떻게 만드는지”가 적혀 있다. 옆에 도구(scripts/ = 실행 코드), 참고서(references/), 사진·아이콘(assets/)을 곁들일 수도 있다.

  2. 요리사(Codex)는 처음엔 메뉴판만 본다. 대화를 시작할 때 Codex는 설치된 모든 레시피의 이름 · 한 줄 설명 · 어디 있는지만 쭉 훑는다. 카드 전체를 다 읽지는 않는다. 책장에 책이 100권 있어도 책등 제목만 먼저 보는 것과 같다.

  3. 주문이 들어오면 그때 해당 카드를 펼친다. 사용자의 요청이 어떤 레시피의 “한 줄 설명”과 맞아떨어지면, 그제야 그 SKILL.md를 통째로 열어 읽고 적힌 순서대로 일한다. 이렇게 “처음엔 목차만, 필요할 때 본문”으로 컨텍스트를 아끼는 방식을 **progressive disclosure(점진 공개)**라고 부른다.

  4. 메뉴판이 너무 길면 글씨를 줄인다. 스킬이 너무 많아 목차조차 자리를 많이 차지하면, Codex는 정해진 예산(컨텍스트의 약 2%, 또는 8,000자)까지만 채운다. 그 안에 안 들어가면 설명을 짧게 줄이고, 그래도 안 되면 일부 스킬은 빼고 “몇 개 빠졌다”고 경고한다.

두 번 "주입"된다는 게 핵심

스킬은 모델에게 두 단계로 들어간다. ① 목차 단계(모든 스킬의 한 줄 요약) → ② 본문 단계(고른 스킬의 SKILL.md 전체). 목차는 항상 보이지만, 무거운 본문은 선택된 것만 들어간다. 그래서 스킬이 많아도 평소 컨텍스트가 터지지 않는다.

핵심 정리

스킬 폴더 구성 요소:

항목필수?역할
SKILL.md필수frontmatter(이름+설명) + 본문 지시문
agents/openai.yaml선택UI 표시·정책·의존성 메타데이터
scripts/선택결정적 동작이 필요할 때 쓰는 코드
references/ · assets/선택추가 참고문서 · 아이콘/템플릿

SKILL.md frontmatter 필드:

필드필수?핵심 제약
name사실상 필수최대 64자. 비면 폴더명으로 대체
description필수최대 1024자. 비면 로드 실패. 암묵 호출 매칭의 핵심
metadata.short-description선택최대 1024자. 비거나 길면 무시

점진 공개 예산과 3단 강등 (render.rs)

  • 예산: 컨텍스트 창을 알면 창 크기 × 2 / 100 토큰(예: 200,000 → 4,000). 모르면 8,000자.
  • 1단계: 모든 설명을 전부 넣어도 예산 이내면 → 전부 포함.
  • 2단계: 안 되면 → 설명을 한 글자씩 공평 분배해 균등 축약. 평균 100자 넘게 잘리면 “설명이 줄었다” 경고.
  • 3단계: 그래도 안 되면 → 설명 전부 제거, 우선순위 높은 스킬부터 채우고 나머지는 빼며 “N개 누락” 경고.
  • 우선순위: System(0) > Admin(1) > Repo(2) > User(3), 동순위는 이름순.
  • alias 최적화: 경로가 길어 예산을 까먹으면 r0 = /절대/경로 별칭 테이블로 바꿔, 더 많은 스킬이 들어가는 쪽을 택한다.

스캐너 동작 상수 (loader.rs)

파일명 SKILL.md · 메타데이터 agents/openai.yaml · 탐색 깊이 최대 6 · 루트당 디렉토리 한도 2,000 · .으로 시작하는 항목은 스킵 · 심볼릭 링크는 Repo/User/Admin에서만 추적(System은 미추적). 메타데이터는 fail-open: openai.yaml이 없거나 깨져도 SKILL.md 로딩은 막지 않고 기본값으로 넘어간다.

실제 예시

A. 디렉토리 레이아웃 (실제 시스템 스킬 구조와 동일)

my-skill/
├── SKILL.md            # 필수. YAML frontmatter(name+description) + 본문 지시
├── agents/
│   └── openai.yaml     # 선택. interface/policy/dependencies 메타데이터
├── scripts/            # 선택. 결정적 동작이 필요할 때 실행/패치할 코드
├── references/         # 선택. SKILL.md가 가리키는 추가 참고문서
└── assets/             # 선택. 아이콘·템플릿 등 (아이콘은 반드시 이 아래)

B. 시스템 내장 스킬 frontmatter (실제 소스 인용)

// codex-rs/skills/src/assets/samples/skill-creator/SKILL.md
---
name: skill-creator
description: Guide for creating effective skills. This skill should be used when users want to create a new skill (or update an existing skill) that extends Codex's capabilities with specialized knowledge, workflows, or tool integrations.
metadata:
  short-description: Create or update a skill
---
 
# Skill Creator
 
This skill provides guidance for creating effective skills.

C. agents/openai.yaml — 의존성·인터페이스 선언 (실제 소스 인용)

# codex-rs/skills/src/assets/samples/openai-docs/agents/openai.yaml
interface:
  display_name: "OpenAI Docs"
  short_description: "Reference OpenAI docs, Codex self-knowledge, and model migration guidance"
  icon_small: "./assets/openai-small.svg"
  icon_large: "./assets/openai.png"
  default_prompt: "Use OpenAI Docs for official docs lookup, questions about Codex itself or Codex surfaces, model selection, model migration, and prompt-upgrade work."
 
dependencies:
  tools:
    - type: "mcp"
      value: "openaiDeveloperDocs"
      description: "OpenAI Developer Docs MCP server"
      transport: "streamable_http"
      url: "https://developers.openai.com/mcp"

agents/openai.yaml의 주요 옵션(loader.rs SkillMetadataFile):

  • interface.icon_small / icon_large — 반드시 assets/ 하위 상대경로. 절대경로/.. 금지(플러그인 공유 assets만 예외).
  • interface.brand_color#RRGGBB 정확히 7자만 허용, 아니면 무시.
  • policy.allow_implicit_invocation — 기본 true. false$skill 명시 호출만 가능(자동 매칭 제외).
  • policy.productsChatgpt/Codex/Atlas 제품 게이팅. 비면 전제품 허용.
  • dependencies.tools[].type / value — 항목별 필수(예: "mcp" + MCP 서버 식별자).

D. 컨텍스트에 실제로 들어가는 두 형태 (render.rs · skill_instructions.rs)

# 초기 카탈로그(목차) 한 줄 형식
- {name}: {description} (file: {path})
# 설명이 잘리면: - {name}: {앞부분} (file: {path})
# 전부 제거되면: - {name}: (file: {path})
 
# 스킬 선택 후 본문 주입 형식 (<skill> 마커)
<skill>
<name>{name}</name>
<path>{path}</path>
{SKILL.md 전체 내용}
</skill>

모델에 들어가는 두 프래그먼트의 정체

초기 카탈로그 = AvailableSkillsInstructions, 역할 developer, 마커 <skills_instructions>. ## Skills 인트로 + ### Available skills(한 줄들) + ### How to use skills(점진 공개 규칙: “SKILL.md를 EOF까지 완전히 읽어라, 서브에이전트에 위임 금지” 등)로 조립. 대상은 활성화 + allow_implicit_invocation인 스킬만. ② 선택된 스킬 본문 = SkillInstructions, 역할 user, 마커 <skill>. build_skill_injections가 명시($이름/링크) 또는 암묵 매칭으로 고른 스킬의 SKILL.md를 파일에서 읽어 주입하고 codex.skill.injected 메트릭을 낸다.

E. 직접 만들 때 — 최소 스킬 템플릿

// my-skill/SKILL.md  (지시문만 있는 최소 스킬)
---
name: my-skill
description: Explain exactly when this skill should and should not trigger. Front-load the key use case and trigger words.
metadata:
  short-description: One-line UI label
---
 
# My Skill
 
1. 첫 단계 (명령형, 입력/출력 명시)
2. 둘째 단계
- 결정적 동작이 필요하면 scripts/foo.py 를 실행/패치하라.

저장 위치(스코프별): Repo = $CWD/.agents/skills/, User = $HOME/.agents/skills/, Admin = /etc/codex/skills/. 명시 호출은 $my-skill. 비활성화는 ~/.codex/config.toml[[skills.config]] + path + enabled = false.

만들 때 체크리스트:

  • SKILL.md 첫 줄 ---, 닫는 --- 있는가 (없으면 로드 실패)
  • name(≤64자) + description(≤1024자, 비면 실패) 채웠는가
  • description에 트리거 조건·범위·경계를 앞쪽에 배치했는가 (축약돼도 매칭되게)
  • 폴더를 .agents/skills/ 같은 스코프 루트 아래(깊이 6 이내)에 뒀는가, 폴더명이 .으로 시작하지 않는가
  • (선택) agents/openai.yaml로 interface/policy/dependencies 선언 — 아이콘은 assets/ 하위 상대경로, brand_color는 #RRGGBB
  • 자동 매칭을 막으려면 policy.allow_implicit_invocation: false
  • scripts/references는 SKILL.md에서 명시적으로 라우팅 (모델이 직접 읽도록)

F. 시스템 내장 스킬 설치 (skills 크레이트 lib.rs)

내장 스킬은 바이너리에 include_dir!로 임베드되어 install_system_skills$CODEX_HOME/skills/.system/에 풀어쓴다. 매 시작마다 다시 쓰지 않도록 임베드 디렉토리 핑거프린트(해시, salt v1)를 .codex-system-skills.marker에 기록하고, 마커가 일치하면 설치를 건너뛴다. 불일치면 기존 디렉토리를 지우고 다시 쓴다. 로더는 이 .system 경로를 SkillScope::System 루트로 스캔하며, System 스코프 파싱 오류는 사용자 에러 목록에 올리지 않는다.

요약 & 셀프체크

3줄 요약:

  • 스킬은 SKILL.md 한 장(이름+설명+본문)을 가진 폴더로, AI에게 작업 절차를 코드 수정 없이 가르친다.
  • 평소엔 “한 줄 설명 목차”만 모델에 들어가고(점진 공개), 요청과 맞아떨어질 때만 본문 전체가 주입된다.
  • 목차가 예산(2% 또는 8,000자)을 넘으면 설명 축약 → 일부 제거 순으로 강등하고, 우선순위는 System > Admin > Repo > User다.

스스로 답해보기:

  1. 사용자가 스킬을 명시하지 않았는데도 Codex가 그 스킬을 골라 쓰게 만드는 필드는 무엇이고, 자동 매칭을 막으려면 어디를 어떻게 바꾸는가?
  2. 설치된 스킬이 너무 많아 목차 예산을 초과하면 어떤 순서로 어떤 일이 일어나는가?
  3. 모델에 들어가는 “목차 프래그먼트”와 “본문 프래그먼트”는 각각 역할(role)과 마커가 어떻게 다른가?

연결

CX_개요 · _분석축_루브릭

근거 파일

  • /home/seunghyeong/harness-work/codex/codex-rs/core-skills/src/model.rs (SkillMetadata, SkillPolicy, SkillInterface, SkillDependencies/SkillToolDependency, allows_implicit_invocation, 제품 제한)
  • /home/seunghyeong/harness-work/codex/codex-rs/core-skills/src/loader.rs (SKILL.md/openai.yaml 파싱, frontmatter 추출, 스캔 상수, 스코프별 루트, 길이 제한)
  • /home/seunghyeong/harness-work/codex/codex-rs/core-skills/src/render.rs (예산 8000자/2%, 3단 강등, alias 테이블, 카탈로그 한 줄 형식, How-to-use 지시)
  • /home/seunghyeong/harness-work/codex/codex-rs/core-skills/src/skill_instructions.rs (<skill> 마커, name/path/contents 본문 주입)
  • /home/seunghyeong/harness-work/codex/codex-rs/core-skills/src/injection.rs (build_skill_injections, 명시/암묵 멘션 수집, $토큰·링크 파싱)
  • /home/seunghyeong/harness-work/codex/codex-rs/core/src/context/available_skills_instructions.rs (developer role, <skills_instructions> 프래그먼트)
  • /home/seunghyeong/harness-work/codex/codex-rs/skills/src/lib.rs (시스템 내장 스킬 .system 캐시 설치, marker 핑거프린트)
  • /home/seunghyeong/harness-work/codex/codex-rs/skills/src/assets/samples/skill-creator/SKILL.md, …/openai-docs/agents/openai.yaml (실제 예시 인용)
  • /home/seunghyeong/harness-work/codex/codex-rs/protocol/src/protocol.rs (SkillScope, Product, SKILLS_INSTRUCTIONS_OPEN/CLOSE_TAG)
  • /mnt/d/6study/10_프레임워크분석/_원문아카이브/codex/83_agent-skills.md (공식문서: progressive disclosure, 2%/8000자, 스코프 표, 메타데이터)

Codex 교차검증 메모 (원본 분석 보존)

본 노트의 모든 형식·상수·스키마는 codex-rs 실제 소스에서 확인된 값이다. 핵심 근거: 스캔 상수(MAX_SCAN_DEPTH=6, MAX_SKILLS_DIRS_PER_ROOT=2000, SKILLS_FILENAME=SKILL.md, SKILLS_METADATA_DIR/FILENAME=agents/openai.yaml)와 길이 제한(MAX_NAME_LEN=64, qualified 128, MAX_DESCRIPTION_LEN=1024)은 loader.rs, 예산(default_skill_metadata_budget = window×2/100, 미지 시 DEFAULT_SKILL_METADATA_CHAR_BUDGET=8000)·3단 강등(render_skill_lines_from_lines)·경고 임계(WARNING_THRESHOLD_CHARS=100)·alias 비교(aliased_render_is_better)·우선순위(prompt_scope_rank)는 render.rs, 본문 주입 <skill> 마커는 skill_instructions.rs, 목차 developer 프래그먼트·<skills_instructions> 태그는 available_skills_instructions.rs와 protocol.rs에서 확인됨. 메타데이터 fail-open과 System 스코프 오류 비노출 동작도 소스 기준으로 보존.