A retrieval-grounded generative assistant over private data on AWS. The engineering is in the retrieval, isolation and delivery layer, not the model.
Discuss a similar buildA generative assistant that answers questions about an organisation's own data, built so that every answer can be traced to the record it came from. The engineering problem is not the model. It is the retrieval, isolation, validation and delivery layer that decides whether an answer is trustworthy.
Application compute, an in-memory cache and a managed PostgreSQL instance sit inside a private subnet. Everything else, including inference, retrieval, document extraction and image analysis, is a managed service reached by API under narrowly scoped IAM roles. Infrastructure is declared in Terraform and delivery runs through a pipeline rather than by hand.
It was later migrated to an on-premises platform, which is itself the useful part: the same architecture was proven twice, once managed and once self-hosted, with the data verified across the move.
Organisations hold the data that would make an assistant useful, and cannot put it behind one.
Three reasons recur, and none of them are about model quality.
The requirement was an assistant that grounds answers in private records, reaches those records through a narrow and auditable path, and does so fast enough to be used rather than tolerated.
Retrieval runs before inference, not after. The model receives private context as input rather than being asked to recall it. That single ordering decision is what makes an answer traceable, and it shapes everything else in the architecture.
Two views. The first is the shape a client needs in order to understand the trust boundary. The second is the engineering view, including identity, delivery and provisioning.
The alternatives that were rejected, and why. This is the part that shows judgement.
Grounding responses in retrieved private context is what makes an answer auditable. Asking a model to recall an organisation's data produces fluent text with no provenance, which is worse than no answer because it is harder to catch.
The access pattern was heavily repetitive: the same records fetched across many requests. Cache-aside puts the fix where the repetition is. Write-through would have added consistency burden for no benefit at this read-to-write ratio, and scaling the database would have paid money to solve a problem that was not about capacity.
The original key design meant a retried write created a duplicate record. Re-keying around the identity of the thing being described made writes idempotent and removed that class of duplicate entirely, rather than adding reconciliation to clean up after it.
Private endpoints for every managed service would have added cost and configuration for a marginal gain, given that the real control is IAM role scope. The boundary is drawn around the components that hold state, and the decision is documented so that it reads as a choice rather than an omission.
A resource created in a console cannot be reproduced, reviewed or reliably destroyed. The practical cost showed up at teardown: resources in Terraform state had to be destroyed through Terraform and console-created resources through the CLI, because deleting a managed resource out of band leaves state pointing at nothing.
Measured behaviour of this build, and the service lines it stands behind.
Measured on this build. Nothing here is a client outcome or a contracted result.
This project is the reference implementation behind two Fortis service lines.
Retrieval-augmented generation over private datasets, document intelligence, and the data pipelines behind them. The pattern here is the one Fortis proposes: retrieval first, read-only, provenance preserved.
Relational, caching and NoSQL components chosen by access pattern rather than habit, with the caching decision driven by measurement of the actual read profile.
A complete AWS footprint declared in code, delivered through a pipeline, and then migrated off with verification at every gate. Both directions of a modernization exercise.
Least-privilege role scoping as the primary control, no static credentials in code, read-only retrieval paths, and cost exposure treated as an operational risk.