소프트웨어 팩토리란 소프트웨어 작업을 중심으로 돌아가는 반복 가능한 루프입니다. 팩토리를 구축하더라도, 출시 가능한 수준의 코드를 만들기 위해서는 여전히 인간의 감각과 주인의식이 필요합니다. 지금 당장 팩토리가 필요한지의 문제도 포함해, 이 주제를 깊이 살펴봅니다.
팩토리가 필요하다면:
제품의 의도, 시스템 설계(중요하다고 판단되는 경우), 품질 기준을 결정하는 초기 단계에는 사람이 반드시 루프 안에 있어야 합니다.
코드 리뷰는 꾸준히 진행하되(상시 가동 팩토리), 가장 필요한 지점에 집중적으로 임해야 합니다. 제 경험상 자동화된 역압(back-pressure)이 무너지는 지점, 또는 유지보수 트레이드오프를 직접 판단해야 하는 지점을 특히 주의깊게 살펴볼 필요가 있습니다.
품질 검사는 가능한 한 일찍, 그리고 지속적으로 이루어지도록 설계하세요. 모든 검사가 그래야 할 필요는 없지만, 타입 시스템, 자동화 테스트, 뮤테이션 테스트, 보안 스캐너, 아키텍처 규칙 린팅 등이 여기에 해당합니다.
검사 수 != 품질. 신호 대 잡음비(signal to noise ratio)가 가장 좋은 검사가 무엇인지 실험해볼 필요가 있습니다. 제약을 의도적으로 강화하거나 완화할 준비도 해두세요.
팩토리를 구축할 때는 인간의 감각 일부가 환경 자체에 녹아들도록, 에이전트가 작업의 정확성을 스스로 증명하도록, 그리고 프로덕션에 배포되는 결과물에 대한 '주인'이 여전히 사람이 되도록 설계해야 합니다.
제 경험으로는, 기존 코딩 하네스만으로도 놀랍도록 멀리 나아갈 수 있습니다! Claude Code나 Codex, 여러 세션, 검증과 제약이 내장된 탄탄한 SPEC만 갖춰도 충분한 경우가 많습니다. GitHub 이슈를 한 묶음씩 던지며 구현 기준과 사람 개입 기준을 함께 제시하는 것도 가능하죠. 다만 이 시스템이 반복 가능하고 이벤트 기반으로 돌아가야 할 때 비로소 팩토리가 진가를 발휘합니다.
앞서 소프트웨어 팩토리란 소프트웨어 작업을 중심으로 돌아가는 반복 가능한 루프라고 했습니다. 아주 작은 팩토리 루프를 보여주는 프롬프트 예시를 살펴보겠습니다:
Read GitHub issue #123 and the repository instructions before changing code. Implement only the stated acceptance criteria. Do not modify authentication, billing, migrations, or existing test assertions. Work in a branch and keep the diff reviewable. Run npm run lint, npm test, and npm run build. If a required check cannot run, stop and explain why. Open a draft pull request with the checks you ran, the remaining risks, and any decision a human still needs to make. Do not merge.
목표를 설정해두면 검사를 통과할 때까지 루프가 계속 돌아가고, 매일 아침 GitHub 이슈에서 특정 레이블을 폴링하거나 열린 풀 리퀘스트를 살펴볼 수 있습니다. 브랜치 보호 규칙으로 머지 경계를 강제하고, 사람은 무엇을 준비 상태로 만들지 선택하거나 리뷰 및 최종 머지 결정을 내리는 방식으로 루프 안에 계속 남아 있을 수 있습니다.
소프트웨어 팩토리는 이벤트 기반의 작업 대기열(Slack 트리거, GitHub 이슈, Linear, 백로그 등)을 격리된 클라우드 환경에서 실행해 트리아지, 구현, 테스트를 사람의 명시적인 감독 아래 처리해야 할 때 추가하세요. 루프의 끝에 모니터 에이전트를 배치해 프로덕션을 감시하고 이슈를 등록하면, 그 이슈가 다시 트리아지 단계로 들어가는 방식으로 운영하는 팀도 있습니다.
제 경험상, 팩토리가 진정으로 필요해지는 시점은 다음과 같습니다. 여러 번의 실행이 일관되게 동작하도록 만드는 것, 에이전트 간 작업 인계(handoff), 서로 다른 세션이 같은 이슈를 중복 처리하지 않도록 방지하는 것, 작업 증거를 보존하는 것, 그리고 사람의 리뷰가 밀릴 때 프로덕션 배포를 멈추는 것이 어려워지는 때입니다.
이 문제의 해결책은 다소 단조롭게 들릴 수 있습니다. 예를 들어 Warp는 들어오는 모든 이슈를 네 가지 상태—ready-to-implement, ready-to-spec, needs-info, wait-to-implement—중 하나로 트리아지하고, 그 레이블이 다음 에이전트를 실행하는 트리거가 됩니다.
이 레이블은 한 번에 여러 역할을 합니다. 대기열이자 잠금(lock)이며, 세션은 ready 상태로 표시된 것만 집어가기 때문에, 사람이 영구적인 거절 없이 작업을 보류해둘 수 있는 수단이기도 합니다.
워크플로우 측면에서, Claude/Codex를 단독으로 사용하는 것과 비교해 몇 가지 공통점과 차이점이 있습니다:
스티어링(Steering): 에이전트가 궤도를 벗어났을 때 사람이 개입해 방향을 재조정할 수 있습니다.
알림(Notifications): 팩토리가 막혔다는 신호입니다. 요구사항이 모호하거나, 위험한 작업을 시작했거나, 사람의 입력(스티어링)이 필요할 때 발생합니다.
인계(Handoff): 작업과 상태, 컨텍스트를 클라우드 팩토리·다른 에이전트·사람 리뷰어 사이에 넘기는 과정입니다. 좋은 인계는 지금까지 무슨 일이 있었는지, 남은 작업이 무엇인지, 왜 인계가 필요한지를 명확히 기록합니다.
잘 설계된 팩토리에서 사람의 역할은 맨 마지막에 최종 diff를 검토하고 승인하는 것에 그치지 않습니다. 초반에 작업 방향을 잡고, 구현 과정에서 스티어링하고, 인계를 통해 작업을 이어가거나, 프로덕션 배포를 막는 것까지 할 수 있습니다.
책임감 있는 팩토리는 검증(verification)에 많은 시간을 쏟습니다. 이 주제는 이후에 더 자세히 다루겠습니다.
소프트웨어 팩토리가 필요하다는 결론을 내렸더라도, 직접 구축하는 것만이 선택지는 아닙니다. 팩토리를 확장할 인프라를 세우는 일은 적지 않은 작업이 필요하므로, 만들지 말지를 먼저 따져볼 필요가 있습니다. Factory, Warp, HumanLayer 모두 이 영역에서 제품을 만들고 있습니다.
지난 1년 사이 제 일상적인 소프트웨어 개발 경험은 크게 달라졌습니다. 저는 점점 더 많은 병렬 작업을 에이전트와 함께 수행하고, 상시 가동 소프트웨어 팩토리로 나아가고 있다고 여러 번 이야기했습니다. 그러면 많은 분들이 이렇게 묻습니다. "그게 실제로 어떤 의미인가요? 무엇을 만들고 있나요? 어떤 프로젝트에 활용하고 있나요?" 대체로 이런 모습입니다:
평범한 하루를 기준으로, 저는 간단한 상시 가동 소프트웨어 팩토리를 운영합니다. 클라우드에서 돌아가는 태스크들이 있는데, 그 절반 정도는 제가 협업하는 중소 규모 기업의 프로덕션 클라이언트 애플리케이션과 관련된 것입니다. 실제 사용자, 실제 인증, 결제, 구독이 있고, 신중하게 다뤄야 할 진짜 위험이 따릅니다. 테스트, 제약, 품질 검사도 없이 에이전트에게 그냥 처리하라고 할 수는 없습니다.
오픈 소스 프로젝트를 진행하기도 하고, 제 책의 부속 사이트를 만들거나, 도구를 개발하거나, 개인 앱을 만들기도 합니다. 이 모두가 성격이 전혀 다른 애플리케이션들이고, 때로는 제가 사용하는 도구 하나만이 공통점인 경우도 있습니다. 마이그레이션 작업일 때도 있고, 본격적인 피처 개발일 때도 있으며, 작업의 영향 범위도 천차만별입니다.
점점 더 많은 병렬 작업으로 나아가고, 속도와 생산성을 높이고, 자율성을 확장하는 방향—즉 시스템을 더 신뢰할 수 있는 수준으로 끌어올리는 방향—을 생각하다 보면, 인간의 코드 리뷰와 인간의 판단이 반드시 필요한 지점이 어디인지를 진지하게 고민하게 됩니다.
그리고 그 상당 부분은 초반에 집중됩니다. 명세(specification)와 요구사항을 정의할 때, 제품의 디자인과 의도를 결정할 때가 그렇습니다. 그다음으로는, 에이전트가 실제로 작업을 제대로 완료했는지 어떻게 검증할 것인가, 기존 시스템을 망가뜨리지 않았는지 어떻게 확인할 것인가, 품질 기준을 충족하는지 어떻게 담보할 것인가의 문제가 남습니다.
코드를 생성하는 것 자체는 가장 걱정해야 할 부분이 아닙니다. 충분한 컨텍스트만 있다면 에이전트가 구현을 작성하고, 테스트를 실행하고, 실패를 분석하고, 코드를 수정하는 것까지 할 수 있습니다. 우리가 도달해야 할 곳은, 환경 안에 인간의 감각이 충분히 녹아들어 있어 무엇이 만들어지고 있는지 믿을 수 있는 상태입니다. 그래야 인간의 주의를 가장 필요한 곳에 집중할 수 있습니다.
물론 "많은 부분을 자동화로 대체할 수 있다는 말은 믿기 어렵다"는 반론도 있습니다. 하지만 모든 것을 자동화한다는 이야기가 아닙니다. 다만 생성되는 코드의 양을 생각하면, 인간이 그 전부를 읽는 것은 현실적으로 어렵습니다. 특히 우리가 항상 로켓을 만드는 것도 아니고, 대부분은 UI나 풀스택 애플리케이션을 만들고 있으니까요.
우리의 판단과 감각은 가장 필요한 곳에 집중되어야 합니다. 시스템에서 가장 위험한 부분이 어디인지, 어디에 인간의 감각을 적용해야 하는지—그것이 프론트엔드일 수도, 시스템 작동 방식일 수도 있습니다. 100% 전부일 필요는 없습니다.
현실을 직시하면, 수십, 수백, 수천 개의 에이전트를 병렬로 실행하는 것은 가능해졌지만, 나 자신의 인지 대역폭은 그에 맞춰 늘어나지 않습니다. 이는 제가 전에 이야기한 적 있는 인지 부채 또는 이해 부채(comprehension debt)로 이어질 수 있습니다.
5년, 10년 전만 해도 엔지니어링 커뮤니티에서는 컨텍스트 스위칭과 그 비용에 대한 논의가 활발했습니다. 작업 중간에 동료가 책상으로 걸어와 말을 걸면 얼마나 힘든지, 다시 집중 상태로 돌아오는 데 얼마나 오래 걸리는지—"어디까지 했더라? 무엇을 하고 있었지?" 하면서 맥락을 되짚어야 했으니까요. 약간의 흔적이 남아 있어도 다시 궤도에 오르는 데 시간이 걸렸습니다.
이제 우리는 예전보다 훨씬 더 빈번하게 컨텍스트 스위칭을 합니다. 팩토리 밖에서 작업하는 날에도 동시에 다섯 개에서 열 개의 서로 다른 프로젝트를, 혹은 단일 프로젝트에서 다섯 개에서 열 개의 기능을 에이전트와 함께 작업할 수 있습니다. 사실상 다섯 개에서 열 개의 세션을 동시에 돌리는 셈입니다.
즉, 그 중 적어도 몇 개는 계속 파악하고 있어야 합니다. 물론 태스크를 충분히 잘 정의했고, 결과물을 어떻게 검증할지까지 명확히 해두었다면, 에이전트에게 더 많은 자율성을 줄 수 있습니다. 하지만 그렇지 않은 태스크도 있고, 리스크나 미묘한 판단이 더 많이 개입되는 태스크도 있습니다. 그런 경우에는 더 주의를 기울여야 합니다.
소프트웨어 팩토리를 최적화할 때는 리뷰어의 관점을 기준으로 삼으세요. 모든 접근 방식의 결과물이 결국 한 사람의 주의를 필요로 한다면, 팩토리가 그 사람이 내려야 할 결정을 얼마나 쉽게 만들어주고 있는지를 물어봐야 합니다.
여러 프로젝트를 에이전트와 병렬로 진행하던 중, 실수를 저지른 적이 있습니다. 다크 모드를 추가하려던 웹앱이 있었는데, 머릿속으로 어떤 식으로 구현해야 할지 대략 그림을 그려두고 있었습니다. 그런데 실수로 다른 프로젝트의 세션 창으로 들어가서, 그 프롬프트를 그대로 입력해버린 겁니다.
결국 다크 모드가 전혀 필요 없는 프로젝트에 다크 모드를 구현하기 시작했습니다. 저도 이런 실수를 하는데, 소프트웨어 팩토리가 이런 실수를 하는 건 결코 원하지 않습니다.
이것은 시스템의 관점에서 접근해야 하는 문제입니다. 사실상 소프트웨어 엔지니어링 문화, 팀 문화를 시스템에 녹여내야 합니다. 동일한 행동 방식이 갖춰지도록, 주인의식이 어딘가에 귀속되도록, 결과에 대해 책임질 사람이 여전히 존재하도록, 그리고 그 모든 것에 대해 명시적으로 생각하고 있어야 합니다.
이런 시스템에서도 매우 주의해야 합니다. AI에게 테스트를 통과시켜달라고 요청해본 분들은 잘 알 겁니다. AI는 단위 테스트 자체를 바꿔 조건을 충족시키거나, 코드 로직을 바꿔 테스트를 통과시키는 방식을 택할 수 있습니다. 이것이 실제 의도에 따라 기능 동작과 테스트 목적을 모두 올바르게 구현했다는 의미는 아닙니다.
소프트웨어 팩토리가 모든 것이 초록색이라고 표시한다고 해서, 실제로 다 잘 된 것은 아닙니다. 특히 처음 세팅하는 단계에서는 더욱 그렇습니다. 각종 검사와 검증이 올바르게 구성되어 있는지, 기대한 대로 동작하는지, 잘못된 신호를 주고 있지는 않은지 면밀하게 살펴봐야 합니다.
테스트가 통과됐지만 실제로는 이런 상황이 되어서는 안 됩니다. "지원하는 인증 프로바이더를 변경했습니다. GitHub를 추가해달라고 하셨는데, UI에 세 개밖에 자리가 없어서 기존 프로바이더 하나를 제거했습니다. 그런데 그게 마침 실제 고객들이 원하던 프로바이더였습니다." 이런 일이 생기지 않도록, 시스템이 어떻게 동작해야 하는지를 매우 명시적으로 정의해야 합니다.
보안도 매우 중요합니다. 팩토리가 GitHub 이슈나 Slack 메시지 같은 신뢰할 수 없는 입력을 읽는다면, 그것이 악의적인 내용일 수 있으며 공급망 공격(supply chain attack) 같은 문제를 포함할 수 있습니다. Vercel처럼 소프트웨어 팩토리를 탐구하는 일부 팀은 에이전트를 격리된 샌드박스에서 실행하며, 해당 태스크에 필요한 시크릿만 제한적으로 제공합니다. 이렇게 하면 실행이 침해되더라도 해당 작업에 필요하지 않은 것에는 접근할 수 없습니다. 방어는 결국 레이어를 쌓아가는 것입니다.
AI 이전 시대를 생각해보면, 완성되지 못한 채 방치된 소프트웨어 프로젝트가 얼마나 많았는지 알 수 있습니다. 주말 프로젝트, 개인 프로젝트 중에 시간이 부족해서, 우선순위를 내기 어려워서, 혹은 그냥 중요하지 않아서 출시하지 못한 것들이 쌓여갔습니다.
이제는 그 프로젝트들을 완성하는 것이 꽤 간단해졌습니다. 하지만 인간의 판단이라는 같은 질문이 다시 찾아옵니다. 그 프로젝트들이 세상에 존재할 가치가 있는가? 출시해야 하는가? 내보내는 순간, 사용자가 단 다섯 명뿐이더라도 유지보수가 따라올 수 있고, 일정 수준의 품질 기준을 유지해야 할 수도 있습니다.
저도 수년에 걸쳐 쌓인 GitHub 프로젝트들이 많은데, 에이전트가 생긴 후 가장 먼저 하는 일이 일단 빌드를 돌리는 것입니다. 클론해보면 의존성이 바뀌어서 빌드가 안 되기 마련이고, 여러 것들이 오래되었거나 보안 취약점을 갖고 있어서 업데이트부터 해야 합니다.
그다음에는, 테스트가 없다면 테스트를 추가해야 합니다. 프로젝트를 어떤 방식으로든 업그레이드하거나 더 현대적인 언어·프레임워크로 마이그레이션할 때, 기존 동작이 보장되도록 하기 위해서입니다.
그러다 보면 이런 생각도 하게 됩니다. 예전에는 Twitter Bootstrap을 썼는데, 이제는 모두가 Tailwind와 shadcn을 쓰니까 UI를 다시 만들어야 하지 않을까. 그리고 어느 순간 이게 예상보다 훨씬 많은 시간을 잡아먹고 있다는 걸 깨닫게 됩니다. 에이전트가 많은 부분을 빠르게 처리해주더라도, 이제는 제품 감각과 취향까지 고려해야 하기 때문입니다.
결국 이런 질문들이 남습니다. 이건 누구를 위한 것인가? 시장이 있는가? 나 자신을 위한 것인가, 다른 사람들을 위한 것인가? 이제 누구든 이런 것들을 빠르게 만들어낼 수 있는 세상에서, 이것을 내놓아도 여전히 충분한 가치가 있을까?
그래서 저는 이 질문—이것들이 존재할 가치가 있는가, 우리의 감각과 판단을 어떻게 반영할 것인가—이 여전히 매우 중요하다고 생각합니다. 바로 그 지점에서 인간의 주의라는 희소 자원이 여전히 진짜 힘을 발휘합니다. 예전에는 하루의 시간이 유한했고, 회의가 있었고, 디자인과 코딩에 쓸 시간을 따로 배분해야 했습니다.
이제 에이전트가 생겼으니, 내가 시간을 어디에 쓰고 있는지, 왜 쓰는지를 훨씬 명확하게 의식해야 합니다.
82분짜리 팩토리 실행 이야기를 해보겠습니다. 오랫동안 많은 분들이 이런 질문을 해오셨습니다. "소프트웨어 팩토리는 어떻게 만드나요?" "Claude Code나 Codex를 쓰다가 소프트웨어 팩토리로 어떻게 발전시키나요?"
이에 대한 첫 번째 대답은 "지금 방식으로도 충분할 수 있습니다"입니다. 하지만 참고할 수 있는 셋업을 직접 제공하고 싶었습니다. 그래서 Factory라는 이름의 레포지토리와 데모 애플리케이션, 워크숍을 함께 만들었습니다.
지난 몇 년간 제 데모 애플리케이션의 단골 소재는 영화 앱이었습니다. 저는 영화를 정말 좋아하고, 항상 영화를 봅니다. 그래서 매우 심플한 영화 앱으로 시작하는 데모 애플리케이션을 만들어두었고, 팩토리가 여러 기능을 구현해나가도록 했습니다. 즐겨찾기 기능, 검색 기능, 다크 테마 등이 목표였습니다.
팩토리를 실제로 돌리며 구현 과정을 직접 확인할 수 있었는데, 한 가지 큰 장점은 실제 문제들을 잡아냈다는 것입니다. 일회성으로 구현을 요청했다면 발견하지 못했을 문제들이었습니다.
60분쯤 지났을 때, 진행이 유독 느리다는 느낌이 들었습니다. 팩토리 하네스에게 "왜 이렇게 느린 거야?"라고 물었더니, "이 속도는 정상입니다. 모든 검증기가 여전히 실행 중입니다"라는 답이 돌아왔습니다.
개별 태스크가 10분, 15분, 20분 걸릴 것이라고 예상했더라도, 검증, 재시도, 브라우저 검사, 사람 리뷰, 기타 추가 지연이 포함되면 두 배에서 네 배까지 걸릴 수 있습니다.
이 모든 것이 결국 더 높은 품질과 시스템에 대한 더 큰 신뢰로 이어진다고 생각합니다. 측정 관점에서는 머지된 PR당 비용, 코드 유효 수명 같은 지표를 이해 부채 지표로 활용할 수 있습니다.
또한 '유용한 지연'과 '팩토리 오버헤드'를 구분해서 생각해야 합니다. 제 경우 검증기들이 실제 문제를 잡아냈고, 일부 시간은 제가 원하는 증거를 생성하는 데 쓰였으며, 나머지는 팩토리 자체를 실행하는 오버헤드였습니다. 최적화에 시간을 따로 쓰지 않았지만, 가치 없는 검사만 잔뜩 돌리는 팩토리가 고품질 팩토리는 아닙니다.
반복적으로 돌리는 검사들이 쓸모가 없는지, 잡음이 많은지, 실제로 시스템을 더 안전하게 만드는지를 꾸준히 살펴봐야 합니다.
검증에 대한 예산 개념을 어떻게 생각하는지를 설명하자면, 제가 과거에 성능 예산(performance budget)을 다루던 방식과 같습니다.
소프트웨어 개발 주기의 초반에 실행할 수 있는 검사들이 있고, 너무 무거워서 나중에 실행해야 하지만 충분한 가치를 제공하는 검사들도 있습니다. 린팅이나 타입 체킹처럼 비교적 빠른 검사는 초반에 실행할 수 있습니다.
전체 테스트 스위트는 드래프트 PR을 만들기 직전이나 그 이후에 실행하는 게 적합합니다. 뮤테이션 테스트, 브라우저 테스트, 보안 검사 등이 여기에 포함됩니다.
이것들을 단순한 요약본으로 대체하는 건 바람직하지 않습니다. 실제 테스트가 필요합니다. 다만 개발 루프를 느리게 만들지 않도록 적절한 위치에 배치하는 것이 중요합니다. 저는 개발 루프가 빠르게 돌아가는 것을 중요하게 여기는 동시에, 견제와 균형 역할을 하는 검사들도 반드시 갖추고 싶습니다.
지금까지 쓴 내용의 대부분은 검사에 관한 것이었습니다.
Vercel은 자사 소프트웨어 팩토리에서 모든 에이전트 실행을 "success", "flawed", "blocked", "manual" 중 하나로 분류하며, "success"만 프로덕션에 배포됩니다. 나머지는 시스템으로 다시 돌아갑니다. 저도 비슷한 방식으로 실행들을 생각하기 시작했습니다.
"flawed"는 잘못된 것이 구현되었거나 충분한 컨텍스트가 없었다는 의미로, 수정이 필요합니다. "blocked"는 환경에 자격 증명이 누락되어 있어 제공해줘야 한다는 뜻입니다. "manual"은 팩토리가 아직 넘어서도록 허용되지 않은 경계입니다.
세 가지 중 둘은 기계적인 수정이 가능하고, 마지막 하나는 신뢰의 문제입니다.
이 분류 체계는 훌륭하지만, 분류만으로는 비용을 알 수 없습니다.
TMDB 앱으로 만든 제 팩토리 구현으로 돌아가서 보면, 거절 없이 처리된 빠른 검색 기능은 7분이 걸렸습니다. 중간에 두 번의 거절과 사람의 판단이 들어간 즐겨찾기 기능은 56분이 걸렸습니다. 같은 팩토리였습니다. 그러니 분류 체계에 단계별 소요 시간을 함께 기록하는 것이 좋습니다. 그렇지 않으면 실행이 flawed로 돌아왔다는 사실은 알아도, 그 사실을 파악하는 데 얼마나 비용이 들었는지는 모르게 됩니다. 또 한 가지 개선할 점은 경계에서의 인계입니다. 제 샘플 팩토리는 첫 번째 이슈에서 멈추고 factory:needs-info로 이동시켰는데, 그 자체는 맞는 동작이었지만 저는 어디에 답을 입력해야 할지 몰랐습니다. 수동 실행은 팩토리가 멈출 때 끝나는 것이 아니라, 사람이 다음에 무엇을 해야 할지 알 때 끝납니다.
몇 주 전에 에이전트 자율성(agentic autonomy)에 관한 글을 쓴 적이 있습니다. 자율성이란 모든 프로젝트에 동일하게 적용되는 단일 설정값이 아니기 때문입니다.
검증은 신뢰를 만들고, 에이전트에게 더 많은 자율성을 부여할 수 있는 기반이 됩니다. 예를 들어 비교적 복잡한 변경 작업을 하더라도, 여러 검사가 갖춰져 있고 모든 것이 올바르게 검증되었으며 직접 확인까지 마쳤다면, 같은 프로젝트에서 비슷한 성격의 태스크를 다음에 할 때는 에이전트에게 조금 더 많은 자율성을 줄 수 있다는 확신이 생깁니다.
소프트웨어 팩토리를 만들 때 바로 이 부분을 고민해야 합니다. 검증은 리스크에 따라 달라집니다. 목표는 최고의 신호 대 잡음비입니다. 단순히 긴 체크리스트를 돌리는 것이 목적이 아닙니다.
Claude와 여러 세션을 사용하며 여러 프로젝트와 기능을 동시에 작업하던 어느 날, 계속 미뤄두던 기능 하나가 있었습니다. Claude가 그 기능을 구현했고, 테스트가 통과되는 것처럼 보였습니다. 검증에 대해 깊이 생각하지 않았지만 테스트가 통과됐으니 됐다고 생각하고 머지했습니다.
즐겨찾기 기능이었는데, 꽤 잘 된 것 같았습니다. 브라우저에서 확인해봤을 때도 괜찮아 보였습니다. 그런데 며칠 후, 몇 가지 수정을 해볼까 하는 생각에 코드로 다시 돌아갔습니다.
에이전트에게 변경을 맡기지 않고 직접 손대고 싶었습니다. 작동 방식이 미묘했기 때문입니다. 아이콘을 탭하면 탭 효과가 제대로 표시되지 않아서, 에이전트에게 정확히 안내할 수 있도록 동작 방식을 먼저 이해하고 싶었습니다.
코드로 돌아갔는데, 그 기능이 어떻게 작동하는지 설명할 수가 없었습니다. 제 레포지토리였고, 변경을 승인한 것도 저였으며, 레포의 많은 부분이 어떻게 돌아가는지도 알고 있었습니다. 하지만 계속 쌓여가는 코드를 제 이해가 따라가지 못하고 있었던 것입니다.
추가된 기능이 실제로 어떻게 작동하는지, UI는 어떻게 구성되어 있는지, 효과는 어떻게 동작하는지를 제대로 흡수하지 못했던 겁니다. 결국 그 기능을 다시 만들어야 했고, 단계별로 "이건 어떻게 동작하지? 어떻게 이해하면 되지?"를 다시 짚어가야 했습니다.
병렬 작업을 하면 이 문제가 더욱 증폭되고, 소프트웨어 팩토리에서 작업할 때는 더더욱 심해집니다. 다섯 개, 열 개의 세션을 동시에 돌리면, 단순히 리뷰 물량이 늘어나는 문제를 넘어서게 됩니다. 다른 곳에서 작업하는 동안 차갑게 식어버릴 수 있는 여러 개의 멘탈 모델이 동시에 만들어집니다.
컨텍스트 스위칭의 어려움은 늘 이야기해온 주제입니다. 대화가 요약(compact)되고, 일부 접근 방식은 기각하고, 다른 것을 시도해보고, 에이전트와 함께 페어링하다 보면, 세션에서 일어난 모든 일을 기억하기가 점점 어려워집니다.
스크롤을 올려봐도 컴팩션이 진행된 부분은 다 남아 있지 않고, 그 모든 것을 머릿속에 담아두는 것도 불가능합니다. 코드는 내려진 결정은 보존하지만, 왜 그 결정을 내렸는지는 보존하지 않는 경우가 많습니다.
이것이 유용한 교훈이 될 수 있다고 생각합니다. 중요한 지점에서는 에이전트에게 자신이 걸어온 경로, 또는 문제를 어떻게 접근했는지에 대한 흥미로운 교훈을 기록해두도록 요청하는 것을 고려해보세요. 나중에 다시 참고할 수 있도록 말입니다.
이것을 레포에 커밋할지 말지는 선택의 문제입니다. 로컬에만 보관해도 되고, 팀과 공유해도 됩니다. 하지만 이 기록은 이후에 참고할 수 있는 자료가 됩니다. 세션에 남아 있기를 바라거나, 나중에 기억이 날 것이라고 기대하는 것보다 훨씬 낫습니다.
이 모든 것의 밑바닥에는 더 큰 원칙이 있습니다.
사람이 직접 타이핑하는 코드의 비율은 급격히 줄어들 수 있습니다. 하지만 인간의 주인의식도 그와 함께 줄어들어야 한다고는 생각하지 않습니다.
문제를 선택하는 것은 여전히 사람입니다.
아키텍처를 선택하는 것도 여전히 사람입니다.
품질 기준을 정하는 것도 여전히 사람입니다.
어떤 검증 신호를 신뢰할지 결정하는 것도 사람입니다.
증거가 충분해서 출시해도 된다고 판단하는 것도 사람입니다.
그리고 결과물이 실패했을 때, "에이전트가 만든 것"이라는 말은 통하지 않습니다. 그렇기 때문에 소프트웨어 엔지니어링의 미래를 '인간이 루프에서 빠져나가는 것'으로 표현하는 건 적절하지 않다고 생각합니다. 대신, 인간의 판단이 자리를 옮기고 있는 것입니다.
기계가 더 강력하고 빠르고 확정적인 신호를 만들어낼 수 있는 루프 구간에서는 사람을 빼야 합니다. 동시에, 컨텍스트와 감각, 리스크, 장기적인 주인의식이 중요한 지점에는 사람을 집중시켜야 합니다.
최고의 소프트웨어 팩토리는 인간의 개입을 얼마나 완전히 제거했느냐로 정의되지 않을 것입니다.
인간의 개입을 얼마나 지능적으로 배치했느냐로 정의될 것입니다.
의도, 시스템 구조, 품질 기준에 대한 인간의 판단은 루프의 앞단에 두세요. 자동화된 역압이 약해지거나 결과가 주관적인 판단을 요구하는 지점에서는 코드 리뷰를 하세요. 결정론적인 신호는 가능한 한 일찍, 지속적으로 루프에 주입하세요. 시스템이 신뢰를 얻거나 잃음에 따라 제약을 의도적으로 조이거나 풀어주세요.
최종적으로 배포되는 코드에 대한 책임은 여전히 사람에게 있습니다. 출시 가능한 수준의 코드는 바로 거기서 시작됩니다.
이 글은 원래 제 Substack에 게재한 글입니다.