elisynth/
Skip to selected work
Available for AI engineering roles

Elisabeth
Nnamani

Role

AI Software Engineer
Systems & LLM engineering

Based

Nigeria
WAT · UTC+1

Elisabeth Nnamani
Nigeria · WAT

Systems that survive contact with reality.

What that means in practice

I am an AI software engineer. Most of what I build sits in the same place: the layer between a language model and a system that has to be correct.

That layer is where the interesting failures live. A model that writes fluent SQL against columns nobody has. A retrieval step that splits a transaction table mid-row and hands back an amount with no date attached. A pipeline that reports success because the frontend quietly fell back to mock data. None of these throw an error. They return something plausible, which is worse.

So the work is rarely the model call. It is the chunking strategy, the schema the output has to survive, the gate that stops a run before it writes to production, the isolation policy that lives in the database instead of in a code path someone can forget. I care about the parts that hold when conditions are not ideal — which, in the market I build for, is most of the time.

02/Selected systems

Five systems,
one argument

Each one is a different answer to the same question: what has to be true for a language model to be trusted inside a system that has to be correct?

01/Live

PrismOS

Type
Multi-agent system
Period
2026
Role
Product owner, architect, lead designer

Seven agents that are required to disagree before any code ships.

AI coding assistants are single-voiced. One model takes a feature request and decides everything itself — scope, architecture, implementation, testing — and it never disagrees with itself. The output compiles and demos well, and it quietly skips every tradeoff a real team would argue about.

A decision worth arguing about

Agreement was the failure mode, not disagreement

Running seven agents was straightforward. Stopping them collapsing into polite consensus was not. Agents respond in parallel without seeing each other's output first, prompts require at least one surfaced disagreement, and the orchestrator routes on structured markers rather than on sentiment. Conflict had to be consequential or it was theatre.

Architecture · PrismOS
9 nodes

Run the pipeline. Step three is a parallel debate — three agents respond independently and are required to surface disagreement before the Release Manager rules.

02/Live

Atlas AI

Type
Autonomous data engineering
Period
2026
Role
Sole architect and engineer

Natural language to production dbt models, grounded in the catalog your organization already has.

A business question — daily revenue by customer segment for the last ninety days — becomes a ticket, which sits in a queue, which becomes a data engineer hunting for the right tables, checking which columns are trustworthy, writing SQL and a dbt model, adding tests, writing docs and updating the catalog. Hours to days per request, and almost none of it creative.

A decision worth arguing about

Invisible grounding is indistinguishable from hallucination

Early on, DataHub was load-bearing in execution and completely invisible in the interface — buried in output_json and one scrolling log line. For a tool whose entire pitch is grounding, that is a product failure regardless of correctness. It drove the context review panel: matched datasets, confidence scores, columns and PII tags sitting directly beside the generated SQL.

Architecture · Atlas AI
8 nodes

Two checkpoints are real. The pipeline will not generate SQL until the matched context is approved, and will not touch the catalog until writeback is approved. Approve them to continue.

03/Live

FinSight

Type
Document intelligence · SaaS
Period
2025 — 2026
Role
Sole engineer

Turning a messy bank statement into clean rows, for a market bank-linking APIs do not serve.

Bank statements are one of the richest personal datasets most people own and one of the least usable. They arrive as CSVs with inconsistent column names, or as PDFs where the transaction table is a visual artifact rather than structured data. Getting anything out of them means manual tagging in a spreadsheet, which almost nobody sustains past the first month.

A decision worth arguing about

Naive chunking produced plausible garbage

Fixed-size chunking splits transaction tables mid-row. Retrieved context then contains an amount orphaned from its date and description, and the model answers confidently and wrongly. Chunking semantically around section headers with row boundaries as hard splits fixed it. The failure never surfaced as an error — only as answers that looked right.

Architecture · FinSight
8 nodes

The ingestion path. The markdown re-serialization step is the one that decides whether the model can reason about the table at all.

04/Submitted

FarmTwin

Type
Offline-first local inference
Period
2026 · 7-day sprint
Role
Sole developer

A cited agronomic advisor that runs entirely on a 2014 laptop with the network unplugged.

Smallholder maize farmers in Nigeria make high-stakes agronomic decisions — planting dates, fertilizer timing and rates, pest response — largely without extension services. Where digital advisory tools exist they assume reliable connectivity, a modern smartphone and a cloud backend. That assumption fails in exactly the places the advice is most needed.

A decision worth arguing about

Model selection turned on grounding, not fluency

Benchmarked Qwen2.5-3B against Llama-3.2-3B on a structured rubric with manual grading against gold prompts. Llama was disqualified primarily because it hallucinated citations — inventing sources that were not in the retrieved context. For a system whose entire value is that an answer comes from IITA and here is the chunk, that is decisive rather than a rough edge. Qwen took the composite 83.5 to 72.9, driven by retrieval grounding.

Architecture · FarmTwin

Everything inside the boundary runs on the device. Cut the network and nothing changes — that is the entire thesis. Try the switch.

05/Live

FlowMind

Type
AI product · SaaS
Period
2025 — 2026
Role
Architect and product owner

Removing the triage tax that kills productivity systems, with the model as the mechanic rather than a chat box.

Knowledge workers capture information faster than they can organize it. Notes land in one app, tasks in another, half-formed ideas in a file nobody reopens. The bottleneck is the triage afterwards — deciding what belongs to which project, what actually matters today, and whether last week's intentions matched last week's reality.

A decision worth arguing about

Structured output is the hard boundary, not the prompt

Auto-organize has to return something that maps cleanly onto typed Postgres columns — project assignment, priority, extracted entities, and a confidence float constrained to 0–1. Free-text output does not survive contact with a schema. The real work sits at the join between the chain and the database.

Architecture · FlowMind
6 nodes

Capture is the user's only job. Everything right of the inbox is chained model work writing structured results back into a relational model the interface reads directly.

03/Trajectory

How the work changed

Read upward. Each stage moved the boundary of what I was accountable for.

01/

Freelance Web Developer

Independent · 2023 — 2024

Learning to ship on someone else's terms.

Client sites and front-end builds, sold and delivered directly. The code was the smaller half of the job.

The larger half was scoping against a fixed budget, shipping to a date I did not set, and handing over something the client could operate without me in the room. Constraints I have never since been able to unsee.

ShiftFrom building what I wanted to build to building what someone had agreed to pay for.

02/Now

IT Intern

Cool Group · June 2026 — December 2026

Working inside an organization's operational context.

Six months inside a functioning IT organization, where systems have owners, history, and consequences that outlast the person who touched them last.

The difference from independent work is not technical difficulty. It is that nothing exists in isolation — every change lands in an environment somebody else depends on.

ShiftFrom owning a repo end to end to operating inside something larger than the thing I built.

03/Now

Freelance AI Software Engineer

Independent · 2025 — Present

Owning the system, not just the surface.

Building LLM-backed products end to end, for clients and for myself: FinSight, FlowMind, PrismOS, Atlas AI, FarmTwin.

This is where the work moved past the interface. Orchestration and agent design, retrieval that has to stay grounded, tenant isolation enforced in the database, billing that survives a webhook, deployment across platforms that each break differently. Five products shipped, each one teaching a failure mode the last one did not have.

ShiftFrom delivering interfaces to being accountable for everything behind them.

04/Capabilities

Grouped by what I do with them

A list of logos tells you what someone has installed. This is organised by the job each layer is doing.

01

Orchestrating models

Multi-agent workflows, chained reasoning, structured output that has to survive a schema, and streaming the whole thing somewhere legible.

  • LangGraph
  • LangChain
  • LlamaIndex
  • MCP
  • Multi-agent systems
  • SSE
  • WebSockets
  • Structured output
02

Running inference

Hosted and local, open-weight by preference, quantized when the hardware demands it.

  • Groq
  • LLaMA
  • Mistral
  • Qwen
  • llama.cpp
  • Q4_K_M quantization
  • gpt-oss
03

Grounding retrieval

The part that decides whether an answer is trustworthy or merely fluent. Chunking strategy, citation enforcement, and grounding in metadata that actually exists.

  • RAG pipelines
  • Semantic chunking
  • sqlite-vec
  • DataHub knowledge graphs
  • Citation enforcement
  • Benchmark rubrics
04

Serving it

APIs that hold under streaming, long-running chains, and authorization that has to resolve before the first byte.

  • FastAPI
  • Python
  • Node.js
  • Express
  • NestJS
  • TypeScript
05

Storing it safely

Multi-tenancy enforced by the database rather than trusted to application code.

  • PostgreSQL
  • Supabase
  • Row-level security
  • SQLAlchemy async
  • asyncpg
  • SQLite
06

Building the product around it

The interface is where an AI system either earns trust or fails to. Grounding you cannot see is indistinguishable from hallucination.

  • Next.js
  • React
  • TypeScript
  • Tailwind CSS
  • Motion
  • Recharts
  • Design systems
07

Shipping it

Across platforms that each fail in their own way, with payment rails that serve the market I build for.

  • Docker
  • Vercel
  • Railway
  • Render
  • Neon
  • Alibaba Cloud SAE
  • Git
  • Paystack
05/Method

Seven things that cost me something

Every principle below came from something that went wrong. None of them are opinions I arrived at in the abstract, and I would not trust them if they were.

01/

The expensive failures return an answer

The bugs I remember all have the same shape. Nothing throws. Nothing logs. The system returns something plausible and you carry on.

Fixed-size chunking split a transaction table mid-row, so the model got an amount with no date attached and answered confidently. An environment variable set at runtime where Next.js needs it at build time made a frontend fall back silently to fixtures, and the application looked like it was working. A Tailwind v4 migration compiled cleanly and simply did not apply any styles.

So I have stopped treating a green run as evidence. The question is not whether it completed. It is whether I can name what it would look like if it were quietly wrong.

FromFinSightSemantic chunking around section headers, row boundaries as hard splits

02/

Set the gate before you run the test

I wanted Pidgin voice input in FarmTwin more than any other feature in it. I am a native speaker and it is the language a large share of the users actually speak.

I defined a 40% word error rate gate before I ran a single clip. Whisper base failed. The Nigerian-English fine-tune failed. The datasets that might have fixed it were gated or unpublished inside the sprint window. The feature shipped as English-only, labelled honestly in the interface.

The gate existed precisely so that decision would be forced by data rather than by how badly I wanted the feature. A threshold you set afterwards is not a threshold.

FromFarmTwinADR-011 — 15-clip evaluation, feature scoped to English

03/

Grade your own work down

My first benchmark pass scored the model I had chosen at 98.8. I had been generous on partial credit, in the direction that happened to suit me.

I re-graded against a stricter reading of the same rubric and it came out at 87.6. That number is less flattering and considerably more useful.

A benchmark you have quietly rigged tells you nothing. It only tells other people something, and briefly.

FromFarmTwinQwen2.5-3B chosen over Llama-3.2-3B on citation fidelity, 83.5 to 72.9

04/

Name the cost of the call

I categorize transactions with a model and no rule table. The honest description of that is a permanent per-upload token cost traded against zero rule maintenance.

I could describe it as the elegant choice and leave the sentence there. It would read better and mean less.

Every architectural decision I am confident about, I can state what it costs. The ones I cannot state a cost for are usually the ones I have not thought about hard enough.

FromFinSightModel-only categorization, 40-transaction batching

05/

Put the guarantee in the system, not the code path

Per-user isolation lives in row-level security policies in the database. It does not live in a middleware function that a future endpoint might forget to call.

Approval checkpoints reconstruct their context from persisted output rather than holding it in memory, so a paused run survives a restart. A gate that evaporates on redeploy was never a gate.

The pattern is the same each time: move the guarantee somewhere it cannot be skipped by someone who is in a hurry, including me.

FromAtlas AIThree resumable phases rebuilt from agent_runs.output_json

06/

Patch what works

Across three versions of PrismOS, every capability added after v1.0 went in as an incremental patch against working architecture. Agent 0, the designer role, project memory, feature classification. Several proposed rebuilds were rejected.

Auth, rate limiting and webhooks were cut and written down as deferred, rather than half-built and left looking finished.

A rewrite is the most expensive way to avoid understanding the thing you already have.

FromPrismOSVersioned blueprint as single source of truth, v1.0 through v1.2

07/

Build for the market you are actually in

Stripe does not serve Nigerian payment rails, so FlowMind and FinSight run on Paystack, and the migration touched the schema, the status enum, webhook verification and the whole billing interface. It was not a client library swap.

FarmTwin runs with the network unplugged on a 2014 laptop because that is the hardware and the connectivity the farms actually have. FinSight parses statements because bank-linking APIs do not cover Nigerian banks at all.

None of this is a constraint I am working around. It is the specification.

FromFlowMindPaystack migration, NGN and USD pricing

06/Contact

Tell me what breaks

I am most useful on systems where a wrong answer is expensive and the failure does not announce itself. Open to AI engineering roles and selected contract work.