ARC-AGI-3: 아직 아무도 풀지 못한 벤치마크 (KR)
ARC-AGI-3: 아직 아무도 풀지 못한 벤치마크
업데이트 메모 (2026-07-23). 이 글은 6월 24일에 처음 썼고, Milestone #1 결과가 나온 뒤 내용을 크게 고쳤습니다. 이번 개정에서는 Kaggle CLI, ARC Prize 공식 발표, 공개된 상위권 코드, 최신 논문을 서로 대조했습니다. 대회는 아직 진행 중이므로 아래 리더보드 숫자는 영구적인 기록이 아니라 해당 날짜에 확인한 값으로 읽어야 합니다.
업데이트 메모 (2026-08-04). 직접 제출을 반복하고 대회에 동봉된 채점 엔진 소스를 뜯어본 뒤, 채점 수식 두 곳을 정정했습니다. 첫째, 1.15 cap은 비율이 아니라 제곱한 값에 적용됩니다. 둘째, 이전 판에 있던 “human baseline의 5배를 넘기면 0점” 컷오프는 현행 채점기에 존재하지 않습니다. 완료한 레벨은 $(h/a)^2$로 연속 감쇠할 뿐입니다. 그 밖에 8월 4일 기준 리더보드 상위는 1.86 / 1.69 / 1.64로 이동했고, 100위 컷은 1.24에서 1.29로 올라왔습니다. 이 사이에 실제로 겪은 시행착오와 전략 재배치는 후속 글인 2편에 정리했습니다.
대회 링크:
ARC Prize 2026 - ARC-AGI-3
공식 벤치마크 페이지:
ARC Prize 2026 - ARC-AGI-3 Competition
기술 보고서:
ARC-AGI-3: A New Challenge for Frontier Agentic Intelligence

한 문단 요약. ARC-AGI-3는 “reasoning”을 정답으로 출력하는 능력이 아니라, 실제 환경 안에서 행동으로 증명하는 능력을 묻습니다. 에이전트는 설명서 없는 낯선 2D grid 게임에 들어가고, 얼마나 적은 시행착오로 규칙을 배워 이기는지로 평가됩니다. Milestone #1 이후에는 한 가지 사실이 분명해졌습니다. Open-weight LLM을 Kaggle notebook 안에서 직접 실행하는 방식은 허용되며, 실제로 Tufa Labs가 이 접근법으로 우승했습니다. 그런데도 7월 23일 Kaggle 최고 점수는 여전히 1.86%에 불과했습니다. 반면 훨씬 큰 frontier model은 공개 게임에서 두 자릿수, 일부 자가보고는 90%대까지 올라갔습니다. 이제 이 벤치마크는 낯선 세계를 행동으로 배우는 능력뿐 아니라, 인터넷이 차단된 9시간짜리 실행 환경에서 처음 보는 게임까지 일반화하는 능력을 함께 드러내고 있습니다.
왜 이 글을 쓰는가
저는 ARC-AGI-3를 꽤 진지하게 들여다보고 있습니다. 그리고 보통 글을 쓰면서 생각을 정리합니다. 이 글은 대회가 실제로 무엇인지, 점수가 어떻게 계산되는지, 리더보드 숫자를 왜 조심해서 읽어야 하는지, 현재 방법들이 어디에서 막히는지, 그리고 제가 어떤 방향으로 접근할지를 가능한 한 정확하게 정리하려는 시도입니다.
이 글에서 점수보다 먼저 강조하고 싶은 원칙이 있습니다. ARC-AGI-3 점수는 평가 맥락과 함께 적어야 합니다. Kaggle hidden score, ARC Prize의 public/semi-private 평가, public game에서 여러 설정을 시도한 연구 결과는 같은 측정값이 아닙니다. 오래된 scoring rule과 이미 막힌 public-source exploit의 영향도 남아 있습니다. 어떤 game set을 썼는지, compute budget과 retry rule은 무엇이었는지, 언제 측정했는지가 빠지면 숫자만으로는 제대로 비교할 수 없습니다.
이 글의 목표는 여섯 가지입니다.
- ARC-AGI-1, ARC-AGI-2, ARC-AGI-3가 각각 어떤 문제였고, 왜 이런 순서로 발전했는지 설명합니다.
- ARC Prize Foundation과 Kaggle 대회가 어떤 맥락에서 운영되는지 설명합니다.
- ARC-AGI-3의 클리어 기준, 채점 기준, RHAE 수식, human baseline의 의미를 초심자도 이해할 수 있게 풉니다.
- StochasticGoose, Blind Squirrel, FORGE/BFS 계열처럼 이미 시도된 전략들이 무엇을 배웠고 어디서 막혔는지 정리합니다.
- 실제로 참여하려는 사람이 어떤 배경 지식을 공부하고, 어떤 코드부터 작성해야 하는지 작업 순서로 제안합니다.
- toy example, local validation, 실패 진단 예시처럼 손에 잡히는 사례를 넣습니다.
처음 읽는 사람을 위한 안내도
먼저 용어부터 맞추겠습니다. ARC-AGI-3는 이름부터 낯섭니다. 하지만 핵심은 어렵지 않습니다.
| 용어 | 쉽게 말하면 |
|---|---|
| ARC | 색이 칠해진 작은 grid를 사용하는 reasoning benchmark 계열입니다. 자연어 상식 문제라기보다, 보드 위의 규칙을 추론하는 문제에 가깝습니다. |
| AGI | 여기서는 거창한 선언이 아닙니다. “새로운 기술을 얼마나 효율적으로 습득하는가”를 측정하려는 좁은 의미로 쓰입니다. |
| Task / game / environment | 저마다 숨은 규칙을 가진 작은 세계입니다. 에이전트는 grid를 보고 action을 선택합니다. |
| Level | 한 game을 구성하는 단계입니다. 보통 뒤쪽 level로 갈수록 앞에서 배운 mechanic이 조합됩니다. |
| Agent | 제출하는 프로그램입니다. 현재 frame을 보고 다음 action을 고릅니다. |
| Action | 위/아래/왼쪽/오른쪽 이동, interact, 좌표 클릭, undo, reset 같은 환경 입력입니다. |
| World model | “이 action을 하면 무엇이 바뀌는가”에 대한 에이전트 내부의 모델입니다. |
| Generalization | 공개된 25개 게임을 외우는 것이 아니라, 처음 보는 hidden game에서도 잘하는 능력입니다. |
| Human baseline | 같은 game을 처음 본 사람이 몇 action으로 level을 깼는지에 대한 기준값입니다. ARC-AGI-3 점수는 이 기준과 비교됩니다. |
| Scorecard / replay | 에이전트가 어떤 game에서 어떤 action을 했고, 어떤 score를 받았는지 기록한 실행 결과입니다. |
가장 쉬운 비유는 이렇습니다. 설명서 없는 퍼즐 게임을 처음 열었다고 해봅시다. 키를 눌러 보고, 무엇이 움직이는지 보고, 규칙을 추측하고, 목표를 짐작한 뒤, 적은 행동 수로 클리어합니다. ARC-AGI-3는 AI에게 바로 그 일을 시킵니다.
어떤 배경 지식이 필요한가
처음부터 RL 논문을 잔뜩 읽고 시작할 필요는 없습니다. 오히려 게임 frame 하나도 제대로 저장하지 않은 상태에서 deep RL부터 붙잡으면 진행이 더 느려질 가능성이 큽니다. ARC-AGI-3는 연구 난도가 높은 문제이지만, 첫걸음은 꽤 구체적입니다.
시작 전에 있으면 좋은 최소 배경은 이 정도입니다.
| 배경 | 왜 필요한가 | 초심자 기준 |
|---|---|---|
| Python | starter kit가 Python 중심입니다. | 파일 하나를 수정하고, 명령을 실행하고, 에러 메시지를 읽을 수 있으면 됩니다. |
| 배열과 grid | observation이 2D integer grid입니다. | 두 grid를 비교해서 어떤 cell이 바뀌었는지 찾을 수 있으면 됩니다. |
| Search | 에이전트는 여러 action sequence를 직접 시도해야 합니다. | BFS, 깊이 제한 search, visited-state set 정도면 시작할 수 있습니다. |
| Logging | 상호작용형 에이전트를 디버깅할 때는 최종 점수만 봐서는 거의 아무것도 알 수 없습니다. | frame, action, state hash, action을 고른 이유를 저장해야 합니다. |
| 기본 ML 용어 | CNN, value model, world model 같은 말이 자주 나옵니다. | 모델이 무엇을 예측하려는지만 이해해도 충분합니다. |
| Kaggle code competition | 제출 파일은 Kaggle이 실행하는 notebook입니다. | 평가 중 인터넷이 차단되고, 코드가 자체 완결적이어야 한다는 점을 알아야 합니다. |
반대로 첫날부터 필요하지 않은 것도 있습니다.
- 첫날부터 대형 language model이 필요한 것은 아닙니다. 평가 중 hosted API는 호출할 수 없지만, 공개된 model weight를 Kaggle input으로 넣어 local inference를 실행하는 것은 허용됩니다. Milestone #1은 이 경로가 실제로 경쟁력이 있음을 보여 줬습니다.
- 멋진 neural architecture도 바로 필요하지 않습니다. 로그가 부실한 fancy model보다, 관찰 가능한 graph search가 훨씬 낫습니다.
- 공개된 25개 game을 전부 손으로 풀 필요도 없습니다. 몇 개를 직접 해보는 것은 좋지만, 외우는 순간 hidden game에는 도움이 안 됩니다.
- Kaggle forum의 모든 논쟁을 이해할 필요도 없습니다. 공식 docs, starter kit, local game 하나로 시작하면 됩니다.
초심자에게는 이 태도가 가장 중요합니다.
각 game을 처음 보는 작은 기계처럼 다룬다.
에이전트가 처음 해야 할 일은 영리한 척하는 것이 아닙니다. 실험하고, 무엇이 바뀌었는지 기록하고, 이미 쓸모없다고 확인한 action은 반복하지 않고, 다음 실험을 조금 더 낫게 만드는 것입니다.
이 벤치마크가 교육적으로 좋은 이유도 여기에 있습니다. 디버깅을 잘할 때 거치는 과정을 그대로 요구하기 때문입니다.
1
2
3
4
5
주의 깊게 관찰한다
작은 개입을 한다
결과를 기록한다
가설을 수정한다
다음 개입을 고른다
이 루프를 만들 수 있다면, hand-written heuristic만으로도 이미 ARC-AGI-3 에이전트의 뼈대를 만든 셈입니다.
1. 계보: 정적인 puzzle에서 행동하는 game으로
ARC-AGI, 즉 Abstraction and Reasoning Corpus는 François Chollet이 제안한 intelligence 측정 방식에서 출발합니다. 핵심은 이미 가진 skill의 크기가 아니라 skill-acquisition efficiency입니다. 말하자면 “처음 보는 문제에서 얼마나 적은 정보와 시도로 새 기술을 배워내는가”입니다.
이 대회의 뿌리는 2019년 Chollet의 논문 On the Measure of Intelligence입니다. 여기서 중요한 관점은 “AI가 이미 훈련된 지식을 얼마나 많이 저장했는가”가 아닙니다. 오히려 다음 질문에 가깝습니다.
낯선 문제를 만났을 때, 시스템은 얼마나 적은 경험으로 새 규칙을 배워 쓸 수 있는가?
이 관점에서는 benchmark가 단순 지식 시험이면 안 됩니다. 인터넷에 있는 사실을 많이 외운 모델이 이기면, 그것은 general intelligence라기보다 memorization일 수 있습니다. 그래서 ARC 계열은 자연어 trivia나 상식 문제 대신, 작은 grid 안에서 새 규칙을 추론하게 만듭니다. 사람에게는 비교적 자연스럽지만, 훈련 분포 바깥의 문제를 다루지 못하는 모델에게는 어렵습니다.
ARC Prize Foundation은 이 benchmark를 open competition 형태로 운영하면서 두 가지를 목표로 삼습니다.
- 측정: frontier model이 정말 새로운 문제에 적응하는지 확인합니다.
- 유도: 단순 leaderboard 경쟁이 아니라 open-source solution과 paper를 통해 연구 방향을 공개적으로 축적합니다.
Kaggle은 여기서 실행 플랫폼 역할을 합니다. 참가자는 코드를 제출하고, Kaggle은 인터넷이 차단된 환경에서 에이전트를 실행합니다. 즉, 이 대회는 “좋은 prompt를 만들어 hosted LLM을 잘 부르는 능력”이 아니라, 스스로 실행되는 에이전트를 만드는 능력을 봅니다.
- ARC-AGI-1 (2019) — 정적(static)입니다. 몇 개의 input→output grid 예시를 보고 변환 규칙을 추론한 뒤, 빠진 output grid를 만듭니다.
- ARC-AGI-2 (2025) — 여전히 정적이지만 더 어렵고 조합적입니다. 여러 규칙이 함께 작동하고, 문맥에 따라 규칙이 달라집니다.
- ARC-AGI-3 (2026) — interactive입니다. 이제 output grid 하나를 맞히는 문제가 아닙니다. 에이전트가 직접 환경을 탐색하고, 규칙을 배우고, 목표를 추론하고, action sequence를 계획해야 합니다.
세 버전의 차이를 숫자까지 포함해서 보면 이렇습니다. 단, 아래 점수들은 서로 다른 평가 맥락에서 나온 값이라 정밀한 사과 대 사과 비교는 아닙니다. 여기서 봐야 할 것은 방향성입니다.
| 항목 | ARC-AGI-1 (2019) | ARC-AGI-2 (2025) | ARC-AGI-3 (2026) |
|---|---|---|---|
| Format | static grid puzzle | 더 어렵고 조합적인 static grid puzzle | interactive game environment |
| Instructions | input-output demo pair | input-output demo pair | 자연어 설명 없이 interaction으로 규칙을 발견해야 함 |
| Best reported AI score | o3가 semi-private set에서 public compute 기준 75.7%, high-compute 기준 87.5%를 기록했고, public eval report에서는 90%를 넘었습니다. | ARC Prize 2025 Kaggle private top score 24.03% | 서로 직접 비교할 수 있는 숫자는 아닙니다. 3-game preview 1위는 12.58%, full competition의 Milestone #1 우승은 1.21%, 공식 Sol Max 평가는 public 13.33% / semi-private 7.78%였습니다. |
| Human reference | 원래 private task에서 human tester가 각각 97-98%를 풀었고, 둘을 합치면 100%를 풀었습니다. 요약 자료에서는 예전 rough benchmark로 ~85%가 자주 쓰입니다. | public eval sample의 average human performance는 66%였습니다. 선별된 evaluation task들은 human-solvable 조건을 통과했습니다. | 포함된 environment는 사람이 100% 풀 수 있도록 calibration되었습니다. AI 점수는 human action baseline 대비 효율로 계산됩니다. |
| Scoring | task accuracy, 대체로 solved/not solved | accuracy에 cost-per-task reporting이 함께 중요해짐 | Relative Human Action Efficiency. 사람 대비 action efficiency가 핵심 |
| Dataset scale | 400 public train, 400 public eval, 100 semi-private, 100 private | 1,000 public train, 120 public eval, 120 semi-private, 120 private | 25개 public demo environment, 55개 semi-private, 55개 fully private. 각 environment 안에 여러 level이 있음 |
ARC-AGI-3의 점수는 평가 맥락을 함께 읽어야 합니다. 12.58%는 preview competition의 hidden game 3개, 1.21%는 Kaggle의 offline hidden evaluation, 13.33% / 7.78%는 ARC Prize가 별도로 수행한 public / semi-private 평가에서 나온 값입니다. 서로 연관된 능력을 재지만 game set, compute budget, submission rule이 다르므로 같은 리더보드의 숫자처럼 직접 비교해서는 안 됩니다.
전환의 핵심은 이것입니다.
지능을 “고정된 데이터셋에서 패턴을 맞히는 능력”이 아니라, “낯선 환경에서 적응적으로 행동하는 능력”으로 본다.
이 전환 때문에 현재 시스템들이 급격하게 무너집니다.
작은 toy example로 보면 차이가 더 분명합니다.
정적인 ARC 문제에서는 이런 식입니다.
1
2
input grid: 왼쪽에 빨간 사각형 하나
output grid: 같은 빨간 사각형이 오른쪽으로 이동
해야 할 일은 변환 규칙을 추론하고 output을 쓰는 것입니다. 세계 안에서 행동하지 않습니다. 답을 제출할 뿐입니다.
ARC-AGI-3에서는 비슷한 난이도의 아이디어도 이렇게 바뀝니다.
1
2
3
4
5
frame 0: 빨간 사각형, 파란 문, 초록 버튼
action 1: 오른쪽으로 이동
frame 1: 빨간 사각형이 오른쪽으로 이동
action 2: 버튼을 누름
frame 2: 파란 문이 사라짐
이제 에이전트는 직접 상호작용하면서 배워야 합니다. 이동이 가능하다는 것, 버튼이 어떤 효과를 낸다는 것, 문이 무언가를 막고 있었다는 것, 어쩌면 최종 목표가 문 뒤에 있다는 것까지 추론해야 합니다. “output grid를 완성하라”보다 훨씬 더 까다로운 문제 설정입니다.
2. 실제로 무엇을 측정하는가
공식 설명에서 ARC-AGI-3는 agentic intelligence를 네 가지 능력으로 나눕니다.
- Exploration — 정보가 그냥 주어지지 않습니다. 행동해서 알아내야 합니다.
- Modeling — 관측한 frame을 바탕으로 world model을 만들어야 합니다. 즉, 다음 상태를 예측할 수 있어야 합니다.
- Goal-setting — 목표가 자연어로 주어지지 않습니다. 무엇을 향해 가야 하는지 스스로 추론해야 합니다.
- Planning & execution — 추론한 목표까지 가는 action sequence를 계획하고, 중간 피드백에 따라 수정해야 합니다.
이 네 가지는 추상적인 슬로건이 아닙니다. 각각 매우 구체적인 실패 모드와 연결됩니다.
| 능력 | 머릿속에 그릴 모습 | 없으면 생기는 문제 |
|---|---|---|
| Exploration | action을 눌러 보며 어떤 object가 반응하는지 찾습니다. | 의미 없는 행동을 반복하거나 핵심 mechanic을 발견하지 못합니다. |
| Modeling | “버튼을 누르면 문이 열린다” 같은 cause-effect를 기억합니다. | action이 어떤 결과를 낼지 예측하지 못합니다. |
| Goal-setting | board가 암시하는 winning condition을 추론합니다. | mechanic 일부를 이해해도 어디로 가야 할지 모릅니다. |
| Planning & execution | 목표까지 짧은 action sequence를 고릅니다. | 사실을 알아도 solution path로 바꾸지 못합니다. |
많은 AI benchmark는 사실상 마지막 줄만 묻습니다. 답을 맞히는가? ARC-AGI-3는 그 앞의 과정까지 함께 묻습니다.
1
행동한다 → 관측한다 → 모델을 수정한다 → 다시 행동한다
그리고 점수는 이 순환을 얼마나 효율적으로 수행하는지로 계산됩니다.
3. 게임은 어떻게 생겼는가
환경은 일부러 단순하게 만들어져 있습니다. 어려워야 하는 부분은 interface 조작이 아니라 reasoning이기 때문입니다.
- Observation: 최대 64×64 grid입니다. 각 cell은 0–15 사이의 integer color/state 값을 가집니다. 좌표 원점은 왼쪽 위
(0,0)입니다. - Actions:
RESET과 표준화된ACTION1–ACTION7interface가 있습니다.RESET— level을 다시 시작합니다.ACTION1–ACTION4— 보통 위/아래/왼쪽/오른쪽 같은 단순 action입니다.ACTION5— interact, select, rotate, attach/detach, execute 등 game마다 의미가 달라질 수 있습니다.ACTION6—(x, y)좌표 클릭입니다. 좌표는 0–63 범위입니다.ACTION7— undo입니다.
- Scale: technical report 기준으로 25개 public-demo environment와 110개 hidden environment가 있습니다. hidden environment 110개는 55개 semi-private와 55개 fully private으로 나뉩니다.
프로그래밍에 익숙하지 않은 독자라면 grid를 작은 보드게임처럼 생각하면 됩니다.

1
2
3
4
5
0 0 0 0 0
0 2 0 3 0
0 0 1 0 0
0 4 0 0 0
0 0 0 0 0
여기서 숫자가 크다고 더 많은 양을 뜻하는 것은 아닙니다. 색이나 object type에 가깝습니다. 하지만 에이전트는 1이 player인지, 3이 door인지, 4가 button인지 알지 못합니다. action을 해보고 frame이 어떻게 바뀌는지를 보면서 의미를 배워야 합니다.
한 턴의 흐름은 이렇습니다.
| 단계 | 일어나는 일 |
|---|---|
| 1 | 환경이 가장 최근 frame을 보냅니다. grid, metadata, available actions, state가 포함됩니다. |
| 2 | 에이전트가 memory를 갱신합니다. 이전 frame과 무엇이 달라졌는지 확인합니다. |
| 3 | 에이전트가 action 하나를 고릅니다. 예를 들어 ACTION1 또는 좌표가 붙은 ACTION6입니다. |
| 4 | 환경이 action을 적용하고 새 frame을 돌려줍니다. |
| 5 | level을 클리어하거나, game over가 되거나, action budget이 끝날 때까지 반복합니다. |
어려운 점은 action 이름이 game마다 구체적으로 설명되지 않는다는 것입니다. ACTION5는 어떤 game에서는 “줍기”일 수 있고, 다른 game에서는 “회전”일 수 있습니다. ACTION6은 좌표 클릭이지만, 어느 좌표가 의미 있는지는 알려주지 않습니다. 그래서 처음 해야 할 일은 puzzle solution을 찾는 것이 아니라 control discovery, 즉 조작법을 알아내는 일입니다.
프로그래머가 실제로 받는 것은 무엇인가
여기서부터 ARC-AGI-3는 일반적인 ML 문제와 완전히 달라집니다. 보통의 prediction 문제라면 이렇게 생각할 수 있습니다.
1
answer = model(question)
하지만 ARC-AGI-3에서는 이런 식이 아닙니다. 에이전트는 환경을 반복해서 호출하고, 돌아온 bundle을 해석하고, action 하나를 고릅니다. 그리고 그 action의 비용을 바로 치릅니다. API 형태로 단순화하면 대략 이런 루프입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# game을 시작하거나 reset한다.
bundle = post("/api/cmd/RESET", {
"game_id": game_id,
"card_id": card_id,
})
guid = bundle["guid"]
while bundle["state"] == "NOT_FINISHED":
action = choose_action(bundle, memory)
payload = {
"game_id": game_id,
"card_id": card_id,
"guid": guid,
}
if action["id"] == 6:
payload["x"] = action["x"]
payload["y"] = action["y"]
next_bundle = post(f"/api/cmd/{action['name']}", payload)
update_memory(memory, bundle, action, next_bundle)
bundle = next_bundle
돌아오는 값도 교과서적인 (observation, reward, done) 한 줄이 아닙니다. 실제로는 이런 bundle에 가깝습니다.
1
2
3
4
5
6
7
8
9
10
11
{
"game_id": "ls20-016295f7601e",
"guid": "2fa5332c-2e55-4825-b5c5-df960d504470",
"frame": [[0, 0, 0, ...], [0, 3, 3, ...], ...],
"state": "NOT_FINISHED",
"levels_completed": 0,
"win_levels": 254,
"action_input": {"id": 6, "data": {"x": 12, "y": 34}},
"available_actions": [1, 2, 3, 4, 6],
"score": 0.0, # API/toolkit response에 포함되는 경우가 많다
}
이 bundle에서 유용한 state를 뽑아내는 것도 참가자가 해야 할 일입니다.
| Field | 확인할 수 있는 것 | 확인할 수 없는 것 |
|---|---|---|
frame | 눈에 보이는 grid | object의 의미, 목표, 물리 규칙, 클릭할 만한 좌표 |
available_actions | 지금 쓸 수 있는 action id | ACTION6에서 유용한 (x, y) 좌표 |
state | 진행 중인지, 이겼는지, 끝났는지 | 얼마나 이기기에 가까운지 |
levels_completed | 완료한 level 수 | 어떤 mechanic을 배웠는지, 왜 진행됐는지 |
win_levels | 해당 environment의 전체 level 수 | 다음 level로 가는 방법 |
action_input | 방금 반환된 frame을 만든 action | 그 action이 전략적으로 좋았는지 |
| local action counter | 지금까지 몇 action을 썼는지 | 보통 remaining_turns_to_good_score 같은 친절한 값은 없습니다. 직접 세거나 framework wrapper에서 읽어야 합니다. |
이 마지막 줄이 초반에 은근히 막막합니다. 환경은 state와 progress 값은 주지만, “좋은 점수를 받으려면 앞으로 몇 턴 남았습니다” 같은 친절한 신호는 주지 않습니다. action budget을 관리하려면 에이전트가 직접 action 호출 횟수를 세고, level이 바뀐 시점과 reset 시점을 기록하고, 완료한 level당 action 수를 따로 계산해야 합니다.
처음 디버깅할 때의 느낌은 대략 이렇습니다. 에이전트가 ACTION6을 (12, 34)에 보냈습니다. 그런데 다음 bundle을 보니 frame도 그대로이고, levels_completed도 그대로이고, state도 여전히 NOT_FINISHED입니다. 그럼 무엇을 배운 걸까요?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
def update_memory(memory, prev, action, nxt):
prev_grid = prev["frame"]
next_grid = nxt["frame"]
changed = prev_grid != next_grid
progress = nxt.get("levels_completed", 0) - prev.get("levels_completed", 0)
state_changed = nxt["state"] != prev["state"]
key = (hash_grid(prev_grid), canonical_action(action))
memory["outcome"][key] = {
"changed": changed,
"progress": progress,
"state_changed": state_changed,
"next_hash": hash_grid(next_grid),
}
if not changed and progress == 0 and not state_changed:
memory["no_ops"].add(key)
이 작은 함수도 이미 일종의 learning입니다. 거창한 game theory를 배운 것은 아니지만, “이 state에서 이 action은 거의 쓸모없었다”는 사실을 배웠습니다. 다음 호출에서는 그 정보를 써야 합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
def choose_action(bundle, memory):
grid = bundle["frame"]
legal = bundle["available_actions"]
state_hash = hash_grid(grid)
candidates = []
for action_id in legal:
if action_id == 6:
for x, y in candidate_clicks(grid):
candidates.append({"id": 6, "name": "ACTION6", "x": x, "y": y})
else:
candidates.append({"id": action_id, "name": f"ACTION{action_id}"})
candidates = [
a for a in candidates
if (state_hash, canonical_action(a)) not in memory["no_ops"]
]
return rank_candidates(candidates, bundle, memory)[0]
작은 model을 학습시킨다면 training data도 이런 transition에서 나옵니다. 예를 들어 StochasticGoose 계열의 action learning은 처음부터 최종 goal을 예측하려 하지 않습니다. 더 작은 문제부터 잡습니다.
1
2
3
4
5
6
training_example = {
"grid_before": prev["frame"],
"action": encode_action(action),
"label_changed": int(prev["frame"] != nxt["frame"]),
"label_progress": int(nxt["levels_completed"] > prev["levels_completed"]),
}
CNN은 P(frame changes | grid, action) 또는 P(progress | grid, action) 같은 값을 배울 수 있습니다. 이건 꽤 유용합니다. 에이전트가 명백한 no-op에 action budget을 덜 낭비하게 만들기 때문입니다. 하지만 이것만으로 game을 푸는 것은 아닙니다. 탐색 낭비를 조금 줄인 것에 가깝습니다.
왜 그냥 torch나 LLM에 넣으면 잘 안 되는가
처음에는 이런 생각을 하기 쉽습니다.
1
2
policy = CNN()
action = policy(torch.tensor(frame))
또는 이런 식입니다.
1
2
prompt = f"이 grid에서 다음에 뭘 해야 해?\n{frame}"
action = llm(prompt)
이 발상 자체가 틀린 것은 아닙니다. 하지만 실제로 해보면 아주 구체적인 벽에 부딪힙니다.
| 단순한 생각 | 실제로 막히는 이유 |
|---|---|
| 25개 public game에서 CNN policy를 학습한다 | hidden game은 다릅니다. public mechanic을 외우면 “여기서 먹힌 행동”은 배우지만, “다음 낯선 game에서 무엇을 실험해야 하는지”는 잘 못 배웁니다. |
| RL을 처음부터 돌린다 | reward가 sparse하고 action이 비쌉니다. 실패한 탐색 action도 RHAE를 깎고, Kaggle runtime은 유한합니다. hidden game마다 수백만 step을 쓰는 blank-slate RL은 현실적이지 않습니다. |
| next frame prediction을 학습한다 | transition data가 충분해야 의미가 있습니다. 초반에는 어떤 action이 transition을 만드는지도 모릅니다. |
| GPT나 Claude 같은 hosted API를 호출한다 | Kaggle evaluation에서는 인터넷이 차단되므로 요청 자체가 provider에 도달하지 않습니다. |
| Local LLM에게 다음 action만 묻는다 | 합법적이고 실제 성과도 나왔지만, prompt 하나만으로는 부족합니다. compact observation, persistent memory, tool, legal-action 검사, 그리고 가설을 실제 transition으로 검증하는 절차가 필요합니다. |
| image classification처럼 푼다 | label이 “cat/dog”처럼 고정되어 있지 않습니다. 목표는 unknown rule 아래에서 action sequence를 찾는 것입니다. |
| brute force로 action sequence를 많이 시도한다 | scorer는 모든 action을 봅니다. 사람이 20 action으로 깬 level을 500 action으로 겨우 깨면, 점수는 거의 남지 않을 수 있습니다. |
그러니 실전적인 결론은 “neural net을 쓰지 말자”도 아니고, “LLM은 쓸모없다”도 아닙니다. 핵심은 model에게 지금 가진 데이터로 학습 가능한 작은 역할을 맡겨야 한다는 것입니다.
| Model의 역할 | Input | Target | 왜 가능한가 |
|---|---|---|---|
| Action-change predictor | (frame, action) | frame이 바뀌었는가 | 매 step 후 label을 바로 얻을 수 있습니다. |
| Progress predictor | (frame, action) | levels_completed나 score가 좋아졌는가 | sparse하지만 직접 측정 가능합니다. |
| State embedding | frame | 비슷한 state를 가깝게 표현 | state de-duplication과 loop detection에 도움이 됩니다. |
| Transition model | (frame, action) | next frame 또는 changed cells | transition이 충분히 쌓이면 short-horizon planning에 쓸 수 있습니다. |
| Goal hypothesis scorer | frame history | 어떤 object/state가 progress와 관련 있어 보이는가 | heuristic으로 시작하고, action outcome으로 검증할 수 있습니다. |
그래서 처음 부딪히는 진짜 질문은 “어떤 transformer를 쓸까?”가 아닙니다. 훨씬 더 기본적입니다.
1
2
3
4
5
6
나는 정확히 무엇을 관측했나?
무슨 action을 보냈나?
무엇이 바뀌었나?
progress가 바뀌었나?
이 transition을 전에 본 적이 있나?
이번 관측이 다음 call을 어떻게 바꿔야 하나?
ARC-AGI-3가 강제로 만들게 하는 것은 바로 이 작은 loop입니다. 너무 평범해 보이지만, 이 loop가 없으면 비싼 model도 배울 자료가 없습니다.
클리어 기준: 무엇을 하면 “깼다”고 보는가
ARC-AGI-3에서 에이전트는 각 game의 level을 순서대로 진행합니다. 환경은 내부적으로 대략 세 가지 상태를 가집니다.
| State | 의미 |
|---|---|
NOT_FINISHED | 아직 level이 진행 중입니다. 에이전트가 다음 action을 골라야 합니다. |
WIN | 현재 level의 objective를 만족했습니다. 이 level은 완료로 기록됩니다. |
GAME_OVER | action budget이 끝났거나, game이 실패 상태에 들어갔습니다. 보통 RESET만 의미 있는 action입니다. |
초심자가 헷갈리기 쉬운 지점은 이것입니다. ARC-AGI-3의 objective는 자연어로 주어지지 않습니다. 환경은 “초록 버튼을 눌러 파란 문을 열고 빨간 block을 목표 지점에 놓으세요”라고 말해주지 않습니다. 에이전트는 frame 변화와 score/state 변화만 보고 어떤 조건이 WIN으로 이어지는지 추론해야 합니다.
따라서 “클리어”에는 두 층이 있습니다.
- 환경상의 클리어: game state가
WIN이 됩니다. - 점수상 의미 있는 클리어: human baseline에 비해 너무 많은 action을 쓰지 않고
WIN에 도달합니다.
두 번째가 중요합니다. brute-force로 500번 헤매다가 WIN에 도달했다면, 사람 기준으로는 “깼다”고 말할 수 있어도 ARC-AGI-3 점수에서는 거의 의미가 없을 수 있습니다. 이 대회는 “언젠가 맞혔는가”가 아니라 “처음 보는 규칙을 얼마나 효율적으로 습득했는가”를 묻기 때문입니다.
Public과 private split
이 대회에서 반드시 이해해야 할 것은 public/private split입니다.
- 25 public games — 소스 코드를 볼 수 있고, 훈련·디버깅에 쓸 수 있습니다.
- 110 hidden games — 참가자도 에이전트도 볼 수 없습니다. 이 중 55개가 public leaderboard 쪽, 55개가 최종 private leaderboard 쪽입니다.
즉, Kaggle에서 “public leaderboard”라고 부르는 점수도 참가자가 미리 본 public game에서 계산되는 것이 아닙니다. leaderboard는 여전히 hidden game에서 계산됩니다. 그래서 public game level을 꽤 많이 풀었는데도 competition score가 0.00일 수 있습니다.
| 구분 | 개수 | 참가자가 볼 수 있나 | 역할 |
|---|---|---|---|
| Public demo games | 25 | 예 | 소스가 공개되어 local 개발, 디버깅, 기본 실험에 씁니다. |
| Semi-private hidden games | 55 | 아니오 | 대회 진행 중 public leaderboard와 scorecard reporting에 쓰입니다. |
| Fully private hidden games | 55 | 아니오 | competition 종료 후 최종 순위를 결정하는 holdout입니다. |
이 구조 때문에 public game에서 잘 동작하는 에이전트와 leaderboard에서 점수가 나는 에이전트가 전혀 다를 수 있습니다. public game은 “연습장”에 가깝고, leaderboard는 “처음 보는 환경에서도 같은 원리를 적용할 수 있는가”를 묻는 장치입니다.
starter kit로 실제로 하는 일
초심자에게 가장 현실적인 출발점은 ARC-AGI-3 Kaggle Starter입니다. 공식 docs가 제안하는 흐름은 꽤 분명합니다. 로컬에서 Python 파일 하나를 수정하고, 실제 game environment에서 실행해 보고, 준비가 되면 Kaggle notebook으로 제출합니다.
대략 이런 순서입니다.
1
2
3
4
5
6
git clone https://github.com/arcprize/ARC-AGI-3-Kaggle-Starter.git
cd ARC-AGI-3-Kaggle-Starter
make setup
make play-local
make submit
make status
초심자가 집중할 파일은 보통 이것입니다.
1
agent/my_agent.py
여기에 에이전트의 행동 선택 규칙을 구현합니다. 나머지는 game을 로드하고, loop를 돌리고, notebook을 패키징하고, Kaggle에 제출하기 위한 기반 코드입니다. 이 구분이 중요합니다. 제출 준비 코드와 에이전트의 핵심 로직을 혼동하면 초반 시간을 많이 쓰게 됩니다.
처음에는 작업 모드를 세 가지로 나눠서 생각하는 것이 좋습니다.
| Mode | 용도 | 기억할 점 |
|---|---|---|
| Local offline | public game에서 빠르게 실험합니다. | 개발용으로 가장 좋습니다. online scorecard는 없지만 rate limit도 없습니다. |
| Online API / scorecard | 공유 가능한 scorecard와 replay를 남깁니다. | 분석과 공유에 좋지만 느리고 rate limit이 있습니다. |
| Kaggle submission | 실제 leaderboard scoring입니다. | 제출 기회가 제한적입니다. 평소 디버깅용으로 쓰면 안 됩니다. |
공식 docs도 local/offline 실행을 개발용으로 권장합니다. Kaggle submission을 쓰기 전에 local harness가 최소한 다음 질문에 답할 수 있어야 합니다.
- 에이전트가 어떤 game을 시도했는가?
- 어떤 level을 완료했는가?
- 각 level에서 action을 몇 개 썼는가?
- frame을 실제로 바꾼 action은 얼마나 되는가?
- 같은 state를 얼마나 반복했는가?
- click을 했다면 어디를 클릭했고, 왜 그 좌표를 골랐는가?
- 개발용 public game과 holdout public game에서 행동이 어떻게 달라졌는가?
이 질문들에 답하지 못하면 leaderboard 점수만으로는 거의 배울 수 없습니다. 실패했다는 사실은 알려주지만, 왜 실패했는지는 알려주지 않기 때문입니다.
에이전트가 기억해야 하는 것
무작위 에이전트보다 한 단계 나아가려면 가장 먼저 필요한 것은 neural network가 아니라 memory입니다. ARC-AGI-3는 의미 없는 action 반복에 매우 불리한 점수를 줍니다. 그래서 초반 에이전트도 최소한 다음을 기록해야 합니다.
| 기억할 것 | 예시 | 왜 도움이 되는가 |
|---|---|---|
| State hash | grid와 주요 metadata의 hash | 같은 frame을 목적 없이 다시 방문하는 것을 막습니다. |
| Action outcome | (state_hash, action) -> changed / no-op / error / win | 이미 아무 변화가 없던 action을 반복하지 않습니다. |
| Changed cells | action 뒤 값이 바뀐 좌표들 | control object와 반응하는 object를 찾는 단서가 됩니다. |
| Available actions | frame metadata가 알려준 action set | sampling할 action 공간을 줄입니다. |
| Level identity | 현재 game과 level 정보 | level이 바뀌면 이전 가정을 초기화할 수 있습니다. |
| Short trajectory | 최근 N개의 state/action | frame이 조금 바뀌어도 loop를 감지할 수 있습니다. |
가장 단순한 no-op detector는 이전 grid와 다음 grid를 비교하는 것입니다.
1
2
def grid_changed(prev_grid, next_grid):
return prev_grid != next_grid
실제 코드에서는 array comparison을 제대로 써야 하고, metadata를 어디까지 포함할지도 신중히 정해야 합니다. 하지만 아이디어는 단순합니다. 이 state에서 ACTION1을 했는데 같은 state가 나왔다면, 같은 state에서 ACTION1을 계속 고르지 않도록 막는 것입니다.
이건 사소해 보이지만 무작위 에이전트가 action budget을 날리는 가장 큰 이유 중 하나를 줄여 줍니다. random exploration은 “무언가를 배웠다”와 “벽에 또 부딪혔다”를 구분하지 못합니다.
4. Scoring: RHAE
ARC-AGI-3의 점수는 Relative Human Action Efficiency, 줄여서 RHAE입니다. 한 level $\ell$에 대한 기본 score는 다음과 같습니다.
\[s_\ell \;=\; \min\!\left(\left(\frac{h_\ell}{a_\ell}\right)^{2},\; 1.15\right)\]여기서 $h_\ell$은 human baseline action count이고, $a_\ell$은 에이전트가 그 level을 클리어하는 데 쓴 action 수입니다.
human baseline은 대충 정한 숫자가 아닙니다. 공식 scoring methodology는 처음 보는 human player들의 action count를 기준으로 삼습니다. 평균이 아니라 upper median 계열의 기준을 쓰는 이유는, 한 명의 운 좋은 speedrun이나 한 명의 극단적으로 느린 run에 benchmark가 흔들리지 않게 하려는 것입니다. 즉, 이 기준은 “이론상 최단 경로”가 아니라 처음 본 사람이 능숙하게 풀었을 때의 현실적인 효율에 가깝습니다.
중요한 설계 선택이 세 가지 있습니다.
- 제곱합니다. 에이전트가 사람보다 2배 느리면 ratio는 0.5지만, score는 $0.5^2 = 0.25$입니다. 절반이 아니라 25%만 인정됩니다.
- 1.15 cap이 있습니다. cap은 비율이 아니라 제곱한 값에 적용됩니다. 사람이 10 action에 푼 level을 에이전트가 2 action에 exploit처럼 풀어도, 그 level의 점수는 1.15에서 잘립니다.
- 컷오프는 없습니다. 이 글의 이전 판에는 “$5h$를 넘기면 0점”이라는 컷오프 규칙이 있었는데, 대회에 동봉된 채점 엔진(v0.9.8)을 직접 확인해 보니 그런 규칙은 없습니다. 완료하지 못한 level이 0점일 뿐, 완료한 level은 아무리 느려도 $(h/a)^2$로 연속 감쇠합니다. $5h$면 4%, $10h$면 1%입니다.
이 설계는 꽤 의도적입니다.
| 설계 | 왜 필요한가 |
|---|---|
| Completion을 봅니다. | level을 실제로 끝내지 못한 에이전트가 높은 점수를 받으면 안 됩니다. |
| Efficiency를 봅니다. | random search로 언젠가 맞히는 것은 인간 수준의 skill acquisition이 아닙니다. |
| 제곱합니다. | 사람보다 조금 느린 것과 10배 느린 것을 강하게 구분합니다. |
| 1.15 cap을 둡니다. | 한 level에서 exploit성 초고속 solve가 전체 평균을 왜곡하지 못하게 합니다. |
| 뒤 level에 더 큰 weight를 둡니다. | 앞 level은 tutorial에 가깝고, 뒤 level은 mechanic 조합과 transfer를 묻기 때문입니다. |
game score는 level index로 가중한 평균입니다. 뒤 level일수록 더 중요하게 계산됩니다. 한 game에 $n$개 level이 있고, 에이전트가 앞에서부터 $k$개 level을 순서대로 클리어했다면:
\[S_g \;=\; \min\!\left( \frac{\sum_{\ell=1}^{k} \ell}{\sum_{\ell=1}^{n} \ell}, \frac{\sum_{\ell=1}^{n} \ell\,s_{g,\ell}}{\sum_{\ell=1}^{n} \ell} \right), \qquad S \;=\; \frac{1}{G}\sum_{g=1}^{G} S_g .\]첫 번째 항은 environment cap입니다. 앞 level 몇 개를 아주 빠르게 풀었다고 해도, 뒤 level을 못 푼 에이전트가 높은 game score를 받지 못하게 막는 장치입니다.
Python으로 쓰면 대략 이런 모양입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
def rhae_score(games):
"""ARC-AGI-3 score를 fraction으로 반환한다. percent는 여기에 100을 곱한다."""
game_scores = []
for levels in games:
weighted = 0.0
completed_weight = 0
total_weight = sum(range(1, len(levels) + 1))
for i, level in enumerate(levels, start=1):
human_actions, agent_actions, solved = level
if solved and agent_actions > 0:
level_score = min((human_actions / agent_actions) ** 2, 1.15)
weighted += i * level_score
completed_weight += i
env_cap = completed_weight / total_weight
env_score = weighted / total_weight
game_scores.append(min(env_cap, env_score))
return sum(game_scores) / len(game_scores)
계산 흐름을 말로 풀면 이렇습니다.
| 단계 | 무엇을 계산하나 | 왜 중요한가 |
|---|---|---|
| Level score | 사람이 쓴 action 수 h와 에이전트가 쓴 action 수 a를 비교해 min((h / a)^2, 1.15)를 계산합니다. 완료하지 못한 level은 0점입니다. | “깼다”만으로는 부족하고, 사람에 비해 얼마나 효율적으로 깼는지를 반영합니다. |
| Game score | 뒤쪽 level일수록 더 큰 weight를 주어 level score를 평균냅니다. | 쉬운 앞부분만 풀고 멈추는 에이전트가 과대평가되지 않도록 합니다. |
| Completion cap | sequential하게 완료한 level까지만 점수 상한을 인정합니다. | 초반을 건너뛰고 운 좋게 뒤쪽 일부만 맞히는 shortcut을 막습니다. |
| Benchmark score | hidden game들의 game score를 평균내고 0-100% scale로 보고합니다. | 특정 environment 하나에 overfit한 에이전트보다 넓게 일반화하는 에이전트를 높게 봅니다. |
숫자로 보는 예시
human baseline이 10 action인 level이 있다고 해봅시다.
| Agent action 수 | Ratio $h/a$ | 제곱 후 score | 의미 |
|---|---|---|---|
| 8 | 1.25 | 1.15 (cap) | 사람보다 빨라도 제곱값은 1.15에서 잘립니다. |
| 10 | 1.00 | 1.00 | 사람과 같은 효율입니다. |
| 20 | 0.50 | 0.25 | 2배 느리면 25%만 인정됩니다. |
| 50 | 0.20 | 0.04 | 5배 느리면 4%만 인정됩니다. |
| 100 | 0.10 | 0.01 | 컷오프는 없지만, 여기까지 오면 사실상 0에 가깝습니다. |
여기서 직관이 한 번 꺾입니다.
풀었다고 충분하지 않습니다.
랜덤 탐색으로 언젠가 클리어하는 에이전트는 level을 “완료”했을 수 있습니다. 하지만 사람이 10 action에 푼 것을 50 action에 풀면 4%만 인정됩니다. 이 대회가 묻는 것은 “결국 이겼나”가 아니라 “처음 본 문제를 얼마나 효율적으로 배웠나”입니다.
game cap도 중요합니다. 5-level game에서 에이전트가 level 1과 2만 완벽하게 풀었다고 해봅시다. 그러면 최대 game score는:
\[\frac{1 + 2}{1 + 2 + 3 + 4 + 5} \;=\; \frac{3}{15} \;=\; 20\%.\]뒤 level을 못 풀면 앞 level을 아무리 빨리 풀어도 game 전체 점수는 높아지지 않습니다. 뒤 level이야말로 mechanic을 정말 이해했는지를 묻는 곳이기 때문입니다.
RHAE가 개발 방식을 어떻게 바꾸는가
RHAE 때문에 ARC-AGI-3는 일반적인 win/loss game benchmark와 다르게 접근해야 합니다. local run에서 “level completed”가 찍혔다고 바로 좋은 에이전트가 아닙니다. 얼마나 비싼 completion이었는지를 같이 봐야 합니다.
human baseline이 20 action인 level을 두 에이전트가 모두 풀었다고 해봅시다.
| Agent | 사용한 action 수 | Level score | 해석 |
|---|---|---|---|
| A | 24 | $(20/24)^2 = 0.694$ | 조금 느리지만 의미 있는 클리어입니다. |
| B | 90 | $(20/90)^2 = 0.049$ | 풀긴 했지만 action budget을 거의 태운 결과입니다. |
completion count만 보면 A와 B는 같아 보입니다. RHAE에서는 전혀 다릅니다. 그래서 local report에는 최소한 다음이 들어가야 합니다.
- completion count
- actions per completed level
- estimated RHAE per completed level
- no-op action rate
- repeated-state rate
- first state-changing action step
- first score-changing action step
- late-level reach rate
마지막 metric도 중요합니다. game score는 뒤 level에 더 큰 weight를 둡니다. level 1을 반복해서 잘하는 것과 level 3, 4까지 도달하는 것은 다른 신호입니다. 실전에서는 public tutorial level 하나를 과하게 최적화한 에이전트보다, 초반 score는 낮아도 여러 game에서 더 깊은 level까지 가는 에이전트가 더 흥미로울 수 있습니다.
작은 local validation protocol
public game은 leaderboard game이 아닙니다. 그래도 투명하게 볼 수 있는 유일한 개발 set입니다. 작은 dataset처럼 다루는 편이 좋습니다.
1
2
3
4
public games
→ development split
→ holdout split
→ final sanity split
단순한 split은 이렇게 잡을 수 있습니다.
| Split | 용도 | 규칙 |
|---|---|---|
| Development | heuristic과 model을 고칩니다. | log를 마음껏 보고 수정해도 됩니다. |
| Holdout | candidate를 비교합니다. | 매 결과를 본 뒤 바로 tuning하지 않습니다. |
| Final sanity | accidental overfit을 확인합니다. | 실제 submission 전에만 봅니다. |
public game이 25개뿐이라 통계적으로 강한 split은 아닙니다. 그래도 모든 public game을 매번 tuning에 쓰는 것보다는 훨씬 낫습니다. development game에서는 좋아졌는데 holdout game에서 무너지면, Kaggle submission을 쓰기 전에 봐야 할 경고를 본 것입니다.
초심자용 report는 이렇게 단순해도 됩니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
agent: graph_noop_v03
games: 18 development, 7 holdout
development:
completed_levels: 14
median_actions_per_completed_level: 37
no_op_rate: 0.31
repeated_state_rate: 0.18
holdout:
completed_levels: 3
median_actions_per_completed_level: 92
no_op_rate: 0.62
repeated_state_rate: 0.44
이건 leaderboard에 올릴 만한 에이전트는 아닙니다. 하지만 디버깅 가능한 에이전트입니다. development game에서 배운 public game 전용 prior가 holdout으로 옮겨가지 않았고, holdout 실패의 주된 원인이 no-op과 loop라는 점을 보여줍니다. 단순한 score = 0.00보다 훨씬 쓸모 있는 신호입니다.
candidate를 비교할 때도 단일 metric 하나만 보지 않는 편이 좋습니다. 초반 local objective는 이런 식으로 잡을 수 있습니다.
\[J_{\text{local}} = 0.35 \cdot \text{completed\_level\_rate} + 0.25 \cdot \widehat{\text{RHAE}} + 0.20 \cdot \text{late\_level\_reach} - 0.10 \cdot \text{no\_op\_rate} - 0.10 \cdot \text{repeat\_state\_rate}.\]이 수식이 정답이라는 뜻은 아닙니다. 중요한 것은 어떤 에이전트를 고를 때 “많이 풀었나”만 보지 말고, “효율적으로 풀었나”, “뒤 level까지 갔나”, “action을 낭비하지 않았나”를 같이 보자는 것입니다. 나중에는 game별, level별로 weight를 다르게 줄 수 있지만, 처음에는 이런 단순한 composite score만으로도 후보 비교가 훨씬 안정됩니다.
5. 대회 구조: 규칙, 상금, 마감
ARC-AGI-3는 ARC Prize 2026의 핵심 track 중 하나입니다. Kaggle code competition으로 열렸고, 일반적인 prediction competition과는 조금 다릅니다.
- 평가 중 인터넷이 차단됩니다. GPT, Claude, Gemini 같은 hosted API는 호출할 수 없습니다. 하지만 공개된 pretrained weight를 Kaggle input으로 넣고 notebook 안에서 local inference를 실행하는 것은 허용됩니다.
- 상금을 받으려면 open-source 공개가 필요합니다. 정확한 milestone claim 절차는 주최 측 clarification을 봐야 하지만, prize-eligible solution은 공개되어야 합니다.
- Notebook-only submission입니다. Kaggle overview 기준으로 CPU/GPU notebook runtime은 최대 9시간입니다. ARC Prize docs는 local starter kit도 제공합니다.
- Timeline: 2026년 3월 25일 시작, 6월 30일과 9월 30일 milestone, 11월 2일 final submission, 11월 8일 paper due, 12월 4일 결과 발표입니다.
- ARC-AGI-3 prize pool: 총 $850K입니다. 100% 에이전트를 위한 $700K Grand Prize, 확정 상금인 $75K Top Score Award, $75K milestone prize가 있습니다.
확정 상금은 다음처럼 나뉩니다.
| Pool | Distribution |
|---|---|
| Top Score Award | $40K / $15K / $10K / $5K / $5K |
| Milestone #1 | $25K / $10K / $2.5K |
| Milestone #2 | $25K / $10K / $2.5K |
Kaggle code competition이 처음이라면 핵심 차이는 이것입니다.
| 일반 prediction competition | ARC-AGI-3 |
|---|---|
| 보통 prediction CSV를 제출합니다. | 코드를 제출하고 Kaggle이 실행합니다. |
| test data는 고정된 row입니다. | evaluation은 interactive game loop입니다. |
| 모델은 offline에서 학습하고 숫자만 출력해도 됩니다. | 에이전트가 반복적으로 행동하고 피드백을 받아야 합니다. |
| internet은 보통 training 이후 중요하지 않습니다. | 인터넷이 차단되어 hosted API를 쓸 수 없습니다. |
즉, 외부 LLM API를 감싼 harness는 연구용으로는 흥미로울 수 있지만, Kaggle final submission으로는 그대로 쓸 수 없습니다. 제출용 에이전트에는 필요한 구성요소가 모두 포함되어 있어야 합니다. 예를 들면 rule, heuristic, 작은 model, learned prior, search procedure, local memory 같은 것들입니다.
6. 현재 상황: 겉치레를 걷어내고 보면
Milestone #1이 기준점을 바꾸었다
6월 30일에 마감된 첫 milestone에서는 전체 대회 환경에서 실제 성과를 인정받은 방법이 처음 공개됐습니다.
| 순위 | 팀 / 시스템 | 핵심 접근법 |
|---|---|---|
| 1 | Tufa Labs, The Duck | Local Qwen 3.6 27B FP8, live Python REPL, multimodal observation, 오래된 context를 순차적으로 비우는 eviction |
| 2 | Reki | Local Gemma-4-31B, 구조화된 JSON plan과 reflection, legal-action repair, NumPy click fallback |
| 3 | forge | Local Gemma-4-31B, 구조화된 plan과 reflection, 설정 가능한 candidate 생성·선택 framework |
Duck의 공식 milestone 점수는 1.21%였습니다. 이 시스템은 model을 policy network로 쓰기보다, 실시간으로 환경을 조사하며 코드를 쓰는 agent로 활용합니다. 매 단계의 observation을 Python 변수로 만들고, model이 추론한 뒤 helper function을 호출하거나 분석 코드를 실행합니다. 이어서 action을 하나 내고 그 결과를 다시 관찰합니다. 상황에 따라 rendered image, raw ASCII grid, segmentation 결과 중 적합한 표현을 골라 봅니다. Context가 가득 차면 오래된 interaction부터 제거해 긴 playthrough를 이어 갑니다.
기법의 출처는 정확히 구분할 필요가 있습니다. 작고 색이 드문 물체를 먼저 누르는 NumPy salient click 규칙과, 여러 번 눌러도 변화가 없던 물체를 다시 누르지 않게 하는 dead-signature는 Duck이 아니라 2위 Reki의 기법입니다. Reki와 forge는 공식 GPT-OSS template에서 출발해 base model을 Gemma로 바꿨습니다. 상위 3개 시스템 가운데 에이전트가 직접 탐색 코드를 작성하는 것은 Duck뿐입니다.
팀 구성의 변화도 흥미롭지만 과장해서는 안 됩니다. Duck은 스스로를 StochasticGoose의 후속작이라고 설명하고, StochasticGoose를 만든 Dries Smit도 Duck 팀에 합류했습니다. 이는 full competition의 Kaggle 실행 조건에서는 per-level CNN과 sparse RL에만 의존하는 것보다 local LLM harness가 더 유망했다는 강한 실전 신호입니다. 그렇다고 action prior나 RL 자체가 쓸모없다는 뜻은 아닙니다. 더 강한 harness 안에서 여전히 중요한 부품이 될 수 있습니다.
서로 섞으면 안 되는 네 가지 점수표
| 평가 맥락 | 결과 | 이 결과가 말해 주는 것 |
|---|---|---|
| 30-day preview, hidden game 3개 | StochasticGoose 12.58% | CNN + sparse-RL이 작은 preview set에서는 분명한 신호를 냈지만 full launch에는 일반화하지 못했습니다. |
| Kaggle Milestone #1 hidden evaluation | Duck 1.21% | 외부 연결 없이 local open-weight model을 실행하는 coding harness가 규정에 맞고 실제 경쟁력도 있음을 입증했습니다. |
| ARC Prize 공식 model evaluation | Sol Max public 13.33% / semi-private 7.78% | 훨씬 큰 frontier harness가 공개 game에서 얻은 성능을 semi-private set에도 일부 이어 갔음을 보여 줍니다. |
| Public-game 연구 보고 | Rodionov 58.12%; Schema 98.98% / 95.35% | 명시적 working model과 검증 절차가 공개 game을 많이 풀 수 있음을 보여 주지만, 최고 수치는 public-only이거나 자가보고입니다. |
저는 2026년 7월 23일 Kaggle CLI로 leaderboard도 다시 확인했습니다. 상위 세 점수는 1.86, 1.61, 1.60이었고, Tufa Labs는 1.45였습니다. 1.50 이상이 10개 팀, Duck의 최초 점수인 1.21 이상이 122개 팀이었습니다. 따라서 Duck은 1.2% 부근에서 처음 등장한, 널리 살펴보고 재현할 수 있는 baseline이지 현재 frontier 전체를 뜻하지는 않습니다. 현재 1.86점 팀의 방법은 공개되지 않았으므로 상위권 전체가 Duck 계열이라고 단정할 수도 없습니다.
공개 이후 Duck을 복제하거나 변형한 notebook이 빠르게 늘어난 것은 사실입니다. CLI로 검색해도 수십 개가 나옵니다. 그러나 점수가 비슷하다는 이유만으로 같은 계보라고 볼 수는 없습니다. 예를 들어 milestone의 0.86점 submission은 forge였고, 0.79점 안팎의 Gemma dynamics notebook은 별도 계열이었습니다. 전략의 출처는 점수가 아니라 코드를 보고 판단해야 합니다.
Public game에서 보고된 급격한 상승도 신중하게 읽어야 합니다. Andrey Rodionov의 executable world model agent는 GPT-5.5 high로 25개 중 15개 game을 완전히 풀고 평균 RHAE 58.12%를 기록했습니다. Schema는 Opus/Fable fallback으로 98.98%, GPT-5.6 Sol로 95.35%를 보고했습니다. 다만 Schema는 두 결과 모두 미검증 자가보고라고 명시하고 있고, 점수가 낮은 game을 더 강한 설정으로 다시 실행한 뒤 game별 최고 점수를 남깁니다. Public game을 미리 볼 수 있다는 점, 반복 tuning, best-of selection, 훨씬 큰 hosted model, hidden holdout 부재가 모두 public 90%대와 Kaggle 1%대 사이의 차이에 영향을 줍니다.
이제 남는 결론은 “CNN이 LLM보다 낫다”도, “LLM은 Kaggle에 낼 수 없다”도 아닙니다. 상호작용 기록을 working model로 바꾸고, 그 model의 예측을 실제 transition으로 검증한 뒤, 검증을 통과한 지식 위에서 계획하는 과정이 필요합니다. 어떤 표현 방식과 base model이 이 과정을 가장 효율적으로 수행하는지는 아직 열린 문제입니다.
왜 현재 시스템이 어려워하는가
Frontier LLM은 language로 표현되는 문제와 training distribution 안에 있는 지식에 강합니다. ARC-AGI-3는 이 두 편안함을 모두 제거합니다.
| 일반 LLM benchmark | ARC-AGI-3 |
|---|---|
| 문제 지시가 자연어로 주어집니다. | 목표가 주어지지 않습니다. |
| 모델은 한 번 답합니다. | 에이전트는 수십~수백 번 행동해야 합니다. |
| 입력은 주로 symbolic text입니다. | 입력은 변화하는 grid world입니다. |
| memorized pattern에 어느 정도 기댈 수 있습니다. | private game은 처음 보는 환경이고 public demo와 다르게 설계됩니다. |
| 중간의 틀린 생각은 비용이 없습니다. | 잘못된 action은 action budget을 소모합니다. |
마지막 줄이 특히 가혹합니다. 일반 benchmark에서는 중간 reasoning이 틀려도 최종 답만 맞으면 됩니다. ARC-AGI-3에서는 틀린 exploratory move도 action입니다. 그리고 action은 점수 계산에서 가장 중요한 비용 단위입니다. 에이전트는 배우기 위해 action을 써야 하지만, 너무 많이 쓰면 점수가 무너집니다.
예를 들어 사람이 12 action에 푼 level을 에이전트가 120 action에 풀었다면:
\[\left(\frac{12}{120}\right)^2 = 0.01.\]그 level에서 인정되는 점수는 1%뿐입니다. brute-force로 이긴 것도 점수 관점에서는 실패와 크게 다르지 않을 수 있습니다.
왜 leaderboard에는 설명이 필요한가
Kaggle leaderboard가 여전히 2% 아래인데 public notebook과 연구 보고에는 훨씬 높은 점수가 나오는 이유는 크게 세 가지입니다.
- Stale score — Kaggle은 metric이 바뀌어도 오래된 submission을 자동으로 재채점하지 않습니다. 예전 rule로 계산된 점수가 섞여 있을 수 있습니다.
- Patched exploit — 한동안 public game source를 disk에서 찾아 실제 simulator에 대해 exhaustive search를 돌리는 white-box trick이 가능했습니다. private leaderboard에는 맞지 않고, 해당 경로는 이후 막힌 것으로 알려져 있습니다.
- 평가 protocol의 차이 — hosted frontier model 연구는 훨씬 많은 compute를 쓸 수 있고, 일부 public 연구는 실패한 game을 다시 실행하거나 game별 최고 결과를 선택합니다. Kaggle은 hidden game에서 self-contained notebook 하나를 9시간 안에 실행합니다.
따라서 public notebook score만 기준점으로 삼는 것은 위험합니다. 중요한 것은 같은 원리가 unseen game에서도 살아남는지, 실제 action을 얼마나 쓰는지, Kaggle runtime 안에서 끝나는지입니다.
7. 접근법들: 각각 무엇을 배우고 어디서 막히는가
먼저 용어를 번역해 둡니다.
| 용어 | 여기서의 의미 |
|---|---|
| CNN | image/grid의 local spatial pattern을 잘 보는 neural network입니다. |
| Sparse reward | 보상이 드물게 주어지는 상황입니다. 보통 level을 클리어하거나 milestone에 도달했을 때만 의미 있는 피드백이 생깁니다. |
| State graph | 에이전트가 본 frame들을 node로, action을 edge로 만든 graph입니다. |
| Value model | 어떤 state/action이 성공에 가까운지 추정하는 model입니다. |
| World model | 환경이 어떻게 작동하는지 명시적으로 나타낸 working model입니다. Learned simulator일 수도 있고, state graph나 “state S에서 action A를 하면 무엇이 일어나는가”를 예측하는 Python code일 수도 있습니다. |
| Intrinsic exploration | 외부 reward만이 아니라 novelty, uncertainty, information gain으로 탐색하는 방식입니다. |
| Planning | action을 바로 실행하기 전에 가능한 future sequence를 탐색하는 것입니다. |
| BFS / A* | 가능한 action sequence를 systematic하게 탐색하는 search algorithm입니다. BFS는 짧은 경로부터 넓게 보고, A*는 heuristic으로 유망한 경로를 먼저 봅니다. |
| Beam search | 모든 후보를 보지 않고, 매 depth마다 상위 몇 개 후보만 남기는 search입니다. |
| White-box / black-box | game source나 내부 field를 볼 수 있으면 white-box, 오직 observation/action API만 쓰면 black-box에 가깝습니다. hidden evaluation에서는 black-box 가정이 더 안전합니다. |
중요한 구분은 reactive system과 model-based system입니다. reactive system은 “지금 어떤 action이 좋아 보이는가”를 묻습니다. model-based system은 “이 action을 하고, 그 다음 action을 하면 무엇이 일어날까”를 묻습니다. 사람이 새로운 game을 배울 때는 보통 두 번째 방식에 많이 의존합니다.
(a) CNN + sparse-RL action prediction (StochasticGoose 계열). 작은 CNN이 어떤 action이 frame을 바꾸는지 예측하게 하고, 변화가 있을 법한 action을 먼저 시도합니다. Click 좌표도 convolutional 64×64 head로 예측할 수 있습니다.
장점: sample-efficient하고 self-contained입니다. 지금도 action prior나 no-op filter로 쓸 가치가 있습니다.
한계: 이것만으로 완성된 에이전트를 만들기는 어렵습니다. 화면을 바꾸는 action이 왜 목표에 도움이 되는지는 설명하지 못하며, preview의 성과도 full benchmark로 이어지지 않았습니다.
(b) State graph + value model (Blind Squirrel / just-explore). 이미 본 state를 graph로 만들고, loop나 no-op action을 줄입니다. 점수가 좋아지는 path를 발견하면 그 path를 거꾸로 labeling해서 value model을 학습할 수 있습니다.
장점: 방문한 상태에 대해서는 해석 가능하고, loop를 피하는 데 도움이 됩니다.
한계: 이미 가본 frontier 안에서만 강합니다. 아직 가보지 않은 목표 상태를 상상하는 힘은 약합니다.
(c) Learned neural world model + intrinsic exploration. $(s, a, s’)$ 경험으로 transition model을 학습하고, 그 model 위에서 planning합니다. 아직 불확실하거나 model 사이의 예측이 크게 엇갈리는 action을 먼저 실험합니다.
장점: 이미 방문한 state 바깥을 예측할 수 있고, compact한 action prior를 만들 수 있습니다.
한계: sparse reward와 적은 online data로 신뢰할 만한 model을 빠르게 만드는 일이 어렵습니다. 현재로서는 전체를 지휘하는 controller라기보다 강한 보조 구성요소에 가깝습니다.
(d) Local LLM tool/coding harness (Duck, Reki, forge). Open-weight model을 offline notebook 안에서 실행하고 observation tool, memory, legal-action 검사, reflection, 제한된 action interface를 붙입니다. Duck은 여기에 Python REPL을 제공해 model이 상태를 직접 분석하고 변환하는 code를 작성하게 합니다.
장점: Kaggle 규정에 맞고, Milestone #1에서 실제 성과도 확인됐습니다. 하나의 고정 policy에 묶이지 않고 test time에 표현 방식과 문제 풀이 절차를 바꿀 수 있습니다.
한계: 27B~31B급 model이 runtime과 memory budget 대부분을 사용합니다. Context 관리, 잘못된 출력 형식, 느린 inference, 불안정한 visual grounding도 해결해야 합니다. Duck의 1.21%는 coding loop만으로 hidden generalization이 해결되지는 않는다는 사실도 보여 줍니다.
(e) 검증 가능한 executable world model (Rodionov / Schema 방향). Coding agent가 game dynamics를 설명하는 Python model을 유지하고, 그 model의 예측을 실제 transition과 비교합니다. 예외가 쌓인 model은 더 단순한 설명으로 정리하고, 실제 action을 쓰기 전에 살아남은 model 위에서 계획합니다.
장점: 가설을 그럴듯한 문장에서 틀릴 수 있는 예측으로 바꿉니다. Rodionov는 public 평균 RHAE 58.12%, Schema는 90%대 중후반을 보고했습니다.
한계: 가장 높은 결과는 visible public game과 훨씬 큰 hosted model을 사용했습니다. 후속 ablation에서는 model 크기와 reasoning effort의 영향이 가장 컸고, 일부 조건에서는 textual working model이 flexible executable model보다 나았습니다. Verification은 일관되게 도움이 됐지만 Python code 자체가 만능 열쇠인 것은 아닙니다.
(f) Public-game source 기반 BFS / FORGE 계열. 2026년 6월 하순의 고득점 public notebook에서 두드러졌던 역사적 계열입니다. Public game source로 game class를 직접 실행하고, 실제로 효과가 있는 action을 찾은 뒤 BFS/A*/beam search로 solution path를 탐색합니다. 여기에 hidden field나 transient field를 hash에 넣거나 빼면서 state 구분을 더 정교하게 만듭니다.
장점: public game에서는 매우 강합니다. 어떤 action이 실제로 frame을 바꾸는지 미리 scan하고, click 좌표도 _get_valid_actions() 같은 내부 helper를 통해 좁힐 수 있으면 search가 훨씬 쉬워집니다.
한계: 이 방식은 public source와 내부 구현에 기대는 부분이 많습니다. hidden/private game에서도 같은 방식의 source introspection이 가능하다고 가정하면 위험합니다. 따라서 이런 notebook은 “final solution”이라기보다, 어떤 search 장치가 도움이 되는지 배우는 참고 자료로 보는 편이 안전합니다.
초심자에게 더 중요한 교훈은 “이 중 하나를 복사하라”가 아닙니다. 각 접근이 무엇을 가르쳐 주고, 어디서 실패하는지를 보는 것입니다.
| 접근 | 먼저 가르쳐 주는 것 | 먼저 실패하는 것 |
|---|---|---|
| Action-prediction RL | 어떤 action이 의미 있는 변화를 만드는가 | 그 변화가 왜 중요한가 |
| State graph search | 같은 state를 반복하지 않는 법 | 아직 안 가본 state를 상상하는 법 |
| Learned world-model planning | 방문하지 않은 state를 예측하고 행동 전에 계획하는 법 | 빠르게 신뢰할 만한 model을 만드는 법 |
| Local LLM harness | 표현을 바꾸고 tool을 작성하며 의미 있는 가설을 유지하는 법 | Runtime, context, grounding, hidden generalization |
| 검증 가능한 executable model | 가설을 시험하고 모순이 생기면 수정하는 법 | 좋은 실험을 고르고 지나치게 복잡한 model을 피하는 법 |
| Public-source BFS/FORGE | search, action scan, state hashing의 힘 | hidden game에서 source/introspection 의존이 깨지는 문제 |
지금 제 판단은 조금 더 구체적입니다. Local LLM harness가 변화에 대응하는 controller 역할을 맡고, 이미 확인한 사실은 exact transition memory가 보존합니다. 아직 모르는 규칙은 executable hypothesis로 표현하고, 여러 가설의 예측이 엇갈릴 때는 disagreement가 큰 action을 실험합니다. 이미 아는 경로를 다시 실행할 때는 shortest-path replay로 action 낭비를 줄입니다. Model은 abstraction을 만들고 수정하되, 환경이 이미 증명한 사실을 잊지 않도록 deterministic code가 받쳐 주는 구조입니다.
공개 코드에서 보이는 패턴: 6월의 search, 7월의 harness
6월 25일 무렵에는 public source를 이용한 BFS와 state hashing이 가장 눈에 띄었습니다. Milestone #1 이후에는 중심이 local LLM harness로 이동했습니다. 그렇다고 앞선 search 기법이 사라진 것은 아닙니다. 지금 공개 코드에서 반복되는 발상은 다음처럼 정리할 수 있습니다.
| 전략 축 | 핵심 아이디어 | 배울 점 | 조심할 점 |
|---|---|---|---|
| Duck-style coding harness | Local LLM이 Python REPL에서 observation을 분석하고 필요한 helper code를 작성합니다. | Model이 game마다 적절한 표현과 분석 절차를 새로 만들 수 있습니다. | Context와 runtime을 많이 쓰며, model이 작성한 code도 틀릴 수 있습니다. |
| Reki-style structured controller | 짧은 action queue, reflection memory, JSON repair, legal-action 제약을 둡니다. | 자유로운 reasoning과 엄격한 action interface를 분리할 수 있습니다. | 형식이 안정적이라고 game model이 정확한 것은 아닙니다. |
| Verified executable model | 규칙을 Python prediction으로 만들고 실제 transition과 대조합니다. | 가설을 검증하고 반례에 따라 수정하는 절차가 중요합니다. | Public game의 높은 점수를 hidden generalization으로 오해하면 안 됩니다. |
| Exact transition graph + replay | 관찰한 $(s,a,s’)$를 정확히 저장하고, 이미 찾은 경로는 shortest path로 재실행합니다. | 같은 실험과 실패를 반복하지 않고 RHAE 낭비를 줄일 수 있습니다. | Grid가 같아도 hidden timer나 latent state가 다를 수 있습니다. |
| Action prior / salient click | CNN이나 NumPy heuristic으로 no-op 가능성이 큰 action과 click 좌표를 줄입니다. | 큰 action space를 다루려면 값싼 후보 축소가 필요합니다. | Heuristic만으로 goal이나 장기 계획을 알 수는 없습니다. |
| Public-source graph search | 공개 simulator와 내부 helper를 이용해 BFS/A*/beam search를 강화합니다. | State hash, action dedup, replay engineering의 좋은 실험장입니다. | Hidden game에도 source introspection이 가능하다고 가정할 수 없습니다. |
여기서 중요한 변화는 “search가 LLM으로 대체됐다”가 아닙니다. LLM이 가설과 도구를 만들고, deterministic memory와 search가 이미 확인한 사실을 지키는 방향으로 역할이 재배치됐다고 보는 편이 정확합니다. 큰 prompt 하나에 모든 일을 맡기는 방식보다, 역할이 분명한 작은 도구를 제공하는 방식이 강합니다.
공개 코드를 참고할 때는 다음을 분리해야 합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
가져올 것:
observation을 여러 표현으로 바꾸는 tool
transition log와 exact state graph
no-op/action dedup
legal-action 검사와 output repair
hypothesis prediction 검증
reset 후 shortest-path replay
따로 검증할 것:
public source와 hidden field 의존성
model size와 harness 효과의 분리
grid hash가 hidden state를 놓치는 문제
public game별 tuning과 best-of selection
Kaggle 9시간 안의 실제 처리량
Public example은 여전히 정답지가 아닙니다. 다만 이제는 실패 원인뿐 아니라 local LLM과 deterministic program을 어떻게 나눠 맡길 것인지까지 보여 주는 설계 자료가 됐습니다.
초심자를 위한 세 번의 구현 패스
처음 시작하는 사람에게 바로 “world model을 만들자”고 말하면 너무 큽니다. 저는 세 번의 구체적인 구현 패스로 나누겠습니다.
Pass 1: 무작위 에이전트의 낭비 줄이기
먼저 가능한 action만 고르는 무작위 에이전트에서 시작합니다. 그다음 가장 분명한 낭비를 제거합니다.
- available action 안에서만 sampling합니다.
- 같은 state에서 이미 no-op으로 확인된 action은 다시 고르지 않습니다.
- 바로 직전 state로 돌아가는 2-step loop를 피합니다.
- coordinate click은 전체 pixel에서 균등 무작위로 찍지 말고, object처럼 보이는 cell 근처에서 고릅니다.
- reset은 state가 막혔거나 game over일 때만 씁니다.
목표는 똑똑한 에이전트를 만드는 것이 아닙니다. 무작위 탐색이 쓸 만한 데이터를 남기게 만드는 것입니다.
click action의 후보 좌표도 처음에는 아주 단순하게 만들 수 있습니다.
1
2
3
4
5
6
7
8
def candidate_clicks(grid):
background = most_common_color(grid)
cells = []
for y, row in enumerate(grid):
for x, value in enumerate(row):
if value != background:
cells.append((x, y))
return cells
이 방법은 자주 틀릴 겁니다. 그래도 64×64 전체 board에서 아무 pixel이나 찍는 것보다는 대개 낫습니다. background를 계속 클릭하는 것만 줄여도 action budget이 꽤 절약됩니다.
작은 예시를 보겠습니다.
1
2
3
4
5
0 0 0 0 0
0 1 0 2 0
0 0 0 0 0
0 3 0 0 0
0 0 0 0 0
여기서 0이 background라고 추정되면 click 후보는 (1,1), (3,1), (1,3) 세 곳입니다. 전체 25개 cell을 균등하게 클릭하면 대부분 background를 누르게 됩니다. 하지만 non-background cell만 후보로 두면 적어도 object를 건드릴 가능성이 커집니다.
물론 이 heuristic도 틀릴 수 있습니다. 어떤 game에서는 background처럼 보이는 cell이 버튼일 수 있고, object 주변 빈칸을 클릭해야 할 수도 있습니다. 그래서 click 후보는 하나가 아니라 여러 계열로 나누는 것이 좋습니다.
| 후보 계열 | 예시 | 왜 필요한가 |
|---|---|---|
| object cell | 색이 background와 다른 cell | 가장 단순한 object interaction 후보입니다. |
| object border | object 주변 1-cell neighborhood | object 옆 빈칸을 눌러야 하는 game에 필요합니다. |
| changed cell | 직전 action 후 바뀐 cell | 이미 반응을 보인 위치를 다시 조사합니다. |
| centroid | 같은 색 object의 중심점 | 큰 object를 한 번에 대표하는 좌표입니다. |
| sparse grid | 일정 간격으로 찍은 보조 좌표 | object detector가 틀렸을 때 최소한의 탐색을 보장합니다. |
초반 에이전트는 이 후보들을 모두 만들고, no-op 결과를 보면서 점점 줄여가면 됩니다.
Pass 2: state graph 만들기
no-op을 줄였다면, 이제 관측한 transition을 전부 저장합니다.
1
2
3
state_hash --ACTION1--> next_state_hash
state_hash --ACTION5--> next_state_hash
state_hash --ACTION6(x=12,y=7)--> next_state_hash
그러면 이런 질문을 할 수 있습니다.
- 이 state에서 아무 변화도 만들지 않는 action은 무엇인가?
- 어떤 action이 아직 보지 못한 state로 이어지는가?
- 어떤 action이 score나 game state를 바꾸는가?
- 어떤 state를 계속 반복 방문하고 있는가?
- 에이전트가 graph를 넓히고 있는가, 아니면 같은 부분 안에서 돌고 있는가?
state graph는 첫 번째 세계 지도입니다. 아직 learned model은 아니지만, raw experience를 구조화된 데이터로 바꿔 줍니다. 이게 있어야 그 다음 learning도 의미가 생깁니다.
state hash는 생각보다 중요합니다. 예를 들어 grid만 hash하면 다음 두 state가 같아 보일 수 있습니다.
1
2
3
4
5
grid는 같음
하지만 내부 counter는 2/3
grid는 같음
하지만 내부 counter는 3/3, 다음 action에서 문이 열림
반대로 action count처럼 매번 변하는 transient field까지 hash에 넣으면, 사실상 같은 state가 매번 다른 state로 보입니다. 그러면 visited-state cache가 무력화됩니다.
그래서 public examples의 FORGE 계열이 hidden field probing, transient field detection, trigger-aware hashing에 신경을 쓰는 것입니다. 이건 꼼수가 아니라, interactive search에서는 state representation이 곧 search space라는 사실을 보여줍니다.
Pass 3: action priority 붙이기
graph를 만들었다면 이제 action을 균등 무작위로 고르지 않습니다. 점수를 매깁니다.
| Signal | 의미 |
|---|---|
+ novelty | 아직 보지 못한 state로 갈 것 같은 action을 선호합니다. |
+ change_prior | 비슷한 state에서 frame을 바꾼 action을 선호합니다. |
+ object_focus | background가 아닌 object와 관련된 action을 선호합니다. |
+ score_delta | score나 level state를 개선한 transition을 선호합니다. |
- no_op | 이미 아무 변화가 없던 action의 점수를 낮춥니다. |
- loop_risk | 최근 state로 돌아갈 가능성이 큰 action의 점수를 낮춥니다. |
처음에는 hand-written priority function이어도 됩니다.
1
2
3
4
5
6
7
8
score = (
2.0 * novelty
+ 1.0 * change_prior
+ 0.5 * object_focus
+ 3.0 * score_delta
- 2.0 * no_op
- 1.5 * loop_risk
)
이것이 AGI는 아닙니다. 하지만 최소한 일관된 에이전트입니다. 행동하고, 관측하고, 기억하고, 배운 것에 따라 다음 행동을 바꿉니다. 여기까지 와야 neural action prior나 learned transition model을 붙일 자리가 생깁니다.
초반에 꼭 진단해야 할 실패 모드
대부분의 에이전트는 지루한 방식으로 실패합니다. 다행히 지루한 실패는 측정하기 쉽습니다.
| 증상 | 가능한 원인 | 첫 번째 수정 |
|---|---|---|
| action은 많은데 frame 변화가 거의 없음 | unavailable 또는 irrelevant action을 sampling함 | available-action metadata와 no-op cache를 씁니다. |
| frame은 바뀌지만 score/level progress가 없음 | action prior는 motion을 찾지만 goal을 못 찾음 | goal hypothesis와 score-change tracking을 추가합니다. |
| 같은 frame 근처를 반복함 | loop detector가 없음 | recent-state window를 두고 되돌아가는 action의 점수를 낮춥니다. |
| public game 하나에서는 좋은데 다른 game에서 무너짐 | public-game overfit | public game을 split하고 holdout에서 평가합니다. |
| click action이 많지만 의미가 없음 | 좌표를 균등 무작위로 고름 | non-background cell, changed cell, object center 근처를 클릭합니다. |
| level은 풀지만 score가 낮음 | exploratory action을 너무 많이 씀 | actions per completed level을 보고 brute-force rollout을 줄입니다. |
| runtime이 터짐 | search width가 너무 큼 | candidate action 수, planning depth, per-turn model update를 제한합니다. |
거창한 architecture diagram보다 이런 표가 초반에는 더 유용합니다. 무엇을 log해야 하고, 다음에 무엇을 고쳐야 하는지 보여주기 때문입니다.
8. Meta-game: scoring의 함정과 남은 질문
이 부분은 forum을 읽어야만 알게 되는 실전 함정입니다.
env.make()를 여러 번 호출하면 위험할 수 있습니다. 특히 parallelization 과정에서 process마다 scorecard를 열면 점수가 0이 되는 식의 문제가 생길 수 있습니다. main thread에서 한 번만 여는 방식을 지키는 것이 중요합니다.MAX_ACTIONS = ∞같은 설정은 위험합니다. recording이 커져 Kaggle storage quota를 터뜨릴 수 있습니다. logic error가 아니라 storage failure로 실패할 수 있습니다.- 에이전트가 human baseline을 볼 수 있는가?
environment_info.baseline_actions같은 정보가 test game에서 의도적으로 노출되는지, 실제로 활용할 수 있는지는 2026년 6월 기준으로 조심스럽게 다뤄야 합니다. 확정된 사실처럼 쓰면 안 됩니다. - 코드 공개를 둘러싼 딜레마는 실제로 벌어졌습니다. Duck이 공개된 뒤 복제본과 가벼운 변형이 leaderboard에 빠르게 늘었습니다. 주최 측도 Milestone #2에 가장 빨리 진입하는 방법으로 공개 template이나 submission을 복사해 수정하라고 안내합니다. 전체 baseline이 빠르게 좋아진다는 장점은 있지만, 점수만으로는 새로운 방법을 만든 팀과 공개 harness의 prompt를 바꾼 팀을 구분하기 어려워졌습니다.
- variance가 있습니다. 같은 코드도 run-to-run 점수가 달라질 수 있습니다. 특히 낮은 점수대에서는 작은 차이가 순위를 크게 흔듭니다.
작지만 중요한 실전 정보도 있습니다.
| 항목 | 의미 |
|---|---|
| Local offline | 빠릅니다. development와 분해 실험에 씁니다. online scorecard/replay는 없지만 iteration이 빠릅니다. |
| Online API | scorecard와 replay를 남길 수 있습니다. 다만 rate limit과 API key 관리가 있습니다. |
| Kaggle submission | 실제 leaderboard scoring입니다. 제출 횟수와 runtime 예산이 제한되어 있으므로 마지막 확인용으로 써야 합니다. |
| Scorecard | 여러 game run의 결과를 묶어 보는 기록입니다. 실패 원인을 추적하려면 scorecard보다 더 자세한 local log가 필요합니다. |
| Replay | action sequence와 frame 변화를 다시 볼 수 있는 자료입니다. 사람이 실패를 이해하는 데 매우 중요합니다. |
| Public notebook score | stale metric과 exploit history 때문에 그대로 믿으면 안 됩니다. |
| Private leaderboard | 최종 standing의 핵심입니다. public game overfit은 여기서 드러납니다. |
초심자가 가장 많이 하는 실수는 Kaggle submission을 local debugger처럼 쓰는 것입니다. 이 대회에서는 반대로 해야 합니다. local/offline에서 수백 번 망하고, 그 망한 이유를 log로 설명할 수 있을 때만 Kaggle submission을 써야 합니다.
9. 나라면 어떻게 접근할 것인가
제 접근은 이렇습니다.
- Kaggle submission만으로 실험하지 않습니다. 25개 public game을 offline에서 실행하고 전체 trace를 저장합니다. 일부 game은 holdout으로 두어 가장 노골적인 public overfit부터 걸러냅니다. Public holdout이 진짜 hidden set은 아니지만 25개 전체를 동시에 튜닝하는 것보다는 낫습니다.
- 현재 공개 baseline부터 재현합니다. 공식 GPT-OSS notebook과 Duck을 먼저 실행하고, Reki식 structured controller와 기존 graph-search/action-prior baseline을 같은 local protocol에서 비교합니다.
- RHAE뿐 아니라 Kaggle 실행 가능성도 측정합니다. Model load time, token throughput, tool-call latency, peak memory, game당 action 수, 전체 예상 runtime을 기록합니다. Public game을 잘 풀어도 hidden suite를 9시간 안에 처리하지 못하면 대회 baseline이 아닙니다.
- 확정된 사실과 가설을 분리합니다. 실제로 관찰한 transition은 deterministic cache에 저장합니다. 아직 확실하지 않은 규칙, goal, object 역할은 지지 증거와 반례를 함께 가진 hypothesis ledger에 둡니다.
- Planning을 두 층으로 나눕니다. 이미 관찰한 transition에서는 shortest-path search로 효율적인 replay를 만들고, 아직 보지 못한 state와 action에만 model이 작성한 program이나 learned prediction을 사용합니다.
- 가설이 충돌하는 곳을 탐색합니다. 단순히 새로운 frame을 만드는 action보다, 그럴듯한 가설들이 서로 다른 결과를 예측하는 action에 정보 가치가 있습니다.
- Milestone #2를 외부 검증 시한으로 삼습니다. 9월 30일 전에 local suite를 고정하고, 구성요소별 ablation을 수행한 뒤, local model·transition cache·recovery path가 전체 runtime budget을 통과한 경우에만 제출합니다.
starter kit에서 실제로 수정해야 하는 부분은 많지 않습니다. 보통 중요한 코드는 agent/my_agent.py 안의 MyAgent class입니다.
1
2
3
4
5
6
7
8
9
10
11
class MyAgent(Agent):
def is_done(self, frames, latest_frame) -> bool:
"""에이전트가 playthrough를 멈추고 싶으면 True를 반환한다."""
return False
def choose_action(self, frames, latest_frame) -> GameAction:
"""frame history를 보고 다음 legal action 하나를 반환한다."""
state = parse_grid(latest_frame)
model = update_world_model(frames)
goal = infer_goal(state, model)
return plan_next_action(state, model, goal)
이 stub 하나가 문제 전체를 압축해서 보여 줍니다.
1
perception → memory/model update → goal inference → planning → action
처음 코드를 열면 막막할 수 있으니, 저는 choose_action()을 네 개의 작은 함수로 나누는 것을 권합니다.
1
2
3
4
5
def choose_action(self, frames, latest_frame):
state = self.parse_state(latest_frame)
self.update_memory(frames, state)
candidates = self.make_candidates(state)
return self.select_action(state, candidates)
각 함수의 첫 버전은 아주 단순해도 됩니다.
| 함수 | 첫 버전에서 할 일 | 나중에 붙일 것 |
|---|---|---|
parse_state | grid, available actions, game state를 꺼냅니다. | object segmentation, changed-cell extraction |
update_memory | state hash와 직전 action outcome을 저장합니다. | state graph, cross-level memory |
make_candidates | available actions와 click 후보를 만듭니다. | action scan, object-focused click, learned action prior |
select_action | no-op과 loop를 피하고 점수 높은 action을 고릅니다. | short-horizon planning, world-model rollout |
처음 공부할 것도 이 순서로 맞추면 좋습니다.
- Python data handling: list, dict, dataclass, JSONL log.
- NumPy grid operation: equality, changed-cell mask, connected component.
- Graph/search basics: BFS, visited set, shortest path, depth limit.
- Kaggle notebook runtime: 인터넷 차단, file path, package import, submission output.
- Small ML model: CNN이나 value model은 로그와 graph가 생긴 뒤에 붙입니다.
처음부터 “world model”이라는 큰 단어를 붙잡지 말고, 다음 질문에 답하는 함수부터 만들면 됩니다.
1
2
3
4
5
이 action은 frame을 바꾸는가?
바꾼다면 어떤 cell이 바뀌는가?
같은 state에서 이미 해본 action인가?
이 action은 최근 loop로 돌아가는가?
이 action은 score나 level state를 바꾼 적이 있는가?
이 질문들이 code로 답해지기 시작하면, 그 다음이 model입니다.
실제 구축 순서
처음 시작한다면 저는 neural network부터 만들지 않을 겁니다. 아래 순서로 쌓겠습니다.
| 단계 | 만들 것 | 이유 |
|---|---|---|
| 0 | random starter를 로컬에서 실행 | environment, submission path, logging이 되는지 확인합니다. |
| 1 | 모든 frame/action/result를 replay log로 저장 | 보지 못하는 것은 개선할 수 없습니다. |
| 2 | no-op action detector | 아무 변화 없는 action 반복을 줄입니다. |
| 3 | visited-state cache | 같은 state를 빙빙 도는 것을 막습니다. |
| 4 | simple state graph | 에이전트가 발견한 세계 지도를 만듭니다. |
| 5 | action prior | 비슷한 state에서 frame을 바꾼 action을 우선합니다. |
| 6 | local goal guess | 도달, 정렬, 제거, 색 matching 같은 후보 goal을 추적합니다. |
| 7 | short-horizon planning | 몇 step 앞을 state graph나 model 위에서 탐색합니다. |
| 8 | learned transition prediction | 아직 시도하지 않은 action의 next frame을 예측합니다. |
| 9 | cross-level memory | 같은 game 안의 앞 level mechanic을 뒤 level에 재사용합니다. |
이 순서가 중요합니다. replay logging 없는 learned world model은 black box입니다. visited-state cache 없는 planner는 loop를 다시 발견하느라 시간을 씁니다. level-change detector 없는 cross-level memory는 이전 board에서만 맞았던 가정을 다음 board에 그대로 가져갈 수 있습니다.
처음 볼 local metric도 단순해야 합니다.
| Metric | 확인할 수 있는 것 |
|---|---|
| unique state 수 | exploration이 넓어지는가, loop인가 |
| no-op action rate | action budget을 얼마나 낭비하는가 |
| first useful action step | 의미 있는 변화를 발견하기까지 얼마나 걸리는가 |
| completed level 수 | 가장 거친 성공 신호 |
| actions per completed level | 클리어가 점수로 의미 있을 만큼 효율적인가 |
| cross-level reuse | level 1에서 배운 것이 level 2에 도움이 되는가 |
이 metric들이 보이기 전에는 ML을 얹어도 개선인지 착시인지 알기 어렵습니다.
첫 일주일 계획
처음부터 제대로 된 baseline까지 가는 것을 목표로 한다면, 저는 첫 일주일을 이렇게 잡겠습니다.
| Day | 목표 | 산출물 |
|---|---|---|
| 1 | starter를 로컬에서 실행하고, 변경 없는 baseline을 한 번 제출합니다. | 환경과 submission path가 동작한다는 확인. |
| 2 | frame, action, state hash, outcome을 replay log로 저장합니다. | runs/YYYYMMDD/*.jsonl 같은 log 파일. |
| 3 | no-op detection과 repeated-state detection을 구현합니다. | random보다 덜 낭비하는 agent. |
| 4 | 최소 state graph를 만들고, game 하나에 대해 시각화합니다. | state와 transition이 보이는 graph dump. |
| 5 | object-focused click candidate와 available-action filtering을 추가합니다. | click-heavy game에서 낮아진 no-op rate. |
| 6 | public game을 development/holdout으로 나누고 둘 다 실행합니다. | 작은 comparison report. |
| 7 | simple action-priority function을 붙이고 baseline과 비교합니다. | 첫 candidate와 실패 기록. |
첫 주의 목표는 leaderboard score가 아닙니다. 관측과 기록 체계를 만드는 것입니다. 주말에는 실패 run 하나를 열고 이렇게 말할 수 있어야 합니다.
1
2
3
4
5
이 에이전트가 막힌 이유:
- ACTION5가 70%의 state에서 아무 변화도 만들지 않았다.
- coordinate click 대부분이 background였다.
- 같은 11개 state를 140 action 동안 반복했다.
- level 2에 한 번도 도달하지 못했다.
이 정도면 진전입니다. 실패에 이름이 붙으면, 다음 수정도 정해집니다.
첫 주 이후: Duck을 검증 가능한 hybrid로 확장하기
기본 logger가 동작한 다음에는 LLM에게 모든 일을 맡기기보다 역할을 다음처럼 나누는 편이 좋습니다.
1
2
3
4
5
6
7
8
frame 관찰
→ state 정규화와 exact history 조회
→ LLM에 compact evidence와 사용할 수 있는 tool 제공
→ LLM이 가설, 분석 code, legal action 제안
→ 실제 action 하나 실행
→ exact transition 기록
→ 예측과 실제 결과 대조
→ 가설 유지·수정·폐기
실제 action을 실행하는 공통 함수는 단순하게 유지할 수 있습니다.
1
2
3
4
5
6
7
8
9
10
11
def execute_and_learn(state, action, expected=None):
next_state = env.step(action)
edge = transition_cache.record(state, action, next_state)
if expected is not None:
hypotheses.update_from_prediction(expected, next_state)
if edge.conflicts_with_previous_outcome:
transition_cache.mark_latent_or_stochastic(state, action)
return next_state
Cache key에는 적어도 game, level, 정규화된 grid, API가 제공하는 안정적인 metadata가 들어가야 합니다. Visible grid만 hash하면 위험합니다. 화면은 같아도 timer, animation phase, inventory flag 같은 latent state가 다를 수 있기 때문입니다. 같은 key와 action에서 서로 다른 결과가 나오면 기존 edge를 덮어쓰지 말고 conflict로 기록해야 합니다.
결과가 일관된 edge들은 graph를 이룹니다. Reset하거나 실패한 뒤 이미 발견한 목표로 돌아갈 때, 또는 뒤 level에서 같은 mechanic이 다시 나올 때 BFS나 Dijkstra로 가장 싼 경로를 찾을 수 있습니다. 이는 같은 action을 반복해서 낭비하는 문제를 직접 줄입니다. 다만 처음 경로를 발견할 때 쓴 action까지 되돌려 주지는 않으며, 아직 관찰하지 않은 state를 통과해 계획할 수도 없습니다. Transition cache는 정확한 기억과 replay 장치이지, 그 자체로 완전한 world model은 아닙니다.
LLM은 exact memory가 끝나는 지점에서 일해야 합니다. Object에 의미를 붙이고, 가능한 transition function을 작성하고, goal 후보를 만들고, 서로 경쟁하는 설명을 구분할 실험을 고릅니다. 예를 들어 가설 $h_1$은 “파란 물체가 움직인다”고 예측하고 $h_2$는 “선택한 행 전체가 회전한다”고 예측한다면, 두 가설의 예측이 갈리는 action이 단순한 novelty click보다 정보 가치가 높습니다.
첫 ablation도 구체적으로 설계해야 합니다.
| Variant | 확인할 질문 |
|---|---|
| Duck baseline | 공개 harness를 그대로 실행했을 때 어디까지 가는가? |
| + exact transition cache | 같은 state와 action을 반복하는 낭비가 줄어드는가? |
| + shortest-path replay | 이미 찾은 trajectory를 더 적은 action으로 재현하는가? |
| + prediction verification | 틀린 규칙이 뒤 계획을 계속 오염시키지 않고 제거되는가? |
| + disagreement probe | 더 적은 탐색 action으로 중요한 mechanic을 찾는가? |
edge_reuse_rate, transition_conflict_rate, replay_actions_saved, invalid_action_rate, tokens_per_action, wall-clock time, 완료한 level 수, RHAE를 함께 기록해야 합니다. 이런 측정이 없으면 복잡한 harness가 실제로 더 잘 푸는 것인지, 단지 compute를 더 쓰는 것인지 구분하기 어렵습니다.
초반에 피하고 싶은 것들
저라면 초반에는 다음을 피하겠습니다.
- leaderboard 제출 결과로 직접 튜닝하지 않습니다. 피드백이 너무 느리고 드뭅니다.
- public game mechanic을 코드에 박아 넣지 않습니다. 로컬에서는 좋아 보여도 hidden game에서는 무너집니다.
- 깨끗한 log 없이 비싼 neural model부터 붙이지 않습니다. 그러면 model이 왜 실패하는지 보이지 않습니다.
- completion count만 최적화하지 않습니다. RHAE에서는 느린 win이 거의 쓸모없을 수 있습니다.
- runtime 제한 없이 search 폭만 넓히지 않습니다. timeout이 나는 훌륭한 plan은 0점입니다.
- 실패한 trajectory를 버리지 않습니다. 실패 run에는 어떤 action이 쓸모없는지 보여주는 데이터가 들어 있습니다.
원칙은 간단합니다. 모든 실험은 결과물을 남겨야 합니다. replay, metric table, changed-state summary, failure label 중 하나는 있어야 합니다. leaderboard 숫자 하나만 남는 실험은 배운 것이 너무 적습니다.
“world model + intrinsic exploration”이 실제로 뜻하는 것
말은 거창하지만 첫 버전은 작게 시작할 수 있습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
memory = StateGraph()
model = TransitionModel()
while not done:
state = observe()
candidates = legal_actions(state)
scored = []
for action in candidates:
predicted = model.predict(state, action)
novelty = memory.novelty(predicted)
uncertainty = model.uncertainty(state, action)
goal_value = goal_heuristic(predicted)
scored.append((novelty + uncertainty + goal_value, action))
action = max(scored)[1]
next_state = step(action)
memory.add(state, action, next_state)
model.update(state, action, next_state)
이것이 곧 final solution이라는 뜻은 아닙니다. 다만 제가 신뢰하는 방향은 대략 이쪽입니다. 관측을 기록하고, action이 무엇을 하는지 배우고, 목표가 불분명할 때는 novelty와 uncertainty를 따라가며, 환경이 조금씩 읽히기 시작하면 goal-directed planning으로 전환합니다.
10. 이 대회에서 실제로 얻는 것
- 상금 — milestone pool, top score pool, 그리고 현재로서는 매우 어려운 grand prize가 있습니다.
- Paper Prize track — 점수뿐 아니라 방법론을 설명하는 paper도 별도 보상을 받을 수 있습니다.
- Kaggle medal/ranking — portfolio 관점에서 의미가 있을 수 있습니다.
- 진짜 open problem에 기여 — public game은 빠르게 풀리고 있지만, Kaggle 제약 안에서 hidden game에 일반화하는 성능은 여전히 바닥에 가깝습니다. 새 아이디어가 기여할 공간이 충분합니다.
- RL, world models, program induction 사이의 포지셔닝 — 학습 주제로도 매우 좋습니다.
11. 제 생각
Milestone #1 결과를 보고 이 글의 이전 결론 하나를 분명히 정정해야 했습니다. Hosted API에 의존하는 submission을 낼 수 없다는 판단은 맞았습니다. 그러나 그 사실을 “LLM harness는 Kaggle에 낼 수 없다”로 일반화한 것은 틀렸습니다. Local open-weight model은 허용되고, 공식 template도 실행 방법을 보여 주며, Duck은 바로 그 계열의 시스템으로 milestone에서 우승했습니다.
최신 결과는 기술적인 예상도 바꿨습니다. 이제 저는 답이 단순히 learned neural world model이라고 보지 않습니다. 더 일관되게 나타나는 공통점은 하나의 절차입니다. 환경에 대한 working model을 만들고, 그 model로 예측하고, interaction history와 대조하고, 모순이 생기면 고치고, 검증을 통과한 지식으로 계획하는 과정입니다. Executable Python model은 유용한 표현 방식이지만, ablation 결과를 보면 그것만이 성공의 원인이라고 할 수는 없습니다. Base model의 능력과 reasoning effort도 여전히 큰 영향을 줍니다.
현재 제가 가장 가능성 있게 보는 조합은 local LLM harness + exact transition memory + 검증 가능한 executable hypothesis + disagreement-driven exploration + shortest-path replay입니다. Learned action prior나 neural transition model도 이 구조 안에 들어갈 수 있습니다. 다만 환경에서 이미 정확히 확인한 사실까지 neural model의 불완전한 기억에 맡길 이유는 없습니다.
7월 23일 기준 Kaggle leaderboard는 여전히 2% 아래인데, 공개 game은 더 큰 model과 더 많은 compute를 사용해 훨씬 높은 비율로 풀리고 있습니다. 이 간격은 변명해야 할 이상 현상이 아니라 이 대회의 연구 문제 그 자체입니다. 제한된 action과 compute 안에서, 처음 보는 세계를 상대로 과학자처럼 가설을 세우고 검증하는 과정을 어떻게 self-contained agent 안에 압축할 것인가?
이 대회의 질문은 “어떤 trick이 지금 leaderboard를 조금 올리는가”가 아닙니다. 더 근본적으로는:
처음 보는 작은 세계 안에서, 시스템이 어떻게 실험하고, 기억하고, 모델을 만들고, 목표를 세우고, 계획하는가?
그 질문이 좋아서 이 문제를 붙잡고 있습니다. 구축 과정도 계속 정리해 볼 생각입니다.
Resources
- ARC Prize 2026 - ARC-AGI-3 on Kaggle
- What is ARC-AGI?
- ARC-AGI-1
- ARC-AGI-2 dataset repository
- OpenAI o3 ARC-AGI-1 report
- ARC Prize 2025 technical report
- ARC-AGI-3 information page
- Official ARC-AGI-3 competition page
- ARC Prize 2026 overview and key dates
- ARC-AGI-3 technical report
- ARC-AGI-3 docs, especially Games, Actions, Scoring methodology, Local vs Online, and Scorecards
- ARC-AGI-3 Kaggle Starter
- ARC Prize 2026 Milestone #1 공식 결과
- Tufa Labs의 Duck harness 설명과 공개 코드
- 공식 Kaggle GPT-OSS-120B template
- Executable World Models for ARC-AGI-3과 후속 ablation 연구
- Schema harness 보고와 공개 trace dataset
- 공식 GPT-5.6 ARC-AGI-3 결과
- ARC-AGI-3 Preview: 30-Day Learnings
- StochasticGoose preview solution
- ARC-AGI Community Leaderboard
- 초심자용 보조 자료: DataCamp ARC-AGI-3 overview, Mark Barney ARC-AGI-3 explainer, TokenCost evaluation-cost writeup
- Community tooling과 game guide는 빠르게 바뀌므로, historical leaderboard tracker, simplified submission notebook, offline recording viewer, game mechanic wiki는 Kaggle discussion forum에서 최신 링크를 확인하는 편이 안전합니다.