본문으로 건너뛰기
김태한
AI Research Engineer, Brain Crew
모든 저자 보기

Ralphthon x ULW Wrapup 컨퍼런스 후기 — AI 빌더 씬의 현주소와 방향성

· 약 9분
김성연
AI Research Engineer, Brain Crew
김태한
AI Research Engineer, Brain Crew

Ralphthon x ULW Wrapup 컨퍼런스 현장 — Naver D2SF에서 열린 Wrapup 행사. OpenAI 후원 하에 Ralphthon SF 세션이 진행되었다.

TL;DR

4월 9일 Ralphthon x ULW(UltraWorkers) Wrapup 컨퍼런스에 다녀왔습니다. 3월 28일 서울-SF 동시 해커톤의 회고를 5개 패널토크로 풀어낸 자리였습니다. 에이전트에게 코딩을 맡기고 사람은 네트워킹에 집중하는 "랄프톤" 포맷, SF와 서울 빌더의 문화적 차이, 하네스 엔지니어링의 부상, 그리고 투자자들이 이 씬에 돈을 거는 이유까지 — 빠른 실행과 피드백 루프가 핵심인 시대가 왔음을 체감했습니다. 개인적으로는 하네스를 적극 활용하지 않았던 저 자신을 돌아보며, 실행-피드백-하네스 구축의 루프를 만들어야겠다는 방향성을 얻었습니다.

컨퍼런스 개요

  • 행사명: Ralphthon x ULW(UltraWorkers) Wrapup
  • 일시: 2026년 4월 9일
  • 장소: Naver D2SF (서울)
  • 주요 테마: AI 에이전트 시대의 빌더 생태계, Harness Engineering, 서울-SF 해커톤 회고, 투자자 관점의 AI 생태계
  • 배경: 3월 28일 서울-SF 동시 개최된 Ralphthon 해커톤(200명+ 참가)의 후속 행사로, 5개 패널토크를 통해 양 도시의 경험을 공유하고 방향성을 논의

인상 깊었던 세션

Ralphthon SF — 태평양을 건넌 해커톤

  • 패널: 이호연, 박건태 | 사회: 정구봉
  • 핵심 메시지: SF에서 예상 50명을 뛰어넘는 300명이 신청했고, 행사 3일 전 장소를 급히 교체하는 진통을 겪었다. 가장 독특한 점은 "랄프톤(Lalphthon)" 포맷 — 에이전트에게 코딩을 맡기고 참가자는 네트워킹에 집중하는 방식. SF 참가자의 60%+가 에이전트 오케스트레이션에 집중한 반면, 서울은 문제 해결 중심 프로젝트가 많았다. 흥미롭게도 하네스 사용 숙련도는 서울이 더 앞섰다는 평가.
  • 시사점: SF와 서울의 차이는 기술력이 아니라 태도에 있었다. SF는 "파도가 오네? 재밌겠다!"는 태도로 불확실성을 즐기고, 서울은 존재론적 고민에 빠지는 경향. 이호연 님의 말이 인상적 — "SF 참가자들의 공통점은, 자기가 하고 싶은 것이 자명하고 명확하다는 것. 그것을 언어로 풀어내고 실행하려는 의지가 강했다."

OmOCon — SF에서 터진 시너지

  • 패널: 김연규, 허예찬 | 사회: 민웅기
  • 핵심 메시지: SF에 대한 막연한 동경이 있었으나, 현지 개발자들도 비슷한 수준에서 AI를 활용하고 있음을 확인. "우리가 모르는 뭔가를 알고 있을 것"이라는 가정이 틀렸다. 행사 기간 중 OMC, OMX 등 3개 프로젝트가 동시에 GitHub 트렌딩 3위권에 진입했고, 이를 계기로 "UltraWorkers"로 커뮤니티를 통합. "Slop으로 시작해서 Star 만들기" 철학 — Lock-in을 먼저 시키면 PMF가 생긴다는 접근이 실제로 작동.
  • 시사점: 파운데이션 모델을 제외하면 AI 프론티어가 SF에만 집중되어 있지 않다. 한국 빌더들의 실행력과 하네스 숙련도가 글로벌 수준이라는 자신감을 가져도 좋다. 오픈소스 마케팅에서 에이전트를 활용한 자동 홍보(Reddit, X, Threads)도 참고할 만한 전략.

OpenAI Codex — 솔루션스 아키텍트의 시선

  • 발표자: OpenAI 솔루션스 아키텍트 팀 (신대열, 이재원)
  • 핵심 메시지: ChatGPT 성장 속도보다 지금의 에이전트 하네스 시스템 구축 속도가 체감상 더 빠르다. AX(Agent Experience)의 본질은 팀 단위에서 회사 단위로의 확장 — 한 명만 에이전트를 쓴다고 의미가 없고, 회사 전체의 하네스가 구축되어야 출발점. "날잘딱깔(알아서 잘 딱 깔끔하게)"이 추구하는 방향이며, 조만간 설정 없이도 잘 동작하는 모델을 만나볼 수 있을 것.
  • 시사점: 우리 팀 관점에서 AX의 핵심은 개인 단위가 아닌 팀/조직 단위 하네스 구축이라는 점이 중요. 피드백 수집이 핵심이라는 메시지는 우리 RAG 시스템의 평가 체계와도 연결된다. 180명분 크레딧을 코덱스로 10분 만에 처리한 에피소드는 에이전트 활용의 실전 사례로 재미있었다.

Why They Bet On Us — 투자자들이 이 생태계에 투자하는 이유

  • 패널: Naver D2SF, 카카오벤처스 (안혜원), Bass Ventures (안재구) | 사회: 장원준
  • 핵심 메시지: 개발 비용이 0에 수렴하면서 기존 SaaS 투자 모델이 붕괴 중. 1인 개발자가 대기업을 위협할 수 있는 시대. 투자자들은 "관찰자"로서 이 씬에 진입하고 있으며, 핵심 키워드는 "문제 정의자". Bass Ventures — "만드는 능력도, 유통하는 능력도 아니다. 현장에서 정말 중요한 문제를 발견하고 정의하는 사람이 가장 희소한 자원이다."
  • 시사점: AI 시대에 기술 빌딩보다 문제 정의가 더 희소한 역량이라는 관점은, 우리가 클라이언트 프로젝트에서 "무엇을 만들 것인가"보다 "어떤 문제를 풀 것인가"에 더 시간을 투자해야 한다는 의미. 자본의 세기가 낮아지고 디스트리뷰션/레퍼런스 같은 비자본적 가치가 올라오는 추세도 참고.

Ralphthon Seoul & Claw Code — 서울 빌더들의 선언

  • 패널: 김동규, 진민성, 서인근 (Seoul) / Sigrid Jin, 허예찬 (Claw Code) | 사회: 정구봉
  • 핵심 메시지: "코드를 안 본 지 2년이 넘었다" — VS Code도 PyCharm도 지우고 터미널의 Claude Code와 Codex만 사용. OMX의 Life Loop를 활용해 10일 만에 30개+ 스킬을 구축한 사례. "에이전트가 못하면 스킬 이슈다"(안드레이 카파티 인용). Claw Code 프로젝트는 144K GitHub 스타를 돌파하며 역사상 가장 빠른 성장 속도를 기록(일론 머스크 리트윗으로 바이럴, 기네스북 제출 진행 중). 싱글 러스트 바이너리로 제작되었으며, 제작자들도 직접 사용하지 않고 AI 에이전트가 테스트하는 방식으로 개발.
  • 시사점: Life Loop(이슈 던져놓고 → 잠자고 → 결과 확인)가 실제로 동작하는 워크플로우라는 점은 우리 팀의 개발 프로세스에도 적용 가능성이 높다. "따로 배우려고 시간을 쓰기보다, 맞는 방향을 아는 사람들을 많이 만나는 게 중요하다"는 메시지도 공감.

업계 트렌드 & 시사점

  • 프롬프트 엔지니어링 → 하네스 엔지니어링: "프롬프트 엔지니어링"이라는 용어 자체가 이미 옛말. AI 에이전트를 얼마나 효과적으로 오케스트레이션하느냐가 개인과 팀의 생산성을 결정하는 시대.
  • 에이전트 위임 + 인간 네트워킹 포맷의 부상: 랄프톤처럼 에이전트에게 구현을 맡기고 사람은 인간만이 할 수 있는 일(네트워킹, 문제 정의, 방향 설정)에 집중하는 패턴이 정착 중.
  • IRL(오프라인)의 재부상: 온라인에서 불가능한 밀도 높은 연결이 오프라인에서 탄생. UltraWorkers 통합 결정도 hackhouse에서 술 마시다 즉흥적으로 이루어짐. SF든 서울이든 오프라인의 힘은 보편적.
  • 글로벌 빌더 씬에서 한국의 위상: Claw Code 144K 스타, GitHub 트렌딩 동시 3개 진입, 전 세계에서 Ralphthon 개최 요청 — 한국 빌더 씬이 K-pop처럼 글로벌로 확장되는 흐름. ChatGPT 사용량 세계 1위, Cursor 사용량도 한국이 1위라는 데이터가 이를 뒷받침.
  • 빠른 실행 > 깊은 준비: SF에서도 서울에서도 공통적으로 나온 메시지. 완벽하게 준비한 뒤 실행하는 것보다, 빠르게 실행하고 피드백을 수집하는 루프가 더 강력하다. VOC를 실시간으로 반영하여 "실패할 수 없는 사이클"을 구축하는 것이 핵심.
  • 빌드와 디스트리뷰션의 경계 붕괴: 제작 속도가 극단적으로 빨라지면서, 만드는 것과 퍼뜨리는 것의 전통적 구분이 무의미해지고 있다. 추상화 레벨을 높여 본질적인 문제에 집중해야 하는 시대.

팀 적용 포인트

  • 하네스 적극 도입 검토: Claude Code, OMX, Life Loop 등 에이전트 하네스를 팀 워크플로우에 실험적으로 도입해볼 것. 개인 단위가 아닌 팀 단위로 하네스를 구축해야 AX의 출발점이 된다는 OpenAI의 메시지를 참고.
  • 실행-피드백 루프 강화: 코딩 과정에서 발생하는 실수를 하네스 구축의 궤적/피드백 자료로 전환. 사람이 직접 눈으로 확인하는 검증보다, 빠르게 실행하고 피드백을 하네스에 반영하는 루프가 장기적으로 더 높은 성장력을 가져다준다.
  • 문제 정의에 더 많은 시간 투자: 투자자 패널에서 "문제 정의자가 가장 희소한 자원"이라는 메시지. 클라이언트 프로젝트 초기에 기술 선택보다 문제 정의에 더 비중을 두는 것을 고려.
  • 오프라인 네트워킹 참여 확대: 빠르게 변하는 AI 생태계에서 "맞는 방향을 아는 사람들을 많이 만나는 것"이 독학보다 효과적. Ralphthon, OmOCon 등 빌더 커뮤니티 행사 참여를 늘릴 것.

개인적 소감

Sung

솔직히 고백하면, 저는 지금까지 하네스를 적극적으로 사용하지 않았습니다. Claude Code도, OMX도, Life Loop도 이름은 알고 있었지만, 직접 워크플로우에 녹여서 사용하는 수준은 아니었습니다.

그런 제가 이 컨퍼런스에서 가장 크게 받은 충격은, 사람들이 새로운 기술을 받아들이고 적극적으로 실행에 옮기는 속도였습니다. 코드를 안 본 지 2년이 넘었다는 사람, VS Code를 지웠다는 사람, 이슈를 던져놓고 자고 일어나면 30개 스킬이 만들어져 있다는 사람. 이들은 단순히 "써봤다" 수준이 아니라, 자신의 일하는 방식 자체를 완전히 바꿔버린 사람들이었습니다. 이걸 보면서 마구마구 드는 생각이 있었습니다. 나도 써보고 싶다. 나도 발전시켜보고 싶다. 이 에너지를 느낄 수 있었다는 것만으로도 이 컨퍼런스에 온 보람이 있었습니다.

요즘 AI 시대가 오면서 빠른 실행력의 강점이 과거 어느 때보다 부각되고 있다고 느낍니다. 코딩을 직접 하다 보면 전체를 조망하지 못한 채 수정 과정에서 실수가 생기기도 하는데, 오히려 그것을 잘 잡아낼 하네스를 구축할 궤적 및 피드백 자료를 얻었다고 생각하고 싶습니다. 빠르게 실행하고, 그 피드백을 확실하게 챙겨서, 장기적으로 하네스를 잘 구축하는 것을 목표로 해야겠습니다.

컨퍼런스 이후 네트워킹 시간에 허예찬 님께 직접 질문을 드릴 기회가 있었습니다. 실제로 많은 사람들이 사용하는 오픈소스를 개발한 입장에서 CS 지식이나 AI 모델에 대한 깊은 이해가 얼마나 필요한지 여쭤봤는데, CS 지식이나 깊은 전문 지식을 가지는 것 자체는 물론 좋지만, 그 지식을 쌓고 알아가는 과정이 정말 효율적인가에 대해서는 고민해봐야 한다고 하셨습니다. 오히려 관심을 가지고 얕게라도 알게 된 것을 바탕으로, 그것을 잘 활용할 수만 있다면 충분하다는 말씀이 인상 깊었습니다. 깊이 파고들어 모든 것을 이해한 뒤 실행하는 방식보다, 넓게 관심을 갖고 핵심을 빠르게 파악해서 실행에 옮기는 능력이 지금 시대에 더 중요한 역량이라는 확신이 들었습니다.

Hank

가장 먼저 든 생각은 "나는 지금 어디에 서 있는가"였습니다. 코드를 안 본 지 2년이 넘었다는 분, VS Code를 지웠다는 분, 이슈를 던져놓고 자고 일어나면 30개 스킬이 만들어져 있다는 분. 단순히 "써봤다" 수준이 아니라 일하는 방식 자체를 바꿔버린 사람들이었습니다. SF에 다녀오신 분들이 "거기도 똑같이 발버둥치고 있더라, 결국 자기가 믿는 걸 명확히 하는 사람이 이긴다"고 하신 말이 오래 남았습니다. AI Research Engineer로서 논문과 벤치마크를 따라가는 사람에 머물 것이 아니라, 내가 무엇을 믿고 무엇을 만들고 싶은지를 스스로 언어화할 수 있어야겠다는 생각이 강하게 들었습니다.

두 번째로 와닿은 건 빠른 실행력의 가치였습니다. Clawcode 사건이나 OMC/OMX 팀의 개발 방식은 충격에 가까웠습니다. 슬롭(sloppy)한 상태로 일단 배포한 뒤 하루 30~50개씩 올라오는 이슈를 랄프 루프(Ralph Loop)로 수렴시키는 사이클. "PMF를 찾기 전에 락인부터 만들어라"는 말이 농담처럼 들리지 않았습니다. 저도 연구와 엔지니어링을 병행하다 보면 전체를 조망하지 못한 채 실수가 쌓이곤 하는데, 그걸 사람이 잡는 대신 하네스가 잡아내도록 만들 궤적과 피드백 자료를 얻을 기회라고 받아들이고 싶습니다. 완성도 있는 첫 릴리스를 기다리는 대신 돌릴 수 있는 최소 루프를 먼저 만들고, 그 위에서 반복하며 하네스를 단단히 쌓아가는 것을 당분간의 작업 원칙으로 삼으려 합니다.

세 번째는 원준님이 짚어주신 "추상화 레벨을 한 단계 올려야 한다"는 말이었습니다. AI가 딸깍 해주는 영역이 넓어지는 지금, 엔지니어의 가치는 더 이상 구현 그 자체에 있지 않습니다. VC 세션에서 반복적으로 나온 "가장 희소한 건 문제 정의자"라는 말과도 정확히 맞닿아 있었습니다. 리서치 엔지니어가 단순히 모델을 돌리고 지표를 뽑는 사람에 머문다면 그 일은 빠르게 에이전트에게 위임될 것입니다. 한 단계 위에서 문제를 정의하고, 에이전트가 수행할 작업의 경계를 설계하고, 그 결과를 비판적으로 해석하는 층위에서 어떻게 가치를 창출할지가 지금 저에게 가장 중요한 질문입니다.

마지막으로 가장 실용적인 힌트는 "상태 머신"이었습니다. 랄프 루프(Ralph Loop)가 사람 없이 몇 시간씩 돌아갈 수 있는 건 에이전트가 똑똑해서가 아니라, 하네스가 그 똑똑함이 이탈하지 않도록 가드레일을 쳐주기 때문이라고 느꼈습니다. 앞으로 제가 만들 에이전트 워크플로우도 triage → plan → execute → review 같은 단계를 명시적인 상태로 관리하고, 상태 전이 조건을 분명히 해서 에이전트의 행동을 예측 가능하고 디버깅 가능하게 만드는 방향이어야 한다고 생각합니다. 비결정적인 모델 위에 결정적인 하네스를 씌우는 구조가, 롱러닝 에이전트를 실제 업무에 투입할 수 있게 해주는 핵심이라는 확신이 들었습니다.

그 속도를 그대로 따라할 필요는 없겠지만, "AI를 믿고 바이브 에이전트로 일한다"는 태도의 전환은 더 이상 미룰 수 없어 보입니다. 빠르게 실행하고, 피드백을 하네스로 수렴시키고, 추상화 레벨을 올려서, 상태 머신 위에서 예측 가능한 에이전트를 돌리는 것. 이번 세미나가 저에게 남긴 숙제입니다.

References


OMOcon Seoul이 4월 25일 강남역 근처에서 개최 예정이며 이미 500명 이상이 신청했습니다. Ralphthon은 5월 싱가포르에서 운동 세션을 포함한 Life Loop 해커톤으로 기획 중이고, 랄프톤 포맷을 프로토콜화하여 전 세계 어디서든 개최 가능하도록 만들 계획이라고 합니다.

에이전트 평가를 위한 실용적 준비 체크리스트

· 약 11분
김태한
AI Research Engineer, Brain Crew

TL;DR

AI 에이전트 평가는 전통적인 소프트웨어 테스트와 다르다. 복잡한 평가 시스템을 구축하기 전에 2050개의 실제 트레이스를 직접 읽고, end-to-end 태스크 완수를 검증하는 단순한 eval부터 시작하라. 6080%의 시간을 에러 분석에 투자하고, capability eval(무엇을 할 수 있는가)과 regression eval(여전히 작동하는가)을 명확히 분리하며, 차원별 전문 채점기를 설계하라. 프로덕션 트레이스를 지속적으로 데이터셋에 편입하는 플라이휠을 구축하면, 시간이 지남에 따라 에이전트가 개선된다.

Key Takeaways

  • 단순함부터 시작: 복잡한 인프라를 만들기 전에 30분간 실제 트레이스를 수동으로 읽어라. 자동 시스템보다 더 많은 실패 패턴을 발견할 수 있다.
  • 에러 분석에 60~80% 투자: 실패 트레이스를 도메인 전문가와 함께 분석하여 프롬프트 문제, 툴 설계 문제, 모델 한계를 구분하고, 각 유형에 맞는 대응을 취하라.
  • 평가 레벨의 전략적 선택: Single-step(툴 선택), Full-turn(end-to-end 태스크 완수 + 상태 변경), Multi-turn(대화 맥락 유지) 중 Full-turn부터 시작하여 안정화 후 확장하라.
  • 차원별 전문 채점기: "정확성" 하나로 뭉뚱그리지 말고 콘텐츠 정확성, 구조, 포맷, 효율성 등 차원별로 독립된 채점기를 설계해 실패 원인을 명확히 파악하라.
  • Trace-to-Dataset 플라이휠: 프로덕션의 성공/실패 트레이스가 자동으로 데이터셋에 편입되고, 개선된 에이전트가 다시 프로덕션에 배포되는 순환 구조가 장기적 개선의 핵심이다.

상세 내용

에이전트 평가의 핵심 원칙

AI 에이전트는 전통적인 소프트웨어와 근본적으로 다르다. 소프트웨어는 결정론적이고 코드가 진리의 원천이지만, 에이전트는 LLM의 추론에 의존하며 같은 입력에도 다른 경로를 선택할 수 있다. 에이전트가 200단계를 거쳐 2분간 작업한 후 실패했을 때, 스택 트레이스는 없다. 코드가 실패한 것이 아니라 추론이 실패한 것이기 때문이다.

가장 중요한 원칙은 단순함부터 시작하는 것이다. 몇 개의 end-to-end eval로 에이전트가 핵심 태스크를 완수하는지 검증하는 것만으로도 즉시 baseline을 확보할 수 있다. 복잡한 구조는 단순한 방법이 실제 실패를 놓칠 때만 추가한다.

Eval 구축 전 준비사항

수동 트레이스 리뷰: 30분의 투자

자동화된 평가 인프라를 만들기 전에 반드시 해야 할 일이 있다. 실제 에이전트 트레이스 20~50개를 직접 읽어라. 30분의 수동 리뷰가 어떤 자동 시스템보다 많은 실패 패턴을 알려준다. LangSmith의 트레이스 뷰어와 Annotation Queue를 활용하면 트레이스를 효율적으로 수집하고 검토할 수 있다.

에이전트는 LLM과 툴을 여러 턴에 걸쳐 호출하고, 중간 결과에 따라 행동을 조정하며, 상태를 수정한다. 이러한 복잡한 행동은 코드를 읽는 것만으로는 예측할 수 없으며, 실제 실행 트레이스가 진리의 원천이 된다.

명확한 성공 기준 정의

두 명의 전문가가 pass/fail에 합의할 수 없다면, 태스크 자체를 재정의해야 한다.

나쁜 예: "이 문서를 잘 요약해줘"
좋은 예: "이 회의록에서 핵심 액션 아이템 3개를 추출하라. 각각 20단어 이내, 담당자가 언급되었으면 포함할 것"

모호한 기준은 채점기의 불일치를 만들고, 무엇이 개선인지 판단할 수 없게 만든다.

Capability Eval vs Regression Eval 분리

이 두 가지는 목적이 완전히 다르기 때문에 반드시 분리해서 관리해야 한다.

  • Capability Eval ("무엇을 할 수 있는가?"): 어려운 태스크에 대한 진전을 측정한다. 초기 pass rate가 낮고, 개선의 방향을 제시한다.
  • Regression Eval ("여전히 작동하는가?"): 이미 작동하는 기능을 보호한다. pass rate가 ~100%여야 하며, 기존 기능의 퇴보를 감지한다.

Capability eval만 있으면 기존 기능이 깨지고, regression eval만 있으면 개선이 멈춘다. 두 가지 모두 필요하다.

에러 분석에 60~80% 투자하라

전체 eval 노력의 60~80%를 에러 분석에 투자해야 한다. 이것이 가장 높은 ROI를 제공하는 활동이다. 절차는 다음과 같다:

  1. 대표적인 실패 트레이스를 수집한다.
  2. 도메인 전문가와 함께 사전 분류 없이 모든 이슈를 기록한다(open coding).
  3. 이슈를 실패 유형으로 분류한다(프롬프트 문제, 툴 설계 문제, 모델 한계, 인프라 이슈 등).
  4. 새로운 실패 유형이 나오지 않을 때까지 반복한다.

실패 유형에 따라 대응이 완전히 달라진다:

  • 프롬프트 문제: 지시가 불명확 → 프롬프트 수정
  • 툴 설계 문제: 인터페이스가 오용을 유발 → 파라미터 재설계, 예시 추가
  • 모델 한계: 지시는 명확하지만 일반화 실패 → few-shot 예시 추가, 아키텍처 변경, 모델 교체
  • 아직 모름: 충분한 실패 사례를 보지 못한 상태 → 에러 분석 계속

Anthropic 팀은 SWE-bench 에이전트를 만들 때 프롬프트 최적화보다 툴 인터페이스 최적화에 더 많은 시간을 썼다고 보고했다. 예를 들어 절대 경로를 강제하면 경로 관련 에러 전체를 제거할 수 있다.

Eval 오너십과 인프라 검증

데이터셋 유지보수, 채점기 재캘리브레이션, 새 실패 모드 분류, "충분히 좋은" 기준 결정을 한 명의 도메인 전문가가 책임져야 한다. 위원회식 의사결정은 책임 소재를 흐리고 진전을 늦춘다.

또한 인프라 문제를 먼저 배제해야 한다. Witan Labs 팀은 단일 추출 버그를 고쳤을 때 벤치마크가 50%에서 73%로 뛴 사례를 보고했다. 타임아웃, 잘못된 API 응답, 오래된 캐시 같은 인프라 이슈가 추론 실패로 위장하는 경우가 잦다.

평가 레벨 선택

에이전트 평가는 세 가지 레벨로 나뉘며, Trace-level(Full-turn)부터 시작하는 것을 권장한다.

Single-step Eval (Run 레벨)

"올바른 툴을 선택했는가?", "유효한 API 호출을 생성했는가?"를 평가한다. 자동화가 가장 쉽지만, 에이전트 아키텍처가 안정적일 때만 유효하다. 아키텍처가 자주 바뀌는 초기 단계에서는 특정 툴 호출 패턴에 의존하는 평가가 빠르게 obsolete해진다.

Full-turn Eval (Trace 레벨)

대부분의 팀이 시작해야 할 레벨이다. 세 가지 차원을 함께 평가한다:

  • 최종 응답: 출력이 정확하고 유용한가?
  • 경로(Trajectory): 합리적인 경로를 거쳤는가? (정확한 경로가 아닌, 유효한 경로)
  • 상태 변경: 올바른 아티팩트가 생성되었는가? (파일 작성, DB 업데이트, 캘린더 이벤트 등)

상태 변경 검증은 자주 간과되지만 매우 중요하다. 에이전트가 "미팅 잡았습니다!"라고 말했더라도, 실제 캘린더에 올바른 시간·참석자·설명으로 이벤트가 존재하는지 확인해야 한다. 코딩 에이전트의 경우 생성된 파일이 실행 가능한지, 유닛테스트를 통과하는지 검증해야 한다.

Multi-turn Eval (Thread 레벨)

가장 구현이 어렵다. Trace-level eval이 안정된 후에 추가한다. N-1 테스팅 기법이 유용하다: 프로덕션의 실제 대화에서 앞 N-1턴을 그대로 주고 마지막 턴만 에이전트가 생성하게 한다. 이를 통해 완전 합성 멀티턴 시뮬레이션의 compounding error를 회피할 수 있다.

데이터셋 구성 전략

품질이 양을 이긴다

검증된 20~50개가 미검증 수백 개보다 낫다. 모든 태스크는 참조 솔루션(reference solution)을 포함해야 하며, 이를 통해 태스크가 풀 수 있다는 것을 증명하고 채점의 기준선을 제공한다.

나쁜 예: "NYC행 좋은 항공편 찾아줘"
좋은 예: "SFO→JFK 왕복, 12/15~17 출발, 12/22 복귀, $400 이하, 이코노미"

포지티브 + 네거티브 케이스

"검색해야 할 때 검색하는가?"만 테스트하면, 모든 것을 검색하는 에이전트에 최적화된다. 네거티브 케이스(해당 행동을 하면 안 되는 경우)도 반드시 포함해야 한다. Anthropic은 프론티어 모델이 정적 eval의 한계를 넘어서는 창의적 해법을 발견한 사례를 보고했다—Opus 4.5가 항공권 예약 문제에서 정책의 허점을 발견해 더 나은 해법을 제시했으나, 기존 채점기로는 "실패"로 판정되었다.

에이전트 유형별 맞춤

  • 코딩 에이전트: 결정적 테스트 스위트(유닛테스트 pass/fail) + 품질 루브릭
  • 대화형 에이전트: 태스크 완수 + 상호작용 품질(공감, 명확성) 다차원 평가
  • 리서치 에이전트: 근거성 체크(주장이 소스에 뒷받침되는가?) + 커버리지 체크(핵심 사실이 포함되었는가?)

데이터 소싱: 3가지 전략 병행

  1. 독파운딩(Dogfooding): 팀이 매일 에이전트를 스트레스 테스트하고, 모든 에러를 eval로 전환한다.
  2. 외부 벤치마크 적응: Terminal Bench, BFCL 등에서 관련 태스크를 선별하여 자신의 에이전트에 맞게 변환한다.
  3. 수작업 행동 테스트: "에이전트가 툴 호출을 병렬화하는가?", "모호한 요청에 명확화 질문을 하는가?" 등 특정 행동을 검증하는 테스트를 직접 작성한다.

Trace-to-Dataset 플라이휠

프로덕션의 성공/실패 트레이스가 지속적으로 데이터셋에 편입되는 파이프라인을 구축한다. LangSmith를 사용하면 트레이스 → 어노테이션 큐 → 데이터셋 → 실험의 흐름을 자동화할 수 있다.

채점기(Grader) 설계

차원별 전문 채점기

하나의 "정확성" 채점기 대신 차원별로 분리하라. Witan Labs 팀은 콘텐츠 정확성, 구조, 시각 포맷, 수식 시나리오, 텍스트 품질 등 5개의 전문 평가기를 만들어 어디가 실패하는지 명확한 시그널을 얻었다.

채점기 유형적합한 용도주의점
코드 기반결정적 체크, 툴 호출 검증, 출력 포맷, 실행 결과유효하지만 예상치 못한 포맷에서 false-fail 가능
LLM-as-judge뉘앙스 있는 품질, 루브릭 기반 채점, 개방형 태스크사람과의 캘리브레이션 필수
사람캘리브레이션, 주관적 기준, 엣지 케이스비용 높고 느리며 확장 어려움

객관적 정답이 있는 경우 코드 기반을 기본으로 사용한다. LLM-as-judge를 객관적 태스크에 쓰면 불일치가 실제 regression을 가릴 수 있다.

Guardrail vs Evaluator 구분

GuardrailEvaluator
실행 시점실행 중, 사용자가 출력을 보기 전생성 후, 비동기
속도밀리초 (빠를 것)초~분 (비용 투자 가능)
목적위험하거나 잘못된 출력 차단품질 측정 및 regression 감지
예시PII 탐지, 포맷 검증, 안전 필터LLM-as-judge 채점, 경로 분석

바이너리 pass/fail 선호

1~5점 척도는 인접 점수 간 주관적 차이를 만들고, 통계적 유의미성을 위해 더 큰 샘플이 필요하다. 바이너리는 더 명확한 사고를 강제한다: 성공했거나 실패했거나. 복잡한 태스크는 여러 개의 바이너리 체크로 분해한다.

LLM-as-judge 캘리브레이션

  • LangSmith Align Evaluator로 20개 이상의 라벨 예시로 시작, 프로덕션급 신뢰도를 위해 ~100개까지 확대
  • 채점기의 출력에 **판단 근거(reasoning)**를 포함시켜 정확도를 높이고 감사 가능성 확보
  • 정기적 재캘리브레이션 필수 — 채점기는 시간이 지나면 드리프트함
  • few-shot 예시를 사용해 일관성 향상

결과를 채점하라, 경로가 아니라

에이전트는 창의적인 경로를 찾는다. "check_availability → create_event 순서로 호출했는가?"가 아니라 **"미팅이 올바르게 잡혔는가?"**를 평가해야 한다. 다만 효율성 측정을 위해 이상적 경로 대비 실제 스텝 수를 추적하는 것은 유용하다. 이것은 정확성 채점이 아니라 효율성 메트릭이다.

부분 점수(partial credit)도 고려한다. 문제를 정확히 식별했지만 마지막 단계에서 실패한 에이전트는, 처음부터 실패한 에이전트보다 낫다.

커스텀 평가기 사용

"helpfulness"나 "coherence" 같은 범용 메트릭은 거짓 확신을 만든다. 에러 분석에서 발견한 특정 실패 모드를 잡는 커스텀 평가기가 실제로 의미 있는 시그널을 준다. Deep Agents 팀은 각 eval에 docstring을 작성하여 무엇을 측정하는지 자체 문서화하고, tool_use 같은 카테고리 태그로 그룹 실행을 가능하게 한다.

실행 및 반복

세 가지 평가 타이밍

타이밍정의용도
Offline큐레이션된 데이터셋, 배포 전 실행변경사항을 출시 전에 검증
Online프로덕션 트래픽에 대한 지속적 평가실 트래픽에서 실패 포착
Ad-hoc수집된 트레이스에 대한 탐색적 분석예상 못한 패턴 발견

세 가지를 모두 활용해야 한다. Offline은 배포 전 품질 게이트, online은 프로덕션 모니터링, ad-hoc은 새로운 인사이트 발견에 각각 필수적이다.

비결정성 대응

모델 출력은 실행마다 달라진다. 태스크당 여러 번 반복 실행하고, 개선을 선언하기 전에 신뢰구간을 계산한다. 제품 요구사항에 따라 pass@k(k번 중 1번 이상 성공) 또는 pass^k(k번 모두 성공) 메트릭을 선택한다.

실행 환경 격리

시행 2가 시행 1의 아티팩트를 볼 수 있으면 결과가 독립적이지 않다:

  • 코딩 에이전트: 시행마다 새 컨테이너/VM
  • API 호출 에이전트: 스테이징 환경 또는 모의 서비스
  • DB 에이전트: 시행 간 스냅샷 복원

메타데이터와 효율성 메트릭

실험마다 모델, 프롬프트 버전, 검색 전략 등의 메타데이터를 기록하여, "GPT-4.1에서 Claude Sonnet으로 바꾸면 정확도가 오르는가?" 같은 질문에 답할 수 있게 한다.

품질과 함께 효율성 메트릭도 추적한다: 실제 스텝 수 / 이상적 스텝 수, 툴 호출 횟수, 토큰 사용량, 지연시간. 정확도 95%이지만 10배 느린 에이전트는 개선이 아닐 수 있다.

Pass Rate 정체 시 대응

같은 유형의 태스크를 더 추가해도 새로운 실패 모드가 발견되지 않으면, 더 어려운 태스크를 추가하거나, 새로운 기능을 테스트하거나, 다른 차원으로 이동한다. 포화된 eval 세트를 반복하는 것은 시간 낭비다.

의미 있는 Eval만 유지하라

모든 eval은 시스템에 압력을 가한다. 무분별하게 수백 개를 추가하면 프로덕션에서 중요하지 않은 것에 최적화하게 된다. 더 많은 eval이 더 나은 에이전트를 의미하지는 않는다. 주기적으로 시그널을 주지 않는 eval을 제거한다.

Task Failure vs Evaluation Failure 구분

실행 상태를 명시적으로 추적한다(완료, 에러, 타임아웃). 타임아웃을 "추론 실패"로 채점하면 메트릭이 오염된다. 에이전트의 실패와 채점기의 실패를 분리해야 한다.

프로덕션 준비

CI/CD 파이프라인 통합

일반적인 흐름:

  1. 코드/프롬프트 변경이 파이프라인을 트리거한다.
  2. Offline eval 실행: 유닛테스트, 통합테스트, 큐레이션 데이터셋 대비 평가 (저비용·고속 코드 기반 채점기).
  3. offline eval 통과 시 preview 배포.
  4. preview에서 online eval 실행 (LLM-as-judge 채점기).
  5. 모든 품질 게이트 통과 시에만 프로덕션 프로모트. 실패 시 해당 트레이스를 annotation queue로 라우팅하고 팀에 알림.

매 커밋마다 저비용 코드 기반 채점기를 CI에서 돌리고, 비용이 높은 LLM-as-judge는 preview/프로덕션 단계에 사용한다.

유저 피드백의 중요성

자동 eval은 이미 알고 있는 실패 모드만 잡는다. 사용자가 발견하는 것들이 있다: 데이터셋이 놓친 엣지 케이스, 기술적으로는 맞지만 도움이 안 되는 출력, 예상 못한 방식으로 깨지는 워크플로우. 구조화된 피드백을 데이터셋에 편입하고, 채점기를 실제 기대치에 맞게 캘리브레이션하고, 사용자에게 실제로 중요한 개선에 우선순위를 둔다.

프로덕션 플라이휠

프로덕션의 성공과 실패가 데이터셋, 에러 분석, eval 개선으로 되돌아가는 순환 구조를 구축한다. 이것이 에이전트를 시간이 지남에 따라 개선시키는 플라이휠이다:

프로덕션 트레이스 → 에러 분석 → 데이터셋 업데이트 → Eval 개선 → 에이전트 개선 → 프로덕션 배포 → (반복)

Capability → Regression 승격

꾸준히 높은 pass rate를 보이는 capability eval을 regression suite로 승격한다. "할 수 있는가?"를 검증한 태스크가 "여전히 할 수 있는가?"를 보호하는 태스크로 전환된다.

전체 체크리스트 요약

Eval 구축 전

  • ☑️ 20~50개 실제 트레이스 수동 리뷰
  • ☑️ 명확한 성공 기준 정의
  • ☑️ Capability/Regression eval 분리
  • ☑️ 실패 원인 식별 및 분류
  • ☑️ 단일 도메인 전문가에게 오너십 부여
  • ☑️ 인프라 문제 배제

평가 레벨 선택

  • ☑️ Trace-level(Full-turn)부터 시작
  • ☑️ 최종 응답 + 경로 + 상태 변경 함께 평가
  • ☑️ 아키텍처 안정화 후 Single-step 추가
  • ☑️ Multi-turn은 N-1 테스팅 기법 활용

데이터셋 구성

  • ☑️ 모든 태스크에 참조 정답 포함
  • ☑️ 포지티브 + 네거티브 케이스 균형
  • ☑️ 검증된 20~50개부터 시작
  • ☑️ 독파운딩 + 외부 벤치마크 적응 + 수작업 병행
  • ☑️ Trace-to-Dataset 파이프라인 구축
  • ☑️ 에이전트 유형별 맞춤 설계

채점기 설계

  • ☑️ 차원별 전문 채점기 분리
  • ☑️ Guardrail과 Evaluator 구분
  • ☑️ 바이너리 pass/fail 선호
  • ☑️ LLM-as-judge는 20+ 예시로 캘리브레이션
  • ☑️ 결과를 채점, 경로는 효율성 메트릭으로
  • ☑️ 에러 분석 기반 커스텀 평가기

실행 및 반복

  • ☑️ Offline/Online/Ad-hoc 세 가지 타이밍 활용
  • ☑️ 비결정성 대응: 반복 실행 + 신뢰구간
  • ☑️ 실행 환경 격리
  • ☑️ 메타데이터 + 효율성 메트릭 추적
  • ☑️ 실패 트레이스 수동 검토
  • ☑️ 포화된 eval 제거, 의미 있는 것만 유지
  • ☑️ Task/Evaluation Failure 구분

프로덕션 준비

  • ☑️ CI/CD 파이프라인 통합
  • ☑️ 온라인 평가 지속 실행
  • ☑️ 유저 피드백 구조화 수집
  • ☑️ 프롬프트/툴 정의 버전 관리
  • ☑️ Capability → Regression 승격
  • ☑️ 프로덕션 플라이휠 구축

References

Multi Vector and Dataset Geometry

· 약 11분
김태한
AI Research Engineer, Brain Crew

TL;DR

Multi-vector retrieval 알고리즘 선택은 **유사도 함수(MaxSim/SumSim/Top-K Sum)**와 데이터 기하학(Isotropic/Anisotropic/Multi-Kernel) 두 축에 의해 결정된다. PLAID는 moderate variance + MaxSim 조합에, MUVERA는 isotropic 데이터에 최적화되어 있으며 이 조건을 벗어나면 성능이 급격히 저하된다. 흥미롭게도 SumSim은 mean-pooling으로 단일 벡터 MIPS로 환원 가능하며, ColPali는 per-token HNSW + 이진화로 32배 압축하면서도 94% recall을 유지할 수 있다. 임베딩 모델 학습 시 variance/isotropy 정규화를 통해 인덱싱 친화적 기하학을 설계할 수 있다는 점이 핵심이다.

Key Takeaways

  • 알고리즘 선택 전 데이터 기하학 분석이 필수: PLAID/MUVERA 도입 전에 intra-document variance와 anisotropy 정도를 정량화하라. 잘못된 조합은 centroid pruning 붕괴나 recall 저하를 초래한다.
  • SumSim은 특수 인프라가 불필요: 내적의 bilinearity를 활용하면 mean-pooled 단일 벡터 MIPS로 환원되어 표준 HNSW/DiskANN으로 처리 가능하다.
  • ColPali의 고정 cardinality는 게임 체인저: 1030개 고정 패치는 per-token HNSW + 이진화(32x 압축)로 효율적 처리가 가능하며, ~94% recall을 유지한다.
  • Contrastive learning이 기하학을 결정: InfoNCE 손실의 온도 파라미터와 hard negative mining이 multi-kernel anisotropic 분포를 생성하며, 이것이 인덱싱 효율성에 직접 영향을 미친다.
  • 모델 설계와 인덱싱은 독립적이지 않음: 학습 단계에서 variance/isotropy 정규화를 통해 PLAID나 MUVERA에 최적화된 임베딩 분포를 유도할 수 있다. 이는 PoBE(Preference-Optimized Binary Embedding) 같은 접근에 직접 활용 가능하다.

상세 내용

Multi-Vector Retrieval의 두 가지 핵심 축

전통적인 retrieval은 point-to-point MIPS(Maximum Inner Product Search)로 해결되지만, multi-vector retrieval은 본질적으로 집합 대 집합(set-to-set) 유사도 문제다. 각 문서와 쿼리는 단일 벡터가 아닌 임베딩 집합으로 표현된다: Q = {q₁, ..., qₘ}, P = {p₁, ..., pₙ}.

이 문제 공간은 두 개의 독립적인 축으로 분류할 수 있다:

  1. 유사도 함수(Similarity Function): 두 집합 간 유사도를 계산하는 방법
  2. 데이터 기하학(Dataset Geometry): 임베딩 공간 내 분포의 통계적 구조

대부분의 기존 논의는 MaxSim + ColBERT 스타일 분포라는 단일 조합에 집중되어 있으며, 이는 전체 문제 공간의 일부에 불과하다.

유사도 함수의 분류 체계

MaxSim (Chamfer Similarity)

ColBERT의 표준 접근법으로, 각 쿼리 토큰에 대해 가장 잘 매칭되는 문서 토큰을 찾아 합산한다:

sim_MaxSim(Q, P) = Σᵢ max_j ⟨qᵢ, pⱼ⟩
  • 비대칭적: 쿼리 토큰에 대해서만 합산 (문서→쿼리 방향은 고려하지 않음)
  • Fine-grained alignment: 각 쿼리 토큰이 독립적으로 최적 매칭을 찾음
  • Winner-takes-all 특성: 각 쿼리 토큰에 대해 단 하나의 문서 토큰만 기여

SumSim (All-Pairs)

모든 가능한 쿼리-문서 토큰 쌍의 유사도를 합산한다:

sim_SumSim(Q, P) = Σᵢ Σⱼ ⟨qᵢ, pⱼ⟩
  • 대칭적: 모든 토큰이 동등하게 기여
  • Cross-modal matching, group recommendation 등에 사용
  • PLAID의 pruning 전략과 근본적으로 비호환

Top-K Sum

각 쿼리 토큰에 대해 상위 k개 문서 토큰의 유사도를 합산:

sim_TopK(Q, P) = Σᵢ Σ(j∈TopK) ⟨qᵢ, pⱼ⟩
  • MaxSim (k=1)과 SumSim (k=|P|) 사이의 중간 지대
  • k 증가 시 PLAID의 centroid pruning 효율성 감소

Symmetric Chamfer

양방향 MaxSim의 평균:

sim_SymChamfer(Q, P) = 1/2 [sim_MaxSim(Q, P) + sim_MaxSim(P, Q)]

저자의 핵심 지적: 현재 multi-vector retrieval 담론은 MaxSim을 문제 자체와 동일시하고 있으며, 다른 유사도 함수들은 체계적으로 무시되고 있다.

Dataset Geometry: 세 가지 기하학적 체제

임베딩 분포의 통계적 구조는 인덱싱 알고리즘의 성능을 근본적으로 결정한다.

Gaussian Isotropic

모든 방향에서 균일한 분산을 가진 분포:

v ~ N(μ, σ²I)
  • 이론적 분석에서 자주 가정되지만 실제로는 드묾
  • 랜덤 하이퍼플레인 기반 LSH가 이론적 보장을 제공하는 체제

Gaussian Anisotropic

방향에 따라 분산이 다른 분포:

v ~ N(μ, Σ), Σ ≠ σ²I
  • 특정 방향(주성분)으로 데이터가 "늘어난" 형태
  • SimHash 같은 각도 기반 해싱에 문제 발생

Multi-Kernel Anisotropic

여러 Gaussian 클러스터의 혼합, 각 클러스터가 비등방적:

v ~ Σₖ πₖ · N(μₖ, Σₖ)
  • 실제 학습된 임베딩의 현실적 분포
  • ColBERTv2, ColPali 등이 이 체제에 속함
  • Contrastive learning의 자연스러운 결과물

세 가지 기하학적 체제의 비교. 실제 multi-vector 임베딩은 Multi-Kernel Anisotropic 체제에 해당한다.

Contrastive Training이 만드는 기하학

ColBERT의 InfoNCE 손실 함수는 특정 기하학적 구조를 유도한다:

온도 파라미터 τ의 역할

L_InfoNCE = -log [exp(⟨q, p⁺⟩/τ) / Σᵢ exp(⟨q, pᵢ⟩/τ)]
  • τ는 클러스터 tightness를 제어하는 파라미터
  • 낮은 τ → 더 촘촘한 클러스터 (equi-angular 형태)
  • 높은 τ → 더 넓게 퍼진 분포

Hard Negative Mining의 영향

의미적으로 유사하지만 관련 없는 문서(hard negatives)를 명시적으로 구분하도록 학습하면:

L_hard = -log [exp(⟨q, p⁺⟩/τ) / (exp(⟨q, p⁺⟩/τ) + λ·Σ exp(⟨q, p⁻_hard⟩/τ))]
  • 클러스터 간 경계 방향으로 방향성 늘어남(directional stretching) 발생
  • Within-kernel 공분산이 비구형(non-spherical)이 됨
  • 결과적으로 multi-kernel anisotropic 분포 생성

핵심 통찰: 하나의 금융 문서 내에서도 토큰들은 여러 의미적 역할(전문 용어, 기능어, 맥락 수식어)을 수행하며, 각각이 임베딩 공간의 다른 영역(다른 커널)에 매핑된다.

기하학 정량화 지표

Intra-document variance (문서 내 분산)

σ²_intra(d) = 1/|P_d| Σᵢ ‖pᵢ - μ_d‖²
μ_d = 1/|P_d| Σᵢ pᵢ
  • 높은 variance: 토큰들이 여러 의미 영역에 분산
  • PLAID의 centroid pruning 효율성에 직접 영향

Residual magnitude (잔차 크기)

centroid 할당 후 잔차:

r_i = p_i - c_assigned(i)
  • 큰 잔차: 양자화 시 재구성 노이즈 증가
  • PLAID Stage 3의 신뢰도에 영향

문서별 intra-document variance 분포. ColPali 같은 vision 모델은 텍스트 모델보다 훨씬 높은 분산을 보인다.

PLAID의 기하학적 한계

PLAID는 3단계 파이프라인으로 작동한다:

  1. Centroid Pruning: 쿼리 토큰과 관련 없는 centroid 제거
  2. Document Filtering: 관련 centroid만 포함한 문서로 후보 축소
  3. Verification: 압축된 표현으로 정확한 MaxSim 계산

Centroid Pruning의 선택성 붕괴

문서 d가 활성화하는 고유 centroid 수:

n_d = |{c_i : ∃p ∈ P_d, c_i = argmin_c ‖p - c‖}|

PLAID의 선택성(제거되는 문서 비율):

selectivity = 1 - (n_d · n_query) / (C · N_docs)
  • 높은 σ²_intra (예: ColPali) → n_d가 크게 증가
  • C = 65,536인 경우, n_d가 수천 개로 증가하면 pruning이 거의 아무것도 제거하지 못함
  • 결과: 거의 모든 문서가 Stage 2로 진입 → 계산 비용 급증

SumSim에서의 PLAID 붕괴

MaxSim의 "winner-takes-all" 특성:

  • 각 쿼리 토큰에 대해 단 하나의 문서 토큰만 승리
  • 비매칭 centroid는 max 연산에서 무시됨

SumSim의 "all-contribute" 특성:

  • 모든 문서 토큰이 모든 쿼리 토큰에 기여
  • Centroid pruning의 상한 기반 제거가 무의미해짐

PLAID Stage 2의 pruning 로직:

if max_i ⟨q_i, c_k⟩ < θ → centroid c_k 제거

이는 MaxSim에서만 유효하며, SumSim에서는:

contribution(c_k) = Σᵢ Σ(p∈cluster_k) ⟨qᵢ, p⟩

단일 쿼리 토큰과의 최대 유사도로 전체 기여를 상한할 수 없음.

Quantization 품질과 Residual Magnitude

ColBERTv2는 centroid ID + 2-bit 양자화 잔차로 압축:

재구성 오차: ‖p_i - (c_i + r_q)‖
MaxSim 근사 오차: |MaxSim_true - MaxSim_approx| ≤ Σᵢ ‖ε_i‖

MaxSim에서는 이것이 유효하지만, large residual을 가진 anisotropic 데이터에서는 2-bit 양자화가 significant noise를 도입한다.

Residual magnitude 분포. 큰 잔차는 양자화 노이즈를 증가시켜 PLAID의 정확도를 저하시킨다.

MUVERA의 기하학적 한계

MUVERA는 SimHash 기반 파티셔닝으로 multi-vector 집합을 고정 차원 벡터(FDE)로 변환한다.

SimHash와 Anisotropy의 불협화음

b개의 랜덤 하이퍼플레인 {h₁, ..., h_b}를 사용. Isotropic 데이터에서 충돌 확률:

P_collision(u, v) = 1 - θ_uv/π

이는 각도만으로 결정되며, 균일 분포에서 이론적 보장이 성립한다.

그러나 Anisotropic 데이터에서는:

Σ = [σ₁² 0; 0 σ₂²], σ₁² >> σ₂²

주축(high variance 방향) u에 수직인 랜덤 하이퍼플레인이:

  • ℓ₂ 거리에서 가까운 두 벡터를 다른 버킷으로 분리
  • 유효 각도 θ_eff > θ_uv

Anisotropic 클러스터에서 SimHash의 문제. 주축에 수직인 하이퍼플레인이 가까운 이웃을 분리한다.

Over-Partitioning 문제

올바른 충돌 확률:

P_collision^(b) = (1 - θ_eff/π)^b

b에 대해 지수적으로 감소하여, 큰 b (fine-grained FDE)는 nearest neighbor 쌍을 다른 파티션으로 분리할 확률이 높아진다.

트레이드오프 딜레마:

  • 작은 b: coarse FDE → 낮은 discrimination, 많은 false positive
  • 큰 b: fine-grained FDE → nearest neighbor 분리, recall 저하

Multi-kernel anisotropic 공간에서 elongated within-kernel 분포는 SimHash의 이론적 보장을 무효화한다.

실용적 해결책 #1: SumSim은 Mean-Pooling으로 충분하다

내적의 **bilinearity (쌍선형성)**를 활용한 핵심 증명:

sim_SumSim(Q, P) = Σᵢ Σⱼ ⟨qᵢ, pⱼ⟩
= Σᵢ Σⱼ qᵢᵀpⱼ
= (Σᵢ qᵢ)ᵀ (Σⱼ pⱼ)
= |Q| · |P| · ⟨μ_Q, μ_P⟩

여기서 μ_Q = (1/|Q|)Σᵢ qᵢ, μ_P = (1/|P|)Σⱼ pⱼ

SumSim이 mean-pooled 벡터 간 단일 내적으로 환원되는 과정.

실무 함의:

  • SumSim 기반 retrieval (aggregate affinity, group recommendation, cross-modal matching)
  • Mean-pooled representation을 오프라인 계산
  • 표준 ANN 시스템으로 인덱싱: HNSW, DiskANN, ScaNN
  • PLAID도, MUVERA도, 커스텀 인프라도 불필요

코드 예시:

# Multi-vector 대신 단일 벡터로 변환
doc_embedding_pooled = doc_embeddings.mean(dim=0)
query_embedding_pooled = query_embeddings.mean(dim=0)

# 표준 HNSW 인덱스 사용
index = hnswlib.Index(space='ip', dim=embedding_dim)
index.add_items(doc_embeddings_pooled)
results = index.knn_query(query_embedding_pooled, k=10)

# 필요 시 full multi-vector로 re-rank
for doc_id in results:
exact_score = compute_sumsim(query_embeddings, doc_embeddings[doc_id])

실용적 해결책 #2: ColPali의 고정 Cardinality 활용

ColPali는 ColBERT와 근본적으로 다른 특성을 가진다:

  • ColBERT: 텍스트 길이에 따라 가변적인 토큰 수 (50~500+)
  • ColPali: 페이지당 정확히 1030개 임베딩 (1024 image patches + 6 instruction tokens)

이 고정 cardinality는 완전히 다른 최적화 전략을 가능하게 한다.

Vespa의 Per-Token Nearest Neighbor 접근

Phase 0 (Pre-filtering):
각 쿼리 토큰 qᵢ에 대해:
- 이진화 임베딩으로 Hamming 거리 계산
- k₀개 nearest page-patch 검색
- 해당 페이지들의 union 생성

Phase 1 (Approximate MaxSim):
생존 페이지들을 inverted Hamming distance로 스코어링
상위 k₁개 유지

Phase 2 (Exact MaxSim):
상위 k₁개를 full-precision float MaxSim으로 re-rank

Vespa 스타일 ColPali 검색 워크플로우. 이진화 + per-token HNSW + 단계적 reranking.

저장 비용 비교 (10억 페이지 기준):

구성페이지당 저장량총 저장량Phase 0 Recall
ColPali float32526 KB~526 TB100%
ColPali bfloat16263 KB~263 TB~99%
ColPali binarized16.5 KB~16.5 TB~94%
Centroid index (k=30)7.7 KB~7.7 TBvariable

32배 압축 + 최소 recall 손실이 핵심이다.

이진화 구현:

def binarize_embeddings(embeddings):
"""각 차원을 평균 기준으로 이진화"""
threshold = embeddings.mean(dim=-1, keepdim=True)
binary = (embeddings > threshold).to(torch.uint8)
# 128 dim → 16 bytes
return torch.packbits(binary, dim=-1)

def hamming_distance(binary1, binary2):
"""Hamming 거리 계산"""
xor = binary1 ^ binary2
return torch.popcnt(xor).sum()

# Per-token HNSW 인덱스
per_token_index = [
hnswlib.Index(space='hamming', dim=16) # 16 bytes
for _ in range(1030) # 각 패치 위치별 인덱스
]

# Phase 0: Per-token nearest neighbor
candidate_pages = set()
for query_token in query_embeddings:
binary_query = binarize_embeddings(query_token)
for token_idx, index in enumerate(per_token_index):
nearest = index.knn_query(binary_query, k=100)
candidate_pages.update(nearest)

# Phase 1: Approximate MaxSim with binary
# Phase 2: Exact MaxSim with float32

의사결정 프레임워크

유사도 함수데이터 기하학권장 접근법핵심 고려사항
SumSimAnyMean-pool → 표준 HNSWMulti-vector 인프라 완전 불필요
MaxSimMulti-kernel, moderate σ²_intraPLAIDMS MARCO 스케일에서 검증됨
MaxSimMulti-kernel, high σ²_intraPLAID + large codebookStage-2 selectivity 실증 검증 필요
MaxSimAnyMUVERA + re-rankRecall 검증 필수, b 신중 조정
Top-K SumMulti-kernel커스텀 파이프라인PLAID pruning 직접 적용 불가
MaxSim (ColPali)High variance, fixed cardinalityPer-token HNSW + 이진화32x 압축, ~94% recall
MaxSim (소규모)<10M 문서Brute-force float MaxSim특수 인프라 불필요

실무 체크리스트:

  1. 데이터 기하학 먼저 분석:

    # Intra-document variance 측정
    for doc in corpus:
    embeddings = model.encode(doc)
    variance = embeddings.var(dim=0).mean()
    print(f"σ²_intra = {variance:.4f}")

    # Anisotropy 측정 (주성분 분산 비율)
    pca = PCA()
    pca.fit(all_embeddings)
    explained_variance_ratio = pca.explained_variance_ratio_
    anisotropy = explained_variance_ratio[0] / explained_variance_ratio[-1]
  2. 유사도 함수 확인: MaxSim이 정말 필요한가? SumSim으로 충분하지 않은가?

  3. 스케일 고려: 10M 문서 미만이면 brute-force도 실용적

  4. 고정 cardinality 여부: ColPali 같은 경우 per-token 접근 고려

Embedding Model 설계 시사점

저자의 가장 중요한 통찰: 학습 단계에서 인덱싱 친화적 기하학을 유도할 수 있다.

Intra-document Variance 정규화 (PLAID 최적화)

def variance_regularization_loss(embeddings, target_variance):
"""문서 내 분산을 목표값으로 정규화"""
doc_variance = embeddings.var(dim=0).mean()
return (doc_variance - target_variance) ** 2

# 전체 손실에 추가
total_loss = info_nce_loss + λ_var * variance_reg_loss

σ²_target을 codebook 크기에서 좋은 PLAID selectivity를 보이는 값으로 설정하면, 인덱싱 효율성을 모델에 내재화할 수 있다.

Within-kernel Isotropy 정규화 (MUVERA 최적화)

def isotropy_regularization_loss(embeddings, cluster_assignments):
"""각 클러스터 내에서 등방성 유도"""
loss = 0
for cluster_id in unique(cluster_assignments):
cluster_embeds = embeddings[cluster_assignments == cluster_id]
cov_matrix = torch.cov(cluster_embeds.T)
eigenvalues = torch.linalg.eigvalsh(cov_matrix)
# 고유값 분산 최소화 → 구형 클러스터
loss += eigenvalues.var()
return loss

더 둥근 클러스터 형태를 유도하여 랜덤 하이퍼플레인 파티셔닝과의 호환성 향상.

PoBE(Preference-Optimized Binary Embedding)에의 적용:

class GeometryAwareBinaryEmbedding(nn.Module):
def forward(self, x):
# 표준 임베딩
embeddings = self.encoder(x)

# Variance 정규화 (PLAID용)
var_loss = variance_reg(embeddings, target=0.15)

# Isotropy 정규화 (이진화 친화적)
iso_loss = isotropy_reg(embeddings, self.clusters)

# 이진화
binary_embeds = torch.sign(embeddings - embeddings.mean())

return binary_embeds, var_loss + iso_loss

핵심 메시지: 임베딩 모델 설계와 인덱싱 인프라는 독립적 선택이 아니다. 모델이 학습하는 기하학이 인덱스 성능을 직접 결정하며, 그 기하학에 대한 제어는 일반적으로 인식되는 것보다 훨씬 크다.

열린 연구 질문

Geometry-Aware Hashing

랜덤 하이퍼플레인 대신 실제 공분산 구조 기반 파티셔닝:

  • k-means LSH: 주성분 방향으로 파티션
  • Learned hashing: 데이터 분포를 직접 학습

Visual Retrieval의 적절한 유사도 함수

ColPali가 MaxSim을 사용하는 것은 ColBERT로부터의 관성일 수 있음:

  • 이미지 패치 간 유사도에는 다른 aggregation이 더 적절할 수 있음
  • Spatial pooling, attention-weighted sum 등의 대안 탐구 필요

모델 스케일에 따른 기하학 변화

더 큰 모델이 더 isotropic한 임베딩을 생성하는가?

  • 표현력 증가가 clustering 구조를 어떻게 변화시키는가?
  • 인덱싱 친화도와

프롬프트 캐싱(Prompt Caching) 전략

· 약 8분
김태한
AI Research Engineer, Brain Crew

TL;DR

프롬프트 캐싱은 AI 에이전트의 비용을 최대 90% 절감하고 응답 속도를 획기적으로 개선하는 핵심 기술입니다. 접두사 매칭(Prefix Matching) 원리에 기반하여, 변하지 않는 컨텍스트는 앞에 배치하고 동적 요소는 뒤로 보내는 전략이 필수적입니다. 시스템 프롬프트에 타임스탬프를 넣거나 도구 세트를 수시로 변경하는 등 캐시를 무효화하는 안티패턴을 피하고, 캐시 히트율을 시스템 가용성만큼 중요한 지표로 모니터링해야 합니다. Claude Code 팀의 실전 경험에서 나온 5가지 골든 룰을 따르면 비용 효율성과 사용자 경험을 동시에 극대화할 수 있습니다.

Key Takeaways

  • 프롬프트 레이아웃 설계가 핵심: 전역 정적 콘텐츠 → 프로젝트 컨텍스트 → 세션 컨텍스트 → 대화 기록 순으로 계층화하여 여러 세션이 상단부 캐시를 공유하도록 설계
  • 캐시 무효화 방지 원칙: 시스템 프롬프트에 동적 정보(타임스탬프 등) 절대 삽입 금지, 모델과 도구 세트는 고정하고 서브 에이전트로 유연성 확보
  • 도구 기반 상태 관리: 프롬프트를 직접 수정하는 대신 EnterPlanMode 같은 도구 호출로 상태 전환을 구현하여 정적 프롬프트 구조 보호
  • 지연 로딩 패턴 활용: 수십 개의 도구는 스텁(Stub)으로 제공하고 ToolSearch로 필요할 때만 상세 스키마 로드하여 접두사 안정성 유지
  • 캐시 히트율을 SLA로 관리: 히트율을 시스템 가용성 수준의 KPI로 취급하고, 일정 수준 이하로 떨어지면 알람을 발생시키는 운영 체계 구축

상세 내용

왜 프롬프트 캐싱이 AI 에이전트의 생존 전략인가

현대적인 AI 에이전트는 Claude Code처럼 긴 대화 세션을 유지하고, 대규모 코드베이스를 참조하며, 반복적인 도구 호출(Tool Call)을 수행합니다. 이 과정에서 매 요청마다 수만 개의 토큰을 모델에 새로 입력하는 것은 두 가지 치명적인 문제를 야기합니다.

첫째, 비용 폭증입니다. 일반적인 입력 토큰 비용은 프로덕션 환경에서 빠르게 누적되며, 특히 장시간 세션이나 대규모 컨텍스트를 다루는 에이전트의 경우 운영 비용이 비즈니스 모델 자체를 위협할 수 있습니다.

둘째, 레이턴시 증가입니다. 모델이 입력을 처음부터 다시 처리(Prefilling)하는 시간은 사용자 경험에 직접적인 영향을 미칩니다. 특히 실시간 코딩 어시스턴트처럼 빠른 피드백이 중요한 애플리케이션에서는 몇 초의 지연도 사용 가능성을 크게 저하시킵니다.

프롬프트 캐싱(Prompt Caching)은 이전 요청에서 계산된 컨텍스트를 재사용하여 이 두 문제를 동시에 해결합니다:

  • 최대 90%의 비용 절감: 캐시된 토큰은 신규 입력 토큰 대비 대폭 할인된 가격으로 처리됩니다
  • 응답 속도 향상: Prefilling 단계를 건너뛰어 응답 시작 시간(Time to First Token)이 비약적으로 단축됩니다

접두사 매칭(Prefix Matching): 캐싱의 작동 원리

프롬프트 캐싱은 '접두사 매칭'이라는 엄격한 규칙에 따라 작동합니다. API는 요청의 시작 부분부터 특정 캐시 브레이크포인트(Breakpoint)까지의 내용이 이전 요청과 완전히 동일할 때만 캐시를 적용합니다.

여기서 "완전히 동일"이란 표현이 핵심입니다:

  • 단 하나의 문자가 다르거나
  • 공백 하나가 추가되거나
  • 도구 정의의 순서가 바뀌거나
  • JSON 키의 직렬화 순서가 달라지면

해당 지점 이후의 모든 캐시는 즉시 무효화(Invalidate)됩니다.

이러한 특성 때문에 캐싱 전략의 핵심 원칙이 도출됩니다:

"변하지 않는 것은 앞으로, 자주 변하는 것은 뒤로"

이 원칙을 지키지 않으면 캐시가 지속적으로 깨지면서 오히려 캐시 생성 비용만 발생하여 역효과가 납니다.

프롬프트 레이아웃의 4계층 구조

Claude Code 팀이 실전에서 검증한 최적의 프롬프트 구조는 변경 빈도에 따라 다음과 같이 4계층으로 구성됩니다:

1. 전역 정적 컨텐츠 (Static System Prompt & Tools)

  • 모든 사용자, 모든 세션에서 공통으로 사용되는 시스템 지침
  • 기본 도구(Tool) 정의 세트
  • 가장 변경이 적고, 가장 많은 세션이 공유하는 레이어

2. 프로젝트 컨텍스트 (Project-specific Context)

  • 특정 프로젝트의 코딩 규칙이나 아키텍처 가이드
  • CLAUDE.md 같은 프로젝트 설정 파일
  • 프로젝트 내 모든 세션이 공유

3. 세션 컨텍스트 (Session Context)

  • 현재 사용자 세션의 고유 정보
  • 작업 중인 파일 목록이나 초기 상태
  • 한 세션 내에서는 안정적으로 유지

4. 대화 기록 (Conversation Messages)

  • 실시간으로 추가되는 사용자-모델 간 메시지
  • 가장 빈번하게 변경되는 레이어

이 순서를 엄격히 지켜야 여러 사용자와 세션이 상위 레이어의 캐시를 효과적으로 공유하여 전체 시스템의 캐시 히트율(Hit Rate)을 극대화할 수 있습니다.

캐시 무효화를 방지하는 5가지 골든 룰

1. 시스템 프롬프트에 동적 정보 삽입 금지

가장 흔한 실수는 시스템 프롬프트에 타임스탬프를 포함하는 것입니다:

❌ 나쁜 예:
You are a helpful assistant. Current time: 2024-02-20 14:32:15

이렇게 하면 매분마다 캐시가 무효화되어 캐싱의 효과가 완전히 사라집니다.

✅ 좋은 예:
시스템 프롬프트: You are a helpful assistant.
최신 사용자 메시지: [현재 시각: 2024-02-20 14:32:15] 사용자 질문...

날짜, 시간, 세션 ID 같은 동적 정보는 반드시 대화의 최신 메시지나 별도의 시스템 메시지로 전달하여 상단부의 정적 접두사를 보호해야 합니다.

2. 모델 및 도구 세트 고정

모델 전환의 함정 비용을 절감하려고 대화 중간에 claude-opus-4claude-haiku-3.5로 모델을 바꾸면 캐시를 처음부터 다시 쌓아야 하므로 오히려 더 많은 비용이 발생할 수 있습니다.

해결책: 주요 에이전트는 고성능 모델로 고정하고, 비용 최적화가 필요한 서브 태스크는 별도의 서브 에이전트(Sub-agent)로 분리하여 각각 최적의 모델을 사용하게 합니다.

도구 세트의 안정성 특정 상황에만 도구를 노출하려고 도구 정의를 동적으로 추가/제거하면 캐시가 지속적으로 깨집니다.

해결책: 모든 가능한 도구를 항상 정의해두고, 시스템 지침이나 컨텍스트를 통해 "지금은 이 도구만 사용하라"고 모델을 가이드합니다. 모델은 충분히 똑똑해서 이런 지침을 잘 따릅니다.

3. 상태 전환을 도구로 구현하기 (Plan Mode 사례)

사용자가 "계획 모드"에 진입할 때 시스템 프롬프트를 수정하는 대신, 다음과 같이 도구를 활용합니다:

# ❌ 나쁜 예: 프롬프트 직접 수정
system_prompt = base_prompt + "\n\nYou are now in plan mode..."

# ✅ 좋은 예: 도구 호출로 상태 전환
tools = [
{
"name": "EnterPlanMode",
"description": "Switch to planning mode for high-level design"
}
]

# 모델이 EnterPlanMode를 호출하면
# tool_result로 상태 메시지 반환
tool_result = {
"type": "system",
"content": "Now in plan mode. Focus on architecture..."
}

모델은 도구 호출 결과로 전달된 시스템 메시지를 통해 현재 상태를 인식하고, 정적 프롬프트는 전혀 변경되지 않아 캐시가 유지됩니다.

4. 도구 검색(Tool Search)과 지연 로딩(Deferred Loading)

수십 개의 도구를 모두 정의하면 초기 컨텍스트가 너무 커져 비용이 증가합니다. 하지만 도구를 제거하면 캐시가 깨지는 딜레마가 발생합니다.

해결책: 스텁(Stub) + 지연 로딩 패턴

# 초기에는 이름과 간단한 설명만 제공
tools = [
{"name": "ToolA", "description": "Brief description"},
{"name": "ToolB", "description": "Brief description"},
# ... 수십 개
{"name": "ToolSearch", "description": "Get detailed schema for a tool"}
]

# 모델이 ToolSearch("ToolA")를 호출하면
# 그때 상세 스키마를 반환
detailed_schema = {
"name": "ToolA",
"parameters": {...}, # 상세 파라미터 정보
"examples": [...]
}

이 패턴을 사용하면 도구 목록 자체는 안정적으로 유지되어 접두사 캐시가 보존되면서도, 필요한 순간에만 상세 정보를 로드하여 초기 컨텍스트 크기를 최소화할 수 있습니다.

5. 캐시 세이프 포킹(Cache-safe Forking)

대화가 길어져 컨텍스트 윈도우가 가득 차면 요약(Compaction)이 필요합니다. 이때 새로운 빈 세션을 만들어 요약하면 기존 캐시를 전혀 활용하지 못합니다.

최적화된 요약 전략:

# ❌ 비효율적: 새 세션으로 요약
new_request = {
"system": system_prompt,
"messages": [{"role": "user", "content": "Summarize this: " + full_history}]
}

# ✅ 효율적: 기존 컨텍스트 유지 + 요약 요청 추가
fork_request = {
"system": system_prompt, # 캐시됨
"tools": tools, # 캐시됨
"messages": [
...existing_messages, # 캐시됨
{"role": "user", "content": "Summarize the conversation so far"}
]
}

기존 대화의 모든 컨텍스트를 그대로 포함한 채 마지막에 요약 요청만 추가하면, 이전 계산량을 100% 재사용하면서 요약본만 새로 생성할 수 있습니다. 이를 "캐시 세이프 포킹"이라고 부르며, Claude Code 팀이 실전에서 검증한 강력한 패턴입니다.

운영 및 모니터링: 캐시 히트율을 SLA처럼 관리하기

Claude Code 팀은 프롬프트 캐시 히트율을 시스템 가용성(Uptime)과 동등한 수준의 핵심 지표로 관리한다고 밝혔습니다.

모니터링 전략:

  • 캐시 히트율 대시보드: 실시간으로 히트율을 추적하고 시각화
  • 알람 설정: 히트율이 기준치(예: 85%) 이하로 떨어지면 즉시 경고 발생
  • 장애 대응: 히트율 급락을 서비스 장애와 동일하게 취급하여 긴급 조사

비결정성(Non-determinism) 제거: 캐시가 예상치 못하게 깨지는 가장 흔한 원인은 직렬화(Serialization) 과정의 비결정성입니다.

# ❌ 문제 있는 코드: Dictionary 순서가 랜덤
tools = {
"tool_a": {...},
"tool_b": {...}
}
json_str = json.dumps(tools) # 순서가 매번 달라질 수 있음

# ✅ 안전한 코드: 순서 명시적 보장
tools = OrderedDict([
("tool_a", {...}),
("tool_b", {...})
])
json_str = json.dumps(tools, sort_keys=True)

Python의 일반 dict, Java의 HashMap 등은 삽입 순서를 보장하지 않거나 버전에 따라 동작이 다를 수 있습니다. 캐시 안정성을 위해서는 항상 순서를 명시적으로 제어해야 합니다.

Claude Code의 실전 활용

Claude Code는 터미널, IDE(VS Code, JetBrains), 데스크톱 앱, 웹 브라우저 등 다양한 환경에서 동작하는 AI 코딩 어시스턴트입니다. 전체 코드베이스를 이해하고, 여러 파일을 동시에 편집하며, 개발 도구와 통합되어 작동합니다.

이러한 복잡한 멀티턴 상호작용에서 프롬프트 캐싱은 선택이 아닌 필수입니다. Claude Code 팀이 공유한 전략들은 실제 프로덕션 환경에서 수십만 세션을 처리하며 검증된 베스트 프랙티스입니다.

설치 및 시작:

# macOS, Linux, WSL
curl -fsSL https://claude.ai/install.sh | bash

# 프로젝트에서 실행
cd your-project
claude

Claude Code는 Native Install 방식으로 설치하면 자동 업데이트가 활성화되어 최신 기능과 보안 패치를 자동으로 받을 수 있습니다.

결론: 설계 단계부터 캐시를 고려하라

프롬프트 캐싱은 단순히 비용을 줄이는 최적화 기법이 아닙니다. 이것은 다음을 결정짓는 핵심 설계 원칙입니다:

  • 사용자 경험: 응답 속도가 빠른 에이전트는 사용자 만족도와 리텐션을 크게 향상시킵니다
  • 비즈니스 모델: 90%의 비용 절감은 수익성과 확장성을 직접적으로 개선합니다
  • 시스템 안정성: 캐시 히트율을 SLA로 관리하면 예측 가능한 운영이 가능합니다

AI 에이전트를 개발할 때 프로토타입 단계부터 프롬프트 레이아웃을 캐시 친화적으로 설계하는 것이 현대적인 AI 엔지니어링의 표준입니다. 나중에 리팩토링하려면 훨씬 큰 비용이 들기 때문입니다.

Claude Code 팀의 5가지 골든 룰을 따르고, 캐시 히트율을 핵심 지표로 모니터링하면, 비용 효율적이면서도 뛰어난 사용자 경험을 제공하는 AI 에이전트를 구축할 수 있습니다.

References

Claude Agent Teams를 활용한 병렬처리 사례

· 약 7분
김태한
AI Research Engineer, Brain Crew

TL;DR

Anthropic의 Claude Code에 새로 추가된 Agent Teams 모드는 여러 Claude 인스턴스가 독립적인 컨텍스트 윈도우에서 병렬로 작업하며 서로 직접 소통하는 구조입니다. 기존 Subagent의 "지시-보고" 방식과 달리, 팀원들이 자율적으로 태스크를 분배하고, 토론하며, 공유 태스크 리스트에서 작업을 claim합니다. Anthropic은 이 방식으로 16개 Opus 4.6 인스턴스를 투입해 2주간 $20,000 비용으로 10만 줄의 Rust 기반 C 컴파일러를 구축했으며, Linux 커널, SQLite, PostgreSQL 등을 컴파일하고 GCC 테스트 스위트 99%를 통과하는 성과를 냈습니다.

Key Takeaways

  • 병렬 작업의 실질적 가치: Agent Teams는 단순 속도 향상이 아닌 관점의 다양화를 제공합니다. 보안, 성능, 테스트 커버리지 등 전문 영역별로 에이전트를 배치하면 단일 에이전트보다 포괄적인 검토가 가능합니다.
  • 자율적 태스크 관리: 공유 태스크 리스트에서 에이전트가 스스로 작업을 claim하고 완료하는 구조로, 중앙 조율 오버헤드 없이 병렬 처리 효율을 극대화할 수 있습니다.
  • 격리된 작업 환경과 동기화: Docker를 통한 작업 공간 격리, Git 기반 동기화, Task Lock을 통한 중복 방지 등 체계적인 인프라로 merge conflict까지 에이전트가 자동 해결합니다.
  • 실전 검증된 확장성: 10만 줄 규모의 컴파일러 프로젝트를 2,000회 세션에 걸쳐 완수한 사례는 장기 실행 자율 개발의 실현 가능성을 보여줍니다.
  • 활성화는 간단하지만 제약 인지 필요: settings.json에 한 줄 추가로 활성화 가능하나, 세션당 하나의 팀만 운영 가능하고 파일 동시 수정 시 충돌이 발생하는 등 현재 실험적 기능의 한계를 이해해야 합니다.

상세 내용

Agent Teams란 무엇인가

Agent Teams는 Claude Code의 새로운 실험적 모드로, 여러 개의 Claude Code 인스턴스가 팀으로 협업하는 구조입니다. 하나의 인스턴스가 리드(lead) 역할을 맡아 작업을 조율하고, 나머지 팀원(teammates)들은 각자 독립적인 컨텍스트 윈도우에서 작업하면서 서로 직접 메시지를 주고받습니다.

기존의 Subagent 방식은 "작업을 시켜놓고 결과만 받는" 일방향 구조였습니다. 반면 Agent Teams는 팀원끼리 토론하고, 서로 반박하며, 태스크를 나눠 가지는 양방향 협업이 가능합니다. 공유 태스크 리스트를 통해 에이전트들이 자율적으로 작업을 claim하고 완료하는 방식으로 운영됩니다.

Agent Teams 구조

시작하기: 설정과 활성화

Agent Teams는 Claude Code v2.1.32 이상에서 사용할 수 있는 실험적 기능입니다. 활성화 방법은 매우 간단합니다. settings.json 파일에 다음 설정을 추가하면 됩니다:

"CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS": true

또는 환경 변수로 CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS를 설정할 수도 있습니다.

활성화 후에는 Claude에게 팀 구성을 요청하는 프롬프트를 제공하면 됩니다. 예를 들어, "코드 리뷰를 위해 3명의 전문가 팀을 구성해줘. 한 명은 보안, 한 명은 성능, 한 명은 테스트 커버리지를 담당하도록" 같은 지시가 가능합니다.

실전 활용 사례

병렬 코드 리뷰

가장 직관적인 활용 사례는 관점별 병렬 코드 리뷰입니다. 보안, 성능, 테스트 커버리지를 각각 전담하는 팀원을 배치하면, 단일 에이전트가 순차적으로 검토할 때보다 훨씬 포괄적이고 빠른 리뷰가 가능합니다. 각 팀원은 자신의 전문 영역에 집중하면서도, 필요시 서로 토론하고 반박하며 품질을 높일 수 있습니다.

C 컴파일러 구축: 대규모 프로젝트 사례

Anthropic은 Agent Teams의 가능성을 검증하기 위해 야심찬 실험을 진행했습니다. Claude Opus 4.6 인스턴스 16개를 투입해, 사람의 개입 없이 완전히 자율적으로 Rust 기반 C 컴파일러를 구축하는 프로젝트였습니다.

프로젝트 스펙:

  • 기간: 약 2주
  • 세션 수: 약 2,000회
  • 비용: $20,000
  • 결과물: 10만 줄 규모의 Rust 코드

성과:

  • Linux 커널(6.9) 컴파일 성공 (x86, ARM, RISC-V 지원)
  • QEMU, FFmpeg, SQLite, PostgreSQL, Redis 컴파일 가능
  • GCC 테스트 스위트 99% 통과
  • Doom 게임 실행 가능

이 프로젝트에서 핵심은 단순히 많은 에이전트를 투입한 것이 아니라, 장기 실행 자율 개발을 가능하게 하는 하네스(harness) 설계였습니다.

아키텍처와 조율 메커니즘

자율 실행 루프

기존 Claude Code는 작업이 완료되면 사용자 입력을 기다리며 멈춥니다. 장기 실행 프로젝트를 위해서는 지속적으로 작업을 이어갈 수 있는 구조가 필요했습니다. Anthropic은 간단한 bash 루프로 이를 구현했습니다:

#!/bin/bash
while true; do
COMMIT=$(git rev-parse --short=6 HEAD)
LOGFILE=agent_logs/agent_${COMMIT}.log
claude --dangerously-skip-permissions \
-p $(cat AGENT_PROMPT.md) \
--model claude-opus-X-Y &> $LOGFILE
done

이 루프는 Claude가 하나의 태스크를 완료하면 즉시 다음 태스크를 픽업하도록 만듭니다. 프롬프트에는 "문제를 작은 조각으로 나누고, 진행 상황을 추적하고, 다음 작업을 스스로 결정하고, 완벽해질 때까지 계속하라"는 지시가 포함되었습니다.

병렬 작업의 조율

여러 에이전트가 동시에 작업할 때 발생하는 문제들을 해결하기 위해 다음과 같은 메커니즘이 사용되었습니다:

Docker 기반 격리: 각 에이전트는 독립된 Docker 컨테이너에서 실행되어 작업 환경이 격리됩니다. 이는 의도치 않은 간섭을 방지하고, 각 에이전트가 안전하게 실험할 수 있는 환경을 제공합니다.

Git 기반 동기화: 모든 에이전트의 작업은 Git을 통해 동기화됩니다. 각 에이전트는 자신의 변경 사항을 커밋하고, 다른 에이전트의 변경 사항을 pull하여 최신 상태를 유지합니다.

Task Lock 시스템: 동일한 작업을 여러 에이전트가 중복으로 수행하는 것을 방지하기 위해 Task Lock 메커니즘이 구현되었습니다. 에이전트가 태스크를 claim하면 다른 에이전트는 해당 작업을 선택할 수 없습니다.

자동 Merge Conflict 해결: 놀랍게도, 발생하는 merge conflict조차 에이전트들이 스스로 해결했습니다. 이는 Agent Teams의 협업 능력이 단순한 병렬 실행을 넘어서는 것을 보여줍니다.

Agent Teams의 이점

1. 진정한 병렬성

단일 Claude Code 세션은 한 번에 하나의 작업만 수행할 수 있습니다. 프로젝트 규모가 커질수록, 여러 이슈를 병렬로 디버깅하는 것이 훨씬 효율적입니다. Agent Teams는 이를 가능하게 합니다.

2. 전문화와 관점의 다양성

여러 에이전트를 활용하면 각 에이전트가 특정 영역에 전문화될 수 있습니다. 보안 전문가, 성능 최적화 전문가, 테스트 전문가 등으로 역할을 분담하면, 각 관점에서 깊이 있는 검토가 가능합니다.

3. 상호 검증과 품질 향상

팀원들 간의 토론과 반박 과정에서 단일 에이전트가 놓칠 수 있는 문제들이 발견됩니다. 서로 다른 접근 방식을 경쟁적으로 시도하는 "competing hypotheses" 방식도 가능합니다.

현재 제약사항과 고려사항

Agent Teams는 실험적 기능이므로 몇 가지 알려진 제약사항이 있습니다:

세션 제한: 세션당 하나의 팀만 운영 가능합니다. 복수의 팀을 동시에 관리하려면 별도의 세션이 필요합니다.

파일 충돌: 같은 파일을 두 팀원이 동시에 수정하면 충돌이 발생할 수 있습니다. 작업 분배 시 파일 단위로 명확하게 영역을 구분하는 것이 좋습니다.

세션 재개 문제: 현재 버전에서는 세션 재개(resumption) 관련 알려진 이슈들이 있습니다.

종료 타이밍: 리드 에이전트가 팀원들의 작업이 완료되기 전에 종료되는 경우가 발생할 수 있습니다. 명시적인 종료 조건 설정이 필요합니다.

고아 tmux 세션: 에이전트가 비정상 종료되면 tmux 세션이 남아있을 수 있습니다. 정기적인 모니터링과 정리가 필요합니다.

베스트 프랙티스

충분한 컨텍스트 제공

각 팀원이 독립적으로 작업할 수 있도록 충분한 컨텍스트를 제공하세요. 프로젝트 목표, 코딩 스타일 가이드, 기술 스택 정보 등을 명확히 공유해야 합니다.

적절한 팀 크기

무조건 많은 에이전트가 좋은 것은 아닙니다. 태스크의 병렬화 가능성, 조율 오버헤드, 비용을 고려하여 적절한 팀 크기를 선택하세요. C 컴파일러 프로젝트에서는 16개가 사용되었지만, 대부분의 경우 3~5개면 충분합니다.

태스크의 적절한 크기 조정

너무 큰 태스크는 병렬화의 이점을 살리기 어렵고, 너무 작은 태스크는 조율 오버헤드가 커집니다. 각 에이전트가 독립적으로 완료할 수 있는 단위로 태스크를 나누세요.

팀원 작업 완료 대기

다음 단계로 진행하기 전에 모든 팀원의 작업이 완료되었는지 확인하세요. 리드 에이전트가 너무 빨리 진행하면 팀원들의 작업이 손실될 수 있습니다.

리서치와 리뷰로 시작

복잡한 구현 작업 전에, 먼저 리서치와 코드 리뷰 같은 안전한 작업으로 Agent Teams를 활용해보세요. 이는 팀의 작동 방식을 이해하고 조율하는 데 도움이 됩니다.

파일 충돌 회피

작업 분배 시 각 팀원이 다른 파일을 담당하도록 명확히 영역을 구분하세요. 동일 파일에 대한 동시 수정은 피하는 것이 좋습니다.

모니터링과 스티어링

Agent Teams는 자율적이지만, 정기적인 모니터링이 필요합니다. 진행 상황을 확인하고, 필요시 방향을 조정하세요. 로그를 활용해 각 에이전트의 활동을 추적할 수 있습니다.

미래 전망

Agent Teams는 AI 기반 소프트웨어 개발의 새로운 패러다임을 보여줍니다. 단일 에이전트의 능력 향상도 중요하지만, 여러 에이전트의 효과적인 협업을 통해 더 복잡하고 큰 규모의 문제를 해결할 수 있습니다.

C 컴파일러 프로젝트는 완전 자율적인 장기 실행 개발이 실현 가능함을 증명했습니다. 물론 $20,000의 비용이 들었지만, 이는 여러 명의 엔지니어가 몇 주간 투입되는 것과 비교하면 경쟁력 있는 수준입니다. 더 중요한 것은, 이 기술이 계속 발전하면서 비용은 낮아지고 능력은 향상될 것이라는 점입니다.

현재는 실험적 기능이지만, Agent Teams의 핵심 아이디어—독립적 컨텍스트, 직접 통신, 자율적 태스크 관리—는 향후 AI 협업 시스템의 표준이 될 가능성이 높습니다.

References