Skip to content

Andrew82mm/Loci

Repository files navigation

Loci

Tests Python Version License Code style: ruff

Замена линейной истории сообщений на динамический граф знаний — локальный, прозрачный и полностью под вашим контролем.

Loci — множественное число от латинского locus («место»). Отсылка к «методу локусов» — древнеримской технике запоминания, где информация мысленно привязывается к конкретным местам в пространстве.


Идея

Обычный LLM-чат забывает всё после закрытия окна. Даже в рамках одной сессии контекст ограничен токенами, а модель видит лишь плоский список сообщений — без структуры, без приоритетов, без памяти о прошлых разговорах.

Loci решает это иначе: вместо того чтобы передавать модели всю историю чата, система поддерживает живой граф знаний в формате Markdown-файлов. Каждый факт, каждая сущность, каждое решение — это отдельный узел графа, который можно читать, редактировать и версионировать вручную, как код в Git. Папка с памятью полностью совместима с Obsidian.

Поскольку память хранится в обычных файлах на диске, она не привязана ни к одному провайдеру или интерфейсу. Один и тот же граф знаний можно подключить к Claude, GPT-5, Llama, своему агенту или CLI — модель сменилась, а контекст остался. В будущем это позволит синхронизировать память между разными инструментами: чат-ботами, IDE-агентами, автономными пайплайнами.


Архитектура: 4 слоя памяти

┌─────────────────────────────────────────────────┐
│  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:

  1. Векторный поиск — ChromaDB + paraphrase-multilingual-MiniLM-L12-v2 находит семантически близкие чанки (поддерживает русский и другие языки). Нерелевантные результаты отфильтровываются по score threshold.
  2. Графовый обход — для каждого найденного файла подтягиваются связанные сущности через 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

Команды CLI

Команда Описание
pin <текст> Закрепить информацию с высоким приоритетом
edit <файл> Редактировать файл памяти (pinned / context / имя сущности)
project <название> Переключить namespace проекта
snapshots Список всех снэпшотов
rollback [имя] Откатить память к снэпшоту
reindex Принудительная переиндексация
help Справка
exit Выход

Разработка

# Установить dev-зависимости
pip install pytest pytest-cov mypy ruff

# Тесты
make test

# Линтер
make lint

# Проверка типов
make typecheck

47 тестов (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+

About

Persistent knowledge graph memory for LLM conversations

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors