Your Unique Identity — SDK для создания AI-персонажей с постоянной памятью
YUI-SDK — это концептуальный JavaScript/TypeScript SDK для создания ИИ-персонажей с долгосрочной памятью и режимом обучения. Название отсылает к Yui из Sword Art Online — ИИ-компаньоне.
⚠️ Важно: Это концепт/POC, а не готовый продукт. Проект находится в разработке.
YUI-SDK предоставляет единый удобный инструмент для создания AI-персонажей с постоянной памятью и режимом обучения, где вы можете в обычном диалоге объяснить персонажу факты о нём.
В обычном диалоге вы рассказываете персонажу о себе — и он запоминает. Но что если нужно запомнить факты о самом персонаже? Например:
- "Ты была Discord-ботом два года назад"
- "Тебе 25 лет, ты из Токио"
- "У тебя есть питомица по имени Луна"
Эти факты не обязательно хранить в системном промпте — это лишь засоряет контекстное окно. Вместо этого факты о персонаже лежат в отдельной памяти и автоматически подтягиваются, когда диалог заходит в соответствующую тему.
┌─────────────────────────────────────────────────────────────┐
│ System Prompt │
│ "Тебя зовут Юна. Ты дружелюбный ассистент." │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ Persona Facts (память о себе) │
│ • "Я была Discord-ботом два года назад" │
│ • "Мне 25 лет, я из Токио" │
│ • "У меня есть питомица по имени Луна" │
│ ↑ Только когда релевантно ↑ │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ User Memories (память о пользователе) │
│ • "Пользователь работает программистом" │
│ • "Пользователь любит кофе" │
│ ↑ Только когда релевантно ↑ │
└─────────────────────────────────────────────────────────────┘
Вам не нужно устанавливать векторные базы данных или другие внешние зависимости:
- Установили SDK
- Он скачал embedding модель (~270MB, один раз)
- Просто работает
- Персонаж получает read-only доступ к фактам о себе
- Может запоминать информацию о пользователе
- Для обычного общения
bun run chat:debug- Вы рассказываете факты о персонаже в формате чата
- Персонаж запоминает и подтверждает понимание
- Факты сохраняются в первом лице: "Мне 25 лет", а не "Персонажу 25 лет"
bun run chat:education:debugSDK представляет собой модульную систему для построения ИИ-персонажей с:
- Двухуровневой памятью — persona facts (о себе) + user memories (о пользователе)
- Семантическим поиском через векторные эмбеддинги
- Function calling для автоматического сохранения и восстановления
- Локальным хранением в SQLite
- Мультиязычными эмбеддингами (50+ языков, включая русский)
- Двухуровневая память — раздельное хранение фактов о персонаже и о пользователе
- Семантический поиск — мультиязычная модель
paraphrase-multilingual-mpnet-base-v2(50+ языков) - Локальное хранение — SQLite, ничего не уходит в облако кроме запросов к LLM
- Офлайн эмбеддинги — генерация векторов через
@xenova/transformers - Function calling — автоматическое сохранение важной информации
- Временной контекст — учитывает время, прошедшее с последнего разговора
- Режим обучения — удобный способ обучить персонажа фактам о нём самом
git clone <repo-url>
cd YUI-SDK
# Education mode — обучение персонажа фактам о нём
bun run chat:education:debug
# Normal mode — обычный диалог с персонажем
bun run chat:debugimport { Persona } from "yui-sdk";
const persona = new Persona({
systemPrompt: "Тебя зовут Юна. Ты дружелюбный ассистент.",
apiKey: process.env.OPENAI_API_KEY!,
memory: {
dbPath: "./brain.sqlite",
contextWindow: 10,
topK: 3,
},
});
await persona.init();
// Normal mode — обычный диалог
const response = await persona.chat("Привет! Меня зовут Иса.");
// Education mode — обучение фактам о персонаже
persona.setMode("education");
await persona.chat("Тебе 25 лет, ты из Токио");bun add yui-sdkТребования:
- Bun как runtime
- Любой OpenAI совместимый провайдер
# Normal mode — обычный диалог
bun run chat
bun run chat:debug # С отладочной информацией
# Education mode — обучение персонажа
bun run chat:education
bun run chat:education:debug # С отладочной информациейbun run dev # Режим разработки с hot-reload
bun run build # Сборка в dist/
bun run test # Запуск тестов┌─────────────────────────────────────────────────────────────────┐
│ User Message │
└─────────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────┐
│ Passive Recall (перед каждым сообщением) │
│ 1. Генерируется embedding для сообщения пользователя │
│ 2. Семантический поиск top-K фактов о персонаже │
│ 3. Семантический поиск top-K воспоминаний о пользователе │
│ 4. Добавление в system prompt │
└─────────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────┐
│ LLM с function calling │
│ - recall_memory(query, topK) — активный поиск │
│ - save_memory(content, importance) — сохранить о пользователе │
│ - save_persona_fact(content, importance) — сохранить о себе* │
└─────────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────┐
│ Response + сохранение в историю │
└─────────────────────────────────────────────────────────────────┘
* Только в education mode
| Характеристика | Normal Mode | Education Mode |
|---|---|---|
| Persona facts | Read-only | Read-write |
| User memories | Read-write | Нет доступа |
| Tools | save_memory, recall_memory |
save_persona_fact, recall_persona_facts |
| Применение | Обычный диалог | Обучение персонажа |
// Инициализация (загружает модель эмбеддингов ~270MB)
await persona.init();
// Отправить сообщение
const response = await persona.chat("Привет!");
// С отладочной информацией
const debug = await persona.chatDebug("Как тебя зовут?");
// {
// content: string,
// toolCalls: ToolCall[],
// toolExecutions: ToolExecution[],
// passiveRecall: PassiveRecall[], // воспоминания о пользователе
// personaRecall: PassiveRecall[], // факты о персонаже (read-only)
// stepsUsed: number
// }
// Режим работы
persona.setMode("normal"); // обычный диалог
persona.setMode("education"); // обучение фактам о персонаже
// Статистика
persona.getStats();
// { messageCount, memoryCount, personaFactsCount, lastActivity }
// Управление
persona.clearHistory(); // очистить историю сообщений
persona.clearMemories(); // очистить воспоминания о пользователе
persona.clearPersonaFacts(); // очистить факты о персонаже
persona.close(); // закрыть БДnew Persona({
// Базовый промпт персонажа (не заменяет память, а дополняет её)
systemPrompt: "Тебя зовут Юна. Ты дружелюбный ассистент.",
apiKey: "sk-...",
// LLM настройки
model: "gpt-4o-mini",
baseURL: "https://api.openai.com/v1", // опционально
temperature: 0.7,
maxSteps: 3,
memory: {
dbPath: "./brain.sqlite",
contextWindow: 10, // сообщений в истории
topK: 3, // воспоминаний о пользователе в passive recall
educationTopK: 5, // фактов о персонаже в passive recall (education mode)
},
// Embeddings настройки
embeddingsConfig: {
// Модель по умолчанию: paraphrase-multilingual-mpnet-base-v2 (~270MB, 50+ языков)
// Для экономии места: paraphrase-multilingual-MiniLM-L12-v2 (~120MB)
// Только английский: all-MiniLM-L6-v2 (~23MB)
model: "Xenova/paraphrase-multilingual-mpnet-base-v2",
},
timeThreshold: 5, // минут для time context
mode: "normal", // "normal" | "education"
});-- messages (краткосрочная история диалога)
CREATE TABLE messages (
id INTEGER PRIMARY KEY,
role TEXT, -- 'user' | 'assistant'
content TEXT,
created_at INTEGER
);
-- memories (долгосрочная память о пользователе)
CREATE TABLE memories (
id TEXT PRIMARY KEY,
content TEXT,
embedding TEXT, -- JSON-encoded Float32Array (768 dims для mpnet-base)
importance REAL, -- 0.0 - 1.0
created_at INTEGER,
last_accessed INTEGER
);
-- persona_facts (факты о персонаже)
CREATE TABLE persona_facts (
id TEXT PRIMARY KEY,
content TEXT,
embedding TEXT, -- JSON-encoded Float32Array (768 dims для mpnet-base)
importance REAL, -- 0.0 - 1.0
created_at INTEGER,
last_accessed INTEGER
);Примечание: Эмбеддинги хранятся как JSON-строки для переносимости. Размерность зависит от модели:
paraphrase-multilingual-mpnet-base-v2— 768 dimsparaphrase-multilingual-MiniLM-L12-v2— 384 dimsall-MiniLM-L6-v2— 384 dims
При смене модели старые эмбеддинги автоматически очищаются с предупреждением.
Первый запуск может быть медленным
- Embedding модель (~270MB для mpnet-base-v2) загружается при первом
init() - Последующие запросы быстрые
- Для более быстрой загрузки используйте
paraphrase-multilingual-MiniLM-L12-v2(~120MB)
Vector dimension mismatch
- Произошла при смене embedding модели (384 → 768 dims или наоборот)
- Старые эмбеддинги автоматически очистятся с предупреждением
- Переобучите персонажа в education mode
LLM не сохраняет факты
- Проверьте
systemPrompt— не должен переопределять инструкции по памяти - Включите
chat:debugдля просмотра tool calls - В normal mode факты о персонаже только read-only
Низкий semantic search score (< 0.5)
- Убедитесь что используете мультиязычную модель для русского текста
paraphrase-multilingual-mpnet-base-v2даёт лучшие результаты- Проверьте что факты сохранены на том же языке что и запросы
Ошибка Bun SQLite
- Используйте Bun runtime (не Node.js)
bun run chat # не nodeMIT