
두 번의 컨텍스트 엔지니어링 (Context Engineering): GenAI 앱을 위한 한 번, 그리고 이를 구축한 AI 에이전트들을 위한
요약
GenAI 앱 개발 과정에서 앱 내부와 AI 에이전트 파이프라인 양쪽에서 발생하는 컨텍스트 엔지니어링의 중요성을 다룹니다. 비용과 지연 시간을 최적화하기 위한 계층화된 페르소나, 추출된 메모리, 인라인 태그를 활용한 감정 UX 구현 사례를 소개합니다.
핵심 포인트
- 비용과 지연 시간 절감을 위한 선택적 컨텍스트 구성 전략
- 계층화된 페르소나와 추출된 메모리를 통한 토큰 최적화
- 추가 추론 없이 인라인 태그를 활용한 실시간 감정 UX 구현
- AI 에이전트가 작성한 코드 기반의 아키텍처 및 오케스트레이션 관리
저는 작은 GenAI 앱을 만들기 위해 시작했습니다. 결과적으로 저는 컨텍스트 엔지니어링 (Context Engineering)을 두 번 하게 되었습니다. 한 번은 앱 내부에서, 또 한 번은 앱을 구축한 AI 에이전트 (AI agents)들의 파이프라인 내부에서였습니다. 그리고 두 번째 과정은 아무도 저에게 경고해주지 않았던 부분이었습니다.
이 앱은 Dev로, Hinglish(힌디어와 영어가 섞인 언어) AI 동기부여 코치입니다 https://dev-desi-ai-coach.web.app/ — 현재 라이브 상태이며 곳곳이 거칠지만, 제품이 아닌 학습용 결과물입니다. Flutter + Firebase + Gemini를 사용했습니다. 기술 스택은 평범합니다. 흥미로워진 지점은 두 가지 컨텍스트 (Context) 문제였습니다.
솔직히 말씀드리면: 대부분의 코드는 제 지시 아래 AI 에이전트 (AI agents)들이 작성했습니다. 제가 주장하는 것은 아키텍처 (Architecture), 결정 사항, 그리고 오케스트레이션 (Orchestration)이며, 이것이 실제 작업이었음이 드러났습니다.
레이어 1: 앱 내부의 컨텍스트 엔지니어링 (Context engineering inside the app)
LLM이 "개인적"인 느낌을 주게 만드는 순진한 방법은 모든 프롬프트 (Prompt)에 모든 것 — 전체 히스토리, 사용자의 모든 목표, 전체 프로필 — 을 집어넣는 것입니다. 그렇게 하면 작동은 하겠지만, 지연 시간 (Latency)과 비용이 모두 폭발하게 됩니다.
그래서 Dev는 턴 (Turn)마다 선택적으로 컨텍스트를 구성합니다:
계층화된 페르소나 (Tiered persona) — 가벼운 핵심 인격이 기본적으로 로드되며, 실제 대화에서 깊이가 필요한 경우에만 더 무겁고 확장된 버전이 활성화됩니다. 동일한 캐릭터를 유지하면서 토큰 (Tokens)은 아주 적게 사용합니다.
추출된 메모리 (Extracted memory) — 전체 대화 내용을 다시 재생하는 대신, 백그라운드 단계에서 몇 가지 지속적인 사실들을 추출하여 용량이 제한된 작은 저장소에 담고, 오직 그 내용들만 다시 주입합니다. (정확히 말하자면, 이것은 벡터 RAG (Vector RAG)가 아니라 선택적 컨텍스트 조립 (Selective context assembly)과 제한된 배열 (Capped array) 방식입니다. 있는 그대로를 과장하지 않겠습니다.)
히스토리 (History)와 출력 (Output)에 대한 엄격한 제한 (Hard caps). 지루하게 들릴 수 있지만, 제한 (Caps)이야말로 비용을 경계 내로 유지하고 예측 가능하게 만드는 핵심입니다.
제가 가장 자랑스럽게 생각하는 기술은 바로 $0짜리 감정 채널입니다. Dev의 마스코트가 각 답변의 감정적 톤 (Emotional tone)에 반응합니다. 뻔한 구현 방식은 감정 분석을 위한 두 번째 호출 (Call)을 하는 것이지만, 이는 더 많은 지연 시간 (Latency)과 토큰 (Tokens)을 소모합니다. 대신 저는 모델이 스트리밍 (Streaming)하는 동안 아주 작은 인라인 태그 (Inline tag)를 출력하도록 했습니다:
[TONE:hype] Arre wah! Streak intact. Keep going. 🔥
클라이언트는 [TONE:hype]를 파싱하여 마스코트 애니메이션을 구동하고, 렌더링하기 전에 해당 태그를 제거합니다. 추가적인 추론 (Inference) 없이 실시간 감정 UX를 구현한 것입니다. 모델은 이미 토큰을 생성하고 있었고, 저는 그저 저렴한 작업 하나를 더 맡겼을 뿐입니다.
(그리고 제한된 LLM 티어 (LLM tier)가 속도를 제한할 수 있으므로: AI 레이어는 API 자체의 재시도 힌트 (Retry hints)를 준수하며 백오프 (Backoff)와 함께 재시도를 수행하며, 가공되지 않은 에러 (Raw error)를 절대 노출하지 않습니다. 할당량 초과 실패는 빨간색 스택 트레이스 (Stack trace)가 아니라, 캐릭터의 대사로 변환됩니다. 실패 경로 (Failure path)를 설계할 때 진심을 다해 설계하십시오.)
Layer 2: 에이전트를 위한 컨텍스트 엔지니어링 (Context Engineering) — 나를 놀라게 한 부분
이 작업의 대부분을 제가 직접 손으로 작성하지는 않았습니다. 저는 멀티 에이전트 파이프라인 (multi-agent pipeline)을 실행하고 마치 작은 팀을 지휘하듯 이를 관리했습니다. PM 에이전트 (Claude "Fable" 5)는 제 결정을 정교한 사양 (specs)으로 변환했고, 개발자 에이전트 (Claude Sonnet 5)는 이를 구현했습니다. 평가자 에이전트 (Claude Opus 4.8)는 병합 (merge) 전 모든 차이점 (diff)을 독립적으로 검토했으며, 두 번째 코딩 에이전트 (Cursor)는 별도의 브랜치에서 병렬로 작동했습니다. 이들은 공유된 클레임 파일 (claims file)을 통해 협업했으며, 모든 변경 사항은 병합되기 전에 정적 분석 (static analysis), 363개의 테스트, 깨끗한 프로덕션 빌드 (production build)라는 동일한 게이트 (gates)를 통과해야 했습니다. 이러한 규율이야말로 에이전트들이 무언가를 망가뜨리지 않으면서도 빠르게 움직일 수 있는 유일한 이유입니다. 에이전트들은 때때로 주니어 개발자들과 정확히 똑같이, 자신 있게 틀리곤 하므로 이 게이트들은 타협 불가능한 요소입니다.
여기서 제가 예상치 못했던 실패 모드 (failure mode)가 발생했습니다. 에이전트들이 프로젝트의 문서 (docs)를 읽는데, 그 문서들에는 토큰 비용 (token cost)이 발생한다는 점입니다. 저의 사양 (specs), 평가 노트 (eval notes), 아키텍처 문서 (architecture docs), 그리고 러닝 보드 (running board) — 즉 에이전트들의 공유된 "메모리" — 가 조용히 약 258k 토큰까지 불어났으며, 그중 대부분은 이미 배포된 무관한 사양들이었습니다. 매 세션마다 에이전트들은 완료된 작업들의 늪을 헤치며 나아가야 했습니다. 속도는 느려지고 비용은 높아졌으며, 그들은 오래된 결정에 닻을 내리는 앵커링 (anchor) 현상을 보였습니다.
그래서 저는 앱에 했던 것과 똑같이 툴링 (tooling)에도 계층화된 컨텍스트 (tiered context)를 적용했습니다:
HOT — 항상 로드되는 필수 요소 (현재 보드, 워크플로우). 예산: ≤40k 토큰.
WARM — 작업 관련 사양 (specs), 해당 작업을 수행할 때만 로드.
COLD — 배포된 사양의 아카이브 (archive). 자동 로드되지 않으며, 아무것도 잃어버리지 않도록 한 줄짜리 인덱스 (index)만 유지하여 주변에 떠돌지 않게 함.
그리고 저는 이를 단순히 지향하는 것이 아니라 강제했습니다. CI 단계에서 각 계층의 토큰 가중치를 계산하고, 코퍼스 (corpus)가 예산을 초과하면 빌드를 실패하게 만들었습니다 (전체 한도는 400k로 제한했습니다). 규칙은 다음과 같습니다: 기능을 배포하면 → 동일한 PR 내에서 해당 사양을 아카이브하십시오. 이제 에이전트의 컨텍스트는 파이프라인이 허용하지 않기 때문에 물리적으로 부패할 수 없습니다.
이것이 제가 예상하지 못했던 핵심 교훈입니다. 만약 AI 에이전트(AI agents)를 사용하여 구축한다면, 그들의 컨텍스트 윈도우(context window)는 여러분의 앱(app)만큼이나 의도적으로 설계해야 하는 하나의 리소스입니다. 동일한 규율을 적용하되 계층만 다를 뿐이며, CI(지속적 통합)는 이를 고착화하는 지점입니다.
솔직한 주의사항 (dev.to이니까요)
이것은 표준 스택(standard stack) 기반의 잘 구축된 단일 사용자 앱이며, 분산 시스템(distributed-systems)의 마법은 아닙니다. 가치는 실천 방식(practices)에 있습니다.
에이전트들에게는 신뢰가 아닌 가드레일(guardrails)이 필요했습니다. 평가 에이전트(eval agent)와 게이트(gates)가 개발 에이전트(dev agent)가 배포한 실제 문제들을 잡아냈습니다. 이 중 하나라도 제거하면 품질은 즉시 하락합니다.
실제 작동하는 것을 살펴보고 싶다면 여기 있습니다. 하지만 제가 정말 피드백을 받고 싶은 두 가지 아이디어는 인라인 톤 태그(inline tone-tag) 패턴과 CI 컨텍스트 예산 게이트(CI context-budget gate)입니다. 이 두 가지에 대해 자세히 기술된 것을 많이 보지 못했으며, 저는 이것들이 일반화될 수 있다고 생각합니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기
