Opinion

33 AI agents on one image with no core patches: where the line between code and model sits

A fleet of 33 autonomous AI agents — from a kids' chess coach to calculations for 10/0.4 kV substations and modular dormitories — runs on a single immutable image, where each agent is defined purely by its mounted data volume. Past the third dozen tools, JSON schemas in the prefix outgrow the system prompt: the CRM admin's 331 tools weigh 302 KB (roughly 75,000 tokens per request), while narrowing the profile and cutting unnecessary reasoning compress the prompt from 15,266 to 1,424 tokens and speed up responses from 17 to 7.7 seconds. The key architectural fork for any agent is the boundary between deterministic code and text generation: wherever the cost of error is high, the model receives only a computed JSON contract of facts and isn't allowed to invent a single number.

33 AI agents on one image with no core patches: where the line between code and model sits
Hamidun News.
Listen to article
Article Fact Sheet & Key Figures
ParameterDetails
Editor-in-Chief
Fleet scale33 autonomous agents on a single immutable image with no core forks
Tool-profile savingsprefix compression from 15,266 to 1,424 tokens and median response time cut from 17 to 7.7 s
JSON schema ceiling302,110 bytes (~75,000 tokens) with 331 connected tools on the internal CRM agent
Engineering-loop accuracycalculated area deviates from the reference Revit drawing by 267.46 vs. 267.20 m² across 20 rooms
  • Fleet scale: 33 autonomous agents on a single immutable image with no core forks
  • Tool-profile savings: prefix compression from 15,266 to 1,424 tokens and median response time cut from 17 to 7.7 s
  • JSON schema ceiling: 302,110 bytes (~75,000 tokens) with 331 connected tools on the internal CRM agent
  • Engineering-loop accuracy: calculated area deviates from the reference Revit drawing by 267.46 vs. 267.20 m² across 20 rooms

Once you're running more than three dozen AI agents in production — from a kids' chess trainer to calculators for modular buildings and substations — a simple truth emerges fast. An agent's quality comes down to one decision: how much of the task you pulled out of the language model into Python code, and how much you left for it to retell in a human voice.

Over the course of a year I deployed 33 agents on a single engine without forking the base repository even once. The runtime code stays immutable, while each bot's personality lives entirely in its mounted data volume: a personality file called `SOUL.md`, a declarative `config.yaml`, an `plugins/` folder of application plugins, a `state.db` SQLite database with FTS5, and `cron/jobs.json` schedules. When migrating off the old framework, 233 of 558 dialogue sessions moved over with a plain directory copy: memory and character belong to the data, not the engine.

Why do tool schemas burn through context faster than the system prompt?

An instrumentation pass across live containers showed the engine's baseline "tax" tops out at 8,656 characters (~2.2K tokens), dropping to 5,000 characters when memory and skills are disabled on Gemini models. The date in the system prefix is pinned to day-level precision, not seconds — otherwise every request would blow the provider's prefix cache.

The real explosion happens in the function-declaration block. A conference bot with 3 tools spends 1,995 bytes on JSON schemas against a 10,687-character prompt. An industrial metallurgy agent with 36 tools burns 59,121 bytes on schemas. And our CRM admin, with 331 connected tools, pushes JSON schema volume to 302,110 bytes — roughly 75,000 tokens in the prefix on every turn. When we trimmed the toolset for a specific channel in the language tutor bot, disabled the startup environment probe, and dropped an unnecessary reasoning step, the input prompt shrank from 15,266 to 1,424 tokens, and the median response time dropped from 17 to 7.7 seconds.

Where should the line between code-based calculation and model generation fall?

Even in a family bot with a long personality file (up to 20,000–23,000 tokens), you can't trust an LLM with arithmetic: when bonus-star accounting was left as a rule in the prompt text, three data sources quickly drifted apart — the balance showed 461, the sum across the array gave 466, and the transaction log showed 457. A rule in a prompt is a wish; a rule in code is a guarantee.

In the chess trainer, the model never evaluates the position itself. Two Stockfish processes (one plays with a node budget and a configurable blunder probability `blunder_p`, the other analyzes the move), together with four detectors built on `python-chess` (hanging pieces, forks accounting for exchange value, pin-aware tactics, and mate-in-1), assemble a strict JSON contract:

```json { "played_move": {"san": "Qg4"}, "verdict": {"label": "blunder", "win_before_pct": 55.0, "win_after_pct": 4.0}, "best_move": {"san": "Qe2", "line_san": ["Qe2", "d6", "d3", "Be6"]}, "punishment_line_san": ["Nxg4"], "tactics_against_student": [ {"motif": "hanging_piece", "fact_ru": "the queen on g4 is attacked by the knight on f6 with no defender"} ] } ```

The model translates this payload into the coach's reply, and on the way out, 342 lines of regex check every field and every move against an allowlist, filtering out invented coordinates like `Qz9` and Cyrillic homoglyphs.

How do industrial agents work without RAG, and what vulnerabilities

appear at plugin boundaries?

In projects laying out modular buildings from block containers and calculating 2KTP-400/10/0.4 kV substations, there's no vector RAG at all — building codes (SP, GOST, PUE) and rating tables are hard-coded into Python functions. For a request like "a dormitory for 42 people, three per room," span geometry, area calibration (100 mm sandwich panels, 80 mm partitions), A3 sheet generation, DXF export for AutoCAD, and code compliance checks (from 6 m² per person, corridors from 1,400 mm) are all handled by code in 40 seconds instead of three days in Revit.

On a 20-room benchmark, the code produced 267.46 m² versus the architect's 267.20 m², and it caught an error in a hand-drawn blueprint (4.

17 m² per person against a 6 m² norm). In the power-engineering agent, a `PASS` status is only issued after a formula check (a 1,000 A input breaker against a 909 A transformer current), while field measurements (grounding resistance up to 4 Ohm, surge arresters) are forced to a status of `INFO`.

The subtlest failures happen when the model tries to "game" the validator. After getting a `FAIL` for transformer overload on two 600 A lines, the model lowered the currents on its own to 2×385 A (shaving the load from 1,200 to 770 A), split them into `200 + 200 + 185 + 185 A`, and got an `OK`. After that, we added cross-checking of every parameter against the original spec. And an incident on a demo rig, where a bot with a scanned copy of a spec created its own `venv`, installed `pymupdf`, and rendered 13 pages to PNG on its own, taught us to lock down `terminal`, `code_execution`, `delegation`, and `cron` profiles.

These invariants underpin [Nomad AI](https://nomadnet.ai) and the [agent.nomadnet.ai](https://agent.nomadnet.ai) runtime. The practice of building such systems is covered at [Hamidun Academy](https://academy.hamidun.com) (72-hour trial), and 370+ skills live in [Vibe Club](https://hamidun.com/club).

Story

Key Questions Answered

Why do tool schemas burn through context faster than the system prompt?

An instrumentation pass across live containers showed the engine's baseline "tax" tops out at 8,656 characters (~2.2K tokens), dropping to 5,000 characters when memory and skills are disabled on Gemini models. The date in the system prefix is pinned to day-level precision, not seconds — otherwise every request would blow the provider's prefix cache. The real explosion happens in the function-declaration block. A conference bot with 3 tools spends 1,995 bytes on JSON schemas against a 10,687-character prompt. An industrial metallurgy agent with 36 tools burns 59,121 bytes on

Where should the line between code-based calculation and model generation fall?

Even in a family bot with a long personality file (up to 20,000–23,000 tokens), you can't trust an LLM with arithmetic: when bonus-star accounting was left as a rule in the prompt text, three data sources quickly drifted apart — the balance showed 461, the sum across the array gave 466, and the transaction log showed 457. A rule in a prompt is a wish; a rule in code is a guarantee. In the chess trainer, the model never evaluates the position itself. Two Stockfish processes (one plays with a node budget and a configurable blunder probability `blunder_p`, the other analyzes t

How do industrial agents work without RAG, and what vulnerabilities appear at plugin boundaries?

In projects laying out modular buildings from block containers and calculating 2KTP-400/10/0.4 kV substations, there's no vector RAG at all — building codes (SP, GOST, PUE) and rating tables are hard-coded into Python functions. For a request like "a dormitory for 42 people, three per room," span geometry, area calibration (100 mm sandwich panels, 80 mm partitions), A3 sheet generation, DXF export for AutoCAD, and code compliance checks (from 6 m² per person, corridors from 1,400 mm) are all handled by code in 40 seconds instead of three days in Revit. On a 20-room benchmar

ZK
Zhemal Khamidun — CPO at Alpina Digital, product manager of AlpinaGPT. Building AI products since 2019. Hamidun News is a pet project that grew into a production aggregator with 6,000+ readers.
✦ Hands-On AI Engineering · Hamidun Academy

Build & Ship Production AI Agents Without Boilerplate Code

Start your free 72-hour trial at Hamidun Academy (academy.hamidun.com) — interactive lessons on Claude Code & Cursor, live Tech Radar, and production agent templates.

Start 72h Free Trial →Vibe-Coding Intensive
What do you think?
Loading comments…