포스트

AI 개발의 rework tax: 컨텍스트를 잃을 때마다 다시 내는 비용

AI가 컨텍스트를 잃었을 때 같은 작업을 다시 시키는 비용을 rework tax로 정의하고, 규격화·관계 기반 탐색·영속 저장소로 이 비용을 줄이는 방법과 그 끝에서 개발자가 남게 될 자리를 정리한다.

AI 개발의 rework tax: 컨텍스트를 잃을 때마다 다시 내는 비용

저는 요즘 claude code, codex 가 없으면 개발을 전혀 못하는 수준까지 이르렀는데요, 이렇게 AI Agent를 활용해 개발하다 보면 어제 같이 논의하던 코드를 오늘 AI 에게 수정하라고 명령하면 이 함수와 클래스를 처음부터 다시 분석합니다.

결국 어제 얘기했던 그 세션은 AI Agent 에게는 다른 차원의 얘기였기 때문에 코드 분석 비용을 처음부터 다시 지불해야하죠.

저는 이걸 rework tax라고 부르기로 했습니다. AI가 컨텍스트를 잃었을 때, 같은 수준의 작업을 다시 수행하기 위해 치러야 하는 비용입니다. 토큰과 시간뿐 아니라, 잘못 복원된 컨텍스트 때문에 생긴 오류를 사람이 되돌리는 시간까지 포함합니다.

이 글은 그 세금이 어디서 발생하는지, 어떻게 줄일 수 있는지, 그리고 그 세금이 0에 가까워지면 개발자에게 무슨 일이 일어나는지에 대한 제 중간 정리입니다.

필자는 rework tax를 업계 표준 용어로 생각하지 않습니다, 아래에서 인용하는 연구들도 “rework tax”를 직접 측정한 것은 아니고, 각자 다른 지표를 측정했습니다. 서로 다른 관측을 하나의 프레임으로 묶은 것은 제 해석입니다.


1. 체감보다 큰 비용이라는 신호들

먼저 확인해 볼 것은 이게 저만의 착각인가입니다. 공개된 연구를 보면 몇 가지 신호가 있습니다.

METR은 2025년에 경험 많은 오픈소스 기여자를 대상으로 무작위 대조 실험을 했습니다. 개발자 16명, 실제 이슈 246건이었고, AI 도구 사용이 허용된 조건에서 작업 완료 시간이 19% 더 길었습니다. 흥미로운 건 인식 차이입니다. 참가자들은 실험이 끝난 뒤에도 AI가 자신을 20% 정도 빠르게 해 줬다고 평가했습니다. 연구진은 느려진 이유의 후보로 프롬프트 작성, 생성 결과 검토, 통합 과정의 마찰을 들었습니다. (METR)

다만 이 결과의 범위는 좁게 봐야 합니다. 연구진 스스로 “AI가 대부분의 개발자에게 도움이 되지 않는다는 증거는 아니다”라고 명시했고, 대상은 자신이 오래 관리해 온 대형 저장소에서 높은 품질 기준으로 작업하는 숙련자였습니다. 신규 프로젝트나 익숙하지 않은 코드에서는 다른 결과가 나올 수 있습니다.

DORA의 2025년 보고서는 다른 각도에서 같은 곳을 가리킵니다. 응답자의 90%가 업무에 AI를 사용하고 80% 이상이 생산성이 올랐다고 답했지만, 30%는 AI가 생성한 코드를 거의 또는 전혀 신뢰하지 않는다고 답했습니다. 보고서는 AI 도입이 처리량과는 긍정적 관계를, 배포 안정성과는 부정적 관계를 유지한다고 정리합니다. 그리고 그 이유를 이렇게 설명하죠. 강한 자동화 테스트와 빠른 피드백 루프 같은 통제 장치 없이 변경량만 늘어나면 불안정성이 커진다고요. (DORA 2025, Google Cloud 발표 글)

GitClear는 2020년부터 2024년까지 2억 1,100만 줄의 변경 데이터를 분석했습니다. 복사·붙여넣기로 분류된 줄의 비중이 8.3%에서 12.3%로 올랐고, 리팩터링으로 분류된 줄은 24.1%에서 9.5%로 떨어졌습니다. (GitClear 2025 리포트)

이 세 자료는 서로 다른 것을 측정했습니다. 그런데 제가 보기에 한 방향을 가리킵니다. AI는 새 코드를 만드는 데는 강하지만, 이미 있는 코드의 맥락 위에 얹는 데는 약하다는 것입니다. 기존 구현을 찾아 재사용하는 대신 비슷한 코드를 다시 만들고, 어제의 결정을 이어받는 대신 다시 결정합니다.

그게 rework tax입니다. 그리고 이 세금은 코드베이스가 커질수록, 기능이 오래될수록 비싸집니다.


2. 컨텍스트는 세 가지 경로로 사라진다

이러한 비용을 줄이려면 AI가 컨텍스트를 잃는 경로를 먼저 파악해봐야합니다, 크게 세 가지로 나뉘는 것으로 보여지는데요.

2-1 세션 경계에서 사라진다

가장 단순한 경우입니다. 대화가 끝나면 그 안의 결정은 남지 않습니다. 요약(compaction)을 거치면 일부는 남지만, 무엇을 남기고 무엇을 버릴지는 요약 시점의 판단에 달려 있습니다. Anthropic도 compaction의 핵심을 “무엇을 유지하고 무엇을 버릴지 고르는 일”로 설명합니다. (Effective context engineering for AI agents)

2-2 컨텍스트 창 안에서도 흐려진다

컨텍스트 창에 넣기만 하면 안전한 것도 아닙니다. Chroma는 18개 모델을 대상으로 입력 길이가 늘어날 때 성능이 어떻게 변하는지 측정했고, 단순한 과제에서도 입력이 길어지면 성능이 유의미하게 달라진다고 보고했습니다. 특히 찾아야 할 정보와 질문의 의미적 거리가 멀수록, 주제가 비슷한 오답이 섞여 있을수록 저하가 커졌습니다. (Context Rot)

즉 저장소 전체를 프롬프트에 넣는 방식은 컨텍스트 손실의 해결책이 아닙니다. 손실 지점을 세션 경계에서 컨텍스트 창 내부로 옮길 뿐이죠. 이 부분은 이전 글에서 Lost in the Middle 연구와 함께 다뤘습니다.

2-3 애초에 어디에도 적혀 있지 않다

가장 비싼 경우입니다. “왜 이 값을 프로세스 종료 후에도 복원해야 하는가”, “왜 이 API는 재시도하면 안 되는가” 같은 정보가 코드 어디에도 없다면, AI는 컨텍스트를 잃은 게 아니라 처음부터 가진 적이 없습니다. 이건 새 세션에서 복원 불가능합니다. 사람이 매번 다시 넣어 주는 수밖에 없죠.

정리하면 rework tax는 이렇게 구성됩니다.

구성 요소발생 지점비용의 형태
재탐색 비용관련 파일을 다시 찾음입력 토큰, 도구 호출 횟수, 지연 시간
재설명 비용사람이 규칙을 다시 설명사람의 시간, 프롬프트 길이
오복원 비용잘못 추측한 맥락으로 코드 생성리뷰 시간, 재작업, 운영 장애

앞의 두 개는 눈에 보여서 그나마 낫습니다. 문제는 세 번째죠. 컴파일도 되고 테스트도 통과하는데 어제의 결정과 다른 코드가 들어옵니다.


3. rework tax 를 줄이는 방법

①: 컨텍스트를 기억이 아니라 규격으로 만든다

첫 번째 방향은 코드 구조화입니다. 다만 목적을 조금 다르게 잡아야 합니다. 지금까지 구조화는 사람의 유지보수를 위한 투자였습니다. rework tax 관점에서 구조화의 목적은 하나 더 생깁니다.

AI가 컨텍스트를 잃어도 코드만 보고 복원할 수 있게 만드는 것입니다.

예를 들어 화면을 만들 때마다 아래 형태를 지키기로 정해 두면,

1
2
3
4
5
@Composable
fun CheckoutScreen(
    state: CheckoutUiState,
    onEvent: (CheckoutEvent) -> Unit,
)

AI는 “이 프로젝트에서 화면은 상태를 렌더링하고 이벤트만 위로 보낸다”는 규칙을 대화에서 기억할 필요가 없습니다. 아무 화면 파일 하나만 열어도 규격이 보이니까요. 상태 조합도 마찬가지입니다. sealed interface로 가능한 상태를 미리 정해 두면(그 밖의 상태는 표현 자체가 어려워지는 타입입니다) “로딩과 성공이 동시에 참일 수 없다”를 프롬프트에 다시 쓰지 않아도 됩니다.

이 방향의 세부 내용은 AI 시대에 Android 코드 구조화가 더 중요해진 이유에서 다뤘으니 여기서는 rework tax와의 연결만 짚겠습니다.

  • 규격이 있으면 재탐색 범위가 좁아집니다. 읽을 파일이 정해져 있으니까요.
  • 규격이 타입으로 표현되면 재설명이 줄어듭니다. 컴파일러가 대신 말해 줍니다.
  • 규격을 어긴 결과는 빌드에서 멈춥니다. 오복원 비용이 리뷰 단계 앞으로 당겨집니다.

물론 규격이 강해질수록 새 요구사항을 넣는 비용도 커집니다. 모든 화면을 상태 머신(상태·이벤트·전이 규칙을 명시적으로 관리하는 구조)으로 만들면 비즈니스 로직보다 구조 유지 코드가 많아질 수 있죠. 저는 틀리면 비싼 규칙에만 규격을 세우는 편이 맞다고 봅니다.


②: 관계를 검색 대상으로 만든다

두 번째는 탐색 방식입니다.

AI 에이전트가 코드를 찾는 기본 방법은 파일 이름과 텍스트 검색입니다. 그런데 실제로 필요한 질문은 대부분 관계에 대한 것이죠. “이 함수를 누가 호출하는가”, “이 타입을 바꾸면 어디까지 깨지는가”, “이 Repository의 실제 구현은 어디인가” 같은 것들입니다.

이 질문에 grep으로 답하려면 여러 번 검색하고 결과를 읽어야 합니다. 매 세션마다 반복되죠. 재탐색 비용이 가장 크게 쌓이는 지점입니다.

그래서 코드베이스를 한 번 파싱해 호출·참조 관계를 그래프로 저장해 두고, 에이전트가 MCP(Model Context Protocol, AI 도구가 외부 기능을 호출하는 표준 인터페이스)로 질의하게 하는 도구들이 나오고 있습니다. Tree-sitter나 LSP로 심볼과 참조를 뽑아 SQLite 같은 저장소에 넣고, “이 심볼의 호출자”나 “변경 영향 범위”를 한 번의 도구 호출로 돌려주는 방식입니다. code-review-graphCodeGraphContext 같은 프로젝트가 이 범주에 있고, Aider의 repo map처럼 CLI 안에 내장된 가벼운 형태도 있습니다.

이 도구들이 내세우는 토큰 절감 배수는 저장소 특성에 따라 달라질 수 있고, 대부분 도구를 만든 쪽이 자체 측정한 수치입니다. 저는 그 숫자보다 방향이 중요하다고 봅니다. 관계를 매번 추론하지 말고 한 번 계산해서 재사용한다는 것이죠.

대신 이 방식에는 유지 비용이 붙습니다.

  • 인덱스가 코드 변경을 따라가지 못하면 오래된 정보를 확신 있게 답해 버립니다. 컨텍스트 손실보다 나쁠 수 있습니다.
  • 언어와 빌드 시스템에 따라 관계 추출 정확도가 다릅니다. Kotlin은 컴파일러 플러그인, Compose, DI 프레임워크가 만들어 내는 연결이 많아서 정적 파싱만으로는 놓치는 경로가 생깁니다.
  • 그래프가 있어도 “왜 이렇게 연결했는가”는 답하지 못합니다. 구조는 알려주지만 의도는 알려주지 않죠.

그래서 이건 세 번째 방향과 짝을 이뤄야 합니다.


③: 애초에 컨텍스트를 잃지 않게 만든다.

세 번째는 영속 저장소입니다. 흔히 second brain이나 LLM wiki라고 부르는 그것이죠.

가장 가벼운 형태는 저장소 루트의 지침 파일입니다. AGENTS.md는 2025년 8월 OpenAI 주도로 공개 스펙이 되었고, 12월에 Linux Foundation 산하 재단으로 이관되었습니다. 2025년 12월 기준 6만 개 이상의 오픈소스 프로젝트가 채택했다고 합니다. (agents.md)

효과를 측정한 연구도 있습니다. 저장소 10개, PR 124건을 대상으로 AGENTS.md 유무를 비교한 실험에서 중앙값 실행 시간이 28.64%, 출력 토큰이 16.58% 줄었고 과제 완료율은 비슷했다고 보고합니다. (arXiv:2601.20404) 표본이 크지는 않지만, 같은 정보를 매 세션 다시 만들어 내는 비용이 실재한다는 방증으로는 충분해 보입니다.

지침 파일보다 더 나아간 형태도 있습니다. Anthropic은 긴 작업을 다루는 세 가지 기법으로 compaction, structured note-taking, sub-agent 구조를 제시합니다. 그중 structured note-taking이 여기에 해당하죠. 에이전트가 진행 상황과 결정을 컨텍스트 밖 파일에 적어 두고 필요할 때 다시 읽는 방식입니다. (Anthropic) Letta처럼 메모리 계층 자체를 제품으로 만든 시도도 있습니다. (Letta)

이 블로그 저장소도 작게나마 같은 구조를 씁니다. 루트의 AGENTS.md가 글 작성 규칙과 검증 명령을 담고, docs/reference/ 아래에 문체 원칙과 기술 주장 기준을 나눠 뒀습니다. 새 세션에서 글을 쓸 때 “이 블로그는 존댓말을 쓰고 근거 없는 생산성 수치를 만들지 않는다”를 다시 설명하지 않아도 되는 정도의 효과는 확인했습니다.

다만 여기서 한 가지는 분명히 해야 합니다. 문서는 낡습니다. 코드가 바뀌어도 문서는 조용히 그대로 남습니다. 그래서 저는 영속 저장소를 하나로 보지 않고 신뢰 등급을 나눠서 봅니다.

계층예시검증 방식낡았을 때
실행되는 컨텍스트타입, 테스트, Lint 규칙빌드가 자동 검사빌드가 깨져서 드러남
규격 문서AGENTS.md, 아키텍처 결정 기록사람이 주기적으로 갱신조용히 틀린 채로 남음
세션 메모작업 노트, 진행 상황갱신 안 됨다음 작업을 오염시킴

우선순위는 위에서 아래입니다. 규칙을 타입이나 테스트로 표현할 수 있다면 문서에 쓰지 말고 코드에 넣는 게 낫습니다. 문서에는 코드로 표현할 수 없는 것만 남기는 거죠. 왜 이 선택을 했는지, 무엇을 시도했다가 되돌렸는지, 어떤 제약이 외부에서 왔는지 같은 것들입니다.

Android로 옮기면 이렇게 되겠습니다.

  • 화면 상태 조합 규칙 → sealed interface로 표현 (실행되는 컨텍스트)
  • 프로세스 종료 후 복원해야 하는 값 → SavedStateHandle 사용과 복원 테스트 (실행되는 컨텍스트)
  • 이 기능이 왜 WorkManager 대신 Foreground Service를 쓰는지 → 결정 기록 (규격 문서)
  • 지난주에 시도했다가 되돌린 마이그레이션 방식 → 작업 노트 (세션 메모)

6. rework tax가 0에 수렴하면 무슨 일이 생기나

여기까지가 방법론입니다. 그런데 이 세 가지가 다 잘 되면 어떻게 될까요.

규격이 충분히 강해서 AI가 코드만 보고 규칙을 복원할 수 있고, 관계 그래프가 정확해서 영향 범위를 한 번에 알 수 있고, 영속 저장소가 의도까지 담고 있다면. 그러면 AI가 컨텍스트를 잃어도 손해가 거의 없습니다. 컨텍스트를 잃는 것이 문제가 아닌 상태가 되죠.

그 상태에서는 사람이 매 작업마다 개입할 이유가 줄어듭니다. 코드 생산과 유지보수가 사람 없이 돌아가는 구간이 늘어난다는 뜻입니다.

솔직히 말하면 저는 그런 미래를 바라지 않습니다. 코드를 직접 설계하고 예외케이스를 생각해내는게 재밌어서 이 일을 하고 있으니까요. 그런데 rework tax를 줄이는 일이 지금 당장 제 작업을 편하게 만드는 것도 사실입니다. 저는 제가 원하지 않는 방향으로 매일 조금씩 밀고 있는 셈이죠.

피할 수 있는 흐름 같지도 않습니다. 그래서 질문을 바꿔야 했습니다. 이 흐름을 막을 방법이 아니라, 그 안에서 제 자리가 제 미래가 어떻게 하면 보장받을 수 있을지요. 결국 밥그릇 싸움인거죠…


7. 왜 설계 공부가 답인지, 이제야 말이 된다

Android 개발자로서 저는 막연히 이렇게 생각해 왔습니다. 생명주기, 화면 재생성, 프로세스 종료, DB 마이그레이션처럼 예외적인 케이스와 설계에 대한 기반을 쌓으면 오래 살아남을 거라고요.

그런데 이 논리는 약합니다. “AI가 아직 못 하니까”에 기대고 있으니까요. 못 하는 범위는 계속 줄어듭니다. 실제로 AI 시대에 필요한 역량으로 시스템 설계와 판단을 꼽는 글은 많지만, 대부분 “AI가 실행은 잘하는데 판단은 못 한다”는 관찰에서 멈춥니다. 그 경계가 왜 안정적인지는 잘 설명하지 못하죠.

rework tax를 정리하면서 조금 다른 연결고리를 찾았습니다.

설계란 컨텍스트를 복원 가능한 형태로 코드에 새겨 넣는 일입니다.

앞의 세 가지 방법을 다시 보면 전부 같은 작업이었습니다. 어떤 상태가 존재해도 되는지 정하는 것, 어떤 경계 밖으로는 의존이 나가면 안 되는지 정하는 것, 무엇을 타입으로 강제하고 무엇을 문서로 남길지 정하는 것. 이게 전부 설계입니다.

그리고 이 작업의 입력은 코드베이스 안에 없습니다. 도메인, 사용자, 운영 제약, 실패했을 때 누가 얼마나 곤란해지는지에서 옵니다. 프로세스 종료 후 복원해야 하는 값이 무엇인지는 Android 문서가 알려주지 않습니다. “결제 진행 중에 앱이 죽으면 사용자가 돈을 두 번 낼 수 있다”를 아는 사람이 정합니다.

그래서 제가 내린 잠정 결론은 이렇습니다. 설계 공부가 중요한 이유는 AI가 설계를 못 해서가 아닙니다. rework tax를 줄이는 일 자체가 설계이고, 그 일의 입력값을 가진 사람이 아직 사람이기 때문입니다. AI가 코드를 아무리 잘 만들어도, 무엇을 존재하지 못하게 만들지는 누군가 정해야 합니다.

Android의 예외 케이스들이 여기서 다시 의미를 갖습니다. 생명주기와 프로세스 종료는 그 자체로 어려운 지식이라기보다, 코드에 적혀 있지 않으면 AI가 절대 알 수 없는 컨텍스트의 대표적인 예입니다. 화면 회전으로 ViewModel이 살아남는 건 프레임워크가 알려주지만, 이 값이 회전 후에도 남아야 하는지 아닌지는 기능을 아는 사람만 압니다. 그걸 SavedStateHandle과 테스트로 옮겨 적는 순간, 그 지식은 사람의 머릿속에서 저장소로 이동합니다.

그 이동을 잘하는 사람이 rework tax를 낮추는 사람이고, 저는 당분간 그쪽을 연습하려고 합니다.


다음에 해볼 것

거창한 결론보다는 측정부터 해 보려 합니다. rework tax는 아직 제가 만든 이름일 뿐이고, 실제로 얼마인지 세어 본 적이 없으니까요.

  • 어제 하던 작업을 새 세션에서 다시 시켰을 때, AI가 몇 개의 파일을 다시 열고 몇 번의 검색을 하는지 세어 보기
  • 그 파일들 중에 AGENTS.md나 타입으로 대체할 수 있었던 게 몇 개인지 보기
  • 프롬프트에 반복해서 쓰고 있는 문장을 찾아, 그게 코드로 표현 가능한 규칙인지 판단하기
  • 반복되는 규칙 중 하나만 골라 타입이나 테스트로 옮기고, 같은 작업을 다시 요청해 비교하기

개인적으로 세 번째가 제일 유용하더라고요. 같은 설명을 세 번 이상 쓰고 있다면, 그건 프롬프트에 있을 게 아니라 코드에 있어야 하는 규칙일 가능성이 높습니다.

관련해서 다양한 의견이 있을 것 같은데 언제든 댓글 환영합니다, 긴 글 읽어주셔서 감사합니다.

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.