본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.
본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.
이미지 로딩 중...
AI Generated
2025. 12. 27. · 2 Views
Context Fundamentals - AI 컨텍스트의 기본 원리
AI 에이전트 개발의 핵심인 컨텍스트 관리를 다룹니다. 시스템 프롬프트 구조부터 Attention Budget, Progressive Disclosure까지 실무에서 바로 적용할 수 있는 컨텍스트 최적화 전략을 배웁니다.
목차
- 컨텍스트_아키텍처
- Attention_Budget_제약
- Progressive_Disclosure_원칙
- Quality_Over_Quantity
- 컨텍스트_예산_관리
- Progressive_Loading_구현
1. 컨텍스트 아키텍처
어느 날 김개발 씨가 회사에서 AI 에이전트 프로젝트를 맡게 되었습니다. ChatGPT API를 처음 다뤄보는 김개발 씨는 API 문서를 읽다가 머리가 복잡해졌습니다.
"시스템 프롬프트, 메시지 히스토리, 툴 정의... 이게 다 뭐지?"
컨텍스트 아키텍처는 AI 모델에게 전달되는 모든 정보의 구조를 말합니다. 마치 회사에서 신입사원에게 업무를 맡길 때 회사 규칙, 업무 매뉴얼, 이전 회의록을 함께 전달하는 것과 같습니다.
시스템 프롬프트, 툴 정의, 메시지 히스토리라는 세 가지 핵심 요소가 하나의 컨텍스트를 구성합니다.
다음 코드를 살펴봅시다.
// AI 컨텍스트의 세 가지 핵심 구성요소
interface AIContext {
// 1. 시스템 프롬프트: AI의 역할과 규칙 정의
systemPrompt: string;
// 2. 툴 정의: AI가 사용할 수 있는 도구들
tools: ToolDefinition[];
// 3. 메시지 히스토리: 대화 기록
messages: Message[];
}
// 실제 컨텍스트 구성 예시
const context: AIContext = {
systemPrompt: "당신은 코드 리뷰 전문가입니다.",
tools: [{ name: "readFile", description: "파일 읽기" }],
messages: [
{ role: "user", content: "이 코드를 검토해주세요" },
{ role: "assistant", content: "네, 살펴보겠습니다" }
]
};
김개발 씨는 입사 3개월 차 주니어 개발자입니다. AI 에이전트 프로젝트를 맡게 된 첫날, 선배 개발자 박시니어 씨가 다가와 물었습니다.
"컨텍스트가 뭔지 알아요?" 김개발 씨는 고개를 갸웃거렸습니다. "그냥 대화 내용 아닌가요?" 박시니어 씨가 미소를 지으며 설명을 시작했습니다.
"반만 맞았어요. 컨텍스트는 AI에게 전달하는 모든 정보를 의미합니다." 쉽게 비유하자면, 컨텍스트 아키텍처는 마치 새로운 직원에게 업무를 인수인계하는 과정과 같습니다.
회사의 규칙과 문화를 알려주고, 사용할 수 있는 도구와 시스템을 소개하며, 지금까지 진행된 업무 히스토리를 전달합니다. AI도 마찬가지입니다.
첫 번째 요소는 시스템 프롬프트입니다. 이것은 AI의 역할과 행동 규칙을 정의합니다.
"당신은 친절한 고객 상담원입니다"라고 하면 AI는 그 역할에 맞게 행동합니다. 회사로 치면 직무 기술서와 같습니다.
두 번째 요소는 툴 정의입니다. AI가 어떤 도구를 사용할 수 있는지 명시합니다.
파일을 읽거나, 데이터베이스를 조회하거나, 외부 API를 호출하는 등의 기능을 정의합니다. 마치 신입사원에게 "이 시스템들을 사용할 수 있어요"라고 알려주는 것과 같습니다.
세 번째 요소는 메시지 히스토리입니다. 사용자와 AI 사이에 오간 대화 기록입니다.
이 기록을 통해 AI는 이전 맥락을 이해하고 일관된 응답을 할 수 있습니다. 이전 회의록을 참고하는 것과 비슷합니다.
위의 코드를 살펴보면, AIContext 인터페이스가 이 세 가지 요소를 명확하게 정의하고 있습니다. systemPrompt는 문자열로, tools는 배열로, messages도 배열로 구성됩니다.
실제 API 호출 시 이 세 가지가 함께 전달됩니다. 실무에서 이 구조를 이해하는 것이 왜 중요할까요?
AI 에이전트의 성능은 컨텍스트 구성에 따라 크게 달라지기 때문입니다. 시스템 프롬프트가 모호하면 AI의 응답도 일관성이 없어집니다.
툴 정의가 부실하면 AI가 제대로 된 작업을 수행하지 못합니다. 박시니어 씨의 설명을 들은 김개발 씨는 고개를 끄덕였습니다.
"아, 그래서 API 문서에 이 세 가지가 항상 함께 나오는 거군요!" 컨텍스트 아키텍처를 제대로 이해하면 더 효율적인 AI 에이전트를 설계할 수 있습니다. 다음 섹션에서는 이 컨텍스트에 숨겨진 중요한 제약 조건을 살펴보겠습니다.
실전 팁
💡 - 시스템 프롬프트는 명확하고 구체적으로 작성하세요
- 툴 정의에는 각 도구의 용도와 파라미터를 상세히 기술하세요
- 메시지 히스토리는 필요한 맥락만 유지하고 불필요한 것은 정리하세요
2. Attention Budget 제약
프로젝트를 진행하던 김개발 씨가 이상한 현상을 발견했습니다. AI 에이전트가 긴 파일을 읽은 후에는 응답 품질이 눈에 띄게 떨어지는 것이었습니다.
"왜 갑자기 멍청해지는 거지?" 김개발 씨는 혼란스러웠습니다.
Attention Budget은 AI 모델이 한 번에 집중할 수 있는 정보의 한계를 의미합니다. 연구에 따르면 실제 AI 에이전트 작업에서 관찰 데이터가 전체 컨텍스트의 약 83.9%를 차지합니다.
마치 책상 위에 서류가 쌓이면 중요한 문서를 찾기 어려워지는 것처럼, 컨텍스트가 관찰 데이터로 가득 차면 AI의 판단력이 흐려집니다.
다음 코드를 살펴봅시다.
// Attention Budget 모니터링 시스템
interface ContextBudget {
totalTokens: number; // 전체 토큰 수
systemPrompt: number; // 시스템 프롬프트 토큰
toolDefinitions: number; // 툴 정의 토큰
observations: number; // 관찰 데이터 토큰 (파일 내용 등)
conversation: number; // 대화 히스토리 토큰
}
function analyzeContextUsage(budget: ContextBudget): void {
const observationRatio = budget.observations / budget.totalTokens;
// 관찰 데이터가 80% 이상이면 경고
if (observationRatio > 0.8) {
console.warn(`경고: 관찰 데이터 비율 ${(observationRatio * 100).toFixed(1)}%`);
console.warn("컨텍스트 정리가 필요합니다.");
}
}
김개발 씨는 AI 에이전트에게 대규모 코드베이스를 분석하도록 했습니다. 처음에는 정확한 분석 결과를 내놓던 AI가 점점 이상한 답변을 하기 시작했습니다.
심지어 방금 읽은 파일의 내용도 제대로 기억하지 못하는 것 같았습니다. 박시니어 씨가 모니터를 살펴보더니 말했습니다.
"Attention Budget을 초과했네요." Attention Budget이란 무엇일까요? 쉽게 비유하자면, 책상 위의 공간과 같습니다.
책상이 아무리 넓어도 서류가 쌓이면 중요한 문서를 찾기 어려워집니다. AI도 마찬가지입니다.
컨텍스트 윈도우가 크더라도 정보가 너무 많으면 중요한 부분에 집중하기 어려워집니다. 실제 연구 결과에 따르면, AI 에이전트 작업에서 **관찰 데이터가 전체 컨텍스트의 83.9%**를 차지한다고 합니다.
관찰 데이터란 파일 내용, API 응답, 검색 결과 등 AI가 작업 중에 수집하는 정보를 말합니다. 문제는 이 비율이 높아질수록 AI의 성능이 떨어진다는 것입니다.
시스템 프롬프트에서 정의한 규칙을 잊어버리거나, 사용자의 원래 요청을 놓치거나, 논리적 일관성이 깨지는 현상이 발생합니다. 위의 코드는 컨텍스트 사용량을 모니터링하는 간단한 시스템입니다.
ContextBudget 인터페이스로 각 영역별 토큰 사용량을 추적합니다. analyzeContextUsage 함수는 관찰 데이터 비율이 80%를 넘으면 경고를 출력합니다.
왜 80%를 임계값으로 잡았을까요? 시스템 프롬프트와 대화 히스토리가 최소한의 공간을 확보해야 AI가 제대로 작동하기 때문입니다.
관찰 데이터에 모든 공간을 내주면 AI는 마치 정보의 홍수 속에서 길을 잃은 것처럼 행동합니다. 실무에서 이 문제를 해결하려면 두 가지 접근법이 필요합니다.
첫째, 관찰 데이터의 양을 줄이는 것입니다. 필요한 정보만 선별적으로 로드해야 합니다.
둘째, 중요도에 따라 정보를 구조화하는 것입니다. 핵심 정보가 컨텍스트의 앞부분에 위치하도록 배치합니다.
김개발 씨는 깨달았습니다. "아, 무조건 많이 읽게 하는 게 좋은 게 아니었군요!" 박시니어 씨가 고개를 끄덕였습니다.
"맞아요. AI에게 정보를 주는 것도 전략이 필요해요."
실전 팁
💡 - 컨텍스트 사용량을 정기적으로 모니터링하세요
- 관찰 데이터 비율이 70%를 넘으면 정리를 고려하세요
- 파일 전체를 읽기보다 필요한 부분만 선별적으로 로드하세요
3. Progressive Disclosure 원칙
"그러면 어떻게 해야 해요? 파일을 아예 안 읽게 하면 AI가 코드를 이해할 수 없잖아요?" 김개발 씨의 질문에 박시니어 씨가 웃으며 답했습니다.
"필요한 것만, 필요할 때만 보여주면 됩니다. 이걸 Progressive Disclosure라고 해요."
Progressive Disclosure는 모든 정보를 한꺼번에 로드하지 않고, 필요에 따라 점진적으로 제공하는 원칙입니다. 마치 도서관에서 책을 찾을 때 모든 책을 책상에 쌓아두지 않고, 필요한 책만 하나씩 가져오는 것과 같습니다.
AI 에이전트에 이 원칙을 적용하면 컨텍스트를 효율적으로 관리할 수 있습니다.
다음 코드를 살펴봅시다.
// Progressive Disclosure 패턴 구현
class ProgressiveLoader {
private summaryCache: Map<string, string> = new Map();
// 1단계: 파일 목록만 로드
async loadFileList(directory: string): Promise<string[]> {
return await fs.readdir(directory);
}
// 2단계: 파일 요약 정보 로드
async loadFileSummary(filePath: string): Promise<string> {
if (this.summaryCache.has(filePath)) {
return this.summaryCache.get(filePath)!;
}
// 첫 50줄만 읽어서 요약 생성
const preview = await this.readLines(filePath, 50);
return this.extractSignatures(preview);
}
// 3단계: 필요한 부분만 상세 로드
async loadSection(filePath: string, start: number, end: number): Promise<string> {
return await this.readLines(filePath, end - start, start);
}
}
김개발 씨는 도서관에서 책을 찾던 경험을 떠올렸습니다. 처음에는 서가 분류를 보고, 그다음 책 제목을 훑어보고, 마지막으로 필요한 책만 꺼내서 읽습니다.
모든 책을 한꺼번에 책상에 쌓아두는 사람은 없습니다. Progressive Disclosure는 바로 이 원리를 AI 에이전트에 적용하는 것입니다.
정보를 단계적으로, 필요한 만큼만 제공합니다. 1단계는 개요 수준입니다.
파일 목록이나 디렉토리 구조만 보여줍니다. AI는 이 정보를 바탕으로 어떤 파일이 필요한지 판단합니다.
이 단계에서 사용하는 토큰은 매우 적습니다. 2단계는 요약 수준입니다.
필요하다고 판단된 파일의 핵심 정보만 로드합니다. 함수 시그니처, 클래스 정의, 주요 주석 등 구조를 파악할 수 있는 정보입니다.
전체 파일을 읽는 것보다 훨씬 적은 토큰으로 맥락을 파악할 수 있습니다. 3단계는 상세 수준입니다.
실제로 수정하거나 분석해야 하는 부분만 전체 내용을 로드합니다. 이 시점에서 AI는 이미 무엇을 봐야 하는지 알고 있으므로 효율적으로 작업할 수 있습니다.
위의 코드에서 ProgressiveLoader 클래스는 이 세 단계를 메서드로 구현합니다. loadFileList는 파일 이름만 반환합니다.
loadFileSummary는 첫 50줄에서 함수 시그니처 등을 추출합니다. loadSection은 지정된 범위만 읽어옵니다.
summaryCache를 사용하는 이유도 중요합니다. 같은 파일의 요약을 여러 번 요청할 수 있으므로 캐싱으로 중복 로드를 방지합니다.
작은 최적화지만 누적되면 큰 차이를 만듭니다. 실무에서 이 패턴을 적용하면 놀라운 효과를 볼 수 있습니다.
수백 개의 파일로 구성된 프로젝트에서도 AI가 효율적으로 작업할 수 있게 됩니다. 컨텍스트 윈도우가 가득 차는 문제도 크게 줄어듭니다.
김개발 씨는 코드를 보며 말했습니다. "아, 이래서 IDE에서도 파일 트리를 먼저 보여주고, 클릭하면 내용을 보여주는 거군요!" 박시니어 씨가 고개를 끄덕였습니다.
"맞아요. 사람에게 좋은 UX가 AI에게도 좋은 UX입니다."
실전 팁
💡 - 파일 전체를 읽기 전에 항상 요약이나 개요를 먼저 확인하세요
- 캐싱을 활용해서 중복 로드를 방지하세요
- AI에게 "어떤 파일이 필요한지"를 먼저 물어보는 패턴을 고려하세요
4. Quality Over Quantity
"요즘 AI 모델들은 컨텍스트 윈도우가 100K, 200K 토큰까지 지원하잖아요. 그냥 다 넣으면 안 되나요?" 김개발 씨의 순진한 질문에 박시니어 씨가 고개를 저었습니다.
"큰 창문이 있다고 해서 창문 전체에 포스터를 붙이진 않잖아요."
Quality Over Quantity는 큰 컨텍스트 윈도우를 가득 채우는 것보다 관련성 높은 정보를 선별하는 것이 중요하다는 원칙입니다. 연구에 따르면 컨텍스트가 커질수록 AI의 검색 정확도와 추론 능력이 오히려 저하됩니다.
100K 토큰을 다 사용할 수 있다고 해서 다 사용해야 하는 것은 아닙니다.
다음 코드를 살펴봅시다.
// 컨텍스트 큐레이션 시스템
interface RelevanceScore {
content: string;
score: number; // 0-1 사이의 관련성 점수
recency: number; // 최신성 점수
importance: number; // 중요도 점수
}
function curateContext(
items: RelevanceScore[],
maxTokens: number
): string[] {
// 복합 점수 계산: 관련성 + 최신성 + 중요도
const scored = items.map(item => ({
...item,
finalScore: item.score * 0.5 + item.recency * 0.3 + item.importance * 0.2
}));
// 점수순 정렬 후 토큰 제한 내에서 선별
scored.sort((a, b) => b.finalScore - a.finalScore);
let tokenCount = 0;
return scored
.filter(item => {
tokenCount += countTokens(item.content);
return tokenCount <= maxTokens * 0.7; // 70% 임계값
})
.map(item => item.content);
}
김개발 씨는 의문이 들었습니다. 최신 AI 모델들은 엄청나게 큰 컨텍스트 윈도우를 제공합니다.
Claude는 200K 토큰, GPT-4는 128K 토큰을 지원합니다. 이렇게 크면 그냥 다 넣어도 되지 않을까요?
박시니어 씨가 설명했습니다. "교실에 학생 한 명만 있으면 선생님이 잘 가르칠 수 있어요.
하지만 학생이 천 명이면요?" 이것이 바로 Quality Over Quantity 원칙의 핵심입니다. 컨텍스트 윈도우가 크다고 해서 무조건 채우면 안 됩니다.
오히려 정보가 많아질수록 AI가 중요한 정보를 찾아내기 어려워집니다. 연구 결과들이 이를 뒷받침합니다.
"Lost in the Middle" 현상이라고 불리는데, 긴 컨텍스트의 중간 부분에 있는 정보는 AI가 잘 활용하지 못합니다. 컨텍스트 시작과 끝 부분의 정보에 더 주목하는 경향이 있습니다.
또한 컨텍스트가 커지면 추론 능력도 저하됩니다. 관련 없는 정보가 많으면 AI가 "노이즈"에 현혹되어 잘못된 판단을 내릴 수 있습니다.
마치 시끄러운 카페에서 대화하기 어려운 것과 같습니다. 위의 코드는 정보를 선별하는 큐레이션 시스템입니다.
각 정보에 관련성, 최신성, 중요도 점수를 부여합니다. 관련성은 현재 작업과 얼마나 관련 있는지, 최신성은 얼마나 최근 정보인지, 중요도는 전체 맥락에서 얼마나 핵심적인지를 나타냅니다.
curateContext 함수는 이 세 가지 점수를 가중 평균하여 최종 점수를 계산합니다. 관련성에 50%, 최신성에 30%, 중요도에 20%의 가중치를 부여했습니다.
그리고 토큰 제한의 70%만 사용합니다. 나머지 30%는 AI의 응답과 추가 작업을 위한 여유 공간입니다.
실무에서 이 원칙을 적용하려면 "이 정보가 정말 필요한가?"라는 질문을 계속해야 합니다. 전체 파일 대신 관련 함수만, 모든 로그 대신 에러 로그만, 전체 문서 대신 해당 섹션만 포함하는 습관이 필요합니다.
김개발 씨가 물었습니다. "그러면 어떤 기준으로 정보를 선별해야 하나요?" 박시니어 씨가 대답했습니다.
"사용자의 현재 질문에 직접 답할 수 있는 정보인지 생각해보세요. 그게 가장 좋은 기준입니다."
실전 팁
💡 - 컨텍스트 윈도우의 70% 이상 사용하지 않도록 목표를 세우세요
- 정보를 넣기 전에 "이게 정말 필요한가?"라고 질문하세요
- 중요한 정보는 컨텍스트의 시작과 끝 부분에 배치하세요
5. 컨텍스트 예산 관리
김개발 씨는 이제 컨텍스트의 중요성을 이해했습니다. 하지만 실제로 얼마나 사용하고 있는지 어떻게 알 수 있을까요?
"눈에 보이지 않는 걸 어떻게 관리하죠?" 박시니어 씨가 모니터링 대시보드를 열어 보여줬습니다.
컨텍스트 예산 관리는 토큰 사용량을 실시간으로 추적하고 임계값을 설정하여 효율적으로 관리하는 전략입니다. 일반적으로 70-80%를 임계값으로 설정하고, 이를 초과하면 오래된 정보를 정리하거나 요약합니다.
마치 가계부를 쓰듯이 컨텍스트 사용량을 기록하고 분석해야 합니다.
다음 코드를 살펴봅시다.
// 컨텍스트 예산 관리자
class ContextBudgetManager {
private maxTokens: number;
private warningThreshold = 0.7; // 70% 경고
private criticalThreshold = 0.8; // 80% 임계점
constructor(maxTokens: number) {
this.maxTokens = maxTokens;
}
checkBudget(currentTokens: number): BudgetStatus {
const usage = currentTokens / this.maxTokens;
if (usage >= this.criticalThreshold) {
return { status: 'critical', action: 'summarize_old_messages' };
} else if (usage >= this.warningThreshold) {
return { status: 'warning', action: 'prepare_cleanup' };
}
return { status: 'healthy', action: 'none' };
}
async cleanup(messages: Message[]): Promise<Message[]> {
// 오래된 메시지를 요약으로 대체
const oldMessages = messages.slice(0, -10);
const summary = await this.summarize(oldMessages);
return [{ role: 'system', content: summary }, ...messages.slice(-10)];
}
}
박시니어 씨가 보여준 대시보드에는 현재 컨텍스트 사용량이 실시간으로 표시되고 있었습니다. 마치 스마트폰의 저장 공간 사용량을 보는 것 같았습니다.
"컨텍스트 관리는 예산 관리와 같아요." 박시니어 씨가 설명했습니다. "월급을 다 쓰면 안 되듯이, 컨텍스트 윈도우도 다 채우면 안 됩니다." 컨텍스트 예산 관리의 핵심은 두 가지 임계값입니다.
첫 번째는 70%의 경고 임계값입니다. 이 수준에 도달하면 시스템이 정리 준비를 시작합니다.
두 번째는 80%의 임계점입니다. 이 수준을 넘으면 즉시 정리 작업이 필요합니다.
왜 이런 임계값이 필요할까요? AI의 응답도 토큰을 사용하기 때문입니다.
컨텍스트가 95% 찬 상태에서 요청을 보내면 AI가 충분한 응답을 생성할 공간이 없습니다. 또한 도구 호출 결과도 컨텍스트에 추가됩니다.
여유 공간이 없으면 작업 중간에 오류가 발생할 수 있습니다. 위의 코드에서 ContextBudgetManager 클래스는 이 전략을 구현합니다.
checkBudget 메서드는 현재 토큰 사용량을 확인하고 상태를 반환합니다. 'healthy', 'warning', 'critical' 세 가지 상태가 있습니다.
cleanup 메서드는 임계점 초과 시 호출됩니다. 오래된 메시지를 요약으로 대체하는 방식으로 공간을 확보합니다.
최근 10개 메시지는 유지하고, 그 이전의 메시지들은 하나의 요약으로 압축합니다. 실무에서는 이 모니터링을 자동화해야 합니다.
매 API 호출 전에 예산을 확인하고, 필요하면 자동으로 정리하는 파이프라인을 구축합니다. 수동으로 관리하면 언젠가 실수하게 됩니다.
요약 전략도 중요합니다. 단순히 오래된 메시지를 삭제하면 맥락이 사라집니다.
대신 핵심 결정사항, 확인된 사실, 진행 상황 등을 요약으로 보존합니다. 이렇게 하면 적은 토큰으로 중요한 맥락을 유지할 수 있습니다.
김개발 씨가 질문했습니다. "요약은 AI한테 시키나요?" 박시니어 씨가 고개를 끄덕였습니다.
"네, 별도의 요약 요청을 보내서 압축된 버전을 만들어요. 조금의 비용이 들지만 장기적으로는 더 효율적입니다."
실전 팁
💡 - 모든 API 호출 전에 토큰 사용량을 확인하는 미들웨어를 구축하세요
- 요약할 때는 결정사항과 핵심 사실을 우선적으로 보존하세요
- 임계값은 사용 패턴에 따라 조정하세요. 도구 호출이 많으면 더 낮게 설정합니다
6. Progressive Loading 구현
"이론은 알겠는데, 실제로 어떻게 구현하나요?" 김개발 씨의 질문에 박시니어 씨가 키보드를 잡았습니다. "직접 만들어볼까요?
파일 시스템 기반의 progressive loading 시스템을요."
Progressive Loading은 앞서 배운 원칙들을 실제 코드로 구현한 것입니다. 파일 시스템을 탐색할 때 전체 내용을 한꺼번에 읽지 않고, 구조 파악에서 시작해서 필요한 부분만 점진적으로 로드합니다.
이 패턴은 대규모 코드베이스를 다루는 AI 에이전트에서 필수적입니다.
다음 코드를 살펴봅시다.
// 파일 시스템 기반 Progressive Loading 구현
class FileSystemLoader {
private tokenBudget: number;
private usedTokens: number = 0;
constructor(budget: number) {
this.tokenBudget = budget;
}
// 1단계: 디렉토리 구조만 로드 (최소 토큰)
async loadStructure(rootPath: string): Promise<TreeNode> {
const structure = await this.scanDirectory(rootPath);
this.usedTokens += this.countTokens(JSON.stringify(structure));
return structure;
}
// 2단계: 파일 시그니처 로드 (함수/클래스 선언만)
async loadSignatures(filePath: string): Promise<string> {
const content = await fs.readFile(filePath, 'utf-8');
const signatures = this.extractSignatures(content);
if (this.wouldExceedBudget(signatures)) {
throw new Error('Token budget exceeded');
}
this.usedTokens += this.countTokens(signatures);
return signatures;
}
// 3단계: 특정 범위만 상세 로드
async loadRange(filePath: string, startLine: number, endLine: number): Promise<string> {
const lines = (await fs.readFile(filePath, 'utf-8')).split('\n');
const section = lines.slice(startLine - 1, endLine).join('\n');
if (this.wouldExceedBudget(section)) {
return this.truncateToFit(section);
}
this.usedTokens += this.countTokens(section);
return section;
}
private wouldExceedBudget(content: string): boolean {
return this.usedTokens + this.countTokens(content) > this.tokenBudget * 0.7;
}
}
박시니어 씨가 코드를 작성하기 시작했습니다. "이 시스템의 핵심은 세 가지 레벨의 로딩입니다." 1단계는 구조 로드입니다.
loadStructure 메서드는 디렉토리 구조만 스캔합니다. 파일 이름과 폴더 계층만 가져오고 내용은 읽지 않습니다.
이 정보만으로도 AI는 프로젝트의 전체적인 구조를 파악할 수 있습니다. 예를 들어 "src/components에 Button.tsx, Modal.tsx가 있고, src/hooks에 useAuth.ts가 있다"는 정보만으로도 많은 것을 알 수 있습니다.
이 단계에서 사용하는 토큰은 전체 소스 코드를 읽는 것의 1% 미만입니다. 2단계는 시그니처 로드입니다.
loadSignatures 메서드는 파일의 함수와 클래스 선언만 추출합니다. 구현 세부사항은 제외하고 인터페이스만 가져옵니다.
AI는 이 정보로 각 파일이 무엇을 하는지, 어떤 함수를 제공하는지 파악합니다. "export function fetchUser(id: string): Promise<User>"라는 시그니처만 봐도 이 함수가 무슨 일을 하는지 알 수 있습니다.
100줄짜리 구현 코드 전체를 읽을 필요가 없습니다. 3단계는 범위 로드입니다.
loadRange 메서드는 특정 줄 범위만 읽어옵니다. AI가 실제로 수정하거나 분석해야 하는 부분만 상세하게 로드합니다.
이 시점에서는 이미 어떤 부분이 필요한지 명확히 알고 있습니다. 코드에서 주목할 부분은 wouldExceedBudget 메서드입니다.
매번 새로운 콘텐츠를 로드하기 전에 예산 초과 여부를 확인합니다. 70% 임계값을 사용해서 여유 공간을 확보합니다.
만약 예산을 초과하면 어떻게 될까요? loadRange에서는 truncateToFit을 호출해서 예산 내에서 가능한 만큼만 반환합니다.
loadSignatures에서는 에러를 던져서 호출자가 다른 전략을 선택하도록 합니다. 김개발 씨가 코드를 따라 치며 물었습니다.
"extractSignatures는 어떻게 구현하나요?" 박시니어 씨가 답했습니다. "정규 표현식으로 function, class, interface 선언을 찾거나, TypeScript 파서를 사용해서 AST에서 추출할 수 있어요.
간단한 버전은 정규식으로 충분합니다." 이 패턴을 적용하면 수천 개의 파일로 구성된 대규모 프로젝트에서도 AI 에이전트가 효율적으로 작동합니다. 필요한 정보만 정확히 로드하므로 컨텍스트 낭비가 없습니다.
김개발 씨는 감탄했습니다. "이렇게 하면 정말 큰 프로젝트도 다룰 수 있겠네요!" 박시니어 씨가 미소 지었습니다.
"맞아요. AI 에이전트의 실력은 컨텍스트 관리 능력에서 결정됩니다."
실전 팁
💡 - extractSignatures 구현 시 언어별 파서를 활용하면 정확도가 높아집니다
- 토큰 카운팅은 tiktoken 같은 라이브러리를 사용하세요
- 캐싱 레이어를 추가하면 반복 로드를 방지할 수 있습니다
이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!
댓글 (0)
함께 보면 좋은 카드 뉴스
Context Compression 컨텍스트 압축 전략 완벽 가이드
LLM 애플리케이션에서 컨텍스트 윈도우를 효율적으로 관리하는 압축 전략을 다룹니다. Anchored Summarization부터 프로브 기반 평가까지, 토큰 비용을 최적화하면서 정보 품질을 유지하는 핵심 기법들을 실무 관점에서 설명합니다.
Context Degradation 컨텍스트 저하 패턴 진단
LLM의 컨텍스트 윈도우에서 발생하는 다양한 정보 손실과 왜곡 패턴을 진단하고, 이를 완화하는 실전 전략을 학습합니다. 프롬프트 엔지니어링의 핵심 난제를 풀어봅니다.
프로덕션 워크플로 배포 완벽 가이드
LLM 기반 애플리케이션을 실제 운영 환경에 배포하기 위한 워크플로 최적화, 캐싱 전략, 비용 관리 방법을 다룹니다. Airflow와 서버리스 아키텍처를 활용한 실습까지 포함하여 초급 개발자도 프로덕션 수준의 배포를 할 수 있도록 안내합니다.
LangChain LCEL 완벽 가이드
LangChain Expression Language(LCEL)를 활용하여 AI 체인을 우아하게 구성하는 방법을 배웁니다. 파이프 연산자부터 커스텀 체인 개발까지, 실무에서 바로 활용할 수 있는 핵심 개념을 다룹니다.
Human-in-the-Loop Workflow 완벽 가이드
AI 시스템에서 인간의 판단과 승인을 통합하는 Human-in-the-Loop 워크플로를 알아봅니다. 자동화와 인간 감독의 균형을 맞추는 핵심 패턴을 초급자도 이해할 수 있게 설명합니다.