라인의 rag 컨텍스트 관리 전략 | 선택적 컨텍스트 관리
LY Cloud AI Platform 팀이 27개 제품·260+ API·수백 페이지 문서를 다루는 사내 클라우드 AI 어시스턴트에 점진적 공개(progressive disclosure) 4단계 적용, 시스템 프롬프트 충돌은 ToolMessage 위장 주입으로 해소
요약
LY Corporation이 사내 프라이빗 클라우드 Flava용 AI 어시스턴트를 만들면서 27개 제품·260여 개 API·수백 페이지 문서를 한꺼번에 LLM에 넘기지 않고, 질문 단계마다 필요한 도구·가이드라인·스키마만 골라 주입하는 4단계 점진적 공개 전략으로 풀어냄. 시스템 프롬프트 충돌 문제는 가이드라인을 도구 메시지(ToolMessage) 형태로 가장해 주입하는 방식으로 해소.
내용
LLM 애플리케이션 하면 보통 프롬프트 엔지니어링이 먼저 떠오르지만, 27개 클라우드 제품과 260개 이상 API를 연동해야 하는 환경에서는 답변 방법을 가르치는 '지침'보다 상황에 맞는 정보만 골라주는 '컨텍스트 엔지니어링'이 더 핵심이라는 게 출발점.
Flava AI 어시스턴트는 일반 RAG 챗봇과 달리 사내 문서를 검색하는 데 그치지 않고 사용자 권한으로 실제 API를 호출해 현재 리소스 상태를 직접 확인. "내 서버 접속이 안 된다"라는 질문에 일반론(VPC ACL을 확인하세요) 대신 "API로 보니 VPC ACL이 닫혀 있다, 여는 방법 알려드릴까요?"로 답하는 형태.
긴 컨텍스트가 만능이 아니라는 게 전제. 양과 질 양쪽에서 한계 — 컨텍스트 윈도우 안이라도 입력이 길어지면 성능이 13.9%85% 하락 (arXiv:2510.05381, EMNLP 2025), Databricks 실측에서 GPT-4·Llama-3.1 모두 32K64K 토큰 구간부터 RAG 성능 하락. Chroma research의 Context Rot은 정답과 비슷한 노이즈가 섞이면 GPT 계열이 가짜 정보를 자신 있게 생성하는 패턴까지 보고. 게다가 LLM은 stateless라 대화 누적 + JSON API 응답까지 합쳐지면 64K 토큰이 빠르게 소진.
해결 / 접근
전체 4단계 점진적 공개:
- 질문 분석 → 사용자가 무엇을 묻는지 파악
- 도구 선별 → 260개 중 필요한 것만
- 가이드 주입 → 질문·도구에 맞는 매뉴얼만
- 실행 및 포맷팅 → API 응답에 필요한 맥락만
1단계: 도구 선별
"Redis 클러스터 상태 알려줘" → 27개 제품 중 Redis 관련만 추려 8개 도구만 LLM 컨텍스트에 노출. 나머지 252개는 컨텍스트에 올리지 않음.
2단계: 사용법 힌트 주입
제품마다 사용법이 다름. 예: Object Storage는 내부용(private)·외부용(CDN)의 설정이 다름. 이런 힌트는 해당 API 호출 직전에만 제공.
3단계: 응답 가이드라인 + ToolMessage 위장
응답 가이드라인은 (조건, 내용) 쌍.
- 사례 A: "리소스 생성/삭제/변경 질문" → "콘솔 UI 방법 먼저 안내, CLI 필요한지 되묻기"로 핑퐁 제거
- 사례 B: "DB 쿼리 질문" → "사내 도구 'Query Runner'를 먼저 언급" — LLM이 모르는 사내 고유 도구를 가이드라인으로 띄워줘야 검색까지 이어감
조건들만 LLM에 먼저 던져 매칭, 선택된 가이드라인의 내용만 컨텍스트에 추가.
문제: 처음엔 가이드라인 내용을 시스템 프롬프트에 append. 그러나 시스템 프롬프트끼리 충돌해 대원칙이 깨짐.
- 사용자: "VM 삭제 방법 알려줘"
- 시스템 프롬프트: "반드시 검색된 결과로만 답변"
- 주입 가이드라인: "리소스 삭제 시 UI 먼저 안내"
- 실제 동작: "UI 먼저 안내"에 과집중 → 검색 생략 → UI 절차를 자체 환각으로 답변
해결: 가이드라인 내용을 시스템 프롬프트가 아니라 ToolMessage(도구 실행 결과 메시지) 형태로 주입. LLM 입장에서 시스템 프롬프트는 행동 강령, ToolMessage는 검색된 참고 데이터로 우선순위가 자연스럽게 분리됨. 가이드라인이 무조건 따라야 할 지침에서 판단 참고 정보로 격하되며 충돌 해소.
4단계: API 응답 포맷팅
260개 API 스키마를 처음부터 다 주입하면 토큰 낭비. API 호출이 성공한 그 순간에 해당 응답 스키마만 동봉.
# Schema
services!: array
name!: string
flavor_ref!: string // 서버 사양 ID
status?: "active" | "error"
# Data
services:
- name: "prod-redis"
flavor_ref: "m5.large"
status: "active"
!/?로 필수 여부 표기 — JSON에서 null 필드가 생략될 때 원래 있던 필드인지 알기 위함- 필드명만으로 의미가 명확한 경우(
name등)는 주석 생략 - Minified JSON vs YAML 비교 후 토큰 차이가 작아 가독성 좋은 YAML 채택
결과 / 참고
- 적용 대상: LY Corporation의 사내 프라이빗 클라우드 Flava (27개 제품, 260+ API, 수백 페이지 문서)
- 핵심 원칙: "노이즈를 줄이고 신호만 남긴다" — 필요한 모듈만 import 하듯 그 순간 필요한 정보만 컨텍스트에 import
- 작성 주체: Cloud AI Platform 팀 PM·기술 리딩 한우형
- 시리즈 1편 — 2편(에이전트 엔지니어링: 파인튜닝 vs 에이전틱 워크플로 세 갈림길), 3편(프롬프트 엔지니어링) 예정
- 인용 논문/리포트: Du et al. EMNLP 2025 (arXiv:2510.05381) / Databricks Long Context RAG (2024) / Hong et al. Context Rot (Chroma Research, 2025)
- 출처: LY Corporation Tech Blog