Suraj Malla
AI engineer · Kathmandu, Nepal · runs Mytrya
I build AI systems for small B2B teams and run them in production. Mytrya is the name I work under.
Over the last two years I’ve built and operated a support agent platform for a software company: one agent across their helpdesk, their live chat and a chat widget of its own on their site and inside their apps, acting in billing and the dev board, with a learning loop that reads what the human team actually sends. Alongside it, a daily dashboard that reads the same desk for their leadership, and two smaller internal tools. That work is described under Work, with the client unnamed.
On my own time I built offScript, a rehearsal partner for actors with two speech engines, a directing room and an improvised mode on a live speech model, and NEPSE Copilot, a multi-account investing copilot for the Nepal Stock Exchange with encrypted depository sync, one-tap order approval on Telegram and a voice mode. Both are live. Both taught me things the client work didn’t: how to make a voice interface wait for the right reason, and how to make a scoring system grade itself.
The practice is one person on purpose. You talk to the person who writes the code, runs it and answers when it breaks. The cost of that is capacity, so I take a small number of projects at a time and say no when a project isn’t a fit.
I write most things in TypeScript on Next.js, keep data in Postgres or Redis, and use Claude, Gemini and OpenAI models through their APIs, chosen per task and measured where the choice matters.
How I build
7 rules
These aren’t values. They’re rules that appear in the code of the systems under Work, and each exists because of something that went wrong without it.
- 01
Dry-run is the default
Anything that can write to a system ships with a mode that shows the full trace and writes nothing. That mode is on until you turn it off, one integration at a time.
- 02
Grounded or escalated
An agent may state what it retrieved and cite where it came from. It may not approximate. When there is nothing to ground an answer in, escalating to a person is the correct output.
- 03
Numbers are computed, not generated
Counts, medians, returns and thresholds are computed in code where a test can check them. Models describe and classify. They don't add up.
- 04
Read the structure that already exists
Scripts have scene headings, tickets have fields, boards have columns. Parsing them is exact and free. Asking a model to infer them costs the whole document and returns a guess.
- 05
Cost is part of the spec
Caps per window, shared in-flight requests, and work deferred until someone actually opens the page. A system whose bill grows with curiosity gets switched off.
- 06
Assume the source will disappear
Rate limits are measured, not assumed. The old path stays as a fallback. An unexpected response shape is treated as an outage and reported, never interpreted as data.
- 07
Identifiers come from context
Ticket IDs, account IDs and record keys are read from the assembled context, never from model output. A hallucinated ID has nowhere to go.
Next step
Have a process that runs on someone copying data between two tabs?
Describe it: what it is, who does it, how often, and what goes wrong when it's late. I reply within one working day with a scoping call or a reason it isn't worth automating.