전체 글/개념
컨텍스트 윈도우는 통이 아니라 예산이다
무엇을 넣느냐보다 무엇을 빼느냐가 결과를 갈랐고, 그 기준을 정리했습니다.
2026-03-25 / 7분 / 개념
처음에는 컨텍스트를 통으로 생각했습니다. 크기가 20만이면 20만어치를 넣을 수 있다고 봤고, 그래서 넣을 수 있는 것은 다 넣었습니다. 결과는 나쁘지 않았지만 좋아지지도 않았습니다.
예산으로 보기 시작한 뒤에 달라졌습니다. 한 칸을 쓰면 다른 무엇을 못 쓴다는 뜻이고, 그러면 질문이 “무엇을 더 넣을까”에서 “무엇을 빼도 되는가”로 바뀝니다.
통과 예산의 차이
통에는 순서도 우선순위도 없습니다. 예산에는 둘 다 있습니다. 같은 문서를 넣더라도 어디에 놓는지, 요약해서 넣는지, 앞부분만 넣는지가 전부 선택이고, 그 선택은 비용과 정확도를 동시에 움직입니다.
실제로 도움이 된 규칙은 하나였습니다. 새로 넣을 것이 생기면, 자리를 만들기 위해 무엇을 뺄지 함께 정하기. 뺄 것을 못 정하면 그건 아직 필요하다는 근거가 약한 것이었습니다.
넣을 수 있다는 것과 넣어야 한다는 것은 다른 이야기다.
작업 메모, 2026-02
쓰고 있는 계산
예산을 실제로 관리하려면 남은 자리를 알아야 합니다. 아래는 지금 쓰고 있는 최소 버전으로, 항목마다 우선순위와 대략의 토큰 수를 두고 넘치면 낮은 것부터 자릅니다.
PARTS = [
("instructions", 1, 600),
("task", 1, 900),
("retrieved_docs", 3, 8000),
("history", 4, 4000),
]
def fit(parts, limit):
kept, used = [], 0
for name, prio, size in sorted(parts, key=lambda p: p[1]):
if used + size > limit:
continue # dropped, and we know which
kept.append(name)
used += size
return kept, used정확한 토큰 수는 중요하지 않았습니다. 중요한 건 무엇이 먼저 잘리는지가 코드에 적혀 있다는 점이었습니다. 그 뒤로는 이상한 출력이 나와도 어디가 잘렸는지 추적할 수 있었습니다.
여기서 안 되는 것
긴 대화에는 이 방식이 잘 맞지 않았습니다. 대화가 이어지면 잘라낼 것을 고르는 일 자체가 판단이 되고, 그 판단을 규칙으로 적기 어려웠습니다.
그래서 지금은 대화형에는 요약 갱신을, 단발성 작업에는 예산 규칙을 씁니다. 하나로 통일하려던 시도는 두 번 다 실패했습니다.