MEMORY.md에 스스로 정리해 두고, 내일 다시 꺼내 쓴다. 사실 이 프로젝트는 인기 오픈소스 OpenCode를 포크해 샤오미가 기억·체크포인트·심판 모델 같은 기능을 얹은 것이다. (저장소: XiaomiMiMo/MiMo-Code · TypeScript/Bun · MIT · TrendShift 1위)이 레포가 무엇을 하는 물건인가.
대부분의 AI 코딩 도구는 창을 닫으면 대화가 증발한다. 다음에 켜면 "우리 프로젝트가 뭐였죠?"부터 다시 시작해야 한다. MiMoCode는 일하는 도중에 스스로 메모를 남기고, 다음 세션에서 그 메모를 검색해 이어 간다. 마치 매일 출근해 어제 적어 둔 업무 노트를 펴 보는 직원처럼.
MiMoCode(저장소명 MiMo-Code)는 샤오미 MiMo 팀이 공개한 터미널 기반 AI 코딩 에이전트다. mimo 명령어 하나로 터미널에 띄우면, 자연어로 "이 버그 고쳐줘"·"테스트 추가해줘"라고 시켰을 때 AI가 직접 파일을 읽고 고치고, 셸 명령을 돌리고, Git을 다룬다. 여기까지는 요즘 흔한 코딩 에이전트의 모습이다.
차별점은 이름이 'Code'인데도 핵심이 "오래 가는 기억"이라는 점이다. 공식 슬로건이 "long-horizon"(긴 호흡의 작업)인 이유다. 며칠에 걸친 큰 작업을 하나의 흐름처럼 이어 가도록, 세션 간 기억·자동 체크포인트·맥락 재구성을 정식 기능으로 넣었다.
packages/opencode다. 즉 "샤오미가 OpenCode 위에 기억·체크포인트 같은 자기 기능을 덧댄 확장판"으로 이해하면 정확하다. 배울 거리로는 "잘 만든 오픈소스를 어떻게 포크해 키우는가"도 포함된다.트렌딩 이유 · 경쟁 대비 장점.
코딩 에이전트는 이미 Claude Code·Cursor·OpenCode 등 강자가 많다. 그런데도 MiMoCode가 TrendShift 1위까지 오른 이유는 세 가지다. 첫째, 모두가 약점으로 꼽던 "세션이 끝나면 맥락이 날아간다" 문제를 정면으로 푼다. 둘째, 설정 0에 가까운 진입 장벽 — MiMo Auto 채널로 API 키 없이 바로 써 보게 했고, Claude Code 설정을 원클릭 임포트한다. 셋째, 대기업(샤오미)이 미는 오픈소스라는 신뢰감과, 포크 원본 OpenCode가 약 7개월 만에 누적 1,000만 다운로드를 달성한 전례에서 비롯된 신뢰 기반이다.
| 비교 항목 | 일반 코딩 에이전트 | MiMoCode |
|---|---|---|
| 세션 간 기억 | 대부분 휘발 — 매번 새로 설명 | 영속 메모리(SQLite 전문검색)로 이어짐 |
| 긴 작업 | 맥락 창이 차면 끊김 | 자동 체크포인트 + 맥락 재구성 |
| 멈춰야 할 때 | 너무 일찍/늦게 멈춤 | 심판 모델이 목표 달성 여부 판정 |
| 품질 | 답 1개 | Max 모드: 후보 N개 중 선택(best-of-N) |
| 시작 | API 키·설정 필요 | 키 없이 즉시(MiMo Auto) + CC 임포트 |
오늘 AI와 한 시간 동안 프로젝트 구조·코딩 규칙·해결한 버그를 공유해도, 창을 닫으면 전부 사라진다. 내일이면 다시 처음부터 설명해야 하고, 같은 실수를 반복하기도 한다. 맥락 창(context window)이 가득 차면 한 세션 안에서도 앞부분을 잊는다.
/dream·/distill 같은 명령으로 AI가 최근 작업 기록을 훑어 오래 갈 사실만 골라 MEMORY.md에 정리한다. 다음 세션에서는 SQLite 전문검색(FTS5)으로 필요한 기억만 끄집어내 맥락에 넣는다. 맥락이 꽉 차면 체크포인트에서 핵심을 재구성한다.
"기억하는 에이전트"를 떠받치는 기술들.
MiMoCode는 파이썬 한 줄 없는 100% TypeScript 프로젝트다(모델이 아니라 도구이기 때문). Bun 런타임을 1순위로 삼고, Effect라는 함수형 프레임워크 위에 전체를 올린 17개 패키지짜리 모노레포다.
| 레이어 | 기술 | 역할 |
|---|---|---|
| 언어·런타임 | TypeScript (ESM) + Bun 1.3 | 코어 전체 · Node 호환은 조건부 임포트로 병행 |
| 모노레포 | Bun workspaces + Turborepo | 17개 패키지 빌드 오케스트레이션 · Nix flake |
| 에이전트 골격 | Effect (effect-ts) | Service/Layer 의존성 주입 · 이펙트 제너레이터로 전부 구성 |
| LLM 호출 | Vercel AI SDK (ai@6) | streamText·generateObject · 다중 프로바이더 추상화 |
| 저장소 | SQLite + Drizzle ORM | 메모리·세션 저장 · FTS5 전문검색 · 34개 마이그레이션 |
| 터미널 UI | OpenTUI + SolidJS | TUI 렌더링 · node-pty로 가상 터미널 |
| 서버·API | Hono + Zod 4 | 로컬 API 서버 · 스키마 검증 · OpenAPI 생성 |
| 데스크탑 | Electron (electron-vite) | 맥/윈/리눅스 데스크탑 앱(packages/desktop) |
| 웹·콘솔 | SolidStart + Vite 7 + Tailwind 4 | 웹 콘솔 · 결제/관리(packages/console) |
| 클라우드 | SST v3 → Cloudflare | Workers · R2 · Durable Objects(동기화) · Stripe |
| 코드 인텔리전스 | tree-sitter · LSP · ripgrep | 구문 파싱 · 언어 서버 연동 · 빠른 검색 |
| 확장 | MCP(modelcontextprotocol) | 외부 도구 연결 · 플러그인 API |
.bun.ts/.node.ts)로 준비해 둔다.한 번의 작업이 어떻게 흐르고, 기억이 어떻게 이어지는가.
MiMoCode의 한 턴은 크게 이렇게 흐른다: ① 사용자 지시 → ② 기억 검색(관련 메모 주입) → ③ 추론·도구 실행 루프 → ④ 체크포인트 저장 → ⑤ 종료 판정(심판) → ⑥ 메모리 정리. 전체 그림 한 장:
가장 상징적인 부분. 메모는 그냥 마크다운 파일(<data>/memory/<scope>/<id>/<key>.md)로 저장되고, SQLite FTS5로 색인된다. 검색할 때 단순히 점수 높은 순으로 자르지 않는다 — 흔한 단어로 인한 잡음을 걸러내려 "최고 점수 대비 상대 비율(기본 0.15)" 아래는 버리되, 1등 결과는 항상 남긴다. 작은 메모 모음에서는 BM25 절댓값이 작아 고정 기준을 쓰면 멀쩡한 결과까지 날아가기 때문이다.
// 메모 검색의 핵심 아이디어(의사코드)
const hits = fts5.search(query, limit * 3); // 3배로 넉넉히
const top = hits[0].score;
const floor = top * 0.15; // 상대 점수 바닥
return hits.filter((h, i) =>
i === 0 || h.score >= floor); // 1등은 무조건 유지
scope가 4종(global 전역 · projects 프로젝트별 · sessions 세션별 · cc)인데, 특히 cc 스코프는 Claude Code의 기록(~/.claude/projects)을 옵트인으로 색인한다 — 즉 다른 도구에서 쌓인 맥락까지 끌어와 기억으로 쓸 수 있다.
session/ 폴더에만 약 40개 파일이 있고, 그 중심에 checkpoint.ts와 형제들(compaction·overflow·prune·budgeted-read)이 있다. 맥락 창이 한계에 가까워지면 자동으로 상태 스냅샷을 찍고, 맥락이 넘치면 최신 체크포인트 + 프로젝트 MEMORY.md + 작업 진행도 + 최근 메시지로 맥락을 다시 짜 맞춘다. 토큰 예산 안에서 중요도 순으로 골라 넣는 게 포인트다.
자율 루프의 고질병은 너무 일찍 "다 했어요"라고 멈추는 것이다. MiMoCode는 /goal로 세션의 종료 조건을 걸어 두고, 에이전트가 멈추려 할 때 별도의 읽기 전용 '심판 모델'이 대화 전체를 보고 정말 조건을 충족했는지 평가한다. 일하는 모델의 낙관에 휩쓸리지 않도록 "차갑게" 판정하는 역할이다.
Max 모드는 한 번에 후보 응답을 여러 개(기본 5개) 만들어, 심판이 가장 좋은 걸 고르는 best-of-N 방식이다. 품질을 끌어올리는 대신 비용이 든다. /dream은 최근 7일치 세션 기록을 훑어 오래 갈 사실을 MEMORY.md로 승격하고, /distill은 30일치에서 반복되는 수작업 흐름을 찾아 재사용 가능한 스킬·서브에이전트로 추출한다 — 쓸수록 똑똑해지는 구조다.
Tab 키로 모드를 바꾼다. build는 모든 도구를 쓰는 기본 작업 모드, plan은 파일을 건드리지 않는 읽기 전용 분석 모드(위험한 변경 전 안전하게 탐색), compose는 계획→실행→리뷰→TDD→검증을 묶어 오케스트레이션하는 모드. 상황에 맞춰 '권한'을 바꿔 끼우는 셈.17개 패키지 모노레포에서 어디가 무슨 일을 하나.
| 경로 | 역할 |
|---|---|
packages/opencode/ | 이름만 opencode인 실제 코어. 포크 흔적이자 거의 모든 기능이 여기 있다. |
src/memory/ | 이 레포의 간판. FTS5 색인, BM25 상대 점수 필터, scope별 마크다운 저장. |
src/session/ | 체크포인트·compaction·overflow·prune·goal — '긴 작업'을 가능케 하는 심장. |
src/tool/ | 에이전트가 쓰는 도구 모음. 각 도구마다 .txt 시스템 프롬프트가 짝으로 있다. |
src/cli/cmd/import | Claude Code 설정·기록을 원클릭으로 가져오는 진입 장벽 낮추기 코드. |
AGENTS.md | 레포가 자기 자신을 어떻게 개발하는지 적은 규약 — 코딩 에이전트 협업 문서의 좋은 예시. |
이 레포에서 배울 만한 것 + 어디를 보면 되는지.
벡터 DB·임베딩 없이도 SQLite 내장 전문검색만으로 쓸 만한 장기 기억을 구현할 수 있다는 실전 예제. 특히 작은 코퍼스에서 절대 점수 기준이 왜 위험한지, "상대 점수 바닥 + 1등 보존" 트릭이 왜 필요한지 주석까지 읽으면 검색 랭킹 감각이 잡힌다. src/memory/service.ts·fts-query.ts부터.
"맥락 창이 차면 어떻게든 된다"가 아니라, 스냅샷→재구성을 정식 서브시스템으로 설계한 사례. 토큰 예산·중요도 랭킹·경계(boundary) 판단을 코드로 본다. 긴 자율 작업을 만들려는 사람에게 필독. src/session/checkpoint*.ts.
Service/Layer 의존성 주입, 이펙트 제너레이터로 비동기·에러를 타입 안전하게 다루는 실제 대형 코드베이스. Effect를 배우고 싶은데 장난감 예제만 봤다면, 여기가 진짜 현장이다. 다만 학습 곡선이 가파르니 작은 도구(src/tool/read.ts)부터.
같은 심판 패턴을 종료 판정(언제 멈출까)과 Max 모드(후보 5개 중 고르기)에 어떻게 다르게 쓰는지 비교해 보면, 자율 에이전트 신뢰성을 끌어올리는 감이 온다. src/session/goal.ts·max-mode.ts.
그냥 쓰려면 / 직접 빌드하려면 무엇이 필요한가.
| 항목 | 요구사항 |
|---|---|
| 설치(권장) | curl -fsSL https://mimo.xiaomi.com/install | bash 또는 npm install -g @mimo-ai/cli |
| 실행 환경 | 터미널 + Node 또는 Bun. 모델이 아니므로 GPU 불필요 |
| 모델 접근 | MiMo Auto(키 없이 무료·한시) · 샤오미 MiMo 플랫폼 OAuth · OpenAI 호환 커스텀 프로바이더 |
| 기존 도구 임포트 | Claude Code 설정·기록 원클릭 가져오기 지원 |
| 소스 빌드 | Bun 1.3.x + Turborepo. (Nix flake로 재현 빌드 가능) 기본 브랜치는 main |
| Docker | Alpine 기반 이미지에 ripgrep 포함, 컴파일된 단일 바이너리 실행 |
MIT 라이선스지만 별도 USE_RESTRICTIONS.md가 붙어 불법·군사·악성코드 용도, 사람 감독 없는 고위험 자동 실행을 금지한다. 또 cc 스코프가 Claude Code 기록을 색인할 수 있으니, 민감한 코드가 있는 환경에서는 메모리 색인 범위를 점검하자.
난이도별로 손에 익히는 단계.
설치 스크립트로 깔고 mimo를 띄운 뒤, 작은 프로젝트에서 "README에 사용법 섹션 추가해줘"를 시켜 본다. MiMo Auto 덕에 API 키 없이 바로 된다. 끝난 뒤 MEMORY.md가 생겼는지 확인해 보자.
# 설치 후 프로젝트 폴더에서
mimo
# 자연어로 지시: "이 레포 구조 설명하고 README 보강해줘"
Tab으로 plan 모드(읽기 전용)에 들어가 "이 코드베이스에서 인증 로직이 어디 흩어져 있어?"를 물어본다. 파일을 건드리지 않고 분석만 하므로, 낯선 레포를 처음 파악할 때 안전하다.
프로젝트 규칙(예: "커밋 메시지는 한글로")을 메모리에 저장시키고, 새 세션을 열어 같은 작업을 시켰을 때 그 규칙이 자동으로 반영되는지 확인한다. /dream을 호출해 세션 기록이 MEMORY.md로 어떻게 승격되는지도 본다.
저장소를 클론해 Bun으로 빌드하고, src/memory/service.ts의 BM25 상대 점수 필터를 직접 따라 읽는다. 검색 limit·점수 비율(0.15)을 바꿔 가며 결과가 어떻게 달라지는지 실험해 보자.
git clone https://github.com/XiaomiMiMo/MiMo-Code
cd MiMo-Code && bun install
# 기본 브랜치는 main
workflow/의 deep-research.js 예제를 본떠, 서브에이전트를 parallel()로 펼치는 작은 워크플로를 작성한다. 또는 자주 반복하는 작업을 /distill로 스킬화해 재사용 가능한 명령으로 만들어 본다.
한 주씩 따라가는 계획.
| 주차 | 주제 | 학습 자료 |
|---|---|---|
| 1주차 | 코딩 에이전트 개념 + MiMoCode/OpenCode 사용 | 직접 사용 · README · long-horizon 블로그 |
| 2주차 | TypeScript ESM + Bun 런타임/워크스페이스 | Bun 공식 문서 · package.json·turbo.json |
| 3주차 | Effect 함수형: Service·Layer·이펙트 제너레이터 | Effect 공식 튜토리얼 · src/tool/*.ts |
| 4주차 | SQLite + Drizzle + FTS5/BM25 전문검색 | Drizzle 문서 · SQLite FTS5 · src/memory/ |
| 5주차 | 맥락 관리: 체크포인트·compaction·토큰 예산 | src/session/checkpoint*.ts 정독 |
| 6주차 | 심판 모델·best-of-N·서브에이전트 오케스트레이션 | goal.ts·max-mode.ts·workflow/ |
본문에 나온 용어 빠른 참조.
| 용어 | 의미 |
|---|---|
| 코딩 에이전트 | 스스로 파일을 읽고·고치고 명령을 실행해 목표를 이루는 AI 도구. |
| cross-session memory | 세션이 바뀌어도 이어지는 영속 기억. MiMoCode의 간판 기능. |
| OpenCode | MiMoCode가 포크한 원본 오픈소스 코딩 에이전트(anomalyco/opencode). |
| Bun | Node를 대체하려는 빠른 JS 런타임. MiMoCode의 1순위 런타임. |
| Effect | 에러·비동기·DI를 타입으로 다루는 TS 함수형 프레임워크. |
| FTS5 / BM25 | SQLite 전문검색 엔진 / 검색 결과 관련도 랭킹 공식. |
| 체크포인트 | 맥락이 찰 때 상태를 스냅샷으로 저장 → 나중에 맥락 재구성. |
| compaction | 넘치는 맥락을 핵심만 추려 다시 짜 맞추는 과정. |
| 심판 모델 | 일하는 AI의 결과를 객관적으로 평가하는 별도 모델 호출. |
| best-of-N | 후보 답 N개를 만들어 가장 좋은 하나를 고르는 품질 향상 기법. |
| MCP | AI가 외부 도구·데이터를 표준 방식으로 호출하는 규약. |
| 모노레포 | 여러 프로젝트를 한 저장소에 모아 함께 빌드·관리하는 방식. |