무대가 되는 프로젝트는 ASAT(Auditory Spatial Adaptation Training)다. Java 25와 Spring Boot 4, 헥사고날 아키텍처, JSpecify와 NullAway, PostgreSQL, Redis로 구성한 개인 포트폴리오 플랫폼이다. AWS EC2에 배포되어 있고 도메인은 lemuel.co.kr을 쓴다. 전문 훈련을 다루는 도메인이라 내용의 일부는 추상화해서 서술한다.


1. 혼자 하는 프로젝트의 세 가지 결핍

ASAT를 시작할 때 혼자였다. 지금도 혼자다. 혼자 하는 개발에는 팀 안에서 일할 때는 잘 보이지 않던 결핍이 있다. 2편에서 짧게 언급했던 것인데, ASAT를 만들면서 이 결핍을 가장 크게 체감했다.

첫 번째 결핍은 요구사항이다. 회사 프로젝트는 외부에서 요구사항이 들어온다. 내가 만들기 싫어도 만들어야 할 것들이 있고, 그 제약이 역설적으로 설계의 출발점을 제공한다. 혼자 하는 프로젝트는 그 외부 제약이 없다. 모든 것을 내가 결정해야 하는데, 모든 것을 내가 결정할 수 있다는 사실이 오히려 출발을 어렵게 만든다. 무엇을 만들지는 쉽게 정해지지만, 무엇을 만들지 않을지는 계속 흔들린다.

두 번째 결핍은 토론 상대다. 아키텍처 결정에는 반박이 필요하다. "이 구조가 맞는가"를 묻는 목소리가 팀에는 있지만 혼자에게는 없다. 내가 내린 결정에 내가 반박하는 것은 잘 안 된다. 어제 내린 결정을 오늘 다시 보면 그때의 맥락이 그대로 머리에 남아 있어서, 다른 각도에서 보는 것이 구조적으로 어렵다.

세 번째 결핍은 리뷰다. 코드는 쓴 사람에게 편향된다. 방금 내가 쓴 코드는 내가 가장 잘못 볼 가능성이 크다. 팀에는 그 편향을 깨줄 동료가 있지만 혼자에게는 없다. 리뷰 없이 쌓이는 코드는 결국 초기의 편향이 시스템 전반으로 굳어버린다.

ASAT에서 이 세 결핍이 모두 두드러졌다. 도메인이 낯설었기 때문에 요구사항을 스스로 정의해야 했고, 헥사고날과 JSpecify 같은 구조적 선택이 결과에 크게 영향을 미쳤기 때문에 결정의 토론이 필요했고, 혼자 쓰는 코드가 기능적으로 돌아가는 것만으로는 프로덕션 수준에 닿지 않았기 때문에 리뷰가 절실했다. 이 세 공백을 메꿔보려고 파이프라인을 붙였다.

2. 에이전트에게 역할을 주다

구체적으로 무엇을 했는가를 말하면 이렇다. Claude 세션을 하나가 아니라 여러 개로 분리하고, 각 세션에 서로 다른 역할과 맥락을 심었다. PM 성격의 에이전트는 요구사항을 묻는 역할, 아키텍트 성격의 에이전트는 구조를 따지는 역할, QA 성격의 에이전트는 경계 조건을 지적하는 역할. 세 결핍에 각각 대응하는 배치였다.

이 글에서는 구체적인 명령 파일이나 프롬프트를 공개하지 않는다. 2편에서 정리한 원칙이다. 개별 파일의 형식보다 중요한 것은 에이전트 간에 어떤 흐름이 만들어지는가이기 때문이다. PM 에이전트가 요구사항을 초안으로 만들면, 그것을 아키텍트 에이전트가 받아 구조를 설계하고, QA 에이전트가 받아 경계 조건을 점검한다. 각 단계의 결과물이 다음 단계의 입력이 되는 구조다. 단순한 직렬이 아니라 종종 역방향 피드백이 있었다. QA가 제기한 경계 조건이 아키텍트의 구조를 수정하게 만들고, 수정된 구조가 요구사항의 불분명함을 다시 드러내기도 했다.

에이전트가 열 개를 넘어가는 시점부터 이 흐름이 나 없이도 움직이는 감각이 생겼다. 내가 한 일은 첫 번째 요청을 던지는 것뿐이었고, 그 뒤로는 에이전트들이 서로 주고받는 내용을 지켜보다가 중간에 개입하는 방식이 됐다. 처음 이 감각을 느꼈을 때는 묘했다. 혼자 짜던 프로젝트인데 갑자기 회의가 열린 것 같았다. 혼자가 혼자가 아니게 되는 경험이었다.

3. 파이프라인이 실제로 작동하는 동안 일어난 일

2편에서 파이프라인을 "왜 쓰는가"의 외부 조건을 정리했다면, 여기서는 "쓰는 동안 어떤 경험을 했는가"의 내부 경험을 정리한다. 세 가지 변화가 관찰됐다.

첫째, 내 결정이 반박받는다는 감각이 생겼다. 혼자 내리던 결정이 에이전트들에 의해 여러 번 흔들렸다. 내가 아키텍트로서 "이 모듈은 이렇게 나누자"고 결정하면, QA 에이전트가 "그 경우 다음 경계 조건은 어떻게 처리되는가"를 묻는다. 질문에 답하지 못하면 결정을 다시 들여다봐야 했다. PM 에이전트가 "이 요구사항의 우선순위 근거가 무엇인가"를 물으면, 근거가 빈약한 결정은 흔들렸다. 혼자서는 이런 흔들림이 잘 일어나지 않는다. 내가 내린 결정을 내가 다시 반박하려면 상당한 자기 비판이 필요하고, 그 자기 비판은 피곤한 일이다. 에이전트가 대신 해주자 피로가 외부화됐고, 결정의 품질이 올라갔다. 이것은 지식의 문제가 아니라 인지적 마찰의 배분 문제였다. 반박의 마찰을 내 안에서 에이전트로 옮기는 것이 파이프라인의 본질이었다.

둘째, 기록이 자연스럽게 축적됐다. 에이전트 간 주고받음이 전부 로그로 남는다. 이 로그가 예상치 못한 가치를 가졌다. 며칠 지나서 "왜 이 모듈을 이렇게 나눴지"를 다시 물어보면, 로그에 그 답이 있다. 내가 따로 적어두지 않아도 결정의 맥락이 보존되는 것이다. 혼자 개발할 때 가장 쉽게 잃어버리는 것이 결정의 맥락인데 — 오늘 내린 결정의 이유를 3주 뒤에 재구성하는 것은 종종 불가능하다 — 파이프라인이 그 맥락을 자동으로 문서화해준 셈이다. 이 로그들이 쌓이니까 프로젝트 자체가 일종의 자기 문서화를 해나가는 감각이 생겼다. ASAT의 docs/ 디렉토리에는 내가 직접 쓴 문서보다 에이전트 간 대화에서 추출한 정리가 더 많다.

셋째, 초기 편향이 분산됐다. 혼자 개발하면 초기에 내린 가정이 이후 모든 결정을 지배한다. 첫 주에 "이 프로젝트는 이런 방향"이라고 정해두면, 둘째 주부터는 그 방향을 기준으로만 판단하게 된다. 편향이 복리로 쌓인다. 파이프라인은 이 쌓임을 부분적으로 막아줬다. 에이전트들이 각자 다른 역할로 개입하면서 초기 가정을 반복해서 재검토하는 기회가 만들어진다. "이 구조를 이 방향으로 계속 가도 되는가"를 묻는 역할이 QA에도 아키텍트에도 PM에도 있다. 각자 다른 각도에서 묻기 때문에 한 방향의 편향이 고착되기 어렵다. 2편에서 언급한 Writer/Reviewer 패턴의 확장판인데, 확장의 핵심은 리뷰어가 한 명이 아니라 여러 역할이라는 점이었다.

세 가지 관찰은 서로 분리되지 않는다. 반박이 일어나는 동안 기록이 쌓이고, 쌓인 기록이 편향을 다시 드러낸다. 세 현상이 맞물려 있어서 파이프라인의 가치가 단순 속도 향상이 아니라 개발 과정 자체의 구조 개선이라는 것을 뒤늦게 이해했다. 처음 파이프라인을 붙일 때는 "혼자서는 부족하니까 도구로 보완한다"는 생각이었는데, 돌아보면 그게 아니었다. 파이프라인이 작동하는 동안 내가 개발하는 방식 자체가 변하고 있었다.

4. 그럼에도 과했던 것

시리즈 전체가 유지해온 정직함을 마지막 편에서도 지켜야 한다. 파이프라인이 작동했다고 해서 모든 것이 잘됐다는 뜻은 아니다. 세 지점에서 과잉이 있었다.

에이전트를 너무 잘게 쪼갠 경우가 있었다. 초기에는 역할을 많이 만들수록 좋다고 생각했다. PM에서 그치지 않고 "요구사항 분석 PM"과 "우선순위 PM"으로 나누고, QA도 "단위 테스트 QA"와 "통합 테스트 QA"로 나누는 식이었다. 어느 시점부터 에이전트 간 맥락 전달 비용이 이득을 상쇄하기 시작했다. 한 에이전트가 다른 에이전트에게 상황을 전달하려면 같은 맥락을 여러 번 반복해서 써야 했고, 그 반복이 내가 직접 쓰는 시간보다 길어지는 역전이 일어났다. 결국 15개 남짓이던 에이전트를 몇 개 통폐합했다. 역할의 분해능이 높다고 결과 품질이 비례해서 올라가지는 않았다.

모든 단계를 파이프라인에 태우려 한 경우도 있었다. 간단한 수정조차 PM부터 QA까지 전 단계를 돌리려다, 브라우저에서 3초면 끝났을 확인이 20분 걸리는 일이 생겼다. 파이프라인은 복잡도가 충분히 높은 작업에서만 이득을 준다. 작은 수정에는 과한 장치가 된다. 이 판단을 초기에는 잘 못 했고, 매번 파이프라인을 돌리는 습관이 붙었다가 나중에 고쳤다.

Anthropic 공식 문서의 경고 — "단순한 제어 루프가 멀티 에이전트를 능가한다" — 를 결국 ASAT 안에서도 확인했다. 2편에서 이 경고를 인용했을 때는 일반론이었는데, 4편의 이 자리에서는 내 경험으로 되짚는 문장이 됐다. 도구가 있다고 해서 매번 꺼내 쓰는 것이 아니라는 원칙이 ASAT 내부에서도 똑같이 적용됐다. 파이프라인을 가진 사람에게도 단순 세션으로 충분한 순간이 많다는 것이 솔직한 관찰이다.

5. 도구가 동료가 되는 경험 — 시리즈를 닫으며

네 편을 쓰는 동안 계속 따라다닌 질문이 있었다. AI에게 무엇을 맡기고 무엇은 맡기지 않는가. 1편에서는 실무 스택 정렬이라는 각도로, 2편에서는 파이프라인을 꺼내지 않는 판단이라는 각도로, 3편에서는 반복 산출물의 재분배라는 각도로, 그리고 4편에서는 파이프라인이 작동하는 동안의 경험이라는 각도로 이 질문에 답해왔다.

네 편이 모여서 도달한 한 줄은 이것이다. 판단과 책임은 여전히 내 것이고, 과정은 함께한다. AI는 판단을 대신하지 않고 책임을 지지도 않지만, 판단에 이르는 과정을 나눠 가질 수는 있다. 이 나눔의 정도를 조절하는 것이 AI와 일하는 9년차 개발자의 실제 기술이었다. 도구를 많이 쓸수록 좋은 것도 아니고 적게 쓸수록 좋은 것도 아니다. 어떤 일에 얼마큼 나눠 가지게 할 것인가를 판단하는 감각이 핵심이었다.

처음 이 시리즈를 쓰기 시작한 것은 어느 푸드테크 스타트업의 AI 활용 포트폴리오 제출 요청 때문이었다. 제출용 문서를 쓰다가 공개용으로 풀어 시리즈가 됐다. 요청은 포트폴리오였지만, 쓰는 동안 내가 얻은 것은 내 일과 내 도구에 대한 관찰이었다. 네 편을 쓰면서 "나는 AI와 이렇게 일한다"가 한 번 언어화됐고, 언어화된 뒤에는 다르게 일할 수 있게 됐다. 글을 쓰는 행위 자체가 일하는 방식을 바꿨다.

이 시리즈를 끝까지 읽어준 분에게 감사하다. 그리고 이 시리즈를 쓰는 동안 곁에서 놀아준 아이에게도.

LIST

+ Recent posts