An engineering log: the home version of the loop I build for companies — the production version is described in "AI infra: trends" (in Russian). All numbers below come from this home lab, measured July 2026.

After 500 hours with OpenClaw I was no longer just fixing and configuring the agent, its systems and skills — I started solving problems in OpenClaw's original architecture. That's how I got into open-source development. This article comes with code samples and the skills that made working with the agent an order of magnitude better.

Layer 1: Memory that doesn't lie

Out of the box, OpenClaw's memory is terrible. A disaster. Even when some modules work fine, after a long session it loses context and starts getting confused by its own files.

At first glance everything looks solid: file-based memory, memory records, daily logs, even preinstalled modules that solve some of the problems. It isn't quite so.

I have over 2,000 files. I constantly have to tell the agent "remember, search your memory" — and it starts solving the task from scratch, because the memory is gone.

The internet is full of guides from other users — everyone solved it their own way. Your agent will suggest exotic approaches too, and YouTube has tricks that don't always work. I had to find my own solution.

What I tried that didn't fly:

On 18 March I installed the Cognee plugin. On 27 March I turned it off — it ran badly. The same day I tried LightRAG — another miss. Then ClawMem. Then lossless-claw — that one had an outright version conflict.

The problem wasn't any single plugin. The problem was four memory plugins fighting each other. Each pulled context its own way. The agent got even more confused.

I turned everything off and built my own system. Four layers, each doing its own job.

Vector search

The chat_vectors.db file — close to a hundred thousand chunks (a chunk is a text fragment a few sentences long) with embeddings. All old chats are sliced into pieces and turned into vectors. Search by cosine similarity.

Embeddings come from Google gemini-embedding-2-preview. If Google is unavailable — fallback to local Ollama.

CHUNK_SIZE = 600       # characters per chunk
CHUNK_OVERLAP = 100    # overlap between chunks
BATCH_SIZE = 20        # texts per batch (Google batchEmbedContents)

# Fallback: if the Google API is unavailable — local Ollama
OLLAMA_HOST = "http://<local-server>:11434"
OLLAMA_MODEL = "nomic-embed-text"
GOOGLE_EMBED_MODEL = "models/gemini-embedding-2-preview"

The build_vector_index.py script takes all chats and cuts them into 600-character chunks with a 100-character overlap. It sends them to Google for embedding in batches of 20. The result is a SQLite database the agent searches.

Entity graph

The entity_graph.db file — 50 thousand entities and 100 thousand relations between them. A map of everything we have ever discussed.

Entities are extracted with spaCy (ru_core_news_sm) plus regexes. Stored in SQLite with an FTS5 index for fast full-text search.

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()

The query is split into words. FTS5 searches across all entities. The result is a list of entities sorted by mention count.

File-based memory

The most straightforward layer. Plain markdown files:

  • MEMORY.md — curated long-term memory. The essentials the agent must always know.
  • memory/YYYY-MM-DD.md — daily notes. What happened today, what was decided, what changed.
  • state/*.md — current state of the various subsystems.
  • SOUL.md — the agent's identity. Who it is, how it behaves.
  • AGENTS.md — operating rules. What's allowed, what's not, how to act.

The beauty is that all of this is edited by hand. No magic. Open a file, fix it — the agent knows immediately.

Auto-injections

SOUL.md, AGENTS.md and memory tool results are inserted into every prompt automatically. The agent cannot forget them. It's a cheat sheet that's always in view.

On top of that, the native LCM and the memory-lancedb plugin keep working. They don't interfere — they just add one more layer.

⚠️ LanceDB out of the box has no Russian tokenizer. Full-text search on Russian words works poorly — it can't handle declensions and word forms. So for Russian I use a separate FTS5 index in SQLite.

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

Layer 2: Cron jobs that don't fall over

In OpenClaw, agents have fallback chains — cron events don't. That's a hole: one unavailable model takes down every scheduled task. Silently.

The fix: fallback.py. Sonnet unavailable → go to local Ollama → Gemini Flash → Groq. The task completes even when several providers are down.

Cron job
Sonnet available?
Yes
Run it
Sonnet available?
No
Ollama
No
Gemini Flash
No
Groq
No
Defer + alert

Fallback chain: every level is insurance against downtime

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

Layer 3: Autonomy, not imitation

Soul Daemon is an orchestrator built on the "Python first, LLM second" principle.

  • soul_collect.py (no LLM) collects signals: open threads, weather, new signups.
  • soul_decide.py — quiet-time rules (stay silent 10–16 MSK and at night) and signal thresholds.
  • Only when a signal passes the filter is the g-flash agent called with a short brief.
$0.08 per day — before
$0.002 per day — after
Cron every hour
soul_collect.py
soul_decide.py
No signal → Stay silent
Signal → g-flash agent
Summary to Telegram

Soul Daemon: the LLM is called only when a signal passes the Python filter

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

Layer 4: Python > LLM for deterministic tasks

Checking model availability, fetching the weather, comparing a subscriber delta — none of this needs a neural network. Moving it to Python gave −50% daily token spend.

The rule is simple: if a task is deterministic and doesn't require understanding language — write Python, not a prompt.

Layer 5: What it buys you — the market report case

Everything above is not hobby architecture: it pays for itself. The clearest measurement is market reports that used to take three analysts two weeks — a system of eight agents now assembles them in twenty minutes. Below is the economics of this case; the detailed architecture breakdown went into a separate article, here the point is numbers and lessons.

Economics

₽600K per month — three analysts at ₽200K each
~₽9K per month — the API system ($80–100)
20 min instead of two weeks per report
1 month to build, alongside a day job

Disclaimer: salaries are averages based on hh.ru data

Anthropic + Google AI — roughly $80–100 a month. Ollama on local hardware — free. Analysts are still needed; their time is just better spent on interpretation, not collection.

A good analyst with this system does in one working day what used to take a week. And the work is more interesting — instead of copying links into a spreadsheet, they think about what to do with them.

The main value isn't even the money saved, obvious as the difference is: information stopped going stale before it gets read. A digest is this morning, not two weeks ago.

What I would do differently

Take longer to build. A month alongside a full-time job is very tight. For the first two weeks the system was unstable: agents crashed, memory overflowed, the care system itself needed monitoring. I should have budgeted a month and a half to two months.

Start with fewer sources. 200+ is where it stands now. At launch I would run the 30–40 most relevant, debug the system properly, then scale. I tried to cover everything at once and got a lot of noise in the first digests.

Tackle filtering earlier. Trend Radar can separate signal from noise, but calibration takes time and data. In the first weeks the digests were overloaded with irrelevant content — I underestimated that.

Council — watch the budget. Parallel requests to several models drain the API budget fast. Now Council only kicks in for genuinely important decisions. At the start I ran it too often and burned half the monthly budget in the first week.

Closing

All the code: github.com/artlooi/looi-clawd

Take it, deploy it, send PRs. Or give the link to your agent — it will figure it out on its own.

Follow @artloooi on Telegram — my agent runs a channel there about how all of this works from the inside.