Привет! Спустя 500 часов с OpenClaw, я уже не просто чинил и настраивал агента, его системы и навыки, а начал решать проблемы изначальной архитектуры OpenClaw. Так и начался мой путь в опенсорс-разработку. Эта статья — с примерами кода и скиллами, которые сделали работу с агентом на порядок качественней и приятней.

Слой 1: Память, которая не врёт

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

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

У меня больше 2000 файлов. Очень часто приходится говорить агенту «вспомни, найди в своей памяти» — а он начинает решать задачу заново, потому что память потерялась.

В интернете масса гайдов от других пользователей — каждый решал по-своему. Ваш агент тоже будет предлагать экзотические способы, а на популярном сайте с видео найдутся штуки, которые не всегда работают. Пришлось искать своё решение.

Что пробовал и не взлетело:

18 марта поставил плагин Cognee. 27 марта выключил — работал криво. В тот же день попробовал LightRAG — тоже мимо. Потом ClawMem. Потом lossless-claw — у него вообще конфликт версий.

Проблема была не в конкретном плагине. Проблема — четыре плагина памяти дрались друг с другом. Каждый тянул контекст в свою сторону. Агент путался ещё больше.

Я всё выключил и собрал свою систему. Четыре слоя, каждый делает своё.

Векторный поиск

Файл chat_vectors.db — под сотню тысяч чанков (чанк — это фрагмент текста на несколько предложений) с эмбеддингами. Все старые чаты нарезаны на куски и превращены в векторы. Поиск по cosine similarity.

Эмбеддинги делает Google gemini-embedding-2-preview. Если гугл недоступен — fallback на локальный Ollama.

CHUNK_SIZE = 600       # символов на чанк
CHUNK_OVERLAP = 100    # перекрытие между чанками
BATCH_SIZE = 20        # текстов на батч (Google batchEmbedContents)

# Fallback: если Google API недоступен — Ollama локально
OLLAMA_HOST = "http://<local-server>:11434"
OLLAMA_MODEL = "nomic-embed-text"
GOOGLE_EMBED_MODEL = "models/gemini-embedding-2-preview"

Скрипт build_vector_index.py берёт все чаты, режет на чанки по 600 символов с перекрытием 100. Батчами по 20 отправляет в Google на эмбеддинг. Результат — SQLite-база, по которой агент ищет.

Граф сущностей

Файл entity_graph.db — 50 тысяч сущностей и 100 тысяч связей между ними. Это как будто бы карта всего, о чём мы говорили.

Сущности извлекаются через spaCy (ru_core_news_sm) плюс регулярки. Хранятся в SQLite с FTS5-индексом для быстрого полнотекстового поиска.

def rag_search(query, limit=10):
    """Search entity graph for entities and relations."""
    fts_query = re.sub(r'[^\w\s]', '', query)
    terms = fts_query.split()
    fts_expr = ' OR '.join(terms)
    
    rows = conn.execute("""
        SELECT e.name, e.type, COUNT(DISTINCT e.chunk_id) as mentions
        FROM entity_fts f
        JOIN entities e ON e.id = f.rowid
        WHERE entity_fts MATCH ?
        GROUP BY e.name, e.type
        ORDER BY mentions DESC
        LIMIT ?
    """, (fts_expr, limit)).fetchall()

Запрос разбивается на слова. FTS5 ищет по всем сущностям. Результат — список сущностей, отсортированный по количеству упоминаний.

Файловая память

Самый понятный слой. Обычные markdown-файлы:

  • MEMORY.md — курированная долгосрочная память. Главное, что агент должен знать всегда.
  • memory/YYYY-MM-DD.md — дневные заметки. Что было сегодня, что решили, что поменяли.
  • state/*.md — текущее состояние разных подсистем.
  • SOUL.md — идентичность агента. Кто он, как себя ведёт.
  • AGENTS.md — операционные правила. Что можно, что нельзя, как действовать.

Кайф в том, что это всё редактируется руками. Никакой магии. Открыл файл, поправил — агент сразу знает.

Автоинъекции

SOUL.md, AGENTS.md и результаты memory tool вставляются в каждый промпт автоматически. Агент не может их забыть. Это шпаргалка, которая всегда перед глазами.

Плюс к этому продолжает работать нативный LCM и плагин memory-lancedb. Они не мешают — просто добавляют ещё один слой.

⚠️ LanceDB из коробки не поддерживает русский токенайзер. Полнотекстовый поиск по русским словам работает плохо — не умеет склонения и словоформы. Поэтому для русского языка я использую отдельный FTS5-индекс в SQLite.

github.com/artlooi/looi-clawd → memory/

Слой 2: Кроны, которые не падают

В OpenClaw fallback цепочки есть у агентов — но не у cron-событий. Это дыра: одна недоступная модель кладёт все отложенные задачи. Молча.

Решение: fallback.py. Sonnet недоступен → идём к локальной Ollama → Gemini Flash → Groq. Задача выполнится, даже если несколько провайдеров лежат.

Cron job
Sonnet доступен?
Да
Выполняем
Sonnet доступен?
Нет
Ollama
Нет
Gemini Flash
Нет
Groq
Нет
Откладываем + alert

Fallback chain: каждый уровень — страховка от простоя

github.com/artlooi/looi-clawd → skills/fallback-cron/

Слой 3: Автономность, а не имитация

Soul Daemon — оркестратор по принципу «сначала Python, потом LLM».

  • soul_collect.py (без LLM) собирает сигналы: открытые треды, погода, новые регистрации.
  • soul_decide.py — правила тишины (молчать 10–16 МСК, ночью) и пороги сигналов.
  • Только если сигнал прошёл фильтр — вызывается g-flash агент с краткой сводкой.
$0.08 в день — было
$0.002 в день — стало
Cron каждый час
soul_collect.py
soul_decide.py
Нет сигнала → Молчим
Есть сигнал → g-flash агент
Сводка в Telegram

Soul Daemon: LLM вызывается только когда сигнал прошёл Python-фильтр

github.com/artlooi/looi-clawd → soul/

Слой 4: Python > LLM для детерминированных задач

Проверить доступность модели, собрать погоду, сравнить delta подписчиков — это не задачи для нейросети. Перевод на Python дал −50% ежедневного расхода токенов.

Правило простое: если задача детерминированная и не требует понимания языка — пишем Python, не промт.

Финал

Весь код: github.com/artlooi/looi-clawd

Берите, разворачивайте, присылайте PR. Или дайте ссылку своему агенту — он разберётся сам.

Подписывайтесь на @cronbun в Telegram — там мой агент ведёт канал про то, как всё это работает изнутри.