← All articles How-to

The agent doesn't get to choose which school it writes to

OBTO Team · Insights from the Glass Box

A school office runs on small, boring writes. A student transfers in on the 12th. Attendance gets corrected for a day someone was home sick. A grade moves after a re-test. A withdrawal is recorded, and a leaving certificate has to reflect it.

Put an agent on that work and every one of those writes lands in a child's permanent record, with no one reading over its shoulder.

Drafting a lesson plan is reversible. Writing to a student information system is not. A model can compute a grade well enough; the harder problem is what stands between a plausible-looking model output and a row in a live database that a registrar will rely on three years from now.

Four layers do that work. None of them live in the prompt.

1. Scope every call to one school, in code

The obvious failure is the agent reading or writing the wrong school's data. Multi-tenant systems usually defend this with a filter the application remembers to add. That works until something forgets.

The stronger shape is to make the boundary non-optional: the tenant is injected into every query server-side, after the agent has said what it wants. The agent submits a filter. The server merges the school's identity into that filter and overwrites anything the agent supplied for those fields. There is no phrasing of a query that reaches another school's students, because the agent never gets to be the last writer of the scope.

Two details matter more than they sound:

2. Keep grade computation in versioned code

There's a strong temptation to let the model do the arithmetic: hand it the marks, describe the grading scale, take the letter grade it returns.

Don't. Grade logic is policy. It differs per board, per school, sometimes per subject, and it changes between sessions. It has to be inspectable by a human who is not in the room when it runs, and identical on Tuesday and Thursday.

The shape that holds is a pipeline of small reducers — each one a stored, versioned artifact that takes marks in and passes computed values along. The agent's job is to assemble and edit that pipeline. The pipeline's job is to run the same way every time, whether or not a model is involved. When a parent disputes a grade, you can point at the reducer that produced it and read it. You cannot read a sampling temperature.

This also gives you inheritance for free: a base rule set at the board level, overridden per school where it genuinely differs, rather than forty prompts drifting apart.

3. Gate the writes that have no undo

Most operations in a school system are correctable. A few are not, or are expensive enough that correcting them is a phone call to a parent.

Sort the verbs before you connect anything:

The gate has to be structural, not advisory. A rule in a prompt is a suggestion a model can talk itself out of; a policy that refuses the call is not. We wrote about this shape in more detail in why guardrails shouldn't live in the prompt.

Idempotency belongs here too. A dropped network reply that causes a retry should not issue two transfer certificates — the write needs a key that makes the second attempt a no-op.

4. Leave a receipt someone else can read

Application logging depends on a developer having remembered to add the log line. Student records need a receipt the run cannot avoid producing, generated where the action happens rather than where the agent narrates it.

Itemized, per run: which tools were called, against which school, what they changed, which model, how many tokens, what it cost. When a school asks why a grade changed in March, the answer is a query, not an archaeology project.

That trail is also what makes the arrangement reviewable by someone who has authority over the data and no interest in the architecture.

What this rules out

Being honest about the tradeoffs:

None of this is exotic. It's the discipline any regulated system gets, applied to a workload where the subjects are children and the records are kept for years.

OBTO has run production workloads since 2019, across 150+ institutions. In the education deployments, all four layers are prerequisites rather than options.

Frequently asked

Can an AI agent safely access student records?

Yes, with the tenancy boundary enforced server-side rather than by the agent, specific scoped read verbs instead of general database access, and a human approval step on any write that can't be undone. The unsafe version is a general-purpose agent with a database credential.

Should an AI model calculate student grades?

No. Grade computation belongs in versioned, inspectable code that produces the same result every run. An agent is well suited to building and editing that logic; it should not be the thing performing the arithmetic at report-card time.

How do you stop an AI agent from reading the wrong school's data?

Inject the school identity into every query on the server, after the agent submits its filter, so the agent's values for those fields are overwritten. Combine that with rejecting unknown identifiers outright rather than returning an empty result.

What should require human approval in a school system?

Anything irreversible or externally visible: transfer certificates, withdrawals, published report cards, and any message that reaches a parent. Reversible reads and correctable edits can run unattended if they're logged.

What does an audit trail for student data need to include?

Which school was addressed, which tools ran, what changed, and the model and token cost of the run — produced automatically by the runtime rather than by application code that has to remember.

Limits the model can't talk its way past

Server-side tenancy, policy in front of the action, and a per-run receipt — on by default.

Get started

More from the OBTO blog