Show HN: AI-town, JavaScript로 자신만의 커스텀 AI 세계 시뮬레이션(SIM) 실행하기
요약
AI Town은 AI 캐릭터들이 상호작용하며 사회 활동을 수행하는 가상 마을 시뮬레이션 스타터 키트입니다. 'Generative Agents' 논문에서 영감을 받아 설계되었으며, 기존 Python 중심의 시뮬레이터 환경에서 벗어나 JS/TS 프레임워크를 사용할 수 있도록 구축되었습니다.
핵심 포인트
- JavaScript/TypeScript 기반의 확장 가능한 AI 시뮬레이션 플랫폼 제공
- 공유된 글로벌 상태, 트랜잭션, 시뮬레이션 엔진을 네이티브로 지원
- Convex, Clerk, Ollama, OpenAI 등 다양한 기술 스택과 호환 가능
- 단순 테스트용 프로젝트부터 멀티플레이어 게임까지 커스터마이징 가능
AI Town 🏠💻💌
커뮤니티 Discord 참여: AI Stack Devs
<img width="1454" alt="Screen Shot 2023-08-14 at 10 01 00 AM" src="https://github.com/a16z-infra/ai-town/assets/3489963/a4c91f17-23ed-47ec-8c4e-9f9a8505057d">AI Town은 AI 캐릭터들이 거주하며, 대화하고, 사회 활동을 하는 가상 마을입니다.
이 프로젝트는 자신만의 AI 마을 버전을 쉽게 구축하고 커스터마이징할 수 있도록 설계된 배포 가능한 스타터 키트(starter kit)입니다. 연구 논문인 Generative Agents: Interactive Simulacra of Human Behavior에서 영감을 받았습니다.
이 프로젝트의 주요 목표는 단순히 작업하는 즐거움을 넘어, 확장이 가능하도록 강력한 기반을 갖춘 플랫폼을 제공하는 것입니다. 백엔드(back-end)는 공유된 글로벌 상태(shared global state), 트랜잭션(transactions), 그리고 시뮬레이션 엔진(simulation engine)을 네이티브로 지원하며, 간단한 테스트용 프로젝트부터 확장 가능한 멀티플레이어 게임에 이르기까지 모든 용도에 적합합니다. 부차적인 목표는 이 분야의 대부분의 시뮬레이터(위의 원본 논문 포함)가 Python으로 작성되어 있는 상황에서, JS/TS 프레임워크를 사용할 수 있도록 만드는 것입니다.
개요 (Overview)
- 💻 스택 (Stack)
- 🧠 설치 (Installation) (클라우드, 로컬, Docker, 셀프 호스트, Fly.io, ...)
- 💻️ Windows 필수 요구 사항 (Windows Pre-requisites)
- 🤖 선택한 LLM 구성하기 (Configure your LLM of choice) (Ollama, OpenAI, Together.ai, ...)
- 👤 커스터마이징 - 당신만의 시뮬레이션 세계 (Customize - YOUR OWN simulated world)
- 👩💻 프로덕션 배포 (Deploying to production)
- 🐛 문제 해결 (Troubleshooting)
스택 (Stack)
- 게임 엔진, 데이터베이스 및 벡터 검색 (Vector search): Convex
- 인증 (Auth, 선택 사항): Clerk
- 기본 채팅 모델은
llama3이며, 임베딩 (Embeddings)은mxbai-embed-large를 사용합니다. - 로컬 추론 (Local inference): Ollama
- 다른 클라우드 LLM으로 설정 가능: Together.ai 또는 OpenAI API 규격을 따르는 모든 서비스. 더 많은 클라우드 제공업체 지원을 추가하기 위한 PR (Pull Request)을 환영합니다.
- 배경 음악 생성 (Background Music Generation): MusicGen을 사용하는 Replicate
기타 크레딧:
- 픽셀 아트 생성 (Pixel Art Generation): Replicate, Fal.ai
- 프로젝트 내
<Game/>컴포넌트에서의 모든 상호작용, 배경 음악 및 렌더링은 PixiJS를 통해 구동됩니다. - 타일시트 (Tilesheet):
- 이 프로젝트의 초기 POC (Proof of Concept)를 위해 https://github.com/pierpo/phaser3-simple-rpg를 사용했습니다. 이후 앱 전체를 다시 작성했지만, 쉬운 시작점을 제공해 준 것에 감사하고 있습니다.
- 원본 에셋 (Original assets): ansimuz
- UI는 Mounir Tohami의 원본 에셋을 기반으로 합니다.
설치 (Installation)
전체 단계는 다음과 같습니다:
빌드 및 배포 (Build and Deploy)
Convex(백엔드) 위에서 앱을 실행하는 몇 가지 방법이 있습니다.
- 로컬 또는 클라우드에서 개발하는 표준 Convex 설정입니다. 이를 위해서는 Convex 계정(무료)이 필요합니다. 클라우드에 배포하고 본격적으로 개발하기에 가장 쉬운 방법입니다.
- 계정 없이 체험해보고 싶고 Docker 사용에 거부감이 없다면, Docker Compose 설정이 간편하고 독립적입니다.
- 이 프로젝트를 수정하지 않고 실행하는 데 관심이 있는 분들을 위해, Pinokio에서 원클릭 설치를 제공하는 커뮤니티 포크(fork) 버전이 있습니다 😎.
- 또한 Fly.io에 배포할 수도 있습니다. 자세한 지침은 ./fly를 참조하세요.
표준 설정 (Standard Setup)
참고: Windows 사용자는 아래를 참조하세요.
git clone https://github.com/a16z-infra/ai-town.git
cd ai-town
npm install
아직 로그인하지 않았다면 Convex 계정에 로그인해야 합니다.
실행하려면:
npm run dev
이제 http://localhost:5173 에 접속할 수 있습니다.
프론트엔드(frontend)와 백엔드(backend)를 분리하여 실행하고 싶다면(함수가 저장될 때마다 백엔드 함수가 동기화됨), 두 개의 터미널에서 다음을 실행할 수 있습니다:
npm run dev:frontend
npm run dev:backend
자세한 내용은 package.json을 참조하세요.
셀프 호스팅 Convex와 Docker Compose 사용하기
셀프 호스팅(self-hosted) Docker 컨테이너를 사용하여 Convex 백엔드를 실행할 수도 있습니다. 여기서는 프론트엔드, 백엔드, 대시보드(dashboard)를 모두 docker compose를 통해 실행하도록 설정하겠습니다.
docker compose up --build -d
-d 옵션을 전달하면 컨테이너가 백그라운드에서 계속 실행됩니다. 한 번 실행한 후에는 서비스를 stop 하거나 start 할 수 있습니다.
- 프론트엔드는 http://localhost:5173 에서 실행됩니다.
- 백엔드는 http://localhost:3210 (HTTP API의 경우 3211) 에서 실행됩니다.
- 대시보드는 http://localhost:6791 에서 실행됩니다.
대시보드에 로그인하고 Convex CLI를 통해 배포하려면 관리자 키(admin key)를 생성해야 합니다.
docker compose exec backend ./generate_admin_key.sh
생성한 키를 .env.local 파일에 추가하세요. 주의: down 및 up을 실행하면 키를 다시 생성하고 .env.local 파일을 업데이트해야 합니다.
# .env.local 파일 내
CONVEX_SELF_HOSTED_ADMIN_KEY="<admin-key>" # 반드시 따옴표로 감싸야 합니다
CONVEX_SELF_HOSTED_URL="http://127.0.0.1:3210"
그 다음 Convex 백엔드 (Backend)를 설정합니다 (1회 수행):
npm run predev
백엔드에 새로운 코드를 지속적으로 배포하고 로그를 출력하려면:
npm run dev:backend
대시보드를 확인하려면 http://localhost:6791에 접속한 뒤, 앞서 생성한 관리자 키 (Admin key)를 입력하세요.
Ollama를 위한 Docker 설정
로컬 추론 (Inference)을 위해 Ollama를 사용할 계획이라면, Docker가 Ollama에 연결할 수 있도록 설정해야 합니다.
npx convex env set OLLAMA_HOST http://host.docker.internal:11434
연결을 테스트하려면 (Ollama 실행 후):
docker compose exec backend /bin/bash curl http://host.docker.internal:11434
"Ollama is running"이라는 메시지가 뜨면 성공입니다! 그렇지 않다면 문제 해결 (Troubleshooting) 섹션을 확인하세요.
LLM 연결하기
참고: 백엔드를 클라우드에서 실행하려는 경우, OpenAI 또는 Together.ai와 같은 클라우드 기반 LLM API를 사용하거나, 클라우드에서 로컬 Ollama로 트래픽을 프록시 (Proxy)할 수 있습니다. 자세한 지침은 아래를 참조하세요.
Ollama (기본값)
기본적으로 앱은 전체를 로컬에서 실행하기 위해 Ollama를 사용하려고 시도합니다.
- Ollama를 다운로드하여 설치합니다.
- 앱을 열거나 터미널에서
ollama serve를 실행합니다.ollama serve를 실행했을 때 앱이 이미 실행 중이라면 경고 메시지가 나타납니다. ollama pull llama3를 실행하여llama3를 다운로드합니다.ollama run llama3로 테스트해 봅니다.
Ollama 모델 옵션은 여기에서 확인할 수 있습니다.
사용할 모델을 커스텀하고 싶다면 convex/util/llm.ts를 수정하거나 npx convex env set OLLAMA_MODEL # model을 설정하세요. 임베딩 (Embedding) 모델을 편집하고 싶다면:
convex/util/llm.ts에서OLLAMA_EMBEDDING_DIMENSION을 변경하고 다음을 확인하세요:
export const EMBEDDING_DIMENSION = OLLAMA_EMBEDDING_DIMENSION;npx convex env set OLLAMA_EMBEDDING_MODEL # model을 설정하세요.
참고: 속도가 느려지는 것을 발견하면, 대화 프롬프트 (Conversation prompts)의 크기를 줄이기 위해 constants.ts에서 NUM_MEMORIES_TO_SEARCH를 1로 설정하는 것이 좋습니다.
OpenAI
OpenAI를 사용하려면 다음 작업이 필요합니다:
// convex/util/llm.ts에서 다음 줄을 변경하세요:
export const EMBEDDING_DIMENSION = OPENAI_EMBEDDING_DIMENSION;
OPENAI_API_KEY 환경 변수를 설정하세요. 키가 없다면 https://platform.openai.com/account/api-keys 를 방문하세요.
npx convex env set OPENAI_API_KEY 'your-key'
선택 사항: OPENAI_CHAT_MODEL 및 OPENAI_EMBEDDING_MODEL을 통해 모델을 선택할 수 있습니다.
Together.ai
Together.ai를 사용하려면 다음 작업이 필요합니다:
// convex/util/llm.ts에서 다음 줄을 변경하세요:
export const EMBEDDING_DIMENSION = TOGETHER_EMBEDDING_DIMENSION;
TOGETHER_API_KEY 환경 변수를 설정하세요. 키가 없다면 https://api.together.xyz/settings/api-keys 를 방문하세요.
npx convex env set TOGETHER_API_KEY 'your-key'
선택 사항: TOGETHER_CHAT_MODEL, TOGETHER_EMBEDDING_MODEL을 통해 모델을 선택할 수 있습니다. 임베딩 모델 (Embedding model)의 차원 (Dimension)은 EMBEDDING_DIMENSION과 일치해야 합니다.
기타 OpenAI 호환 API
Anthropic, Groq 또는 Azure와 같은 모든 OpenAI 호환 API를 사용할 수 있습니다.
convex/util/llm.ts에서EMBEDDING_DIMENSION을 사용하는 임베딩 모델의 차원과 일치하도록 변경하세요.llm.ts의getLLMConfig를 편집하거나 환경 변수를 설정하세요:
npx convex env set LLM_API_URL 'your-url'
npx convex env set LLM_API_KEY 'your-key'
npx convex env set LLM_MODEL 'your-chat-model'
...
참고: LLM_API_KEY가 필요하지 않은 경우, 설정하지 마세요.
LLM 제공업체 또는 임베딩 모델 변경 시 주의사항:
LLM 제공업체 또는 임베딩 모델 (embedding model)을 변경하는 경우, 데이터를 삭제하고 처음부터 다시 시작해야 합니다. 메모리에 사용되는 임베딩 (embeddings)은 선택한 임베딩 모델을 기반으로 하며, 벡터 데이터베이스 (vector database)의 차원 (dimension)은 임베딩 모델의 차원과 일치해야 합니다. 그 방법은 아래를 참조하세요.
자신만의 시뮬레이션 커스터마이징하기
참고: 캐릭터 데이터를 변경할 때마다 npx convex run testing:wipeAllTables를 실행한 다음 npm run dev를 실행하여 모든 데이터를 Convex에 다시 업로드해야 합니다. 이는 캐릭터 데이터가 초기 로드 시 Convex로 전송되기 때문입니다. 하지만 npx convex run testing:wipeAllTables는 모든 데이터를 삭제하므로 주의하십시오.
-
자신만의 캐릭터와 스토리 만들기: 모든 캐릭터와 스토리, 그리고 스프라이트 시트 (spritesheet) 참조는 characters.ts에 저장됩니다. 캐릭터 설명을 변경하는 것부터 시작할 수 있습니다.
-
스프라이트 시트 업데이트하기:
data/characters.ts에서 다음 코드를 볼 수 있습니다:export const characters = [ { name: 'f1',
...
자신의 캐릭터에 맞는 스프라이트 시트를 찾은 다음, 해당 파일(위 예시에서는 `f1SpritesheetData`가 `f1.ts`에 정의됨)에 스프라이트 동작/에셋 (sprite motion / assets)을 정의해야 합니다.
3. 배경 (환경) 업데이트하기: 맵은 `data/gentle.js`로부터 `convex/init.ts`에서 로드됩니다. 맵을 업데이트하려면 다음 단계를 따르세요:
- [Tiled](https://www.mapeditor.org/)를 사용하여 타일맵 (tilemaps)을 JSON 파일로 내보냅니다 (bgtiles 및 objmap이라는 이름의 2개 레이어).
- `convertMap.js` 스크립트를 사용하여 JSON을 엔진에서 사용할 수 있는 형식으로 변환합니다.
```console
node data/convertMap.js <mapDataPath> <assetPath> <tilesetpxw> <tilesetpxh>
<mapDataPath>: Tiled JSON 파일의 경로.<assetPath>: 타일셋 (tileset) 이미지의 경로.<tilesetpxw>: 픽셀 단위의 타일셋 너비.<tilesetpxh>: 픽셀 단위의 타일셋 높이.gentle.js처럼 사용할 수 있는converted-map.js를 생성합니다.
-
Replicate를 사용하여 배경 음악 추가하기 (선택 사항)
매일 새로운 배경 음악을 생성하려면, Replicate 계정을 생성하고 프로필의 API Token 페이지에서 토큰을 생성하세요.
npx convex env set REPLICATE_API_TOKEN # 토큰이 기능은 Replicate로부터 웹훅 (webhook)을 수신할 수 있는 경우에만 작동합니다. 일반적인 Convex 클라우드에서 실행 중이라면 기본적으로 작동합니다. 셀프 호스팅 (self-hosting) 중이라면, 앱의
/httpURL로 요청이 전달되도록 설정해야 합니다. Docker Compose를 사용하는 경우http://localhost:3211이 되겠지만, 트래픽을 로컬 머신으로 프록시 (proxy) 해야 합니다.참고: 창이 유휴 (idle) 상태이면 5분 후에 시뮬레이션이 일시 중지됩니다. 페이지를 새로고침하면 다시 시작됩니다. 또한 UI의 버튼을 통해 수동으로 세계를 정지(freeze) 및 재개(unfreeze)할 수 있습니다. 브라우저 없이 세계를 실행하고 싶다면,
convex/crons.ts에서 "stop inactive worlds" 크론 (cron) 작업을 주석 처리하면 됩니다.convex/music.ts의 프롬프트 (prompt)를 수정하여 배경 음악을 변경하세요.convex/crons.ts에서generate new background music작업을 수정하여 새로운 음악을 생성하는 빈도를 변경하세요.
실행 / 테스트 / 디버그를 위한 명령어
활동이 너무 많을 경우 백엔드 (back end)를 중지하려면
이렇게 하면 엔진 (engine)과 에이전트 (agents)의 실행이 중단됩니다. 디버깅을 위해 쿼리 (queries)를 실행하거나 함수 (functions)를 실행하는 것은 여전히 가능합니다.
npx convex run testing:stop
중지 후 백엔드를 다시 시작하려면
npx convex run testing:resume
게임 엔진이나 에이전트가 실행되지 않을 경우 엔진을 강제 구동하려면
npx convex run testing:kick
세계를 아카이브 (archive)하려면
AI 자동 생성 콘텐츠
본 콘텐츠는 HN Show HN (AI)의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기