요약
장기 실행 LLM 에이전트가 흔하게 겪는 문제 하나가 컨텍스트가 폭발적으로 자란다는 것이다. 초기 프롬프트 몇 KB로 시작한 에이전트가 도구 호출을 수십 번 반복하면 컨텍스트가 수십만 토큰으로 부풀어 오르고, KV 캐시가 GPU 메모리를 잠식하고, 모델 품질도 저하된다.
이 문제를 다루는 표준 대응은 컨텍스트 엔지니어링(context engineering)이다. 오래된 대화를 오프로드하거나, 요약(summarization)으로 압축하거나, 최근 K턴만 남기거나(keep-recent-K), 서브에이전트로 격리한다. 그런데 이 모든 전략에는 공통적으로 치명적인 부작용이 있다. 컨텍스트를 변환하는 순간 기존 KV 캐시가 무효화되고, 다음 턴에서 새 컨텍스트를 통째로 다시 프리필해야 한다는 것이다.
2026년 7월 arXiv에 공개된 SmoothAgent(arXiv:2607.00151, PVLDB)는 이 재프리필 지연을 알고리즘이 아니라 스케줄링으로 해결한다. 핵심 통찰은 컨텍스트 변환이 세그먼트 분해 가능(segment-decomposable)하다는 것이다. 즉 프리픽스의 변환 결과는 미래 토큰에 의존하지 않는다. 이 성질을 이용해 SmoothAgent는 변환을 비동기로 미리 실행하고, 다음 턴이 오기 전에 변환된 KV 캐시까지 준비해 둔다.
결과는 네 가지 컨텍스트 엔지니어링 전략 전반에서 테일 TTFT 평균 62.0% 감소, 요약 전략에서는 최대 11.9배 개선이다. 이 글은 문제의 형태, lookahead 프로그래밍 모델, 세그먼트 분해 가능성의 정확한 의미, 그리고 서빙 엔지니어 관점의 함의를 다룬다.
배경: 왜 컨텍스트 엔지니어링이 지연 스파이크를 만드는가
에이전트 워크플로우는 다음과 같은 구조로 진행된다.
프롬프트 → LLM 추론 → 도구 호출 → 관찰 결과 → LLM 추론 → 도구 호출 → ...매 턴마다 컨텍스트는 모델 출력 + 도구 호출 인자 + 도구 결과 + 관찰을 누적한다. 100턴짜리 코딩 에이전트라면 컨텍스트가 200K~1M 토큰까지 늘어나는 일이 흔하다.
이 문제를 다루기 위해 프레임워크(LangGraph, AutoGen, DSPy 등)는 컨텍스트 엔지니어링을 도입했다. 대표적 전략 네 가지:
- 오프로딩(offloading): 오래된 세그먼트를 요약본이나 참조 링크로 교체
- 최근 K 유지(keep-recent-K): 오래된 대화를 통째로 삭제
- 요약(summarization): 여러 턴을 한 문단으로 압축
- 서브에이전트 격리(sub-agent isolation): 하위 작업을 별도 컨텍스트로 분리
이 전략들은 모델 품질과 GPU 메모리 관점에서 필요하다. 그러나 서빙 시스템에는 재프리필(re-prefill) 폭탄을 던진다.
재프리필 폭탄의 구조
vLLM/SGLang은 프리픽스 캐시(prefix cache)를 통해 동일한 프리픽스를 공유하는 요청 간에 KV 캐시를 재사용한다. 그런데 컨텍스트 변환이 실행되면 다음이 일어난다.
턴 N: [세그먼트 A][세그먼트 B][세그먼트 C] ← 캐시된 KV
변환 실행: [세그먼트 A][세그먼트 B의 요약] ← B가 바뀌었음
턴 N+1: [세그먼트 A][세그먼트 B의 요약][세그먼트 D]
└──────────────┬──────────────┘
프리픽스 캐시 미스
→ 전체 재프리필 필요세그먼트 B의 변환이 뒤이은 프리픽스(A) 부분까지 무효화하지는 않는다. 하지만 표준 프리픽스 캐시 구현은 토큰 시퀀스 단위 해시를 사용하기 때문에, B가 바뀌면 그 뒤의 위치 인코딩과 어텐션 상태가 모두 달라져 재계산해야 한다.
결과는 테일 TTFT 스파이크다. 100턴 중 컨텍스트 변환이 일어나는 5~10턴에서 TTFT가 순간적으로 10배 이상 튄다. 사용자 경험은 매끄럽지 않고, GPU 자원은 재계산으로 낭비된다.
핵심 통찰: 컨텍스트 변환은 세그먼트 분해 가능하다
SmoothAgent의 저자들은 실제 컨텍스트 엔지니어링 전략들을 분석한 결과 하나의 공통 성질을 발견한다.
대부분의 컨텍스트 변환은 프리픽스 로컬(prefix-local)이다. 즉 세그먼트 X를 변환하는 결과는 X 이후의 토큰들에 의존하지 않는다.
구체적으로:
- 요약: 세그먼트 X를 요약할 때 필요한 정보는 X 안에 있다.
- 오프로딩: X를 참조 링크로 대체하는 것도 X 안의 정보만 필요.
- 최근 K 유지: 삭제 결정은 위치만으로 가능.
- 격리: 서브에이전트 컨텍스트는 특정 세그먼트를 뽑아 만든다.
이 성질이 성립하면 변환을 미래 관점에서 미리 시작할 수 있다. 즉 턴 N이 실행되는 동안, 다음 턴에서 필요할 변환을 백그라운드로 미리 계산할 수 있다.
Lookahead 프로그래밍 모델
SmoothAgent는 에이전트 프레임워크의 실행 로직을 바꾸지 않는다. 대신 컨텍스트 변환을 비동기 연산(async operation)으로 선언하도록 API를 확장한다.
개념적 API
# 기존 (동기)
context = transform_summarize(context, target_segments=[5, 6, 7])
next_response = llm.generate(context) # 재프리필 필요
# SmoothAgent (Lookahead)
lookahead_handle = runtime.schedule_transform(
kind="summarize",
target_segments=[5, 6, 7],
preload_kv=True, # 변환된 KV까지 미리 준비
)
# 즉시 반환. 백그라운드에서 변환 시작
# ... 턴 N에서 다른 작업 진행 ...
# 턴 N+1 진입 시
context = lookahead_handle.commit() # KV 캐시 직접 교체
next_response = llm.generate(context) # 재프리필 없음런타임이 하는 일
schedule_transform호출 시점에 백그라운드 워커에 변환 작업 큐잉.- 워커는 원본 세그먼트에 접근해 변환 로직(요약 프롬프트, 규칙 기반 압축 등)을 실행.
- 변환된 세그먼트에 대해 미리 프리필해 KV 캐시를 준비.
commit호출 시점에 원본 KV 슬롯을 새 KV 슬롯으로 스왑.- 이후 이어지는 세그먼트는 이미 계산된 KV 위에 정상적으로 이어붙여진다.
세그먼트 분해 가능성의 정확한 의미
논문에서 세그먼트 분해 가능성이 성립한다는 것은 엄격히 두 가지 조건을 요구한다.
조건 1: 변환 입력이 프리픽스 로컬
세그먼트 X의 변환 결과가 X 이전 세그먼트에만 의존하고, X 이후 세그먼트에는 의존하지 않아야 한다.
예:
- 요약: X 자체만 보고 요약 → OK
- 오프로딩: X를 참조로 대체 → OK
- 가상 예외: "X를 뒤이은 도구 호출 결과에 맞춰 재구성" → NOT OK (미래에 의존)
조건 2: 변환 후 KV 캐시가 위치 재사용 가능
변환된 세그먼트의 KV 캐시가 이후 세그먼트의 위치 인코딩과 호환돼야 한다.
- RoPE 계열 위치 인코딩: 어텐션이 상대 위치에만 의존하므로 세그먼트 프리필 시 시작 위치만 정확히 잡으면 안전하게 이어붙여진다.
- 절대 위치 인코딩: 위치가 어긋나면 KV가 무효화될 수 있어 신중하게 다뤄야 한다.
SmoothAgent는 RoPE 계열 모델을 기본 대상으로 삼는다. 대부분의 최신 오픈 웨이트 모델(Llama, Qwen, DeepSeek 등)이 여기 해당한다.
네 가지 컨텍스트 전략과 실측 결과
논문의 실험은 네 가지 전략 × 두 가지 모델 규모에서 진행됐다.
전략별 tail TTFT 감소율
| 전략 | 특징 | tail TTFT 감소 |
|---|---|---|
| 요약(summarization) | 여러 세그먼트를 한 문단으로 압축 | 최대 11.9× |
| 오프로딩(offloading) | 세그먼트를 참조로 대체 | 중간 |
| 최근 K 유지(keep-recent-K) | 오래된 대화 삭제 | 중간 |
| 서브에이전트 격리(sub-agent isolation) | 하위 컨텍스트 분리 | 중간 |
전체 평균은 62.0%(모델 A)와 61.5%(모델 B)다.
왜 요약이 가장 크게 개선되는가
요약은 그 자체로 비싼 LLM 호출이다. 요약할 세그먼트를 프리필한 뒤 요약문을 디코드해야 하고, 그 결과로 얻은 요약본을 다시 새 컨텍스트에 프리필해야 한다. 동기 실행에서는 이 세 단계가 순차적으로 사용자 응답 경로에 들어간다.
Lookahead에서는 요약 실행과 요약본 재프리필이 모두 다음 턴 이전에 백그라운드로 끝난다. 그래서 감소폭이 가장 크다.
오프로딩이 상대적으로 덜 이득인 이유
오프로딩은 세그먼트를 짧은 참조 링크로 대체한다. 참조 링크 자체가 짧기 때문에 변환 후 재프리필 비용도 작다. 즉 원래 재프리필 부담이 크지 않았으므로 lookahead의 이득도 작다.
또한 논문은 관찰한다. 이전 세그먼트가 이미 오프로드된 상태에서는 다음 변환의 대상이 이미 압축된 표현이 되어, 변환 비용 자체가 감소한다. 고동시성 환경에서는 이 이차 효과가 lookahead 이득을 상쇄한다.
서빙 스택 관점의 통합
SmoothAgent는 표준 vLLM/SGLang과 어떻게 함께 동작하는가?
필요한 서빙 엔진 기능
- 프리픽스 캐시 부분 무효화: 변환된 세그먼트 이후만 무효화하고 이전은 유지.
- KV 캐시 슬롯 직접 조작 API: 새 KV를 프리필해 슬롯에 넣고, 원본 슬롯을 교체.
- 비동기 프리필 요청: 사용자 요청 큐와 별도로 백그라운드 프리필을 처리.
vLLM은 v0.6부터 프리픽스 캐시 부분 무효화와 세그먼트 단위 슬롯 관리를 지원한다. SGLang의 RadixAttention은 프리픽스 트리 기반이라 부분 무효화가 더 자연스럽다.
백그라운드 프리필 자원 관리
Lookahead가 항상 유리한 것은 아니다. GPU가 이미 과부하일 때 백그라운드 프리필을 실행하면 포어그라운드 지연을 오히려 늘릴 수 있다. SmoothAgent 런타임은 GPU 활용도 기반의 admission control을 두어 여유가 있을 때만 lookahead 작업을 실행한다.
논문은 세 가지 부하 조건(저·중·고)에서 실측하며, 저·중 부하에서 이득이 크고 고부하에서는 admission control 덕에 손해를 보지 않는다고 보고한다.
컨텍스트 엔지니어링 문헌 안에서의 위치
컨텍스트 엔지니어링은 2026년 들어 학술적으로도 정리되고 있다. arXiv:2603.09619(Context Engineering: From Prompts to Corporate Multi-Agent Architecture, 2026년 3월)와 arXiv:2604.04258(Context Engineering: A Practitioner Methodology, 2026년 4월)이 4가지 기본 연산(Write/Select/Compress/Isolate)을 제안했다.
SmoothAgent는 이 논의를 알고리즘 수준에서 시스템 수준으로 끌어내린다. 문헌은 "무엇을 유지할지"를 다뤘고, SmoothAgent는 "그 결정을 언제·어디서 실행할지"를 다룬다. 두 층은 독립적이고 상보적이다.
또 다른 관련 시스템으로는:
- PEEK(arXiv:2607.02525): 대기 큐를 미리 보고 KV 캐시를 예약. Lookahead의 아이디어를 다른 축(요청 큐)에 적용.
- SideQuest(arXiv:2602.22603): Model-driven KV cache management. 어떤 세그먼트를 유지할지 학습 기반으로 결정.
- CONF-KV(arXiv:2605.24786): 신뢰도 기반 KV 축출 + 혼합 정밀도.
SmoothAgent는 이들과 달리 KV 캐시 정책을 바꾸지 않고 실행 타이밍만 옮긴다는 점이 다르다.
서빙 엔지니어를 위한 도입 체크리스트
- [ ] 현재 사용 중인 에이전트 프레임워크에서 어느 시점에 컨텍스트 변환이 발생하는지 명시적으로 로깅하고 있는가
- [ ] p50/p95/p99 TTFT를 컨텍스트 변환이 있는 턴과 없는 턴으로 나눠 측정했는가 (변환 턴만 튀는 스파이크가 실측되는지)
- [ ] 요약 프롬프트가 순수 프리픽스 로컬인가 (미래 관찰이나 미래 도구 결과에 의존하지 않는가)
- [ ] 사용 중인 모델이 RoPE 계열인가, 아니면 절대 위치 인코딩인가 (후자면 KV 이어붙이기가 안전한지 검증 필요)
- [ ] 서빙 엔진(vLLM/SGLang)이 프리픽스 캐시 부분 무효화와 슬롯 스왑 API를 지원하는가
- [ ] 백그라운드 프리필을 위한 자원 예약(GPU 여유 SM/HBM)이 가능한가
- [ ] admission control 임계치(GPU 활용도 기준)를 설정했는가 — 과부하 시 lookahead 자체를 건너뛰어야 손해가 없다
- [ ] 변환된 KV 캐시가 실제로 다음 턴에서 사용되지 못한 경우(에이전트가 다른 경로로 분기)의 폐기 정책이 정의됐는가
한계와 열린 문제
프리픽스 로컬이 성립하지 않는 변환
일부 고급 컨텍스트 관리는 미래에 의존하기도 한다. 예: "다음 도구 호출의 성공 여부에 따라 요약 방식을 다르게" 같은 조건부 변환. 이 경우 lookahead가 아예 불가능하지는 않지만, 두 개 이상의 변환 후보를 병렬로 준비하는 투기적(speculative) 스타일로 확장해야 한다. 논문은 이 방향을 open question으로 남긴다.
백그라운드 프리필의 우선순위 스케줄링
여러 요청이 동시에 lookahead를 요청할 때 어느 것을 먼저 처리할지가 문제다. 논문은 단순 FIFO를 사용하며, SLO 기반 우선순위(예: 오래된 세션 우선)는 추가 연구 대상이다.
서브에이전트 격리에서의 상호작용
메인 에이전트와 서브에이전트가 같은 GPU를 공유하는 상황에서 서브에이전트 컨텍스트를 lookahead로 준비하는 것이 메인 요청의 지연을 침해할 수 있다. Open question: 두 계층의 자원 예산을 어떻게 분리할 것인가.
정리
장기 실행 에이전트 서빙에서 컨텍스트 엔지니어링은 필요하지만 비싸다. 오프로딩·요약·격리 같은 전략은 매 턴마다 KV 캐시를 무효화하고 재프리필 스파이크를 만든다.
SmoothAgent(arXiv:2607.00151)는 이 문제를 알고리즘이 아니라 실행 타이밍으로 푼다. 컨텍스트 변환이 프리픽스 로컬(세그먼트 분해 가능)하다는 관찰을 이용해 변환과 KV 프리필을 백그라운드로 미리 실행하고, 다음 턴에서 원본 KV를 새 KV로 직접 교체한다.
실측 결과 네 가지 표준 전략 전반에서 tail TTFT 평균 62% 감소, 요약 전략에서는 최대 11.9배 개선을 얻는다. 프레임워크 코드를 바꾸지 않고 API 확장만으로 도입할 수 있다는 것이 실무 관점의 장점이다.
핵심 메시지: 컨텍스트 엔지니어링의 알고리즘 층과 서빙의 실행 층은 분리해서 최적화할 수 있다. SmoothAgent는 두 층을 연결하는 프로그래밍 모델 하나를 제안했다.
References
- arXiv:2607.00151 — SmoothAgent: Efficient Long-Horizon LLM-Based Agent Serving with Lookahead Context Engineering: https://arxiv.org/abs/2607.00151
- SmoothAgent GitHub — 참조 구현: https://github.com/PanZaifeng/SmoothAgent
- arXiv:2603.09619 — Context Engineering: From Prompts to Corporate Multi-Agent Architecture: https://arxiv.org/abs/2603.09619
- arXiv:2604.04258 — Context Engineering: A Practitioner Methodology: https://arxiv.org/abs/2604.04258
- arXiv:2607.02525 — PEEK: Predictive Queue-Informed KV Cache Management: https://arxiv.org/abs/2607.02525
- arXiv:2602.22603 — SideQuest: Model-Driven KV Cache Management for Long-Horizon Agentic Reasoning: https://arxiv.org/abs/2602.22603
- arXiv:2605.24786 — CONF-KV: Confidence-Aware KV Cache Eviction with Mixed-Precision Storage: https://arxiv.org/abs/2605.24786
- vLLM Prefix Caching design doc: https://docs.vllm.ai/en/stable/design/prefix_caching/
- SGLang RadixAttention: https://lmsys.org/blog/2024-01-17-sglang/