Skip to main content
Overview

마인크래프트 사회 시뮬레이션 재시작

May 27, 2026
8 min read
  • Repository

  • Documentation

  • 기억으로는 2023년쯤 시작한 것 같았는데, git 기록으로는 2024년 5월 22일에 첫 커밋이 남아 있었다.

  • 그때의 프로젝트는 Voyager를 거의 기준점으로 삼았고, 지금의 프로젝트는 Voyager를 참고하되 그대로 되살리지 않는 쪽에 가깝다.

  • 2026년에 다시 잡은 데에는 모델 비용도 있지만, 더 큰 이유는 더 많은 맥락과 권한을 받은 모델의 판단을 실행 기록으로 검증하는 구조를 만들고 싶어졌기 때문이다.

  • 지금 목표는 집짓기 진행기가 아니라, 한 actor가 기억과 목표를 가지고 행동을 고르고, 그 결과를 확인한 뒤 다음 cycle로 넘기는 일이다.


오랫동안 멈춰 있던 minecraft-llm-agent-community를 다시 보고 있다. 정확히 언제 처음 시작했는지는 기억이 좀 흐릿했는데, 레포를 뒤져보니 첫 커밋은 2024년 5월 22일이었다. 기억 속에서는 2023년 말이나 2024년 초쯤으로 뭉개져 있었는데, 실제로는 2024년 5월 말에 꽤 몰아서 작업했다.

당시 README에는 “2024년 6월 18일 이후 다시 재개” 같은 문장이 남아 있었다. 결국 그 문장은 오래 지켜지지 않았다. 할 마음은 있었고, 그림도 컸다. Minecraft 세계에서 여러 agent가 자율적으로 그룹을 만들고, 마을을 이루고, 협력과 공존과 생존 문제를 어떻게 푸는지 보고 싶었다. 지금 봐도 방향 자체는 별로 바뀌지 않았다.

바뀐 것은 접근 방식이다.

처음의 모양

2024년 프로젝트는 거의 Voyager 복제에서 출발했다. README의 완료 항목도 “Voyager baseline으로 기본 환경 구성”, “Voyager baseline으로 single agent 만들기”, “Voyager 분석과 architecture image 작성” 같은 식이었다. 문서에도 Voyager의 learn() 루프를 다시 쓴 의사 코드가 있고, 한 cycle에 모델 호출이 순차적으로 다섯 번 들어간다는 식의 분석이 남아 있다.

그 시점에는 이게 자연스러웠다. Minecraft에서 대규모 언어 모델 agent를 만들겠다고 하면 가장 먼저 떠오르는 참조가 Voyager였고, 나도 그걸 기준으로 skill library와 curriculum, critic, action generation을 생각했다. 멀티 actor 사회를 만들려면 먼저 Voyager식 single actor를 잡고, 그 위에 여러 bot을 올리면 된다고 생각했던 것 같다.

그런데 실제로는 그 전 단계에서 시간을 많이 썼다. Mineflayer와 Minecraft server 사이의 통신, Fabric server 설치, plugin import, physics tick, bot이 말이 너무 많아지는 문제, bot이 server에서 kick되는 문제 같은 것들이 계속 나왔다. git log에도 mineflayer-hawkeyes를 못 불러오는 문제, bot이 너무 많이 말하는 문제, server에서 kick되는 것을 막기 위해 operator 권한을 주는 작업이 남아 있다.

이런 문제는 해결하면 되는 종류의 문제이긴 하다. 다만 그때의 나는 core loop를 붙잡기보다 환경을 계속 고치고 있었다. 그리고 솔직히 게을렀다. 통신 오류 하나를 제대로 재현하고 줄여서 격리할 만큼 끈질기게 파고들지 못했다. 그렇게 프로젝트는 멈췄다.

2025년 1월에도 한 번 더 손댄 흔적이 있다. 로컬에서 돌게 고치고, mock response를 붙이고, Mineflayer bridge server가 여러 bot을 받도록 바꾸는 작업이 있었다. 그런데 이때도 여전히 Voyager의 Python 구조와 JavaScript bridge server 사이를 오가는 형태였다. 내 쪽의 문제인지, 구조의 문제인지 잘라 말하기는 어렵지만, 그 상태로 사회 시뮬레이션을 쌓기에는 너무 많은 층이 불안정했다.

재시작의 이유

2026년에 다시 잡은 데에는 모델 비용도 있다. 2024년에는 이런 프로젝트를 계속 돌리려면 비용 걱정이 꽤 컸다. 지금은 Gemini 쪽에 명시적인 무료 티어가 있고, OpenAI 쪽도 완전한 의미의 무료 티어라고 부르기는 애매하지만 무료 실험 요청, 계정별 한도, 저렴한 모델, 크레딧 기반 경로가 있다. 적어도 짧은 실제 실행을 자주 돌리면서 실행 쪽 코드를 고치는 실험은 훨씬 현실적이다.

하지만 모델 성능이나 비용만으로 다시 시작한 것은 아니다. 그 사이에 memory system, agent runtime, tool boundary에 대한 논의가 많이 늘었다. 나도 Codex나 Claude Code를 오래 쓰면서 조금 생각이 바뀌었다. 모델에게 더 긴 prompt를 주거나 더 똑똑한 모델을 붙이면 agent가 되는 것이 아니라, 모델이 틀렸을 때 무엇이 사실인지 남겨주는 환경이 먼저 있어야 했다.

Minecraft에서는 이 차이가 더 크게 보인다. bot이 조금 움직였다고 해서 목적을 달성한 것이 아니다. “나무를 캤다”는 문장은 증거가 아니다. inventory가 늘었는지, 어떤 block을 dig 했는지, 떨어진 item을 실제로 주웠는지, chest ledger가 바뀌었는지, chat이 전달됐는지 같은 실행 기록이 있어야 한다.

예전 프로젝트가 “Voyager를 돌려서 배우게 만들자”에 가까웠다면, 지금 프로젝트는 “actor가 행동을 제안하면 실행 쪽에서 할 수 있는지 확인하고, 실패 이유까지 다음 cycle의 재료로 남기자”에 가깝다.

권한과 검증

정확히는 Minecraft에서 집을 잘 짓는 bot을 만들고 싶은 것만은 아니다. 내가 관심 있는 것은 우리가 코딩 도구로 대규모 언어 모델을 쓰는 방식과 비슷하다. 모델에게 레포 맥락을 주고, 파일을 고치게 하고, 터미널과 테스트를 만지게 한다. 예전보다 더 많은 권한과 더 많은 맥락을 주고, 어느 정도는 스스로 판단하게 둔다.

그런데 코딩에서도 모델의 말 자체를 믿지는 않는다. 믿을 수 있는 것은 diff, type check, test, 실제 실행 결과다. 모델이 “고쳤다”고 말해도 빌드가 깨지면 고친 것이 아니다. 반대로 설명이 조금 어설퍼도 테스트가 통과하고 diff가 납득되면 다음 판단의 재료로 쓸 수 있다.

이 프로젝트에서 Minecraft는 그런 문제를 보기 좋은 환경이다. world state가 있고, inventory가 있고, block과 item과 chat이 있다. 모델이 더 많은 맥락을 보고 더 넓은 행동 권한을 가지게 할수록, 그 판단을 검증 가능한 단위로 쪼개는 일이 중요해진다. 그래서 사회, action skill, 가능한 행동 목록, memory system 같은 것을 계속 정의하려고 한다. 멋진 설정을 붙이려는 것이 아니라, 모델이 스스로 판단할 수 있는 범위를 넓히되 그 판단이 반복해서 확인되게 만들고 싶기 때문이다.

memory도 같은 이유로 중요하다. 단순히 “이전에 이런 일이 있었다”는 일기를 쌓는 것이 목적은 아니다. 어떤 관찰이 다음 판단에 들어가도 되는지, 어떤 실행 결과를 근거로 기억을 써야 하는지, 실패한 판단을 다음 시도에서 어떻게 줄일지 정해야 한다. 그래야 actor가 길게 살아가는 것처럼 보일 때도, 실제로는 검증 가능한 작은 cycle들이 이어져 있는지 볼 수 있다.

Voyager와의 거리

Voyager는 여전히 중요한 참조다. automatic curriculum, executable skill library, environment feedback, self-verification 같은 아이디어는 지금도 유용하다. 다만 지금 레포의 문서에는 Voyager를 다시 살리지 말라는 문장이 반복해서 나온다. 조금 과하게 보일 수도 있는데, 일부러 그렇게 적어둔 것이다.

Voyager식 전역 skill library를 그대로 가져오면 이 프로젝트가 하고 싶은 사회 시뮬레이션과 충돌한다. 여기서는 skill이 actor에게 귀속되어야 한다. actor별 작업 공간에는 그 actor가 현재 할 수 있는 행동, 그 행동이 실제로 확인된 근거, 아직 후보인 행동이 정식으로 쓸 수 있는 행동이 됐는지 남아야 한다. skill은 “레포 어디엔가 있는 JavaScript 함수”가 아니라, 그 actor가 현재 소유한 몸의 일부에 가까워야 한다.

다른 참조들도 비슷하게 다룬다. Generative Agents에서는 observation, memory, reflection, planning의 조합을 가져오되, reflection text를 Minecraft progress로 취급하지 않는다. SayCan이나 SWE-agent 쪽에서는 action interface가 agent 성능을 크게 바꾼다는 감각을 가져온다. 최근에 정리한 Hermes memory system 자료에서는 memory를 일기처럼 쌓는 것이 아니라, 언제 쓸 수 있고 어떤 실행 기록을 가리키는지 함께 남기는 입출력 계약으로 봐야 한다는 점을 가져왔다.

참조는 제품 명세가 아니다. 참조에서 mechanism만 떼어와서 이 프로젝트의 목표에 맞게 다시 번역해야 한다. 이 규칙을 문서에 계속 적어두는 이유는, 그렇지 않으면 금방 “논문 따라 하기”가 되기 때문이다.

현재 루프

현재 구현의 중심은 social-cycle runtime이다. 이름은 거창하지만, 지금은 한 번의 행동 주기를 관리하는 작은 루프다.

ActorSoul과 LifeGoal이라는 내부 이름이 있다. 이름은 좀 과하지만, 역할은 단순하다. actor가 어떤 존재로 살 것인지, 무엇을 오래 중요하게 여길 것인지에 대한 지속 맥락을 들고 있는 기록이다.

거기에 최근 관찰, 기억, 관계 정보, 지금 가능한 행동 목록이 붙는다. provider라고 부르는 모델 호출은 이번 cycle의 작은 목표와 행동 후보를 낸다. 실행 쪽 코드는 그 행동에 필요한 인자가 있는지, 같은 실패를 반복하는지, 실제로 허용된 행동인지 확인한다. 그다음에야 Mineflayer가 Minecraft client로 움직인다. 실행이 끝나면 verifier가 inventory, block, chest, chat 같은 변화를 보고 결과를 남긴다. 그 결과와 판단이 다음 cycle로 넘어간다.

중요한 분리는 간단하다. 모델은 제안한다. 실행 쪽 코드는 가능한 행동인지 검사한다. Mineflayer는 세계를 읽고 바꾼다. 성공 주장은 모델의 문장이 아니라 실제 실행 기록이 가진다.

이 구조 때문에 현재 레포에는 꽤 건조한 장치들이 많다. 예를 들어 모델이 “동쪽으로 이동한다”라고 이유만 쓰고 실제 좌표나 제한된 탐색 방향을 주지 않으면 실행하지 않는다. 같은 행동이 같은 이유로 반복 실패하면 다음에는 Minecraft 호출 전에 막는다. 기억은 다음 판단에 영향을 줄 수 있지만, 물리적으로 무언가가 진행됐다는 증거가 되지는 못한다.

이런 것들은 화려한 기능은 아니다. 하지만 내가 2024년에 못 했던 디버깅을 가능하게 하는 층이다. 실패했을 때 “모델이 멍청했다”로 끝나는 것이 아니라, 모델이 이상한 행동을 골랐는지, 실행 전 검사가 빠졌는지, Mineflayer 실행이 실패했는지, 결과 확인 코드가 과하게 해석했는지를 나눠 볼 수 있다.

집이라는 목표

요즘 붙잡고 있는 목표는 “스스로 보금자리를 만들자”에 가깝다. 말만 보면 집짓기 agent처럼 들린다. 실제로 buildBasicShelter라는 행동도 있다. 하지만 이 목표는 최종 제품이라기보다 넓은 구조를 시험하기 위한 사례에 가깝다.

최근에는 집을 짓는 데 필요해 보이는 작은 행동들을 하나씩 실제로 실행해 보는 확인 작업을 했다. 작업대 놓기, 조약돌 캐기, 간단한 shelter 만들기, 공동 chest 쓰기처럼 지금 코드가 제공하는 행동 14개를 각각 테스트했고, 14개 모두에서 실행 결과를 확인했다. 여기서 확인했다는 말은 모델이 성공했다고 쓴 문장이 아니라, inventory나 block 상태 같은 실행 기록이 예상대로 바뀌었다는 뜻이다.

그런데 이걸 프로젝트 정체성으로 삼으면 금방 잘못 간다. 집, base, shelter, storage는 actor가 어떤 상황에서 신경 쓸 수 있는 소재일 뿐이다. 이 목표를 잡으면 나무 캐기, 판자와 막대 제작, crafting table 배치, cobblestone 채굴, shared chest 보관, 다른 actor에게 요청하거나 알려주는 행동이 한 번에 걸린다. 그래서 좋은 테스트 사례다. 기억, 가능한 행동 목록, 실행 전 검사, 실제 실행, 결과 확인, 다른 actor와의 관계가 한꺼번에 걸린다.

하지만 그 목표가 runtime architecture가 되면 안 된다. 그래서 문서에는 계속 “house-building architecture가 아니다”라고 적혀 있다. 지금 필요한 것은 집짓기 전용 planner가 아니라, actor가 현재 관찰한 세계와 기억과 관계와 몸을 바탕으로 작은 행동을 고르고, 그 행동을 확인 가능한 방식으로 실행하는 바닥층이다. 이 바닥층이 충분히 일반적이면 집짓기 다음에 농사, 거래, 공동 창고, 갈등 같은 쪽으로도 확장할 수 있다.

이 관점에서는 행동 14개가 테스트를 통과한 것도 자랑거리가 아니라 하한선에 가깝다. 조건을 미리 맞춘 작은 테스트 환경에서 각 행동이 따로 성공했다는 뜻이다. 좋은 소식이지만, 사회 시뮬레이션이 됐다는 뜻은 아니다.

또 100번의 행동 주기를 요청한 긴 실행도 54번째에서 파일 권한 문제로 멈췄다. 성공담이라고 보기는 어렵다. 그래도 어디서 멈췄는지, 어떤 기억과 이전 판단이 다음 맥락에 들어갔는지, 큰 목표를 실제 확인 없이 완료라고 주장하지 않았는지 확인할 수 있었다.

아직 작은 것

지금 구현은 아직 한 actor 중심이다. 여러 actor가 각자의 장기 목표와 기억을 가지고 오래 상호작용하는 수준은 아니다. 다른 actor에게 다가가기, 요청하기, 알리기, 건네주기, 기다리기 같은 사회적 행동도 아직 작은 조각이다. 적대 상황과 더 복잡한 관계 변화는 대부분 planned 상태다.

그래도 이번에는 예전처럼 큰 그림부터 세우고 bridge server가 흔들리는 상태로 올라가고 싶지는 않다. core loop는 작아도 end to end로 돌아야 한다. 관찰이 들어오고, 가능한 행동 목록이 보이고, 모델이 작은 행동을 제안하고, 실행 쪽 코드가 막거나 실행하고, Mineflayer 결과가 기록으로 남고, 기억과 판단이 다음 cycle에 들어가야 한다.

이 루프가 안정되면 그다음에 여러 actor를 늘려도 된다. 반대로 이 루프가 불안정하면 actor를 열 명으로 늘려도 그건 사회 시뮬레이션이 아니라 로그가 많은 실패일 가능성이 높다.

처음 꿈은 그대로 남아 있다. 다만 이번에는 꿈보다 먼저 증거를 쌓으려고 한다.

참고

Loading comments...