Skip to main content
Glama
civilian7

korean-people-persona

by civilian7

korean-people-persona

Набор инструментов для преобразования и поиска по набору данных HuggingFace nvidia/Nemotron-Personas-Korea (около 1 млн строк, 9 файлов parquet) с использованием SQLite.

Обзор

  • Источник: NVIDIA, Nemotron-Personas-Korea — https://huggingface.co/datasets/nvidia/Nemotron-Personas-Korea

  • Лицензия: В соответствии с условиями лицензии на странице исходного набора данных

  • Файл БД: 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)

  • Свободное место на диске: около 5 ГБ (parquet ~2 ГБ + БД ~3 ГБ)

Related MCP server: Legal Search MCP

Источник данных

Элемент

Значение

Репозиторий

nvidia/Nemotron-Personas-Korea

Файлы

train-0000{0..8}-of-00009.parquet (9 шт.)

Строк в файле

около 111 112

Всего строк

1 000 000

Пропущенные значения

0 во всех столбцах (гарантируется NOT NULL)

country

везде одно значение 대한민국 (Республика Корея)

*_list

строки в формате repr Python → нормализованы в JSON-массивы

Структура папок

korean-people-persona/
├── data/                  # 원본 parquet (gitignore — 약 2GB)
│   └── train-*-of-*.parquet
├── database/              # 생성된 SQLite (gitignore — 약 3GB)
│   └── persona.db
├── src/
│   ├── convert/                # parquet → SQLite 변환기
│   │   ├── __init__.py
│   │   └── __main__.py
│   └── mcp_server/             # (예정) MCP 서버
├── build.sh / build.bat / build.ps1
├── requirements.txt
└── README.md

Папки data/ и database/ исключены через .gitignore из-за большого объема.

Загрузка набора данных

Выберите один из трех способов. Результирующие файлы должны находиться в папке data/ в формате train-*-of-*.parquet.

1) Опция скрипта преобразования (рекомендуется)

Пакет src/convert автоматически загрузит недостающие файлы:

pip install huggingface_hub pyarrow
PYTHONPATH=src python -m convert --download              # 없을 때만 받음
PYTHONPATH=src python -m convert --download --force-download   # 항상 재다운로드

2) Прямое использование huggingface-cli

pip install huggingface_hub
huggingface-cli download nvidia/Nemotron-Personas-Korea \
    --repo-type dataset \
    --include "train-*-of-*.parquet" \
    --local-dir ./data

3) Клонирование через git lfs

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. Данный набор данных (на момент публикации) доступен без аутентификации.

Объем: 9 файлов parquet суммарно около 1–2 ГБ.

Основная таблица persona

CREATE TABLE persona (
  uuid                       TEXT    PRIMARY KEY,                                  -- 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)

Анализ семьи/семейного положения

Описание столбцов

Столбец

Описание

Пример

uuid

32-символьная hex-строка (без дефисов). PK

03b4f36a18e6469386d0286dddd513c8

persona

Краткое резюме (1–2 предложения)

"Мужчина 70 лет, всю жизнь занимавшийся сельским хозяйством в сельской местности..."

*_persona

Подробная персона по областям (длинный текст)

Профессия/спорт/искусство/путешествия/еда/семья

cultural_background

Культурный фон и история развития

skills_and_expertise

Описание навыков и компетенций

skills_and_expertise_list

Список ключевых слов (JSON-массив)

["Excel","документооборот"]

hobbies_and_interests

Описание хобби и интересов

hobbies_and_interests_list

Список ключевых слов (JSON-массив)

["альпинизм","рыбалка"]

career_goals_and_ambitions

Будущие цели

sex

남자 (муж) / 여자 (жен)

age

Целое число

marital_status

4 типа

미혼 (не женат/не замужем) / 기혼 (женат/замужем) и т.д.

military_status

2 типа

군필 (служил) / 해당없음 (не применимо) и т.д.

family_type

39 типов

배우자와 자녀 (супруг и дети) и т.д.

housing_type

6 типов

아파트 (квартира) и т.д.

education_level

7 типов

초등학교 (начальная школа) ~ 대학원 (аспирантура)

bachelors_field

Область бакалавриата

occupation

Профессия (свободный текст)

district

Район (си/гун/гу)

강남-서초

province

Провинция (си/до)

서울, 경기 и т.д. (17 типов)

country

Страна

대한민국 (одно значение)

Полнотекстовый поиск — persona_fts (FTS5)

Индексация 10 длинных текстовых столбцов на корейском языке методом внешнего контента.

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='rowid',
  tokenize='unicode61 remove_diacritics 2',
  prefix='2 3 4'
);

Токенизатор: unicode61 + префиксный индекс (2/3/4 символа). Для обработки корейских окончаний при поиске рекомендуется использовать префиксное сопоставление вида 등산*. Если требуется морфологический анализ, замените на кастомный токенизатор на базе mecab-ko / kiwi.

Синхронизация FTS: Поскольку набор данных статический, сборка выполняется один раз через INSERT INTO persona_fts(rowid, ...) SELECT .... При изменениях добавьте триггеры.

Использование ИИ-агентами (MCP-сервер)

Данный репозиторий предоставляет MCP-сервер (Model Context Protocol), позволяющий MCP-совместимым агентам (Claude Desktop, Cursor, Cline и др.) напрямую искать и выбирать данные.

Запуск

PYTHONPATH=src python -m mcp_server          # stdio 서버 시작

Способы регистрации для агентов

Во всех примерах необходимо заменить абсолютный путь к репозиторию /abs/path/to/korean-people-persona на ваш. Если создана виртуальная среда (.venv), укажите command как путь к Python внутри venv, чтобы избежать конфликтов зависимостей. (например: macOS/Linux /abs/path/.venv/bin/python, Windows C:/abs/path/.venv/Scripts/python.exe)

Claude Desktop

Расположение файла конфигурации:

ОС

Путь

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.

{
  "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)

Регистрация одной командой:

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:

{
  "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:

{
  "mcpServers": {
    "korean-persona": {
      "command": "python",
      "args": ["-m", "mcp_server"],
      "env": { "PYTHONPATH": "/abs/path/to/korean-people-persona/src" }
    }
  }
}

Или используйте UI Settings → MCP → Add new MCP Server. После перезапуска Cursor вызывайте через @korean-persona.

ChatGPT (Developer Mode / Connectors)

Интеграция MCP в ChatGPT работает на базе HTTP/SSE (удаленный коннектор). Поскольку этот сервер работает через stdio, его нельзя подключить напрямую без HTTP-адаптера.

  1. Запуск сервера с HTTP-транспортом SDK mcp:

    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:

    ngrok http 8765
  3. ChatGPT → Settings → Connectors → Developer mode → Add custom connector

    • URL: https://<ngrok>/sse

    • Аутентификация: при необходимости добавьте заголовок Bearer-токена (MCP_AUTH_TOKEN)

  4. В новом чате активируйте коннектор в меню Tools.

Безопасность: коннекторы ChatGPT открывают инструменты вне модели, поэтому защищайте публичный URL аутентификацией. Для локального использования рекомендуем Claude Desktop / Cursor на базе stdio.

Gemini CLI

Конфигурация пользователя Google gemini-cli ~/.gemini/settings.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 (или команда /mcp в CLI) → инструменты появятся автоматически.

Общее устранение неполадок

Симптом

Причина / Решение

Инструменты не видны

Не перезапустили приложение. Claude Desktop нужно закрыть полностью (включая иконку в трее)

ModuleNotFoundError: mcp_server

Проверьте, указывает ли PYTHONPATH на src (рекомендуется абсолютный путь)

Иероглифы отображаются некорректно

Добавьте env.PYTHONIOENCODING=utf-8 (особенно в Windows)

Команда python не найдена

Укажите абсолютный путь в command (например, /usr/bin/python3, C:/Python311/python.exe)

Ошибка прав доступа

В 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) Симуляция маркетингового интервью

"Выбери 10 женщин старше 60 лет, увлекающихся альпинизмом, и симулируй их реакцию на рекламный слоган новых наколенников."

Агент выполняет:

  1. search_persona(query="등산*", filters={"sex":"여자","age_min":60}, limit=10, full=True)

  2. Внедряет каждую персону в системный промпт → генерирует оценку слогана для каждого.

  3. Кластеризует ответы и резюмирует инсайты.

2) Кастинг персонажей по регионам

"Найди персону 50-летнего самозанятого, живущего в районе Ёндо-гу, Пусан, и опиши его для использования в качестве героя рассказа."

search_persona(
  filters={"province":"부산", "district_like":"%영도%",
           "age_min":50, "age_max":59,
           "occupation_like":"%자영%"},
  limit=5, full=True
)

3) Анализ влияния политики

"Проанализируй, в каких провинциях больше всего одиноких домохозяйств старше 70 лет с начальным образованием."

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. Агрегация результатов → расчет распределения "за/против" с учетом весов.

Прямое использование (код)

Вызов из Python без MCP:

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)

Прямые SQL-запросы

-- 1) 등산을 좋아하고 트로트 관련 언급이 있는 60대 여성
SELECT p.uuid, p.age, p.province, p.occupation
FROM persona_fts f
JOIN persona p ON p.rowid = 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.rowid = 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 (загрузка/работа)

PRAGMA journal_mode = WAL;
PRAGMA synchronous  = NORMAL;
PRAGMA temp_store   = MEMORY;
PRAGMA cache_size   = -262144;   -- 256MB

Процесс сборки

Сборка одной командой (рекомендуется)

Обертки для ОС автоматически создают venv, устанавливают зависимости, скачивают и преобразуют данные.

Платформа

Команда

Linux / macOS

chmod +x build.sh && ./build.sh

Windows (cmd)

build.bat

Windows (PowerShell)

.\build.ps1

Опции перескачивания передаются аналогично:

./build.sh --force-download
build.bat --force-download
.\build.ps1 --force-download

Если в PowerShell ошибка политики выполнения: PowerShell -ExecutionPolicy Bypass -File .\build.ps1

Ручной запуск

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.

  7. INSERT INTO persona_fts(persona_fts) VALUES('optimize') и ANALYZE.

  8. Контрольная точка WAL и завершение.

Оценка дискового пространства

  • Основная таблица + индексы: около 1.5 ~ 2.5 ГБ

  • FTS5 с префиксами: дополнительные 1 ~ 3 ГБ

  • Итого ожидается около 3 ~ 5 ГБ (после фактической загрузки).

Related MCP Connectors

Related MCP Servers