처리중입니다. 잠시만 기다려주세요.
TTJ 코딩클래스
정규반 단과 자료실 테크 뉴스 코딩 퀴즈
테크 뉴스
Hacker News 2026.08.30 31

레거시 코드에서 AI 에이전트가 헤매는 진짜 이유, DDD로 풀다

Hacker News 원문 보기

LLM으로 코드를 짜는 일이 일상이 된 지금, 많은 개발자가 비슷한 경험을 한다. 아무것도 없는 상태에서 새로 시작하는 프로젝트나 규모가 작은 코드베이스에서는 생산성이 눈에 띄게 오른다. 그러나 수년째 운영 중인 시스템, 무거운 의존성 트리와 강한 결합, 그리고 손대지 못한 기술 부채가 쌓인 브라운필드에 에이전트를 투입하는 순간 결과물의 품질은 가파르게 떨어진다. 문제는 모델의 성능이 아니라 코드가 대답해 주지 못하는 질문에 있다.

실패는 특정한 모양을 가진다

원문 저자는 실패의 형태를 구체적으로 짚는다. 새 저장소에 '채용 공고 상태' 필드를 요청하면 깔끔하게 하나가 나온다. 그러나 4년째 배포되어 온 시스템에 같은 요청을 하면, 이미 세 가지 표기로 존재하는 개념에 모델이 네 번째 철자를 새로 지어낸다. 코드베이스 자체가 무엇이 진짜인지 한 번도 결정하지 않았기 때문이다. 그냥 호출하면 될 자리에 어댑터를 끼워 넣고, 정작 어댑터가 핵심이던 지점에서는 곧장 통과시켜 버린다. 하나하나가 시스템에 대한 질문이지만, 시스템은 그 답을 어디에도 적어 두지 않았다. 그래서 모델은 추측하고, 자주 틀린다.

저자는 브라운필드의 깊이가 기술적 층위 하나로 끝나지 않는다고 본다. 그 아래에는 혼란, 사라진 의미, 그것을 해소할 공통 언어의 부재라는 두 번째 층이 있다. 모델이 빠지는 곳이 바로 이 지점이다. 결론은 명확하다. 업그레이드가 필요한 것은 모델이 아니라 코드이며, 코드의 '준비 상태'는 조금씩 만들어 나갈 수 있는 대상이다.

결정하는 일과 타이핑하는 일의 가격이 달라졌다

기술 부채는 개발이라는 행위의 자연스러운 결과다. 미래의 비즈니스 결정이 지금의 코드를 흔들 것을 우리는 미리 대비하지 못하고, 빠른 납품을 위해 대가를 치르며, 그 결과 코드 냄새는 점점 커진다. 흔한 대응은 기술 예산의 10~20%를 부채 상환에 떼어 두는 것이지만, 대개 '다음 분기에는'이라는 말로 끝난다.

저자의 통찰은 이 부채 상환이 서로 값이 다른 두 반쪽으로 이뤄져 있다는 데 있다. 무엇을 바꿔야 하는지 '결정하는 일'과 그것을 파일로 '타이핑하는 일'이다. 결정의 비용은 예나 지금이나 비싸지만, 타이핑의 비용은 붕괴했다. 모듈 추출, 두 패키지에 걸친 리팩터링, 테스트 커버리지 확대 같은 기계적 절반을 LLM이 2020년과는 비교되지 않는 비용으로 처리한다. 저자는 존 오스터하우트의 '전술적/전략적' 구분을 빌려 오되 뜻을 살짝 비틀어, 저작권의 분할로 사용한다. 전략적 작업은 시스템을 읽고 무엇을 왜 바꿔야 하는지, 그 변경이 정말 기능에 봉사하는지를 판단하는 일이다. 전술적 작업은 그 결정을 파일로 옮기는 일이다. 앞쪽은 시스템 전체를 머릿속에 담아야 하는 일이고, 뒤쪽은 값이 싸진 일이다.

이슈에서 PR까지, 반복되는 작업의 척추

실제 흐름은 이렇다. 저자는 전략적 단계에 온전히 개입해 코드베이스를 살피고 필요한 변경을 기능과의 정합성 관점에서 평가한 뒤, 그 결과를 각 저장소의 GitHub 이슈로 남긴다. 이 이슈는 스킬과 서브에이전트로 구성된 AI 시스템이 처리한다. 스킬은 마크다운으로 쓰인 절차서로, '이슈 처리'나 '컨텍스트 맵 재생성' 같은 작업이 그날그날의 지시 문구에 좌우되지 않고 매번 같은 방식으로 실행되게 한다. 서브에이전트는 신선한 컨텍스트와 좁은 임무(구현, 보안 검토, 명세 대조)를 가진 별도 세션으로, 전체 대화록이 아니라 결과만 보고한다. 구현이 끝나면 PR이 올라오고, 저자는 리뷰 세션에서 수용하거나 개선을 요청한다. 이때 그는 변경 대상이 어떤 다른 부분에 소비되는지, 그 변경을 그들이 견딜 수 있는지를 먼저 확인한다. 구현자가 아니라 조정자이자 설계자로 남는 것이다.

전략의 언어로서의 DDD

전략적 절반은 그것이 쓰인 언어만큼의 가치를 가진다. 여기서 도메인 주도 설계가 등장한다. 에릭 에반스가 제시한 유비쿼터스 언어와 바운디드 컨텍스트는 비즈니스와 기술 사이의 소통 간극을 줄이는 방법이었는데, 에이전트가 개입하면 이 연결은 더 중요해진다. 우리가 모델에 요구를 진술하고 모델의 추론을 되읽는 통로가 바로 그것이기 때문이다.

저자는 모든 저장소 루트에 .workflow.json 매니페스트를 둔다. 저장소가 자신이 무엇인지를 도구에 알려 주는 선언이며, 언어·먼저 읽을 디렉터리·배포 전 통과해야 할 검사와 함께 도메인 블록을 담는다. 이 블록 하나가 저장소의 유일한 등록 절차라, 어긋날 수 있는 두 번째 레지스트리가 없다. 블록은 프로젝트, 바운디드 컨텍스트, 각 컨텍스트 용어집의 위치, 서브도메인 유형, 이웃 컨텍스트로 향하는 모든 엣지를 담는다. 저자의 예시인 채용 지원 추적기 job-offer-box는 hyperion 프로젝트 아래의 러스트 백엔드와 웹 프런트엔드 두 저장소로 나뉜다. 하나의 엣지는 목적지(to), 호출 방향(direction·outbound/inbound), 모델이 충돌할 때 누구의 것이 이기는지(owner·supplier), 닫힌 어휘에서 고른 관계 유형(pattern), 그리고 설명(note)으로 기술된다. 웹 저장소가 쓸 때는 백엔드의 형태를 그대로 받고 읽을 때는 자기 형태로 번역하기에, 예시의 pattern은 하나의 라벨로 정리되지 않는 'unclassified'로 표기된다.

매니페스트 옆에는 컨텍스트마다 CONTEXT.md가 놓인다. 모든 용어의 정확한 의미와 의도적으로 배제한 동의어까지 담는 살아 있는 용어집이다. 컨텍스트당 두 파일, 둘 다 코드를 소유한 저장소가 소유한다. 그 위의 컨텍스트 맵은 저작하지 않는다. 디스크의 모든 저장소를 훑어 도메인 블록을 합쳐 하나의 CONTEXT-MAP.md로 뽑는 생성기가 만들며, 언제든 버리고 다시 만들 수 있다. 규칙은 지속 상태를 쥔 쪽이 용어를 소유한다는 것이라, 백엔드가 Job Offer·Profile·Resume 같은 제품 언어를 소유하고, 웹은 View Model·Filter State 같은 화면 어휘만 소유하며 나머지는 OpenAPI에서 생성된 타입스크립트로 도착한 [published]로 표시된다. 맵이 있으면 모델은 자신이 어느 컨텍스트에 있는지 알고, 용어집이 있으면 그곳에서 쓰는 단어를 안다.

엣지가 양쪽에서 두 번 선언되는 것이 이 구조의 핵심이다. 생성기는 짝을 대조하되 공급자와 소비자가 각자의 입장을 명명한다는 점을 고려한 페어링 표로 판정한다. 저자는 이를 스킬로 돌려 매니페스트를 만졌을 때, 저장소를 온보딩할 때, 다른 컨텍스트가 의존하는 것을 바꾸기 전 세 시점에 실행한다. 각 불일치는 지문을 가진 DDD 이슈로 기록되어, 절반만 고친 뒤 재실행하면 같은 이슈가 갱신되고 사라진 발견은 이슈를 닫는다. 이렇게 정리되는 것은 컨텍스트의 경계와 이웃과의 대화 방식, 즉 지도의 모양이다. 다만 컨텍스트 내부는 여전히 말이 안 되는 객체도 저장할 수 있는 평범한 코드로 남아 있고, 저자는 다음 단계로 값 객체·애그리게잇·도메인 서비스 같은 DDD 프리미티브로 각 컨텍스트를 옮기는 작업을 예고한다. 한국의 실무자에게 이 접근이 시사하는 바는 분명하다. 에이전트 도입의 병목은 모델이 아니라, 우리 코드가 스스로 답하지 못하는 의미의 공백이라는 점이다.

이 뉴스가 유용했나요?

이 기술을 직접 배워보세요

AI 도구, 직접 활용해보세요

AI 시대, 코딩으로 수익을 만드는 방법을 배울 수 있습니다.

AI 활용 강의 보기

"비전공 직장인인데 반년 만에 수익 파이프라인을 여러 개 만들었습니다"

실제 수강생 후기
  • 비전공자도 6개월이면 첫 수익
  • 20년 경력 개발자 직강
  • 자동화 프로그램 + 소스코드 제공

매일 AI·개발 뉴스를 받아보세요

주요 테크 뉴스를 매일 아침 이메일로 전해드립니다.

스팸 없이, 언제든 구독 취소 가능합니다.