OMC (oh-my-claudecode) · 컨텍스트/프롬프트 조립 (CLAUDE.md 주입 + 키워드 감지 + 스킬 인젝션)

한 줄 요약

OMC는 Claude가 보는 텍스트를 파일(CLAUDE.md)·입력 가로채기(키워드 훅)·세션 복원 세 군데에서 조립해, 백지 상태로 시작하는 모델에게 “무엇을 알고 시작할지”를 심는다. 왜 배우나: 키워드 한 단어로 모드가 켜지는 마법의 정체가 이 “프롬프트 조립”이며, 직접 하네스를 만들 때 가장 먼저 베껴야 할 핵심이다.


그림

flowchart TD
  A["설치 1회: omc-setup"] --> B["CLAUDE.md에<br/>OMC:START~END 마커 블록 끼우기"]
  B -. "세션마다 CC가 자동 로드" .-> M["모델 시스템 프롬프트<br/>(항상 켜진 운영 매뉴얼)"]

  S["세션 시작 SessionStart"] --> S1["상태 복원<br/>(ralph·ultrawork·메모리·notepad)"]
  S1 --> AC["additionalContext<br/>(추가 주입 텍스트)"]

  U["사용자 입력 UserPromptSubmit"] --> K["키워드 탐지기"]
  K --> K1["청소: 코드·인용·옛 로그 제거"]
  K1 --> K2{"매직 키워드?"}
  K2 -- "예" --> K3["모드 상태파일 쓰기<br/>+ MAGIC KEYWORD 안내문"]
  K2 -- "아니오" --> K4["그냥 통과"]
  U --> J["스킬 주입기"]
  J --> J1["트리거 매칭 + 점수"]
  J1 --> J2["학습된 스킬 요약 블록"]
  K3 --> AC
  J2 --> AC
  AC --> M
  M --> R["모델 응답:<br/>모드/스킬 실행"]

쉽게 풀기

Claude 본체는 기억이 없는 천재 가정교사다. 매번 새로 출근해 책상 위 종이만 읽고 일을 시작하며, 어제 한 일도 집에 있는 도구도 스스로는 모른다. OMC는 그 가정교사가 출근하기 전에 책상에 종이를 미리 깔아두는 비서다. 종이를 까는 자리가 세 군데다.

flowchart LR
  subgraph 정적["1. 벽 안내문 (설치 1회)"]
    P1["CLAUDE.md 마커 블록"]
  end
  subgraph 동적["2. 현관 쪽지 (매 입력)"]
    P2["키워드 탐지 훅"]
    P3["스킬 주입기"]
  end
  subgraph 복원["3. 어제 일지 (세션 시작)"]
    P4["SessionStart 복원"]
  end
  정적 --> 모델["기억 없는 천재 모델"]
  동적 --> 모델
  복원 --> 모델
  1. 벽에 붙인 상시 안내문 (CLAUDE.md 마커 블록) — 설치 때 딱 한 번, CLAUDE.md<!-- OMC:START --> … <!-- OMC:END --> 주석 테두리 블록을 끼운다. 안에는 직원(에이전트)·연장(도구)·위임 규칙·모델 라우팅이 적혀 있다. Claude Code가 세션마다 CLAUDE.md를 자동 로드하므로 이 안내문은 항상 걸려 있는 운영 매뉴얼이 된다. 따로 주입 코드를 돌릴 필요 없이 파일에 박아두면 끝.

  2. 현관에서 쪽지 끼우기 (키워드 훅, 매 입력) — 사용자가 문장을 칠 때마다 UserPromptSubmit 훅이 먼저 가로챈다. ralph·autopilot·ultrawork·ccg 같은 매직 키워드가 보이면 “이 모드를 시작하라”는 쪽지를 끼워준다(keyword-detector.mjs). 동시에 입력과 관련 있는 “학습된 스킬” 요약도 함께 끼운다(skill-injector.mjs).

  3. 출근 직후 어제 일지 복원 (SessionStart) — 새 세션이 시작되면 프로젝트 메모리·위키·notepad 우선순위 메모·중단됐던 모드 상태(ralph 루프 등)를 다시 책상에 올린다(session-start.mjs / wiki-session-start.mjs).

핵심 비유: 모델은 추론기, OMC는 그 앞에 종이를 까는 담당자. 마법 같은 자동화는 전부 “어떤 종이를 깔았느냐”의 결과다.

가로챈 쪽지를 모델이 왜 따를까?

훅이 끼운 텍스트는 모델에게 “시스템이 준 추가 지시문”으로 보인다. 사용자 글인지 비서 쪽지인지 구분 못 하고 한 덩어리로 읽기 때문에, 키워드 한 단어가 모드를 켠다.


핵심 정리

조립이 일어나는 세 자리

자리시점누가
CLAUDE.md 마커 블록설치 1회 (정적)installer
키워드·스킬 쪽지매 입력 (동적)keyword-detector / skill-injector
세션 복원세션 시작마다session-start / wiki-session-start

마커 블록 안의 주요 섹션

섹션 태그한 줄 역할
OMC:VERSION설치 버전(드리프트 감지)
<operating_principles>위임·증거우선·최소경로 원칙
<delegation_rules>위임 vs 직접 판단
<model_routing>haiku·sonnet·opus 배분
<agent_catalog>에이전트 + 기본 모델
<tools> / <skills>도구 목록 / 키워드→스킬 매핑

키워드 → 모드 매핑 (요지)

상태파일까지 만드는 스킬형과 텍스트만 끼우는 모드형으로 갈린다.

flowchart TD
  IN["입력 키워드"] --> Q{"sanitize 후<br/>매칭 + 정보성 질문?"}
  Q -- "정보성('ralph가 뭐야?')" --> SKIP["모드 안 켬"]
  Q -- "스킬형" --> SF["상태파일 + 안내문<br/>ralph·autopilot·ultrawork·ultragoal·ralplan"]
  Q -- "모드형" --> MF["텍스트만<br/>ccg·deep-interview·tdd·review·wiki…"]
  SF -. "ralph는 동반" .-> UW["ultrawork 상태파일도 생성"]
  • ralph / don't stop / until done / 랄프(로렌 제외) → ralph (상태파일 , ultrawork 동반)
  • autopilot / full auto / 오토파일럿autopilot (상태파일 )
  • ultrawork / ulw / uwultrawork (상태파일 )
  • ultragoal / ralplan → 각각 상태파일 (명시 호출 의도 요구)
  • ccg / deep interview / tdd / code review / ultrathink / wiki 등 → 텍스트 모드만 (상태파일 )

스킬 인젝션 예산 (토큰 폭발 방지)

제한의미
디스크립터 1개최대 1000자본문은 디스크, 요약만
전체 컨텍스트최대 3000자한 입력 총량
세션당 개수최대 5개초과분은 미주입
재주입 방지세션 1시간 TTLdedup

실제 예시

A. 설치 시 박히는 CLAUDE.md 마커 블록

<!-- OMC:START -->
<!-- OMC:VERSION:4.9.1 -->
# oh-my-claudecode - Intelligent Multi-Agent Orchestration
...
<skills>
Keyword triggers: "autopilot"→autopilot, "ralph"→ralph, "ulw"→ultrawork, ...
</skills>
<!-- OMC:END -->

B. 키워드 매칭 후 끼워지는 안내문 (본문이 아니라 “경로 + 안내”만)

핵심은 스킬 본문을 인라인하지 않고 경로만 가리킨다는 점이다. 흐름은 아래와 같다.

sequenceDiagram
  participant U as 사용자
  participant H as keyword-detector
  participant CC as Claude Code
  participant M as 모델
  U->>H: 입력 ("ralph 시작")
  H->>H: sanitize → 키워드 매칭
  H->>H: 모드 상태파일 atomic write
  H-->>CC: additionalContext (경로+안내, 본문 X)
  CC->>M: 원문 + 주입텍스트 병합
  M->>M: SKILL.md 읽어 워크플로 시작

C. 학습된 스킬 frontmatter + 주입 형식

# skills/wiki/SKILL.md
name: wiki
triggers: ["wiki", "wiki this", "wiki add", "wiki lint", "wiki query"]

D. 훅이 stdout으로 돌려주는 JSON (모델이 소비하는 핵심)

{ "continue": true,
  "hookSpecificOutput": {
    "hookEventName": "UserPromptSubmit",
    "additionalContext": "<주입할 텍스트>"
  } }

message가 아니라 반드시 hookSpecificOutput.additionalContext 여야 모델이 받는다(코드 주석에 명시). Claude Code가 이 값을 모델 컨텍스트에 추가한다.

E. 직접 만들 때 최소 키워드 훅

// myharness/scripts/keyword-hook.mjs
#!/usr/bin/env node
import { readFileSync } from 'fs';
const input = readFileSync(0, 'utf-8');           // stdin
let data = {}; try { data = JSON.parse(input); } catch {}
const prompt = (data.prompt || '').toLowerCase();
 
// echo/코드블록 제거(false positive 방지)
const clean = prompt.replace(/```[\s\S]*?```/g, '').replace(/`[^`]+`/g, '');
 
const MAP = [
  [/\b(loop|don't stop|until done)\b/, 'ralph'],
  [/\b(auto|autopilot)\b/, 'autopilot'],
];
let hit = null;
for (const [re, name] of MAP) if (re.test(clean)) { hit = name; break; }
 
if (!hit) { console.log(JSON.stringify({ continue: true, suppressOutput: true })); process.exit(0); }
 
console.log(JSON.stringify({
  continue: true,
  hookSpecificOutput: {
    hookEventName: 'UserPromptSubmit',
    additionalContext:
`[MAGIC KEYWORD: ${hit.toUpperCase()}]
Preferred invocation: /myharness:${hit}
Read fallback: skills/${hit}/SKILL.md
IMPORTANT: start the ${hit} workflow immediately.`
  }
}));

모드 상태파일이라는 부수효과

키워드가 매칭되면 텍스트만 넣는 게 아니라 <omcRoot>/state/sessions/<sid>/<mode>-state.json을 atomic write 한다. 예: ralph는 {active, iteration, max_iterations:100, prompt, session_id, linked_ultrawork:true, awaiting_confirmation:true}. 이 파일을 Stop 훅(persistent-mode.mjs)이 읽어 루프 강제에, SessionStart가 읽어 모드 복원에 쓴다. 그래서 ralph 키워드는 ultrawork 상태파일도 같이 만든다.

직접 만들 때 체크리스트

  • 마커 래퍼는 START/END + VERSION 3줄, 교체 시 사용자 본문 보존(^START\r?\n[\s\S]*?^END).
  • 키워드 훅은 stdin JSON 읽고 hookSpecificOutput.additionalContext로만 반환(message 아님).
  • 정보성 질문/코드블록/과거 echo는 sanitize 후 매칭(자기강화 루프 방지).
  • 자동 스폰 위험 키워드(team류)는 자동감지에서 빼고 슬래시 전용으로.
  • 스킬 본문 인라인 금지, “경로 + 요약”만(세션당 개수/문자 예산 둘 것).
  • 모드 상태는 session-scoped JSON atomic write, SessionStart에서 복원.
  • 훅 실패는 항상 {continue:true} fail-open.
  • 킬스위치 env(DISABLE_OMC, OMC_SKIP_HOOKS=keyword-detector) 존중.

요약 & 셀프체크

3줄 요약

  1. 모델은 백지 천재, OMC는 그 앞에 종이를 까는 비서 — CLAUDE.md(상시)·키워드 훅(매 입력)·세션 복원(시작) 세 자리에서 텍스트를 조립한다.
  2. CLAUDE.md 마커 블록은 자동 로드되고, 키워드·스킬은 훅이 additionalContext로 끼우되 본문이 아니라 “경로 + 요약”만 넣어 토큰을 아낀다.
  3. 무한 루프·자기강화·오탐을 막는 안전장치(team 제외, 정보성 질문 필터, echo 제거, 예산 제한)가 핵심 노하우다.

스스로 답해보기

  • Q1. 키워드 한 단어가 모드를 켤 수 있는 이유는? (힌트: 모델이 사용자 글과 훅 쪽지를 어떻게 구분하나)
  • Q2. 스킬 본문을 통째로 안 넣고 “경로 + 요약”만 넣는 이유 두 가지는?
  • Q3. “ralph”는 상태파일을 만드는데 “tdd”는 안 만든다. 왜 차이가 날까?

연결

OMC_개요 · OMC_10_entrypoint-hooks-loop · _분석축_루브릭


근거 파일

Codex 교차검증

별도 Codex 교차검증 기록은 없다. 핵심 사실(마커 블록 자동 로드, additionalContext 필드 필수, team 자동감지 제외, 스킬 예산 제한, ralph→ultrawork 동반 상태파일)은 모두 위 근거 파일의 실코드/실측에 근거하며 추측으로 변경하지 않았다. 추후 교차검증 결과는 이 콜아웃에 누적한다.