20 May 2026 · 5 min read · Sam Akbari
Every record explains itself: the ai_context serializer
Cyril gives every entity an ai_context serializer — a deterministic, schema-aware view built for the model, not the database. It's the unglamorous core of what makes AI grounding actually work.
Updated 28 August 2026
The exciting part of AI-native software is the agent doing something useful. The part that actually makes it work is boring: how a record describes itself to a model.
Get that wrong and every downstream demo is built on sand. Get it right and the agent stops guessing.
Raw rows are the wrong input
A database row is built for the database. It has foreign keys, status enums, nullable columns, internal flags, and timestamps in UTC. Hand that to a model and you've asked it to do two jobs at once: reconstruct what the record means, and then reason about it.
It will do the first job badly. status: 3 means nothing without the lookup table. A null in closed_at could mean "still open" or "never tracked." A foreign key is a number the model can't follow. So the model invents the meaning it needs — confidently — and the error compounds through every step that follows.
The fix isn't a bigger model. It's giving the model the right input.
What an ai_context serializer is
In Cyril, every entity — an account, a deal, a project, a ticket, an invoice — exposes an ai_context serializer. It's a single method that returns a deterministic, schema-aware view of the record built specifically for AI grounding.
That view does the interpretation the model shouldn't have to:
- Enums are resolved to their human meaning —
status: 3becomes"stage: negotiation". - Related counts are folded in — an account carries its open-ticket count, active-project status, and outstanding-invoice state, because that's what a question about the account will need.
- Internal-only fields are stripped — the model never sees row IDs, soft-delete flags, or tenant plumbing.
- The shape is stable — the same record produces the same context every time, so prompts are cacheable and behaviour is reproducible.
It is, deliberately, not the API response and not the database row. It's a third representation whose only audience is a model.
Why "mandatory on every entity" is the whole point
It would be easy to write an ai_context serializer for the three entities a launch demo touches. That's the trap. The value of a single data graph is that a question can cross any boundary — "which at-risk accounts also have a late project and an unpaid invoice?" only works if accounts, projects, and invoices all explain themselves the same way.
So in Cyril the serializer is a requirement, not a feature. A new entity isn't done until it has one. The test patterns check for it. That discipline is unglamorous and it's exactly what lets an agent traverse the platform without hitting a record it can't read.
Determinism is a security property too
Because the serializer is the only AI-facing view, it's also the place we control exposure. Field-level decisions about what an agent may see live in one auditable spot per entity, scoped by org_id like every other query. There's no separate "AI export" path quietly widening the blast radius — the same serializer that grounds the model is the same boundary that limits it.
What it buys you
- Ask a cross-module question and get an answer grounded in resolved, related, current data — not raw rows the model had to decode.
- Trust the answer enough to act on it, because the same record always produces the same context.
- Know that what the AI can see is defined in one place per entity, not scattered across integrations.
The serializer will never be the headline feature. It's the layer that decides whether the headline features are true.
Common questions
How is this different from the API response?
The API response is shaped for a developer assembling a screen: it is complete, normalised, and expects the caller to know the domain. The serializer is shaped for a reader with no schema knowledge and no ability to follow a foreign key, so it resolves rather than references.
Why not just run retrieval over the database?
Retrieval finds text that resembles the question. It answers what was written down at some point, not what is currently true of a record — and for "which accounts are at risk this quarter", currently true is the whole question.
Does building this view slow queries down?
The related state it folds in is state a real answer would have needed anyway; gathering it once, deterministically, is cheaper than the model asking for it across several turns. Determinism also makes the result cacheable, which the raw-row path is not.
What happens when a new entity is added?
It is not finished until it has one. That is enforced in the test patterns rather than left to memory, because the value of the graph is that a question can cross any boundary — one entity without a serializer is a hole an agent falls into.
If you'd like to be among the first to use Cyril, join the waitlist.
Filed under
Keep reading
31 August 2026 · 8 min read
What to ask an AI vendor about permissions
The AI demo is not the risk. The permission model underneath it is, and it is the thing that decides whether the feature can ever leave the pilot group. Eight questions, product-neutral, with the answer you want to hear for each.
28 August 2026 · 9 min read
What changes when your development team is an AI
Cyril is a full business platform built by AI, directed by one person. The interesting part is not the speed — it is that the practices which make AI a reliable developer turn out to be the same practices that make software agent-ready.
25 August 2026 · 9 min read
The integration tax: what five separate tools really cost
Licences are the smallest line. Here is an open, assumption-by-assumption model of what it costs to run sales, support, docs, projects and finance in five separate systems — including the line that has only existed since AI arrived.
Share this post