소프트웨어 공장은 소프트웨어 작업을 감싸는 반복 가능한 루프입니다. 소프트웨어 공장을 만들고 있다면, 배포할 만한 수준의 코드에도 여전히 사람의 취향과 책임이 필요합니다. 이 이야기를 하면서, 애초에 지금 공장이정말필요한지도 함께 따져 보겠습니다.
필요하다면:
제품 의도, (신경 쓴다면) 시스템 설계, 품질 기준선을 정하는 앞단에는 사람이 루프 안에 들어와 있어야 할 겁니다.
코드 리뷰는 하십시오(사람이 지켜보는 공장, lights-on factory). 다만 어디에 가장 필요한지 의도를 갖고 고르십시오. 제 경험으로는 자동화가 걸어 주는 제동이 듣지 않는 지점을 살펴봐야 합니다. 유지보수성을 두고 절충해야 하는 지점도 마찬가지입니다.
품질 검사는 가능한 한 이르게, 그리고 끊이지 않고 돌아가게 하는 것을 목표로 하십시오. 전부 그럴 필요는 없지만, 여기에는 타입 시스템, 자동화 테스트, 변이 테스트, 보안 스캐너, 아키텍처 규칙 린팅이 들어갑니다.
검사 개수가 곧 품질은 아닙니다. 어떤 검사가 신호 대 잡음 비를 가장 좋게 만드는지는 직접 실험해 봐야 할 겁니다. 제약을 의도적으로 조이거나 풀 준비를 해 두십시오.
공장은 사람의 취향이 환경에 일부라도 새겨지고, 에이전트가 자기 작업이 맞다는 증거를 내놓고, 운영에 나가는 것은 여전히 사람이 "책임지는" 형태로 짓는 것이 좋습니다.
정말 소프트웨어 공장이 필요합니까?
제 경험으로는 기본 코딩 하네스만으로도 놀라울 만큼 멀리 갈 수 있습니다! 예를 들어 Claude Code나 Codex를 여러 세션으로 띄우고, 검증을 안에 넣은 좋은 SPEC과 제약을 함께 쓰는 식입니다. 구현 기준과 사람이 개입할 기준을 적어 둔 GitHub 이슈를 한 번에 여러 건 던져 줄 수도 있습니다. 다만 이 체계가 반복 가능하고 이벤트에 반응해야 하는 순간이 오면 공장이 도움이 됩니다.
앞에서 소프트웨어 공장은 소프트웨어 작업을 감싸는 반복 가능한 루프라고 했습니다. 아주 작은 공장 루프를 보여 주는 프롬프트를 하나 볼 수 있습니다.
코드를 고치기 전에 GitHub 이슈 #123과 저장소 지침을 읽으세요.명시된 인수 조건만 구현하세요. 인증, 결제, 마이그레이션, 기존 테스트 단정문은건드리지 마세요. 브랜치에서 작업하고 diff는 리뷰할 수 있는 크기로 유지하세요.npm run lint, npm test, npm run build를 실행하세요. 필요한 검사를 돌릴 수 없다면멈추고 이유를 설명하세요. 실행한 검사, 남은 위험, 사람이 아직 내려야 하는 결정을적어서 초안 풀 리퀘스트를 여세요. 머지는 하지 마세요.
목표를 하나 걸어 두면 검사가 통과할 때까지 이 루프가 계속 돌아갑니다. 특정 라벨이 붙은 GitHub 이슈를 주기적으로 확인하거나, 매일 아침 열려 있는 풀 리퀘스트를 훑어볼 수도 있습니다. 브랜치 보호 규칙으로 머지 경계를 강제할 수 있고, 사람은 무엇을 준비 상태로 올릴지 고르고 리뷰하고 최종 머지를 결정하면서 루프 안에 남습니다.
Slack 트리거, GitHub 이슈, Linear, 백로그처럼 이벤트로 들어오는 작업 큐를 격리된 클라우드 환경에서 돌려 분류와 구현과 테스트를 처리하되 사람이 명시적으로 지켜봐야 한다면, 그때 소프트웨어 공장을 도입하십시오. 어떤 곳은 루프 끝에 운영을 감시하다가 이슈를 등록하는 에이전트를 두고, 그 이슈가 다시 분류 단계로 들어가게 만듭니다.
제 경험으로는, 여러 번 돌린 실행이 일관되게 동작하도록 만드는 일, 에이전트 사이에 작업을 넘기는 일, 서로 다른 세션이 같은 이슈를 집어 가지 않게 막는 일, 증거를 남기는 일, 사람 리뷰가 뒤처지면 운영 배포를 멈추는 일이 어려워질 때 공장이 유용해집니다.
이걸 푸는 방법은 조금 심심하게 들릴 수도 있습니다. 예를 들어 Warp는 들어오는 이슈를 전부 네 가지 상태 중 하나로 분류한다고 말합니다. 구현 준비 완료, 명세 준비 완료, 정보 부족, 구현 대기입니다. 그리고 그 라벨이 다음 에이전트를 띄웁니다.
이 라벨은 한 번에 여러 일을 합니다. 큐 역할을 하고, 잠금 역할을 하고, 세션이 준비 완료 표시가 붙은 것만 집어 가니까 사람이 영구히 거절하지 않고도 일감을 잠시 세워 둘 자리가 됩니다.
워크플로 측면에서는 Claude나 Codex만 쓰는 것과 비슷한 점도 있고 다른 점도 있습니다.
방향 조정: 에이전트가 궤도를 벗어나면 입력을 주고 방향을 다시 잡아 줄 수 있습니다
알림: 공장이 막혔다고 말하는 방법입니다. 요구사항이 모호했거나, 위험한 일을 시작했거나, 사람 입력이 필요할 때(방향 조정) 알림이 옵니다
인계: 작업과 그 상태와 맥락을 클라우드 공장, 다른 에이전트, 사람 리뷰어 사이에서 옮깁니다. 인계가 잘 되면 지금까지 무슨 일이 있었는지, 무엇이 남았는지, 왜 넘기는지가 함께 따라갑니다.
좋은 공장에서 사람이 하는 일은 맨 끝에서 최종 diff를 리뷰하고 승인하는 것에 그치지 않습니다. 초반에 작업의 모양을 잡고, 구현 중에 방향을 틀고, 인계를 통해 받아 가고, 운영 배포를 막을 수도 있습니다.
책임 있는 공장이 시간을 많이 쓰는 곳은 검증입니다. 뒤에서 더 다루겠습니다.
소프트웨어 공장이 필요하다고 결론이 나도, 직접 짓는 것만이 선택지는 아닙니다. 공장을 규모 있게 돌릴 인프라를 세우는 데는 손이 많이 가니 만들기와 사기를 견줘 볼 만합니다. Factory, Warp, HumanLayer가 모두 이 문제를 다루고 있습니다.
요즘 제 하루는 이렇습니다
소프트웨어를 개발하는 제 하루하루는 지난 1년 사이에 많이 달라졌습니다. 저는 에이전트와 병렬로 일하는 비중을 계속 늘려 왔고, 사람이 지켜보는 소프트웨어 공장 쪽으로 옮겨 가고 있다는 이야기를 해 왔습니다. 그러면 많은 분이 묻습니다. 그게 실제로 무슨 뜻이냐, 무엇을 만들고 있냐, 그런 걸 어떤 종류의 프로젝트에 쓰고 있냐고요. 대체로 이런 모습입니다.
아주 평범한 날에도 저는 단순한 형태로 사람이 지켜보는 소프트웨어 공장을 하나 돌립니다. 클라우드에서 돌아가는 작업을 둘 수 있습니다. 그 절반쯤은 제가 함께 일하는 작은 회사들의 운영 중인 고객 애플리케이션일 수도 있습니다. 실제 사용자가 있습니다. 실제 인증, 결제, 구독이 붙어 있고, 조심해서 다뤄야 하는 묵직한 위험이 있습니다. 테스트와 제약과 품질 검사를 갖춰 놓지도 않고 "에이전트야, 가서 이것 좀 해 둬"라고 던질 수는 없습니다.
오픈소스 프로젝트를 볼 수도 있습니다. 제 책의 부속 사이트를 만들 수도 있고, 도구를 다룰 수도 있고, 제 앱을 만들 수도 있습니다. 이들은 모두 아주 다른 종류의 애플리케이션이고, 어떤 때는 공통점이 그 작업에 쓰는 도구뿐입니다. 어떤 날은 마이그레이션을 하고, 어떤 날은 묵직한 기능 개발을 합니다. 작업이 미치는 영향 범위(blast radius)도 아주 크게 다를 수 있습니다.
그러니 병렬 작업을 점점 늘리는 지점으로 가려고 하면서, 속도와 생산성을 끌어올리고 자율성을, 다시 말해 그 체계를 더 믿을 수 있는 상태로 만들려고 하다 보면, 사람의 코드 리뷰와 사람의 입력이 반드시 필요한 자리가 어디인지 생각하지 않을 수 없습니다.
그리고 그중 많은 부분이 앞단에서 필요합니다. 명세와 요구사항을 정의할 때, 제품의 설계가 어떤 모습이어야 하는지, 제품의 의도가 무엇인지 정할 때 말입니다. 그다음에는 에이전트가 그 일을 제대로 해냈는지 어떻게 확인할지, 기존에 잘 돌던 시스템을 깨지 않았는지 어떻게 확인할지, 내 품질 기준선을 맞췄는지 어떻게 보장할지가 남습니다.
그래서 코드를 생성하는 일은 가장 걱정해야 할 부분이 아닙니다. 맥락이 충분하면 에이전트는 구현을 쓰고 테스트를 돌리고 실패를 들여다보고 코드를 고쳐 줍니다. 사람의 취향이 환경에 충분히 새겨져 있어서 만들어지는 것을 믿을 수 있다고 느끼는 상태까지 가야 합니다. 그래야 사람의 주의를 가장 필요한 자리에 모을 수 있습니다.
이런 것을 그냥 자동화로 없앨 수 있다는 말은 못 믿겠다고 반박하는 분들도 있습니다. 전부를 자동화로 없앤다는 뜻은 아닙니다. 다만 지금 생성되는 코드의 양을 생각하면 사람이 그걸 다 읽는다는 건 현실적이지 않다고 봅니다. 우리가 로켓을 만드는 것도 아니고, 대개는 UI를 만들고 풀스택 애플리케이션을 만드니까요.
우리의 판단과 취향은 가장 필요한 자리에 모아 쓰는 것이 가장 좋습니다. 이 시스템에서 가장 위험한 부분은 어디인가? 사람의 취향을 어디에 발라야 하는가? 그건 프런트엔드일 수도 있고 시스템이 동작하는 방식일 수도 있습니다. 전부일 필요는 없습니다.
제 인지 대역폭은 에이전트만큼 늘어나지 않습니다
현실은 이렇습니다. 이제 우리는 에이전트를 수십 개, 수백 개, 수천 개까지 병렬로 띄울 수 있지만, 우리 자신의 인지 대역폭은 그렇게 늘어나지 않습니다. 그래서 전에 이야기한 인지 부채, 또는 이해 부채가 쌓입니다.
5년, 10년 전을 떠올려 보면 엔지니어링 커뮤니티에서 컨텍스트 스위칭과 그 비용을 두고 말이 많았습니다. 한창 일에 몰입해 있을 때 동료가 책상으로 걸어오는 것을 사람들이 얼마나 싫어하는지 이야기했습니다. 그러면 흐름을 되찾는 데 한참이 걸렸습니다. 내가 어디까지 했지, 뭘 하고 있었지를 다시 따라잡아야 했으니까요. 머릿속에 잔상이 조금 남아 있어도 시간은 걸렸습니다.
지금 우리는 그때보다 훨씬 더 자주 맥락을 바꿉니다. 소프트웨어 공장 없이 일하는 날에도, 저는 서로 다른 프로젝트 다섯 개나 열 개를 에이전트와 동시에 진행하거나, 한 프로젝트에서 기능 다섯 개나 열 개를 동시에 진행할 수 있습니다. 세션을 다섯 개나 열 개 열어 둔다고 봐도 됩니다.
그러면 그중 적어도 몇 개는 제가 꿰고 있어야 합니다. 작업을 충분히 잘 정의했고, 결과와 완료 판정 방법까지 충분히 정해 뒀다고 믿을 수 있으면 어떤 작업에는 자율성을 더 줄 수 있습니다. 하지만 그렇게 느껴지지 않고 위험이 더 크거나 결이 미묘한 작업도 있습니다. 그런 건 제가 지켜봐야 합니다.
소프트웨어 공장을 리뷰어 기준으로 최적화하는 것도 고려해 보십시오. 어떤 방식을 쓰든 결과물은 결국 한 사람의 주의로 흘러 들어가니, 내가 여전히 내려야 하는 결정을 공장이 얼마나 더 싸게 만들어 주는지 물어봐야 합니다.
엉뚱한 프로젝트에 넣은 실수
에이전트와 여러 프로젝트를 병렬로 돌리다가 실수한 적이 있습니다. 웹 앱에 다크 모드를 넣으려던 날이었는데, 머릿속에는 이게 어떤 모양이어야 하는지 그림이 있었습니다. 그런데 실수로 다른 프로젝트의 세션으로 들어가서 그 프롬프트를 그대로 넣었습니다.
그래서 다크 모드가 전혀 필요 없는 프로젝트에 다크 모드를 구현하기 시작했습니다. 저는 그런 실수를 할 수 있습니다. 하지만 제 소프트웨어 공장이 그런 실수를 하는 건 원하지 않습니다.
이건 정말 시스템의 문제로 봐야 합니다. 사실 우리가 하려는 일은 소프트웨어 엔지니어링 문화, 팀 문화를 시스템 안에 새겨 넣어서 그 시스템이 같은 방식으로 행동하게 만들고, 책임이 어딘가에 분명히 놓여 있게 만들고, 무슨 일이 생기면 누군가는 여전히 그 책임을 지게 만들고, 그런 것들을 어떻게 생각하는지 아주 명시적으로 적어 두는 것입니다.
초록불이 사람을 속일 때
이런 체계를 갖췄더라도 아주 조심해야 합니다. AI에게 테스트를 통과시켜 달라고, 유닛 테스트 같은 걸 통과시켜 달라고 부탁했을 때 무슨 일이 벌어지는지 많이들 봤을 겁니다. 그 조건을 만족시키려고 유닛 테스트를 고쳐 버리거나, 코드 로직을 고쳐서 그 조건을 통과시킵니다. 그렇다고 기능 동작과 그 테스트가 원래 검사하려던 것을 함께 맞추라는 내 의도를 따른 것은 아닙니다.
소프트웨어 공장이 전부 초록불이라고 보여 준다고 해서 정말로 초록불인 것은 아닙니다. 특히 처음 세팅하는 시기에는 더 그렇습니다. 검사와 검증이 제대로 된 모양인지, 내가 기대한 일을 하고 있는지 꼼꼼히 봐야 합니다. 이들이 사람을 속이게 두면 안 됩니다.
이런 상황도 원치 않을 겁니다. 테스트는 통과했다고 하는데 사실은 이렇게 된 경우 말입니다. "지원하는 인증 제공자를 바꿨습니다. 예를 들어 GitHub를 인증 제공자로 추가해 달라고 하셨는데, 제 UI에는 자리가 셋뿐이라 기존 것 하나를 빼 버렸습니다. 그런데 그게 마침 고객이 실제로 원했던 것이었습니다." 그러니 이 체계가 어떻게 동작해야 하는지 아주 명시적으로 적어 둬야 합니다.
그리고 보안도 아주 중요합니다. 공장이 GitHub 이슈나 Slack 메시지처럼 신뢰할 수 없는 입력을 읽는다면 그 입력이 공격일 수 있고, 공급망 공격 같은 문제가 섞여 들어올 수 있습니다. 그래서 Vercel처럼 소프트웨어 공장을 실험하는 곳은 에이전트를 격리된 샌드박스에서 돌리고 그 작업에 필요한 비밀만 넣어 둡니다. 그러면 한 번의 실행이 털려도 그 작업에 필요 없는 것에는 손이 닿지 않습니다. 방어가 여러 겹으로 쌓이는 셈입니다.
어떤 옛 프로젝트가 다시 살아날 자격이 있을까
요즘 일하는 방식에서 큰 몫을 차지하는 것이 무엇이 존재해야 하는지 정하는 일이라고도 생각합니다. AI가 있기 전, 여러 해 전을 떠올려 보면 버려진 소프트웨어 엔지니어링 프로젝트가 참 많았습니다. 버려진 주말 프로젝트, 개인 프로젝트가 그렇게 많았고, 끝낼 시간이 없어서 출시하지 못했습니다. 우리에게 그만큼 중요하지 않았거나 시간을 못 내서, 세상에 내보내는 일을 우선순위에 올릴 여력이 없었습니다.
지금은 그런 프로젝트를 마무리하는 게 꽤 쉬워졌지만, 사람의 판단 문제는 똑같이 남습니다. 그 프로젝트들이 존재할 자격이 있는가? 출시해야 하는가? 세상에 내놓으면 사용자가 다섯 명뿐이어도 유지보수를 해야 할 수 있습니다. 이제는 지키고 싶은 품질 기준선도 생겼을 수 있습니다.
저도 여러 해에 걸쳐 쌓인 GitHub 프로젝트가 참 많은데, 에이전트가 생긴 뒤로 제일 먼저 하는 일은 일단 빌드가 되게 만드는 것입니다. 당연히, 클론하면 의존성이 다 바뀌어서 빌드가 안 됩니다. 절반쯤은 낡았거나 보안 취약점이 널려 있으니 그것부터 올려야 합니다.
그다음에는 테스트가 없었다면 테스트를 넣어야 합니다. 프로젝트를 어떤 식으로든 업그레이드하거나 더 현대적인 언어나 프레임워크로 옮길 때, 최소한 그 동작은 그대로 남아 있다는 것을 알 수 있어야 하니까요.
그러고 나면 스스로 묻기 시작합니다. 좀 시시한 예지만, 그때는 Twitter Bootstrap을 썼는데 이제는 다들 Tailwind와 shadcn을 쓰니 UI를 다시 구현해야 하겠다고요. 그러면 눈에 보이는 건, 어느새 시간이 더 들고 있다는 사실입니다. 물론 에이전트가 이 중 많은 부분을 더 빨리 해내지만, 이제는 제품 감각과 취향 같은 것들까지 계산에 넣어야 합니다.
여전히 이런 질문이 남습니다. 이건 누구를 위한 것인가? 시장이 있는가? 나를 위한 것인가, 다른 사람을 위한 것인가? 세상에 내놓는다면, 이제 누구나 이런 걸 금방 만들어 낼 수 있는데도 여전히 흥미로울까?
그래서 이것들이 존재할 자격이 있는가 하는 사람의 질문, 우리의 취향과 판단을 어떻게 계산에 넣을 것인가 하는 질문은 계속 아주 중요하게 남을 것 같습니다. 희소한 자원인 사람의 주의가 바로 여기서 진짜로 쓰입니다. 예전에는 하루에 쓸 수 있는 시간이 한정돼 있었습니다. 회의도 있었고, 설계와 코딩에 시간을 배분해야 했습니다.
에이전트가 도와주는 지금은, 내 시간을 어디에 왜 쓰는지 아주 분명히 정해 둬야 한다고 생각합니다.
직접 하나 만들어 보니
82분이 걸린 공장 실행 이야기를 해 보겠습니다. 꽤 오래전부터 사람들이 물어 왔습니다. 소프트웨어 공장을 어떻게 만드느냐고요. 또는 Claude Code나 Codex는 익숙한데, 내 세팅을 소프트웨어 공장 쪽으로 어떻게 발전시키느냐고요.
제가 먼저 해 온 말은 이렇습니다. "지금 그대로도 괜찮을 수 있습니다. 공장이 없어도 하는 일에 아무 문제가 없을 수 있습니다." 그래도 살펴볼 수 있는 참고 구성은 주고 싶었습니다. 그래서 Factory라는 저장소를 하나 만들어 뒀으니 가서 보시면 됩니다. 데모 애플리케이션과 워크숍도 함께 만들었습니다.
지난 몇 년 동안 제가 여러 가지를 시연할 때 늘 쓰던 데모 애플리케이션은 영화 앱입니다. 저는 영화를 아주 좋아합니다. 영화 보는 걸 좋아하고 늘 봅니다. 그래서 아주 단순한 영화 앱에서 출발하는 데모 애플리케이션이 있습니다. 그리고 이 공장이 해 주기를 바라는 것은 기능 몇 개를 구현하는 일입니다. 서로 다른 기능이 몇 개 있습니다. 즐겨찾기 기능이 있으면 좋겠고, 검색도 되면 좋겠고, 다크 테마도 들어가면 좋겠습니다. 그런 것들입니다.
그래서 공장을 돌려 이 작업을 시작했습니다. 구현은 직접 보실 수 있습니다. 좋았던 점 하나는 실제 문제를 잡아냈다는 것입니다. 그냥 한 번에 구현해 달라고 했다면 제가 못 잡았을 문제들입니다.
60분쯤 지났을 때 이거 유난히 느리다는 느낌이 들었습니다. 공장을 돌리는 하네스에 왜 느린지 물었습니다. 답은 이랬습니다. "전혀 문제없습니다. 검증기가 아직 다 돌고 있습니다."
개별 작업이 10분, 15분, 20분쯤 걸릴 거라고 예상했을 수 있지만, 검증과 재시도와 브라우저 검사와 사람 리뷰 같은 추가 지연이 붙기 시작하면 두 배에서 네 배까지 걸릴 수 있습니다.
그게 더 나은 품질과 시스템에 대한 더 큰 신뢰로 쌓인다고 생각합니다. 측정 관점에서는 머지된 PR당 비용이나 코드가 살아 있는 기간 같은 지표를 이해 부채 지표로 볼 수 있습니다.
무엇이 의미 있는 지연이고 무엇이 공장 오버헤드인지도 생각해야 합니다. 제 경우에는 검증기가 실제 문제를 몇 개 잡았습니다. 일부 시간은 제가 원했던 증거를 만드는 데 들어갔습니다. 일부는 공장이 돌아가는 데 붙는 오버헤드였습니다. 최적화에 시간을 들이지는 않았지만, 가치를 못 느끼는 검사만 많이 돌리는 공장이 품질 좋은 공장이라는 뜻은 아닙니다.
반복해서 도는 검사는 이렇게 살펴봐야 합니다. 관련 없는 검사인가? 잡음만 내는가? 정말로 시스템을 더 안전하게 만드는가?
검증 예산
검증에 쓸 예산을 어떻게 생각하는지 말하자면, 결국 이 이야기입니다. 검증 예산 말입니다. 저는 예전부터 성능 예산을 생각해 온 방식과 똑같이 봅니다.
개발 생애주기 앞쪽에서 돌릴 수 있는 검사가 있고, 아주 무겁지만 그만큼 가치가 커서 뒤쪽에서 돌리고 싶은 것도 있습니다. 린팅이나 타입 검사처럼 빠른 검사도 있습니다. 이런 건 비교적 빠르니 앞쪽에서 돌릴 수 있습니다.
테스트 전체는 초안 PR을 만들기 직전이나 그 뒤에 돌릴 수 있습니다. 여기에는 변이 테스트, 브라우저 테스트, 보안 검사 같은 것이 들어갈 수 있습니다.
이런 것들을 요약으로 대체하고 싶지는 않을 겁니다. 실제 테스트가 필요합니다. 다만 개발 루프가 느려지지 않도록 알맞은 자리에 예산을 배분해야 합니다. 저는 제 개발 루프가 느려지는 건 절대 원하지 않습니다. 빠른 반복 루프는 제게 중요하지만, 그러면서도 견제와 균형 장치는 남겨 두고 싶습니다.
실행이 배포까지 가지 못할 때
위에서 쓴 이야기는 대부분 검사에 관한 것입니다.
Vercel은 자기 소프트웨어 공장에서 에이전트 실행을 전부 "성공", "결함", "막힘", "수동" 중 하나로 표시하고, "성공"만 운영에 나갑니다. 나머지는 시스템으로 다시 들어옵니다. 저도 실행을 비슷한 틀로 생각해 왔습니다.
여기서 "결함"은 엉뚱한 것을 구현했거나 맥락이 온전하지 않았다는 뜻이니 고쳐야 합니다. "막힘"은 환경에 자격 증명 같은 것이 빠져 있어서 사람이 넣어 줘야 한다는 뜻입니다. "수동"은 공장이 아직 넘어가면 안 되는 경계입니다.
이 셋 중 둘은 기계적으로 고칠 수 있고, 마지막 하나는 신뢰의 문제입니다.
이렇게 분류하는 건 좋지만, 분류만으로는 비용이 보이지 않습니다.
TMDB 앱으로 만든 제 공장 구현으로 돌아가 보면, 반려가 한 번도 없었던 빠른 찾기 기능은 7분이 걸렸습니다. 즐겨찾기는 반려가 두 번, 중간에 사람이 내린 결정까지 껴서 56분이 걸렸습니다. 같은 공장인데도 그렇습니다. 그래서 저는 이 분류에 단계별 시간을 함께 붙이겠습니다. 그러지 않으면 실행이 결함으로 돌아온 사실은 알아도, 그것을 알아내는 데 무엇을 치렀는지는 모르게 됩니다. 또 고치고 싶은 것은 경계에서의 인계입니다. 제 예시 공장은 첫 이슈에서 멈추고 그것을 factory:needs-info로 옮겼는데, 그 판단 자체는 옳았지만 제 답을 어디에 적어야 하는지는 알 수 없었습니다. 수동 실행은 공장이 멈춘 시점에 끝나는 게 아니라, 사람이 다음에 무엇을 해야 하는지 알게 된 시점에 끝납니다.
자율성은 스위치 하나가 아닙니다
몇 주 전에 에이전트 자율성과 자율성을 어떻게 생각해야 하는지에 관한 글을 썼습니다. 자율성은 모든 프로젝트에 똑같이 적용되는 스위치 하나가 아니기 때문입니다.
검증을 해 두면 신뢰가 생기고, 에이전트에게 자율성을 더 줄 수 있는 여지가 생깁니다. 예를 들어 만만하지 않은 변경을 하는데 검사를 여럿 걸어 뒀고, 전부 제대로 검증됐고, 제가 직접 손으로 확인까지 했다면, 같은 프로젝트에서 다음에 비슷한 작업을 할 때는 에이전트에게 자율성을 조금 더 줘도 괜찮다고 느낄 수 있습니다.
소프트웨어 공장을 만들 때 생각해야 하는 것이 이 부분입니다. 검증은 위험에 따라 달라집니다. 목표는 신호 대 잡음 비를 가장 좋게 만드는 것입니다. 그냥 긴 체크리스트를 돌리는 게 목표가 아닙니다.
다시 배워야 했던 기능
Claude로 여러 세션을 돌리던 어느 날, 미뤄 두고 있던 기능이 하나 있었습니다. 그때 저는 여러 프로젝트를 동시에, 프로젝트마다 기능 여러 개를 동시에 진행하고 있었습니다. Claude가 제가 작업하던 그 기능을 구현했습니다. 테스트는 통과하는 것처럼 보였습니다. 검증에 별 생각을 들이지 않았지만 테스트가 통과했으니 잘 돌아간다고 생각했습니다. 그래서 머지했습니다.
즐겨찾기 기능이었습니다. 저는 이게 꽤 괜찮다고 생각했습니다. 브라우저에서 확인해 봤고 괜찮아 보였습니다. 그런데 며칠 뒤에 손볼 데가 있어서 코드로 돌아갔습니다.
에이전트에게 그냥 바꿔 달라고 하고 싶지는 않았습니다. 동작이 미묘했기 때문입니다. 아이콘을 누르면 누를 때 나와야 할 효과가 제대로 나오지 않아서 그걸 손보고 싶었습니다. 에이전트를 제대로 안내하려면 제가 그 동작 방식을 이해해야 했습니다.
코드로 돌아갔는데, 그 기능이 어떻게 동작하는지 설명할 수 없었습니다. 제 저장소였습니다. 그 변경을 제가 승인했습니다. 저장소의 많은 부분은 어떻게 돌아가는지 알고 있었지만, 제 이해가 쌓여 가는 코드를 따라가지 못했습니다.
제가 흡수하지 못한 것은 새로 들어온 그 기능이 실제로 어떻게 동작하는지, UI가 어떻게 동작하는지, 그 효과가 어떻게 나오는지였습니다. 결국 이 기능을 다시 만들면서 한 단계씩 짚어야 했습니다. 이건 어떻게 동작하지? 어떻게 이해할 수 있지?
병렬 작업이 이해도에 하는 일
병렬로 일하면 이 문제가 전체적으로 커지고, 소프트웨어 공장에서 그렇게 하면 더 커집니다. 세션을 다섯 개나 열 개 돌리면 단순히 리뷰할 양이 늘어나는 문제로 끝나지 않습니다. 내가 다른 곳에서 일하는 동안 꽤 차갑게 식어 버릴 수 있는 머릿속 모델이 여러 개 생깁니다.
컨텍스트 스위칭이 어렵다는 이야기는 오래전부터 해 왔습니다. 대화가 압축되고, 어떤 접근은 퇴짜를 놓고, 이것저것 시도하고, 에이전트와 짝을 지어 일하다 보면 그 세션에서 무슨 일이 있었는지 다 기억하기 어렵습니다.
위로 스크롤해 볼 수는 있지만, 그동안 압축이 일어났으니 전부 남아 있지 않고, 머릿속에 다 담아 둘 수도 없습니다. 코드는 어떤 결정이 내려졌는지는 남기지만, 왜 그렇게 결정했는지는 남기지 않는 일이 많습니다.
여기서 배울 만한 점이 있다고 생각합니다. 중요한 곳에서는 에이전트에게 자기 작업 경로나 문제에 어떻게 접근했는지에 관한 흥미로운 교훈을 기록해 두게 하는 것을 고려해 보십시오. 나중에 다시 찾아볼 수 있도록 말입니다.
이걸 저장소에 커밋할지는 선택입니다. 로컬에만 둬도 되고, 팀과 공유해도 됩니다. 어느 쪽이든 나중에 꺼내 볼 수 있는 자료가 됩니다. 그 내용이 세션에 남아 있기를 바라거나 내가 나중에 기억해 내기를 바라는 것보다 낫습니다.
책임은 사라지지 않습니다
이 모든 것 아래에는 더 넓은 원칙이 하나 있습니다.
사람이 직접 타이핑하는 코드의 비율은 크게 떨어질 수 있습니다. 그렇다고 사람의 책임까지 함께 떨어져야 한다고는 생각하지 않습니다.
문제를 고르는 것은 여전히 누군가입니다.
아키텍처를 고르는 것도 여전히 누군가입니다.
품질 기준선을 정하는 것도 여전히 누군가입니다.
어떤 검증 신호를 믿을지 정하는 것도 누군가입니다.
증거가 배포해도 될 만큼 충분한지 판단하는 것도 누군가입니다.
그리고 그렇게 만든 시스템이 실패했을 때 "에이전트가 썼다"는 말은 통하지 않습니다. 그래서 저는 소프트웨어 엔지니어링의 미래를 사람이 루프에서 빠지는 것으로 설명하는 게 가장 적절하다고 보지 않습니다. 그보다는 사람의 판단이 자리를 옮기고 있습니다.
기계가 더 강하고 빠르고 결정적인 신호를 낼 수 있는 루프 구간에서는 사람을 빼야 합니다. 동시에 맥락과 취향과 위험과 장기적인 책임이 가장 중요한 자리에는 사람을 모아야 합니다.
가장 좋은 소프트웨어 공장은 사람의 개입을 얼마나 완전히 없앴는지로 규정되지 않을 것입니다.
사람을 얼마나 똑똑하게 배치했는지로 규정될 것입니다.
의도, 시스템의 모양, 품질 기준선에 관한 사람의 판단은 앞단에 두십시오. 자동화가 걸어 주는 제동이 약해지는 곳이나 결과 판단이 주관적으로 흐르는 곳에서는 코드를 리뷰하십시오. 결정적인 신호는 전부 최대한 이르게, 그리고 끊이지 않고 루프에 넣으십시오. 시스템이 신뢰를 얻거나 잃는 정도에 맞춰 제약을 의도적으로 조이고 푸십시오.
결국 어떤 코드가 배포되는지는 여전히 사람이 책임져야 합니다. 배포할 만한 코드는 여전히 거기서 시작합니다.