시스템 프롬프트 유형 분류와 혼합 설계

멀티태스크/파이프라인/페르소나/도구 중심 유형별 분해 전략과 계층적 라우팅

시스템 프롬프트 분해 6단계가 그대로 적용되지 않는 경우를 다룬다. 시스템 프롬프트를 4가지 유형(멀티태스크/파이프라인/페르소나/도구 중심)으로 분류하고, 각 유형에 맞는 분해 전략을 제시한다. 혼합 유형에서의 계층적 라우팅(Layered Routing) 설계와 “컨텍스트 윈도우의 밀도”를 핵심 설계 목표로 두는 이유를 구체적 예시와 함께 설명한다.

Agent
Architecture
Prompt Engineering
저자

Kwangmin Kim

공개

2026년 03월 25일

1 6단계의 적용 범위

시스템 프롬프트 분해 6단계는 “agent가 여러 종류의 태스크를 수행하는” 멀티태스크형 프롬프트에 최적화된 레시피이다. 시스템 프롬프트의 성격에 따라 분해 전략이 달라진다.

2 시스템 프롬프트 유형 분류

2.1 유형 A: 멀티태스크형

6단계 그대로 적용한다.

  • “질문도 답하고, 포스트도 쓰고, TBD도 전환하고, 시리즈도 정리해”
  • 독립적인 태스크가 여러 개 존재한다 → 태스크 경계를 찾아 스킬로 분리한다

분해 전략: 6단계를 순서대로 수행한다. 1단계(독립 태스크 식별)가 핵심이고, 나머지 단계가 자연스럽게 따라온다.

안티패턴 — 태스크 내부 단계를 별도 스킬로 분리:

“포스트 작성”을 “YAML 헤더 생성”, “본문 작성”, “index 업데이트”로 쪼개면 과분리이다. 항상 함께 실행되는 단계는 하나의 스킬 안에 Step으로 포함한다. 분리의 단위는 사용자 요청의 경계이지, 내부 처리 단계가 아니다.

2.2 유형 B: 단일태스크 + 복잡한 파이프라인형

단계(stage)로 쪼갠다.

  • “사용자가 업로드한 이미지를 분석해서 보고서를 생성해” → 전처리 → 분류 → 분석 → 보고서 생성 → 후처리
  • 태스크는 하나지만 처리 단계가 많다
  • 1단계(독립 태스크 식별)가 무의미하다 — 대신 파이프라인 단계를 스킬로 분리한다
멀티태스크형: 태스크 종류로 쪼갬       파이프라인형: 처리 단계로 쪼갬
스킬 A: 질문 응답                     스킬 A: 이미지 전처리
스킬 B: 포스트 작성                   스킬 B: 객체 분류
스킬 C: TBD 전환                     스킬 C: 보고서 생성

분해 전략: 파이프라인의 각 단계가 독립적으로 재실행 가능한지를 기준으로 분리한다. “전처리만 다시 해줘”가 의미 있는 요청이면 분리 대상이다.

파이프라인 스킬 분리 판단 기준:

질문 Yes → 분리 No → Step으로 흡수
이 단계만 단독 재실행이 가능한가? 별도 스킬 상위 스킬의 Step
이 단계의 입출력 형식이 독립적인가? 별도 스킬 상위 스킬의 Step
이 단계의 실행 시간이 길어 중단/재개가 필요한가? 별도 스킬 상위 스킬의 Step
이 단계가 다른 파이프라인에서도 재사용되는가? 공통 스킬 인라인

안티패턴 — 모든 단계를 별도 스킬로 분리:

5단계 파이프라인을 5개 스킬로 쪼개면, 각 스킬이 이전 스킬의 출력 형식에 의존하는 체인이 생긴다. 이 의존성이 암묵적이면 — 즉, “분석 스킬의 출력이 보고서 스킬의 입력과 같은 형식이어야 한다”가 어디에도 적혀 있지 않으면 — 하나의 스킬 수정이 전체 파이프라인을 깨뜨린다.

[나쁜 예 — 암묵적 의존성]
preprocess.md → classify.md → analyze.md → report.md
  각 스킬 사이의 데이터 형식이 명시되지 않음
  → classify.md의 출력 형식을 바꾸면 analyze.md가 깨짐

[좋은 예 — 명시적 인터페이스 or 단일 스킬]
image-analysis.md
  Step 1: 전처리 (입력: 이미지 파일 → 출력: 정제된 이미지)
  Step 2: 분류 (입력: 정제된 이미지 → 출력: 클래스 레이블)
  Step 3: 분석 (입력: 클래스 레이블 + 원본 → 출력: 분석 결과)
  Step 4: 보고서 (입력: 분석 결과 → 출력: markdown 보고서)
  → 단계 간 데이터 흐름이 하나의 파일 안에서 명확함

2.3 유형 C: 페르소나/톤 중심형

조건부 규칙을 구조화한다.

  • “너는 친절한 고객 상담 봇이야. 항상 공감하고, 3문장 이내로 답하고…”
  • 스킬 분리보다 규칙의 우선순위화, 조건부 규칙 구조화가 핵심이다
코어: 페르소나 정의 + 톤 규칙
조건부 규칙:
  불만 고객일 때 → 사과 먼저
  기술 질문일 때 → 단계별 안내
  환불 요청일 때 → 정책 확인 후 안내

분해 전략: 규칙의 우선순위를 명시하고, 충돌 시 어떤 규칙이 이기는지 정한다. 태스크형과 달리 선택이 아니라 중첩이 핵심이다 — 불만 고객의 기술 질문이면 “사과 먼저” + “단계별 안내”가 동시에 적용된다.

규칙 충돌 해결 패턴:

[규칙 우선순위 — 숫자가 클수록 우선]
P3: 기본 톤 (친절, 공감)              ← 항상 적용
P2: 상황별 규칙 (불만→사과, 기술→단계별)  ← 상황에 따라 적용
P1: 안전 규칙 (금지 표현, 에스컬레이션)   ← 최우선, 다른 규칙을 override

충돌 시: 높은 우선순위가 낮은 우선순위를 override한다
예: "3문장 이내로 답한다" (P3) vs "환불 절차는 단계별로 전부 안내한다" (P2)
   → P2가 우선 → 환불 안내는 3문장 제한을 무시한다

구조화 포맷:

## 페르소나 코어 (항상 적용)
- 이름: 고객지원 AI
- 톤: 친절, 공감, 간결
- 금지: 단정적 법률 조언, 경쟁사 비방

## 상황별 규칙
### 불만 고객
- 트리거: 부정적 감정 표현, 재문의
- 추가 규칙: 사과 → 공감 → 해결책 순서
- 톤 조정: 더 공손, 사과 표현 포함

### 기술 질문
- 트리거: 오류 코드, 기능 문의
- 추가 규칙: 단계별 번호 안내, 스크린샷 요청
- 톤 조정: 기본 유지

### 에스컬레이션 (override)
- 트리거: 3회 이상 같은 문의, "사람과 통화"
- 동작: 상담원 연결 안내, 이전 규칙 무시

안티패턴 — 페르소나를 스킬로 분리:

“불만 고객 대응.md”, “기술 질문 대응.md”처럼 상황별 스킬을 만들면 안 된다. 페르소나 규칙은 중첩 적용이 자연스럽고(불만+기술, 불만+환불), 스킬 라우팅은 하나만 선택하도록 설계되어 있다. 중첩이 필요한 규칙을 배타적 선택 구조에 넣으면 조합 폭발이 발생한다.

2.4 유형 D: 도구/API 사용 중심형

도구별 사용 가이드 + 조합 패턴으로 분리한다.

  • “DB 쿼리, 이메일 전송, 캘린더 조회 등 10개 도구를 사용할 수 있어”
  • 태스크보다 도구 사용 규칙과 권한이 프롬프트의 대부분을 차지한다
  • 도구별 가이드 + 도구 조합 패턴으로 분리하는 것이 자연스럽다

분해 전략: 도구를 3가지 층으로 나눈다.

[Layer 1: 도구 레지스트리] — 코어에 포함, 항상 로드
  어떤 도구가 있는지 목록 + 한 줄 설명
  → agent가 "어떤 도구가 쓸 수 있는지" 파악하는 데 사용

[Layer 2: 도구별 사용 가이드] — 해당 도구 호출 시에만 로드
  파라미터, 권한, 에러 처리, 예제
  → agent가 "이 도구를 어떻게 쓰는지" 실행 시 참조

[Layer 3: 도구 조합 패턴] — 복합 시나리오에서만 로드
  "Jira 티켓 생성 후 Slack 알림" 같은 멀티 도구 워크플로우
  → 자주 쓰이는 조합을 정의해 둔다

도구 가이드 구조:

## Jira API
- 권한: 읽기/쓰기 (프로젝트 INGEST만)
- 사용 가능 액션: create, update, query, transition
- 파라미터:
  - project: 필수, "INGEST"
  - summary: 필수, 100자 이내
  - priority: 선택, 기본값 "Medium"
- 제약: 삭제 불가, 상태 변경은 allowed_transitions만 가능
- 에러 처리: 403 → 권한 부족 메시지 출력, 재시도 안 함

안티패턴 — 도구 × 액션 조합을 각각 별도 스킬로 분리:

“jira-create.md”, “jira-update.md”, “jira-query.md”처럼 쪼개면 스킬이 도구 수 × 액션 수로 폭발한다. 10개 도구에 평균 3개 액션이면 30개 스킬이 된다. 하나의 도구는 하나의 가이드로 묶는다.

2.5 6단계 적용 가능 조건

조건 충족 시 미충족 시
독립적인 태스크가 2개 이상인가? 6단계 적용 유형 B/C/D 전략 검토
태스크 간 공유하는 절차가 있는가? 2단계(공통 추출)가 효과적 공통 추출 불필요, 바로 분리
도메인별로 규칙이 다른가? 5단계(도메인 분리)가 효과적 코어에 통합해도 된다
프롬프트가 충분히 긴가? (체감 1000자+) 분해 이점 있음 분해 오버헤드가 더 크다

3 혼합 유형 판별법

실제 시스템 프롬프트는 대부분 단일 유형이 아니라 2~3가지 유형이 섞여 있다. 혼합 유형을 판별하려면 프롬프트의 각 섹션이 어떤 유형에 해당하는지 태깅한다.

판별 절차:

Step 1: 프롬프트의 모든 섹션/규칙을 나열한다
Step 2: 각 항목에 유형 태그를 붙인다
  - "~를 하라" (태스크 지시) → A 또는 B
  - "~처럼 말하라" (톤/스타일) → C
  - "~도구를 사용하라" (도구 규칙) → D
Step 3: 태그 비율로 주 유형과 부 유형을 결정한다
Step 4: 주 유형의 분해 전략을 뼈대로 삼고, 부 유형을 내부에 흡수한다

진단 매트릭스:

프롬프트에 있는 것 주로 해당하는 유형 판별 신호
“~을 해라”가 3개 이상, 서로 독립 실행 가능 A (멀티태스크) 태스크 간 입출력이 겹치지 않는다
“~을 해라”가 1개, 내부 단계가 3개 이상 B (파이프라인) Step 1 → Step 2 → … 순서 의존
“~처럼 말하라”가 프롬프트의 30%+ C (페르소나) 톤, 금지 표현, 상황별 태도 규칙이 많다
도구 사용법이 프롬프트의 40%+ D (도구 중심) 파라미터, 권한, 에러 처리가 대부분이다

예시 — 블로그 관리 agent (이 프로젝트):

AGENT_GUIDE.md 구성 분석:
  - 질문 응답, 포스트 작성, TBD 전환, 시리즈 정리 → 유형 A (독립 태스크 4개)
  - info-search → 교재 검색 → 블로그 검색 → 판단 → 유형 B (파이프라인)
  - "한다 체", "이모지 금지", "경어체 금지" → 유형 C (톤 규칙)
  - 도구 규칙 없음 → 유형 D 해당 없음

→ 주 유형: A (멀티태스크), 부 유형: B (파이프라인을 전처리로 흡수) + C (코어에 톤 규칙 포함)

4 혼합 유형 설계

4.1 “더 쪼개면 되지 않나?”가 틀린 이유

스킬이 20~30개로 늘어나면 다음 문제가 발생한다.

  • 라우팅 테이블 비대화: 스킬을 줄이려고 쪼갠 건데 라우팅 규칙이 원래 프롬프트만큼 커진다
  • 오분류 증가: 선택지가 많을수록 agent가 잘못 라우팅할 확률이 높아진다
  • 의존성 복잡화: A스킬 안에서 B가 필요하고 B 안에서 C가 필요하면 호출 체인이 디버깅 불가능해진다

핵심 통찰: 스킬을 더 세분화하는 것이 아니라, agent가 한 번에 보는 선택지를 줄이는 것이 답이다. 이것은 결국 컨텍스트 윈도우의 밀도 문제이다. agent의 문맥 윈도우에 “지금 이 판단에 필요한 정보만” 밀도 있게 채우는 것이 목표이지, 모든 가능성을 한꺼번에 펼쳐놓는 것이 아니다.

4.2 왜 계층이 플랫보다 나은가 — 정량적 직관

20개 스킬 중 1개를 고르는 것과, 4개 중 1개를 두 번 고르는 것의 차이를 직관적으로 비교한다.

LLM의 라우팅을 “N개 선택지 중 정답 1개를 고르는 분류 문제”로 모델링하면, 오류율은 선택지 수에 비례해서 올라간다. 정확한 수치는 모델과 프롬프트에 따라 다르지만, 방향은 일관된다.

[플랫 라우팅] 20개 중 1개 선택
  오분류 확률 ∝ (N-1)/N = 19/20의 후보가 오답
  → 비슷한 이름의 스킬이 있으면 혼동 확률 급증
  예: code-review vs code-analysis, jira-create vs jira-update

[계층 라우팅] 4개 중 1개 → 5개 중 1개
  1차 오분류 확률 ∝ 3/4의 후보가 오답
  2차 오분류 확률 ∝ 4/5의 후보가 오답
  총 정확도 ≈ (1차 정답 확률) × (2차 정답 확률)
  → 각 단계의 선택지가 서로 의미적으로 멀리 떨어져 있어 구분이 쉽다

비유: 서점에서 책을 찾을 때 “20만 권 중 한 권을 바로 찾아라”보다 “인문관 → 3층 → 철학 코너 → 선반 B”로 좁혀가는 게 빠른 것과 같다. 각 단계에서의 선택지가 적고, 각 선택지 간 의미 거리가 멀기 때문이다.

4.3 해법: 계층적 라우팅 (Layered Routing)

한 번에 모든 스킬 중에서 고르는 게 아니라, 단계별로 좁혀간다.

사용자 요청
    ↓
[1차 라우팅] 유형 판별 — A/B/C/D 중 어디에 해당? (선택지 3~4개)
    ↓
┌──────────────┬──────────────┬──────────────┬──────────────┐
│ 유형 A        │ 유형 B        │ 유형 C        │ 유형 D        │
│ 멀티태스크    │ 파이프라인    │ 페르소나      │ 도구 중심     │
│              │              │              │              │
│ [2차 라우팅]   │ [2차 라우팅]   │ [2차 라우팅]   │ [2차 라우팅]   │
│ 어떤 태스크?   │ 어떤 단계?    │ 어떤 상황?    │ 어떤 도구?    │
│  ├ 질문응답    │  ├ 전처리     │  ├ 불만고객    │  ├ DB 쿼리    │
│  ├ 포스트작성  │  ├ 분석       │  ├ 기술질문    │  ├ 이메일     │
│  └ TBD전환    │  └ 보고서     │  └ 환불요청    │  └ 캘린더     │
└──────────────┴──────────────┴──────────────┴──────────────┘

20개 중 1개를 고르는 것보다 4개 중 1개를 두 번 고르는 게 훨씬 정확하다.

4.4 구체적 예시: 코드 리뷰 + 자동 수정 + Jira + Slack Agent

이 agent에는 A+B+D가 섞여 있다.

  • 유형 A 요소: 코드 리뷰, 자동 수정, 보고서 생성 (독립 태스크)
  • 유형 B 요소: 코드 분석 → 이슈 탐지 → 수정 제안 → 적용 (파이프라인)
  • 유형 D 요소: Jira API, Slack API, Git API (도구 사용)

잘못된 접근 — 플랫하게 전부 쪼갬:

skills/
├── code-review.md
├── code-analysis.md
├── issue-detection.md
├── fix-suggestion.md
├── fix-application.md
├── report-generation.md
├── jira-create-ticket.md
├── jira-update-ticket.md
├── jira-query.md
├── slack-notify.md
├── slack-thread-reply.md
├── git-create-pr.md
├── git-diff-analysis.md
└── ... (15개 이상)

→ 라우팅 테이블: 15개 스킬 × 조건 = 라우팅만 200줄
→ agent가 매번 15개를 보고 고름 → 오분류 빈발

올바른 접근 — 유형별 레이어 분리:

[코어] agent-guide.md
├── 1차 라우팅: 태스크 유형 판별 (선택지 3개)
├── 공통 규칙 (코드 스타일, 톤)
└── 도구 레지스트리 (어떤 도구가 있는지 목록만)

[태스크 스킬] tasks/          ← 유형 A: "무엇을 하는가"
├── code-review.md            # 내부에 파이프라인 단계(유형 B) 포함
├── auto-fix.md
└── report.md

[도구 스킬] tools/            ← 유형 D: "어떻게 외부와 소통하는가"
├── jira.md                   # create/update/query를 하나의 파일 안에
├── slack.md
└── git.md

태스크 스킬이 도구 스킬을 호출하는 구조이다.

# code-review.md 안에서:
Step 1: 코드 분석        (파이프라인 단계 — 유형 B를 내부 Step으로 흡수)
Step 2: 이슈 탐지
Step 3: 수정 제안
Step 4: tools/jira.md 호출 → 티켓 생성   (도구 — 유형 D를 참조로 연결)
Step 5: tools/slack.md 호출 → 알림

5 혼합 유형 설계 원칙

5.1 유형별로 레이어를 나눈다

같은 레벨에 섞지 않는다.

tasks/     ← 유형 A (무엇을 하는가)
tools/     ← 유형 D (어떤 도구를 쓰는가)
personas/  ← 유형 C (어떤 톤으로 하는가)

태스크 스킬과 도구 스킬이 같은 폴더에 나란히 있으면 agent가 혼동한다. 레이어가 다르면 폴더도 다르다.

5.2 파이프라인(유형 B)은 태스크 스킬의 내부 구조로 흡수한다

  • 파이프라인 단계를 별도 스킬로 쪼개면 호출 체인이 복잡해진다
  • 대신 태스크 스킬 안에 Step 1~N으로 포함한다

5.3 라우팅은 항상 “넓은 범주 → 좁은 선택” 순서

  • 1차: “이것은 코드 리뷰인가, 자동 수정인가, 보고서인가?” (3개)
  • 2차: “코드 리뷰 중 어떤 단계인가?” (태스크 내부에서 판단)
  • 도구: “이 단계에서 어떤 도구가 필요한가?” (태스크가 결정)

5.4 유형 흡수의 우선순위

혼합 유형에서 어떤 유형이 어떤 유형을 흡수하는지에는 일관된 패턴이 있다.

[흡수 관계 — 바깥이 안쪽을 흡수]
유형 A (멀티태스크)
  └── 유형 B (파이프라인) → 태스크 스킬의 내부 Step으로 흡수
  └── 유형 C (페르소나)  → 코어의 톤 규칙으로 흡수
  └── 유형 D (도구)      → 별도 레이어(tools/)로 분리, 태스크가 참조

이 패턴이 성립하는 이유: 사용자 요청의 진입점은 항상 “무엇을 해라”(태스크)이다. “친절하게 해라”(페르소나)나 “Jira를 써라”(도구)는 태스크 수행의 방식이지 목적이 아니다. 라우팅의 1차 기준은 목적이어야 한다.

예외: agent의 주 목적이 대화 자체인 경우(고객 상담, 컴패니언 봇)에는 유형 C가 최상위가 되고, 태스크(환불, 기술 지원)가 내부 분기로 들어간다.

6 컨텍스트 밀도가 핵심인 이유

이 모든 설계의 본질은 하나다: agent의 문맥 윈도우에 “지금 이 판단에 필요한 정보만” 밀도 있게 채우는 것.

6.1 컨텍스트 밀도란

컨텍스트 밀도는 “현재 로드된 전체 토큰 중 지금 이 판단에 실제로 필요한 토큰의 비율”이다.

컨텍스트 밀도 = (지금 필요한 정보의 토큰 수) / (컨텍스트에 로드된 전체 토큰 수)

밀도가 낮으면 LLM의 attention이 불필요한 정보에도 분산된다. 이것이 시스템 프롬프트 분해 6단계에서 다룬 attention dilution 문제의 근본 원인이다. 밀도를 높이는 방법은 두 가지뿐이다: 필요한 정보를 더 넣거나, 불필요한 정보를 빼거나.

6.2 구체적 비교: 코드 리뷰 Step 3 수행 시

agent가 code-review 태스크의 Step 3(수정 제안)을 수행 중일 때, 컨텍스트에 있어야 하는 것:

  • code-review.md의 Step 3 규칙
  • tools/jira.md (다음 단계에서 필요하므로)
  • 공통 코드 스타일 규칙

컨텍스트에 있으면 안 되는 것:

  • auto-fix.md의 전체 절차
  • report.md의 전체 절차
  • tools/slack.md (아직 필요 없음)

플랫 구조에서는 15개 스킬이 모두 라우팅 테이블에 나열되어 매번 컨텍스트를 차지한다. 계층 구조에서는 현재 경로에 해당하는 것만 로드된다. 같은 문맥 윈도우 크기에서, 불필요한 정보가 줄면 필요한 정보의 밀도가 올라가고, 밀도가 올라가면 agent의 판단 정확도가 올라간다.

6.3 구조별 밀도 비교

구조 컨텍스트 내용 예상 토큰 필요 토큰 밀도
단일 파일 (v2.0) 모든 규칙 + 모든 절차 ~3000 ~400 ~13%
플랫 스킬 (15개) 라우팅 테이블(15개) + 현재 스킬 ~1200 ~400 ~33%
계층 스킬 1차 라우팅(3~4개) + 현재 태스크 + 현재 도구 ~600 ~400 ~67%

밀도가 13%에서 67%로 올라가면, agent가 같은 판단을 할 때 “노이즈 속 신호”의 비율이 5배 개선된다. 이것은 모델의 능력이 바뀐 것이 아니라, 모델이 보는 입력의 품질이 바뀐 것이다.

스킬 수를 늘리는 게 아니라, agent가 매 순간 보는 컨텍스트의 밀도를 높인다. 이를 위해 라우팅의 깊이를 늘린다.

6.4 밀도 vs 깊이의 트레이드오프

라우팅 깊이를 늘리면 밀도는 높아지지만, 라우팅 단계 자체가 오류를 일으킬 수 있다. 1차 라우팅에서 잘못 분류되면 2차 이하의 모든 선택이 무의미해진다.

[적정 깊이의 판단 기준]
깊이 1 (플랫):   선택지 ≤ 5개이면 충분하다
깊이 2 (2단계):  선택지 6~25개일 때 적합하다 (√25 = 5, 각 레벨 ~5개)
깊이 3 (3단계):  선택지 26개 이상일 때만 고려한다 — 거의 없다

경험적 규칙: 각 레벨의 선택지를 3~5개로 유지한다.
깊이 2이면 최대 5×5=25개 스킬을 커버한다.
대부분의 agent 시스템은 깊이 2면 충분하다.

깊이가 3 이상 필요하다면, 스킬 수 자체를 줄이는 것을 먼저 검토한다. 여러 스킬을 하나로 합치거나, 유사한 스킬을 하나의 스킬 안에 분기로 처리하는 것이 라우팅 깊이를 늘리는 것보다 대부분 낫다.

7 관련 주제

선행 지식

후속 주제

관련 포스트

Subscribe

Enjoy this blog? Get notified of new posts by email: