Files
memo/MANUAL.md
T

18 KiB
Raw Blame History

Как пользоваться memo

Инструкция для человека. Без внутренностей — только что делать руками.

Смысл одной фразой: вы пишете обычные markdown-файлы, а memo рядом с ними отвечает на вопросы по смыслу — не по словам, а по содержанию, и не отправляя ничего в интернет.


1. Что это и зачем

У вас есть папка с заметками. Обычные .md-файлы, обычные подпапки-темы. memo строит рядом с каждой папкой-темой маленький индекс (SQLite) и умеет искать по нему:

  • по смыслу — «как чинят карточку в jellyfin» найдёт заметку, где написано «удаление элемента из медиатеки», хотя слова «карточка» там нет;
  • по точному значению — 76.117, номер тикета, версия — найдёт точную строку;
  • сразу и то, и другое (по умолчанию) — режим называется гибридный.

Что важно понять сразу:

Ваши файлы — главные memo только читает .md. Он никогда ничего в них не пишет и не переименовывает.
Индекс — расходник .memo/index.db внутри папки можно удалить в любой момент. Он пересоберётся. Это не ваши данные.
Всё локально Никаких облаков и API. Модель лежит файлом на диске, считает на процессоре.
Никакого «формата memo» Никаких спец-тегов, баз данных для правки, экспортов. Только markdown.

2. Структура вашей библиотеки

memo не навязывает вам схему — он просто следует за вашими папками.

Коллекция = папка, в которой лежат .md напрямую. Одна папка = одна тема = одна независимая база. Папки друг о друге не знают.

Пример нормальной библиотеки:

~/notes/                     <- корень библиотеки (не коллекция: тут нет .md напрямую)
├── infra/                   <- КОЛЛЕКЦИЯ (тут *.md)
│   ├── servers.md
│   ├── hosts.md
│   └── .memo/index.db       <- индекс, создастся сам
├── work/
│   └── jira/                <- КОЛЛЕКЦИЯ (тут *.md)
│       ├── access.md
│       └── ci.md
└── life/
    └── books/               <- КОЛЛЕКЦИЯ (тут *.md)
        ├── history.md
        └── notes.md

Тут три коллекции: infra, work/jira, life/books. Папки work и life — просто группировка, коллекциями они не считаются (в них нет .md напрямую), и это правильно: иначе одни и те же заметки индексировались бы по нескольку раз.

Правило простое: завёл папку, положил туда .md — это новая коллекция. Ничего регистрировать не надо.


3. Установка (один раз)

Нужен JDK 21.

cd /root/WORK/memo

# 1. Собрать всё
./gradlew installDist

# 2. Скачать модель (в артефакты не входит, 287 МБ, один раз)
mkdir -p models/siglip2
curl -fSL -o models/siglip2/text_model_int8.onnx http://static.binom.pw/models/siglip2/text_model_int8.onnx
curl -fSL -o models/siglip2/tokenizer.model     http://static.binom.pw/models/siglip2/tokenizer.model

# 3. Сказать, где модель (добавьте в ~/.bashrc, чтобы не повторять)
export MEMO_MODEL_DIR=/root/WORK/memo/models/siglip2

Без переменной MEMO_MODEL_DIR программы ищут модель в /root/WORK/memo/models/siglip2 — если у вас этот путь, шаг 3 можно пропустить.

После сборки появятся три программы:

memo-cli/build/install/memo/bin/memo              <- для человека и для скриптов
memo-mcp/build/install/memo-mcp/bin/memo-mcp      <- для агента (MCP)
memo-watch/build/install/memo-watch/bin/memo-watch <- демон слежения (необязателен)

4. Первый запуск: проиндексировать и найти

CLI=/root/WORK/memo/memo-cli/build/install/memo/bin/memo

# Проиндексировать всю библиотеку (коллекции найдутся сами)
$CLI index ~/notes
#> индексировано: 4 обновлено, 4 файлов всего
#> индексировано: 4 обновлено, 4 файлов всего
#> индексировано: 4 обновлено, 4 файлов всего
#> итого: 12 обновлено в 3 коллекциях

# Спросить по смыслу
$CLI search ~/notes/infra "где публикуются релизы"
#> 0.016  /root/notes/infra/hosts.md:6  Прокси
#>        Корпоративные домены проксируются кади на 76.132.
#> 0.016  /root/notes/infra/hosts.md:3  Nexus
#>        Нексус доступен на 76.117, публикация — только через CI.

Первая строка в каждой паре — похожесть, адрес файл:строка и заголовок раздела; ниже — сам текст куска.

Обратите внимание: первая команда была index, но она не обязательна. search сам до-индексирует то, что изменилось, прямо перед поиском. Можно просто писать заметки и сразу спрашивать.

Команды целиком

$CLI index  <путь>                                   # проиндексировать (повторный прогон — быстрый)
$CLI search <путь> "<вопрос>"                        # искать: и смысл, и точные слова
$CLI search <путь> "<вопрос>" --k 5                  # вернуть 5 результатов (по умолчанию 8)
$CLI search <путь> "<вопрос>" --json                 # машинный вывод (для скриптов и агента)
$CLI search <путь> "<вопрос>" --mode lex             # только точные слова (BM25)
$CLI search <путь> "<вопрос>" --mode vec             # только по смыслу (вектор)
$CLI status <путь>                                   # что проиндексировано и когда

Что писать в <путь>:

  • корень библиотеки (~/notes) — поиск по всем коллекциям сразу, ответы перемешиваются и сортируются по релевантности;
  • одну папку-коллекцию (~/notes/infra) — поиск только внутри неё.

Область видно по адресам в результатах: .../infra/hosts.md — значит, нашли в infra.


5. Подключить к агенту (Hermes)

Здесь memo и живёт по-настоящему: агент получает инструмент поиска и перестаёт перечитывать всю библиотеку целиком.

Добавьте в конфиг Hermes (~/.hermes/config.yaml, секция mcp_servers):

mcp_servers:
  memo:
    command: /root/WORK/memo/memo-mcp/build/install/memo-mcp/bin/memo-mcp
    env:
      MEMO_MODEL_DIR: /root/WORK/memo/models/siglip2
    enabled: true

Инструменты подхватятся только в новой сессии Hermes — как и любой MCP-сервер, они читаются при старте процесса. В текущей беседе их не будет; начните новую и проверьте, что появились memo_search, memo_status, memo_reindex.

Агенту после этого можно говорить просто: «поищи в заметках, чем мы чинили карточку в jellyfin». Он вызовет memo_search и получит пути, строки и текст найденных кусков.

Три инструмента

Инструмент Что делает
memo_search(path, query, k, mode) Гибридный поиск. Если индекса нет — создаёт его сам.
memo_status(path) Что проиндексировано, сколько файлов и чанков, когда обновлялось.
memo_reindex(path) Полная переиндексация (нужна редко — обычный поиск и так до-индексирует).

Проверить без агента

Тот же код инструмента, но из командной строки — удобно, когда что-то не работает:

$CLI mcp-probe --tool memo_search --args '{"path":"/root/notes/infra","query":"домены","k":3}'
$CLI mcp-probe --tool memo_status --args '{"path":"/root/notes"}'

Ответ печатается ровно в той форме, которую получил бы агент.


6. Демон слежения — нужен ли он вам

Короткий ответ: для работы с агентом — не нужен. Поиск сам замечает изменения: перед каждым запросом он сверяет дату и размер файлов и до-индексирует то, что поменялось. Написали заметку — сразу нашли её.

Демон memo-watch нужен ровно в одном случае: заметки правят мимо агента — вы сами в редакторе, через git pull, синхронизацию, чужой скрипт, — и вы хотите, чтобы индекс был свежим заранее, а не в момент вопроса.

memo-watch/build/install/memo-watch/bin/memo-watch ~/notes
#> индексирую: /root/notes/infra -> обновлено 4
#> индексирую: /root/notes/life/books -> обновлено 4
#> индексирую: /root/notes/work/jira -> обновлено 4
#> наблюдаю: /root/notes/infra
#> наблюдаю: /root/notes/life/books
#> наблюдаю: /root/notes/work/jira

При старте он сразу проходит по всем коллекциям — индекс полный с первой секунды, ждать изменений не надо. Дальше печатает наблюдаю: по каждой и доиндексирует по факту правок:

#> индексирую: /root/notes/infra -> обновлено 1

Какие папки он мониторит

Ровно те, что вы передали аргументом, — по тому же правилу, что и остальные команды:

  • передали корень (~/notes) — следит за всеми коллекциями внутри него (в примере — infra, work/jira, life/books) и держит индекс по каждой;
  • передали одну папку (~/notes/infra) — следит только за ней.

Внутрь служебных папок (.memo, .git, любые .-папки) он не заглядывает. Список наблюдаемых папок печатается при старте строками наблюдаю: <путь> — это и есть ответ на вопрос «что он мониторит».

Демон переживает правки так: ловит изменения (с задержкой 0.5 с, чтобы не дёргаться на каждое нажатие), раз в 10 минут делает полный сверочный проход — это страховка для случаев, когда система о событиях файлов не сообщила (сетевые диски, sshfs).

Пока это ручной запуск: автостарта (systemd) нет, сам он нигде в системе не прописан и сейчас не работает — его надо запускать руками, когда понадобится.


7. Порядок работы: как это выглядит в жизни

# 1. Завести тему — просто папка с markdown
mkdir -p ~/notes/infra
cat > ~/notes/infra/hosts.md <<'EOF'
# Хосты

## Nexus
Нексус доступен на 76.117, публикация — только через CI.

## Прокси
Корпоративные домены проксируются кади на 76.132.
EOF

# 2. Спросить
$CLI search ~/notes/infra "где публикуются релизы"
#> 0.031  /root/notes/infra/hosts.md:10  Nexus
#>        Нексус доступен на 76.117, публикация — только через CI.

# 3. Дописать заметку — и сразу спросить про неё, без переиндексации
printf '\n## Свежий раздел\nуникальное_слово_дзынь_47\n' >> ~/notes/infra/hosts.md
$CLI search ~/notes/infra "уникальное слово дзынь"
#> 0.016  /root/notes/infra/hosts.md:10  Свежий раздел
#>        уникальное_слово_дзынь_47
#> 0.016  /root/notes/infra/hosts.md:6  Прокси
#>        Корпоративные домены проксируются кади на 76.132.

# 4. Периодически освежать всё скопом (обычно не нужно — бывает после git pull)
$CLI index ~/notes

Записывать заметки можно любым способом: редактором, >>, агентом, git pull. memo не требует, чтобы записи шли через него.


8. Если что-то не так

Поиск ничего не находит, хотя файлы на месте. Проверьте, что папка — коллекция, то есть .md лежат в ней напрямую:

$CLI status ~/notes                 # должны быть видны коллекции и число файлов
find ~/notes -name '*.md' | head    # файлы на месте?

$CLI status ~/notes/emptygroup
#> коллекции не найдены

Если status пишет коллекции не найдены — вы указали папку, в которой нет .md напрямую (например, общую группировку вроде work, где лежат только подпапки). Укажите корень библиотеки или папку-коллекцию.

Свежая правка не находится. Проверьте, что ищете в той же папке, где файл: поиск по ~/notes/infra не увидит заметку из ~/notes/work. Поиск по корню видит всё.

Хочу начать с чистого листа. Удалите индексы — данные не пострадают:

find ~/notes -name .memo -type d -prune -exec rm -rf {} +
$CLI index ~/notes

database is locked. Значит, одновременно пишут два процесса. Подождите минуту и повторите; если повторяется — пришлите текст ошибки, это повод для отдельного разбирательства.

Инструменты memo_* не появились у агента. MCP-серверы читаются при старте Hermes: начните новую сессию. Проверьте, что путь к memo-mcp в конфиге верный и файл исполняемый.

Где посмотреть, что вообще происходит.

$CLI status ~/notes     # по каждой коллекции: файлов, чанков, когда индексировали
find ~/notes -name index.db    # где лежат индексы

9. Что можно удалять без страха

Путь Что это Удалять?
~/notes/**/*.md ваши заметки Нет — это ваши данные
~/notes/**/.memo/ индексы Да, пересоберутся командой index
models/siglip2/ модель Да, но придётся скачать заново
build/ сборка Да, но придётся пересобрать

Правило: всё, что не .md, — расходник.