AI Sparkup

복잡한 AI 세상을 읽는 힘 ⚡

AI 코딩 도구가 쓸모없다고? 30만 라인 코드베이스에서 작동하는 비밀

현재 AI 코딩 도구로 실제 대규모 프로덕션 코드베이스에서 성과를 내려면 ‘빈번한 의도적 압축(Frequent Intentional Compaction)’ 워크플로우가 핵심이다. 단순 채팅을 넘어선 체계적 접근법이 필요하다.

대부분의 개발자들은 AI 코딩 도구에 대해 비슷한 불만을 토로합니다. “너무 많은 쓸모없는 코드(slop)를 만들어낸다”, “기술부채 공장이다”, “대규모 저장소에서는 작동하지 않는다”, “복잡한 시스템에는 맞지 않는다”

스탠포드 연구진이 10만 명의 개발자를 대상으로 진행한 분석에서도 이런 문제점들이 확인됩니다. AI 도구들이 생성한 “추가 코드”의 상당 부분이 결국 지난주에 만들어낸 쓸모없는 코드를 다시 작업하는 데 쓰인다는 것이죠. 새로운 프로젝트나 작은 변경 사항에는 유용하지만, 대규모 기존 코드베이스에서는 오히려 개발자들의 생산성을 떨어뜨린다는 결론입니다.

스탠포드 연구에서 나타난 AI 도구 사용 후 재작업 증가 현상

하지만 정말 “언젠가 더 똑똑한 모델이 나오면” 기다려야 할까요? 이 글에서 소개하는 내용은 HumanLayer의 엔지니어링 팀이 실제로 검증한 방법론을 바탕으로 하고 있습니다. 그들은 현재 모델로도 30만 라인의 Rust 코드베이스에서 성공적으로 작업하고, 하루에 일주일치 작업을 완료하며, 전문가 검토를 통과하는 코드 품질을 유지했습니다.

기존 방식의 한계: “바이브 코딩”의 문제점

대부분 사람들이 AI 코딩 에이전트를 사용하는 방식은 마치 챗봇과 대화하는 것과 같습니다. 문제에 대해 앞뒤로 채팅하면서 해결책을 찾아가다가 결국 컨텍스트가 가득 차거나, 포기하거나, 에이전트가 사과하기 시작하는 지점에 도달하게 되죠.

조금 더 영리한 방법은 잘못된 방향으로 갔을 때 세션을 버리고 새로 시작하는 것입니다. 하지만 이것도 근본적인 해결책은 아닙니다.

Sean Grove는 AI Engineer 2025에서 우리가 모두 “잘못된 바이브 코딩”을 하고 있다고 지적했습니다. AI 에이전트와 두 시간 동안 채팅해서 원하는 것을 명시하고, 모든 프롬프트는 버리고 최종 코드만 커밋하는 방식은 마치 자바 개발자가 JAR을 컴파일하고 바이너리만 체크인하면서 소스는 버리는 것과 같다는 것입니다.

컨텍스트 엔지니어링의 핵심 원리

LLM은 상태가 없는 함수입니다. 컨텍스트 윈도우가 들어가면 다음 스텝이 나오는 구조죠. 이는 코딩 에이전트를 다룰 때도 마찬가지입니다. 어떤 시점에서든 Claude Code 같은 에이전트의 한 턴은 상태가 없는 함수 호출입니다.

따라서 출력의 품질에 영향을 줄 수 있는 유일한 레버는 입력의 품질, 즉 컨텍스트 윈도우의 내용입니다. 컨텍스트 윈도우는 다음 기준으로 최적화해야 합니다.

정확성 – 잘못된 정보가 가장 치명적입니다.
완전성 – 빠진 정보가 두 번째로 문제가 됩니다.
크기 – 너무 많은 노이즈가 세 번째 문제입니다.
방향성 – 올바른 궤도에서 진행되고 있는지 확인해야 합니다.

의도적 압축(Intentional Compaction)이란?

컨텍스트 윈도우를 채우는 것들을 살펴보면 파일 검색, 코드 플로우 이해, 수정 적용, 테스트/빌드 로그, 도구에서 나오는 거대한 JSON 블롭 등이 있습니다. 이 모든 것들이 컨텍스트 윈도우를 가득 채울 수 있습니다.

“압축”은 단순히 이런 것들을 구조화된 결과물로 정제하는 과정입니다. 컨텍스트가 가득 차기 시작할 때, 작업을 멈추고 새로운 컨텍스트 윈도우로 시작하면서 다음과 같은 프롬프트를 사용할 수 있습니다.

“지금까지 우리가 한 모든 것을 progress.md에 작성해주세요. 최종 목표, 우리가 취하고 있는 접근법, 지금까지 완료한 단계들, 그리고 현재 해결하고 있는 문제를 포함해서 기록해주세요.”

좋은 의도적 압축의 결과물은 다음과 같은 내용을 포함해야 합니다.

목표: 무엇을 달성하려고 하는가
접근법: 어떻게 해결하려고 하는가
진행 상황: 지금까지 무엇을 했는가
현재 상태: 지금 어디서 막혔는가
다음 단계: 무엇을 해야 하는가

체계적 접근: 연구-계획-구현 워크플로우

앞서 설명한 의도적 압축을 단발성으로 하는 것이 아니라, 개발 과정 전체에 체계적으로 적용하는 방법이 있습니다. HumanLayer 팀이 “빈번한 의도적 압축”이라고 부르는 기법입니다.

핵심 아이디어는 간단합니다. 컨텍스트 윈도우가 가득 찰 때까지 기다리지 말고, 미리미리 압축하자는 것입니다. 컨텍스트 활용도를 40-60% 선에서 유지하면서 정보가 너무 많아지기 전에 정리하는 방식이죠. 마치 책상이 완전히 어수선해질 때까지 기다리지 말고, 적당히 정리하면서 일하는 것과 비슷합니다.

이 방식은 크게 세 단계로 나뉩니다. 때로는 연구 단계를 건너뛰고 바로 계획으로 가기도 하고, 구현 준비가 되기 전에 압축된 연구를 여러 번 거치기도 합니다.

1단계: 연구 (Research) – “무엇이 어떻게 돌아가는가?”

이 단계는 마치 새로운 회사에 첫 출근해서 업무 파악을 하는 것과 같습니다. 코드베이스라는 거대한 미로에서 길을 찾기 전에 먼저 지도를 그려보는 과정이죠.

예를 들어 “로그인이 안 된다”는 버그를 고쳐야 한다면, AI에게 이렇게 요청합니다. “로그인 관련 코드를 모두 찾아서 어떤 파일들이 관련되어 있는지, 사용자가 로그인 버튼을 눌렀을 때 어떤 순서로 코드가 실행되는지 정리해줘”

연구 단계가 끝나면 이런 내용이 나와야 합니다.

  • 핵심 파일들: auth.js, login-form.jsx, user-service.py 등이 관련됨
  • 실행 흐름: 버튼 클릭 → 폼 검증 → API 호출 → 토큰 저장 → 페이지 리다이렉트
  • 문제 지점: API 응답이 예상과 다른 형태로 와서 파싱에 실패하는 것 같음
  • 의존성: 로그인 기능이 알림 시스템과 연결되어 있어서 함께 테스트해야 함

2단계: 계획 (Plan) – “정확히 무엇을 어떻게 고칠 것인가?”

이제 구체적인 수술 계획을 세우는 단계입니다. 의사가 수술 전에 어떤 순서로 어떤 절차를 거칠지 미리 계획하는 것처럼요.

같은 로그인 버그 예시로 보면, 계획은 이렇게 나와야 합니다.

1단계: user-service.py의 login 함수에서 반환하는 JSON 구조 확인

  • 현재 코드 확인: 어떤 필드를 반환하는지 보기
  • 문제 파악: 프론트엔드가 기대하는 필드명과 다른지 확인
  • 테스트: curl로 실제 API 응답 확인해보기

2단계: 필드명이 다르다면 백엔드를 고칠지 프론트엔드를 고칠지 결정

  • 다른 곳에서도 이 API를 쓰는지 확인 (영향도 분석)
  • 더 안전한 쪽을 선택

3단계: 선택된 파일 수정

  • auth.js의 32번째 줄에서 response.user_id 대신 response.userId 사용
  • 수정 전후 코드 비교해서 다른 곳에 영향 없는지 확인

4단계: 테스트

  • 로그인 성공 케이스 테스트
  • 로그인 실패 케이스 테스트
  • 알림 기능도 같이 잘 작동하는지 확인

3단계: 구현 (Implement) – “계획대로 실행하기”

이제 계획을 하나씩 따라가면서 실제로 코드를 고치는 단계입니다. 여기서 중요한 것은 계획에서 벗어나지 않는 것입니다.

AI에게 “위의 계획 1단계를 실행해줘”라고 말하면, AI가 user-service.py 파일을 열어서 JSON 구조를 확인해줍니다. 그 결과를 보고 “좋아, 이제 2단계 실행해줘”하고 진행하는 방식입니다.

만약 중간에 예상과 다른 상황이 생기면 (예를 들어, 다른 파일에서도 이 API를 사용하고 있어서 함부로 바꿀 수 없다던지) 그때 계획을 업데이트합니다. “계획 파일에 새로 발견된 의존성과 수정된 접근법을 반영해줘”라고 요청하는 거죠.

이렇게 하면 AI가 길을 잃고 헤매는 대신, 명확한 방향성을 가지고 단계적으로 문제를 해결할 수 있습니다. 마치 GPS가 있는 상태로 운전하는 것과 같죠.

실제 성공 사례: BAML 프로젝트

이 방법론의 실효성을 보여주는 구체적인 사례가 있습니다. HumanLayer 팀은 BAML이라는 30만 라인의 Rust 코드베이스에서 이 기법들을 테스트했습니다. BAML은 LLM과 함께 작동하는 프로그래밍 언어를 위한 프로젝트입니다.

중요한 것은 이 작업을 수행한 개발자가 기껏해야 아마추어 수준의 Rust 개발자였고, BAML 코드베이스를 이전에 한 번도 다뤄본 적이 없었다는 점입니다. 그럼에도 불구하고 한 시간 만에 버그를 수정하는 PR을 만들었고, 다음 날 아침 메인테이너의 승인을 받았습니다.

몇 주 후에는 더 복잡한 문제에 도전했습니다. 7시간 동안(연구/계획에 3시간, 구현에 4시간) 35,000라인의 코드를 추가하여 취소 지원과 WASM 컴파일 기능을 구현했습니다. BAML 팀이 추정하기로는 시니어 엔지니어가 각각 3-5일씩 걸릴 작업이었습니다.

핵심은 효과적인 지점에서의 인간 검토

이 방법론에서 가장 중요한 부분은 가장 큰 영향력을 발휘할 수 있는 지점에 인간의 검토를 넣는다는 것입니다.

생각해보세요. 나쁜 코드 한 줄은 그냥 나쁜 코드 한 줄로 끝납니다. 하지만 계획의 잘못된 한 줄은 수백 줄의 나쁜 코드를 만들어낼 수 있습니다. 더 나아가 연구 단계의 잘못된 이해 – 예를 들어 “이 기능이 A 파일에 있다”고 잘못 파악하거나 “데이터 흐름이 이렇게 된다”고 잘못 이해하는 것 – 는 수천 줄의 잘못된 코드로 이어질 수 있습니다.

마치 건물을 지을 때와 같습니다. 벽돌 하나가 삐뚤어진 것은 그 벽돌만 다시 놓으면 됩니다. 하지만 설계도가 잘못되면 건물 전체를 다시 지어야 하죠. 땅을 잘못 골랐다면 아예 처음부터 다시 시작해야 하고요.

따라서 인간의 시간과 에너지를 가장 큰 파급효과를 가진 부분에 집중해야 합니다. 연구와 계획을 검토할 때 한 번의 수정으로 얻는 효과가 코드를 한 줄씩 검토하는 것보다 훨씬 큽니다.

실제로 BAML 프로젝트에서 연구 단계에서 Claude가 “이 버그는 실제로는 버그가 아니고 코드베이스가 올바르게 작동하고 있다”고 잘못 판단한 적이 있었습니다. 그 연구 결과를 그대로 썼다면 엉뚱한 방향으로 몇 시간을 날렸을 것입니다. 다행히 사람이 검토해서 그 연구를 버리고 더 정확한 가이드를 포함한 새로운 연구를 시작할 수 있었죠. 이런 식으로 초기 단계에서의 인간 검토가 전체 작업의 성패를 좌우합니다.

팀 협업과 멘털 얼라인먼트

이 접근법이 중요한 또 다른 이유는 팀의 멘털 얼라인먼트를 유지하는 데 있습니다. 매우 생산적인 AI 코더와 함께 일해본 사람이라면 누구나 경험했을 것입니다. 매일 2,000라인의 복잡한 Go 코드를 리뷰하는 것은 지속 가능하지 않습니다.

더 큰 문제는 팀 차원의 멘털 얼라인먼트 부족이었습니다. 제품이 무엇이고 어떻게 작동하는지에 대한 감각을 잃어가고 있었죠.

AI로 훨씬 많은 코드를 작성하게 되면, 어떤 시점에서든 주어진 엔지니어에게 익숙하지 않은 코드베이스의 비중이 훨씬 커지게 됩니다. 따라서 다음 두 가지를 가능하게 하는 엔지니어링 프로세스가 절대적으로 필요합니다.

팀 멤버들을 같은 선상에 유지하기
팀 멤버들이 익숙하지 않은 코드베이스 부분에 대해 빠르게 학습할 수 있게 하기

대부분의 팀에서는 이것이 풀 리퀘스트와 내부 문서입니다. HumanLayer 팀에게는 이제 스펙, 계획, 그리고 연구가 그 역할을 합니다. 매일 2,000라인의 golang을 읽을 수는 없지만, 잘 쓰여진 200라인의 구현 계획은 읽을 수 있습니다.

컨텍스트 엔지니어링의 한계

이 방법론이 완벽한 것은 아닙니다. HumanLayer 팀도 실패 사례가 있었습니다. 몇 주 전에 parquet-java에서 hadoop 의존성을 제거하려고 7시간 동안 시도했지만 실패했습니다. 연구 단계에서 의존성 트리를 충분히 깊이 파고들지 못했고, 클래스들을 상위 스트림으로 옮길 때 깊게 중첩된 hadoop 의존성을 도입하지 않을 것이라고 잘못 가정했기 때문입니다.

7시간의 프롬프팅만으로는 해결할 수 없는 크고 어려운 문제들이 있고, 코드베이스에 대한 전문가가 최소 한 명은 필요하다는 교훈을 얻었습니다.

실용적 적용 방법

이 방법론을 팀에 도입하려면 다음을 고려해야 합니다.

컨텍스트 활용도 관리: 컨텍스트 윈도우 활용도를 40-60% 선에서 유지하세요. Geoff Huntley의 말처럼 “약 170k의 컨텍스트 윈도우가 있고, 가능한 한 적게 사용해야 합니다. 더 많이 사용할수록 더 나쁜 결과를 얻게 됩니다.”

서브 에이전트 활용: 서브 에이전트는 역할 놀이를 위한 것이 아니라 컨텍스트 제어를 위한 것입니다. 가장 일반적인 사용 사례는 새로운 컨텍스트 윈도우를 사용해서 찾기/검색/요약을 수행하여 부모 에이전트가 컨텍스트 윈도우를 더럽히지 않고 바로 작업에 들어갈 수 있게 하는 것입니다.

체계적인 문서화: 연구, 계획, 구현의 각 단계에서 나온 결과물을 체계적으로 문서화하고 팀 내에서 공유할 수 있는 시스템을 구축하세요.

지금까지 소개한 내용은 HumanLayer 팀이 실제 프로덕션 환경에서 검증한 방법론을 바탕으로 하고 있습니다. 이들의 3명 팀은 매월 약 12,000달러의 Claude Opus를 사용하면서도 기존보다 훨씬 높은 생산성과 코드 품질을 유지하고 있습니다. 새로 합류한 인턴은 첫째 날에 2개의 PR을, 8일째에 10개의 PR을 제출했습니다.

AI 코딩이 장난감과 프로토타입을 위한 것이 아니라, 깊이 있는 기술적 엔지니어링 기예라는 것을 보여주는 사례입니다. “언젠가 더 똑똑한 모델이 나올 때”까지 기다릴 필요가 없습니다. 지금 당장 현재의 모델들로도 충분히 강력한 결과를 얻을 수 있습니다.


참고자료: Advanced Context Engineering for Coding Agents


AI Sparkup 구독하기

최신 게시물 요약과 더 심층적인 정보를 이메일로 받아 보세요! (무료)

Comments