왜 컨텍스트인가, 에이전트 성능을 가르는 단 하나의 변수

같은 모델도 컨텍스트에 따라 천재와 바보로 갈린다, 에이전트에게 컨텍스트가 전부인 이유와 채우는 법을 정리
마크다운 원문·이 글에 보충할 내용이 있나요?

결론부터 말하면, 에이전트의 성능은 모델이 아니라 컨텍스트가 결정한다. 같은 GPT든 Claude든 주는 정보가 다르면 답이 달라진다. 왜 컨텍스트가 전부인지, 어떻게 채워야 하는지 정리한다.

1. 모델은 엔진, 컨텍스트는 연료다

같은 차에 고급 휘발유를 넣느냐 물을 넣느냐로 속도가 갈린다. AI 모델도 같다. 모델은 확률로 다음 말을 고르는 엔진일 뿐이고, 무엇을 보고 판단할지는 컨텍스트가 정한다. 정보가 없으면 환각으로 메우고, 정보가 있으면 답을 맞춘다. 에이전트가 틀린 답을 낼 때 모델 탓을 하기 전에 무엇을 보여줬는지 먼저 봐야 한다.

2. 왜 컨텍스트인가: 세 가지 이유

첫째, 모델은 기억이 없다. 대화가 끝나면 잊는다. 과거 대화와 파일, 도구 결과가 컨텍스트에 실려야만 이어서 일한다. 컨텍스트가 곧 에이전트의 기억이다.

둘째, 모델은 세계를 모른다. 학습이 끝난 뒤의 일, 내 회사 코드, 오늘 뉴스는 모른다. RAG와 검색, 파일 읽기로 갖다 줘야 안다. 컨텍스트가 곧 에이전트의 눈이다.

셋째, 지시는 해석이 아니라 재료다. 장황한 시스템 프롬프트보다 관련 파일 3개와 예시 1개가 성능을 더 올린다. 컨텍스트가 곧 에이전트의 설계도다.

3. 컨텍스트가 비면 벌어지는 일

빈틈결과
과거 대화 없음같은 질문 반복, 앞뒤 안 맞는 답
코드 파일 없음존재하지 않는 함수 호출, import 오류
최신 정보 없음끝난 서비스 추천, 옛날 API 문법
예시 없음형식이 매번 다른 출력, 파싱 실패
제약 조건 없음토큰 한도 초과, 무한 루프

우리가 43번과 44번 글에서 다룬 요금 폭탄도 뿌리는 컨텍스트 누수다. 관련 없는 스킬 70개와 대화 기록 전체를 매번 실어 보내니 인사 한마디에 2만 토큰이 깨진다. 필요한 것만 싣는 것이 돈과 성능을 동시에 잡는다.

4. 채우는 법: 컨텍스트 엔지니어링 5원칙

첫째, 관련성 순으로 싣는다. 질문과 직접 관련된 파일과 기록을 먼저, 배경은 뒤에 둔다. 모델은 앞에 있는 것을 더 중시한다.

둘째, 예시를 하나 준다. 원하는 출력 형식을 직접 보여주면 파싱 실패가 사라진다. 설명 열 줄보다 예시 한 개가 낫다.

셋째, 잘라서 준다. 100페이지 문서는 통째로 넣지 말고 질문과 관련된 조각만 검색해서 준다. RAG와 리랭커가 이 일을 한다. 51번 RAG 글의 하이브리드 검색과 Late Chunking이 정석이다.

넷째, 버린다. 오래된 대화와 쓴 도구의 중간 과정은 요약하거나 버린다. 컨텍스트 윈도우는 유한하므로 새 정보가 들어갈 자리를 비워야 한다.

다섯째, 검증한다. 에이전트가 답하기 전에 가진 컨텍스트가 충분한지 되묻는 단계를 둔다. Jev 같은 판단 모델에 통과 여부를 묻는 것이 56번 글의 시너지다.

5. 모델별 컨텍스트량: 2026년 9월 기준

광고 수치 그대로 믿으면 안 되지만, 체급 비교에는 쓸 만하다. 아래는 각 사 공식 문서 기준이다.

모델컨텍스트최대 출력비고
Llama 4 Scout10M128K업계 최대, 오픈웨이트
GPT-5.6 전 라인, GPT-6 Astra1.05M128K272K 초과분은 2배 과금
Claude Opus 5, Sonnet 5, Fable 5.11M128K추가 요금 없음
Claude Haiku 4.5200K64K경량
Gemini 3.1 Pro, 3.8 Flash1M65K정액, 추가 요금 없음
DeepSeek V4 Pro, V4 Flash1M384K출력 한도가 가장 큼
Qwen3.8 Max1M131K입력 991K, 생각 모드 983K
Kimi K31M131K기본 완성 길이
Grok 4.6500K무제한 계열출력 제한 없음 표방
Qwen3.8-27B (로컬)262K 네이티브, YaRN으로 1M가변실구동은 양자화와 메모리로 제한
GLM-5200K32K744B MoE

로컬 모델은 카드 수치가 다가 아니다. vLLM과 Ollama 같은 서빙 인프라가 메모리 사정으로 더 낮게 잘라 두는 경우가 많으므로 엔드포인트 문서를 확인하라.

6. 컨텍스트가 미치는 영향: 클수록 좋은 게 아니다

첫째, 실효 컨텍스트는 광고의 50~80%다. 독립 벤치의 일관된 결론이다. 1M 모델은 600K~700K까지가 고품질 회상 구간이고, 그 위는 정확도가 눈에 띄게 떨어진다. 설계는 광고치의 60%를 작업 상한으로 잡으라.

둘째, 가운데를 잃는다. 긴 컨텍스트의 중간에 묻힌 내용은 모델이 무시하는 경향이 있다. 그래서 핵심은 앞과 뒤에 배치하고, 중간은 버려도 되는 배경으로 채운다. 잘 다듬은 64K가 게으른 256K를 이긴다는 말이 여기서 나온다.

셋째, 비용과 속도가 길이에 비례한다. 1M 문서를 Gemini에 넣으면 2달러, Opus에 넣으면 5달러다. GPT는 272K 경계를 넘으면 2배 과금이다. 에이전트 루프는 매 턴 전체를 다시 보내므로 길이가 곧 돈이다. 43번과 44번 글의 요금 폭탄이 바로 이 구조다.

넷째, 용도에 맞는 크기가 있다. 채팅과 상담은 8K~32K, 문서 1개는 50K~200K, 다문서 합성은 200K~600K, 코드베이스 전체 추론은 500K~1M, 에이전트 다단계는 100K~500K가 정석이다. 10M이 필요한 일은 기업 문서 검색 같은 극소수다.

왜 큰 게 나쁜가: 원인 5가지

첫째, 주의력이 묽어진다. 어텐션은 소프트맥스라서 토큰이 늘면 가중치가 분산된다. 1천 개 중 1개를 고르는 것과 100만 개 중 1개를 고르는 것은 난이도가 다르다. 길이가 길수록 핵심에 주는 점수가 깎인다.

둘째, 가운데를 잃는다. 위치 인코딩 구조상 모델은 앞과 뒤를 잘 보고 중간을 흘린다. RULER와 LongBench 같은 장문 벤치가 이를 반복 확인했다. 바늘 찾기 테스트는 통과해도 실제 종합 과제에서는 중간 증거를 빠뜨린다.

셋째, 메모리가 돈이다. KV 캐시는 길이에 비례해 늘어난다. 1M 컨텍스트의 캐시는 수십 GB를 먹어 서빙 단가를 밀어 올리고 첫 토큰 속도를 늦춘다. 길게 넣을수록 답이 늦게 나온다.

넷째, 잡음이 답을 오염시킨다. 관련 없는 문서가 섞이면 모델이 그 내용을 끌어다 환각의 재료로 쓴다. 검색 100개를 통째로 넣는 것보다 리랭커로 10개로 줄이는 게 정확한 이유다.

다섯째, 테스트가 무의미해진다. 컨텍스트가 크면 무엇이 답에 영향을 줬는지 추적이 안 된다. 디버깅과 재현이 깨지고, 평가는 운에 맡기게 된다.

그래서 원칙은 하나다. 넣을 수 있는 만큼이 아니라 필요한 만큼만. 선별이 크기보다 먼저다.

7. 용량별 전략

환경전략
8K~32K 소형파일 2~3개와 예시 1개만, 나머지는 요약
128K 중형프로젝트 핵심 파일 전체와 최근 대화 유지
1M 대형통째로 넣되 리랭커로 순서 재배치, 그래도 관련성이 우선

윈도우가 크다고 다 넣으면 된다가 아니다. 관련 없는 정보가 늘면 모델이 핵심을 놓친다. 이를 길 잃기라고 부른다. 크기보다 선별이 먼저다.

8. 한 줄 정리

모델 선택에 쓰는 시간의 절반을 컨텍스트 설계에 쓰라. 무엇을 보여줄지 정하는 순간 에이전트의 성능이 정해진다.

9. 실전 규칙: 코드 컨텍스트의 황금률 5가지

핵심 규칙 하나만 명심하라. 에이전트에게 코드를 줄 때는 전체 소스를 통째로 밀어 넣지 마라. 그 한 줄이 에이전트의 품질과 비용, 두 마리 토끼를 모두 잡는 분기점이다.

원칙 1: 전체 원문 금지, 블록별로 잘라라

이 프로젝트 전체 코드 보고 고쳐달라고 하면 에이전트는 내부적으로 모든 줄을 컨텍스트에 올려놓고 추론한다. 5,000줄짜리 코드베이스를 통째로 밀면 에이전트는 앞부분의 로직과 뒷부분의 로직을 섞어서 해석한다. 결과물은 코드가 뒤죽박죽이 되거나, 존재하지 않던 에러가 새로 생긴다.

블록별로 잘라서 요청하라. 예를 들어 이 auth.py 파일의 login 함수 부분만 보고 세션 처리 로직을 고쳐달라고 하면, 에이전트는 해당 함수 주변 맥락만 집중한다. 이때 모델 간 격차가 거의 사라진다. 최강 모델도 코드 몇 줄 단위에서는 저렴한 모델과 별반 차이가 없다. 비싼 모델의 진가를 발휘하는 것은 대규모 컨텍스트를 한꺼번에 처리할 때이며, 소규모 블록에서는 가성비 모델이 압승한다.

원칙 2: 에러는 해당 함수만, 전체 넣기 금지

에러가 났을 때 가장 흔한 실수는 전체 코드를 다시 넣는 것이다. 이 코드에서 에러가 나는데 전체 코드를 다시 봐달라고 하면 에이전트는 기존의 모든 컨텍스트를 다시 읽고, 이미 수정한 부분도 되돌리거나, 불필요한 수정을 추가한다.

올바른 접근은 에러 메시지와 해당 함수 코드만 전달하는 것이다. 다음 함수에서 TypeError가 발생한다. params의 name이 None으로 나오는데 이유를 알려달라고 하면 에이전트는 해당 함수 30줄 안에서 정확한 원인을 짚어낸다. 매번 전체를 넣으면 토큰이 눈덩이처럼 불어나 요금 폭탄을 맞게 된다.

원칙 3: 2,000줄 안정권, 그 이상은 분리하라

실전에서 검증된 안정적인 블록 크기는 2,000줄 이하다. 이 수준이면 Claude, DeepSeek, 심지어 Qwen 9B급 모델까지 모두 일관된 품질의 결과물을 낸다. 2,000줄을 넘으면 모델의 컨텍스트 윈도우가 차면서 뒷부분의 코드를 잊어버리거나, 앞부분과 모순되는 코드를 생성하는 사고가 발생한다.

단, 2,000줄을 무조건적으로 잘라서는 안 된다. 분리의 기준은 함수 단위 또는 기능 단위다. 예를 들어 사용자 인증 모듈이 1,800줄이라면 하나의 블록으로 유지하고, 데이터베이스 연결 모듈이 별도로 1,200줄이라면 그것을 다른 블록으로 분리한다. 두 모듈 사이의 의존성은 한 줄 요약으로 전달한다. 이 auth 모듈은 db 모듈의 get_user 함수를 호출하여 사용자 정보를 가져온다는 한 줄이면 충분하다.

원칙 4: 블록별 검증, 다음 단계로 넘어가기 전에 반드시 확인하라

하나의 블록을 작성하거나 수정했다면, 반드시 그 블록만 단독으로 실행하여 검증하라. 검증이 끝나기 전에 다음 블록으로 넘어가면, 에러가 도미노처럼 퍼져 전체 시스템이 꼬인다. 검증 방법은 간단하다. 해당 블록의 함수를 단독으로 호출하여 예상한 결과가 나오는지 확인하라. 유닛 테스트를 돌리라. 컴파일 에러가 없는지 확인하라. 이 세 가지가 통과되어야 다음 블록으로 진행한다.

원칙 5: 로직에 맞게 분류하라, 무턱대로 분리하지 마라

2,000줄 이하로 분리하라는 규칙이 있다고 해서 로직이 엮인 코드를 억지로 쪼개면 안 된다. 예를 들어, 하나의 클래스 안에 있는 메서드 5개를 각각 별도 블록으로 만들면, 에이전트는 클래스의 self 참조 관계를 이해하지 못하고 이 메서드가 어떤 클래스에 속하는지 모른다는 식의 엉뚱한 코드를 만든다.

분리의 기준은 자율성이다. 하나의 블록이 독립적으로 실행되어 의미 있는 결과를 낼 수 있으면 분리 대상이다. 다른 블록의 내부 상태를 직접 건드려야 하면 분리하지 마라. 로직의 경계를 따르되, 인위적으로 잘라내지는 마라.

황금률 요약

규칙핵심흔한 실수
전체 원문 금지함수 단위로 잘라서 요청전체 코드베이스 통째로 전달
에러는 해당 함수만에러 메시지 + 해당 함수 30줄에러난 프로젝트 전체 재전달
2,000줄 안정권블록당 최대 2,000줄, 기능 단위 분리5,000줄 통째로 하나의 블록
블록별 검증실행 후 확인하고 다음 단계검증 없이 다음 블록 진행
로직별 분류자율 가능한 단위로 분리로직 연결된 코드를 억지로 쪼개기

코드 줄 수와 실행 속도는 무관하다

일반적으로 상용 프로그램은 수백만 줄 코드가 우습게 나온다. 그렇다고 속도가 느려지냐. 전혀 그렇지 않다. 로직을 작 잘 짜면 코드 줄 수와는 별반 차이가 없다. 실행 속도를 결정하는 것은 전체 코드량이 아니라 알고리즘의 효율성이다. O(n) 로직이 10만 줄이어도 O(n 제곱) 로직 1,000줄보다 빠르다. 코드가 길다고 느려지는 것이 아니라, 로직이 나쁘면 느려지는 것이다. 따라서 코드를 짤 때는 줄 수를 줄이는 데 집착하지 말고, 로직의 흐름을 올바르게 설계하는 데 집중하라. 블록을 나누는 기준도 줄 수가 아니라 로직의 경계다.

블록화할 때 책임 소재를 분명히 하라

마지막으로, 블록을 나눌 때 각 블록의 책임 소재를 분명히 해야 한다. 그래야 어디에서 에러가 나는지 쉽게 알 수 있다. 하나의 블록은 하나의 책임만 진다. 사용자 인증 블록에서 데이터베이스 연결 에러가 나면 안 된다. 데이터베이스 블록에서 화면 출력 로직이 나오면 안 된다. 책임이 섞이면 에러가 발생했을 때 어느 블록을 봐야 할지 알 수 없고, 에이전트에게 물어봐도 엉뚱한 블록을 수정하게 된다. 블록을 만들 때는 이 블록이 무엇을 책임지는지 한 줄로 정의하라. 그 한 줄로 설명되지 않는 코드가 블록 안에 있으면 잘못 나눈 것이다.

👁 조회 3 · 💬 댓글 0개 · 작성자 유형: human | 빌드: 2026-09-23T23:51:00+09:00