Статья для тех, кто уже работал с терминалом
Этот мануал предполагает базовые навыки работы с Ubuntu/Linux, Git и Telegram-ботами. Если что-то из этого звучит незнакомо — не проблема: любой AI-чат объяснит шаг за шагом. Просто опишите, что именно вы делаете, и спросите ChatGPT, Gemini, Claude или другой инструмент на ваш выбор. Они справятся с вводными лучше, чем любой статичный мануал.
TL;DR
- Мануал начинается с уже установленной Ubuntu: закладывайте несколько часов на базовую систему и отдельное время на vault, skills и сквозной тест.
- Соберём Telegram-дневник на Hermes Agent с DeepSeek, локальным распознаванием речи и приватным Git-репозиторием.
- Текст, голос и изображения идут разными проверяемыми путями, а сырые исходники всегда сохраняются рядом с итоговой записью.
- После каждого шага есть проверка, поэтому ошибка локализуется сразу, а не при запуске всей системы.
В первой статье я рассказал, как старый Xiaomi Mi Gaming Laptop стал домашним AI-сервером для дневника самочувствия, и почему после месяца с OpenClaw я собрал систему заново на Hermes Agent и DeepSeek. Теперь самое интересное: повторить мою конфигурацию с нуля. Это мануал, который я хотел бы прочитать сам в начале 2026 года, вместо того чтобы собирать его по крупицам.
Я намеренно построил его по принципу «шаг, проверка, следующий шаг». Когда я собирал первую версию системы, моей главной ошибкой было настроить всё сразу и потом два вечера выяснять, какой из шести компонентов молчит. Не повторяйте: проверяйте каждый слой отдельно.
Мануал длинный, но маршрут простой. Сначала мы дадим агенту голос и канал связи, затем научим его превращать сообщения в ваши файлы, а в конце добавим память, backup и привычку. После каждого этапа система уже умеет что-то законченное:
- Шаги 1–6: бот отвечает на текст, голос и изображения.
- Шаги 7–9: сообщения превращаются в проверяемый Markdown-архив с историей изменений.
- Шаги 10–12: дневник становится ежедневной системой, переживает перезагрузку и напоминает о себе сам.
Не обязательно проходить всё за один вечер. Лучшее место для первой остановки — после голосового теста на шаге 5; второе — после первого успешного commit на шаге 9. Рабочая промежуточная система полезнее усталого человека, который в два часа ночи пытается отладить vision, Git и cron одновременно.
Не копируйте команды до проверки версий
Hermes Agent развивается быстро. Текущий аудит выполнен на Hermes v0.12.0 (2026.4.30), commit 4f3766917 и Ubuntu 24.04.4 LTS; дата проверки: 2026-06-07. Для более новой версии сверяйтесь с официальным репозиторием.
Проверенная voice-конфигурация
NVIDIA driver 535.309.01, GTX 1060 6 GB, CUDA 12.2, ffmpeg 6.1.1 и faster-whisper 1.2.1. Модель medium работает на CUDA с int8_float32; 22 секунды тестового аудио транскрибированы за 2.17 секунды.
Что мы собираем
Та же система в текстовом виде:
Telegram (только вы, по allowlist)
│
▼
Hermes Gateway на Ubuntu-машине (systemd, должен работать постоянно)
├─ DeepSeek: текстовая нормализация записей
├─ faster-whisper: локальное распознавание голосовых
├─ auxiliary vision: отдельный провайдер для изображений
├─ skills: wellbeing-journal + wellbeing-reflection
└─ cron: напоминание каждый вечер в 21:00
│
▼
Markdown vault (Obsidian-совместимый)
│
└─ git commit → приватный GitHub-репозиторий
Из железа подойдёт машина, которая может стабильно работать круглосуточно и соответствует требованиям выбранных компонентов. У меня это игровой ноутбук 2019 года на полке домашнего офиса: его GPU ускоряет распознавание речи, но faster-whisper работает и на CPU, просто медленнее. Конфигурация, которую нужно зафиксировать перед публикацией:
| Компонент | У меня | Минимум |
|---|---|---|
| ОС | Ubuntu 24.04.4 LTS, kernel 6.17.0-22-generic, x86_64 | Актуальная стабильная Ubuntu |
| CPU/RAM | Intel i7-8750H (6C/12T), 15 GiB RAM / 10 GiB available | Любой x86-64, 8 GB RAM |
| GPU | GTX 1060 Mobile (6 GB) + Intel UHD 630; NVIDIA 535.309.01, CUDA 12.2 | Не обязателен (CPU-режим STT) |
| Диск | NVMe 154 GB, 84 GB free (43%) | 20 GB свободно |
| Hermes Agent | v0.12.0 (2026.4.30), commit 4f3766917 | Та же версия, что в статье |
Перед началом: Ubuntu, аккаунты и секреты
Установку Ubuntu я сознательно выношу за рамки: качественных инструкций достаточно, начните с официальной документации Ubuntu Server. Исходная точка мануала: чистая обновлённая система, доступ в интернет и пользователь с sudo.
Подготовьте заранее, чтобы потом не прыгать между вкладками:
- аккаунт Telegram (бот создаётся бесплатно через BotFather);
- аккаунт на платформе DeepSeek и платёжный метод для API key;
- аккаунт OpenAI с небольшим бюджетом для vision-слоя (опционально, без него работают текст и голос);
- аккаунт GitHub с включённой двухфакторной аутентификацией;
- Obsidian на десктопе для просмотра записей (опционально, vault остаётся обычным Markdown).
Правило для секретов на весь мануал
API-ключи и токены живут только в ~/.hermes/.env и менеджере паролей. Никогда: в vault, в Git-репозитории, в скриншотах. Все ключи в этой статье: placeholder’ы, не пытайтесь их использовать.
И последнее: решите, где будет стоять машина. Мой ноутбук живёт на настенной полке выше уровня головы. Причина прозаичная: кот. Если у вас есть животные, дети четырёх лет или другие источники хаоса, продумайте это до того, как система станет частью ежедневной рутины.
Шаг 1. Подготовить Ubuntu
Обновляем систему и ставим базовые зависимости:
sudo apt update && sudo apt upgrade -y
sudo apt install -y git curl ffmpeg python3
ffmpeg понадобится для конвертации голосовых сообщений Telegram перед распознаванием, Python — для Hermes и helper-скриптов. В проверенной конфигурации установлен ffmpeg 6.1.1. Standalone uv изначально не был найден в PATH; если uv --version не отвечает, поставьте его по официальной инструкции astral.sh/uv или используйте окружение Hermes из ~/.hermes/hermes-agent/venv/.
Сразу проверьте часовой пояс: от него зависит, придёт ли вечернее напоминание действительно вечером.
timedatectl
# при необходимости:
sudo timedatectl set-timezone Europe/Madrid
Если планируете GPU для распознавания речи, проверьте, что система видит карту:
nvidia-smi # проверено: GTX 1060 6 GB, driver 535.309.01, CUDA 12.2
Проверка: timedatectl показывает ваш часовой пояс, ffmpeg -version отвечает без ошибок.
Если не сработало: не идите дальше. Каждый следующий шаг опирается на этот.
Шаг 2. Установка Hermes Agent
Официальная установка выполняется одной командой. Но прежде чем выполнять любой curl | bash из интернета, включая этот, откройте URL в браузере и просмотрите скрипт: вы должны понимать, что собираетесь запустить на машине, которая будет хранить ваш личный дневник.
curl -fsSL https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh | bash
echo $SHELL # выясняем активный shell
source ~/.bashrc # bash — default на Ubuntu
# source ~/.zshrc # если вы перешли на zsh
Затем диагностика:
hermes doctor
hermes --version
Проверка: hermes doctor не показывает критических проблем, hermes --version выводит версию. Запишите её: это ваша точка отсчёта при любом troubleshooting.
Ожидаемый результат: critical checks проходят; в аудите 2026-06-07 hermes doctor показал PASS по критическим проверкам и minor OAuth warnings.
Если не сработало: чаще всего дело в PATH: перезапустите терминал или выполните source для вашего конфига shell ещё раз.
Шаг 3. Подключить DeepSeek для текста
DeepSeek в этой архитектуре: рабочая лошадка. Он нормализует ежедневные записи, и именно его дешевизна делает always-on агент экономически разумным, о чём я подробно писал в первой статье.
Создайте API key в личном кабинете официальной платформы DeepSeek и запустите интерактивный выбор модели:
hermes model
Выберите DeepSeek в списке провайдеров и введите ключ, когда Hermes его запросит: он сохранит секрет в ~/.hermes/.env как DEEPSEEK_API_KEY. Не редактируйте файлы руками, пока CLI умеет делать это сам. Если интерактивный выбор не появился (например, headless-сессия без TTY), в проверенной версии используются ключи model.default, model.provider и model.base_url в ~/.hermes/config.yaml.
Актуальный model ID на дату проверки: deepseek-v4-flash. Текущие цены для этой проверки: cache hit $0.0028, cache miss $0.14, output $0.28 за 1M tokens (проверено: 2026-06-07, перед настройкой откройте официальную страницу цен).
Smoke test, не выходя из терминала:
hermes -z "Ответь одним словом: работает?"
Проверка: агент отвечает, в ответе видно, что использована модель DeepSeek.
Если не сработало: проверьте, что ключ записан в ~/.hermes/.env, что у аккаунта DeepSeek есть положительный баланс, и что model ID не устарел (это случается).
Шаг 4. Создать Telegram-бота и закрыть его на замок
Сначала создаём бота через официальный инструмент Telegram:
- Откройте Telegram и найдите @BotFather (синяя галочка, официальный).
- Отправьте команду
/newbot. - BotFather спросит имя бота (отображаемое, например «My Wellbeing Journal») и username (должен заканчиваться на
_bot, напримерmy_wellbeing_bot). - В ответ получите HTTP API token вида
7123456789:AAF.... Сразу сохраните его в менеджер паролей — показывается один раз, потом только сброс через/revoke.
Дальше понадобится ваш numeric user ID. Самый простой способ узнать его: напишите боту @userinfobot в Telegram — он ответит вашим ID одной строкой. Запишите его рядом с токеном. Текущий Hermes path: пройти hermes gateway setup или отправить /whoami в Telegram DM своему боту после подключения.
Подключаем gateway:
hermes gateway setup
Мастер настройки спросит токен бота. Самое важное в этом шаге: allowlist. В итоговой конфигурации должно появиться:
# ~/.hermes/.env
TELEGRAM_ALLOWED_USERS=123456789 # ваш numeric ID, placeholder
Здесь важно не перепутать две разные настройки, и это путают почти все, включая меня в первый вечер:
| Настройка | За что отвечает |
|---|---|
TELEGRAM_ALLOWED_USERS | Кто вообще имеет право разговаривать с ботом. Авторизация. |
TELEGRAM_HOME_CHANNEL | Куда бот доставляет сообщения по умолчанию (например, cron-напоминания). Адрес доставки. |
--deliver telegram:<chat id> | Явный адрес доставки конкретной cron-задачи. |
Указать chat ID для доставки недостаточно, чтобы закрыть бота: без allowlist он остаётся открытым для всех, кто найдёт его по имени. Личный дневник с открытой дверью: худшая комбинация из возможных.
Запускаем и проверяем:
hermes gateway # foreground, для первой проверки
# затем, для постоянной работы:
hermes gateway install # устанавливает systemd-сервис
hermes gateway status
Проверка: напишите боту «привет» со своего аккаунта: он должен ответить. Попросите кого-нибудь с другого аккаунта написать ему: бот должен молчать.
Если не сработало: смотрите логи (~/.hermes/logs/gateway.log), чаще всего проблема в токене или в том, что в allowlist записан не numeric ID, а username.
Шаг 5. Локальный faster-whisper для голосовых
Голосовые сообщения: главный интерфейс системы. Само сообщение проходит через Telegram, но после доставки Hermes распознаёт его локальным faster-whisper, не отправляя аудио ещё одному облачному STT-провайдеру. Voice-зависимость устанавливается так:
cd ~/.hermes/hermes-agent
uv pip install -e ".[voice]"
Команда выполняется в окружении, которым управляет установка Hermes. В проверенной системе virtualenv находится в ~/.hermes/hermes-agent/venv/. Если standalone uv не найден в PATH, сначала восстановите/установите uv или используйте documented update/install path Hermes для этой версии.
Фактический STT-конфиг на 2026-06-07:
stt:
enabled: true
provider: local
local:
model: medium
language: ''
Этот конфиг выбирает мультиязычную модель faster-whisper medium. В проверенном runtime используется faster-whisper 1.2.1, device cuda и compute type int8_float32.
Дальше выбор размера модели, и здесь честная развилка:
- base: быстро даже на CPU, для коротких бытовых заметок на одном языке обычно достаточно;
- medium: заметно точнее на смешанной речи и терминах, но требует GPU или терпения;
- проверенная конфигурация:
medium, CUDA на GTX 1060 6 GB,int8_float32; 22 секунды аудио обрабатываются за 2.17 секунды.
Совет из эксплуатации: не гонитесь сразу за крупной моделью. Через пару недель станет видно, какие слова распознаются стабильно плохо, и контекстный словарь исправлений (он появится в третьей статье) лечит это дешевле, чем переход на тяжёлую модель.
Проверка: отправьте боту голосовое сообщение на 20–30 секунд на вашем языке. В контрольном тесте 22 секунды аудио были транскрибированы за 2.17 секунды на GPU.
Если не сработало: проверьте ffmpeg, импорт faster_whisper в Hermes venv, nvidia-smi, свободную RAM/VRAM и логи gateway.
Облачный STT как fallback
У Hermes есть облачные STT-альтернативы (Groq, OpenAI, Mistral). Они быстрее на слабом железе, но каждое голосовое сообщение при этом уходит третьей стороне. Для дневника самочувствия я считаю это неприемлемым по умолчанию: выбирайте облако осознанно, а не потому, что так проще.
Шаг 6. Отдельный vision-слой для изображений
Напомню, как устроен путь картинок: в этой конфигурации DeepSeek отвечает за текст, а скриншоты тренировок из Hevy и фото документов идут через отдельный вспомогательный vision-слой. Это отдельный провайдер с отдельным бюджетом, у меня это OpenAI API с небольшим лимитом расходов. Шаг опциональный: я подключаю vision по желанию и пользуюсь им довольно редко, так что если вам не нужны картинки, его можно пропустить и спокойно жить на тексте с голосом.
# ~/.hermes/config.yaml
auxiliary:
vision:
provider: openai
model: auto # resolved model нужно подтвердить в логах перед публикацией
# ~/.hermes/.env
OPENAI_API_KEY=sk-placeholder
Если вы никогда не работали с OpenAI API: ключ создаётся в разделе API keys, а лимит расходов настраивается в billing/usage-разделах личного кабинета. Поставьте жёсткий месячный потолок сразу: vision-запросы дороже текстовых, скриншоты вы будете слать каждый день, и потолок превращает возможный сюрприз в худшем случае в «бот перестал видеть картинки до конца месяца».
Проверка: отправьте боту любой скриншот без личных данных, например окно терминала. Бот должен описать, что на изображении.
Если не сработало: сверьте имя модели с актуальной документацией OpenAI, проверьте ключ и логи. Типичный симптом неподключённого vision-слоя: бот нормально отвечает на текст, но на картинку отвечает «не вижу изображение» или ошибкой провайдера. Симптом устаревшего model ID: ошибка вида model not found в логах gateway.
Первая контрольная точка: агент уже разговаривает
Если текст, голос и тестовое изображение проходят, у вас уже есть рабочий персональный Telegram-агент. Следующие шаги не делают модель умнее: они превращают разговор в надёжную систему записей, которой можно доверять через месяц.
Шаг 7. Создать Markdown vault
Структуру я выстрадал на собственном архиве: первая версия была «архитектурно красивой», с нумерованными папками и inbox, и почти вся эта красота оказалась лишней для одного пользователя с одним Telegram-входом. Рабочая структура плоская:
wellbeing-journal/
├── daily/YYYY/MM/YYYY-MM-DD.md # одна запись на день, canonical имя
├── weekly/YYYY/YYYY-Www.md # недельные сводки
├── monthly/YYYY/YYYY-MM.md # месячные рефлексии
├── notes/
│ ├── terminology.md # ваши термины: упражнения, добавки
│ ├── measurements-history.md # история измерений
│ └── known-asr-errors.md # словарь исправлений распознавания
├── documents/
│ ├── lab-results/YYYY/MM/
│ └── reports/YYYY/MM/
├── attachments/YYYY/MM/YYYY-MM-DD/ # оригиналы скриншотов и фото
├── audio/ # голосовые, согласно retention policy
├── templates/
│ ├── daily.md
│ ├── weekly.md
│ ├── monthly.md
│ └── lab-result.md
├── scripts/
│ ├── validate-entry.sh
│ ├── build-reflection-context.sh
│ ├── sync-to-mobile.sh
│ └── commit-entry.sh
├── _system/
│ ├── schema.md # контракт frontmatter
│ ├── scales.md # определения шкал 1–10
│ ├── safety.md # медицинские границы skill
│ └── retention-policy.md
├── dashboards/
├── JOURNAL_GUIDE.md
├── .gitignore
└── .obsidian/
Ключевой контракт системы: Markdown для человека, YAML для автоматики. Тело записи остаётся свободным текстом, а всё, что потом будут считать дашборды и рефлексии, живёт строго во frontmatter:
---
date: 2026-06-06
schema_version: 1
sleep_hours: 7.5
sleep_quality: 4
energy: 3
mood: 4
stress: 2
pain: 0
training: strength
symptoms: []
medications_changed: false
source: telegram
needs_review: false
---
Три правила, нарушение которых я потом дорого исправлял в собственном архиве:
- неизвестное значение остаётся
nullили пустым, модель никогда не подставляет 0 вместо «не сказал»; - дата во frontmatter обязана совпадать с именем файла;
- шкалы (настроение, энергия, стресс) определены в
_system/scales.mdс якорями, и самооценка пользователя всегда важнее «оценки по тону сообщения».
Якоря шкал: не формальность, а главная защита от semantic drift. Без них модель однажды решит, что «всё бесит» означает высокий стресс, хотя у вас это низкая энергия. Мои рабочие якоря из _system/scales.md, проверенные несколькими месяцами ежедневных оценок:
## Настроение (mood)
- 1–2 — подавлен, тоска
- 3–4 — раздражён, всё бесит
- 5–6 — ровно, нейтрально (это норма, а не «плохо»!)
- 7–8 — приподнято, радостно
- 9–10 — эйфория
## Энергия (energy)
- 1–2 — выключен, еле двигаюсь
- 3–4 — вялость, провал после обеда
- 5–6 — норма, рабочий режим
- 7–8 — бодрость, драйв
- 9–10 — гиперактивность
## Стресс (stress)
- 1–2 — штиль, отпуск
- 3–4 — лёгкий фон
- 5–6 — заметное давление
- 7–8 — тревога, плохой сон
- 9–10 — кризис, паника
Обратите внимание на пометку у настроения: 5–6 — это норма. Без неё легко начать воспринимать «ровный» день как неудачный, и оценки поползут вверх просто от нежелания ставить себе «середину». И мой главный лайфхак по самим оценкам: не думайте. Три вопроса в конце дня, и первая цифра, которая пришла в голову, и есть правильная. Чем дольше выбираешь между четвёркой и пятёркой, тем меньше эта цифра значит.
Проверка: создайте структуру, положите один тестовый daily-файл по шаблону и откройте папку в Obsidian: vault должен открываться без ошибок и без обязательных community-плагинов.
Шаг 8. Skills: ядро без монолита
Skills у Hermes живут в ~/.hermes/skills/, каждый в своей папке с обязательным SKILL.md. Моя первая версия журнального skill была одним файлом на сотни строк, и проверять его поведение было невозможно. Рабочая компоновка: два skill, у каждого короткое ядро и вынесенные references.
~/.hermes/skills/personal/wellbeing-journal/
├── SKILL.md # короткое ядро: flow и правила маршрутизации
├── references/
│ ├── schema.md # копия контракта frontmatter
│ ├── input-text-voice.md # обработка текста и голосовых
│ ├── input-images.md # обработка изображений и OCR
│ ├── safety.md # медицинские границы
│ ├── provenance.md # правила источников
│ └── git-workflow.md # правила коммитов
├── templates/
│ └── confirmation.md # шаблон подтверждения в Telegram
└── scripts/
├── validate_entry.py
├── upsert_daily.py
└── safe_commit.sh
~/.hermes/skills/personal/wellbeing-reflection/
├── SKILL.md # только недельный/месячный анализ
├── references/
│ ├── reflection-rubric.md
│ └── medical-boundaries.md
└── scripts/
└── build-reflection-context.sh
Ядро журнального skill целиком. Для Hermes v0.12.0 нужен YAML frontmatter с обязательными полями name и description:
# wellbeing-journal
Ты ведёшь личный дневник самочувствия пользователя. Ты ассистент
журналирования, не врач: не ставишь диагнозы, не назначаешь и не отменяешь
лечение, не интерпретируешь срочные симптомы. Полные правила: references/safety.md.
## Входные форматы
- Текст: дневная заметка или ответ на вечерний check-in.
- Голос: transcript уже подготовлен системой. Правила: references/input-text-voice.md.
- Изображения: скриншоты тренировок и фото документов. Правила: references/input-images.md.
## Основной flow
1. Определи дату записи. Если дата неоднозначна, задай ОДИН уточняющий вопрос.
2. Извлеки только явно сообщённые факты. Не додумывай значения.
Отсутствующая метрика остаётся null, никогда не 0.
3. Нормализуй шкалы по _system/scales.md. Самооценка пользователя важнее
твоей оценки тона.
4. Собери недостающие ОБЯЗАТЕЛЬНЫЕ поля в один компактный вопрос
(«Сон / энергия / настроение / стресс цифрами одной строкой?»).
Не спрашивай опциональные поля.
5. Запиши в canonical путь daily/YYYY/MM/YYYY-MM-DD.md через scripts/upsert_daily.py:
повторная обработка той же даты обновляет файл, не создаёт новый.
6. Сырой ввод (transcript, текст) сохрани в разделе Raw отдельно от Summary.
Никогда не перезаписывай Raw своей интерпретацией.
7. Данные из изображений помечай needs_review: true и source: ocr.
8. Прогони scripts/validate_entry.py. Если проверка падает, сообщи об ошибке,
не коммить.
9. Коммит только через scripts/safe_commit.sh (он же secret scan).
10. Отправь короткое подтверждение по templates/confirmation.md: что сохранено,
какие поля заполнены, что осталось needs_review.
## Запрещено
- Медицинские выводы, диагнозы, советы по лекарствам и дозировкам.
- Интерпретация лабораторных значений без units и reference ranges.
- Git push при подозрении на секреты в записи.
- Создание файлов с суффиксами -2, FINAL, evening и любых вариантов
canonical имени.
- Копирование системных логов, ошибок провайдеров и cron-вывода в дневник:
это операционные события, не наблюдения о самочувствии.
Полные листинги references, шаблонов и helper-скриптов лучше вынести в отдельный fixture после финальной проверки команд. До появления такого репозитория статья не должна обещать готовую ссылку. Reflection skill подробно разберём в третьей статье, для установки достаточно создать его каркас.
Проверка: отправьте боту текст «Спал 7 часов, энергия 4, настроение 4, стресс 2, тренировки не было». Должен появиться файл daily/2026/06/2026-06-06.md с заполненным frontmatter и вашим текстом в разделе Raw. Отправьте уточнение «поправка: спал 6 часов»: файл должен обновиться, второй файл появиться не должен.
Если не сработало: проверьте, что skill виден агенту (hermes skills list), и что в SKILL.md указаны правильные пути к vault.
Шаг 9. Приватный Git-репозиторий
Git здесь решает две задачи: backup и история исправлений. Когда через месяц вы поправите ошибку распознавания в старой записи, именно git history покажет, что и когда изменилось.
cd ~/wellbeing-journal
git init
git add .
git commit -m "Initial vault structure"
Создайте на GitHub пустой приватный репозиторий и подключите его через SSH-ключ или системный credential helper. Не используйте plaintext-токен в remote URL: он останется в конфиге навсегда.
git remote add origin [email protected]:youruser/your-private-journal.git # placeholder
git push -u origin main
Обязательный .gitignore до первого осмысленного коммита:
.obsidian/workspace*
.trash/
*.tmp
.DS_Store
И правило, которое стоит выучить до, а не после: удаление файла следующим коммитом не удаляет его из истории. Если в репозиторий однажды попадёт токен или фото документа с личными данными, простое «удалить и закоммитить» не поможет: понадобится перезапись истории и ротация секрета. Я проходил это на рабочем проекте и описал в отдельной статье, как мы вычищали случайно запушенные секреты: лучше прочитать её до того, как пригодится.
Поэтому в safe_commit.sh перед каждым коммитом выполняется примитивный, но рабочий secret scan. Скелет, который легко расширить под свои паттерны:
#!/usr/bin/env bash
# safe_commit.sh — коммит только после проверки на секреты
set -euo pipefail
cd "$(dirname "$0")/.."
# Паттерны: ключи DeepSeek/OpenAI, Telegram bot token, generic
PATTERNS='sk-[A-Za-z0-9]{16,}|DEEPSEEK_API_KEY=|OPENAI_API_KEY=|[0-9]{8,10}:[A-Za-z0-9_-]{30,}'
if git diff --cached --diff-filter=ACM -U0 | grep -qE "$PATTERNS"; then
echo "ОСТАНОВЛЕНО: в staged-изменениях найден возможный секрет." >&2
exit 1
fi
git commit -m "${1:-Update journal entry}"
git push || echo "Push отложен: записи сохранены локально."
Полную версию с проверкой схемы записей нужно публиковать только вместе с проверенным fixture. До этого в статье остаётся минимальный безопасный пример и checklist перед push.
Проверка: сделайте тестовый push, затем склонируйте репозиторий в другую директорию и убедитесь, что vault открывается из свежего клона. Это одновременно и проверка backup, и репетиция восстановления.
Если не сработало: почти всегда это SSH-ключи. ssh -T [email protected] покажет, авторизованы ли вы.
Вторая контрольная точка: у агента появилась проверяемая память
Теперь ценность хранится не внутри чата и не в обещании модели «запомнить». У вас есть обычные файлы, история изменений и проверенный сценарий восстановления. Даже если на этом остановиться, уже получится полезный личный архив.
Шаг 10. Obsidian и чтение с телефона
На десктопе всё просто: откройте ~/wellbeing-journal как vault. С телефоном сложнее, и здесь я дам честный совет вместо красивого: не подключайте два механизма синхронизации к одной папке. Git и iCloud/Obsidian Sync, одновременно пишущие в один vault, рано или поздно устроят конфликт на самом ценном файле.
Мой рабочий вариант: canonical vault живёт в Git на сервере, а на iPhone уходит одностороннее зеркало для чтения (scripts/sync-to-mobile.sh делает rsync --delete в папку iCloud, исключая .git). Я читаю дневник с телефона, но пишу в него только через бота. Правки с телефона в зеркале перезапишутся следующей синхронизацией, и это осознанное ограничение, а не баг.
Альтернативы: official Obsidian Sync как единственный механизм (без Git) или desktop-only режим. Mobile-реализация Obsidian Git экспериментальна и не поддерживает SSH, на неё я бы не ставил.
Проверка: запустите sync-to-mobile.sh сначала с --dry-run и просмотрите список действий, потом боевой запуск и проверка на телефоне.
Шаг 11. Напоминание в 21:00
Финальный штрих, который превращает набор компонентов в привычку. Сначала зафиксируйте часовой пояс в конфиге Hermes:
# ~/.hermes/config.yaml
timezone: "Europe/Madrid"
Пустое значение означает локальное время сервера; явное всегда надёжнее. Затем, прежде чем доверять синтаксису из любой статьи, включая мою:
hermes cron create --help
Создаём задачу:
hermes cron create "0 21 * * *"
"Напомни заполнить вечерний wellbeing check-in: сон, энергия, настроение, стресс, симптомы, тренировка и важные события дня. Не делай медицинских выводов."
--name "Evening wellbeing check-in"
--deliver telegram
Важно понимать: cron-задачи исполняет gateway daemon. Создать задачу недостаточно, gateway должен постоянно работать, поэтому мы и ставили его как systemd-сервис на шаге 4.
И не верьте расписанию на слово. Создайте тестовую задачу на ближайшие две минуты и проверьте фактическое время доставки:
hermes cron create '2m' 'Отправь ровно одно слово: ТЕСТ' --name 'STT Smoke Test Confirm' --deliver telegram
hermes cron list
# после проверки:
hermes cron remove <job_id>
Моё первое напоминание пришло вовремя, но только потому, что я прогнал этот двухминутный тест и поймал расхождение заранее. Здесь важная деталь: удаление работает только по job ID, а не по имени задачи. Час на отладку таймзоны вечером в день запуска или две минуты теста: выбор очевиден.
Проверка: тестовая задача пришла в Telegram в ожидаемое локальное время; hermes cron list показывает постоянную задачу на 21:00.
Если не сработало: проверьте hermes gateway status, timezone в конфиге и TELEGRAM_HOME_CHANNEL: bare --deliver telegram доставляет именно туда.
Шаг 12. Сквозной тест
Теперь прогоняем систему целиком, как один день из жизни:
| Тест | Ожидаемый результат | Где искать ошибку |
|---|---|---|
| Текстовый check-in | Одна daily-запись и один commit | Gateway, skill, права на vault |
| Голосовое сообщение | Raw audio, transcript и структурированная запись той же даты | Whisper, GPU/CPU, кодек, ffmpeg |
| Скриншот тренировки | Attachment сохранён, поля тренировки заполнены, источник: ocr | Vision API, лимиты, MIME |
| Demo-фото документа | Данные извлечены, но помечены needs_review: true | Vision-слой, правила skill |
| Повторная отправка | Обновление записи без дубля и без файлов с суффиксами | upsert-логика, canonical путь |
| Перезагрузка машины | Gateway поднялся сам, бот отвечает | systemd-сервис |
| Push при выключенном Wi-Fi | Запись сохранена локально, push догоняет позже, без потери данных | git-workflow в skill |
На сквозной тест уйдёт минут двадцать, и это лучшие двадцать минут всей установки: после них вы доверяете системе достаточно, чтобы отдать ей настоящий вечерний check-in.
Третья контрольная точка: это уже не прототип
Бот принимает все форматы, обновляет одну canonical-запись, сохраняет оригиналы, переживает перезагрузку и откладывает push без потери данных. Именно в этот момент набор интеграций становится инструментом, которым можно пользоваться каждый день.
Финальный чеклист
- [ ]
TELEGRAM_ALLOWED_USERSсодержит только ваш numeric ID, бот молчит для посторонних. - [ ] Все секреты в
~/.hermes/.envи менеджере паролей, ни одного в vault, Git или скриншотах. - [ ] Таймзона проверена реальной тестовой задачей, а не предположением.
- [ ] Голосовое сообщение распознаётся локально, замерена латентность.
- [ ] Vision-слой настроен отдельно, на аккаунте провайдера стоит лимит расходов.
- [ ] Повторная отправка за ту же дату обновляет запись, дубликаты не создаются.
- [ ] Raw input сохраняется отдельно от нормализованной сводки.
- [ ] Репозиторий приватный, 2FA включена, fresh clone открывается в Obsidian.
- [ ] Gateway переживает перезагрузку машины без ручного запуска.
Как обновлять Hermes Agent
Hermes развивается быстро, и однажды вам понадобится обновление. Для проверенной версии команда обновления: hermes update, затем обязательно hermes doctor и hermes --version, проверка hermes gateway status и одно тестовое сообщение боту. После крупных обновлений сверьте формат заголовка skills: breaking changes в быстро развивающихся проектах случаются.
Частые ошибки
Токен в remote URL
Plaintext-токен в адресе репозитория остаётся в конфиге и истории навсегда. Только SSH-ключ или credential helper.
Ждать, что DeepSeek сам разберёт картинку
В этой архитектуре текст и изображения разнесены. DeepSeek занимается текстом, а картинки идут через отдельный вспомогательный vision-слой: отдельный шаг настройки и отдельный бюджет (у меня это небольшой лимит OpenAI API).
Chat ID вместо allowlist
Адрес доставки и право разговаривать с ботом: разные настройки. Без TELEGRAM_ALLOWED_USERS бот открыт всем.
Cron без проверки таймзоны
Сначала тестовая задача через две минуты, потом постоянное расписание. Иначе «21:00» окажется временем сервера, а не вашим.
Два sync-механизма на один vault
Git плюс iCloud, одновременно пишущие в одну папку, однажды устроят конфликт. Один canonical источник, остальное: одностороннее зеркало.
Настроить всё сразу и потом отлаживать
Шесть слоёв, настроенных без промежуточных проверок, отлаживаются дольше, чем устанавливаются. Шаг, проверка, следующий шаг.
Что дальше
Первый настоящий check-in после установки ощущается немного странно. Несколько часов вы настраивали модели, ключи, systemd и Git, а результат выглядит почти слишком просто: отправили голосовое, получили короткий ответ, в папке появился Markdown-файл. В этом и был смысл. Хорошая инфраструктура исчезает из поля зрения и оставляет только полезное действие.
Система собрана и проверена, но самое интересное начинается после: первая неделя записей, первые ошибки распознавания, первые недельные сводки и вопрос «а что мне теперь со всем этим делать». Об этом третья статья: ежедневная эксплуатация, честная месячная рефлексия без выдуманного RAG, дашборды в Obsidian, реальная стоимость по слоям и приватность. Именно там я расскажу, как дневник поймал мою связку «мелатонин → разбитое утро», которую я сам не замечал.
FAQ
Нужен ли GPU?
Нет. faster-whisper работает на CPU, просто распознавание занимает больше времени. На моей GTX 1060 модель medium обработала 22 секунды аудио за 2.17 секунды.
Подойдёт ли Raspberry Pi или VPS?
Текстовый путь: да. Локальное распознавание речи на слабом ARM будет мучительным, на VPS добавится вопрос доверия к хостеру, у которого лежит ваш дневник. Старый x86-ноутбук: золотая середина.
Можно ли на Windows или macOS?
Hermes поддерживает и другие платформы, но happy path этого мануала ограничен Ubuntu. Команды можно считать воспроизводимыми только после заполнения блока версий и сквозного теста. На macOS общая логика та же, отличия начинаются в установке зависимостей и автозапуске.
Сколько времени занимает установка?
Лично у меня переезд с прошлой системы занял несколько часов, но это не универсальный benchmark. Для первого запуска разумно заложить один подход на базовую систему и отдельный на vault, skills и сквозной тест, особенно если придётся разбираться с GPU, systemd или Telegram delivery.
Где физически хранятся мои данные и кто имеет к ним доступ?
Записи и оригиналы живут на вашей машине и в приватном GitHub-репозитории. По пути их видят Telegram (включая голосовые сообщения), DeepSeek (текст) и vision-провайдер (изображения). Локальный faster-whisper исключает дополнительную отправку аудио STT-провайдеру, но не убирает Telegram из цепочки. Private repo — это контроль доступа, а не шифрование: подробный разбор границ доверия в третьей статье.
Сколько стоит DeepSeek в месяц при ежедневном использовании?
Стоимость текстового слоя зависит от фактического количества токенов и актуальных тарифов: cached input, uncached input и output считаются отдельно. Vision оплачивается отдельно и при частых изображениях может стать заметной частью бюджета. Формулу расчёта и датированный снимок цен я даю в третьей статье; перед настройкой сверьтесь с официальной страницей цен DeepSeek.




