인류 역사의 대부분 동안 우리는 코드 리뷰를 통해 코드 품질을 평가해 왔습니다. 누군가가 작성한 코드를 읽고 그것이 깔끔하고, 사려 깊고, 빠르고, 이해하기 쉬우며, 테스트가 잘 되어 있는지 확인하는 방식입니다. 하지만 에이전트의 경우 이 접근 방식은 확장이 어렵습니다. 누구도 읽을 수 없을 만큼 코드가 너무 많기 때문입니다. 그 결과, 품질 검사의 점점 더 많은 부분이 에이전트를 둘러싼 하네스, 환경, 운영 체제에서 이루어져야 합니다. 저는 여전히 코드를 읽고 리뷰하지만, 제약 조건을 검사 수단으로 삼는 것에 대해 어디까지 편안한지 매우 신중하게 결정합니다.
이제 소프트웨어 품질은 에이전트 주변에 설정하는 제약 조건에 달려 있습니다.

Guillermo의 목록은 코드 읽기를 건너뛰어도 되는지 판단하는 좋은 테스트입니다. 모든 "예"라는 대답이 실제로는 리스크가 얼마나 낮은지에 대한 진술이라는 점을 주목하세요. 사용자가 없고, 일회성 코드이고, 프로토타입이라는 식이죠. 리스크가 커지면 누군가는 코드를 읽어야 합니다. 매 diff에서 직접 읽지 않는다면 제약 조건이 그 역할을 해야 합니다.
제약 조건은 에이전트의 제안에 테스트와 결정론적 제약을 적용함으로써 시스템이 무엇을 할 수 있는지를 정의합니다. 바로 이러한 제약 조건을 설정하고 유지함으로써, 에이전트가 매일 수십만 또는 수백만 개의 변경 사항을 만들 때에도 고품질 프로덕션 소프트웨어를 안정적으로 제공하는 루프를 구축할 수 있습니다.

우리는 이러한 제약 조건을 품질 게이트라고 부르며, 그 형태는 다양합니다.
여기에는 일반적인 유닛 테스트, 프로퍼티 테스트, 인수 테스트가 포함됩니다. 또한 코드 변형을 생성하고 동일한 테스트로 실행하여 우리가 놓치고 있는 버그가 몰래 들어오지 않는지 확인하는 뮤테이션 테스트도 포함됩니다. 그리고 순환 복잡도(cyclomatic complexity)와 줄 길이처럼 코드를 읽기 쉽게 유지하는 데 도움이 되는 코드 품질 지표도 포함됩니다.

코드를 읽을지 말지에 대해 의견이 갈려도 메커니즘에는 동의할 수 있습니다. Guillermo는 코드를 읽습니다. Bob은 전혀 읽지 않습니다. 둘 다 검증의 관문을 설명하고 있으며, 차이는 그 안에 인간이 있는지 여부뿐입니다. (저는 Bob의 다른 견해를 지지하지 않습니다)
제약 조건은 시스템이 어떤 제안을 수용하고 코드 변경으로 적용할지 결정하는 데에도 중요한 역할을 합니다. 변경 제안이 에이전트를 실행하는 인터프리터에서 에이전트 컨트롤러를 거쳐 프로덕션으로 이동할 때까지, 우리는 그 변경이 안전하게 배포될 수 있고 그 영향이 에이전트의 범위 내에 있다고 확신할 수 있을 만큼 충분한 검사를 수행합니다.
에이전트는 무엇이든 제안할 수 있습니다. 제안이 배포하기에 충분히 안전하고, 정확하며, 범위가 적절하고, 유용한지 여부는 여러분의 제약 조건이 결정합니다.
이 모델은 많은 것을 제공하지만 많은 부분을 생략하기도 하며, 이러한 생략은 오늘날 생각해볼 가치가 있습니다. 한 가지 문제는 자율성입니다. 에이전트는 의도를 잘 수행할 수 있지만, 정보가 부족하거나 수행하려는 작업이 모호할 때는 실패할 수 있습니다. 이는 작업 자체와, 하네스·환경·기타 구성 요소가 작업을 어떻게 파라미터화하는지 모두에 적용됩니다.
인간이 훌륭한 코드를 배포하지 못하는 많은 이유는 에이전트도 동일하게 겪을 수 있습니다. 스크립트 기반 스트레스에서 버티지 못하는 취약한 환경, 비결정적 빌드, 누락된 권한, 약한 테스트 등이 그 예입니다. 이는 에이전트에게 신뢰할 수 있는 피드백을 제공하고, 피해가 적은 실패 모드를 허용하며, 점진적으로 성공을 쌓아가기 쉽게 만드는 더 나은 환경의 필요성을 뒷받침합니다.

우리가 추구하는 환경은 에이전트가 실제 작업을 수행하고, 신뢰할 수 있는 피드백을 받으며, 큰 피해 없이 실패할 수 있는 환경입니다.
또 다른 중요한 문제는 신뢰입니다. 우리는 현대 에이전트처럼 똑똑하고 강력한 대상이라 할지라도 정확성을 검증하지 않은 채 의도를 쉽게 맡길 수 없습니다. 신뢰에서 출발하되, 그 신뢰는 쉽게 얻어지지 않습니다.

일부 제약 조건은 작업이 시작되기 전에 형태를 만듭니다. 다른 제약 조건은 에이전트가 작업하는 동안 피드백을 제공합니다. 또 다른 제약 조건은 에이전트의 결과물이 프로덕션 경계를 넘을 수 있는지 여부를 결정합니다.
시스템 주변에 검증 구조를 배치하는 방법을 모델링하는 방식은 다양합니다.
제 경험상 유닛 테스트에만 의존하는 대신 의도적으로 선택된 더 넓은 범위의 검사를 제약 조건으로 두는 것이 도움이 됩니다. 핵심은 각 검사가 고유한 책임을 가지며, 그 범위는 타입 안전성과 성능부터 후기 단계의 보안 스캐닝까지 다양할 수 있다는 것입니다. 팀은 ESLint 같은 린팅 도구가 강제할 수 있는 아키텍처 규칙을 포함해 자신만의 제약 조건을 정의할 수도 있습니다. 이러한 도구 중 다수는 문제가 발생했을 때 에이전트나 인간을 투입하는 데 사용할 수 있는 내장 훅을 제공합니다.
현재로서는 유용한 에이전트 결과물과 형편없는 결과물 사이의 차이는 대부분 루프를 운영하는 팀의 역량에 달려 있습니다.
AI는 대량의 코드 생성과 빠른 속도를 제공하지만, 그만큼 인간이 모든 변경 사항을 하나하나 검토하기는 더 어려워집니다. 대신 인간의 주의가 어디로 향할지 의도적으로 결정해야 합니다. 기계 속도로 움직이는 시스템에 인간의 검토 지점을 넣는다면 생산성에 영향을 미쳐도 놀라지 마세요. 인간의 주의는 희소하고 가치 있는 자원이므로, 우리의 판단이 필요한 가장 미묘한 문제에 그것을 적극적으로 투입해야 합니다. 후속 단계의 인간은 제약 조건에 대한 자동화된 안전장치가 무너졌을 때만 투입되어야 합니다.
미래의 인간 "코드 리뷰"는 매우 다른 모습이 될 것입니다
정확성은 중요한 측면 중 하나이지만, 유지보수성, 성능, 보안, 효율성, 이해 용이성과 같은 다른 측면도 중요하게 여길 수 있습니다. 정확성이 다양한 신호 유형으로 세분화되듯이, 나머지 품질 요소도 마찬가지입니다. 제약 조건을 얼마나 많이 마련했는지도 중요하지만, 그것들이 품질 및 프로덕션 준비 기준을 충족할 만큼 충분히 엄격한지가 더 중요합니다.
소프트웨어 품질은 단일 지표가 아닙니다. 여러분과 팀에게 각기 다른 중요도를 지닌 신호의 집합이라고 생각하세요.
백프레셔는 다양한 도구를 통해 구현할 수 있습니다. 컴파일러가 유효하지 않은 코드를 거부하고, 테스트가 실패하고, 보안 정책이 나쁜 관행을 차단하고, CI가 배포를 거부하는 방식입니다. 이상적으로는 모든 작업이 끝난 후 단 한 번의 리뷰가 아니라 루프 전체에 걸쳐 존재해야 합니다.

Dex Horthy의 『Why Software Factories Fail』에 나오는 동일한 루프의 지도입니다. 녹색 상자는 인간 리뷰가 루프로 대체되는 것이 아니라 루프 안으로 다시 들어가야 한다는 그의 주장을 담고 있습니다.
제약 조건과 백프레셔를 통해 에이전트는 문제가 되기 전에 잘못된 작업을 잡아낼 수 있습니다
변경의 양이 우리 도구가 처리할 수 있는 것보다 많아서 제약 조건을 적용할 수 없다면 어떻게 될까요? 결국 큐를 만들고 인간의 속도로 움직이는 검증 시스템에 의존하게 됩니다. 확장을 위해서는 마지막까지 기다리는 대신 가능한 한 많은 것을 검증 루프에 계속 투입해야 합니다. 자동화된 검사 내에서 확장할 수 있다면 전체 전달 시스템의 속도와 처리량을 높일 수 있습니다. 검증 루프에 여유가 없다면 몇 가지 중 하나를 선택해야 합니다.
첫째, 검증 시스템을 확장하여 들어오는 변경 사항을 제약하고 반려할 수 있는 더 많은 용량을 확보할 수 있습니다. 둘째, 에이전트가 새로운 변경을 생성하는 속도를 줄여 검증이 작업량을 따라잡을 수 있게 할 수 있습니다. 셋째, 품질 기준을 낮추어 검증이 그렇지 않은 경우보다 덜 엄격하게 반려하도록 할 수 있습니다. 확장 관점에서 우리는 이 모든 것을 할 준비가 되어 있어야 합니다. 동시에, 일부 방향에서 제약을 완화하면 실제로 더 많은 것을 성취할 수 있다는 사실을 인식하는 데 그쳐서는 안 됩니다. 어쩌면 에이전트 개발자 스웜이나 자동화된 소프트웨어 팩토리를 제공하여 각 변경 사항을 우리가 검토할 때까지 기다리지 않고 변경을 생성함으로써 에이전트 생성 변경의 속도를 높일 수 있을지도 모릅니다.
그리고 일부 영역에서는 더 엄격한 제약 조건을 유지하는 대신 다른 영역에서 에이전트에게 더 많은 자유를 주고 싶을 수도 있습니다. 가장 중요하게 여기는 곳에 더 엄격한 제약 조건을 적용함으로써 품질을 희생하지 않고 처리량을 극대화할 수 있습니다. 이러한 결정에는 많은 옵션이 있습니다. 가장 명백하게는 품질의 다양한 측면 사이에서 트레이드오프를 해야 합니다. 우리가 강조했듯이 보안은 매우 중요하지만, 보안을 제공하는 것과 제품을 제때 제공하는 것 사이에서도 트레이드오프를 해야 합니다. 한쪽 끝은 혁신 중심, 다른 쪽 끝은 품질 중심의 스펙트럼이 있습니다. 우리는 그 스펙트럼의 어디쯤에 위치하고 싶은지 어딘가에서 선택을 해야 합니다.
환경과 시스템에서 에이전트나 팀으로 명확한 피드백을 보내서, 사람들이 취향, 의도, 아키텍처와 같은 더 주관적인 문제에 집중할 수 있게 해야 합니다. 인간이 제약 조건의 안전한 범위 안에 머물도록 도울 수 있다면, 문제가 발생한 원인을 찾기 위해 애쓰는 수고를 피할 수 있습니다.
소프트웨어 품질은 정확성만을 의미하지 않습니다. 소프트웨어 품질은 유지보수성, 우수한 성능, 보안, 효율성, 이해 용이성도 의미합니다. 이러한 기준을 충족하고 프로덕션 흐름을 유지하는 데 도움이 되는 모든 제약 조건은 전달 파이프라인에 백프레셔를 만듭니다.
강력한 제약 조건을 어디에 적용하고 어디에서 제거하거나 완화할지 신중하게 결정해야 합니다. 이 두 가지 목표를 모두 충족하는 곳에는 강력한 제약 조건을 적용하세요. 어느 목적도 충족하지 못하는 제약 조건은 유지하지 마세요. 상황에 따라 기준을 높이거나 낮출 준비를 하세요. 그리고 소프트웨어 시스템 곳곳에 있는 제약 조건이 바로 소프트웨어 품질을 강제 가능하게 만든다는 점을 기억하세요.
이 이중 목적을 가장 잘 충족하는 곳에 강력한 제약 조건을 적용하고, 어느 목적도 잘 충족하지 못하는 제약 조건은 제거하거나 완화하는 것을 고려해야 합니다. 또한 필요에 따라 품질 기준을 높이거나 낮출 준비가 되어 있어야 합니다. 결국 소프트웨어 시스템의 여러 지점에 있는 이러한 제약 조건이 품질에 실질적인 힘을 부여합니다. 많은 경우 새로운 도구를 배포하거나 기존 도구를 강화함으로써 더 많은 백프레셔와 제약 조건을 만들 수 있습니다. 이 모든 것은 대부분의 변경 요청을 반려하는 데 사용할 수 있습니다. 파이프라인 전체에 걸쳐 이를 구축해야 합니다.
파이프라인 끝에서 CI 시스템이 문제를 해결하지 않으면 배포할 수 없다고 알려줄 때까지 기다리고 싶지 않습니다. 가능한 모든 경로를 통해 이러한 신호를 최대한 빨리 사용하고 싶습니다. 이 시스템에서 궁극적인 제약 조건은 시스템을 구축하고 운영하기 위해 내린 결정과 행동에 책임을 지기 위해 우리 자신에게 부과하는 것입니다. 하지만 다른 모든 제약 조건과 마찬가지로, 우리의 판단이 얼마나 많이 제약하고, 백프레셔를 가하고, 최종 검사 역할을 하기를 원하는지 신중한 트레이드오프를 해야 합니다.
품질은 에이전트 주변에 배치하는 제약 조건에 있습니다. 따라서 여러분의 앱 품질을 생각할 때 이 문제 정의를 바탕으로 자신만의 제약 기반 계획을 수립하세요.

품질에 대해 말하자면, 이제 에이전트가 코드를 작성합니다. Sonar는 이를 배포 가능하게 만드는 품질 게이트를 제공합니다. 매 커밋마다 동일한 완전한 검사를 실행합니다. 심층적인 파일 간 분석, 리스크가 있는 위치를 보여주는 맵, 그리고 모든 인간과 에이전트를 하나의 기준으로 평가하는 품질 게이트를 제공합니다.
이 기사는 100% 인간이 작성한 것으로 Pangram 4가 평가했습니다.





