Orchestrating AI Code Review at scale
Quick Summary
Cloudflare는 대규모 코드 리뷰 병목을 줄이기 위해 OpenCode 기반의 CI 네이티브 오케스트레이션 시스템을 만들고, 여러 전문 AI 리뷰어와 조정자 에이전트를 조합해 구조화된 리뷰를 수행하도록 했다.
🖼️ 인포그래픽
🖼️ 4컷 인포그래픽
💡 한 줄 요약
Cloudflare는 대규모 코드 리뷰 병목을 줄이기 위해 OpenCode 기반의 CI 네이티브 오케스트레이션 시스템을 만들고, 여러 전문 AI 리뷰어와 조정자 에이전트를 조합해 구조화된 리뷰를 수행하도록 했다.
📌 핵심 요약
- Cloudflare는 내부 프로젝트에서 첫 코드 리뷰 대기 시간이 수 시간 단위로 늘어나는 문제를 겪었고, 기존 AI 코드 리뷰 도구와 단순 diff 프롬프트 방식 모두 대규모 조직의 복잡한 요구를 충족하지 못한다고 판단했다.
- 해결책은 단일 거대 코드 리뷰 에이전트가 아니라 OpenCode를 중심에 둔 플러그인 기반 CI 오케스트레이션 시스템이었다. 이 시스템은 보안, 성능, 코드 품질, 문서, 릴리스 관리, 내부 Engineering Codex 준수 등 전문 리뷰어를 병렬로 운영한다.
- 아키텍처는 GitLab 같은 버전 관리 시스템, AI 제공자, 내부 표준 요구사항을 서로 강하게 결합하지 않도록 설계됐다. 각 플러그인은 제한된 ConfigureContext를 통해 에이전트, 제공자, 환경 변수, 프롬프트, 권한을 등록하고 핵심 조립기가 최종 설정을 만든다.
- OpenCode는 서버 우선 구조와 SDK 덕분에 선택됐다. Cloudflare는 조정자 프로세스를 자식 프로세스로 실행하고, 런타임 플러그인의 spawn_reviewers 도구를 통해 여러 하위 리뷰어 세션을 만들며, 각 리뷰어는 독립적으로 파일을 읽고 검색하며 구조화된 결과를 반환한다.
- 운영 측면에서는 JSONL 기반 실시간 로그 처리, 토큰 사용량 추적, 오류 재시도, 출력 길이 초과 감지, 긴 모델 사고 시간에 대한 heartbeat 로그가 중요했다. 또한 도메인별 리뷰어에게 무엇을 지적할지뿐 아니라 무엇을 무시할지도 명확히 지시해 추측성 경고를 줄였다.
🧩 주요 포인트
- Cloudflare는 내부 프로젝트에서 첫 코드 리뷰 대기 시간이 수 시간 단위로 늘어나는 문제를 겪었고, 기존 AI 코드 리뷰 도구와 단순 diff 프롬프트 방식 모두 대규모 조직의 복잡한 요구를 충족하지 못한다고 판단했다.
- 해결책은 단일 거대 코드 리뷰 에이전트가 아니라 OpenCode를 중심에 둔 플러그인 기반 CI 오케스트레이션 시스템이었다. 이 시스템은 보안, 성능, 코드 품질, 문서, 릴리스 관리, 내부 Engineering Codex 준수 등 전문 리뷰어를 병렬로 운영한다.
- 아키텍처는 GitLab 같은 버전 관리 시스템, AI 제공자, 내부 표준 요구사항을 서로 강하게 결합하지 않도록 설계됐다. 각 플러그인은 제한된 ConfigureContext를 통해 에이전트, 제공자, 환경 변수, 프롬프트, 권한을 등록하고 핵심 조립기가 최종 설정을 만든다.
- OpenCode는 서버 우선 구조와 SDK 덕분에 선택됐다. Cloudflare는 조정자 프로세스를 자식 프로세스로 실행하고, 런타임 플러그인의 spawn_reviewers 도구를 통해 여러 하위 리뷰어 세션을 만들며, 각 리뷰어는 독립적으로 파일을 읽고 검색하며 구조화된 결과를 반환한다.
- 운영 측면에서는 JSONL 기반 실시간 로그 처리, 토큰 사용량 추적, 오류 재시도, 출력 길이 초과 감지, 긴 모델 사고 시간에 대한 heartbeat 로그가 중요했다. 또한 도메인별 리뷰어에게 무엇을 지적할지뿐 아니라 무엇을 무시할지도 명확히 지시해 추측성 경고를 줄였다.
🧠 상세 정리
1. 코드 리뷰 병목과 초기 실험의 한계
글은 코드 리뷰가 버그를 잡고 지식을 공유하는 훌륭한 장치이지만, 동시에 엔지니어링 팀의 병목이 되기 쉽다는 문제의식에서 출발한다. 머지 리퀘스트가 큐에 쌓이고, 리뷰어가 문맥 전환을 한 뒤 diff를 읽고, 변수명 같은 세부 지적을 남기면 작성자가 답하고 다시 반복되는 흐름이 생긴다. Cloudflare 내부 프로젝트에서도 첫 리뷰를 기다리는 중앙값 시간이 종종 몇 시간 단위로 측정됐다. 그래서 처음에는 여러 AI 코드 리뷰 도구를 시험했지만, 많은 도구가 꽤 잘 작동하고 설정 기능도 제공했음에도 Cloudflare 규모의 조직이 요구하는 유연성과 맞춤화에는 부족했다.
2. 단순 diff 프롬프트 방식이 실패한 이유
기존 도구가 충분하지 않자 다음 시도는 git diff를 가져와 미완성 프롬프트에 넣고 대형 언어 모델에게 버그를 찾아달라고 요청하는 방식이었다. 결과는 예상대로 잡음이 많았다. 모호한 제안이 쏟아졌고, 존재하지 않는 문법 오류가 생성됐으며, 이미 에러 처리가 있는 함수에 다시 에러 처리를 고려하라는 조언도 나왔다. 이 경험을 통해 Cloudflare는 단순 요약식 접근이 원하는 품질을 만들 수 없다고 판단했다. 특히 복잡한 코드베이스에서는 모델에게 큰 diff와 일반적인 지시만 주는 방식이 실제 위험과 허위 양성을 구분하는 데 충분하지 않았다.
3. OpenCode 중심의 CI 네이티브 오케스트레이션
Cloudflare가 택한 방향은 처음부터 거대한 단일 코드 리뷰 에이전트를 새로 만드는 것이 아니라, 오픈소스 코딩 에이전트인 OpenCode 주변에 CI 네이티브 오케스트레이션 시스템을 구축하는 것이었다. 엔지니어가 머지 리퀘스트를 열면, 여러 AI 에이전트가 조율된 초기 검토를 수행한다. 하나의 모델과 방대한 범용 프롬프트에 의존하는 대신 최대 일곱 개의 전문 리뷰어가 보안, 성능, 코드 품질, 문서, 릴리스 관리, 내부 Engineering Codex 준수 등을 나누어 본다. 이후 조정자 에이전트가 각 리뷰어의 발견을 중복 제거하고 실제 심각도를 판단해 하나의 구조화된 리뷰 코멘트로 게시한다.
4. 대규모 내부 적용과 목표
이 시스템은 Cloudflare 내부에서 수만 건의 머지 리퀘스트에 걸쳐 운영되고 있다고 설명된다. 깨끗한 코드는 승인하고, 실제 버그는 높은 정확도로 표시하며, 진짜 심각한 문제나 보안 취약점이 발견되면 머지를 적극적으로 차단한다. 글은 이를 Code Orange: Fail Small의 일환으로 엔지니어링 회복탄력성을 높이는 여러 방법 중 하나라고 위치 짓는다. 또한 이 글의 목적은 단순한 제품 소개가 아니라, CI/CD 파이프라인의 중요한 경로에 LLM을 넣을 때, 더 나아가 엔지니어가 코드를 배포하려는 흐름 사이에 LLM을 배치할 때 마주치는 구체적인 엔지니어링 문제를 설명하는 데 있다.
5. 플러그인 아키텍처와 결합도 제어
수천 개 저장소에 적용해야 하는 내부 도구에서 특정 버전 관리 시스템이나 특정 AI 제공자를 하드코딩하면 곧 전체를 다시 작성해야 할 위험이 커진다. Cloudflare는 현재 GitLab을 지원하면서도 미래의 다른 시스템, 여러 AI 제공자, 다양한 내부 표준 요구사항을 함께 수용해야 했다. 이를 위해 진입점이 모든 설정을 플러그인에 위임하고, 플러그인들이 조합되어 리뷰 실행 방식을 정의하는 구조를 만들었다. 각 플러그인은 ReviewPlugin 인터페이스를 구현하며 bootstrap, configure, postConfigure의 세 단계 생명주기를 갖는다. bootstrap은 병렬·비치명적으로 실행되고, configure는 순차·치명적으로 실행되며, postConfigure는 원격 모델 override 같은 비동기 작업을 처리한다.
6. ConfigureContext와 플러그인 격리
ConfigureContext는 플러그인이 리뷰에 영향을 줄 수 있는 통제된 표면을 제공한다. 플러그인은 에이전트를 등록하고, AI 제공자를 추가하고, 환경 변수를 설정하고, 프롬프트 섹션을 주입하고, 세밀한 에이전트 권한을 조정할 수 있다. 그러나 어떤 플러그인도 최종 설정 객체에 직접 접근하지 않는다. 플러그인은 컨텍스트 API를 통해 기여하고, 핵심 조립기가 이를 병합해 OpenCode가 소비하는 opencode.json 파일을 만든다. 이 격리 덕분에 GitLab 플러그인은 Cloudflare AI Gateway 설정을 읽지 않고, Cloudflare 플러그인은 GitLab API 토큰을 알 필요가 없다. 버전 관리 시스템에 특화된 결합은 단일 ci-config.ts 파일에 고립된다.
7. OpenCode 선택 이유와 실행 계층
Cloudflare가 OpenCode를 선택한 이유는 내부에서 이미 폭넓게 사용하고 있어 동작 방식을 잘 알고 있었고, 오픈소스라 기능과 버그 수정을 업스트림에 기여하거나 문제를 쉽게 조사할 수 있었기 때문이다. 글 작성 시점 기준 Cloudflare 엔지니어들은 OpenCode 업스트림에 45개가 넘는 pull request를 반영했다고 언급한다. 또한 OpenCode는 좋은 오픈소스 SDK를 제공해 플러그인을 쉽게 만들 수 있었다. 특히 중요한 점은 OpenCode가 서버 우선 구조라는 점이었다. 텍스트 기반 UI와 데스크톱 앱이 서버 위의 클라이언트로 동작하기 때문에, CLI를 억지로 다루지 않고도 세션을 프로그래밍 방식으로 만들고 SDK로 프롬프트를 보내며 여러 동시 세션의 결과를 수집할 수 있었다.
8. 조정자 프로세스와 하위 리뷰어 세션
오케스트레이션은 두 계층으로 작동한다. 첫 번째는 조정자 프로세스다. Cloudflare는 Bun.spawn을 사용해 OpenCode를 자식 프로세스로 실행하고, 조정자 프롬프트를 명령행 인자가 아니라 stdin으로 전달한다. 거대한 머지 리퀘스트 설명이나 로그를 명령행 인자로 넘기면 Linux 커널의 ARG_MAX 제한에 걸릴 수 있고, 실제로 매우 큰 머지 리퀘스트의 일부 CI 작업에서 E2BIG 오류가 발생했기 때문이다. 두 번째는 OpenCode 프로세스 내부의 리뷰 플러그인이다. 이 런타임 플러그인은 spawn_reviewers 도구를 제공하고, 조정자 LLM이 코드 리뷰 시점이라고 판단하면 OpenCode SDK 클라이언트를 통해 하위 리뷰어 세션을 시작한다. 각 리뷰어는 별도 세션과 별도 프롬프트를 가지며, 도구 사용은 독립적으로 수행한 뒤 구조화된 XML 결과를 반환한다.
9. JSONL 로그, 재시도, heartbeat 운영
장시간 실행되는 프로세스에서 구조화된 로그를 다루는 것도 중요한 운영 과제였다. JSON은 구조화 형식으로 훌륭하지만 전체 객체가 닫혀야 유효하기 때문에, 애플리케이션이 일찍 종료되면 가장 필요한 디버그 로그를 읽기 어려울 수 있다. 그래서 Cloudflare는 각 줄이 독립적인 JSON 객체인 JSONL을 사용한다. 전체 문서를 파싱하지 않고 한 줄씩 읽고 처리할 수 있어 대형 payload를 메모리에 쌓거나 닫히지 않은 배열을 기다릴 필요가 없다. 조정자 출력은 실시간으로 처리하되 디스크 쓰기 부담을 줄이기 위해 100줄 또는 50ms마다 버퍼를 flush한다. step_finish 이벤트에서 토큰 사용량을 추출해 비용을 추적하고, error 이벤트로 재시도를 시작하며, reason이 length이면 모델 출력이 max_tokens 제한으로 잘렸다고 보고 자동 재시도한다. 긴 사고 시간 때문에 사용자가 작업이 멈췄다고 오해하는 문제는 30초마다 “Model is thinking...” 로그를 출력하는 단순한 heartbeat로 크게 줄였다.
10. 전문 리뷰어와 프롬프트 경계 설정
시스템은 하나의 모델에게 모든 것을 검토하게 하지 않고, 도메인별 에이전트로 리뷰를 나눈다. 각 에이전트의 프롬프트는 무엇을 찾아야 하는지뿐 아니라 무엇을 무시해야 하는지도 좁게 정의한다. 예를 들어 보안 리뷰어는 실제로 악용 가능하거나 구체적으로 위험한 문제만 표시하도록 지시받는다. SQL, XSS, 명령 실행, 경로 순회 같은 injection 취약점, 변경 코드의 인증·인가 우회, 하드코딩된 비밀 정보, 안전하지 않은 암호 사용, 신뢰 경계의 미검증 입력은 지적 대상이다. 반대로 가능성이 낮은 전제에 의존하는 이론적 위험, 주 방어가 충분한 상황의 방어 심층화 제안, 해당 머지 리퀘스트가 건드리지 않은 기존 코드 문제, 특정 라이브러리 사용 권고 같은 제안은 제외된다. 글은 LLM에게 하지 말아야 할 일을 알려주는 것이 실제 프롬프트 엔지니어링 가치가 있는 부분이라고 강조한다.
🧾 핵심 주장 / 시사점
- 대규모 조직의 AI 코드 리뷰는 단순히 더 강한 모델을 쓰는 문제가 아니라, 결합도를 낮춘 플러그인 구조와 역할별 에이전트 분리가 핵심 운영 조건이 된다.
- AI 리뷰의 신뢰도는 무엇을 찾을지보다 무엇을 무시할지를 명확히 정할 때 높아진다. 그래야 개발자가 곧바로 무시하게 되는 추측성·이론적 경고를 줄일 수 있다.
- LLM을 CI/CD의 중요한 경로에 넣으려면 모델 품질뿐 아니라 로그 형식, 재시도 조건, 출력 잘림 감지, 사용자에게 진행 중임을 보여주는 heartbeat 같은 운영 세부가 필수다.
✅ 액션 아이템
- Cloudflare가 OpenCode 기반 CI-native orchestration으로 여러 specialized reviewer agent를 조합한 구조를 정리한다.
- false positive suppression, plugin-isolated review, structured review comments가 코드 리뷰 품질에 어떤 영향을 주는지 확인한다.
- GitLab pipeline 안에서 AI code review를 실행할 때 필요한 context packaging, diff scope, severity 분류 기준을 목록화한다.
- multi-agent review orchestration이 단일 LLM reviewer보다 나은 지점을 architecture, security, maintainability 관점에서 구분한다.
- 우리 코드 리뷰 자동화에 적용한다면 reviewer role, escalation rule, human approval gate를 어떻게 설계할지 초안을 만든다.
❓ 열린 질문
- specialized reviewer agents가 서로 다른 결론을 낼 때 orchestrator는 어떤 기준으로 최종 comment를 채택해야 할까?
- AI code review의 false positive를 줄이는 것이 놓치는 버그 증가로 이어지지 않게 하려면 어떤 calibration dataset이 필요할까?
- CI/CD 안에서 AI review가 blocking gate가 되어도 되는 영역과 advisory signal로 남아야 하는 영역은 어떻게 나눌까?
- OpenCode plugin isolation이 보안상 충분한가, 아니면 repository secret과 network access를 별도 sandbox로 더 제한해야 할까?
- Cloudflare 사례를 CRG/CodeGraph 기반 리뷰와 결합하면 어떤 impact-radius 기반 reviewer routing이 가능할까?