TREX: AI 코드 리뷰어가 코드를 실행한다

발행: (2026년 6월 18일 AM 12:29 GMT+9)
14 분 소요

출처: 해커 뉴스

저는 Greptile 소프트웨어 엔지니어인 숄크입니다. 최근 우리는 PR을 검토하는 것뿐만 아니라 코드를 실행하고 문제가 무엇인지 보여주는 코드 리뷰어를 만들었습니다.

1976년, 마이클 파간은 논문을 통해 IBM에서 정식 코드 검토를 소개했습니다. 개발자들은 리스팅을 인쇄하고 방에 모여서 줄 단위로 코드를 읽었습니다.

오늘도 우리는 화면에서 디프를 읽고 있습니다. AI 도구는 이를 빠르게 만들었지만 대부분은 여전히 코드만 읽는 것입니다. 이 방식은 코드에 명백히 드러나는 버그들을 다루기에 적합합니다.

문제는 코드 자체에 전혀 나타나지 않는 버그들이 존재한다는 점입니다. 실행 중 발생합니다. 예를 들어 특정 상태 시퀀스가 필요한 논리 오류, 페이지가 로드된 후에 나타나는 UI 회귀, 혹은 실제 요청이 필요한 경합 조건을 생각해 보세요. 디프를 완벽히 읽어도 이러한 버그들을 완전히 놓칠 수 있습니다.

정적 코드 리뷰에는 한계가 있습니다. 코드가 무엇을 말하는지는 추론할 수 있지만, 실제로 어떤 행동을 하는지는 알 수 없습니다. TREX (Test, Run, Execute의 약자)은 Greptile이 이 한계를 극복하기 위해 만든 대응책이며, 코드 리뷰에 직접 통합된 실행 레이어입니다.

컨텍스트를 낭비하지 않고 에이전트 조율

TREX는 Greptile과 완전히 별도의 제품으로 시작되었습니다. standalone 에이전트가 테스트를 생성하고 실행하는 것이었습니다. 우리는 버그가 발견될 것이라고 기대했지만 이루어지지 않았습니다. 테스트 생성은 버그 탐지와 동일한 작업이 아니었습니다. 별도의 TREX 에이전트가 테스트를 작성할 때, 사용자가 시도한 것과는 관련성이 없었고 불필요한 노이즈를 만들었으며 엣지 케이스를 놓쳤습니다. retrospecively 보면 당연해 보이지만 예상보다 더 오래 걸렸습니다.

우리는 각 에이전트가 자체 컨텍스트 창을 가지게 하려고 별도로 구현했습니다. 또한 두 에이전트는 서로 지식을 공유하지 않고 독립적으로 실행되었습니다. 종종 동일한 코드베이스 부분을 두 번 탐색하면서도 어느 에이전트도 다른 에이전트가 이미 발견한 것을 알지 못했고, 결국 연산 자원을 낭비하게 되었습니다.

가장 쉬운 해결책은 두 에이전트를 하나로 합치는 것이었습니다. 우리는 시도했지만 다른 문제를 마주했습니다: 전체 리뷰를 처리하는 단일 에이전트가 과부하가 발생했습니다. 서비스를 띄우고 스크린샷을 찍고 테스트를 실행하는 등 context 양이 많아 한 에이전트가 깔끔하게 관리하기 어려웠습니다.

해결책은 TREX가 메인 Greptile 리뷰어와 동일한 컨텍스트를 공유하도록 하는 것이었습니다. 완전히 별도의 제품으로 존재하지 않도록 했죠. 이는 한 에이전트 안에서 다른 에이전트를 관리하는 첫 번째 시도였습니다. 두 개의 독립적인 에이전트가 아니라, TREX는 기존 Greptile 리뷰어 에이전트가 이미 발견한 내용을 물려받고 자체 컨텍스트 창을 가지며, 조사해야 할 특정 문제에 대해 스코프가 잡힌 상태입니다.

Greptile 리뷰어 에이전트는 오케스트레이터 역할을 합니다. 디프를 읽고 조사할 가치가 있는 문제를 식별한 뒤, 각 문제에 대해 전용 TREX 에이전트를 독립적으로 실행합니다. TREX 에이전트는 오케스트레이터 에이전트의 자유, 연산 능력, 그리고 지식을 갖게 됩니다.

이것의 좋은 예시는 인증 게이트 뒤에 숨겨진 UI 기능입니다. 로컬에서 테스트하려면 환경을 설정하고 인증을 처리하며, 기능 플래그를 올바른 상태로 만드는 것이 필요합니다. 서브에이전트는 이를 스스로 해결하고 렌더링된 기능을 스크린샷으로 반환합니다.

아키텍처 다이어그램: PR을 검토하던 단일 에이전트와 모래박스 실행 및 아티팩트 출력을 수행하는 병렬 TREX 서브에이전트를 생성하는 오케스트레이터 에이전트가 등장한 후의 차이를 보여줍니다

TREX의 초기 버전은 테스트한 내용과 발생한 결과를 나열하는 불릿 포인트 형식으로 결과를 출력했습니다. 이는 타당한 시작점이었지만 충분한 정보는 제공하지 않았습니다.

에이전트나 인간 리뷰어가 ‘체크아웃 흐름을 테스트했고 실패했다’는 불릿 포인트를 읽으면 큰 도움이 되지 않습니다. 어디에서 문제가 발생했는지 알 수 없습니다. 테스트가 실패한 원인이 설정 문제였는지, 어설션이었는지, 환경 이슈였는지 알 수 없습니다. 초기 에이전트 버전은 자신이 전혀 테스트하지 않았다고 주장하며 과장하는 경우가 있었습니다. 불릿 포인트는 검증할 방법이 없었습니다.

해결책은 각 TREX 발견에 대해 스크린샷, 로그, API 트레이스, 실행 스크립트 등 다중 모달 아티팩트 집합을 뒤에 붙이는 것이었습니다. 각각의 모달은 이야기를 구성하는 다른 부분을 담고 있습니다. 특정 문제에 대해 테스트한 모든 것을 포괄적으로 보여주는 것이 실제 중요합니다.

첫 번째 아티팩트가 ‘와우’를 외치게 만든 것은 비디오였습니다. 애니메이션 변경을 푸시하면 TREX는 이를 재생하는 비디오를 캡처합니다. 로컬 환경을 열 필요 없이 애니메이션의 정확한 모습을 볼 수 있습니다.

아티팩트도 신뢰성을 확보해야 합니다. 모든 아티팩트는 리뷰어가 스스로 검증할 수 있는 충분한 정보를 제공해야 합니다. 스크린샷, 로그, 트레이스, 스크립트는 모두 사용자나 하위 에이전트가 정확히 어떤 일이 발생했는지 확인하도록 돕습니다. 잘못된 증거는 없음보다 더 나쁩니다.

아티팩트가 특히 하위 에이전트에게 중요한 이유는 교사가 학생들에게 작업을 보여줄 것을 요구하는 것과 같습니다. 초등 수학과 비슷합니다. 답을 얻기 전까지는 어디서 오류가 발생했는지 알 수 없습니다. 에이전트도 마찬가지입니다. 아티팩트가 테스트가 결론에 도달하도록 한 모든 단계를 증명한다면, agente는 정확히 어느 단계에서 문제가 발생했는지 식별할 수 있습니다. 트레이스가 없으면 답만 있을 뿐, 그 답은 수정할 위치를 알려주지 않습니다.

TREX가 버그를 발견하면 PR에 댓댓으로 나타납니다. 기능이 정상 작동한다면 요약에 실제 테스트가 되었다는 증거로 기록됩니다. 모든 실행이 잘못된 점을 찾아야만 유용한 것은 아닙니다.

단일 TREX 발견이 아티팩트 집합과 매핑된 다이어그램: 이슈는 TREX 서브에이전트 샌드박스로 전달되고, 로그, 스크린샷, 비디오를 포함한 증거와 함께 결과를 출력합니다

모델 제공업체 간 경쟁은 빠르게 진행됩니다. 한 달에 코드 작업에서 선도하는 모델이 다음月には 뒤처질 수 있습니다. 특정 제공업체의 API에만 tightly 구축하면 순위가 바뀔 때마다 재구성을 해야 합니다. 이는 장기적인 전략으로 viability가 없습니다.

우리는 처음부터 TREX를 모델 무관 하니스 설계에 기반해 만들었습니다. 이는 프론티어 모델 간을 핫 스와핑하면서도 재구성을 필요로 하지 않게 합니다. 이 유연성은 기대보다 더 깊게 확장됩니다: 메인 에이전트와 서브에이전트는 서로 다른 제공업체를 사용할 수 있으며, 동일한 리뷰 내에서 여러 모델을 동시에 실행할 수 있습니다. 이를 통해 내부 평가를 바탕으로 언제든지 최적의 모델을 선택할 수 있게 됩니다.

현재 우리의 평가는 재현율(예: 오픈소스 PR이나 주석이 해결된 고객 데이터에서 실제 버그가 몇 개 잡혔는지)과 정밀도(예: 동일한 PR을 두 번 검토했을 때 일관성 있게 같은 집합의 이슈를 찾는지)를 측정합니다.

우리는 평가에서 지연(latency)을 의도적으로 낮추지 않습니다. 개발자가 리뷰를 기다린다면, 빠르게 답을 받아도 신뢰할 수 없으면 오히려 조금 더 오래 기다려 정확한 답을 얻는 것이 낫다고 생각합니다.

우리가 사용하는 오픈소스 평가 하니스는 네이티브 제공업체 하니스와 동등한 성능을 보입니다. 모델 무관성이 의미 있는 품질 페널티를 초래하지 않으며, 이를 사용하기 전 예상했었다면 확신하지 못했을 것입니다.

TREX의 차별화점은 사용되는 모델이 아니라 모델 주변 인프라입니다. 코드베이스 인덱싱, 오케스트레이션, 아티팩트 생성, 평가 프레임워크 등입니다. 지능을 차별화점으로 삼을 필요가 없으며, 지능은

0 조회
Back to Blog

관련 글

더 보기 »

하라주쿠의 순간

!https://lh7-us.googleusercontent.com/BtsLQo0Q5aOwbYqqQ2qG8gOWAx-UB65p4aMp_UsJ1yKBDX7RdafkwVh7ryfjOLnaSO5595YB8zw0JRPgFINzJortBlCJhigXLawaDFy8AMXFYRSy-TLQRJGHqB...