
Databricks의 Omnigent 구동하기(2) Polly의 크로스 리뷰를 스모크 테스트로 끝까지 통과시키기
요약
Databricks의 오픈 소스 코딩 오케스트레이터인 Omnigent의 Polly를 활용하여, 서브 에이전트 간의 크로스 리뷰 과정을 스모크 테스트로 검증하는 가이드입니다. Claude Code와 Codex를 활용해 서로 다른 벤더가 코드를 리뷰하는 메커니즘을 실제 환경에서 구현하고 실행하는 방법을 다룹니다.
핵심 포인트
- Omnigent의 Polly는 태스크를 분할하여 여러 서브 에이전트에게 할당하는 코딩 오케스트레이터임
- 서로 다른 벤더(Claude Code, Codex 등)가 작성된 코드를 교차 리뷰하는 메커니즘을 제공함
- 성공적인 구동을 위해 각 서브 에이전트용 CLI가 PATH에 설정되어 있고 로그인된 상태여야 함
- 작은 규모의 일회용 리포지토리를 사용하여 메커니즘을 노이즈 없이 관찰하는 것이 권장됨
지난번에는 Databricks가 오픈 소스화한 메타 하네스 (Meta-harness) Omnigent의 개요를 소개했습니다 (지난 기사). 하네스/메타 하네스라는 개념, 합성·제어·협업이라는 세 가지 가치, 설치 및 UI 투어까지 다루었지만, 핵심인 Polly의 크로스 리뷰(Cross-review)에 대해서는 "환경에 따라 끝까지 통과하지 못하는 경우가 있다"라고 적고 멈추었습니다.
이번에는 그 후속편으로서, Polly를 작은 스모크 테스트 (Smoke test)로 실제로 끝까지 구동하여, 다른 벤더에 의한 크로스 리뷰가 돌아가는 과정까지 기록합니다. 아울러, 직접 구동해보고 나서야 알게 된 막히는 부분들도 남겨둡니다. 검증 환경은 macOS, Omnigent v0.2.0입니다.
Polly는 스스로 코드를 작성하지 않는 코딩 오케스트레이터 (Coding orchestrator)입니다. 테크 리드 (Tech lead)처럼 행동하며, 태스크를 분할하여 claude_code / codex / pi 서브 에이전트 (Sub-agent)에게 각각 별도의 git worktree에서 구현하게 하고, 각 diff를 "작성한 것과는 다른 벤더"의 리뷰어에게 넘깁니다. 머지 (Merge)는 사람이 수행합니다.
지난번에는 이 메커니즘을 개념으로서 설명했을 뿐이었기에, 이번의 목표는 단순합니다. 작은 태스크로 구현부터 크로스 리뷰까지 실제로 끝까지 통과시키고, 그 모습과 막히는 부분을 기록하는 것입니다. 큰 리포지토리 (Repository)가 아니라, 일부러 일회용의 작은 리포지토리를 사용합니다. 메커니즘을 노이즈 없이 관찰하기에는 그 편이 더 적합하기 때문입니다.
Omnigent에는 Python 3.12 이상, Node.js 22 LTS, tmux가 필요합니다. macOS / Linux가 전제이며, Windows의 경우 WSL2를 사용하여 Linux 절차를 따릅니다.
공식 인스톨러를 실행합니다.
curl -fsSL https://omnigent.ai/install.sh | sh
CLI는 omnigent와 omni 두 가지 이름으로 설치됩니다. 둘 다 동일한 것입니다. 이미 설치되어 있는 경우에는 omni upgrade로 최신 버전(이번에는 v0.2.0)으로 업데이트할 수 있습니다.
이 부분이 이번의 핵심입니다. Polly의 크로스 리뷰는 "구현한 것과는 다른 벤더가 리뷰한다"는 것이 본질이므로, 최소 2계통의 코딩 CLI가 필요합니다. 이번에 사용하는 것은 claude_code (Claude Code CLI)와 codex (Codex CLI)입니다.
서브 에이전트는 각각 전용 CLI가 PATH에 있는 경우에만 기동할 수 있습니다. Polly가 기동 시에 수행하는 것과 동일한 확인을 미리 수동으로 해둡니다.
command -v claude codex pi
이번 환경에서는 claude와 codex는 발견되었으나, pi는 나오지 않았습니다.
/Users/xxxx/.local/bin/claude
/Users/xxxx/.npm-global/bin/codex
pi는 설치되어 있지 않지만, 크로스 리뷰에 필요한 2개 벤더(claude / codex)가 갖춰져 있으므로 문제없습니다. 리뷰는 "claude_code의 PR을 codex가", "codex의 PR을 claude_code가" 하는 방식으로 쌍방향으로 성립됩니다.
omni setup을 실행하면 검출된 하네스 목록을 확인할 수 있습니다. Claude와 Codex가 Subscription으로 인식되어 있다면 준비 완료입니다.
각 CLI가 로그인된 상태인지도 확인해둡니다. 이것이 통과되지 않으면 Polly 기동 후 서브 에이전트가 부트 (Boot) 시에 실패합니다.
claude --version
codex --version
갑자기 실제 리포지토리를 다루게 하지 않고, 일회용의 작은 git 리포지토리를 만듭니다.
mkdir -p ~/work/polly-smoke && cd ~/work/polly-smoke
git init
cat > calc.py <<'EOF'
...
이 리포지토리 안에서 Polly를 기동합니다. Polly는 현재 디렉토리를 기점으로 worktree를 만들기 때문에, 대상 리포지토리 안에서 기동하는 것이 중요합니다.
omni run ~/agents/polly-dbx/
기동 직후에 UI 테마 (dark / light)를 선택하는 화면이 나옵니다. 취향에 따라 선택하여 진행합니다.
선택을 마치면 http://localhost:6767 에 Web UI가 열립니다. 터미널과 브라우저는 동일한 세션을 실시간으로 반영합니다. 오른쪽 패널은 Files / Agents / Shells 탭으로 구성되어 있으며, 화면 하단에 "Polly (Claude SDK)"라고 표시되어 Polly의 두뇌가 claude-sdk 하네스 (Harness)로 동작하고 있음을 알 수 있습니다.
채팅창에 2개의 슬라이스로 나뉘어 크로스 리뷰 (Cross-review)가 작동하는 태스크를 일본어로 입력합니다.
calc.py 에 subtract 와 multiply 함수를 추가해 주세요.
각각 별도의 서브 에이전트 (Sub-agent)가 구현하게 하고, 테스트도 포함해 주세요.
구현한 쪽과는 다른 벤더 (Vendor)가 크로스 리뷰를 수행하게 하세요.
전송하면 Polly는 대체로 다음 순서로 동작합니다. 첫 번째 턴에서 워커 (Worker)의 존재를 확인하고 (claude 와 codex를 검출, pi는 없다고 보고), 태스크를 subtract 와 multiply 두 개로 분할하며, claude_code 와 codex가 각각 별도의 워크트리 (Worktree)에서 병렬로 구현하게 하고, 각 PR을 작성한 쪽과는 다른 벤더가 리뷰하도록 합니다. 이 과정을 사용자가 일일이 지시할 필요는 없습니다.
완료되면 Polly가 결과를 정리해 줍니다. 이번 결과는 다음과 같았습니다.
| 함수 | 구현 벤더 | 크로스 리뷰 (다른 벤더) | 테스트 | 결과 |
|---|---|---|---|---|
| subtract | claude_code | codex | 4 passed | PASS |
| multiply | codex | claude_code | 4 passed | PASS |
의도한 대로 작성자와 리뷰어가 서로 다른 벤더로 설정되었습니다. subtract는 Claude가 작성하고 Codex가 리뷰하며, multiply는 Codex가 작성하고 Claude가 리뷰하는 방식의 양방향 크로스 리뷰가 성립되었습니다.
오른쪽의 Agents 패널에는 polly(부모) 아래에 구현 및 리뷰를 담당하는 서브 에이전트들이 나열됩니다. 구현 측(add-subtract / add-multiply)과 리뷰 측(review-subtract / review-multiply)이 각각 별도의 워크트리에서 동작한 기록이 남습니다.
결과물은 2개의 로컬 브랜치 (Local branch)입니다.
git log --oneline --all
4b42326 (polly/multiply) Add multiply function and tests
4373fef (polly/subtract) Add subtract function to calc with tests
b4351ee (HEAD -> main) init
내용 또한 심플하고 정확하며, 각각 기존의 add()는 유지한 채 자신의 함수와 테스트만 추가했습니다.
git diff main polly/subtract
def add(a, b):
return a + b
def subtract(a, b):
...
테스트 관점에서 작성자의 차이(다른 벤더)가 미세하게 드러나는 점도 흥미롭습니다. subtract는 양수/음수/0을 커버했고, multiply는 여기에 더해 항등 (Identity) 테스트까지 작성되어 있었습니다. 각 워크트리는 확인을 위해 .worktrees/subtract 와 .worktrees/multiply 에 남아 있습니다.
스모크 테스트 (Smoke test)는 끝까지 통과했지만, 중간에 실제로 몇 차례 막히는 부분이 있었습니다. 이 부분이 개념 소개만으로는 알 수 없는 부분입니다.
첫 실행 중에 codex가 401 에러로 인해 동작을 멈췄습니다. claude_code 와 codex는 실제 벤더의 CLI를 그대로 실행하는 네이티브 하네스 (Native harness)이므로, CLI 인증이 만료되면 그 즉시 해당 워커가 정지합니다. 이번에는 codex가 멈추면서 multiply 구현과 다른 한쪽을 리뷰하는 역할이 동시에 막혔습니다 (pi가 없었기 때문에 codex가 유일한 다른 벤더였기 때문입니다).
대처 방법은 간단합니다. 터미널에서 다시 로그인하면 됩니다.
codex login
그 후, Polly에게 이어서 재개할 것을 지시합니다. 처음부터 다시 할 필요는 없으며, 이미 완성된 subtract는 그대로 활용할 수 있습니다.
codex에 다시 로그인했습니다. multiply를 codex에 다시 구현하고,
claude_code의 subtract를 codex에서 크로스 리뷰(cross-review)해 주세요.
PR은 필요 없으며, 로컬 브랜치(local branch)와 diff로 충분합니다.
네이티브 CLI(Native CLI) 하네스(Harness)는 편리한 반면, 각 벤더(vendor)의 인증 상태에 그대로 의존합니다. 실행하기 전에 각 CLI의 로그인 상태를 확인해 두는 것이 안전합니다.
Polly는 본래 각 구현을 독립된 PR(Pull Request)로 여는 설계입니다. 하지만 이번 스모크(smoke)용 리포지토리(repository)에는 remote가 설정되어 있지 않아 PR을 생성할 수 없었습니다. 결과물은 로컬 브랜치(polly/subtract 및 polly/multiply)와 그 diff에 머물게 됩니다.
스모크 테스트로서는 이것으로 충분하지만, PR까지 생성하고 싶다면 remote를 설정한 후 실행해야 합니다.
git remote add origin <url>
사소하지만 중요한 함정입니다. subtract와 multiply는 별도의 worktree에서 독립적으로 동작했기 때문에, 둘 다 test_calc.py를 신규 파일로 생성했습니다. 그 결과, 한쪽을 main에 머지(merge)한 후 다른 쪽을 머지하면 test_calc.py에서 반드시 충돌(conflict)이 발생합니다.
git checkout main
git merge polly/subtract # 우선 한쪽을 머지
git merge polly/multiply # 여기서 test_calc.py 충돌 발생
병렬 worktree + 독립 브랜치라는 구조상, 동일한 파일에 접근하는 태스크(task)를 분할할 때 발생하기 쉬운 충돌입니다. 그리고 Polly는 머지를 수행하지 않는 설계이므로, 이 통합 작업은 인간의 몫이 됩니다. 태스크를 어떻게 분할할지(여러 슬라이스(slice)가 동일한 파일에 접근하지 않도록 할 수 있는지)가 사후 처리의 양을 좌우합니다.
작은 스모크 테스트였지만, Polly의 본질인 "태스크를 분할하고, 별도의 worktree에서 병렬 구현하며, 다른 벤더가 크로스 리뷰하는" 흐름이 실제로 끝까지 돌아가는 것을 확인할 수 있었습니다. claude_code와 codex라는 두 벤더가 있다면 양방향 크로스 리뷰가 성립합니다.
한편, 직접 구동해 보고 나서야 보이는 운영상의 포인트도 있었습니다. 네이티브 CLI 하네스는 각 벤더의 인증 만료로 즉시 중단된다는 점, remote가 없으면 PR이 되지 않고 로컬 diff에 머문다는 점, 병렬 브랜치가 동일한 이름의 파일을 생성하면 머지 충돌을 인간이 해결해야 한다는 점 등입니다. 이는 개념 소개 단계에서는 나오지 않으며, 실제로 직접 움직여 보지 않으면 알 수 없는 부분들입니다.
다음에 더 큰 리포지토리의 실제 태스크에 적용한다면, 여기서 확인된 "태스크 분할과 파일의 중첩", "각 CLI의 인증", "remote의 유무"를 미리 정비해 두어야 더욱 원활하게 통과할 수 있을 것입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기