3/28/2026

터미널용 효과적인 AI 코딩 에이전트 구축

요즘 에이전트 환경에 대한 관심이 많다. 관련해서 오늘 읽어본 논문에 대해서 간단하게 정리해본다.

이 논문은 무엇을 말하는가?

이 논문은 “새로운 모델이 얼마나 똑똑한가”를 보여주는 논문이 아니다.
정확히는, 터미널에서 실제로 일하는 코딩 에이전트를 만들려면 어떤 구조가 필요한가를 설명하는 설계 논문이다. 저자는 OPENDEV를 오픈소스, Rust 기반, 터미널 네이티브 코딩 에이전트로 소개하면서, 이 시스템을 만들며 마주친 문제와 해결 방식을 정리한다. 초록에서도 같은 메시지가 나온다. 핵심 키워드는 compound AI system, planning과 execution의 분리, adaptive context compaction, event-driven reminders, memory pipeline, lazy tool discovery다.

논문이 보는 배경도 분명하다.
예전 AI 코딩 도구는 IDE 안에서 반응형 보조 역할을 했다면, 최근에는 Claude Code 같은 흐름을 따라 터미널 중심 에이전트가 부상하고 있다. 이유는 간단하다. 실제 개발의 중심에는 여전히 Git, build, SSH, 로그, 배포처럼 터미널이 있기 때문이다. 그런데 Terminal-Bench, LongCLI-Bench 같은 벤치마크를 보면, 최신 모델도 긴 호흡의 CLI 작업에서는 여전히 잘 흔들린다. 저자는 바로 그 지점에서 문제를 본다. 즉 모델이 강해졌는데도 에이전트는 왜 오래 못 버티는가?가 이 논문의 출발점이다.

논문은 이 문제를 세 가지로 정리한다.

  1. 긴 세션에서 컨텍스트 윈도우를 어떻게 관리할 것인가?

  2. Shell 명령과 파일 수정이 가능한 시스템을 어떻게 안전하게 통제할 것인가?

  3. 기능을 늘리면서도 툴 스키마와 프롬프트가 비대해지지 않게 어떻게 설계할 것인가?

이 세 질문이 사실상 논문 전체를 끌고 간다 여기서 중요한 점 하나를 먼저 짚어야 한다.
저자는 이 논문의 목적이 “알고리즘적 돌파구”를 내는 것이 아니라, production-ready agentic coding system을 만들며 얻은 설계 결정과 트레이드오프를 공유하는 것이라고 직접 말한다. 즉, 이 논문은 “우리가 최고다”를 증명하는 성능 논문이 아니라, 좋은 에이전트를 만들기 위한 운영 설계 문서에 가깝다.

이 논문의 가장 중요한 주장: 코딩 에이전트의 병목은 모델이 아니라 운영 구조다

이 논문에서 내가 가장 중요하게 본 문장은, OPENDEV를 단일 LLM이 아니라 compound AI system이라고 규정하는 부분이다. 저자는 세션, 에이전트, 워크플로우, LLM이 계층적으로 연결된 구조를 제시한다. 한 세션 안에는 여러 서브에이전트가 있고, 각 에이전트는 Execution, Thinking, Compaction 같은 워크플로우를 수행하며, 각 워크플로우는 사용자 설정 모델에 독립적으로 바인딩될 수 있다.

이게 왜 중요하냐면.,
많은 사람은 “어떤 모델이 제일 좋은가”를 먼저 묻는다. 하지만 그보다 어떤 종류의 작업에 어떤 모델을 붙일 것인가?가 더 중요하다고 본다. Action model은 실행과 툴 호출을 담당하고, Thinking model은 도구 없이 전략적 추론을 담당하며, Critique model은 자기비평, Vision model은 이미지/스크린샷 분석, Compact model은 컨텍스트 압축용 요약을 맡는다. 그리고 각 역할은 fallback 체인을 갖는다.

즉, OPENDEV는 “최강 모델 하나”를 중심에 두지 않는다.
오히려 비싼 모델은 비싼 일에만, 빠른 모델은 요약 같은 값싼 일에 쓰는 구조를 지향한다. 이건 비용, 지연시간, 품질을 분리해서 조절할 수 있다는 뜻이다. 논문은 이를 첫 번째 기여로 “Per-workflow LLM configurability”라고 적고 있다.

내 해석을 덧붙이면, 이건 단순한 구현 디테일이 아니다.
이 논문은 사실상 “코딩 에이전트는 모델 앱이 아니라 운영체계다” 라고 말하고 있다. 모델이 뇌라면, OPENDEV는 그 뇌 하나만으로 일하는 게 아니라, 뇌를 역할별로 나눠서 배치하는 시스템이다. 이 관점은 앞으로 코딩 에이전트를 볼 때 매우 중요하다.

OPENDEV 전체 구조를 쉽게 풀어보면

OPENDEV를 네 개 층으로 설명된다.
Entry & UI, Agent, Tool & Context, Persistence다. 사용자 입력은 CLI 또는 UI에서 들어와 에이전트 레이어로 전달되고, 에이전트가 툴과 컨텍스트 계층을 활용해 작업한 뒤, 결과를 persistence 계층에 저장한다. 즉 이 시스템은 단순한 채팅 인터페이스가 아니라, 입력-추론-실행-저장으로 이어지는 운영 파이프라인이다.

Entry & UI 계층은 생각보다 단순하다.
CLI entry point가 ConfigManager, SessionManager, ModeManager, Approval Manager를 초기화하고, TUI와 Web UI는 공통 callback 계약 위에서 작동한다. 즉 UI는 다를 수 있지만, 아래쪽 에이전트 계층은 같은 로직을 쓴다. 이건 나중에 CLI, 웹, IDE로 확장할 때 유리한 구조다. 결론부의 future directions에도 hybrid CLI–IDE integration이 미래 과제로 언급된다.

Agent 계층은 이 논문의 중심이다.
여기서 다섯 개 모델 역할이 나뉘고, reasoning은 Extended ReAct loop를 따라간다. 본문은 이 루프를 네 단계 또는 여섯 단계로 서술하는데, 큰 흐름은 같다. 시작할 때 context pressure를 점검해 compaction이 필요한지 보고, 필요하면 thinking phase를 돌리고, 더 깊게 갈 때는 critique를 하고, 마지막에 action model이 툴과 함께 실행 결정을 내린다.

Tool & Context 계층은 이름은 하나지만 실제로는 둘이다.
Tool Registry를 중심으로 파일, 프로세스, 웹, MCP, skills, subagents가 붙고, 그 옆에서 Prompt Composer, Memory, System Reminders, Compaction이 모델이 보는 문맥을 조절한다. 즉, 툴은 “무엇을 할 수 있는가?”를 정하고, 컨텍스트 계층은 “무엇을 보게 할 것인가?”를 정한다. 저자는 이 둘을 함께 놓지만, 실제 설계상으로는 행동 가능성인지 가능성을 나누고 있다고 볼 수 있다.

Persistence 계층도 꽤 중요하다.
대화 세션, 모델 capability cache, operation log, 설정 계층이 모두 여기 있다. 화려하지 않지만, 실제 에이전트는 여기서 production 감각이 드러난다. 단순히 답을 잘하는 게 아니라, 이어서 하고, 되돌리고, 재개하고, 비용을 추적하는 시스템으로 만들려는 의도가 분명하다.

왜 이 논문은 planning을 별도 서브에이전트로 분리했는가?

이 논문에서 가장 흥미로운 아키텍처 선택 중 하나는 planning을 main agent 내부 상태가 아니라 별도의 Planner subagent로 다룬다는 점이다. 사용자가 /plan을 쓰거나 설계/아키텍처/변경 계획 같은 의도가 감지되면, main agent는 plan mode로 “변신”하는 대신 Planner를 spawn한다. Planner는 코드베이스를 탐색하고, 패턴과 리스크를 분석한 뒤, goal/context/files/steps/verification/risks를 포함한 구조화된 plan file을 만든다. 그 후 main agent가 present_plan으로 사용자 승인을 받는다.

이 방식의 핵심은 안전이다.
논문은 이전 설계에서 enter_plan_mode, exit_plan_mode 같은 상태 머신을 썼지만, 에이전트가 read-only 상태에 갇혀버리는 brittle한 문제가 있었다고 설명한다. 그래서 현재는 state machine을 버리고, Planner 자체를 별도 스키마로 컴파일하는 쪽으로 바꿨다고 한다. 저자의 표현을 빌리면, Planner는 write가 “차단되는” 존재가 아니라, 애초에 write tool이 스키마에 존재하지 않는 존재다. 이게 schema-level gating이다.

이건 정말 중요한 설계 철학이다.
안전은 “하지 마!”라는 규칙보다, 그 능력을 보여주지 않는 것이 더 강하다는 뜻이다. 코딩 에이전트는 확률적 시스템이기 때문에, 위험한 도구가 보이면 언젠가는 그것을 떠올리고 시도할 수 있다. 하지만 스키마에 없으면 reasoning 자체가 그 도구를 중심으로 형성되지 않는다. 이 논문이 safety를 가장 잘 이해한 부분이 바로 여기다. 결론에서도 schema-level safety enforcement가 runtime permission check보다 robust했다고 다시 강조한다. 

main agent는 실행과 조율에 집중하고, Planner는 읽기 중심 탐색과 계획 작성에 집중한다. 이건 사고의 분리이자 권한의 분리다. 즉, 전략은 별도 문맥에서, 실행은 별도 문맥에서 다뤄진다. 에이전트 설계에서 이 정도로 planning을 구조화한 사례는 꽤 인상적이다.

Extended ReAct는 왜 필요한가?

OPENDEV는 일반적인 ReAct를 그대로 쓰지 않는다.
각 질의는 initialization 후 반복 루프에 들어가고, 그 안에서 context management → thinking → action → decision 흐름을 거친다. 논문 텍스트는 여기에 self-critique와 learning까지 덧붙여 더 세분화해서 설명한다. 핵심은 하나다. 생각을 행동보다 먼저, 그리고 별도 호출로 빼놓는다는 것이다.

저자들의 판단은 명확하다.
도구가 보이는 순간 모델은 생각보다 행동을 서두른다. 그래서 thinking phase에서는 tool-free conversation만 주고, action phase에서만 full tool schema를 준다. 또 HIGH thinking level에서는 critique model이 reasoning trace를 비평하고, thinking model이 이를 반영해 reasoning을 다듬는다. 이 구조는 단순한 “think step by step” 프롬프트보다 훨씬 구조적이다.

이 부분은 Discussion에서도 다시 일반화된다.
저자는 “Separate thinking from action”을 교훈으로 적으면서, 같은 호출 안에서 “신중히 생각하라”고 말하는 것보다, 툴 스키마를 아예 빼서 행동 유혹을 제거하는 것이 더 효과적이었다고 정리한다. 이건 본문, 토론, 결론이 모두 일치하는 내용이다.

또 하나 흥미로운 것은 doom-loop detection이다.
논문은 같은 툴과 같은 인자가 20개 sliding window 안에서 3번 이상 반복되면 경고를 넣고, 이후에도 반복되면 approval-based pause로 올린다. 이건 단순한 반복 횟수 제한보다 훨씬 정교하다. 왜냐하면 실제 agent failure는 “많이 했다”보다 같은 실패를 그대로 재현했다에서 나오기 때문이다. 예를 들어 없는 파일을 계속 읽거나, 같은 edit mismatch를 무한 재시도하는 경우다.

이 설계는 에이전트를 더 똑똑하게 만든다기보다, 바보 같은 실패를 빨리 멈추게 만든다는 점에서 가치가 있다. 실무에서는 후자가 훨씬 중요하다.

이 논문의 진짜 본론: 컨텍스트 엔지니어링

지금까지 구조를 봤다면, 이제 이 논문의 핵심으로 들어가야 한다.
LLM 기반 에이전트의 품질은 결국 모델이 무엇을 볼 수 있느냐에 의해 결정된다고 말한다. 시스템 프롬프트, 이전 대화, 외부 정보, 메모리, 툴 상태, 사용자 질의가 모두 문맥의 일부라는 뜻이다.

논문은 이 레이어를 여섯 개 하위 메커니즘으로 푼다.
동적 시스템 프롬프트 조립, 툴 결과 최적화, dual-memory, system reminders, error recovery, adaptive context compaction, 그리고 마지막 assembly pipeline이다. 즉 컨텍스트 엔지니어링은 단순한 “요약”이 아니라, 어떤 규칙을 넣고, 어떤 출력은 잘라내고, 어떤 기억을 남기고, 어떤 순간에 리마인더를 주고, 마지막에 어떤 순서로 조립할 것인가까지 포함하는 운영 기술이다.

시스템 프롬프트를 “하나의 긴 문서”로 두지 않았는가?

OPENDEV는 시스템 프롬프트를 하나의 거대한 텍스트로 다루지 않는다.
시스템 프롬프트는 독립적인 섹션들로 쪼개져 있고, 각 섹션은 조건(predicate)과 우선순위(priority)를 가진다. 실행 시점에 Prompt Composer가 현재 환경을 보고 섹션을 걸러내고, 우선순위로 정렬하고, 파일을 읽어 합쳐 최종 시스템 프롬프트를 만든다. 다시 말해, 프롬프트는 정적인 지시문이 아니라 상황에 따라 조립되는 컨텍스트 구조물이다.

이게 왜 중요하냐면, 긴 프롬프트의 가장 큰 문제는 길이만이 아니기 때문이다.
논문은 불필요한 지시가 많이 들어가면 두 가지 문제가 생긴다고 본다. 하나는 당연히 토큰을 낭비한다는 점이고, 다른 하나는 더 중요하게도 정말 필요한 규칙의 신호를 희석시킨다는 점이다. 예를 들어 git 저장소가 아닌 디렉터리에서 git workflow 규칙을 계속 싣고 있거나, subagent를 안 쓰는 세션에서 subagent 사용법이 계속 들어가 있으면, 모델은 중요하지 않은 안내까지 같이 떠안게 된다. 그래서 OPENDEV는 “길게 잘 쓰는 프롬프트”보다 적시에 필요한 섹션만 넣는 프롬프트를 택한다.

또 하나 흥미로운 건 provider-specific section이다.
Anthropic, OpenAI, Fireworks처럼 공급자마다 도구 호출 방식, thinking 지원, context window가 다르기 때문에, OPENDEV는 provider별 안내를 서로 배타적인 섹션으로 넣는다. 즉 현재 provider가 Anthropic이면 Anthropic용 section만, OpenAI면 OpenAI용 section만 들어간다. 이건 사소해 보이지만, 실은 매우 중요하다. 왜냐하면 다른 provider의 capability를 잘못 암시하면 모델이 없는 기능을 있는 줄 알고 행동할 수 있기 때문이다. 논문은 unknown provider라면 아무 섹션도 넣지 않는 graceful degradation을 택했다고 말한다.

캐싱 관점에서도 이 설계는 똑똑하다.
Anthropic처럼 prompt caching을 지원하는 provider에서는 stable 부분과 dynamic 부분을 분리하고, stable block에 cache control을 붙인다. 논문은 system prompt가 매 호출마다 다시 전송되므로, 그중 80~90% 정도의 stable 부분을 캐싱하면 입력 토큰 비용을 크게 줄일 수 있다고 설명한다. 즉 Prompt Composer는 단지 프롬프트를 예쁘게 조립하는 도구가 아니라, 행동 제어와 비용 최적화를 동시에 수행하는 장치다.

내가 보기에 핵심은 이것이다.
이 논문은 프롬프트를 “좋은 문장”의 문제가 아니라 로딩 정책의 문제로 본다. 이 관점이 아주 좋다. 실무에서는 프롬프트를 한 번 잘 쓰는 것보다, 언제 어떤 규칙을 빼고 넣을지가 훨씬 중요하기 때문이다.

툴 결과 최적화는 왜 이렇게 중요하게 다뤄졌나?

이 논문에서 현실감이 가장 강하게 느껴지는 부분 중 하나가 Tool Result Optimization이다.
저자는 아주 단순한 사실을 인정한다. 원본 도구 출력은 대체로 가치보다 훨씬 크다. read_file 한 번이면 수천 토큰의 코드가 들어오고, 디렉터리 listing은 수백 개 항목을 뿌릴 수 있고, 테스트 러너는 수천 줄 로그를 찍을 수 있다. 이런 것들을 그대로 conversation history에 넣으면, 모델이 “무엇을 읽었는지”보다 “무엇이 너무 많이 출력됐는지”에 문맥이 잠식된다. 그래서 OPENDEV는 툴 결과를 conversation에 넣기 전에 도구별 요약 규칙으로 먼저 변환한다.

예를 들어 file read는 전체 내용을 다시 싣는 대신 “몇 줄, 몇 글자짜리 파일을 읽었다”는 메타데이터만 남긴다. 검색 결과는 몇 개 match가 있었는지만 남기고, 디렉터리 listing도 item count로 압축한다. 긴 command output은 전부 넣는 대신 line count 위주로 요약한다. 즉 OPENDEV는 conversation history를 사실의 저장소가 아니라 행동 흔적의 색인처럼 다룬다.

그리고 정말 긴 출력은 한 단계 더 나간다.
8,000자를 넘으면 scratch file로 offload하고, conversation에는 500자 preview와 파일 경로만 남긴다. 여기서 핵심은 “정보를 버린다”가 아니라, 저렴한 retrieval 문제로 바꾼다는 점이다. 논문 Discussion도 이걸 아주 분명하게 교훈으로 정리한다. 큰 출력을 계속 들고 다니는 대신 파일시스템에 내려놓고 필요할 때 다시 읽으면, 비용은 한 번의 read_file 호출로 끝나지만, 그대로 문맥에 남겨두면 그 비용을 이후 모든 LLM 호출에서 계속 내야 한다는 것이다.

게다가 recovery hint도 agent-aware하게 설계했다.
subagent를 쓸 수 있는 agent에게는 Code Explorer에 넘기라고 하고, 그렇지 않은 경우에는 offset/limit 기반으로 나눠 읽으라고 안내한다. 이 점이 중요하다. 흔한 에이전트 실패는 “해결 힌트를 줬는데, 그 힌트가 그 에이전트에게는 불가능한 행동”인 경우다. OPENDEV는 이런 종류의 2차 실패를 줄이려 한다.

실무적으로 보면 이 절의 메시지는 매우 단순하다.
도구 출력은 사실 자체보다 압축된 흔적이 더 중요할 때가 많다.
그리고 그 압축이 잘 되면, 에이전트는 훨씬 오래 버틴다.

dual-memory architecture는 왜 설득력 있는가?

OPENDEV의 thinking phase는 full conversation을 전부 들고 가지 않는다.
이를 dual-memory architecture로 설명한다. 하나는 episodic memory다. 전체 대화에서 전략적 의미만 남기는 LLM 요약이다. 다른 하나는 working memory다. 최근 몇 개 교환은 그대로 verbatim으로 들고 간다. 그리고 thinking LLM에는 이 둘과 현재 user query를 함께 준다.

이 구조가 좋은 이유는, 긴 세션에서 딱 두 가지를 동시에 지키려 하기 때문이다.
하나는 “우리가 전체적으로 뭘 하려 했는지”라는 전략적 연속성이고, 다른 하나는 “방금 어느 줄에서 무슨 에러가 났는지”라는 세부 정확성이다.

전략만 남기면 구체적 편집이 틀리고, 최근 내용만 남기면 처음 목표를 잃는다. 논문은 이 둘을 각각 episodic과 working으로 나눠 잡는다. 그리고 요약은 매번 summary of summary를 만들지 않고, 일정 메시지 수가 쌓일 때마다 full history에서 새로 생성한다. 이유는 summary drift 때문이다. 요약을 다시 요약하면 왜곡이 누적되기 때문이다.

이건 인간 비유로도 이해가 쉽다.
멀리 보면 “무엇을 하려는지”는 기억하지만, 바로 직전의 구체적인 line number나 error message는 최근 기억에서 꺼내는 식이다. OPENDEV는 이걸 꽤 솔직하게 시스템 구조로 옮겼다. 요즘 agent memory 담론에서 흔히 나오는 거대한 영구 기억 저장소보다 훨씬 현실적인 접근이다.

여기에 ACE playbook이 붙는다.
플레이북은 자연어 bullet들의 모음인데, 각 bullet에는 helpful/harmful/neutral 효과성 태그와 시간 정보가 있고, BulletSelector가 effectiveness, recency, semantic similarity를 합쳐 상위 항목만 뽑아 현재 프롬프트에 넣는다. 즉 장기기억도 거대한 문서가 아니라 짧은 전략 조각들의 선택적 주입으로 설계되어 있다. 이건 메모리를 환상적으로 부풀리지 않고, 실제로 모델이 소화 가능한 크기의 “조언 묶음”으로 제한한다는 점에서 매우 실용적이다.

왜 system reminder가 이 논문에서 그렇게 중요한가?

저자는 아주 직접적으로 말한다. 긴 세션이 되면 모델은 초기의 system prompt를 점점 덜 따른다. 초반엔 잘 하던 행동, 예를 들어 “편집 후 테스트를 돌려라”, “todo를 다 끝내고 마무리해라” 같은 규칙도 15~20회 이상의 툴 호출 뒤에는 슬그머니 흐려진다. 그래서 OPENDEV는 규칙을 전부 처음에 몰아넣는 대신, 실수하기 직전에 짧은 reminder를 넣는다.

이 리마인더는 여덟 가지 이벤트 감지기에 의해 동작한다.
tool failure without retry, exploration spiral, denied tool re-attempt, incomplete todos at completion, all todos complete, plan approval without follow-through, unprocessed subagent results, empty completion messages 같은 조건이 걸리면, 대응하는 리마인더를 가장 최근 user-role 메시지로 대화에 넣는다. 논문은 이것을 “point of decision”에서의 steering이라고 본다.

여기서 핵심은 role 선택이다.
논문은 실험상 role: system보다 role: user 리마인더가 더 잘 먹혔다고 말한다. 시스템 메시지는 멀리 밀려나 배경화되지만, user message는 “방금 들어온 것”이라 모델이 더 강하게 반응한다는 것이다. 이건 아주 작은 디테일처럼 보이지만, 사실 이 논문의 설계 철학 전체와 맞닿아 있다. 저자는 프롬프트를 길게 잘 쓰는 것보다, 무엇을 언제 가장 가깝게 배치할 것인가를 더 중요하게 본다.

그리고 guardrail counters도 중요하다.
리마인더가 계속 뜨면 오히려 배경 소음이 되기 때문에 incomplete-todo nudges는 최대 두 번, error-recovery nudges는 최대 세 번처럼 예산을 둔다. 즉 OPENDEV는 리마인더도 무한 교정 장치가 아니라 제한된 신호 자원으로 다룬다. 이것도 매우 운영체계적 사고다. 리마인더를 많이 넣는다고 해결되는 게 아니라, 너무 많으면 학습된 무시가 생기기 때문이다.

내 해석으로는, 이 시스템은 “LLM이 규칙을 모른다”가 아니라 규칙을 오래 유지하지 못한다는 사실에서 출발한다. 그리고 그 해결책도 똑같이 운영적이다. 더 긴 규칙이 아니라, 짧고 늦게 들어오는 신호다.

Adaptive Context Compaction이 왜 이 논문의 실무적 핵심인가?

이제 이 논문의 가장 강한 기여라고 볼 수 있는 Adaptive Context Compaction, ACC를 봐야 한다.
논문은 기존 시스템들이 보통 95~99% 근처에서 emergency compaction을 한 번에 돌리는데, 이 방식은 발동이 너무 늦고, 정보 손실이 심하고, 다음 compaction 때 더 큰 왜곡을 낳는다고 비판한다. 그래서 OPENDEV는 context pressure를 매 iteration 시작마다 측정하고, 70/80/85/90/99%의 다섯 단계로 점진적으로 처리한다.

70%에서는 경고만 남긴다.
80%에서는 오래된 tool result를 compact pointer로 바꾸는 observation masking을 한다.
85%에서는 offload조차 하지 않고 오래된 결과를 [pruned]로 지우는 fast pruning이 들어간다.
90%에서는 aggressive masking으로 최근 극소수만 남긴다.
99%에 이르러서야 full compaction을 LLM으로 수행한다. 그리고 이때도 full history를 scratch file에 저장하고, artifact index와 archive path를 summary에 넣어 복구 가능성을 남긴다.

이 구조가 좋은 이유는, compaction을 “마지막 순간의 요약”이 아니라 관찰값의 생애주기 관리로 보기 때문이다. active에서 faded, archived로 내려가는 흐름은 운영체제의 캐시나 메모리 정책과 비슷하다. 무엇보다도, 도구 출력 최적화와 결합될 때 효과가 커진다. 이미 ingestion 단계에서 요약과 오프로딩이 이루어졌기 때문에, 나중에 compaction이 필요해져도 입력이 훨씬 가벼운 상태다.

논문은 이 구조가 observation 기준 peak context consumption을 약 54% 줄였다고 적는다. 그리고 typical 30-turn session에서는 emergency compaction 자체를 피하게 되는 경우가 많았다고 한다. 결론에서도 이 수치를 다시 반복한다. 다만 동시에, 결론은 이 논문이 체계적인 정량 평가를 아직 갖추지 않았다고 인정한다. 따라서 이 54%는 외부 재현이 끝난 결과라기보다, 현재 시스템 설계가 내부적으로 보여준 유망한 지표로 읽는 것이 맞다.

Discussion의 교훈도 이와 일치한다.
저자는 “Treat context as a budget, not a buffer”라고 말한다. 그리고 “Calibrate from API-reported token counts, not local estimates”라는 교훈도 덧붙인다. 즉 로컬에서 세는 토큰 수보다 provider가 실제 응답에서 돌려준 prompt_tokens를 기준으로 관리해야 한다는 것이다. 보이지 않는 provider-side injection이 있기 때문이다. 이 역시 매우 실용적이다.

이 절 전체를 한마디로 요약하면 이렇다.
좋은 코딩 에이전트는 큰 컨텍스트를 버티는 것이 아니라, 중요한 것만 오래 남게 만드는 시스템이다.

Retrieval과 Code Explorer는 왜 별도 파이프라인으로 나왔을까?

저자는 coding agent에서 retrieval이 가장 consequential capability라고 말한다. 왜냐하면 editing, testing, planning 같은 후속 행동의 품질은 결국 처음에 올바른 코드를 찾았는가에 달려 있기 때문이다. 단순 RAG처럼 질의 한 번에 top-k 파일을 뽑는 접근은 코드베이스에는 잘 맞지 않는다고 본다. 실제 코드는 파일 간 참조, 구조, symbol, 설정이 뒤엉켜 있기 때문이다.

그래서 OPENDEV는 retrieval을 네 층으로 본다.
Layer 1은 anchor-based tool selection이다. 질의에서 strongest anchor가 symbol인지, 문자열인지, 구조 패턴인지, 경로 관습인지 판단해 find_symbol, text_search, ast_search, list_files 중 맞는 걸 택한다.
Layer 2는 multi-step agentic search다. broad understanding이 필요하면 Code Explorer subagent로 넘겨, 그 안에서 읽기 전용 도구들로 탐색을 반복하게 한다.
Layer 3은 context assembly다. system prompt, persistent rules, @file, conversation history, reminders, current query를 한 순서로 조립한다.
Layer 4는 context optimization, 즉 staged compaction이다.

여기서 핵심은 Code Explorer의 isolated context다.
탐색 과정에서 쏟아지는 검색 결과와 파일 읽기 결과가 main agent의 사고 공간을 오염시키지 않도록, Code Explorer가 자체 문맥에서 탐색하고 증류된 요약만 main agent에 돌려준다. 이건 정말 중요한 설계다. 대부분의 retrieval 실패는 “못 찾음”보다 너무 많이 찾아서 정작 본체가 판단 못함에서 생기기 때문이다. OPENDEV는 retrieval 과정을 본체 reasoning에서 분리해 이 문제를 줄인다.

도구 시스템은 “많은 기능”보다 “실패를 흡수하는 기능”이 핵심이다

도구 시스템 자체로 넘어가 보자.
OPENDEV는 registry architecture를 택한다. ToolSchemaBuilder가 스키마를 만들고, ToolRegistry가 dispatch를 담당하고, lifecycle hooks가 그 주위를 둘러싼다. static built-in schema, discovered MCP schema, subagent schema가 합쳐져 LLM prompt에 들어가고, dispatch는 category-based handler로 나뉜다. 논문은 이 설계가 flat namespace의 혼란과 unsafe dynamic loading 문제를 줄인다고 본다.

여기서 안전은 다시 한 번 구조적으로 다뤄진다.
approval system은 Manual / Semi-Auto / Auto 세 수준을 제공하지만, 더 중요한 것은 DANGER 규칙이 사용자 설정보다 더 낮은 층에서 강제된다는 점이다. 즉 어떤 규칙은 auto-deny semantics를 가지며, 사용자가 일반적인 승인 레벨을 바꿔도 이를 우회할 수 없다. 그리고 approvals는 user-global, project-local JSON에 지속 저장되어 fatigue를 줄인다. Discussion도 approval persistence가 중요하다고 강조한다. 같은 명령을 세션마다 다시 승인받게 하면 결국 사용자는 blanket auto-approve로 가버리기 때문이다.

파일 도구는 특히 흥미롭다.
edit_file은 9-pass fuzzy matching chain을 둔다. exact match, whitespace normalization, indentation flexibility, context-aware anchor matching 등 단계별로 완화를 시도하고, 매칭에 성공하면 실제 파일 안 substring을 반환해 원래 포맷을 보존한다. Discussion의 표현대로, 이건 “모델이 정확한 literal output을 항상 내리라”를 기대하지 않고, 도구가 LLM의 approximate output을 흡수하도록 설계한 사례다.

shell execution도 비슷하다.
run_command는 safety gates, command preparation, server detection, execution fork, output management, timeout handling으로 이루어진 6-stage pipeline을 갖는다. server-like command는 background로 자동 승격하고, PTY 기반으로 출력 스트리밍을 유지한다. 이는 기능 자체보다 잘 걸리고, 잘 멈추고, 잘 지켜본다는 점이 핵심이다. 단순히 명령을 실행할 줄 아는 것과, 장시간 실행 작업을 agent workflow 안에서 안전하게 다루는 것은 전혀 다른 문제라는 것을 보여준다.

MCP 부분도 마찬가지다.
논문은 external tools를 모두 처음부터 schema에 넣으면 문맥의 40%까지 먹을 수 있다고 본다. 그래서 search_tools를 통해 keyword-based lazy discovery를 하고, 발견된 도구만 다음 LLM call부터 schema에 넣는다. 즉 extensibility 역시 capability-first가 아니라 token-efficient extensibility로 설계된다.

persistence는 왜 소박하지만 강한가

이 논문은 persistence를 아주 요란하게 다루지 않지만, 사실 production readiness를 가장 잘 보여주는 장이기도 하다.
세션은 metadata JSON과 transcript JSONL로 분리 저장된다. session listing을 빠르게 하기 위한 index도 따로 두고, index가 망가지면 다시 rebuild하는 self-healing 구조를 둔다. cost tracking도 세션 메타데이터에 저장되어, --continue로 이어갈 때 이전 토큰 사용량과 비용이 복원된다.

undo는 두 겹이다.
하나는 in-memory operation log로, 최근 create/modify/delete를 되돌리는 빠른 undo다. 다른 하나는 더 흥미로운 shadow git snapshots다. 셸 명령이나 빌드가 일으킨 부수효과까지 되돌릴 수 있도록, 사용자 저장소와 별개의 bare repository를 shadow로 두고 tree hash를 남긴다. 그러면 /undo는 실제 git history를 건드리지 않으면서도 파일 레벨 복원을 할 수 있다. Discussion과 conclusion도 이 설계를 layered architecture의 확장성 사례로 다시 언급한다.

에이전트의 실전성은 “정답을 잘 맞히는가”뿐 아니라, 실수했을 때 빠르게 되돌릴 수 있는가에 달려 있다. OPENDEV는 그 점을 정확히 짚는다.

Discussion은 이 논문의 요약이 아니라, 사실상 설계 원리의 압축본이다

가장 좋은 교훈은 두 가지다.
하나는 context를 buffer가 아니라 budget으로 다뤄라는 것.
다른 하나는 unsafe tools는 block하지 말고 invisible하게 만들어라는 것이다.
이 둘이 사실 OPENDEV 철학의 중심이다. 앞자는 문맥 관리의 원리이고, 뒤는 안전 관리의 원리다. 그리고 approximate outputs를 흡수하도록 도구를 설계하라는 점까지 합치면, 이 논문은 agent engineering의 본질을 꽤 잘 잡아낸다.

특히 “context engineering 2.0”과 연결하는 related work 부분도 흥미롭다.
논문은 OPENDEV의 구조가 retrieval, processing, management라는 context engineering taxonomy와 직접 맞물린다고 설명한다. staged compaction은 entropy reduction, system reminders는 semantic continuity를 구현하는 사례로 해석된다. 즉 저자는 OPENDEV를 단순 구현체가 아니라, 컨텍스트 엔지니어링 이론의 한 사례로 위치시키려 한다.

이 논문의 한계와, 그럼에도 불구하고 왜 가치가 큰가?

이 논문은 분명히 강한 설계 문서지만, 약점도 분명하다.
가장 큰 약점은 정량 평가 부족이다. 결론부는 이를 숨기지 않는다. SWE-bench, Terminal-Bench, LongCLI-Bench 위에서 체계적이고 비교 가능한 검증이 아직 없다고 직접 인정한다. 즉 이 논문은 “이 구조가 더 낫다”는 강한 성능 주장보다, 이 구조가 왜 필요했는지에 대한 설계 근거를 제공하는 쪽에 가깝다.

또 문서 정합성에서도 약간의 흔들림이 있다.
앞서 본 Planner 서브에이전트의 read-only 여부, built-in tool 수에 대한 본문과 부록의 차이 같은 부분은, 구현이 발전하는 속도에 문서가 완전히 따라가지 못했음을 보여준다. 연구 논문으로 보면 아쉬운 지점이지만, 반대로 말하면 이것이 아주 polished한 benchmark paper가 아니라 실제 제품을 만드는 과정에서 나온 보고서라는 점을 드러내기도 한다.

그럼에도 이 논문의 가치는 높다.
이유는 간단하다. 코딩 에이전트 분야에서 많은 글이 “얼마나 잘 푸는가”에 집중하는 반면, 이 논문은 왜 에이전트가 오래 못 버티는가, 왜 잘못된 도구를 반복 호출하는가, 왜 system prompt를 잊어버리는가, 왜 안전은 권한 체크만으로 부족한가를 아주 구체적으로 다룬다. 즉 실패의 원인을 운영 수준에서 해부한다. 이건 실무적으로 매우 큰 가치가 있다.

마지막 정리

이 시스템의 본질은 “터미널에서 돌아가는 코딩 에이전트”가 아니다.
정확히는, 긴 세션을 버티고, 큰 출력을 흘려보내고, 위험한 행동을 구조적으로 감추고, 필요할 때만 기억을 꺼내고, 잊기 직전에 규칙을 다시 주입하는 운영체계다.

이 논문이 정말 말하고 싶은 것은 아마 이것일 것이다.
코딩 에이전트의 미래는 단순히 더 똑똑한 모델을 붙이는 데 있지 않다.
오히려

무엇을 보게 할지,
무엇을 못 하게 할지,
무엇을 잊지 않게 할지,
실수했을 때 어떻게 복구할지

를 구조적으로 설계하는 데 있다.
OPENDEV는 그 점에서 “좋은 데모”보다 훨씬 가치 있어 보인다.
완벽하게 검증된 정답은 아니지만, 터미널형 AI 코딩 에이전트를 실제로 만들려는 사람에게 매우 실용적인 설계 지도를 제공한다.

해당 논문의 구현체인 OPENDEV에 관심이 있으신 분은 https://github.com/opendev-to/opendev 여기를 참고해보세요.


Share:

잠깐, 글이 유익했나요?

Donate!

0 Comments:

댓글 쓰기