Как я переехал со своим агентом с облака на собственный Mac и потратил на это полтора суток

История о том, почему «просто скопировать файлы» никогда не бывает просто или

“Как Катя хотела выйти замуж по расчету, но не смогла, потому что была гуманитарием.”


Есть такой тип задач, который выглядит на 30 минут, а занимает полтора дня. Ты открываешь ноутбук в пятницу после обеда с чашкой кофе и закрываешь в 3 ночи. Просыпаешься в субботу с твёрдым намерением «просто дочистить хвосты» – и снова закрываешь в 2 ночи. Именно так у меня прошли пятница и суббота, когда я решил перенести своего AI-агента с арендованного сервера на собственный Mac Studio M4 Max.

Это история про OpenClaw, про Docker, про то как полтора суток могут уйти на «просто перенести файлы» – и про то, что в итоге получилось.


Кто такой Ильич и зачем он мне нужен

Контекст. У меня есть личный AI-агент. Я назвал его Илья Ильич – ИИ, каламбур. Он живёт в OpenClaw, это open-source платформа для запуска автономных AI-агентов в мессенджерах. Ильич сидит в Telegram, знает про меня всё что я ему рассказал, ведёт дневники наших разговоров, умеет искать в интернете, читать файлы, транскрибировать голосовые сообщения и много чего ещё.

До сегодняшнего дня Ильич жил на арендованном Ubuntu-сервере на Beget. Работал нормально, но была одна проблема: большие языковые модели стоят денег, а Sonnet через OpenRouter – это примерно 20-40 долларов в день при моём уровне использования и необходимости первичного обучения агента. Катастрофически много.

Между тем дома стоит Mac Studio M4 Max с 128 гигабайтами оперативки. На нём через Ollama крутится Qwen 2.5 72B – модель весом 77 гигабайт, абсолютно бесплатная, работающая локально. Логика простая: перенести Ильича домой, пусть думает на Qwen, а дорогие модели подключать через OpenRouter только для конкретных задач.

Теория – железная. Практика – отдельная история.


Нулевой круг: «Умная» гибридная архитектура

Прежде чем начать переезд, я придумал красивое решение. Зачем полностью мигрировать, если можно оставить Ильича на сервере, а вычислительную мощь Мака подключить через туннель?

Архитектура выглядела элегантно: – Beget: OpenClaw с Ильичом – там уже всё работает – Mac Studio: Qwen 2.5 72B через Ollama + Qdrant для векторного поиска – SSH-туннель: сервер обращается к Маку за вычислениями

На бумаге – идеально. Не нужно ничего переносить, Ильич продолжает работать, а дорогой Claude заменяется на бесплатный локальный Qwen.

На практике – полная катастрофа.

Каждый запрос Ильича проходил путь: Telegram → Beget → SSH-туннель → Mac → Ollama → Mac → туннель → Beget → Telegram. Latency складывалась на каждом этапе. Qwen 72B и без того думает медленно – добавь к этому сетевые задержки через туннель, и простой вопрос «как дела?» превращался в трёхминутное ожидание. Агент регулярно таймаутил на полуслове.

Вывод, который стоил нескольких часов экспериментов: компоненты одной системы должны жить рядом. Если модель и агент работают вместе – они должны быть на одной машине, в одной сети, в идеале в одном Docker-стеке. Любой сетевой прыжок между ними – это боль.

Решение пришло само собой: полный переезд на Mac. Всё вместе, всё локально.


Пятница, после обеда: «Это займёт полчаса»

Первый шаг – установить Docker на Mac. Это действительно заняло полчаса. Docker поставился, контейнер с OpenClaw собрался, запустился. Отлично.

Второй шаг – скопировать данные с Beget. Workspace Ильича: файлы памяти, инструкции, рабочие документы, личная история. Всё это должно переехать в правильное место.

scp -r root@00.000.00.000: openclaw/data/ /Users/openclaw/openclaw-data/data/

Команда отработала. Несколько сотен файлов скопировались. Казалось бы – готово.

Казалось бы.


Первый круг ада: права доступа

Запускаем Telegram-бот, пишем Ильичу. Тишина. Смотрим логи:

Error: EACCES: permission denied, mkdir '/node/.openclaw/agents/main/agent'

OpenClaw работает внутри Docker от пользователя `node`, а папки на хосте принадлежат другому пользователю. Классика. Решение – добавить `user: “0”` в docker-compose.yml, чтобы контейнер работал от root, и выдать права на папки:

sudo chmod -R 777 /Users/openclaw/openclaw-data/agents

Починили. Telegram-бот стартовал. Ильич ответил. Ура?

Не ура. Ильич ответил, но не знал кто он. Вместо «Привет, Сергей! Я Илья Ильич» – шаблонное «Привет! Как тебя зовут?»


Второй круг: файлы скопировались не туда

Оказалось, что при копировании данных с Beget папка `workspace` создалась внутри другой папки `workspace`. Матрёшка. Ильич смотрел в пустую директорию и честно не знал ничего о своей жизни.

Пересохранили в правильное место. Но тут выяснилась следующая проблема – OpenClaw в конфиге смотрел на путь `~/.openclaw/workspace`, а реальный путь был `/home/node/.openclaw/data/workspace`. Разные директории. Агент продолжал работать вхолостую.

Исправили путь в конфиге. Это потребовало ещё одного рестарта и ещё одного раунда отладки.

К этому моменту прошло часа три. Кофе закончился. Пора было наливать что покрепче…


Третий круг: OpenRouter не видит API-ключ

Следующая проблема пришла неожиданно. Попытались переключить Ильича с медленного Qwen на быстрый Gemini через OpenRouter:

Agent failed before reply: No API key found for provider "openrouter"

Начали искать где OpenClaw хранит API-ключи. Оказалось – в нескольких местах одновременно, в зависимости от версии и способа настройки:

1. В переменных окружения Docker (`OPENROUTER_API_KEY`) 2. В секции `env` файла `openclaw.json` 3. В файле `auth-profiles.json` в папке агента

Попробовали первый способ – не сработало. Попробовали второй – не сработало. Создали третий файл вручную – тоже не сработало (неправильный формат JSON).

Решение нашлось в документации OpenRouter: ключ нужен именно в секции `env` внутри `openclaw.json`. Но у нас на тот момент лежал конфиг с Beget, который перезаписал наши правки. После часа хождения по кругу – добавили правильно, перезапустили, заработало.

Урок первый: перед переездом сохраняйте резервную копию оригинального конфига и внимательно читайте документацию по порядку приоритетов настроек.


Четвёртый круг: Qwen 72B и таймауты

Когда наконец всё заработало, выяснилось главное: Qwen 72B на простой вопрос думает две минуты. OpenClaw по умолчанию ждёт 30 секунд, потом убивает запрос.

Подняли таймаут до 800 секунд. Но дело не только в этом. Qwen – мощная модель, но она не обучена следовать инструкциям так же точно как Claude. OpenClaw полагается на то, что агент при старте каждой сессии читает файлы SOUL.md, USER.md, MEMORY.md – это прописано в AGENTS.md. Claude делает это автоматически и аккуратно. Qwen – нет. Или делает, но медленно и непоследовательно.

В итоге: Qwen остался для тяжёлых аналитических задач и ночных кронов. Ильич перешёл на Gemini 2.5 Flash через OpenRouter – быстрый, дешёвый, умный, хорошо следует инструкциям.

Урок второй: выбор модели – это не только про качество ответов. Это про совместимость с тем как построен ваш workflow.


Пятый круг: pairing каждый раз заново

OpenClaw при первом подключении Telegram-пользователя требует «pairing» – верификацию через код. Логика понятная: безопасность. Но мы обнаружили странное: после каждого рестарта Docker-контейнера pairing сбрасывался и нужно было одобрять заново.

Проблема оказалась в архитектуре Docker: контейнер работал от `root`, но OpenClaw хранил данные pairing в папке для пользователя `node`. Пути не совпадали. Файл `telegram-default-allowFrom.json` существовал, но контейнер смотрел в другое место.

Решение нашлось в документации: вместо режима `dmPolicy: “pairing”` нужно использовать `dmPolicy: “allowlist”` и прописать свой Telegram ID напрямую в конфиге. Тогда pairing не нужен вообще.

"channels": {
  "telegram": {
    "dmPolicy": "allowlist",
    "allowFrom": ["0000000"]
  }
}

После этого изменения – рестарты перестали требовать повторной верификации.

Урок третий: для личного бота с одним владельцем `allowlist` безопаснее и удобнее чем `pairing`. Паринг хорош для публичных ботов с неизвестными пользователями.


Шестой круг: голосовые сообщения не транскрибируются

Одна из любимых фич Ильича – голосовые сообщения. Говоришь в телефон, он отвечает текстом. На Beget работало через Groq Whisper.

После переезда – перестало. Файлы скачивались, агент видел плейсхолдер `[media attached: file.ogg]`, но транскрипции не было.

Несколько часов отладки выявили два факта:

Факт первый – попытка использовать локальный Whisper через Ollama не работает. OpenClaw поддерживает аудио только через внешние провайдеры: OpenAI, Groq, Deepgram, Google. Ollama для аудио не поддерживается.

Факт второй – известный баг в OpenClaw: Telegram-плагин в некоторых версиях не вызывает `applyMediaUnderstanding` для голосовых сообщений. В нашей версии 2026.3.24 баг присутствовал.

Обходное решение – добавить `echoTranscript: true` в конфиг и убедиться что ключ Groq прописан в секции `env`. После этого транскрипция заработала.


Седьмой круг: Ильич забывает себя после рестарта

Самая обидная проблема обнаружилась в конце. Перезапускаем контейнер – Ильич «забывает» кто он. Вместо «Привет, Сергей» снова шаблонное приветствие.

Причина в пути workspace. В конфиге для агента `main` было прописано `~/.openclaw/workspace` – тильда раскрывалась в домашнюю директорию пользователя внутри контейнера. Реальный workspace лежал по другому пути.

OpenClaw должен автоматически инжектировать файлы SOUL.md, USER.md, AGENTS.md в системный промпт каждой сессии – это его архитектурная фича. Но только если workspace настроен правильно.

Исправление:

"agents": {
  "list": [
    {
      "id": "main", 
      "workspace": "/root/.openclaw/data/workspace"
    }
  ]
}

После этого изменения Ильич при каждом старте сессии правильно видит свои файлы, знает кто он, кто я, и что происходило в последние дни.


Восьмой круг: а если Telegram заблокируют?

Это не паранойя – это планирование. В России Telegram уже блокировали. В Европе периодически обсуждают регуляцию мессенджеров. У любого сервиса бывают технические сбои.

Когда вся коммуникация с Ильичом завязана на один канал – это точка отказа. Поэтому параллельно с Telegram мы подняли Matrix как резервный канал.

Matrix – это децентрализованный мессенджер с открытым протоколом. Главное его свойство: он работает на собственном сервере. Никакой зависимости от американских или европейских компаний. Никаких блокировок по IP. Адрес `@user:matrix.yourdomain.ru` – это моё, на моём домене, на моём железе.

OpenClaw поддерживает Matrix нативно – достаточно прописать адрес сервера и токен авторизации. Если Telegram завтра перестанет работать, Ильич продолжит отвечать в Matrix без какой-либо перенастройки.

Забавный момент: в логах Docker постоянно мелькала ошибка `[matrix] channel exited: Blocked hostname or private/internal/special-use IP address`. Matrix пытался подключиться к локальному адресу, который Docker блокирует по соображениям безопасности. Решается через `extra_hosts` в docker-compose.yml – но это отдельная история на следующий день.

Еще один урок: резервный канал связи с агентом – не излишество. Это страховка. Matrix на собственном домене занимает 30 минут на настройку и даёт полную независимость от внешних сервисов.


Девятый круг: как достучаться до Мака из любой точки мира

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

Решений несколько, мы выбрали Tailscale.

Tailscale – это VPN-сеть на базе WireGuard, которая работает через NAT без белого IP. Устанавливаешь на Mac и на телефон, входишь в один аккаунт – и они видят друг друга по стабильному адресу `100.x.x.x` независимо от того, где физически находятся устройства.

brew install tailscale

Три минуты установки, один аккаунт на всех устройствах – и Mac доступен из любой точки мира. SSH, Screen Sharing, доступ к веб-интерфейсу OpenClaw – всё работает как в локальной сети.

Бонус для параноиков: трафик между устройствами шифруется end-to-end на уровне WireGuard. Даже серверы Tailscale не видят содержимое.

Ещё один плюс: у нас дома есть камеры видеонаблюдения и NAS. Теперь все они в одной Tailscale-сети. Одно приложение решило несколько проблем сразу.

Урок девятый: для домашнего сервера Tailscale – стандартное решение. Бесплатно до 100 устройств, не требует белого IP, не конфликтует с другими VPN и сетевыми инструментами.


Бонус: Open WebUI


Десятый круг: RAG и Qdrant – память которая не забывает

Отдельная история – Qdrant. Это векторная база данных, и она стоит в стеке не просто так.

Проблема с языковыми моделями известная: у них есть «окно контекста» – ограниченный объём текста который они могут держать в памяти одновременно. Qwen 72B держит около 32 тысяч токенов. Звучит много, пока не начинаешь работать с реальными документами.

У меня в workspace Ильича лежат романы, исследовательские материалы, тексты книг, рабочие документы Просвещения – сотни мегабайт текста. Всё это физически невозможно запихнуть в контекст одного запроса.

Здесь приходит RAG – Retrieval Augmented Generation. Принцип простой:

1. Все документы разбиваются на маленькие куски (чанки) 2. Каждый кусок превращается в числовой вектор через embedding-модель 3. Векторы хранятся в Qdrant 4. Когда Ильич получает вопрос, он сначала ищет в Qdrant релевантные куски 5. Только найденные куски попадают в контекст запроса к модели

Вместо «прочитай все мои книги» – «вот три абзаца из твоих книг которые релевантны этому вопросу». Быстро, точно, экономно.

Для embedding мы используем `nomic-embed-text` – локальная модель через Ollama, бесплатная, хорошо работает с русским языком. Qdrant крутится в отдельном Docker-контейнере в том же стеке.

Qdrant сейчас пустой – это следующий этап: проиндексировать весь workspace Ильича, подключить семантический поиск по документам. Когда это будет сделано, Ильич сможет отвечать на вопросы опираясь на конкретные страницы из книг или рабочих материалов – не галлюцинируя, а цитируя реальный источник.

Почему это важно для домашнего сервера: облачные сервисы вроде NotebookLM или ChatGPT тоже умеют работать с документами. Но они хранят ваши данные на своих серверах. Корпоративные документы, черновики книг, личная переписка – всё это уходит во внешнюю систему. С локальным Qdrant на Mac Studio – данные никуда не выходят.


Итог: что работает

К 3 часам ночи субботы система выглядела так:

  • Mac Studio M4 Max – хост для всего
  • Docker – изолированная среда для OpenClaw
  • OpenClaw 2026.3.24 – платформа агента
  • Ильич – агент с полным контекстом и памятью
  • Telegram – основной канал общения
  • Gemini 2.5 Flash через OpenRouter – основная модель (быстро, дёшево)
  • Qwen 2.5 72B через Ollama – для тяжёлых задач (бесплатно, медленно)
  • Groq Whisper – транскрипция голосовых
  • Qdrant – векторная база для семантического поиска по документам (следующий этап)
  • Matrix – резервный канал связи на собственном домене
  • Tailscale – удалённый доступ к Маку из любой точки мира
  • Open WebUI – локальный ChatGPT для работы с документами и экспериментов

Сервер на Beget остановлен. Docker-контейнер поднимается автоматически при перезагрузке Mac.


Чеклист для тех кто хочет повторить подвиг

Если вы планируете поднять OpenClaw на своём железе или мигрировать с облака – вот что стоит сделать правильно с первого раза:

Перед началом: – сохраните резервную копию `openclaw.json` с рабочего сервера – Запишите все API-ключи в отдельный файл – Проверьте какая модель была основной и почему

Docker: – Если запускаете от `root` (`user: “0”`), убедитесь что все пути в volumes используют `/root/` а не `/home/node/` – Выдайте права на папки данных: `chmod -R 777` для начала, потом можно ужесточить – Проверьте что workspace агента смонтирован явно, а не только через общую папку data

API-ключи: – OpenRouter ключ прописывайте в секцию `env` внутри `openclaw.json` – это работает надёжнее переменных окружения Docker – Groq ключ туда же: `”GROQ_API_KEY”: “gsk_…”`

Telegram: – для личного бота используйте `dmPolicy: “allowlist”` с вашим Telegram ID – избавитесь от постоянного pairing – Ваш Telegram ID можно узнать написав боту `@userinfobot`

Workspace: – прописывайте абсолютный путь workspace в конфиге агента, не используйте тильду – Проверьте что агент реально видит файлы: `docker exec openclaw ls /путь/к/workspace/`

RAG и Qdrant: – Держите Qdrant в том же Docker-стеке что и OpenClaw – не в отдельном месте – Для embedding используйте локальную модель (nomic-embed-text через Ollama) – бесплатно и работает с русским – Индексируйте документы сразу после переезда, пока не забыли – потом будет лень

Архитектура: – не пытайтесь соединять агента и модель через сеть – это медленно и ненадёжно – Всё что работает вместе должно жить вместе: один хост, один Docker-стек – Claude следует инструкциям из AGENTS.md автоматически; другие модели – не всегда – Qwen 72B Q8 требует 77GB RAM и медленный; хорош для batch-задач, не для интерактива – Gemini 2.5 Flash – оптимальный выбор для повседневного агента в 2026


Главный вывод

Все эти полтора суток можно было бы сократить до четырёх часов, если бы я сразу:

1. Внимательно прочитал документацию по путям и монтированию томов 2. Не пытался угадать формат конфигов, а смотрел в оригинальный рабочий файл 3. Понял архитектурное различие между Claude и другими моделями в контексте OpenClaw

Но именно такие дни дают понимание которое не даст никакая документация. Теперь я знаю эту систему изнутри.

Ильич работает. И помнит кто он.


Написано при участии Ильича, Клода и полутора суток терпения

Вам также может быть интересно:
Далее

Экосистемная война: кто управляет ИИ-агентами и почему это политика, а не технология

«Кто управляет информацией, управляет будущим. Кто управляет доступом к информации – управляет настоящим.»– Барух Спиноза (переосмыслено для эпохи…