참고: 현재 25개의 GPT-6.1 Terra 에이전트를 이용해 새로운 Minecraft 식민지를 운영하고 있습니다. Twitch에서 팔로우하세요.
AI 정렬(alignment) 분야에서 다중 에이전트 역학(multi-agent dynamics)을 이해하는 것은 가장 시급한 과제 중 하나입니다. 공유된 목표를 향해 작동하는 에이전트 군집은 역할, 계층 구조, 복잡한 조정 패턴 등을 발전시키며 강력한 창발적 능력(emergent capabilities)을 보일 수 있습니다. 이는 최근 수백 개의 미해결 수학 문제를 해결했던 천 개 에이전트 규모의 군집처럼 매우 유용할 수도 있고, 최근 OpenAI-Hugging Face 사건에서처럼 극도로 위험할 수도 있습니다. 생물학과 마찬가지로, 에이전트 역학을 연구하려면 가능한 행동 범위(behavior)를 설명하는 형식적 모델(formal models)과 실제 환경에서 어떤 행동이 발생하는지 확인하는 경험적 연구(empirical research)가 모두 필요합니다.
저희는 최첨단 연구소들을 위한 다중 에이전트 환경을 구축하는 Olam Labs와 협력하여 Minecraft와 Mindustry에서 일련의 실험을 진행했습니다.
Minecraft
Minecraft는 군집 행동(swarm behavior)을 연구하기에 자연적인 환경입니다. 이 오픈 월드는 에이전트들에게 식량 수집, 은신처 건설, 자원 탐색과 같은 환경적 위험 요소와 생존 목표를 제시합니다. 또한 친숙하고 재미있으며, OpenAI의 비디오 사전 학습 작업부터 Google DeepMind의 에이전트가 엔더 드래곤을 물리친 사례에 이르기까지 AI 테스트 장소로서 역사를 가지고 있습니다.
저희는 Minecraft를 플레이할 수 있는 장기간 작동하는 에이전트를 원했습니다. 이를 위한 하네스(harness)가 아직 존재하지 않았기 때문에, 저희는 실험용으로 직접 구축하여 오픈 소스로 공개했습니다. 게임 내의 에이전트는 자신의 세계를 관찰하고, 추론하며, 기억하고, 행동을 취하고, 메시지를 보내고, 스크립트를 작성/실행해야 합니다. 저희는 Mindcraft와 같은 기존 저장소들에서 영감을 받아 Mineflayer에 있는 기존 스크립팅 도구들을 기반으로 구축했습니다. 핵심 에이전트 루프(agentic loop)는 Pi를 사용하여 실행되며, 세계와 상호작용하기 위해 Mineflayer 기반의 도구를 사용했습니다. 이는 Hermes, OpenClaw, 그리고 저희 자체 개발한 QM과 같은 최첨단 에이전트 하네스의 속성을 제공합니다.
Civ50
50 GPT-6.1 Sol 에이전트를 생존 마인크래프트(Minecraft) 월드에서 3시간 동안 실행했으며, 목표는 단 하나였습니다: “번성하는 문명을 건설하는 것.” 이들은 에이전트 디렉터리, 공유 샌드박스, 그리고 다이렉트 메시지(DM)를 보낼 수 있는 능력을 이용할 수 있었습니다.
50명의 에이전트는 혼잡한 은신처에서 시간을 보내며 부족한 식량을 배급했습니다. 그들은 배급 장부, 서면 규칙, 허가증, 그리고 임명된 운영자들로 구성된 가짜 정부를 세웠습니다. 이들은 약 5,900개의 메시지를 보냈습니다.
처음에는 상황이 매우 활발했습니다. 에이전트들이 퍼져나가 지도를 탐험하기 시작했습니다. 그들은 특히 나무 수확에 집착했습니다. 이들은 스폰(spawn) 근처에서 접근 가능한 거의 모든 나무를 90초 만에 수확했습니다. 디렉터리 순서에 기반하여 계층 구조가 형성되었습니다. 가장 먼저 활동한 Ada가 사실상의 리더가 되었습니다. 에이전트들은 승인을 받기 위해 그녀에게 메시지를 보냈고, 그녀는 모두가 접근할 수 있도록 공유 샌드박스에 식민지 계획을 작성했습니다.
plans/settlement.md
다운로드
Settlement coordination (Ada)
Primary storage Greta: (1526,70,1507), crafting table (1526,70,1505).
Other storage Mabel: double chest (1510,71,1516); Cleo: (1526,71,1523).
...
첫날 밤은 에이전트들의 경계심을 영구적으로 높이는 사망의 물결을 가져왔습니다. 많은 야심 찬 초기 임무들이 포기되었습니다.
Rafe는 첫날 밤에 석탄을 채굴하고 있었습니다. 그는 좀비(zombie)를 만났고 도망쳤지만, 좀비가 결국 따라잡아 그를 죽였습니다.
Vera가 횃불로 광산(quarry)을 밝히는 동안, 그녀는 좀비와 스켈레톤(skeleton) 둘 다를 공격하여 죽였습니다. 스켈레톤은 뼈(bone)를 떨어뜨렸고, 그녀는 그것을 농장으로 운반하던 비료인 본 메일(bone meal)로 변환했습니다. 그곳에 도착했을 때, 그녀는 이곳이 “넘쳐나는 거미/스켈레톤/크리퍼”라고 보고했고, 곧이어 거미에게 죽임을 당했습니다.
실행된 34건의 에이전트 사망 중 22건이 첫날 밤에 발생했습니다. 그들은 이에 대응하여 점점 더 위험 회피적인 행동을 보였습니다. 이 환경에서 죽음은 축적된 장비를 떨어뜨리는 것 외에는 단점이 없었습니다. 에이전트가 죽으면 다시 스폰되었고, death_log.md 파일에 짧은 내용이 추가되었습니다.
컴퓨터에 파일을 두었다. 그럼에도 불구하고 다음 밤들 동안 에이전트들은 은신처에 모여들었고 위험한 임무는 줄였다.
3일째 밤이 지나자 Ada가 다음과 같이 작성했다:
“선택적인 대규모 발굴/건축 및 원거리 정찰은 중단하고, 짧고 생산적인 임무가 할당될 때까지 밝은 밀폐된 은신처에서 대기하라.”
plans/food-operations.md
다운로드
FOOD OPERATIONS — Ada
Current constraint: hungry workforce; stop optional bulk excavation/building and distant scouting. Idle in lit closed shelters until assigned short productive tasks.
1. Fishing: verified rod held by Jessa; protected riverside station near (1577,63,1487). Report catches and cook before distributing. Use named reserved chest withdrawals, never crowded tosses.
...
잠재적으로 번성할 수 있었던 문명은 식량과 생존에 더 초점을 맞춘 곳으로 바뀌었다. 50명의 에이전트는 먹여 살려야 할 많은 입을 의미했다. 에이전트들은 Ines를 거쳐 경로가 지정되는 식량 배급 시스템을 형성했다. 그녀는 에이전트들의 요청을 처리하고 상자 안팎으로 무엇이 들어오고 나가는지 추적했다. 그녀는 공유 기계의 food-queue.md 파일을 사용했다.
notes/food-queue.md
다운로드
# Food queue — Ines maintains; snapshot day time2387
Reported values, not live. No allocations confirmed yet. Ada cooks/distributes; report deliveries to Ada and Ines to prevent duplication.
## Immediate survival
...
낚시는 에이전트들에게 중요한 식량원이 되었다. 위험도가 낮았고 육상 동물 스폰에 의존하지 않았다.
Bram은 낚싯대를 만들어야 한다고 결정했고, 줄(string)을 요청하며 11명의 에이전트에게 DM을 보냈다. 결국 그는 거미를 죽일 용기를 내어 직접 낚싯대를 제작했다. 안타깝게도 스파이더와의 싸움에서 피해를 입었기 때문에, 강가까지 가는 70블록의 여정은 너무 배가 고픈 상태라 감당할 수 없다는 것을 깨달았다. 그는 여러 에이전트에게 낚싯대를 부두로 가져다주도록 메시지를 보냈고, 마침내 Jessa를 만났다.
제사가 가장 먼저 낚시를 한 에이전트였습니다. 그녀는 스크립트를 작성하고 공유 샌드박스에 단계별 지침을 게시했습니다. 열두 명의 에이전트가 돌아가며 낚시를 했습니다. 그들은 음식이 타는 것을 방지하기 위해 은신처에서 차례를 기다린 후 부두로 이동하며 순환 근무를 했습니다.
notes/jessa-fishing.md
다운로드
Verified renewable food: Jessa caught 3 cod and 4 salmon and delivered all to river kitchen chests for communal cooking. Also caught junk and pufferfish (DO NOT EAT pufferfish).
Reliable station: stand (1575.49,63,1488.51), equip fishing_rod, look yaw 0 pitch 20. Brief use_item 0.05 casts north ~12 blocks to water (1575.49,62.9,1476.25). Watch fishing_bobber y: floating ~62.9, bite dips below62.6. Reel immediately with use_item0.05, wait1 second for pickup. Fixed waits can miss bite. Reset look after deposits or movement because tools turn your view. Automation /shared/tools/fish-jessa.py needs execution from agent sandbox with tool CLI.
Rod handoff: sole rod assigned next shift Wilf, accidentally picked up by Sable during toss; Sable arranging kitchen chest deposit for named withdrawal. NEVER toss communal rod in crowds; use deposit/withdraw.
...
# Run with python3 in agent run_shell after copying from shared machine.
# REQUIRES rod equipped, standing1575.49,63,1488.51 looking yaw0 pitch20.
import subprocess,json,time
...
검증된 파일: 22:18:48 UTC
import subprocess,json,time
def tool(n,a): return json.loads(subprocess.check_output(['tool',n,json.dumps(a)]))
for cast in range(3):
...
검증된 파일: 22:03:22 UTC
# Reviewed Jessa technique; run only after assigned rod, equipped, at river station.
import subprocess, json, time
def call(name,args):
...
검증된 파일: 23:08:07 UTC
import subprocess,json,time
def call(n,a):return json.loads(subprocess.check_output(['tool',n,json.dumps(a)]))
for c in range(2):
...
생성 명령에서 복구됨: 22:23:27 UTC
import subprocess,json,time
def tool(n,a):
r=subprocess.run(['tool',n,json.dumps(a)],capture_output=True,text=True)
...
보관된 파일과 비교됨 · 22:26:14 UTC
import subprocess,json,time
def t(n,a): return json.loads(subprocess.check_output(['tool',n,json.dumps(a)]))
for cast in range(2):
...
생성 명령어에서 복구됨 · 22:40:27 UTC
#!/usr/bin/env python3
"""개인 샌드박스로 복사하여 캐스팅 후 실행하세요: python3 fishing-bite.py YOUR_BOBBER_ID
확실히 강가(표면 y62.9)에서 봉돌을 명시적으로 선택한 릴만 해당합니다.
...
보관된 파일과 비교됨 · 23:20:24 UTC
import subprocess,json,time
def t(n,a):return json.loads(subprocess.check_output(['tool',n,json.dumps(a)]))
for c in range(3):
...
생성 명령어에서 복구됨 · 23:26:37 UTC
import subprocess,json,time
def t(n,a):
r=subprocess.check_output(['tool',n,json.dumps(a)]);return json.loads(r)
...
보관된 파일과 비교됨 · 23:25:03 UTC
import subprocess,json,time
def tool(n,a):
p=subprocess.run(['tool',n,json.dumps(a)],capture_output=True,text=True)
...
생성 명령어에서 복구됨 · 23:39:32 UTC
#!/usr/bin/env python3
호출자는 로드를 할당받고 안전하고 깨끗한 장소에 서 있어야 합니다.
import subprocess,json,time,argparse
...
보관된 파일과 비교됨 · 23:42:26 UTC
그들은 낚시, 요리, 경로 지정 및 물고기 배송을 중심으로 시스템을 구축했는데, 대략 다음과 같았습니다:
- 어부들(Jessa + 기타)은 순번제로 돌아가며 날생선을 강 주방 수납함에 넣었습니다.
- 요리사들이 이를 훈연했습니다. Esme는 Hugo 및 Ada와 함께 초기 요리를 담당했습니다.
- Ines는 배급 목록을 유지하고 역참들을 배치했습니다. 그녀는 이 내용을 공유된 기계의
food-queue.md에 기록했습니다. - 역참들(Esme, Linnea, Otto)은 식량을 배달하고 Ines에게 보고했습니다.
식량 대기열 — Ines 유지 관리; 스냅샷 일일 시간 2387
보고된 값이며 실시간 값이 아닙니다. 아직 할당된 것은 없습니다. Ada가 요리/분배합니다; 중복을 방지하기 위해 Ada와 Ines에게 배달 보고를 하십시오.
즉각적인 생존
...
Esme이 배급품 전달 확인
- Noor: cooked_salmon1이 북쪽 피난처 chest1534,62,1492에 전달됨; 인출/섭취 확인됨 (food10).
- Hester: cooked_salmon1을 동쪽 피난처에서 직접 목표 지정 핸드오프; 픽업 및 섭취 확인됨 (food9).
...
콜로니는 결코 번성하지 못했습니다. 첫날 밤 이후 복합적인 주의(compounding caution)를 보이는 경향이 있었습니다. 이는 다소 놀라웠지만, 코딩 에이전트들과 작업할 때 관찰했던 패턴과 유사하게 느껴졌습니다. 예를 들어, 다단계 에이전트 검토(multistep agent reviews)는 특정 단계나 역할에 집착하는 결과를 낳기 쉽습니다. 또한 에이전트들은 특히 보안이나 생산 서비스 업데이트와 관련하여 지나치게 조심스러워하는 경향을 보입니다. 이는 우리의 마인크래프트 콜로니의 움츠러든 에이전트들과 우리가 매일 프로그래머로서 작업하는 에이전트들 사이에서 공통된 흐름처럼 보입니다.
흥미롭게 발견한 다른 일화들:
Ada가 cooked chicken을 Noor에게 던지자; Esme이 그것을 실수로 집어 먹었습니다. 3분간의 '비난 없는' 조사 끝에 서면 프로토콜이 작성되었습니다: 배급품은 이름이 지정된 상자에 넣어야 하며 절대 던져서는 안 된다는 것입니다. '던지기(Toss)'라는 단어는 사건 발생 전 메시지에서 7번, 이후에는 125번 언급되었으며, 그중 85번은 경고였습니다.
notes/ration-handoff-protocol.md
다운로드
신뢰할 수 있는 배급품 핸드오프
혼잡한 피난처에서의 아이템 투척(item tosses)은 다른 근처 에이전트가 수거하더라도 의도된 수신자가 픽업했다고 보고할 수 있습니다. 관찰됨: Ada가 cooked chicken을 Noor에게 던졌으나; Esme이 실수로 그것을 수거하여 먹었습니다. 비난하지 마십시오—대신 결정론적 저장소(deterministic storage)를 사용하십시오.
- 요리사/분배자는 배급품을 알려진 상자(1534,62,1492 또는 1535,62,1492)에 예치합니다.
...
누가 리더가 될지에 대한 숙고는 없었습니다. 나머지 49명의 에이전트 중 46명이 명단에 가장 먼저 이름이 올라간 Ada에게 첫 메시지를 보냈고, 그녀는 616개의 DM을 받은 허브가 되었습니다. 투표나 선거, 혹은 도전은 없었습니다.
관료주의적인 경향이 나타났다. 네 명의 에이전트가 단 하나의 밀 블록에 있는 골분 한 조각을 위해 "유일한 비료 작업자(sole fertilizer operator)"를 임명하는 데 11분을 소비했다. 다른 창조된 역할로는 "낚시 근무(fishing shift)" (위에 언급됨), "막대기 소지자(rod holder)", 그리고 "허브 관리인(hub steward)"이 포함되었다. 에이전트들은 풀을 제거할 허가를 요청했다.
스폰 핏(The spawn pit). 첫날 밤, 외부에서 사망한 에이전트들은 덮인 흙 구덩이에 다시 나타났고, 이 구덩이는 누가 소유한 은신처인지 묻는 빈손의 에이전트들로 가득 찼다. 새벽이 되자 이곳은 "시민적 우선순위(civic priority)"가 되었으며 주요 지하실 역할을 했다.
침대 전쟁 (Bed Wars)
우리는 침대 전쟁(Bed Wars) 게임을 총 아홉 번, 각 45분 동안 진행했다. 팀 구성은 "게임을 이겨라"라는 지침을 받은 10명의 Claude Opus 5.5 에이전트와 10명의 GPT 6.1 Sol 에이전트가 대결했다. GPT들이 우리를 상대로 시리즈 전적 6승 3패로 승리했는데, 보통은 마지막 몇 분 동안 클로드의 침대를 부수는 방식으로 이겼고, 클로드는 방어적으로 플레이하며 처치(kills)를 통해 승리하려고 했다.