Article
From RAG to safe writes
Most teams shipped a RAG-only agent in 2024. The next step — letting the agent change state — is a different category of engineering. Here's the path.
Most teams who shipped agent features in 2024 shipped read-only ones: a chatbot that retrieves documents, summarizes, answers questions. That category has matured. The interesting frontier in 2026 is write-capable agents — copilots that can update a record, place an order, modify a configuration. The engineering shape of “safe writes” is genuinely different from “safe reads.”
This article maps the differences and gives a path for teams thinking about the transition.
Read-side hard problems vs. write-side hard problems
The hard problems of read-only RAG are mostly retrieval quality: chunking, embeddings, reranking, hallucination. The safety problems are real but bounded — leak the wrong document, return the wrong row.
The hard problems of write-capable agents are trust: under what conditions can you let an LLM mutate state, and how do you recover when it gets it wrong? The leak surface gets bigger; the blast radius gets bigger; the rollback story matters.
Concretely:
| Concern | Read-only RAG | Write-capable agent |
|---|---|---|
| Worst case | Wrong answer, leaked row | Wrong write, leaked row, ledger off-by-N |
| Reversibility | Just retry | Often requires rollback |
| Audit need | Helpful | Mandatory |
| Approval gates | Rare | Routine |
| Rate limiting | For cost | For cost and safety |
| Idempotency | Trivial | Critical |
Five things to add when going write-capable
If your agent currently only reads, here’s what changes when you let it write.
1. Reasons on every mutation
Every write tool should require a reason field. The reason ends up in the audit log. You will be reading these reasons six months later, in an investigation, and they need to make sense. Tell the model in the system prompt: “When calling write tools, supply a one-sentence reason describing the user intent that motivated this write.”
We’ve covered this in the write operations guide. It’s the cheapest control you can add; it has the highest investigative value.
2. Approval gates for the high-stakes 5%
Most writes can be automatic. Some — large refunds, role changes, subscription downgrades — should pause for a human. Don’t try to enumerate the rules from scratch; copy your existing customer support policy. The rules that humans need approval for in your support tools are usually the same rules an agent needs.
Build the approval surface into your existing workflow tools (Slack, Linear, an admin UI). The agent’s response when an approval is pending should be: “I’ve requested approval to do X; you’ll get a confirmation when it’s processed.”
3. Idempotency tokens
Agents retry. LLMs sometimes call the same tool twice. Make every write idempotent or make it explicitly resistant to duplication.
The simplest pattern: give every write call an idempotency_key argument (the agent generates a UUID per user-intent). The handler stores (idempotency_key, result) and returns the same result on retry without re-executing. We recommend OrmAI’s built-in idempotency wrapper:
.enable_writes(models=["Order"], require_reason=True, require_idempotency_key=True)
4. Dry-run mode
For any write that affects more than one row, build a dry-run option. The agent can call dry-run first, inspect the affected rows, and only call the real version if it looks right. We’ve found that giving the model both db.update and db.update_dry_run and instructing it to use dry-run for “anything that might affect more than 5 rows” cuts incident-class events significantly.
5. Rollback by design
Every write should log enough to undo itself. OrmAI’s audit row includes before and after field values. The rollback_audit_id(audit_id) admin tool generates an inverse operation.
You won’t roll back often. When you do, you want it to be a one-line operation, not a database surgery session.
A migration path
If you’re thinking about adding write capability to an existing read-only agent:
Week 1–2: Inventory and decide
List every write the agent might want to do. For each, decide:
- Approval required? (Most: no. Some: yes.)
- Reason required? (All: yes.)
- Dry-run available? (Most: optional. Multi-row: yes.)
- Idempotency required? (All: yes.)
- Per-window cap? (All: yes; pick the cap.)
Write this down. It’s the spec for your write policy.
Week 3: Implement the policy
Encode the spec in your OrmAI policy. Test the policy in a dev environment with an agent that’s instructed to “try every write tool.” You’ll find rules to tighten.
Week 4: Build the approval surface
Pick where humans see and act on approval requests. We recommend a Slack integration: a message arrives, two buttons (approve / deny), the approver leaves a one-line note. Total integration: half a day.
Week 5: Audit dashboard
Build (or reuse) a dashboard showing every write the agent has done in the last hour, day, week. Include the reason. Include the approver if applicable. Make it easy to search.
Week 6: Soft launch
Enable the write tools for a small group of internal users or a single tenant. Watch the audit log. Iterate.
Week 7+: Broad rollout
Once the audit log shows zero anomalies for a week, broaden the rollout.
This is roughly the timeline we use with consulting clients. Faster is possible if you’re starting from scratch. Slower is normal if you have legacy code paths to migrate.
What goes wrong (and how to recover)
The common failure modes of write-capable agents and their fixes:
- The model writes the wrong field. Solution:
writable_fieldsconstraint per model. Don’t expose updates to fields the agent shouldn’t touch. - The model writes too much. Solution: per-window write rate caps and approval gates above a row-count threshold.
- The model writes the same thing twice. Solution: idempotency keys.
- The model writes data that’s logically wrong (right field, wrong value). Solution: domain validators in your tool implementation. Hard to enforce from policy alone; this is where domain tools earn their keep.
- The model is manipulated by prompt injection. Solution: capability tokens that don’t widen — the injected instruction can’t grant authority the model doesn’t already have.
When to not go write-capable
Some agents shouldn’t write. Examples:
- Public-facing support chatbots where the user is unauthenticated.
- Agents handling regulated data where every mutation requires a paper trail beyond what the audit log provides.
- Anywhere the cost of a wrong write is fundamentally unrecoverable (irreversible payments, broadcast messages).
For these cases, design the agent to propose writes that get queued for human execution, rather than executing them directly. The audit log captures intent without the risk.
The shape of the next year
We expect 2026 to be the year write-capable agents become normal in production. The infrastructure is here, the patterns are settling, and the customer demand is clear. The teams that ship them safely will be the ones who treated the write boundary as an engineering problem with named solutions, not an “we’ll figure it out” problem.
OrmAI was built for this transition. The policy primitives, the approval gates, the audit log — these are exactly the things you need to make safe writes feasible. If you’re starting that transition now, the production checklist and the write operations guide are the place to start.
Related
Found a typo or want to suggest a topic? Email [email protected].