
Control your own data – Develop and share knowledge – Create your digital self

Control your own data – Develop and share knowledge – Create your digital self
(Including Language Models and Agents)
We often say we want things to be cheaper: services, tools, housing, food. But if we look at how actors, agents, and processes are actually rewarded in our economic systems, there is very little real incentive for anything to become cheaper. In many cases, the system as a whole rewards higher prices and higher costs.
Who has an interest in low prices? An actor is interested in lower prices when they are buying something. As a customer, you benefit directly from cheaper goods and services. But the same actor has the opposite interest when they are selling, producing, or delivering something. Then higher prices and higher margins are better. This seems illogical at first, because you might think everyone would be interested in lower costs and prices in general. In reality, the interest flips depending on whether you are buyer or seller.
This is reinforced by how incentives, rewards, pricing models, and sales models are designed. They usually give better returns when prices and costs go up, not when they go down. The system as a whole now rewards increased cost. When prices rise, the value of property, assets, shares, currency – almost everything – goes up on paper. That looks good in portfolios, balance sheets, and valuations. It also means nobody is really rewarded for making things cheaper. Lower prices can be a threat, because they can reduce the measured value of what people and institutions already own.
The same dynamic hits agents and the language model industry, maybe even harder than some other areas. There is a lot of investment involved in building and running these systems: infrastructure, research, engineering, integration. When so much money is invested, there is pressure to sell services at a high price to “justify” the investment. In principle, you could invest a lot and still sell cheaply. But it cannot really become a trend that prices and costs go down steadily. If that happened, it would signal that the earlier investments and high valuations were not necessary or were overestimated. So the industry tends to protect higher prices instead of embracing falling costs.
To keep all of this going, more and more debt is taken on. People, companies, and states borrow money, which helps drive prices up even more. Debt allows actors to pay higher prices for a while, and supports rising valuations of assets and services. Over time, prices rise to the point where fewer and fewer can afford what they need. Housing, services, tools, and advanced systems become too expensive. At some point, the debt and the high price levels cannot be supported anymore, and the whole structure risks collapsing.
This logic affects how language models and agents are developed and offered. Technically, these systems could become cheaper and more accessible over time. But as long as incentives and rewards are tied to higher prices, higher valuations, and defending large investments, there is little reason for the industry to push costs down for everyone. The result is a system that does not naturally move toward “cheap and accessible,” but instead keeps moving toward “expensive and exclusive,” until almost nobody can afford it and the system breaks.
Letting a language model directly change data, call APIs or touch production systems can be powerful, but it is also risky and hard to reason about. A simple pattern to make this safer and more transparent is to separate “deciding what to do” from “actually doing it”. Instead of letting the model perform actions directly, you first let it generate explicit instructions for actions, and only then interpret those instructions and execute them.
In this pattern, the model never performs actions itself. Its responsibility is to describe the actions that should be taken. It receives a user request and responds with a set of instructions in a structured, predictable format. There are no direct API calls, no hidden side effects, only a clear description of intent.
To make these instructions reliable and machine-friendly, you use a domain specific language (DSL) for instructions and actions. The DSL defines how actions are represented: which actions exist, what parameters they take, which resources they operate on, and what constraints apply. For example, an instruction might look like a JSON object such as:
{ "action": "update_user", "params": { "user_id": "123", "fields": { "email": "new@example.com" } } }
The important point is that the model outputs this DSL, not raw API calls or free-form text describing side effects.
After the model has generated instructions in the DSL, a separate component is responsible for interpreting and executing them. This interpreter reads the DSL, validates it, and then maps each instruction to real actions in your system. For example, it might translate update_user into a call to a user service, or send_email into a call to your email provider. The interpreter also enforces rules: checking required fields, rejecting unsafe actions, enforcing permissions, and deciding what happens on errors.
This creates a clear two-step process. First, the model generates instructions for actions in a domain specific language. Second, the system interprets those instructions and executes the corresponding actions. The model does not perform anything directly. All side effects go through the interpreter and runtime.
Using this pattern has several practical benefits. It increases safety, because you can review or validate instructions before executing them. It improves observability, because you can log and inspect the exact instructions that were generated. It helps with debugging and testing, because you can replay instructions or run them in a dry-run mode without touching real systems. And it makes your setup more flexible, because you can change how actions are executed without changing how the model describes them.
In summary, instead of letting a language model act directly, let it generate instructions in a domain specific language, and then interpret and execute those instructions in a controlled way. This keeps the original idea from the notes: let agents generate instructions for actions, do not perform directly, then interpret the instructions and execute the actions, using a domain specific language for both instructions and actions.
When you build agents, or set up several agents and human actors to work together, you have to assume that everything can be misunderstood. Misunderstandings are not rare errors; they are the default. Instructions will be read differently than you intended, roles will be interpreted in surprising ways, and once you chain multiple agents and people together, small misunderstandings quickly grow into big problems.
A useful mindset is: everything can be misunderstood. That means your job is not just to “give a good prompt” or “define the system once,” but to design for misunderstanding: expect it, surface it, and correct it. This mindset changes how you think about building and operating agents.
If misunderstandings are inevitable, you need processes for control and detection. Don’t just hope the agent understood you; build ways to check. Add validation steps: is the output in the right format, does it stay within the intended scope, does it follow the constraints you set? Use simple checks where you can: schemas, rules, tests, or a separate “validator” agent. Include spot checks and consistency checks so misunderstandings are caught early instead of at the very end of a long workflow.
Clear communication becomes essential when everything can be misunderstood. Vague instructions like “improve this text” are not enough. Be explicit about goal, audience, style, length, and constraints: what the agent should do, for whom, how it should sound, how long it can be, what must be included, and what must be avoided. Use concrete examples of what you want, and sometimes examples of what you do not want. Break big, fuzzy tasks into smaller, clear steps so there is less room for interpretation at each stage.
Communication should also be confirmed, not assumed. One-way instructions are fragile, whether between humans or between humans and agents. Ask the agent to restate the task in its own words before doing the work, and to list the key requirements it will follow. Define clear acceptance criteria so “done” is not a guess. Use those criteria both when you give the task and when you review the result. When agents or humans hand work off to each other, let them summarize what they received and how they understand their next step. This simple confirmation loop exposes misunderstandings early.
You also need to work in several rounds. Expecting a perfect result in one shot is unrealistic when everything can be misunderstood. Instead, think in iterations: draft, review, refine. Let an agent first restate and plan, then execute, then check the result against the requirements. Use feedback from each round to adjust your instructions, constraints, and examples. Short feedback loops with small steps are more reliable than long, one-shot runs with no checks in between.
Putting this into practice for a multi-agent or multi-actor setup can be simple. Let a human define the goal, constraints, and acceptance criteria. Let one agent restate the task and propose a structured plan. Let another agent execute according to that plan. Let a third agent, or a human, act as validator: checking structure, constraints, tone, and completeness against the stated criteria. Between each handoff, require a short summary or confirmation of understanding. At a few key points, add human review where the risk is highest.
All of this comes back to the original core: when you build agents, or have several agents and actors working together, you must assume that everything can be misunderstood. From that assumption follows the need for control processes, for detection of misunderstandings, for clear communication, for confirmed communication, and for working through several rounds. This is less about distrust and more about engineering: designing systems that expect misunderstanding and are built to catch and correct it.
When you choose a plan or a course of action to reach a goal, you are making a decision under uncertainty. Some plans work, some fail. One simple technique to reduce the risk that something goes wrong is to reduce the complexity of the plan.
The basic idea is: less complexity usually means less risk. The more elements a plan contains, the more chances there are for misunderstandings, delays, or failures. High complexity, by itself, often creates high risk.
You can think about complexity by looking at how many “things” are involved in your plan. These “things” include actors, relationships, steps, and actions. Actors are people, teams, systems, or organizations that are part of the plan. Relationships are the connections and dependencies between these actors or elements—who depends on whom, in what order, and for what. Steps are the distinct stages or phases in the plan. Actions are the concrete activities that must be carried out to move from one step to the next.
A high number of actors, relationships, steps, and actions means high complexity. High complexity, in turn, increases the chances that something will break or be forgotten. Simply counting these elements can already give you a feeling for how fragile a plan might be.
To reduce complexity, you can try to lower the number of things involved. Can fewer people or teams be responsible, with clearer ownership? Can some dependencies or handoffs be removed or simplified? Can two steps be merged, or one step removed, without losing what is essential? Can some actions be standardized or automated instead of handled as one-off tasks?
This can be done on several levels if necessary. On an overall level, you can simplify the main structure of the plan: fewer big phases, fewer parallel tracks, fewer top priorities. On a more detailed level, you can look at how sub-plans and workstreams interact and try to reduce unnecessary dependencies between them. On a very concrete level, you can simplify individual tasks and routines so they are easier to execute correctly.
There are situations where you cannot avoid complexity—for example, where regulations, safety, or many stakeholders impose real constraints. In such cases, the goal is not to remove complexity that is necessary, but to isolate it and manage it clearly, instead of spreading it everywhere in the plan.
If a plan feels risky or hard to control, start by looking at the number of actors, relationships, steps, and actions it contains. Ask yourself: where can I remove or merge something, and still reach the same goal? By deliberately reducing complexity, you often reduce risk—and make the plan easier to understand, execute, and adjust along the way.
Most language model–based agents are used as one-off tools: you give them a task, they give you an answer, and the interaction ends there. But if you use agents in real workflows — for example for control, review or quality checks — it quickly becomes obvious that they should be able to learn from the tasks they perform.
An agent can have its own learning process. Instead of being just a task solver, the agent also has a dedicated part that collects experience and knowledge from the tasks it does. This learning part watches what happens, gathers examples, and updates how the agent approaches similar tasks in the future. The knowledge it collects is then used to improve the agent’s ability to solve tasks. Over time, the agent should become better and better at the specific kind of work it is doing.
This learning is specialized to the task. The goal is not general intelligence, but deeper competence in a narrow domain. The agent focuses on a particular type of job and learns patterns, typical cases, and common pitfalls that belong to that job. The result is a form of task-specific learning: the agent becomes highly tuned to the actual work environment and the real data it sees.
A useful example is a control-type agent. Think of an agent used for control, review, or inspection: checking documents, forms, outputs, or processes. In the beginning, it might be given a set of rules: which things to flag, which things to check, how to categorize problems. But in practice, not all errors are equally important. Some errors are technically wrong but should be ignored in a control. Others are rare but critical and must always be surfaced. And the way errors are grouped and described can make a big difference for how useful the control is.
In this kind of control agent, the learning process can be used to refine three things in particular. First, the agent can learn which kinds of errors it should not consider relevant in a control, and gradually stop spending effort on them. Second, it can learn which types of errors are most important: the ones with real impact, high risk or strong consequences. Third, it can learn how to categorize well: how to group similar findings together and label them in a way that makes sense for the organization.
To make this work in practice, the agent needs a loop between doing tasks and updating its behavior. The agent performs a control task, flags errors, and categorizes them. A human or an external system then evaluates the result: which findings were correct, which were noise, which important things were missed. The learning part of the agent collects this feedback and adjusts its internal knowledge: which patterns to ignore, which patterns to prioritize, how to categorize specific types of findings. This knowledge can be stored as examples, simple rules, or other compact representations that the agent can reuse.
Over time, repeated tasks and corrections build up into a useful experience base. The next time the agent does a similar control, it can use this learned experience to focus on what really matters, avoid known false positives, and categorize in a more consistent way. The control agent becomes more specialized and better aligned with how humans actually want the control to work.
There are some practical challenges. If feedback is incomplete or inconsistent, the agent might learn to ignore real problems simply because they were often left uncorrected. It might also overreact to rare cases if it adapts too quickly. To handle this, the learning process should be designed so that learned knowledge can be inspected, adjusted, and, when needed, reset by humans. It should be clear which kinds of errors the agent has learned to ignore and which it prioritizes.
Still, the core idea is simple: give agents a dedicated learning process that collects experience from the tasks they do, and let that experience feed back into how they solve future tasks. For a control-type agent, this means learning which errors not to care about, which are most important, and how to categorize well — all specialized to the concrete job it actually performs.
When you work with language model agents, it’s a mistake to think in terms of one final, perfect agent. Tasks, tools, and requirements change all the time. A more realistic and effective approach is to treat agents as disposable: let them try things, measure how they perform, and replace them when they’re not good enough.
At the core of this approach is a simple mindset: agents should evolve over time. Let them take on new tasks, and let them try different ways of solving those tasks. Don’t lock yourself into a single design. Make it easy to swap agents in and out so you can keep improving.
To make that possible, you need monitoring in place. Build systems that continuously observe how agents behave. Log inputs and outputs, and track which agent handled which request. Measure key metrics so you can compare agents meaningfully.
Those metrics should cover several dimensions. Goal achievement: does the agent actually complete the task as intended? Efficiency: how quickly and with how few steps does it get there? Error rate: how often does it produce wrong, invalid, or unusable results? Cost: how many tokens, API calls, or other resources does it consume per task? Together, these give you a clear picture of whether an agent is good enough for your needs.
Once you can measure, you can decide when to “rip and replace.” Set clear thresholds for minimum goal achievement, maximum acceptable error rate, and reasonable limits for efficiency and cost. If an agent consistently falls short, remove it or reduce its traffic and introduce a new or improved variant. Sometimes you’ll tune the existing agent (change the prompt, adjust the tools it can use, refine constraints). Other times you’ll replace it entirely with a different configuration and compare the two.
Over time, you can run multiple agent variants in parallel and let them “compete” based on your metrics. Route some portion of traffic to each variant, monitor their performance, and gradually phase out the worst performers. This creates a continuous evolution: agents that work well stay in use, and those that don’t are removed and replaced.
You don’t need a complex setup to start. Begin with simple logging, a few basic metrics like goal achievement, error rate, and cost, and a straightforward rule for when to replace an agent. Keep a record of old agents and their performance so you can learn from what didn’t work. The important part is to stop thinking of agents as static and start treating them as components you can monitor, remove, and replace whenever they no longer meet your standards.
In many organizations, “we need more control” sounds reasonable. Something goes wrong, a deviation is reported, or a leader is questioned by the board – and the response becomes: add more control.
The problem is that control rarely stops where it started. New forms, extra approvals, additional reporting and local checklists appear. What was meant to create security can end up creating friction and frustration.
When the focus on control grows, many actors start their own local control initiatives. Units, teams or individuals add their own checks “just to be sure”. This often happens without coordination, and can easily lead to unnecessary or even harmful control. The result is parallel controls, duplicated work and a patchwork of measures no one has the full overview of.
Unnecessary control shows up as time spent on reporting, documenting and signing off without any real effect on outcomes. Harmful control shows up when routines and approvals slow down the work, reduce flexibility and undermine professional judgment. Employees may feel they spend more time documenting their work than doing it, while leaders drown in reports that do not improve decisions.
To avoid this, it is important to have a clear strategy for where and when control should be applied. Control should not spread by default. Before new measures are introduced, someone should always ask: What are we trying to prevent or achieve? Which concrete risk are we addressing? How will this be experienced in practice? How will we know if it has an effect?
Control should be used where it actually makes a difference. That means prioritizing areas where the risk or consequences of errors are high, where there are legal or regulatory requirements, or where there is a history of recurring deviations. Not all areas need the same level of control, and overcontrol can be just as damaging as too little control. A simple principle can be: as little as possible, as much as necessary.
It also matters who performs the control and how it is done. Control should be carried out by competent actors and supported by good systems. Those who control need to understand the subject matter and the processes they are looking at. Systems and routines should be simple, understandable and integrated into everyday work, not added on top as separate layers that no one believes in.
Without this, the control regime itself can come out of control. You get ever more requirements, more data and more reporting, without a clear sense of what is useful. The organization slows down, frustration rises, and trust is weakened.
To keep control under control, someone must take responsibility for the overall picture. That includes regularly reviewing existing controls, removing or simplifying what no longer gives value, and involving those who are actually being controlled when new measures are designed. Control should be a tool that supports good work and sound decisions – not a system that runs away from the people it was meant to help.
Most of us spend our days dealing with problems. Something breaks, a delivery is late, a deadline slips, a system crashes. We jump in, fix it, and move on. Another way to relate to problems is to work so they never show up in the first place.
This raises a simple question: what interest drives most agents, whether human or machine? Is it mainly about solving the problems that appear, or about preventing them from happening at all?
In practice, most people, teams, and agents focus on solving problems when they arise. It is visible, concrete, and easy to point to. You can say: “Here was the problem; here is what I did; here is the result.” The work is tangible and easy to recognize. This kind of problem-solving often creates heroes: the person who steps in when something goes wrong and fixes it.
Preventing problems is different. It is about noticing risks in advance, planning carefully, building good routines, and improving systems so that certain problems simply never occur. When prevention works, nothing dramatic happens. There is no crisis, no story, and usually no visible “before and after.” Because of that, very few people see the problems that never appeared. Preventive work is often taken for granted or not even noticed.
Ideally, we would prioritize both: solve the problems that arise and work to prevent them in the future. After fixing something, we would ask: “What can we change so this does not happen again?” Over time, prevention would reduce the number of issues that require urgent attention. But when an actor has to choose—because there is limited time, money, or energy—solving visible problems usually wins. It feels urgent. It is easier to justify. It is easier to measure.
This creates a pattern. Reacting to problems becomes the default. People get used to firefighting, and the organization learns to depend on crisis work instead of steady improvement. The better someone is at prevention, the less obvious their contribution becomes, making it even harder to justify preventive work when pressure increases.
A more sustainable approach is to make room for both. Keep solving the problems that arise, but also set aside time and attention for preventing new ones. Make preventive work a conscious part of the job, not just something you do “if there is time.” And when something does not go wrong—when a project runs smoothly or a system stays stable—recognize that this is often the result of invisible, preventive effort.
Solving problems is visible. Preventing them is mostly invisible. Both matter. The challenge is to resist the pull toward only what can be seen and praised, and to also value the problems that never have to be solved.
We were supposed to create a mosaic. Not just any mosaic, but one built from pieces with different shapes. The idea was to show that you can create something fantastically beautiful out of diversity and variation. The strength of the mosaic was that things were not alike. Irregularity and difference were the whole point.
To make this possible, we created a system for producing the pieces of the mosaic. The goal was practical: we needed a way to produce enough pieces to actually build the mosaic. Over time, this system was streamlined and optimized. The main measure of success became how many pieces we could produce.
The way we achieved this was by making all the pieces the same. Same shape, same form, same structure. From the perspective of efficiency, this made perfect sense: identical pieces are easier and faster to produce. But from the perspective of the original idea, it quietly destroyed what we were trying to do. We wanted a mosaic that drew its beauty and strength from difference, and we ended up with a system designed for sameness.
At some point, we noticed that the result did not match the original vision. So we tried to fix it in a simple way: we painted the pieces in slightly different colors. That gave us some variation, but only on the surface. The pieces still had the same shape; they only looked different because of the paint. The diversity had become cosmetic instead of structural.
Developers now use language model–based tools for software development. These tools can write, refactor, and explain code. They come with clear and obvious advantages: development is faster, boilerplate disappears, and it is easier to get from idea to working code.
If that is true, it feels natural to expect that the amount and quality of software should have gone up. The tools and apps we use should have become better and more capable. We should see new tools in areas where we did not have any before. In general, there should simply be more good software.
But do we actually experience that?
When we look at the apps and tools we use every day, many of them feel much the same as a few years ago. Some have gained “smart” features and assistants. A few things are smoother or slightly more automated. But we do not see a clear wave of fundamentally better tools, or a flood of new kinds of software in areas that were previously untouched.
Something seems to block the translation from better development tools to noticeably better products. Part of the explanation is that writing code has never been the only hard part. Understanding users, deciding what to build, designing something simple enough to use, dealing with legacy systems and regulations — none of that disappears just because code is easier to generate.
Incentives also matter. Many companies optimize for engagement, lock-in, and short‑term metrics, not for maximum quality or radically better user experience. Extra development capacity can end up in internal projects, experiments, and incremental changes, instead of visible improvements to the tools we rely on.
This does not mean language models make no difference. For developers, a lot has changed: faster prototyping, easier learning, less time spent on repetitive tasks. There are also behind‑the‑scenes improvements in infrastructure and internal tools that users rarely see directly.
If we really used this new capability to its full potential, we might expect more obvious results: simpler and more reliable everyday apps, more tools for niche workflows and small professions, more software adapted to specific languages, regulations, and local needs.
The question “Where is the improved software?” is therefore less about the tools themselves and more about what we choose to build with them. The technical ability to create more good software is increasingly there. Whether we actually get that software depends on priorities, incentives, and the willingness to aim for genuinely better tools, not just more code.