Content
# korean-people-persona
HuggingFace [`nvidia/Nemotron-Personas-Korea`](https://huggingface.co/datasets/nvidia/Nemotron-Personas-Korea) 데이터셋(약 100만 행, 9개 parquet 파일)을 SQLite로 변환·검색하기 위한 도구 모음.
## 개요
- **출처**: NVIDIA, *Nemotron-Personas-Korea* — https://huggingface.co/datasets/nvidia/Nemotron-Personas-Korea
- **라이선스**: 원 데이터셋 페이지의 라이선스 조항을 따름
- **DB 파일**: `database/persona.db`
- **원본 parquet**: `data/train-*-of-*.parquet`
- **테이블**: `persona` (메인) + `persona_fts` (FTS5 외부 콘텐츠 인덱스)
- **타깃 SQLite**: 3.37+ (FTS5, STRICT 테이블, JSON1 사용)
- **Python**: 3.10 이상 (3.11+ 권장)
- **의존성**: `pyarrow >= 15.0`, `huggingface_hub >= 0.24` (`requirements.txt` 참조)
- **디스크 여유**: 약 13 GB (parquet ~2GB + DB 실측 ~10.7GB)
변경 이력은 [CHANGELOG.md](CHANGELOG.md) 참조.
## 데이터 출처
| 항목 | 값 |
|---|---|
| 저장소 | [`nvidia/Nemotron-Personas-Korea`](https://huggingface.co/datasets/nvidia/Nemotron-Personas-Korea) |
| 파일 | `train-0000{0..8}-of-00009.parquet` (9개) |
| 파일당 행 수 | 약 111,112 |
| 총 행 수 | 1,000,000 |
| 결측치 | 모든 컬럼에서 0 (NOT NULL 보장) |
| `country` | 모두 `대한민국` 단일값 |
| `*_list` | 파이썬 `repr` 형식의 문자열 → JSON 배열로 정규화 |
## 폴더 구조
```
korean-people-persona/
├── data/ # 원본 parquet (gitignore — 약 2GB)
│ └── train-*-of-*.parquet
├── database/ # 생성된 SQLite (gitignore — 약 10.7GB)
│ └── persona.db
├── src/
│ ├── convert/ # parquet → SQLite 변환기
│ └── mcp_server/ # MCP 서버 (도구 5종, stdio)
├── examples/ # 활용 데모 스크립트 (아래 '활용 데모' 참조)
│ ├── common.py # 데모 공용 헬퍼
│ ├── synthetic_survey.py # 사례 1 — 합성 설문
│ ├── user_simulator.py # 사례 2 — 챗봇 평가용 유저 시뮬레이터
│ ├── synthetic_reviews.py # 사례 3 — 합성 리뷰 데이터 생성
│ ├── copy_ab_test.py # 사례 4A — 카피 A/B 테스트
│ ├── npc_casting.py # 사례 4B — NPC/캐릭터 캐스팅
│ ├── test_demos.py # 단위 테스트 (pytest)
│ └── requirements.txt # 데모 전용 의존성 (mcp, anthropic)
├── docs/
│ └── use-cases.md # LLM 에이전트 활용 사례 4종 + 프롬프트 레시피
├── build.sh / build.bat / build.ps1
├── requirements.txt
├── CHANGELOG.md
└── README.md
```
`data/`와 `database/`는 용량이 크므로 `.gitignore`로 폴더째 제외됩니다.
## 데이터셋 다운로드
세 가지 방법 중 하나를 선택. 결과 파일은 `data/` 폴더에 `train-*-of-*.parquet` 형태로 위치해야 함.
### 1) 변환 스크립트 옵션 (권장)
`src/convert` 패키지가 누락 시 자동으로 가져옴:
```bash
pip install huggingface_hub pyarrow
PYTHONPATH=src python -m convert --download # 없을 때만 받음
PYTHONPATH=src python -m convert --download --force-download # 항상 재다운로드
```
### 2) huggingface-cli 직접 사용
```bash
pip install huggingface_hub
huggingface-cli download nvidia/Nemotron-Personas-Korea \
--repo-type dataset \
--include "train-*-of-*.parquet" \
--local-dir ./data
```
### 3) git lfs 클론
```bash
git lfs install
git clone https://huggingface.co/datasets/nvidia/Nemotron-Personas-Korea
mv Nemotron-Personas-Korea/train-*.parquet ./data/
```
> **인증**: 비공개 또는 게이트 모델의 경우 `huggingface-cli login` 또는 `HF_TOKEN` 환경변수 필요. 본 데이터셋(공개 시점 기준)은 비인증으로도 다운로드 가능.
> **용량**: parquet 9개 합계 약 1~2 GB.
## 메인 테이블 `persona`
```sql
CREATE TABLE persona (
id INTEGER PRIMARY KEY, -- rowid 별칭 (자동 증가)
uuid TEXT NOT NULL, -- 원본 32자 hex 문자열 (대시 없음, 유니크 인덱스)
-- 페르소나 서술 (긴 한국어 텍스트) ----------------------------------------------
persona TEXT NOT NULL, -- 핵심 1~2문장 요약
professional_persona TEXT NOT NULL, -- 직업/업무 페르소나
sports_persona TEXT NOT NULL, -- 스포츠/운동 페르소나
arts_persona TEXT NOT NULL, -- 예술/문화 페르소나
travel_persona TEXT NOT NULL, -- 여행 페르소나
culinary_persona TEXT NOT NULL, -- 식문화/요리 페르소나
family_persona TEXT NOT NULL, -- 가족 관계 페르소나
cultural_background TEXT NOT NULL, -- 문화·성장 배경 서술
skills_and_expertise TEXT NOT NULL, -- 보유 기술/전문성 서술
hobbies_and_interests TEXT NOT NULL, -- 취미·관심사 서술
career_goals_and_ambitions TEXT NOT NULL, -- 향후 목표/포부
-- 리스트 (JSON 배열로 저장) -----------------------------------------------------
skills_and_expertise_list TEXT NOT NULL CHECK(json_valid(skills_and_expertise_list)), -- 스킬 키워드 JSON 배열
hobbies_and_interests_list TEXT NOT NULL CHECK(json_valid(hobbies_and_interests_list)), -- 취미 키워드 JSON 배열
-- 인구통계 ---------------------------------------------------------------------
sex TEXT NOT NULL, -- 성별: 남자 / 여자
age INTEGER NOT NULL CHECK(age >= 0), -- 나이 (정수)
marital_status TEXT NOT NULL, -- 결혼상태 (4종: 미혼/기혼/이혼/사별 등)
military_status TEXT NOT NULL, -- 병역상태 (군필/해당없음 등)
family_type TEXT NOT NULL, -- 가구 유형 (39종: 1인 가구, 배우자와 자녀 등)
housing_type TEXT NOT NULL, -- 주거 형태 (6종: 아파트, 단독주택 등)
education_level TEXT NOT NULL, -- 최종 학력 (7종: 초등학교 ~ 대학원)
bachelors_field TEXT NOT NULL, -- 학사 전공 분야
occupation TEXT NOT NULL, -- 직업 (자유 텍스트)
district TEXT NOT NULL, -- 시군구 (예: 강남-서초)
province TEXT NOT NULL, -- 시도 (17종)
country TEXT NOT NULL DEFAULT '대한민국' -- 국가 (단일값: 대한민국)
) STRICT;
```
### 인덱스
| 이름 | 컬럼 | 용도 |
|---|---|---|
| `idx_persona_demo` | `(sex, age)` | 성/연령 분포 쿼리 |
| `idx_persona_region` | `(province, district)` | 지역 필터 |
| `idx_persona_edu_occ` | `(education_level, occupation)` | 학력/직업 분석 |
| `idx_persona_family` | `(family_type, marital_status)` | 가구/결혼 분석 |
| `idx_persona_prov_sex` | `(province, sex)` | 시도×성별 집계·층화 샘플링 커버링 |
| `idx_persona_uuid` | `(uuid)` UNIQUE | uuid 단건 조회 |
### 컬럼 의미
| 컬럼 | 설명 | 예시 |
|---|---|---|
| `uuid` | 32자 hex 문자열 (대시 없음). 유니크 | `03b4f36a18e6469386d0286dddd513c8` |
| `persona` | 핵심 1~2문장 요약 | `"농촌 지역에서 평생 농업 일을 해온 70대 남성으로..."` |
| `*_persona` | 영역별 상세 페르소나 (수문장 길이) | 직업/스포츠/예술/여행/식문화/가족 |
| `cultural_background` | 문화·성장 배경 서술 | |
| `skills_and_expertise` | 보유 기술 서술 | |
| `skills_and_expertise_list` | 위 항목의 키워드 리스트 (JSON 배열) | `["엑셀 활용","문서 작성"]` |
| `hobbies_and_interests` | 취미·관심사 서술 | |
| `hobbies_and_interests_list` | 위 항목의 키워드 리스트 (JSON 배열) | `["등산","낚시"]` |
| `career_goals_and_ambitions` | 향후 목표 | |
| `sex` | `남자` / `여자` | |
| `age` | 정수 | |
| `marital_status` | 4종 | `미혼` / `기혼` / `이혼` / `사별` 등 |
| `military_status` | 2종 | `군필` / `해당없음` 등 |
| `family_type` | 39종 | `배우자와 자녀`, `1인 가구` 등 |
| `housing_type` | 6종 | `아파트`, `단독주택` 등 |
| `education_level` | 7종 | `초등학교` ~ `대학원` |
| `bachelors_field` | 학사 전공 분야 | |
| `occupation` | 직업 (자유 텍스트) | |
| `district` | 시군구 | `강남-서초` |
| `province` | 시도 | `서울`, `경기` 등 17종 |
| `country` | 국가 | `대한민국` (단일값) |
## 전문 검색 — `persona_fts` (FTS5)
긴 한국어 서술 컬럼 10개를 외부 콘텐츠 방식으로 인덱싱.
```sql
CREATE VIRTUAL TABLE persona_fts USING fts5(
professional_persona,
sports_persona,
arts_persona,
travel_persona,
culinary_persona,
family_persona,
cultural_background,
skills_and_expertise,
hobbies_and_interests,
career_goals_and_ambitions,
content='persona',
content_rowid='id',
tokenize='trigram'
);
```
**토크나이저**: `trigram` — 연속 3글자를 토큰으로 사용하므로 형태소 분석 없이 **부분 문자열 매칭**이 된다.
- **3글자 이상** 검색어는 조사가 붙은 형태도 그대로 매칭됨 (`등산과`, `트로트`) — prefix `*` 불필요
- **2글자 이하는 매칭 불가** (`캠핑` → 0건). 공백 포함 구절(`'"캠핑 "'`)이나 합성어 OR 조합(`'캠핑장 OR 캠핑카'`)으로 우회
- 불린 연산(`AND`/`OR`/`NOT`)과 큰따옴표 구절 검색 지원
- 더 정교한 한국어 처리가 필요하면 `mecab-ko` / `kiwi` 기반 커스텀 토크나이저로 교체
**FTS 동기화**: 데이터셋이 정적이므로 1회 `INSERT INTO persona_fts(rowid, ...) SELECT ...`로 빌드. 변경이 있으면 트리거를 추가.
## AI 에이전트 활용 (MCP 서버)
본 저장소는 **MCP(Model Context Protocol) 서버**를 제공하므로 Claude Desktop, Cursor, Cline 등 MCP 호환 에이전트가 데이터를 직접 검색·샘플링할 수 있습니다.
### 실행
```bash
PYTHONPATH=src python -m mcp_server # stdio 서버 시작
```
### 에이전트별 등록 방법
> 모든 예시는 **저장소 절대경로 `/abs/path/to/korean-people-persona`** 를 본인 환경에 맞춰 바꿔야 합니다.
> 가상환경(`.venv`)을 만든 경우 `command`를 venv 안 파이썬으로 지정하면 의존성 충돌이 없습니다.
> (예: macOS/Linux `/abs/path/.venv/bin/python`, Windows `C:/abs/path/.venv/Scripts/python.exe`)
#### Claude Desktop
설정 파일 위치:
| OS | 경로 |
|---|---|
| macOS | `~/Library/Application Support/Claude/claude_desktop_config.json` |
| Windows | `%APPDATA%\Claude\claude_desktop_config.json` |
| Linux | `~/.config/Claude/claude_desktop_config.json` |
또는 앱 내 **Settings → Developer → Edit Config** 메뉴.
```json
{
"mcpServers": {
"korean-persona": {
"command": "python",
"args": ["-m", "mcp_server"],
"env": {
"PYTHONPATH": "/abs/path/to/korean-people-persona/src",
"PYTHONIOENCODING": "utf-8"
}
}
}
}
```
저장 후 **Claude Desktop 재시작** → 채팅창 우하단 망치(🔨) 아이콘에서 5개 도구 노출 확인.
#### Claude Code (CLI)
CLI 명령으로 한 줄 등록:
```bash
claude mcp add korean-persona python -m mcp_server \
-e PYTHONPATH=/abs/path/to/korean-people-persona/src \
-e PYTHONIOENCODING=utf-8
```
또는 프로젝트 루트의 `.mcp.json` / 사용자 설정 `~/.claude/settings.json`에 직접 작성:
```json
{
"mcpServers": {
"korean-persona": {
"command": "python",
"args": ["-m", "mcp_server"],
"env": { "PYTHONPATH": "/abs/path/to/korean-people-persona/src" }
}
}
}
```
확인: `claude mcp list` → 활성화 후 `/mcp` 슬래시 명령으로 도구 호출 가능.
#### Cursor
프로젝트별 `.cursor/mcp.json` 또는 사용자 전역 `~/.cursor/mcp.json`:
```json
{
"mcpServers": {
"korean-persona": {
"command": "python",
"args": ["-m", "mcp_server"],
"env": { "PYTHONPATH": "/abs/path/to/korean-people-persona/src" }
}
}
}
```
또는 **Settings → MCP → Add new MCP Server** UI 사용. 커서 재시작 후 `@korean-persona`로 호출.
#### ChatGPT (Developer Mode / Connectors)
ChatGPT의 MCP 통합은 **HTTP/SSE 트랜스포트** 기반으로 동작합니다(원격 커넥터). 본 서버는 stdio 서버이므로 그대로는 등록할 수 없고, **HTTP 어댑터로 감싸서** 노출해야 합니다.
1. `mcp` SDK의 HTTP 트랜스포트로 서버 실행:
```bash
PYTHONPATH=src python -m mcp_server --transport sse --port 8765
```
(현재 본 저장소 `server.py`는 stdio만 호출. HTTP/SSE 모드를 쓰려면 `mcp.run(transport="sse", port=8765)`로 분기 추가가 필요합니다.)
2. ngrok / Cloudflare Tunnel 등으로 외부 노출:
```bash
ngrok http 8765
```
3. ChatGPT → **Settings → Connectors → Developer mode → Add custom connector**
- URL: `https://<ngrok>/sse`
- 인증: 필요 시 Bearer 토큰 헤더 추가 (`MCP_AUTH_TOKEN`)
4. 새 채팅에서 **Tools** 메뉴에서 커넥터를 활성화하면 도구 호출 가능.
> 보안 주의: ChatGPT 커넥터는 모델 외부에 도구를 노출하므로 **공개 URL은 반드시 인증으로 보호**하세요. 로컬 전용이면 stdio 기반 Claude Desktop / Cursor 사용을 권장.
#### Gemini CLI
Google `gemini-cli` 사용자 설정 `~/.gemini/settings.json`:
```json
{
"mcpServers": {
"korean-persona": {
"command": "python",
"args": ["-m", "mcp_server"],
"env": { "PYTHONPATH": "/abs/path/to/korean-people-persona/src" },
"cwd": "/abs/path/to/korean-people-persona"
}
}
}
```
확인: `gemini mcp list` (또는 CLI 내 `/mcp` 명령) → 도구 자동 노출.
#### 공통 트러블슈팅
| 증상 | 원인 / 해결 |
|---|---|
| 도구가 안 보임 | 앱 재시작 누락. Claude Desktop은 완전 종료 필요 (트레이 아이콘까지) |
| `ModuleNotFoundError: mcp_server` | `PYTHONPATH`가 `src`를 가리키는지 확인 (절대경로 권장) |
| 한글 깨짐 | `env.PYTHONIOENCODING=utf-8` 추가 (특히 Windows) |
| `python` 명령 못 찾음 | `command`를 절대경로로 (예: `/usr/bin/python3`, `C:/Python311/python.exe`, venv의 python) |
| 권한 오류 | Windows에서 경로 공백 → 따옴표 또는 경로 변경 |
### 노출 도구
| 도구 | 설명 |
|---|---|
| `search_persona(query, fields, filters, limit, full)` | FTS5 자유 텍스트 검색 + 인구통계 필터 결합 (BM25 정렬) |
| `get_persona(uuid)` | uuid로 단일 페르소나 전체 조회 |
| `sample_persona(filters, n, full)` | 조건부 무작위 샘플링 |
| `aggregate(group_by, filters, limit)` | 인구통계 GROUP BY COUNT |
| `stats()` | 전체 데이터셋 통계·사용 가능 컬럼 안내 |
### 에이전트 활용 샘플
#### 1) 마케팅 인터뷰 시뮬레이션
> "60대 이상 여성 중 등산을 즐기는 분 10명을 샘플링해서, 새로 출시한 무릎 보호대 광고 카피에 대한 반응을 시뮬레이션해줘."
에이전트는 다음 흐름으로 작동:
1. `search_persona(query="등산을 OR 등산과", filters={"sex":"여자","age_min":60}, limit=10, full=True)`
2. 각 페르소나를 시스템 프롬프트로 주입 → 광고 카피 평가 응답 1인 1건씩 생성
3. 응답 클러스터링 후 인사이트 요약
#### 2) 지역 기반 캐릭터 캐스팅
> "부산 영도구에 사는 50대 자영업자 페르소나를 찾아서, 단편소설 주인공으로 쓸 수 있게 정리해줘."
```
search_persona(
filters={"province":"부산", "district_like":"%영도%",
"age_min":50, "age_max":59,
"occupation_like":"%경영%"}, # occupation에 '자영업' 문자열은 없음 — 실제 값은 '소규모 상점 경영자' 등
limit=5, full=True
)
```
#### 3) 정책 영향 분석
> "초등학교 졸업이 최종 학력인 70대 이상 1인 가구가 어느 시도에 가장 많은지 분포 분석해줘."
```
aggregate(
group_by=["province"],
filters={"education_level":"초등학교", "age_min":70,
"family_type_like":"%혼자%"},
limit=20
)
```
#### 4) 의미 기반 검색 + 인용
> "농촌에서 자랐고 손주가 있는 페르소나를 찾아 cultural_background 인용과 함께 알려줘."
```
search_persona(
query='농촌에서 AND 손주들',
fields=["cultural_background", "family_persona"],
limit=5, full=True
)
```
#### 5) 합성 설문조사
> "전국 인구 분포에 비례해서 100명을 층화 샘플링한 뒤, 각자에게 '주 4일제 도입에 찬성하느냐'고 물어봐줘."
1. `aggregate(group_by=["province","sex","age"])` → 분포 비율 계산
2. 비율대로 `sample_persona`를 시도×성별×연령대별로 호출
3. 각 페르소나로 LLM에 1:1 응답 요청
4. 결과 집계 → 가중치 적용한 찬반 분포 산출
### 직접 사용 (코드)
MCP 없이 파이썬에서 바로 호출:
```python
import sys; sys.path.insert(0, "src")
from mcp_server import tools
tools.stats()
tools.search_persona(query="용접공", filters={"sex":"남자"}, limit=5)
tools.sample_persona(filters={"province":"제주"}, n=3, full=True)
```
## 활용 데모 (`examples/`)
[`docs/use-cases.md`](docs/use-cases.md)의 활용 사례 4종에 대응하는 **동작하는 데모 스크립트**.
각 사례 문서에는 코드 없이 Claude Code 세션에 붙여넣어 재현하는 "▶ Claude Code에서 바로 해보기"
프롬프트 레시피도 포함되어 있다.
| 스크립트 | 사례 | 내용 | 산출물 |
|---|---|---|---|
| `synthetic_survey.py` | 1 | 인구 비례 층화 샘플링 합성 설문 (5점 척도 + 이유) | `survey_result.json` |
| `user_simulator.py` | 2 | 가상 고객 ↔ 결함 내장 더미 상담봇 멀티턴 대화 + LLM judge 채점 | `simulator_result.json` |
| `synthetic_reviews.py` | 3 | 관심사 시드 상품 리뷰 생성 + 인구통계 라벨 + 표현 복사 검출 | `synthetic_reviews.jsonl` |
| `copy_ab_test.py` | 4A | 관심사 세그먼트 카피 A/B 선호 평가 (제시 순서 무작위화) | `ab_test_result.json` |
| `npc_casting.py` | 4B | 배역 요구 → 후보 추출 → 캐릭터 시트 생성 | `npc_candidates.md` |
`common.py`는 다섯 스크립트가 공유하는 헬퍼(MCP 접속·층화 샘플링·LLM 호출·집계)다.
### 설치
```bash
pip install -r examples/requirements.txt # mcp, anthropic
```
### 실행
모든 스크립트는 **프로젝트 루트에서** 실행하며, MCP 서버를 직접 띄울 필요 없이
스크립트가 stdio로 자체 기동한다 (`database/persona.db` 빌드 선행 필요).
```bash
# 1) dry-run — API 키 없이 MCP 파이프라인(샘플링/검색)만 검증
python examples/synthetic_survey.py --dry-run --n 10
python examples/user_simulator.py --dry-run --per-group 3
python examples/synthetic_reviews.py --dry-run --n 5
python examples/copy_ab_test.py --dry-run
python examples/npc_casting.py --dry-run
# 2) 실제 실행 — LLM 롤플레이 포함 (ANTHROPIC_API_KEY 필요, 호출량만큼 과금)
# Linux/macOS: export ANTHROPIC_API_KEY=sk-ant-...
# PowerShell: $env:ANTHROPIC_API_KEY = "sk-ant-..."
python examples/synthetic_survey.py --n 20 --question "주 4일제 도입에 찬성하십니까?"
python examples/user_simulator.py --per-group 5
python examples/synthetic_reviews.py --n 10
python examples/copy_ab_test.py --copy-a "카피 A 문구" --copy-b "카피 B 문구"
python examples/npc_casting.py --brief "서울 30대 미혼 직장인 조연"
```
공통 옵션: `--dry-run`(키 불필요), `--model`(기본 `claude-sonnet-4-6`), 표본 수(`--n` 등).
세부 옵션은 각 스크립트의 `--help` 참조. 산출물은 프로젝트 루트에 저장되며 gitignore 처리되어 있다.
### 테스트
```bash
python -m pytest examples/test_demos.py -v # 순수 함수 + 더미봇 규칙 16개
```
## SQL 직접 쿼리
```sql
-- 1) 등산을 좋아하고 트로트 관련 언급이 있는 60대 여성 (trigram — 3글자 이상, '*' 불필요)
SELECT p.uuid, p.age, p.province, p.occupation
FROM persona_fts f
JOIN persona p ON p.id = f.rowid
WHERE persona_fts MATCH '등산과 AND 트로트'
AND p.sex = '여자' AND p.age BETWEEN 60 AND 79
ORDER BY bm25(persona_fts) LIMIT 20;
-- 2) 특정 컬럼 검색 + 스니펫
SELECT p.uuid, snippet(persona_fts, 7, '<b>', '</b>', '...', 10) AS hit
FROM persona_fts f JOIN persona p ON p.id = f.rowid
WHERE f.skills_and_expertise MATCH '용접공' LIMIT 10;
-- 3) JSON 리스트 펼치기
SELECT p.uuid, j.value AS hobby
FROM persona p, json_each(p.hobbies_and_interests_list) j
WHERE j.value LIKE '%낚시%' LIMIT 10;
-- 4) 인구통계 분포
SELECT province, sex, COUNT(*) cnt
FROM persona GROUP BY province, sex ORDER BY cnt DESC;
```
## PRAGMA 설정 (적재/운영)
```sql
PRAGMA journal_mode = WAL;
PRAGMA synchronous = NORMAL;
PRAGMA temp_store = MEMORY;
PRAGMA cache_size = -262144; -- 256MB
```
## 빌드 절차
### 한 줄 빌드 (권장)
OS별 래퍼 스크립트가 가상환경 생성 → 의존성 설치 → 다운로드 → 변환까지 자동 수행.
| 플랫폼 | 명령 |
|---|---|
| **Linux / macOS** | `chmod +x build.sh && ./build.sh` |
| **Windows (cmd)** | `build.bat` |
| **Windows (PowerShell)** | `.\build.ps1` |
재다운로드 옵션은 모두 동일하게 전달:
```bash
./build.sh --force-download
build.bat --force-download
.\build.ps1 --force-download
```
> PowerShell에서 실행 정책 오류가 나면:
> `PowerShell -ExecutionPolicy Bypass -File .\build.ps1`
### 수동 실행
```bash
python -m venv .venv
# Linux/macOS: source .venv/bin/activate
# Windows: .venv\Scripts\activate
pip install -r requirements.txt
PYTHONPATH=src python -m convert [--download] [--force-download]
```
내부 처리:
1. (옵션) `--download` 시 parquet 누락분을 HuggingFace에서 받음
2. `persona.db` 신규 생성 (기존 파일 삭제)
3. PRAGMA 설정 + 스키마/인덱스 생성
4. 9개 parquet을 순차 읽어 행 단위 정규화 후 `executemany` 적재 (트랜잭션 단위: 파일 1개)
5. `*_list` 컬럼은 `ast.literal_eval` → `json.dumps(ensure_ascii=False)` 변환
6. FTS5 가상 테이블 생성 + `INSERT ... SELECT` 1회 빌드
7. `INSERT INTO persona_fts(persona_fts) VALUES('optimize')` 후 `ANALYZE`
8. WAL 체크포인트 후 종료
## 디스크 사용량 (실측)
- `persona.db` 합계 약 **10.7 GB** (메인 테이블 + 인덱스 + FTS5 trigram)
- 빌드 소요 시간 약 24분 (장비에 따라 상이)
- trigram 토크나이저는 모든 3글자 조합을 인덱싱하므로 unicode61 대비 용량이 크다 —
부분 문자열 매칭의 대가
MCP Config
Below is the configuration for this MCP Server. You can copy it directly to Cursor or other MCP clients.
mcp.json
Connection Info
You Might Also Like
markitdown
MarkItDown-MCP is a lightweight server for converting URIs to Markdown.
markitdown
Python tool for converting files and office documents to Markdown.
Filesystem
Node.js MCP Server for filesystem operations with dynamic access control.
TrendRadar
TrendRadar: Your hotspot assistant for real news in just 30 seconds.
mempalace
The highest-scoring AI memory system ever benchmarked. And it's free.
mempalace
The highest-scoring AI memory system ever benchmarked. And it's free.