Agentic Drift: 한 번에 여러 개발자가 되기란 어렵다

발행: (2026년 3월 3일 오전 07:30 GMT+9)
25 분 소요
원문: Dev.to

Source: Dev.to

번역을 진행하려면 번역하고자 하는 본문 텍스트를 제공해 주세요. 현재는 링크만 포함되어 있어 실제 내용이 없으므로, 번역이 필요한 텍스트를 복사해서 알려주시면 그대로 한국어로 번역해 드리겠습니다.

Agentic Drift

나는 여러 AI 코딩 에이전트를 동시에 실행하고 있다 — 한 번에 다섯, 여섯, 때로는 여덟 개의 워크스페이스에서 각각 같은 코드베이스의 다른 기능이나 버그를 처리한다. 짧은 시간 동안은 생산성이 높다. 작은 팀을 고용한 느낌이다. 그런데 실제로 만든 것을 멈추어 보면, 상황이 이상해진다.

한 에이전트는 동적 모델 탐색(dynamic model discovery) 을 추가했다. 다른 워크스페이스에서 다른 문제를 해결하던 또 다른 에이전트도 동적 모델 탐색을 추가했는데, 클래스 이름이 다른 약간 다른 버전이었다. 세 번째 에이전트는 자신의 기능에 모델 목록이 필요했지만 앞의 두 에이전트를 보지 못하고 자체 구현을 인라인했다. 이제 나는 같은 개념의 세 가지 버전을 세 개의 브랜치에 가지고 있었고, 서로에 대해 전혀 알지 못한다.

이것을 나는 agentic drift 라고 부른다: 서로 조정 없이 관련된 코드베이스 부분을 병렬 autonomous 에이전트가 작업할 때 서서히, 눈에 보이지 않게 발생하는 발산. 이것은 Git 의미의 병합 충돌이 아니다 — 파일은 깨끗하게 병합될 수 있다. 이것은 시맨틱 충돌(semantic conflict) 이다. 코드는 컴파일되고 테스트도 통과하지만, 같은 것을 세 번 만들었고 각 버전은 작동 방식에 대한 약간씩 다른 가정을 내포하고 있다.

How it happens

이 현상을 만들게 하는 워크플로우는 시작이 너무 기분 좋기 때문에 매력적이다.

  1. 해야 할 일 여섯 가지를 식별한다.
  2. 여섯 개의 에이전트를 띄운다.
  3. 각각에게 워크스페이스 — 깨끗한 브랜치, 집중된 작업, 완전한 자율성을 부여한다.

한 시간 뒤, 각 에이전트는 실질적인 진전을 보인다. 풀 리퀘스트가 나타나기 시작한다. 마치 CTO가 된 듯한 느낌이다.

문제는 작업들이 진정으로 독립적이지 않을 때 시작된다. 그리고 거의 절대 그렇지 않다. 소프트웨어는 목록이 아니라 그래프이다.

  • 기능 A는 유틸리티가 필요하다.
  • 기능 B도 비슷한 유틸리티가 필요하다.
  • 기능 C는 그 유틸리티가 있어야 할 모듈을 리팩터링한다.

이 에이전트들은 서로 대화하지 않는다. 각각은 지역적으로는 합리적인 결정을 내리지만, 전역적으로는 일관성이 없다.

그 결과는 다음과 같다:

SymptomDescription
Duplicate implementations같은 개념을 여러 방식으로 구현함. 때로는 같은 이름, 때로는 다른 이름을 사용함
Architectural divergence한 브랜치는 시스템을 단순화하고, 다른 브랜치는 확장함. 각각은 고립된 상황에서는 타당하지만, 함께 보면 모순됨
Cross‑pollination artifacts기능 X를 작업하던 에이전트가 모듈 Y의 버그를 수정하고, 기능 Z를 작업하던 또 다른 에이전트도 같은 버그를 다른 방식으로 수정함. 서로 관련 없는 PR에 동일 버그에 대한 두 개의 수정이 나타남
Phantom dependencies어떤 기능이 구현됐다고 기억하지만 실제로는 다른 워크스페이스에 있었음. 현재 병합하려는 브랜치에는 그 기능이 없어 설명할 수 없는 오류가 발생함

통합을 오래 미룰수록 상황은 악화된다. 각 워크스페이스는 서로에게서 더 멀어지고, 최종 병합은 단순히 추가되는 것이 아니라 고고학적인 작업이 된다. 서로 다른 타임라인에서 의도를 재구성해야 한다.

The integration tax

나는 Glue 라는 터미널 기반 코딩 에이전트를 구축하면서 이 문제를 직접 겪었다. Conductor (병렬 에이전트를 위험할 정도로 쉽게 띄울 수 있게 해주는 도구)를 사용해 병렬 작업을 진행한 뒤, 다음과 같은 상황에 처했다:

  • 열려 있는 PR 4개, 그 중 2개는 병합 충돌 발생
  • PR 없이 실제 작업이 진행 중인 피처 브랜치 10개 이상
  • 이미 PR이 열린 브랜치에서 별도 워크스페이스에 커밋되지 않은 변경 사항 존재
  • 작업이 전혀 시작되지 않은 빈 브랜치 3개
  • Ollama 모델 탐색, 스킬 로딩, 세션 재생에 대한 중복 구현이 겹침
  • 한 PR이 다른 PR이 의존하고 있던 캐싱 시스템을 제거함

무엇을 어떤 순서로 병합하고, 모순을 어떻게 조정할지 파악하는 데는 어느 하나의 i(이하 생략)보다도 더 오랜 시간이 걸렸다.

Source:

개별 기능. 이것이 통합 비용—병렬 처리에 대해 지불해야 하는 비용이며, 비선형적입니다:

  • 2개의 병렬 에이전트 → 약 1.5배 통합 작업
  • 8개의 병렬 에이전트 → 약 5배 통합 작업

각 개별 PR은 괜찮아 보입니다: 테스트가 있고, 설명이 명확하며, 코드도 깔끔합니다. 하지만 모든 PR을 한 번에 펼쳐서 공유되는 부분을 추적해 보면 혼란스러움을 알 수 있습니다.

  • 기능 B는 기능 A가 전혀 구축되지 않았다고 가정합니다.
  • 기능 D는 기능 E가 확장하는 무언가를 제거합니다.
  • 모델 레지스트리는 한 에이전트에 의해 리팩터링되고, 다른 세 에이전트에 의해 그대로 유지됩니다.

A prompting experiment: idealized diffing

드리프트 문제와 별개로, 저는 통합 단계에 도움이 될 수 있는 코드 개선을 위한 프롬프트 기법을 실험하고 있습니다. 이 기법은 간단합니다:

  1. 이 코드를 보세요.
  2. 실제로 훌륭했다고 상상해 보세요 — 구조가 잘 잡혀 있고, 엣지 케이스를 우아하게 처리하며, 데이터 흐름이 깔끔하고, 추상화가 명확한 코드.
  3. 그 상상의 버전을 자세히 설명하세요.
  4. 우리가 실제로 가지고 있는 것과 비교하세요.

저는 이를 idealized diffing이라고 부릅니다. “이 코드에 뭐가 문제인가?”(표면적인 지적에 그치는 경우가 많음) 혹은 “리팩터링해라”(점진적인 변경에 그치는 경우가 많음) 라고 묻는 대신, 모델에게 먼저 이상적인 버전의 완전한 정신 이미지를 만들게 하고, 이상과 실제 사이의 차이를 구조화된 개선 계획으로 활용합니다.

가설: 모델에게 구체적인 코드베이스를 참고자료로 제공하면, “상상된 더 나은 버전”이 현실에 기반을 둡니다. 모델은 실제 제약 조건—예를 들어, 붙여넣기를 처리해야 하는 TUI, 뒤로 호환성을 요구하는 세션 스토어—을 볼 수 있습니다. 이상적인 버전은 이러한 제약을 존중하면서 아키텍처를 개선합니다. 코드베이스가 없으면 모델은 세부 사항을 환각하거나 일반적인 것을 만들어냅니다.

초기 결과는 고무적입니다. 충돌하는 브랜치를 병합한 모듈에 적용했을 때, 올바른 질문을 끌어내는 경향이 있습니다:

“이 두 구현은 같은 목적을 수행하지만 X에 대한 서로 다른 가정을 인코딩하고 있습니다 — 여기서 어떻게 통합해야 할지 제시합니다.”

이는 본질적으로 상상을 코드 리뷰 형태로 활용하는 것이며, 목표 상태라는 목표를 제시하는 것이지 개별 이슈 목록을 제시하는 것이 아닙니다.

불만 사항

이 기술은 리팩터링을 위한 사전 작업으로 활용됩니다. 이상적인 버전을 직접 실행하는 것이 아니라, 북극성처럼 작동하여 편집을 시작하기 전에 병합된 코드가 어떻게 보여야 하는지를 파악하도록 도와줍니다. 코드를 작성하기 전에 테스트를 작성하는 것과 같은 건축적 접근이라고 생각하면 됩니다: 코드를 자르기 시작하기 전에 원하는 형태를 정의하는 것이죠.

다른 사람들도 같은 문제를 겪고 있음

저만 이런 문제에 부딪히는 것이 아닙니다. 병렬‑에이전트 작업을 규모 있게 확장할 때마다 이 문제가 나타나고 있습니다:

  • Clash – Git 워크트리 간의 병합 충돌을 문제가 되기 전에 감지하는 CLI 도구로, 삼중 병합 시뮬레이션을 사용합니다. “에이전트가 서로의 변경 사항을 알지 못하고 작업한다”는 상황 때문에 생겨났으며, 상당한 노력이 낭비된 뒤에야 충돌이 드러납니다.
  • Multi‑Agent Coordination Framework – 5,100개 이상의 테스트에서 Claude와 GPT 에이전트를 100개 이상의 세션에 걸쳐 공유 메모리 없이 조정한 방법론을 문서화합니다. 그들의 접근 방식: 프로토콜, 인계 체크리스트, 일관성 게이트, 그리고 공유 상태 대신 구조화된 메모.
  • EQengineered의 Ed Lyons는 같은 두려움을 언급합니다: “에이전트가 서로 다른 방식으로 같은 파일을 수정하면서 발생하는 추한 충돌”과 관리가 어려운 리뷰 작업량. 그의 결론: 에이전트를 구획화된, 잘 이해된 과제로 제한하라.
  • Google의 2025 DORA 보고서는 AI 도입이 90 % 증가하면 버그가 9 % 늘고, 코드 리뷰 시간이 91 % 증가하며, PR 규모가 154 % 커진다고 밝혔습니다. 처리량은 실제이지만, 통합 비용도 마찬가지로 현실적입니다.
  • MCP Agent Mail 은 에이전트에게 신원, 인박스, 파일‑예약 임대를 부여합니다—본질적으로 Git과 SQLite를 기반으로 한 코딩 에이전트를 위한 Gmail입니다. 에이전트는 편집 전에 파일에 대한 독점 잠금을 주장하고, 메시지를 보내 협업합니다. 이론적으로는 협업 문제를 해결하지만, 실제로는 또 다른 절차가 추가되는 느낌—설정해야 할 시스템, 에이전트가 따라야 할 프로토콜, 그리고 또 다른 고장 가능성. 충분히 사용해 보지는 않았지만, 모든 에이전트가 코드를 작성하기 전에 메일을 확인하도록 가르치는 오버헤드가 제공하는 협업 이득을 잠식할 수 있다는 직감이 듭니다.
    Beads 와도 비슷한 분위기—신중한 설계이지만, 대부분의 워크플로우에서는 설정 비용이 문제 자체보다 클 수 있습니다.

도구들은 점차 따라잡고 있지만, 현재 협업 문제는 대부분 해결되지 않은 상태입니다—도구들은 충돌을 더 일찍 감지하거나 협업 프로토콜을 추가하지만, 충돌을 일으키는 의미적 드리프트 자체를 방지하지는 못합니다.

생각하고 있는 완화 방안

Agentic drift는 완전히 없앨 수 없을 것 같습니다. Parallelism은 너무 유용하고, 에이전트 간 완전한 조정 비용이 생산성 향상을 잠식할 것입니다. 하지만 관리는 가능합니다:

1. 짧은 통합 사이클

가장 큰 레버.

  • 일찍 병합하고, 자주 병합합니다.
  • 다섯 개의 브랜치를 하루 동안 두지 말고—몇 시간마다 통합합니다.
  • 통합 비용은 복리로 늘어나므로, 빈번한 병합이 이를 낮게 유지합니다.

2. 공유 컨텍스트 파일

모든 에이전트에게 현재 아키텍처, 최근 결정, 진행 중인 작업을 설명하는 살아있는 문서를 제공합니다.

  • 예시: AGENTS.md 또는 CLAUDE.md.
  • 모든 워크스페이스가 이 파일을 읽습니다.
  • 이것이 drift를 완전히 막지는 않지만, 그 범위를 줄여줍니다.

3. 조기 충돌 감지

에이전트 워크플로에 연결되어 다른 작업 트리와 충돌할 수 있는 쓰기가 발생하기 전에 경고하는 도구를 사용합니다.

  • 예시: Clash.
  • 이것이 drift를 해결하는 것은 아니지만, 기계적 충돌을 충분히 일찍 잡아 재조정할 수 있게 합니다.

4. 에이전트와 함께하는 트렁크 기반 개발

오래 지속되는 기능 브랜치 대신, 에이전트가 짧게 살아있는 브랜치에서 작업하고 main에 빠르게 병합하도록 합니다.

  • 브랜치당 하나의 기능, 한 시간당 하나의 브랜치.
  • “여섯 에이전트를 띄우는” 워크플로와는 충돌하지만, 전체적으로는 긍정적일 수 있습니다.

5. 병합 후 이상화된 Diff 수행

여러 브랜치를 한 번에 병합한 뒤, 여러 브랜치가 손댄 각 모듈에 대해 이상화 프롬프트를 실행합니다.

  • 모델이 병합된 코드에서 모순이나 중복을 식별하도록 합니다.
  • 그런 다음 의도적으로 정리합니다.

6. 아키텍처 경계

작업 간 공유 표면이 적을수록 drift가 적습니다.

  • 에이전트 A가 CLI 진입점을 담당하고, 에이전트 B가 관측성을 담당한다면 서로 간섭할 가능성이 거의 없습니다.
  • 둘 다 app.dart를 건드린다면—그리고 god 클래스는 drift의 자석이 되기 때문에—문제가 발생합니다.

여전히 가치가 있다

나는 병렬 에이전트를 너무 비판하고 싶지는 않다—처리량은 실제이다. 일주일 동안 집중해서 혼자 작업해야 할 기능도 하루 만에 배포할 수 있다. 품질도 종종 놀라울 정도로 좋으며, 각 개별 에이전트는 신중하고 검증된 작업을 수행한다. 문제는 순전히 통합 레이어에 있다.

이는 실제 엔지니어링 팀이 마주하는 동일한 트레이드‑오프이며, 스프린트가 아닌 몇 시간 안에 압축된 형태다. Brooks’s Law는 프로젝트가 늦어질수록 사람을 더 추가하면 더 늦어진다고 말한다. 에이전트 버전은 다음과 같이 표현될 수 있다: 연결된 코드베이스에 에이전트를 추가하면 병합이 더 어려워진다. 에이전트는 빠르지만, 병합은 여전히 수동이며 전체 상황을 이해해야 하고, 결국 당신에게 달려 있다.

해답은 에이전트를 줄이는 것이 아니다. 다음이 필요하다:

  • 더 나은 통합 규율,
  • 더 나은 공유 컨텍스트, 그리고
  • 이상적인 차이점(diff) 기법이 입증된다면, 결합된 출력이 어떻게 보일지에 대해 시작하기 전에 추론할 수 있는 더 나은 도구.

불편한 질문: 격리가 문제라면 어떨까?

제가 계속 되돌아보는 가능성이 있습니다. 어쩌면 worktree‑per‑agent 모델 자체가 잘못된 것이고, 답은 단순히… 격리를 하지 않는 것일지도 모릅니다.

모든 에이전트가 같은 디렉터리의 같은 브랜치에서 작업한다면 병합 단계가 없습니다. 에이전트 A가 유틸리티를 작성하면 에이전트 B가 즉시 확인하고, 에이전트 C가 그 위에 빌드합니다. 분기점도, 가짜 의존성도, 마지막에 발생하는 고고학적 병합도 없습니다. 하나의 현실만 존재하므로 드리프트 문제도 사라집니다.

실제로 어떻게 보이는가

에이전트들이 서로 기대보다 덜 방해합니다. 논리적인 청크 단위로 자신의 변경을 커밋할 수 있고, 통합할 것이 없기 때문에 통합 비용도 없습니다.

장점

  • 서로의 작업을 즉시 확인할 수 있습니다.
  • 서로 다른 히스토리를 최종 병합할 필요가 없습니다.
  • 작업이 긴밀히 연결된 경우 워크플로가 단순해집니다.

단점

  • 컴파일 언어의 경우, 에이전트가 기능을 진행 중일 때 반쯤 완성된 깨진 상태가 나타날 수 있습니다.
  • 두 에이전트가 같은 화면이나 모듈을 건드리면, 하나는 움직이는 목표물을 향해 작업하게 됩니다.
  • 에이전트 A의 작업을 미리 보기 위해서는 에이전트 B의 반완성 변경도 함께 보여야 합니다.
  • 커밋 히스토리가 뒤섞여—다른 기능들의 변경이 교차해—깨끗한 되돌리기가 어려워집니다.

트레이드‑오프

모델격리 수준깔끔한 커밋드리프트 위험중간 상태 혼란
Worktree per agent높음높음높음낮음
Shared workspace낮음낮음낮음높음

어느 쪽이 명백히 더 좋다고 할 수는 없습니다. 올바른 선택은 다음에 따라 달라질 수 있습니다:

  • 언어 (인터프리터 vs. 컴파일)
  • 코드베이스 규모
  • 작업 중복 정도

가능한 중간 지점

실제 답은 그 사이 어딘가에 있을 것이라고 생각합니다—예를 들어 두세 명의 에이전트가 하나의 워크스페이스를 공유하고, 네 번째는 완전히 독립적인 작업을 격리된 상태로 진행하는 식입니다. 아직 그 최적점을 찾지는 못했지만, 효과적이었던 경험이 있다면 듣고 싶습니다.

지금은 같은 파일을 모두 수정한 여덟 개의 브랜치를 다시 병합하는 쪽으로 돌아가고 있습니다.

0 조회
Back to Blog

관련 글

더 보기 »