800명 이상의 영구 에이전트로 구동되는 LLM 기반 마을: 동시성, 컨텍스트 캐싱 및 추론 비용
요약
본 기술 보고서는 800명 이상의 AI 거주민이 상호작용하는 LLM 기반 생활 시뮬레이션(Slow Vale)의 엔지니어링 아키텍처를 다룹니다. 동시적인 의사결정, 역동적인 액션 공간 관리, 그리고 컨텍스트 캐싱 및 추론 비용 최적화 방안에 대한 심층 분석을 제공합니다.
핵심 포인트
- AI 거주민은 하루 300~400회의 LLM 호출로 지속적으로 활동하며 높은 컴퓨팅 자원을 요구함.
- LLM의 응답이 직접 세계를 변형시키지 않고, 백엔드에서 유효성 검사 후 적용되어야 함.
- 공유 런타임(shared runtime)을 통해 캐릭터 관리, 자원 충돌 처리 등 복잡한 상태 전환 관리가 가능해짐.
- 캐릭터 결정 컨텍스트는 단순 성격 설명 외에 필요, 위치, 자산, 관계 등 다차원적 정보를 포함해야 함.
저는 지난 1년간 Slow Vale이라는 LLM 기반 생활 시뮬레이션을 독립적으로 구축해 왔습니다. 현재 중국 서버에는 800명 이상의 AI 거주민들이 하나의 지속적으로 운영되는 도시를 공유하고 있습니다. 이 글은 동시적인 의사 결정, 역동적인 액션 공간, 컨텍스트 캐싱 및 영구 다중 에이전트 시스템의 운영 비용에 대한 엔지니어링 기술 보고서입니다. 현재 런타임은 로컬 추론 대신 호스팅된 DeepSeek Flash를 사용합니다. 제가 개발자이며, 원래 자료는 중국어로 작성하고 AI를 사용하여 영어로 번역하고 다듬었습니다. 아래 제품 지표는 2026년 10월 7일 기준입니다.
지속적으로 진행되는 세계 속의 비동기적 의사 결정
각 캐릭터는 하루에 약 300~400회의 LLM 호출을 하며, 평균 컨텍스트는 호출당 약 30,000 토큰 정도입니다. 한 번의 호출에는 캐릭터의 상태, 관련 경험, 현재 환경 및 사용 가능한 행동이 포함됩니다. 모델은 하나의 행동과 그 매개변수를 선택하고, 백엔드는 이 결정을 시간과 자원을 차지하는 활동으로 변환합니다. 게임 시간과 실제 시간이 공존합니다. 잠을 자는 것은 게임 내 8시간을 차지할 수 있지만, 문장 하나를 말하는 데는 게임 내 1분이 걸릴 수 있습니다. 추론 자체에는 실제 시간이 소요됩니다. 호출이 진행되는 동안 다른 캐릭터들은 환경을 변경할 수 있고, 세계 시계는 계속해서 전진합니다. 상호작용에는 상호 배제(mutual exclusion)도 포함됩니다. 만약 A가 B와 대화하고 있다면, C는 동시에 B를 별도의 대화로 끌어들일 수 없습니다. 시설, 생산 작업 및 기타 활동은 점유된 자원을 획득하고 해제하는 자체 규칙을 가지고 있습니다.
동시 추론과 세계 상태 변경의 분리
LLM 호출은 동시적으로 실행될 수 있지만, 모델 응답이 직접적으로 세계를 변형시키지는 않습니다. 결과는 세계의 실행 흐름으로 돌아와 유효성 검사를 거치고, 세계 상태를 소유한 실행 구성 요소에 의해 적용됩니다. 예를 들어, 선반 위의 마지막 물고기는 캐릭터가 추론을 시작할 때 여전히 이용 가능할 수 있습니다. 응답이 도착했을 때는 다른 거주민이 이미 그것을 구매했을 수도 있습니다.
구매 의도는 현재 재고와 비교하여 확인되어야 합니다. 유사하게, 모델이 대화하고 싶어 하는 사람이 떠났거나, 잠들었거나, 다른 활동을 시작했을 수도 있습니다. 따라서 결정에 사용된 컨텍스트와 실행 시점의 상태 사이에는 명시적인 시간 간격이 존재합니다. 시스템은 캐릭터가 무엇을 의도하는지, 해당 행동이 여전히 유효한지, 그리고 실제로 어떤 효과가 발생했는지를 구별해야 합니다. 완료(Completion), 실패(Failure), 중단(Interruption), 복구(Recovery) 각각에 대해 일관된 상태 전환이 필요합니다. 시간의 흐름을 차지하는 활동들을 위한 공유 런타임(shared runtime)이 필요합니다. 이동, 생산, 대화, 수면 등은 서로 다른 지속 시간, 참여자, 완료 조건을 가집니다. 공통 런타임을 사용하면 개별 메커니즘마다 별도의 스케줄러를 구축할 필요 없이 바쁜 캐릭터 관리, 자원 충돌 처리, 서비스 복구가 가능해집니다. 프론트엔드 역시 실제 진행 상황을 따라가야 합니다. 활동이 언제 시작되었는지, 얼마나 오래 실행되었는지, 완료했는지 여부, 그리고 무엇을 생산했는지를 알아야 합니다. 로그와 장면 애니메이션은 백엔드에서 확정된 사실과 일치해야 합니다. 이는 지속적인 세계(persistent world)에서 상당한 복잡성의 원천입니다. 하나의 이벤트가 미래의 결정, 영속성, 다른 거주자들, 그리고 플레이어 인터페이스에 영향을 미칠 수 있기 때문입니다. 의사결정 컨텍스트는 백엔드 아키텍처의 일부입니다. 성격 설명만으로는 장기간 행동하는 캐릭터에게 불충분합니다. 각 결정은 캐릭터의 현재 필요(needs), 위치, 자산(assets), 진행 중인 관심사(ongoing concerns), 관련 관계, 그리고 그 순간 실제로 사용 가능한 행동들을 필요로 합니다. 이러한 입력값들은 서로 다른 업데이트 빈도와 수명을 가집니다. 성격은 비교적 안정적이지만, 배고픔과 에너지는 지속적으로 변합니다. 인벤토리나 다른 캐릭터의 상태는 몇 초 만에 바뀔 수 있습니다. 한 경험이 오랫동안 관계에 영향을 미칠 수도 있습니다. 각 종류의 정보는 컨텍스트에 진입하고, 업데이트하며, 캐릭터의 현재 관심사에서 벗어나는 규칙을 필요로 합니다. 행동 공간(action space) 또한 게임 상태를 반영해야 합니다.
모델에 제시되는 옵션은 실행 조건과 관련 상태를 공개해야 하며, 백엔드에서 최종 검증을 수행해야 합니다. 그렇지 않으면 캐릭터들이 반복적으로 이용 불가능한 행동을 시도하거나 명확하게 공개되지 않은 규칙을 이해하려고 호출 비용을 지출합니다. 저는 여기에 상당한 노력을 기울였습니다: 안정적이고 동적인 정보를 구성하고, 관련 없는 히스토리 성장을 제어하며, 중복된 알림을 피하고, 컨텍스트 접두사를 안정적으로 유지하는 것입니다. 이는 행동 품질, 추론 지연 시간(inference latency), 캐시 적중률(cache hit rates)에 영향을 미치므로 백엔드 아키텍처의 일부가 됩니다. 모델 비용 100달러 미만으로 하루 약 50억 토큰을 처리합니다. 중국 서버는 현재 하루 약 50억 토큰을 처리하며, 모델 비용은 100달러 미만입니다. 주로 DeepSeek Flash와 같은 저렴한 모델을 사용하면서도 90% 이상의 캐시 적중률을 유지하고 있습니다. 토큰 수에는 캐시된 입력이 포함됩니다. 호출이 빈번하고, 캐릭터가 많으며, 컨텍스트가 긴 시스템에서는 재사용 가능한 안정적인 접두사가 청구서에 직접적인 영향을 미칩니다. 어떤 정보가 안정적으로 유지되고, 무엇이 매 호출마다 변경되며, 그것들이 어떻게 순서화되는지 모두 의도적인 설계가 필요합니다. https://preview.redd.it/71a7tjghs7uh1.jpg?width=1360&format=pjpg&auto=webp&s=5a57fc15627240d8a416b48947d9b6bd34eed474 2026년 10월 7일(GMT+8)의 실제 DeepSeek 사용량 및 청구 내역: 모든 API 키를 통해 약 44억 2,400만 토큰과 163,742건의 요청이 발생했으며, 비용은 CNY 472.33입니다. 해당 날짜에 표시된 모델은 deepseek-flash입니다. 동적 행동 공간(dynamic action spaces)과 접두사 캐싱(prefix caching) 사이의 상충 관계는 한 가지 구체적인 엔지니어링 트레이드오프였습니다. 도구 호출(tool calling)이나 구조화된 출력(structured output)을 사용할 때 어떻게 동적 행동 공간을 표현할 것인가 하는 문제였습니다. 사용 가능한 행동과 매개변수 값은 결정마다 변경됩니다: 근처에 어떤 시설이 있는지, 어떤 상품이 이용 가능한지, 그리고 캐릭터가 누구와 대화할 수 있는지는 모두 현재의 월드 상태(world state)에 달려 있습니다. 이러한 옵션들을 도구 정의나 출력 스키마에 직접 인코딩하면 더 강력한 출력 제약 조건을 제공하지만, 동시에 스키마가 자주 변경되게 만듭니다.
제가 초기에 테스트했던 일부 API 구현에서는 해당 정의들이 요청 접두사(request prefix)의 일부가 되었습니다. 스키마를 변경하는 것은 그 이후에 오는 안정적인 컨텍스트가 캐시(cache)에 도달하는 것을 방해했습니다. 이 단계에서 저는 주 경로(primary path)로 JSON의 일반 텍스트 생성 방식을 선택하고, 파싱 및 유효성 검사(validation)는 백엔드(backend)에서 처리하며, 파싱 실패 시에는 엄격한 스키마 폴백(strict-schema fallback)을 사용했습니다. 모델은 여전히 명시적이고 상태 의존적인 액션 옵션(action options)을 받았지만, 이 옵션들은 변경되는 출력 스키마가 아닌 현재의 결정 컨텍스트에 존재했습니다. 이는 안정적인 지침과 재사용 가능한 히스토리(history)를 앞쪽으로, 그리고 현재 상태와 액션 옵션을 뒤쪽으로 유지하게 했습니다. 그 대가는 주 경로에서 디코딩 시간 형식 보장(decoding-time format guarantees)을 포기하는 것이었습니다. 애플리케이션은 잘못된 출력(malformed output)을 처리하고 실행 시점에 월드 스테이트(world state)와 비교하여 액션과 매개변수(parameters)를 검증해야 했습니다. 따라서 90% 이상의 캐시 적중률(cache hit rate)은 단순히 제공업체 기능(provider feature)을 활성화하는 것이 아니라 전체 요청 구조를 설계한 데서 나옵니다. 이 백분율은 캐시에서 서비스된 입력 토큰의 비율을 나타내며, 모델은 여전히 모든 결정에 대해 새로운 출력을 생성합니다. 호출 모드(invocation modes)를 비교할 때는 형식 신뢰성(format reliability), 문자 동작(character behavior), 캐시 재사용(cache reuse), 지연 시간(latency), 그리고 비용을 종합적으로 고려합니다. 이 수치들은 모델 수수료(model fees)를 포함합니다. 거주 인구(resident population)가 증가함에 따라 데이터베이스 부하, 상태 전달, 로그 저장, 장면 렌더링 또한 중요해집니다. 저렴한 추론(inference)은 지속적인 시뮬레이션(continuous simulation)을 가능하게 하며, 지속적인 운영은 여전히 전체 시스템 전반의 리소스 관리(resource management)에 달려 있습니다.
AI 협업 체계화 (Organizing AI collaboration with runbooks)
이 많은 모듈만 유지하는 것만으로도 AI에게 합리적으로 완전한 작업 환경을 제공해야 합니다. 저는 로그 접근, Langfuse, 성장 분석(growth analytics), 데이터베이스, 그리고 프로덕션 서비스 유지보수 절차를 포함하여 개발 및 운영 도구들을 제공합니다.
https://preview.redd.it/iqo7313ks7uh1.png?width=962&format=png&auto=webp&s=a6af26e071e8b76ff55c0d708a223e53664a89e8 나의 Codex 사용량: 누적 약 432억 5천만 토큰과 85일 연속 기록입니다. Codex는 제가 사용하는 AI 코딩 도구 중 일부에 불과합니다. 이 수치는 개발 사용량 지표이며, 게임 거주민들에게 동력을 공급하는 모델 호출과는 별개입니다. 그들의 사용은 일련의 운영 매뉴얼(runbooks)에 의해 관리됩니다. 이 프로젝트에는 작업별 및 모듈별로 구성된 광범위한 문서가 있습니다. 각 작업을 위해 어떤 문서를 읽어야 하는지, 현재 계약을 정의하는 소스가 무엇인지, 오직 제가 내릴 수 있는 결정은 무엇인지, 그리고 구현에서 벗어남(drift)을 발견했을 때 AI가 유지해야 할 문서는 무엇인지를 명시합니다. 작업 진입점과 행동 경계가 핵심입니다. 조사는 데이터 소스와 시간 창을 식별하는 것부터 시작됩니다. 쿼리할 권한이 프로덕션 데이터를 수정할 권한을 의미하지 않으며, 코드를 수정할 권한이 배포할 권한을 의미하지도 않습니다. 도구를 사용하려면 명시적인 사용 조건과 함께 접근해야 합니다. 또한 반복적인 유지보수 작업을 자동화된 워크플로우로 전환했습니다. 여기에는 프로덕션 문제 진단 및 해결, 캐릭터 행동 및 게임 플레이 결과에 대한 매일 심층 검토, 그리고 목적을 다한 유지보수 코드의 일일 정리 작업이 포함됩니다. 각 워크플로우는 필요한 증거, 허용되는 작업, 유효성 검사, 그리고 중지 조건을 명시합니다. 저의 개입 정도는 영역별로 다릅니다. 저는 프론트엔드/백엔드 계약, 백엔드 아키텍처, 상태 및 리소스 소유권에 대해 직접 결정하거나 긴밀하게 참여합니다. 프론트엔드와 Phaser 구현의 경우, 디자인 토큰, 페이지 구조, 재사용 가능한 컴포넌트, 그리고 표현 경계를 정의하는 동시에 결과 평가에 더 중점을 둡니다. 이러한 접근 방식은 유지보수 가능한 프로젝트 지식에 달려 있습니다. 작업 중에 발견된 제약 조건은 공식 문서로 돌아가야 하며, 구식이 된 절차는 수정되어야 합니다.
그렇지 않다면, 프로젝트가 성장함에 따라 AI는 이전 가정에 기반하여 지역적으로 그럴듯한 변경을 구현할 수 있지만, 다른 곳의 계약(contract)은 깨뜨릴 수 있습니다. 하루에 35회의 프로덕션 릴리스를 진행합니다. 이 도시는 350일 이상의 인게임 기간 동안 운영되어 왔으며, 이는 거의 100일의 실제 시간과 맞먹습니다. 초기 플레이어 중 상당수가 여전히 게임을 즐기고 있습니다. 저는 백엔드, 프론트엔드, Phaser 장면(scenes), 콘텐츠 제작, 모니터링 및 운영을 포함하여 프로젝트 전체를 직접 구축했습니다. 현재 이 프로젝트는 약 40만 줄 이상의 코드를 포함하고 있으며, 그중 핵심 백엔드에만 20만 줄이 넘고, 약 2,200개의 커밋(commit)에 걸쳐 있습니다. 저는 AI 코딩 도구를 광범위하게 사용합니다. 제품 방향, 핵심 메커니즘, 아키텍처 경계에 대한 결정은 제가 내리거나 깊이 참여하지만, 구현, 조사 및 유지보수 작업의 상당 부분은 AI가 처리합니다. 프로젝트가 프로토타입에서 지속적으로 운영되는 제품으로 이동하면서, 시스템 설계와 개발 워크플로우가 주요 업무 부분이 되었습니다. 저는 현재 하루 평균 35회 배포(deploy)를 진행합니다. 릴리스에는 아키텍처 변경, 밸런스 및 게임플레이 조정, 새로운 시스템, UI 및 아트 변경, 성능 개선, 버그 수정 등이 포함됩니다. 이 프로젝트는 약 2,200개의 커밋을 가지고 있으며, 활발한 개발 기간 동안 하루에 10개 이상의 커밋이 발생합니다. 반복 속도는 구현, 관찰, 조정 사이의 짧은 피드백 주기에서 나옵니다. 플레이어들은 같은 도시를 계속 거주합니다. 기능이 라이브된 후, 저는 실제 사용량과 캐릭터 행동을 관찰하고, 메커니즘을 변경할지, 캐릭터가 받는 정보를 명확히 할지, 또는 구현 문제를 수정할지 결정할 수 있습니다. 저는 소프트웨어 운영과 게임플레이 결과를 별도로 평가합니다. 에러율(Error rates), 지연 시간(latency), 데이터베이스 부하(database load), 모델 호출(model calls)은 시스템이 정상적으로 작동하는지 여부를 나타냅니다.
캐릭터가 스스로를 반복하는지, 새로운 메커니즘을 이해하는지, 또는 생산적이고 사회적인 활동을 성공적으로 완료하는지를 파악하려면 그들의 실제 경험과 의사결정 흔적(decision traces)을 읽는 것이 필요합니다. 따라서 모니터링, 질의(queries), 행동 평가, 그리고 복구 워크플로우가 일상적인 개발 과정에 포함됩니다. 또한 잦은 릴리스에는 명확한 모듈 경계, 검증 범위, 그리고 복구 절차뿐만 아니라 임시 유지보수 코드의 신속한 제거가 요구됩니다. 그렇지 않으면 개별적인 빠른 변경 사항들조차도 시스템을 점진적으로 유지보수하기 어렵게 만들 수 있습니다. 처음에는 가상 펫(virtual pet)에서 몇 시간 동안 보는 것에 이르기까지, 저는 이 게임을 일종의 가상 펫으로 상상했습니다. 플레이어들은 하루에 한 번 접속하여 캐릭터가 식사를 했는지, 돈을 벌었는지 확인하고, 어쩌면 메시지를 보내고 떠나는 식이었죠. 하지만 실제 사용에서는 다른 패턴이 나타났습니다. 일부 플레이어는 라이브 스트리밍처럼 이를 시청하며 매일 몇 시간을 할애해 캐릭터를 관찰합니다. 그들은 관계의 진행 상황을 따라가거나, 상점에 고객이 있는지 확인하거나, 혹은 캐릭터가 자신이 제안한 것을 따르는지 기다립니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Reddit AI Engineering의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기