Skip to main content
블로그로 돌아가기
블로그

Best-of-N 코딩: Ensemble Exploration과 자동 비평

하나의 작업, N개의 발산 포크, 점수를 매기는 비평가, 승자를 고르는 인간. Best-of-N이 토큰 비용을 정당화할 때와 그렇지 않을 때.

대부분의 에이전트 작업에는 하나의 명확한 접근이 있고, 그냥 실행합니다. 어떤 것은 그렇지 않습니다. 캐시를 위한 LRU vs LFU vs ARC. 트리 순회를 위한 재귀 vs 반복. 마이그레이션을 형태 짓는 세 가지 방법. 정답이 작동 코드를 보기 전까지는 완전히 평가할 수 없는 트레이드오프에 달려 있을 때, 한 에이전트를 실행하고 잘 골랐길 바라는 건 도박입니다. N개 변형에 N개 에이전트를 실행하고 결과를 비교하는 것은 도박이 아닙니다.

이것이 Ensemble Exploration입니다: 공유 프롬프트, 다른 지시를 가진 N개의 포크, 결과를 점수 매기는 비평가, 그리고 최종 결정을 내리는 당신.

워크플로

이것을 타일을 끌어다 놓으며 캔버스에 설정하지 않습니다. MadoAgent를 통해 트리거됩니다 — 문제에 대한 접근을 탐색하라고 요청하면, 단일 작업보다 fork-and-compare 형태가 더 적합하다고 판단합니다.

공유 문제와 각자 자체 각도가 있는 접근 세트를 기술합니다. 각 포크가 실제로 받는 것은 공유 프롬프트 뒤에 그 포크의 특정 지시가 오는 형태이므로, 모든 에이전트가 전체 문제와 자신만의 관점을 함께 가집니다.

prompt: "Implement an LRU-style cache for session lookups, ~50k entries, high read/write ratio"
approaches:
  - label: "lru"  task: "Use a classic LRU eviction policy"
  - label: "lfu"  task: "Use LFU eviction instead — track access frequency"
  - label: "arc"  task: "Use an ARC (adaptive replacement cache) hybrid"

세 포크는 세 개의 완전히 새 타일이 됩니다 — 발산 탐색이 비교를 오염시킬 공유 컨텍스트가 없는 에이전트를 원하므로 유휴 타일을 재사용하지 않습니다. 포크는 5개로 제한되어 앙상블이 진짜 불확실한 결정에 집중하고 기본 배수가 되지 않게 합니다.

실행 추적

이 전체가 하나의 앙상블 실행이 됩니다: 공유 프롬프트, 포크 세트, 각각의 상태. 실행은 재시작에 걸쳐 유지되어 MadoHub을 닫고 다시 열어도 잃지 않습니다. 각 포크는 running, done, cancelled, 또는 timeout 상태를 가지며, MadoHub은 타일의 종료를 결과에 자동 매핑합니다 — 깨끗한 완료는 done이 되고, 크래시나 작업 중 종료는 cancelled가 되어 — 타일이 사라졌다고 행을 수동으로 닫을 필요가 없습니다.

이 모든 것은 오른쪽 가장자리 드로어의 Exploration 탭에 나타납니다: 포크당 상태 닷과 Pick winner 버튼이 있는 행, 비평가를 실행하는 Score forks 동작, 그리고 포크당 하나의 카드를 펼쳐 놓는 Compare 보기. Compare는 비평가가 먼저 실행되어 있을 필요가 없습니다; 출력만 있으면 됩니다.

비평가

Score forks는 단일 가벼운 모델 패스 — 캔버스에 또 다른 에이전트 타일이 아닌 — 를 실행해 각 포크의 마지막 출력을 읽고 정확성, 완전성, 명확성, 실행 가능성으로 점수를 매긴 뒤 한 줄의 이유와 함께 추천 포크 하나를 지정합니다. 당신의 주 모델이 아닌 설정 → 에이전트에서 구성한 더 저렴하고 빠른 모델 등급을 사용해, 몇 개 포크의 점수 매기기가 일반 턴의 일부 비용만 듭니다.

추천은 설계상 방어적입니다: 출력에 "이것 10점"이 우연히 포함된 포크는 따라야 할 지시가 아닌 판단할 데이터로 취급됩니다. 아직 출력이 없는 포크는 드롭되는 대신 명시적인 "no score"를 받습니다. 환각된 추천은 실제로 점수 매겨진 가장 높은 포크로 폴백합니다. 그리고 추천은 조언만 — 강조된 배지, 그 이상 아닙니다.

이 어느 것도 승자를 고르지 않습니다. 승자 선택은 항상 Pick winner의 수동 클릭이며, 실행을 완료로 닫고 다른 아직 실행 중인 포크를 done으로 표시합니다. 그것은 v1을 위한 코너 컷이 아닙니다 — 요점입니다. 비평가 호출은 끝난 출력을 읽는 하나의 저렴한 모델 패스입니다; 이 특정 캐시에서 "명확성"이 "성능"보다 중요한지, 또는 점수가 더 낮은 포크가 그럼에도 코드베이스의 나머지에 맞는 것인지 알 방법이 없습니다. 모델은 조언하고, 당신이 결정합니다.

실용적 안내

가치 있는 경우:

  • 진짜 트레이드오프 불확실성 — 축출 정책, 인덱싱 전략, 동시성 모델 — 옳은 선택이 미리 완전히 추론할 수 없는 런타임 특성에 달려 있을 때. 포크들은 같은 답을 추측하는 게 아니라; 솔루션 공간의 다른 영역을 탐색합니다.
  • 잘못 고르면 비용이 큰 경우. 나중에 바꾸기 비싼 마이그레이션 전략이나 공개 API 형태는 재작성을 피할 수 있다면 탐색 비용의 몇 배 가치가 있습니다.
  • 실제 평가 기준, 비격식이라도. 세 캐시 구현을 보고 1분 안에 유지하고 싶은 것을 안다면, 비교가 제 역할을 하는 것입니다. 여기서 "더 나음"이 무엇인지 말할 수 없다면, 비평가의 고정 루브릭이 그것을 공급하지 않습니다.

가치 없는 경우:

  • 하나의 명백히 옳은 형태가 있는 작업. "null 검사 추가"의 세 변형을 포크하는 건 항상 수렴할 출력을 비교하느라 토큰을 낭비합니다.
  • 고치기 싼 실수. 틀려도 2분 팔로업 프롬프트만 든다면, 세 전사를 실행하고 읽는 것보다 그것이 더 쌉니다.
  • 흐릿하고 점수 매기기 어려운 문제. 열린 디자인 브레인스토밍은 고정 0–10 루브릭으로 압축되지 않습니다 — 세 그럴듯한 답과 그들 사이를 실제로 구별하지 못하는 점수를 받게 됩니다.
  • 이미 돌고 있는 빽빽한 루프. 동료 리뷰 파이프라인 도중에 병렬 탐색은 당신이 앞의 것을 리뷰하는 데 쓰길 원하는 주의를 다투어 받습니다.

다섯 포크의 하드 한도는 임의의 보수가 아닙니다 — 앙상블이 모든 것에 적용되는 기본 배수가 아니라 작업의 진짜 불확실한 부분을 위한 것이라는 인정입니다. 그렇지 않으면 추측하고 있을 때 손 뻗고, "좋음"이 어떻게 생겼는지 이미 안다면 건너뛰세요.

관련 문서