I have always been passionate about programming.
When I finished high school in 2007, there was only one thing I wanted to study: software engineering. I did not want to study anything else. This was long before becoming a programmer was mainstream — before software engineering was presented as a guaranteed path to a well-paid career.
I enrolled in Software Engineering and Information Technologies simply because I wanted to build things with code.
The excitement I felt whenever I created something non-trivial was insane. I still remember writing my first recursive function and implementing my first binary tree. These may look like small achievements in hindsight, but at the time they felt like discovering a new kind of power.
You begin with an empty file. Then, through logic and imagination, you create something that works — something that did not exist before.
That feeling was pure euphoria.
And it never left me.
Every new challenge brought back the same feeling: learning a new language, building a backend, working with SQL, and later exploring NoSQL databases.
At university, when we started learning design patterns, I wanted to go far beyond passing the exam. I implemented examples of all 23 Gang of Four design patterns in both Java and Python.
I wanted to master what felt like an extremely complex topic. More importantly, I wanted to understand how the same design ideas changed across two fundamentally different languages.
Python supports multiple inheritance. Java does not, although interfaces allow you to model similar relationships in a different way. A pattern that feels natural in one language can feel unnecessary or forced in another. That experience taught me something I still believe today: patterns are not recipes to copy. They are ideas whose implementation depends on the language, the problem, and the surrounding model.
That was a turning point for me. I became obsessed with clean code and with finding solutions that were simple, expressive, and easy to extend.
I remember implementing a queen in a chess model by inheriting the movement capabilities of both a rook and a bishop. One line of code expressed the domain rule clearly: a queen combines both behaviors.
During a hackathon, I used a max-heap to track the highest expenditure. After building the correct structure, retrieving the maximum required a single line and constant time, O(1).
Those moments may sound small, but this is what I love about software engineering. A good model can make a difficult problem suddenly look obvious.
I kept searching for harder challenges, and eventually I encountered my first truly big one.
Together with my colleagues, I took responsibility for organizing the development of a no-code platform that marketers could use to build gamified campaigns. It was a serious technical and organizational challenge. We had to establish the architecture, solve difficult engineering problems, and prepare the platform for major clients in the pipeline, including SEAT and McDonald's.
I designed the initial microservice architecture and eventually moved into the role of CEO of the R&D department, leading around 30 engineers.
Almost everything meaningful I have accomplished came from the same habit: accepting responsibility for a challenge before I completely knew how to solve it.
But accepting responsibility does not mean you always get it right.
I did not design the microservice boundaries properly. The system worked, but the architecture accumulated problems because our services were not separated around the right business boundaries.
That failure became the beginning of the next stage of my journey.
When I left the CEO position to build my own startup, I began learning Domain-Driven Design. I had heard that DDD addressed exactly the kind of problem I had created in production: how to discover meaningful boundaries and split a complex system around the domain rather than around technical convenience.
Then I opened Eric Evans' Domain-Driven Design — the Big Blue Book — and an entirely new world appeared.
I started realizing that, despite having led 30 engineers, my understanding of software design was still barely at the mid-level. Management responsibility and engineering maturity are not the same thing.
Learning DDD raised my understanding more than anything I had studied before. It gave meaning to object-oriented programming, design patterns, encapsulation, and software architecture. These were no longer isolated techniques. They became tools for discovering, expressing, and protecting the rules of a real domain.
I stopped seeing software as a collection of features and infrastructure. I started seeing it as an executable model of a problem.
Years later, when I started building a TypeScript framework for multi-agent systems, I used Domain-Driven Design to tackle the complexity.
That decision was critical because we were not trying to reproduce the existing way of building agent workflows. We set the highest possible bar: enable developers to build AI agents that operate concurrently, react to events, and do not block one another.
We are discovering the necessary concepts through implementation, iteration, and continuous refactoring. The model is not something we designed once on a whiteboard. It is emerging as our understanding of the problem grows.
Many people may consider this overengineering. We see the difficulty as the opportunity.
Many available frameworks arrange a sequence of LLM calls and call the result a multi-agent system. From our perspective, that abstraction is too trivial to be genuinely useful for the systems that are coming next.
If agents and subagents are hardcoded into a workflow, they are difficult to reuse, replace, and share with other developers. They remain coupled to the process in which they were created.
In Mozaik, agents are non-blocking participants rather than steps in a predefined workflow. They are isolated from the process and react independently to semantic events. This creates a loosely coupled system and opens the path toward genuine agent interoperability.
Sequential workflows also increase execution time and waste resources because agents spend much of their time waiting for one another. Mozaik addresses this by allowing independent agents to act concurrently whenever relevant events occur.
We are also introducing advanced ways to control and intercept the agent loop. Agents will be able to intervene in one another's execution at runtime, creating possibilities that fixed workflows cannot provide.
Software design still matters because every decision inside a framework affects every application built on top of it.
The next version of Mozaik is almost ready. Non-blocking agents and concurrency increase complexity, but they also unlock far more powerful systems.
We are introducing shared runtime state for AI agents — conceptually similar to Redux in React — so every participant can work with current information while agents operate concurrently.
We created a structured way for agents to react to a combination of events and shared state. We call this concept a Situation.
We are introducing Interception, which allows participants to intercept and influence one another during runtime.
The system is dynamic: participants and behaviors can be replaced at runtime instead of being permanently wired into a fixed graph.
We are building the most sophisticated TypeScript framework for concurrent AI agents, and we reject the idea that what happens under the hood is no longer important.
Design choices matter.
Software development is not dead.
AI should help us build higher-quality software — not merely produce more software faster.
This is what we are betting on, and we are confident that we will win.
If you share this belief — if you are passionate about software engineering and want to push the boundaries of what can be built with AI agents — let's connect.
Join our online hackathon on September 5–6 and build a concurrent multi-agent system with Mozaik.
Register for the Mozaik hackathonLet us reject the premise that the future has already been decided. Let us push the boundaries together and build something that has not existed before.
With tools and technology we already have, we can build much more valuable systems than most projects today. We can write software that is a pleasure to use and a pleasure to work on; software that doesn't box us in as it grows, but creates new opportunities and continues to add value for its owners.
Newsletter
For developers who want to learn how to build self-organizing agents.
Join our online hackathon
Join our online hackathon for building multi-agent systems.