Замена линейной истории сообщений на динамический граф знаний — локальный, прозрачный и полностью под вашим контролем.
Loci — множественное число от латинского locus («место»). Отсылка к «методу локусов» — древнеримской технике запоминания, где информация мысленно привязывается к конкретным местам в пространстве.
Обычный LLM-чат забывает всё после закрытия окна. Даже в рамках одной сессии контекст ограничен токенами, а модель видит лишь плоский список сообщений — без структуры, без приоритетов, без памяти о прошлых разговорах.
Loci решает это иначе: вместо того чтобы передавать модели всю историю чата, система поддерживает живой граф знаний в формате Markdown-файлов. Каждый факт, каждая сущность, каждое решение — это отдельный узел графа, который можно читать, редактировать и версионировать вручную, как код в Git. Папка с памятью полностью совместима с Obsidian.
Поскольку память хранится в обычных файлах на диске, она не привязана ни к одному провайдеру или интерфейсу. Один и тот же граф знаний можно подключить к Claude, GPT-5, Llama, своему агенту или CLI — модель сменилась, а контекст остался. В будущем это позволит синхронизировать память между разными инструментами: чат-ботами, IDE-агентами, автономными пайплайнами.
┌─────────────────────────────────────────────────┐
│ L4 Ручное управление pin / edit │
├─────────────────────────────────────────────────┤
│ L3 Версионность snapshot / rollback │
├─────────────────────────────────────────────────┤
│ L2 Граф знаний entities + relations │
├─────────────────────────────────────────────────┤
│ L1 Рабочая память buffer → summary │
└─────────────────────────────────────────────────┘
L1 - Рабочая память. Каждые N сообщений буфер автоматически сжимается: быстрая модель извлекает ключевые факты и решения, исходные сообщения архивируются в .md-файлы с меткой времени. В контекст следующего запроса попадает только итог, а не вся история.
L2 - Граф знаний. Из каждой суммаризации извлекаются атомарные факты и сущности с типизированными связями ([[Node A]] --(implements)--> [[Node B]]). Каждая сущность — отдельный .md-файл. Знания разделены на глобальные (о пользователе) и изолированные по проектам (namespace).
L3 - Версионность. Перед любым значимым изменением (суммаризация, ручная правка) автоматически создаётся снэпшот. Можно откатить всю память к любому прошлому состоянию командой rollback.
L4 - Ручное управление. Любой .md-файл памяти можно открыть и отредактировать напрямую — изменения мгновенно учитываются в следующем запросе. Важную информацию можно закрепить командой pin — она всегда попадает в контекст с высшим приоритетом.
Перед каждым ответом система собирает релевантный контекст через гибридный RAG:
- Векторный поиск — ChromaDB +
paraphrase-multilingual-MiniLM-L12-v2находит семантически близкие чанки (поддерживает русский и другие языки). Нерелевантные результаты отфильтровываются по score threshold. - Графовый обход — для каждого найденного файла подтягиваются связанные сущности через SQLite-граф.
Модель всегда указывает, на какие файлы памяти она опиралась при ответе (секция References:).
# 1. Создать и активировать виртуальное окружение
python -m venv .venv && source .venv/bin/activate
# 2. Установить зависимости
pip install -r requirements.txt
# 3. Создать файл с ключом
echo "OPENROUTER_API_KEY=sk-or-v1-..." > .env
# 4. Запустить
python main.py| Команда | Описание |
|---|---|
pin <текст> |
Закрепить информацию с высоким приоритетом |
edit <файл> |
Редактировать файл памяти (pinned / context / имя сущности) |
project <название> |
Переключить namespace проекта |
snapshots |
Список всех снэпшотов |
rollback [имя] |
Откатить память к снэпшоту |
reindex |
Принудительная переиндексация |
help |
Справка |
exit |
Выход |
# Установить dev-зависимости
pip install pytest pytest-cov mypy ruff
# Тесты
make test
# Линтер
make lint
# Проверка типов
make typecheck47 тестов (17 unit + 15 smoke + 15 integration). Не требуют API-ключа.
loci/ # Основной пакет
├── config.py # ENV-переменные и настройки
├── engine.py # MemoryEngine — оркестрация
├── models.py # Pydantic-схемы (Message, Fact, Snapshot, ...)
├── buffer.py # ConversationBuffer со sliding window
├── summarizer.py # SummarizationPipeline (safe cycle)
├── colors.py # ANSI-логгеры
├── storage/
│ ├── filesystem.py # StorageManager (файлы, снэпшоты + Chroma, архив)
│ └── base.py # StorageBackend Protocol
├── graph/
│ ├── extractor.py # KnowledgeGraph — LLM → факты в .md
│ ├── index.py # SQLite relations (GraphIndex)
│ └── renderer.py # Факты → Markdown
├── rag/
│ ├── retriever.py # RAGEngine (Chroma + graph-expansion + score threshold)
│ ├── vector.py # VectorStore (Chroma wrapper)
│ └── chunker.py # Markdown-aware chunking (по заголовкам)
├── llm/
│ ├── client.py # OpenRouter HTTP-клиент
│ └── tokens.py # Token counting (tiktoken + fallback)
└── cli/
└── main.py # REPL-точка входа
main.py # Shim: from loci.cli.main import run_cli
tests/
├── smoke/ # Smoke-тесты (не требуют LLM/API-ключа)
├── unit/ # Unit-тесты (Phase 1+)
└── integration/ # Integration-тесты (Phase 1+)
scripts/ # Скрипты миграции данных
project_memory/ # Папка с памятью (в .gitignore, данные пользователя)
project_memory/
├── context.md # Текущий сжатый контекст
├── pinned.md # Закреплённые факты (высокий приоритет)
├── knowledge/
│ ├── _global/ # Общие знания (о пользователе и т.д.)
│ └── default/ # Знания текущего проекта
│ ├── EntityA.md
│ └── EntityB.md
├── archive/ # Исходные диалоги с меткой времени
└── _system/
├── task.md # Текущая задача диалога
├── conversation_buffer.json
├── relations.db # SQLite-граф знаний
├── snapshots/ # Снэпшоты для отката (включают Chroma)
└── chroma_db/ # Векторная БД
- LLM: любая модель через OpenRouter (GPT-4o, Llama, Gemini и др.)
- Векторная БД: ChromaDB (локально, без сервера)
- Эмбеддинги:
paraphrase-multilingual-MiniLM-L12-v2(мультиязычный, работает оффлайн) - Формат памяти:
.md+ YAML frontmatter (совместимо с Obsidian) - Язык: Python 3.10+