Skip to main content

Command Palette

Search for a command to run...

같은 AI에게 다른 결과를 얻는 법: Claude Code 스킬과 Context Engineering

Updated
5 min read

AI 코딩 도구의 불편한 진실

요즘 AI 코딩 도구를 쓰지 않는 개발자를 찾기 어렵다. 하지만 솔직히 말하면, 대부분의 개발자가 비슷한 불만을 갖고 있다.

"어제는 잘 해줬는데 오늘은 왜 이러지?"

같은 도구, 같은 요청인데 결과가 들쭉날쭉하다. CLAUDE.md를 작성해달라고 하면 어떤 날은 프로젝트에 딱 맞는 걸 만들어주고, 어떤 날은 어디서 복사해온 듯한 일반적인 내용만 나열한다. 기능을 개발해달라고 하면 기존 코드를 완전히 무시하고 새로 작성하기도 한다.

나도 그랬다. Claude Code를 쓰면서 매번 같은 것을 반복해서 설명했다. "이 프로젝트는 이런 구조고, 이런 컨벤션을 쓰고, 이건 이렇게 해야 해." 매 세션마다 처음부터. 결과의 품질은 그날 내가 얼마나 상세하게 설명했느냐에 달려 있었다.

문제는 AI가 아니었다. 내가 AI에게 주는 맥락이 문제였다.


Prompt Engineering에서 Context Engineering으로

Andrej Karpathy는 이렇게 말했다.

"Context engineering is the delicate art and science of filling the context window with just the right information for the next step."

"프롬프트 엔지니어링"이라는 말을 들으면 뭐가 떠오르는가? 대부분은 짧은 질문을 잘 다듬는 기술을 떠올린다. "이렇게 물어보면 더 좋은 답이 나온다" 같은 팁. 하지만 실제로 AI를 업무에 활용하려면, 단순한 질문 하나로는 부족하다.

Karpathy가 제안한 Context Engineering은 더 넓은 개념이다. LLM을 CPU로, 컨텍스트 윈도우를 RAM으로 비유하면, 개발자의 역할은 운영체제다. 작업에 필요한 정확한 정보를 적시에 메모리에 올리는 것. 너무 적으면 AI가 제대로 된 결과를 못 내고, 너무 많으면 핵심이 묻힌다.

토스 기술 블로그의 "소프트웨어 3.0 시대를 맞이하며"에서는 이 개념을 더 구체화한다. Claude Code의 구조를 전통적인 레이어드 아키텍처에 비유하면서, CLAUDE.md는 package.json처럼 정적 설정을, Skills는 단일 책임 원칙(SRP)을 따르는 도메인 컴포넌트 역할을 한다고 설명한다.

핵심은 이것이다: 같은 모델이라도 어떤 맥락을 주느냐에 따라 결과가 극적으로 달라진다. 그리고 그 맥락을 체계적으로 설계하는 것이 바로 Context Engineering이다.


반복되는 맥락을 패키징하다: 스킬이라는 해법

이 깨달음은 자연스럽게 다음 질문으로 이어졌다. "매번 수동으로 맥락을 구성하는 대신, 잘 설계된 맥락을 재사용할 수는 없을까?"

Claude Code의 스킬(Skills) 시스템이 바로 그 답이었다. 스킬은 SKILL.md 파일에 정의된 지시사항으로, Claude가 특정 작업을 수행할 때 자동으로 로드되는 재사용 가능한 컨텍스트 패키지다.

나는 두 가지 스킬을 만들었다.

claude-md-writer: CLAUDE.md 작성 자동화

CLAUDE.md를 잘 쓰는 것은 Context Engineering의 기본이다. 하지만 "잘" 쓰는 것이 의외로 어렵다. Anthropic 공식 권장사항인 200줄 제한을 지키면서, 코드에서 유추할 수 없는 정보만 포함하고, 모든 명령어는 복사-붙여넣기로 실행 가능해야 한다.

이 스킬은 5단계 워크플로우를 따른다:

  1. 탐색 — 기존 파일과 프로젝트 타입을 자동 감지

  2. 분석 — 빌드 시스템, 아키텍처, 환경을 병렬로 조사

  3. 인터뷰 — 코드에서 알 수 없는 정보를 사용자에게 질문

  4. 생성 — 분석과 인터뷰 결과를 종합하여 CLAUDE.md 작성

  5. 검증 — 품질 기준에 부합하는지 확인

핵심 설계 원칙은 "Would Claude fail without this?"다. 이 질문을 통과하지 못하는 정보는 포함하지 않는다. 코드를 읽으면 알 수 있는 것은 적지 않고, Claude가 모르면 틀릴 수밖에 없는 것만 남긴다.

new-feature: 기능 개발 워크플로우

기능 개발 요청을 받으면 바로 코드부터 작성하는 것이 AI의 본능이다. 하지만 이러면 기존 코드를 무시하고 새로 작성하거나, 잘못된 방향으로 한참을 달린 뒤에 되돌아오는 일이 생긴다.

이 스킬은 4단계 게이트를 강제한다:

  1. 리서치 — 요구사항 수집, 기존 코드 분석, 외부 자료 조사

  2. 작업 — 승인된 방향으로만 구현 (승인 없이는 코드를 쓰지 않음)

  3. 검토 — 요구사항 대조, 엣지케이스 확인, 보안 점검

  4. 보고 — 구현 내용과 검증 결과를 정리하여 전달

가장 중요한 설계 결정은 1단계와 2단계 사이의 승인 게이트다. AI가 조사 결과를 먼저 보여주고, 사용자의 승인을 받은 후에야 구현에 들어간다. "잘못된 방향으로 열심히 달리는" 문제를 구조적으로 차단한다.


스킬 도입 전과 후

Before:

  • 매 세션마다 프로젝트 컨텍스트를 처음부터 설명

  • 같은 요청에도 들쭉날쭉한 결과 품질

  • 보안 체크, 엣지케이스 확인 등을 빠뜨리는 경우 발생

  • "이번엔 잘 해줄까?" 하는 불확실함

After:

  • /claude-md-writer create 한 번이면 프로젝트 분석부터 CLAUDE.md 생성까지 완료

  • 누가 실행해도, 언제 실행해도 일관된 프로세스가 보장됨

  • 체계적인 검토 단계 덕분에 빠뜨리는 것이 줄어듦

  • 반복 작업에 들이던 시간이 줄어 핵심 의사결정에 집중 가능

가장 큰 변화는 일관성이었다. 스킬은 바닥을 올려준다. 최소한의 품질이 항상 보장되니, "오늘은 운이 좋아서 잘 나왔다"가 아니라 "항상 이 정도는 나온다"가 된다.


스킬은 바닥을 올리고, 사람은 천장을 결정한다

하지만 솔직하게 말해야 할 것이 있다. 스킬이 모든 것을 해결해주지는 않는다.

스킬은 프로세스를 패키징한 것이지, 판단력을 패키징한 것이 아니다. new-feature 스킬이 리서치 결과를 보여주고 승인을 요청할 때, 그 결과를 제대로 검토하고 올바른 방향을 제시하는 것은 여전히 사람의 몫이다. claude-md-writer가 인터뷰 질문을 할 때, 프로젝트의 진짜 맥락을 전달하는 것도 사람의 역할이다.

결국 최종 결과물의 품질은 그것을 검토하고 피드백하는 사람의 역량에 크게 좌우된다.

이것은 Context Engineering의 본질과도 맞닿아 있다. AI에게 좋은 맥락을 주는 것은 단순히 정보를 많이 넣는 것이 아니라, 올바른 정보를 올바른 시점에 제공하는 것이다. 스킬은 이 과정의 구조를 잡아주지만, 구조 안에 채워넣는 내용의 질은 사용하는 사람에게 달려 있다.

나는 이것을 이렇게 정리한다:

스킬은 바닥을 올려주고, 피드백은 천장을 결정한다.

AI 코딩 도구의 효과를 극대화하고 싶다면, 더 좋은 프롬프트를 고민하는 것을 넘어서 두 가지를 함께 해야 한다. 반복되는 맥락은 스킬로 체계화하고, 그 위에서 자신의 도메인 지식과 판단력으로 방향을 잡아주는 것. Context Engineering은 AI를 더 똑똑하게 만드는 기술이 아니다. 같은 AI에게서 더 나은 결과를 끌어내는 기술이다.


이 글에서 소개한 스킬들은 오픈소스로 공개되어 있습니다.GitHub: Tianea2160/claude-skills


참고 자료

More from this blog

JVM은 컨테이너의 CPU와 메모리 한계를 어떻게 알아낼까

8코어 노드에 컨테이너를 띄웠는데 ForkJoinPool이 스레드를 한두 개만 만들어요. 메모리는 넉넉히 줬는데 컨테이너가 자꾸 OOMKilled로 죽고요. 분명히 같은 JAR인데 로컬에서는 멀쩡하다가 쿠버네티스에만 올리면 이상해져요. 이 글은 "왜 컨테이너 속 JVM은 다르게 행동하는가"를 cgroup이라는 진짜 경계선과, JVM이 그 경계를 읽어내는 내

May 21, 202615 min read

ThreadPoolExecutor는 언제 스레드를 새로 만들까 — execute()의 3단계

Executors.newFixedThreadPool(10) 한 줄을 쓰면서도, 11번째 작업이 오면 스레드가 11개로 늘어날 거라고 막연히 기대해 본 적 없으신가요. 실제로는 큐가 먼저 무한히 쌓이고 스레드는 영원히 10개에 머물러요. 이 글은 ThreadPoolExecutor가 작업을 받았을 때 "스레드를 새로 만들지, 큐에 넣을지, 거부할지"를 결정하는

May 21, 202617 min read

자바 synchronized는 어떻게 동작할까 — 모니터, 락 인플레이션, 그리고 사라진 biased locking

synchronized 키워드 하나로 스레드 안전을 얻는 동안, JVM 안에서는 객체 헤더의 비트를 뒤집고, 스택에 락 레코드를 쌓고, 경합이 생기면 네이티브 모니터로 승격하는 일이 벌어져요. 이 글은 그 한 번의 잠금이 객체 헤더부터 ObjectMonitor까지 어떤 경로를 거치는지, 그리고 한때 있었다가 JDK 18에서 사라진 biased locking

May 19, 202616 min read

JVM 객체 할당의 비밀 — TLAB, Bump-the-Pointer, 그리고 할당이 거의 공짜인 이유

Java에서 new를 호출하면 무슨 일이 벌어질까요? "힙에 메모리를 잡는다"는 한 문장 뒤에는 스레드마다 자기만의 분양 구역을 나눠 갖는 정교한 설계가 숨어 있어요. 이 글은 HotSpot JVM이 객체 할당을 어떻게 "거의 공짜"로 만드는지 그 내부를 따라가 보려는 글이에요. JVM 메모리 동작 원리에 관심 있는 분께 권해요. 자바를 쓰다 보면 객체를

May 15, 202614 min read

Java Zero-Copy — FileChannel.transferTo, sendfile, 그리고 Kafka가 디스크를 네트워크로 흘려보내는 방법

"파일을 읽어서 소켓으로 보낸다." 한 줄짜리 요구사항이에요. 그런데 이 한 줄 뒤에서 데이터는 메모리를 네 번이나 복사하고, CPU는 커널과 유저 공간을 네 번이나 들락거려요. Kafka처럼 초당 수십만 건을 흘려보내야 하는 시스템에서 이 비용은 그냥 넘길 수가 없어요. 이 글은 그 복사를 한 겹씩 벗겨내는 zero-copy의 동작 원리를 따라가요. 전통

May 15, 202617 min read

끄적끄적 테크 블로그

165 posts

물류 회사에 다니고 있는 개발자 블로그입니다. 개발을 너무 좋아해서 정신없이 작업하다가 중간에 끄적거리며 내용들을 몇개 적어봅니다 ㅎㅎ