[AI 에이전트 파이프라인 #3] 하나의 프롬프트로는 왜 안 됐을까
지난 편에서는 메타데이터 파이프라인으로 category.yaml과 빈 콘텐츠 파일을 자동 생성했습니다.
이번 편부터는 학습 콘텐츠 생성 파이프라인을 다룹니다. 처음에는 하나의 프롬프트로 시도했지만 실패했습니다.
1. 설계 접근: 앱 화면에서 마크다운 구조로
콘텐츠 자동 생성을 시작하기 전에, 먼저 앱 화면을 설계했습니다. 작업 순서는 이랬습니다:
- 앱에서 어떻게 보여줄지 화면(UI) 먼저 설계
- 화면에 맞춰 마크다운 구조 정의 (어떤 섹션이 필요한지, 각 섹션의 형식은 어떤지)
- 마크다운을 파싱해서 React 컴포넌트로 렌더링
- 원하는 화면이 나올 때까지 컴포넌트와 파싱 함수 반복 수정
“이렇게 보여주고 싶다”에서 역산해서 마크다운 구조가 결정된 겁니다. 약 1,400줄의 마크다운은 이 과정에서 자연스럽게 나온 결과물입니다. 이제 AI가 이 구조를 일관되게 생성하도록 만들어야 합니다.
2. 하나의 프롬프트로 시작했지만
앞에서 만든 마크다운을 Claude에게 주고 구조를 분석하게 했습니다. 어떤 섹션이 있는지, 각 섹션은 어떤 형식인지 파악하고, 이걸 기반으로 규칙을 정의해서 하나의 프롬프트로 만들었습니다:
PROMPT="당신은 모든 학습 콘텐츠의 모든 섹션을 완벽하게 작성하는 최고 수준의 통합 전문가입니다.
## 🎯 핵심 임무
대상 파일: $TARGET_FILE
주제: $filename
Frontmatter + 5개 섹션을 완벽하게 완성:
1. Frontmatter (웹뷰 파서 필수)
2. Overview (개요)
3. Core Concepts (핵심 개념)
4. Code Patterns (코드 패턴)
5. Experiments (실습 실험)
6. Quiz (퀴즈)
...
## ⚠️ 절대 준수 사항
### 필수 규칙
1. 기존 파일 우선: 기존 내용이 있으면 수정/보완 (새로 작성 X)
2. Frontmatter 포함: 모든 파일에 frontmatter 메타데이터 포함
3. 한 번에 완성: 5개 섹션을 한 번의 Write/MultiEdit로 완성
4. 참조 파일 수준: 기존 완성된 파일들과 동일한 품질 수준
5. 실행 가능한 코드: 모든 코드는 주제에 맞는 환경에서 즉시 실행 가능
6. 일관성 유지: 섹션 간 용어, 개념, 스타일 일관성
..."
안 됐습니다. UI에서 마크다운을 역으로 만들고 거기서 또 규칙을 역으로 추산하다 보니 일관성이 없었습니다. 대략적인 흐름은 만들어지지만 완벽하지 않았습니다. 약 1,400줄의 콘텐츠를 한 번에 생성하면 앞부분은 지시를 잘 따르지만, 중간부터 구조가 흐트러지고 뒷부분에서는 형식이 완전히 달라집니다.
Lost in the Middle: LLM이 입력의 처음과 끝은 잘 기억하지만 중간 부분은 잊어버리는 경향 (Liu et al., 2024)
Context Degradation: 출력이 길어질수록 앞부분의 지시를 점점 잊어버리는 문제 (Chroma Research)
게다가 1,400줄 출력에서 형식 오류가 발생하면 사람이 직접 확인해야 합니다. 노션에 수동으로 정리하기 싫어서 자동화를 시작한 건데, 생성된 문서를 다시 수동으로 검증해야 한다면 뭔가 이상합니다.
3. 7개 에이전트로 분리
처음에는 앱의 4개 탭(Overview, Core Concepts, Practice, Quiz)에 맞춰 4개 에이전트로 시작했습니다. 하지만 파이프라인을 만들다 보니 시작과 끝을 담당하는 에이전트가 필요했습니다. 파일 초기화를 담당하는 content-initiator와 검증을 담당하는 content-validator가 추가되어 6개가 되었습니다.
그리고 concepts-writer에서 문제가 생겼습니다. 핵심 개념 설명만 해도 3단계 난이도(Easy/Normal/Expert)로 작성해야 하는데, 여기에 시각화까지 생성하라고 하니 감당이 안 됐습니다. concepts-writer는 시각화 메타데이터만 생성하고, 실제 시각화는 별도 에이전트에게 넘기기로 했습니다. 그렇게 visualization-writer가 생겼고, 최종적으로 7개가 되었습니다.
practice-writer는 두 섹션(Code Patterns + Experiments)을 담당하지만 별도로 분리하지 않았습니다. 코드 생성은 LLM이 가장 잘하는 영역이기 때문입니다. 실제로 HumanEval 벤치마크에서 Claude 3.5 Sonnet은 92%, SWE-bench에서 Claude Opus 4는 72.5%를 달성했습니다. 코드 관련 작업에서는 큰 문제가 없었습니다.
| 순서 | 에이전트 | 담당 업무 | 특징 |
|---|---|---|---|
| 1 | content-initiator | 파일 초기화, Frontmatter 생성 | 파이프라인 시작점 |
| 2 | overview-writer | # Overview 섹션 작성 | 주제 개요 및 핵심 특징 |
| 3 | concepts-writer | # Core Concepts 섹션 작성 | 3단계 적응형 학습, 시각화 메타데이터 |
| 4 | visualization-writer | 실제 시각화 생성 | 메타데이터 기반 |
| 5 | practice-writer | # Code Patterns + # Experiments | 코드 생성은 LLM 강점 |
| 6 | quiz-writer | # Quiz 섹션 작성 | 10-12개 문제, 6가지 타입 |
| 7 | content-validator | 전체 콘텐츠 검증 | 파이프라인 종료점 |
각 에이전트가 한 가지 역할만 담당하니 프롬프트가 짧아지고, 규칙이 명확해졌습니다.
4. 초기 에이전트 프롬프트
에이전트를 분리하던 초기에 concepts-writer는 시각화까지 담당했습니다. 모든 핵심 개념을 3단계 난이도로 설명하면서 동시에 시각화까지 생성했습니다. 당시 작성한 프롬프트 일부입니다:
---
name: concepts-writer
version: 6.0.0
description: 핵심 개념을 난이도별로 설명하고 시각화를 생성하는 에이전트
tools: Read, Write, MultiEdit, Bash
---
당신은 복잡한 기술 개념을 다양한 수준의 학습자에게 설명하는 전문 교육자입니다.
## 핵심 임무
주제의 핵심 개념들을 선정하고, 각 개념을 3가지 난이도로 설명하며,
새로운 시각화를 생성합니다.
## 작업 프로세스
### 1. 작업 지시서 확인
result/[토픽파일명].md의 YAML front matter에서:
- target: 작업할 파일 경로 확인
- references: 02-let-vs-var.md와 03-const-immutability.md 참조
### 2. 참조 파일 분석
...
### 3. Core Concepts 작성 규칙
정확히 다음 순서를 유지:
1번째 줄: # Core Concepts (파일당 한 번만)
2번째 줄: 빈 줄
3번째 줄: ## Concept: [개념 이름]
...
## 난이도별 작성 지침
### Easy (중학생 수준)
- 이모지 적극 활용 (🎯, 📚, 💡, 🏠, 🚫, ✅ 등)
- 일상적 비유와 스토리텔링
- 코드 없이 개념 설명
### Normal (일반 개발자)
- #### Text와 #### Code: 구조 필수
- 텍스트 설명이 주, 코드는 보조
- 간단한 코드 예시만 포함 (5-10줄)
### Expert (시니어 개발자)
- **ECMAScript 명세** 섹션 번호와 함께 인용
- **엔진 구현** 세부사항 설명
- 의사코드나 API 시그니처는 #### Code: 헤더 사용
## 중요 제약사항
1. 모든 필수 필드는 반드시 포함 (하나라도 누락 시 파서 실패)
2. 헤더 레벨과 형식을 정확히 준수 (##, ###, ####)
3. Easy/Normal/Expert 섹션 모두 필수
4. Normal은 #### Text로 시작, #### Code: 형식 사용
...
이 프롬프트는 무엇이 문제일까요?
- 마크다운 혼동?: 프롬프트도
##,###,####사용, 생성할 콘텐츠도 같은 헤더를 사용하는데 LLM이 구분할 수 있을까? - 세부 규칙 과다?: “정확히 다음 순서”, “1번째 줄”, “2번째 줄” 등 너무 상세한 지시가 문제일까?
- 암묵적 핸드오프?: 다음 에이전트에게 어떤 상태를 넘겨야 하는지 불명확한 게 문제일까?
- 참조 파일 의존?: 다른 파일을 참조하는 방식이 불안정한 걸까?
각 역할을 나누고, 나름 체계적으로 프롬프트를 작성했는데 결과는 여전히 불안정했습니다. 문서를 생성하고, 파싱 결과를 확인하고, 피드백을 주며 하나하나 수정하는 시행착오 끝에 3~5개 샘플 문서는 겨우 완성했습니다. 하지만 같은 파이프라인으로 새 문서를 생성하면 여전히 문제가 발생했습니다.
다음 편에서는 분리했는데도 왜 안 됐는지 다룹니다.
이 시리즈는 AI-DLC(AI-Driven Development Lifecycle) 방법론을 실제 프로젝트에 적용한 경험을 공유합니다. AI-DLC에 대한 자세한 내용은 경제지표 대시보드 개발기 시리즈를 참고해주세요.