실행 땐 AI 모델 없이 코드만으로 — 로봇 정책 COAP 해부

실행 중에는 AI 모델 없이, 미리 개발된 코드가 로봇 상태를 측정하고 동작을 결정한다. RoboDojo 42개 양팔 과제에서 70.24% 성공.
English  ·  日本語  ·  한국어
← 목록으로
온
온틀 리서치
2026년 10월 12일 수정 2026.10.17 읽기 18분 조회 2

이 논문의 핵심은 역할을 나눈 데 있다. AI(코딩 에이전트)는 개발 단계에서 로봇을 움직일 코드를 만들고, 로봇은 실행 단계에서 그 코드만 그대로 따른다. 실행 루프 안에는 신경망 모델이 없다. 대신 카메라 영상과 관절 센서에서 로봇·환경·과제의 상태를 코드로 직접 측정해 변수에 담고, 그 변수만 보고 모든 동작을 코드 논리로 결정한다.

이게 성립하려면 전제가 하나 필요하다. 물체의 3차원 형상, 카메라 위치, 로봇 모양, 테이블 높이 같은 값이 미리 주어져 바뀌지 않아야 한다. 벤치마크는 이 값들을 공개하므로, 코드는 "어떤 물체가 지금 어디에 있는가"만 영상에서 알아내면 된다.

저자들은 이 방식을 Code-Only-as-Policy(COAP)라 부르고, RoboDojo의 양팔 조작 42개 과제에서 실행 시점에 모델 없이 70.24%의 성공률을 보고했다.

이 논문이 푸는 문제

지금 로봇 정책의 주류는 "모델을 제어 루프 안에 계속 둔다"는 전제를 공유한다. VLA(Vision-Language-Action, 영상과 언어를 받아 동작을 출력하는 신경망)는 관측을 동작으로 바로 매핑한다. 에이전트 하네스(모델 호출과 도구 실행을 관리하는 구조)는 매 순간 영상·언어 모델(VLM, 영상과 글을 함께 이해하는 모델)에게 "다음에 뭘 할까"를 물어본다.

이 구조의 불편함은 세 군데에서 동시에 나온다. 첫째, 모델이 무엇을 보고 그 동작을 골랐는지 들여다볼 수 없다. VLA의 결정은 가중치 안에 숨어 있고, 하네스가 쓰는 모델도 추론 텍스트는 보여주지만 실제 선택 과정은 통제가 안 된다. 둘째, 매 스텝마다 모델을 호출하니 느리고 비싸며, 같은 입력이라도 호출마다 결과에 무작위성이 섞인다. 셋째, 새 과제를 배우려면 데이터를 다시 모아 다시 학습해야 하는데, 한 과제를 더 가르치다 이전 과제 성능이 깎이는 일(이른바 망각)이 흔하다.

핵심 아이디어: 상태를 코드 변수로 꺼낸다

간단한 장면부터 보자. 컵 하나를 집는 일이다. COAP는 두 가지를 코드로 적어둔다. 하나는 상태 변수 — 컵의 위치와 방향, 두 팔의 관절각, 지금 몇 번째 단계인가. 다른 하나는 동작 규칙 — "컵 위치로 팔 끝을 옮긴다 → 그리퍼를 닫는다 → 들어올린다". 실행할 때 로봇은 영상에서 컵 위치를 읽어 상태 변수를 채우고, 규칙은 그 변수를 보고 다음 동작을 고른다. 컵이 다른 자리에 놓여도 규칙은 그대로다. 바뀌는 건 변수값뿐이다.

이 구분이 COAP를 다른 방식과 가른다. 정책을 "상태에서 동작으로 가는 함수"로 보면, 이 함수가 얼마나 겉으로 드러나 있느냐가 관건이다. VLA는 함수가 가중치 안에 숨어 있다. 에이전트 하네스는 일부를 텍스트 메모리로 드러내지만 핵심 모델은 여전히 블랙박스다. COAP는 함수 전체를 코드로 꺼낸다. 상태는 코드 변수에, 규칙은 코드 논리에 적는다. 둘 다 눈에 보이니 실행 시점엔 모델이 필요 없다.

저자들은 이 구조를 튜링 머신에 빗댄다. 바뀌는 상태는 기호를 적어두는 테이프, 고정된 규칙은 테이프를 읽고 쓰는 기계의 동작 규칙에 해당한다. 테이프만 갈아 끼우면 같은 규칙으로 새 입력을 처리할 수 있다 — 물체 배치만 달라진 새 상황에서 같은 코드가 그대로 도는 것과 같다. 이름은 Embodied Turing Machine(체화된 튜링 머신)이다.

상태는 세 부분으로 나뉘고, 과제가 달라도 형태는 같다.

  • 환경 상태: 각 물체의 위치·방향·크기·종류, 그리고 "하나가 다른 것 위에 놓여 있다" 같은 물체 사이의 공간 관계. 각 기록에는 측정의 오차·출처·시각까지 함께 저장한다.
  • 로봇 상태: 두 팔 각각의 관절각, 엔드이펙터 자세(로봇 팔 끝의 위치와 방향), 그리퍼 열림 정도, 그리고 각 팔이 닿을 수 있는 자세들.
  • 과제 상태: 현재 단계, 각 물체에 배정된 팔, 재시도 횟수, 과제가 기억해 둬야 할 정보(예: 컵 아래에 있던 색).

지각: 영상에서 물체 위치를 읽는 세 단계

지각도 특별한 신경망이 아니라 NumPy·OpenCV로 짠 평범한 코드다. 크게 세 단계로 움직인다.

  1. 배경과 로봇을 제외한다. 측정된 관절각으로 로봇의 3차원 표면 모형(로봇 메시)을 영상 위에 겹쳐, 로봇이 가린 픽셀을 지운다. 그리고 테이블 색과 다른 픽셀만 남긴다.
  2. 물체 위치를 추정한다. 남은 영역 중 아래 가장자리가 테이블에 닿은 것을 물체 후보로 보고, 그 경계에서 뻗어 나간 가상의 선을 테이블 면과 만나게 해 테이블 위 위치를 구한다.
  3. 알려진 형상과 맞춘다. 미리 공개된 3D 형상을 그 위치에 놓고 좌우로 돌려 가며, 영상 속 물체와 가장 많이 겹치는 자세를 고른다.

카메라 위치, 로봇 모양, 물체 형상, 테이블 높이는 에피소드마다 바뀌지 않는 상수, 즉 규칙의 일부다. 바뀌는 것은 "어떤 물체가 어디 있나"뿐이고 그게 상태다. 밀리미터 정밀도가 필요한 과제는 집기 직전에 손목 카메라로 한 번 더 측정한다.

과제끼리 코드를 나눠 쓰는 구조

모든 과제가 같은 형태의 상태를 쓰기 때문에, 한 과제용으로 짠 모듈을 다른 과제가 그대로 가져다 쓴다. 코드는 아래로만 의존하는 층 구조다. 과제 코드가 물체별 코드를 부르고, 그것이 집기·놓기·밀기·붓기 같은 조작 코드를 부르고, 그것이 다시 지각·모션 코드를 부른다. 위층은 "무엇을"(순서, 과제별 판단, 복구 조건)을 정하고, 아래층이 "어떻게"를 맡는다. 그 결과 새 과제가 돌리는 코드의 83%가 공용 라이브러리에서 온다.

새 과제가 라이브러리를 넓히는 길은 세 가지다.

  • 기존 모듈을 조합한다(옮기기 호출 하나가 집을 지점 찾기, 접근, 쥐기, 들기 확인, 운반, 놓기, 최종 검증으로 펼쳐진다).
  • 기존 과제를 상속해 판단 하나만 덮어쓴다(지정된 바구니로 분류하는 과제가 기존 정렬 과제 흐름을 전부 재사용하고 "어느 바구니에 넣을지"만 바꾼다).
  • 공용 함수에 기본값이 꺼진 파라미터를 하나 더 붙인다.

세 번째가 중요한 이유는 호환성이다. 새 인자를 넘기지 않는 기존 과제는 단위 테스트 입력 범위 안에서 실행 궤적이 그대로 유지되도록 조건을 건다. 다만 이 조건은 테스트한 입력 범위에 한정되므로, 확장이 기존 과제를 절대 깨지 않는다고 전면 보장하는 것은 아니다. 설계 의도는 새 인자를 쓰는 과제만 바뀌도록 범위를 좁히는 데 있다.

다른 접근과의 비교

코드로 정책을 짜는 발상 자체는 새롭지 않다. 논문이 정리한 흐름과 나란히 놓으면 차이가 선명해진다. Code-as-Policies·ProgPrompt·VoxPoser 계열은 모델에게 지각·제어 API를 부르는 코드를 쓰게 한다. PyRUA-Lean은 에피소드가 도는 동안 모델이 조금씩 코드를 쓰고, Skill2Real은 매 결정 단계마다 저장된 스킬에서 새 프로그램을 조립한다. 공통점은 둘이다. 모델이 실행 중에 프로그램을 쓰고, 상태는 외부의 학습된 지각 모델이 가져다준다.

오프라인에서 프로그램을 한 번만 쓰는 RHO·EmbodiedSWE도 있지만, 여기서도 상태는 코드 바깥에서 온다(RHO는 학습된 지각 모델에서, EmbodiedSWE는 시뮬레이터가 알려주는 정답값에서). 이 지각 모델들은 블랙박스라 그 불확실성을 코드가 통제하지 못한다.

COAP의 차이는 상태를 코드가 스스로 측정한다는 데 있다. 측정이 틀리면 코딩 에이전트가 측정 코드를 고치고, 그만큼 상태는 시간이 지날수록 정확해진다. 로봇 쪽 자기개선 연구인 RoboRSI는 여러 역할의 에이전트 루프에 "성능이 깎이면 막는" 게이트를 두지만, 실행 중 결정은 여전히 모델이 내린다. 게이트를 통과한 변경도 블랙박스를 조종할 뿐이라, 테스트한 행동과 실제 실행 행동이 어긋날 수 있다. COAP는 상태가 명시적인 코드이므로 "테스트한 행동이 곧 실행 행동"이고, 소프트웨어를 고치듯 정책을 고친다.

실험은 어떻게 설계됐나

벤치마크는 RoboDojo다. 42개 양팔 과제가 다섯 축에 걸쳐 있다. 기억(Memory, 6개), 정밀(Precision, 8개), 열린 지시(Open instruction, 8개), 일반화(Generalization, 12개), 장기 조작(Long-Horizon, 8개). 각 과제는 50개 레이아웃을 세 시드로 평가한다. 일반화 과제는 레이아웃의 절반이 무작위화되어 새 물체, 새 방·테이블 외관, 최대 20개의 방해물까지 등장한다. 모든 수치는 공식 평가 클라이언트·판정기·요약 스크립트로 산출된다.

정책이 받는 입력은 세 개의 RGB 카메라 영상(머리 1 + 양 손목 2), 관절각·엔드이펙터 자세·그리퍼 명령 같은 관절 센서값, 그리고 지시문이다. 성공률(SR)은 과제 전체가 성공한 에피소드의 비율이고, 점수(Score)는 벤치마크의 진행도 점수다. 이 설계가 재는 것은 "정책이 상태를 얼마나 잘 유지·측정하고 그에 맞게 행동하는가"다. 특히 기억·정밀 과제가 상태 유지와 측정 정확도를 직접 겨냥한다.

여기서 꼭 구분할 점이 있다. COAP의 코드 라이브러리는 오프라인에서 개발된다. Claude Opus 5.5 코딩 에이전트가 사람 개입 없이 닫힌 자기개선 루프 안에서 코드를 쓰고 디버깅한다. "한 에피소드에서만 통하는 꼼수 금지", "테스트 시점에 정답 상태 참조 금지" 같은 고정 규칙 아래에서 돈다. 개발에는 벤치마크의 테스트셋을 쓰지 않고, 완성된 코드는 테스트 레이아웃을 포함한 모든 에피소드에서 그대로 실행된다.

개발 루프: 실패 분석 → 수정 → 검사 → 채택

개선 루프는 네 걸음으로 돈다.

  • 실패 분석: 실패한 개발 실행의 기록을 뒤져 문제가 된 변수나 규칙을 찾는다.
  • 수정: 해당 변수·규칙을 고친다.
  • 검사: 시뮬레이션에 넣기 전에 CPU에서 두 가지를 확인한다. 하나는 과제 코드를 가상 장면에 돌려 모든 단계가 목표 상태에 닿는지, 다른 하나는 모든 경유점에서 역기구학(목표 위치에 도달할 관절각 계산) 해가 있고 로봇·물체가 서로 부딪히지 않는지다. 통과한 것만 다음으로 넘어간다.
  • 채택: 고칠 때 쓰는 데이터(개발셋)와 받아들일지 가를 때 쓰는 데이터(검증셋)를 분리한다. 대상 과제의 성공 수가 재실행 잡음 이상으로 늘고, 다른 과제엔 성능 저하가 없을 때만 변경을 반영한다.

이 채택 규칙은 검증셋에서 큰 성능 저하를 걸러내 개선이 대체로 누적되게 한다. 다만 부록 A.2가 밝히듯 회귀 검사는 큰 저하만 배제할 뿐 모든 변화를 막지는 못하므로, 각 걸음이 성능을 전혀 떨어뜨리지 않는다고까지 보장하는 것은 아니다.

결과와 의미

표 2에서 COAP의 전체 성공률은 70.24%, 진행도 점수는 75.45다. 비교 대상 중 전체 성공률이 가장 높았던 기준선은 에이전트 하네스 계열 PhysicalRSI(에이전트+VLA)로 31.38%였다. 두 값의 차이는 약 38.9%p다. 초록과 본문이 말하는 "state-of-the-art 대비 38.9%"는 이 전체 성공률의 격차를 가리킨다.

차원별로 보면 성공률과 "최고 기준선 대비 격차"는 다른 숫자다. 둘을 나눠 적으면 이렇다.

차원 COAP 성공률 최고 기준선 대비 격차
기억(Memory) 89.9 +39.6
정밀(Precision) 75.1 +41.6
열린 지시(Open) 64.1 +33.1
일반화(Generalization) 65.7 +35.2
장기 조작(Long-Horizon) 56.4 +13.0

주의할 점. 각 줄의 "최고 기준선"은 줄마다 다른 방법일 수 있다. 한 경쟁자를 모든 면에서 눌렀다고 뭉뚱그려선 안 된다.

실험이 보여준 것은 이렇다. 격차가 가장 큰 차원은 정밀(+41.6)이고, 기억(+39.6)이 그다음이다. 기억 과제는 "앞에서 본 정보를 뒤 단계까지 들고 가야" 풀린다. COAP는 그 정보를 과제 상태 변수에 그대로 적어두므로, 이전 단계의 사실이 다음 결정까지 사라지지 않는다. 반대로 장기 조작은 격차가 +13.0으로 가장 좁다.

여기서 필자의 가설을 덧붙이면, 과제가 길어질수록 측정 오차와 복구 실패가 매 단계 쌓이기 때문으로 보인다. 한 번 틀린 위치 추정이 다음 동작을 어긋나게 하고, 그 어긋남이 뒤 단계로 누적된다. 긴 과제일수록 코드 논리가 이 누적을 버텨야 한다는 뜻이다. 다만 이건 격차 패턴을 보고 세운 해석이지, 수치가 직접 증명하는 결론은 아니다.

정리하면, 이 결과는 실행 중 모델 호출을 없앨 수 있음을 보여준다. 개발에 필요한 비용과 현장 적용 가능성은 별도로 평가해야 한다. 이 성과는 어디까지나 오프라인에서 코딩 에이전트가 과제별 로직을 다듬어 얻은 것이기 때문이다. 저자들은 이 코드가 특정 에피소드에 묶이지 않으므로, 한 정책으로 여러 에피소드에서 성공 궤적을 안정적으로 뽑아 VLA·에이전트 하네스의 학습 데이터로 쓸 수 있다고 제안한다.

한계와 남은 질문

저자들이 직접 인정한 약점은 일반화다. COAP는 과제별 코드 로직을 소량 필요로 하기 때문에 일반화에 주로 약하다고 못 박는다(다만 에이전트 하네스 계열도 과제 수준의 메모리를 쓰고 일부는 에피소드 수준 로직에 의존한다고 덧붙인다). 그리고 COAP의 상한은 결국 "상태를 얼마나 정확히 표현하느냐, 코드 논리가 얼마나 견고하냐"에 달려 있다고 명시한다. 측정이 틀리면 결정도 틀린다는 뜻이다.

여기에 필자의 관찰을 더하면, 이 방법이 통하는 전제가 꽤 세다. 카메라 위치·로봇 모양·물체 형상·테이블 높이가 미리 주어지고 바뀌지 않아야, 지각 코드가 가상의 선과 형상 맞춤으로 자세를 복원할 수 있다. 벤치마크는 이 값들을 공개하지만, 현장의 로봇은 물체 형상을 모를 때가 많다. 또 "상태를 정확히 측정할 수 있다"는 가정이 조명·가림·처음 보는 물체 앞에서 얼마나 버티는지는 이 범위만으로 단정하기 어렵다. 접촉이 많고 모양이 변하는 조작으로 갈수록 이 가정은 느슨해질 여지가 있다.

온틀 관점

COAP의 교훈을 업무 자동화로 옮길 때 먼저 그을 경계가 있다. 담당자나 마감일 같은 값은 코드로 또렷이 읽을 수 있지만, 메시지에 담긴 의도는 해석이 필요하다. 모든 것을 코드로 옮길 수는 없다.

좁은 사례 하나로 보자. "담당자가 비어 있는 마감 임박 작업을 찾아 다시 배정한다"는 일이다. 여기서 '담당 공석'과 '마감까지 남은 시간'은 티켓·일정에서 코드로 정확히 읽어 변수에 담을 수 있다. 그러면 "마감 임박 + 담당 공석 → 재배정 알림" 같은 규칙은 코드로 굳혀, 매번 모델에게 "누구에게 뭘 시킬까"를 물을 필요가 없다. 반대로 "이 재배정이 지금 팀 상황에 맞는가" 같은 판단은 메시지의 맥락을 읽어야 하므로 모델의 몫으로 남긴다.

온틀이 지향하는 '반복 업무 경감'의 결이 여기에 있다. 측정 가능하고 반복되는 결정은 검증된 코드로 내려앉히고, 값비싼 모델 추론은 코드가 아직 감당하지 못하는 경계에만 쓴다. 다만 분명히 해둘 것은, 이는 COAP가 보여준 원리를 온틀 설계에 비춰 본 방향이지 지금 그렇게 구현돼 있다는 뜻이 아니다. 자연어 업무의 상태는 로봇 물체 자세만큼 깔끔히 측정되지 않으므로, 현실적 출발점은 '전부 코드'가 아니라 측정 가능한 부분부터 코드로 굳히는 하이브리드다.

실무자를 위한 세 가지 점검

  • 내 과제의 '상태'를 센서·로그 같은 원천에서 코드로 정확히 측정할 수 있는가? 측정이 흔들리면 그 위의 규칙도 함께 흔들린다.
  • 상태 기록에 측정의 오차·출처·시각을 함께 남기는가? 이 메타데이터가 있어야 실패를 거슬러 올라가 어느 변수가 틀렸는지 짚고 고칠 수 있다.
  • 변경을 받아들이는 게이트가 '검증셋 성능 비감소'인가? 대상 과제가 잡음 이상으로 좋아지고 검증셋의 다른 과제엔 저하가 없을 때만 반영해야 개선이 누적된다. 다만 이 게이트는 큰 저하를 걸러낼 뿐 모든 변화를 막지는 못한다는 한계를 함께 기억해야 한다.

결국 실무의 판단 기준은 하나로 모인다. 어떤 상태와 어떤 결정을 코드로 옮길 것인가. 또렷하게 측정되고 되풀이되는 것부터 코드로 내리고, 나머지는 모델에 남기면 된다.

이 방법을 우리 로봇이나 서비스에 그대로 쓸 수 있나요?

전제부터 확인해야 합니다. COAP는 물체 형상·카메라 위치·로봇 모양 같은 값이 미리 공개돼 있다는 조건 위에서 돕니다. 현장 로봇은 이런 형상을 모르는 경우가 많습니다. 그래서 통째로 옮기기보다, 상태를 또렷이 측정할 수 있는 반복 과제부터 코드로 굳히고 나머지는 모델에 맡기는 편이 현실적입니다.

그럼 모델이 아예 필요 없어지는 건가요?

실행(테스트) 시점에는 VLA·VLM 같은 모델이 필요 없습니다. 다만 코드 라이브러리를 만드는 오프라인 개발 단계에서는 Claude Opus 5.5 코딩 에이전트가 코드를 쓰고 디버깅합니다. 또 저자들은 이렇게 만든 코드가 안정적으로 성공 궤적을 뽑아내므로, 반대로 VLA·에이전트 하네스를 학습시킬 데이터를 찍어내는 데에도 쓸 수 있다고 봅니다. "실행 땐 모델 프리"이지, "개발까지 공짜"는 아닙니다.

참고자료