Applied AI Orchestrator · Based in Singapore

Building AI Pipelines
That Loop and Auto-Improve

I build AI systems that run on their own and still prove what they did. Behind them are 18 years of running a technical business: an agency, live servers, and a P&L. I replace fragile prompts with real engineering, a human approval step before anything goes out, and interfaces people can actually use. Currently looking for a senior Applied AI Engineer role in Singapore.

18 years technical & commercial leadership
28 agent autonomous workforce
The AEIS speaking diagnostic recording screen, live in production.
Gemini
Claude Code
n8n
Docker · Caddy
ChromaDB · MCP

How I'm Different

Six things I bring that a prompt alone does not

AI Orchestration

I do not just use AI. I build pipelines that run, measure their own results, and change the next run themselves, with nobody editing a prompt.

The Human Gate

Running on its own does not mean nobody is watching. Drafting and review are separate agents, and every pipeline stops for a person to approve before anything goes out.

UI/UX & Usability

A decade of agency design behind it. Every AI tool I build has to be usable by the person who actually does the job, not just correct.

Hardened Security

Years of running live servers and real databases. My AI runs locked down: it can only reach the few domains it needs, and it cannot touch data it has no business touching.

Commercial Pragmatism

I have run a P&L and a number one selling product. I only build AI that solves a real operating problem, and protects the brand while it does it.

Full Stack Execution

I do not just write prompts; I build the entire housing. From spinning up the Linux VPS and configuring the egress firewalls, to wiring the API and MCP integrations and structuring the databases, I execute the complete pipeline.

The Systems

Production-grade architectures

Six systems I led from architecture to release, now running in production, from live web apps to a printed book. The hard part was never the prompts. It was securing the machines they run on, fitting them to how the business already works, and making sure the numbers they produce are right.

AI Speaking Examiner

A live web app that scores a child’s spoken English against Cambridge A2 and B1 rubrics, across 27 topics, in under seven seconds.

Gemini API · n8n · JavaScript · HTML/CSS · Caddy

Live · Public

Autonomous Content Pipeline

A locked-down agent that drafts and reviews the daily social posts on a server, then holds them in a queue until a person approves.

Claude Code · Docker · n8n · Bash · Python · Graph API

Running Unattended

The Calendar You Can Text

A Telegram bot that updates the live booking calendar from a plain sentence, follows the conversation, and refuses to touch a slot that is already booked.

Telegram API · Gemini · n8n · JavaScript · Google Sheets

Live · Private

A Workforce Of 28 Agents

The specialists the other systems are built from. Writers, designers, reviewers and publishers, each scoped to a deliberately narrow tool list, documented on a public page generated from the real definitions.

Claude Code sub-agents · tool scoping · HTML Canvas

Live · Public

Hybrid RAG Knowledge Base

Search over my Obsidian notes, indexed two ways at once. An agent finds the few notes it needs instead of loading whole folders, so it answers faster and on a fraction of the tokens.

ChromaDB · knowledge graph · Python · Claude Code hooks · MCP

Live · Private

A Printed Book

A 122-page bilingual exam guide typeset from source files, with a generated back cover and barcode. Printed in the thousands and selling now.

Typst · Python · PyMuPDF · Photoshop

In Print

Case Studies

Architecture & engineering judgement

How each system was built, what broke in production, and what I changed to make it reliable. Every one includes the mistake I made first, and what it saves now that it works.

01

AI Speaking Examiner

A public web app. A student scans a QR code printed in the book, records an answer in the browser, and gets a Cambridge-aligned score straight away.

Live · aeis.learnintt.com
What it saves about 20 hours Of marking returned, per month Scoring one recording against four rubrics takes a teacher about ten minutes, so a class of 30 is five hours. At one class a week that is twenty hours a month. The app returns each score in about seven seconds, at any hour.
How it was built 90% Built with applied AI Code, copy and interface drafted by agents I directed. The rubric rules, and the decision to take scoring off the model, are mine.
Read the buildHide the build

The hard part was being fast and consistent at the same time. The app takes a recording, transcribes it, and returns a score against four Cambridge rubrics in about seven seconds. A parent will not wait much longer than that. A score that changes when you submit the same clip twice is worse than no score at all.

So the model no longer returns a score. It returns a transcript and four true or false answers: did the student cover each required point. Code turns those into the score, and caps it by length. Grammar and pronunciation stay with the model, because those are real language judgements. Same recording, same score tomorrow.

The topic menu showing interview, picture discussion and conversation tasks grouped by Cambridge level. A task screen with the question, a play button and a large record button.
27 topics, and the screen a parent reaches by scanning a QR code printed in the book.
What I got wrong first

I asked the model for a 0 to 5 score and trusted it. Weak test clips came back at 4 out of 5, because the model was generous every time. A generous score is worse than a wrong one when a parent acts on it. So I took the decision away from the model. It now returns a transcript and four true or false answers, and ordinary code works out the score.

Scope
27 topics · 4 rubrics
Model
Gemini, audio-native
Runs on
n8n · Caddy · Hetzner
Reached via
17 printed QR codes
My role
Lead: architecture, build, release
02

Autonomous Content Pipeline

A Claude Code agent that drafts and checks the daily social posts on its own, on a server with nobody watching, then stops until a person taps approve on their phone.

Private · Walkthrough On Request
What it saves about 90 hours Of my time, per month One finished post used to take me three to four hours. The pipeline produces about one a day, and my part is a two minute approval on my phone. 45 posts approved so far: 19 published, 26 queued.
How it was built 95% Built with applied AI The agent researches, writes, designs and checks its own drafts. I set the gates, the container rules and the brand limits it works inside.
Read the buildHide the build

The hard part was running unattended code safely. A system that publishes to a real brand with nobody watching is a risk to that brand. So nothing reaches an audience until a person taps approve. The writer is fully autonomous. The publisher is not. That line is the whole design.

n8n workflow cron 07:00 SGT Claude Code container, non-root writes + self-QCs human approval on a phone Facebook / Instagram via n8n
The draft moves on its own until the gate, then stops until a person approves. Nothing has ever published without one. Every arrow in this picture is an n8n step, not a decision the model makes.

Why n8n runs the steps, and not the AI. The AI is not consistent about how it does a job. Ask it the same thing twice and it may take a slightly different route, and a slightly different route gives you a slightly different result. For writing a post, that variety is the point. For uploading an image, writing the row, waiting for the slot and calling the publish endpoint, it is a defect. n8n does those steps the same way every single time, and when one fails it fails in a named node I can open and read. So the model does the language, and n8n does the plumbing.

n8n does the steps

10 runs of the same job Same path, every run. Upload, write the row, wait for the slot, publish, verify. A failure stops at a named node.

The model does the steps

10 runs of the same job Same brief, different route. It may skip the verify, retry in the wrong order, or invent a step. Nothing to open and read afterwards.

I built this inside a hardened container: a non-root user, no host folders mounted, no access to Docker itself, and a firewall that lets traffic out to about twenty domains it needs and blocks everything else.

# container egress: allowlist, then reject everything else
iptables -A OUTPUT -m set --match-set allowed-domains dst -j ACCEPT
iptables -A OUTPUT -j REJECT

# verified after every build:
#   example.com -> blocked   github.com -> 200   whoami -> claude
What I got wrong first

The writing agent made up teaching methods that sound exactly like ours, complete with an acronym, and none of them are in our books. You would only catch it if you knew the source material well. Telling it not to do that in the prompt was not enough, so I added three separate checks that run before the post ever reaches the human gate.

It also checks its own results. Twice a month the pipeline pulls the real engagement figures for the posts it published, compares each one against what it expected, and writes the answer back into the brief the writer reads next time. That is how it worked out that reels reach about four times as many people as carousels, and how it stopped chasing a Facebook reach figure that Meta had quietly retired. Nobody edited a prompt to teach it either. It measured, and the next brief changed.

Status
Unattended since Jul 2026
Isolation
Non-root · no docker socket · 20-domain allowlist
Auth
Service accounts, no OAuth expiry
Self-review
Bi-monthly, from live post data
Published unapproved
Never
03

The Calendar You Can Text

An internal tool that reads a sentence like “open Wednesdays 8pm through November” and updates the live booking calendar. One command undoes it.

Private · Walkthrough On Request
What it saves about 5 hours Of admin time, per month Opening a month of Wednesday evenings used to mean editing every matching row in the booking sheet by hand, and checking each one against live bookings. It is now one sentence.
How it was built 95% Built with applied AI The parser, the date expansion and the tests were AI-written. The refusal rule and the 200 row cap are mine, and they are what the tests protect.
Read the buildHide the build

The thing that mattered was never overwriting real data. The bot has to follow a conversation, work out what a repeating date rule means, and refuse to touch any slot that already has a booking in it. So the model never sees the calendar. It only turns a sentence into a rule. Turning that rule into real dates happens in ordinary code.

// "open Wednesdays 8pm through November"
{
  "action":   "open",
  "weekdays": ["WED"],
  "from":     "2026-11-01",
  "to":       "2026-11-30",
  "times":    ["20:00"]
}
// dates expand in JS, where a calendar bug is a failing test
// and not a parent booking the wrong evening.
The model does language. The code does calendars.
What I got wrong first

I matched calendar rows on date and time. The tool I was using only ever matched on the first column, and said nothing about it, so my matching had quietly dropped to date only. The first time a date held two different sessions, it would have written over a real booking. I found it in testing before launch. The lesson is that a tool you did not write can change what your code means without failing.

Safety
Never touches a booked slot · 200-row cap
Undo
One command
Tested
27 unit tests, live E2E
Unauthorised chats
Ignored in silence
04

A Workforce Of 28 Specialist Agents

The team the other systems are built from. Twenty-eight specialists, each allowed to do a deliberately different amount, and a public field guide generated from the files actually in use.

Live · social.learnintt.com/agents
What it saves about 8 hours Of upkeep, per month The field guide is generated from the real agent files, so one page shows every agent I have and is right the moment one changes. Keeping a written guide to 28 agents current by hand costs about a day a month, and it is stale in between.
How it was built 85% Built with applied AI The agent files and the office illustration were AI-written. Who is allowed to touch what, and which agent exists at all, is mine.
Read the buildHide the build

The rule was that a reviewer must not be able to hide a problem. Every quality-control agent is defined without the tools to write files. It cannot fix what it finds, so it has to report it. Give a reviewer the ability to edit and it quietly patches the symptom instead. The report comes back clean, and the pattern never reaches the person who could change the process.

The field guide is generated from the real agent files, not written next to them, so it cannot end up describing a workforce that no longer exists. The illustration below is drawn from the same roster.

Not a live feed. The roster is real; the working day is a timer running in this browser. Scroll it sideways to see the whole floor.

Each desk is one agent that exists as a definition file. Reviewers are drawn at work like everyone else. What separates them is what they are allowed to touch.
What I got wrong first

I wrote a test to prove no agent could walk through furniture. It reported six problems, which reads like a near pass, while the office on screen was still visibly walking people through their own desks. The test was skipping the desk each agent was heading for, because a chair does sit inside its own desk. That one exemption covered the exact failure I was looking for. Narrowed to the small legal gap between a seat and its approach point, the same code reported 146. A test that excuses the thing it is testing will report clean forever.

Roster
28 agents · 4 teams
Reviewers
No write tools, by definition
Field guide
Generated from the definitions
Scene
Illustration, never presented as live
05

Hybrid RAG Knowledge Base

A search layer over my Obsidian notes. They are indexed two ways at once, so an agent can find the two notes it needs instead of loading whole folders.

Private · Runs On My Own Machine
What it saves about 100,000 Tokens not read, per session The vault is about 75,000 words. Loading all of it to use one paragraph costs that on every session, and it grows every week. Retrieval returns about 400 words instead.
How it was built 90% Built with applied AI The indexer, the session hooks and the graph extraction were AI-written. The duplicate gate was set on real duplicates, by me, not on taste.
Read the buildHide the build

The problem is that a model starts every session knowing nothing. It works out again today what it already worked out yesterday. The obvious fix is to load the whole project at the start, and it is the wrong one. The vault is about 75,000 words. Loading it means paying to read all of it in order to use a paragraph of it, and that bill grows every week the vault does.

So there are two indexes, because two different kinds of question get asked. A knowledge graph answers questions about structure: what connects to what, which notes belong together, which few notes everything else hangs off. A vector database answers questions about content: what does the note on this subject actually say. Ask the graph which note. Ask the vectors what is in it. Think of the notes as the books and this as the index at the back that tells you which book to open. Retrieval gets more accurate as the vault grows, not less, because more notes give both layers more to sort on.

Two hooks make it automatic. One runs when a session opens and hands over the map and the open task list, so work starts already knowing the shape of the project. One runs when it closes and writes the session back out, so what was learned is still there tomorrow.

The store only rebuilds a note that is genuinely newer than the last build. The graph report opens by saying whether the vault is still small enough that I do not need a graph at all, which is the sort of thing a tool should be willing to say about itself.

Not the real graph. An illustration of the idea: notes as nodes, the few hubs larger, retrieval travelling the links between them.

The vault holds notes. The graph holds how they relate. A question that names a subject goes to the vectors; a question about how two things connect goes here.
$ python rag_query.py "how do we handle the human approval gate" --n 2

Top 2 results for: "how do we handle the human approval gate"

#1  [0.3927]  03-Claude-Brain/Social-Auto-Pipeline.md  (chunk 0)
    Goal: automate the work around a post, but never the
    decision to post. Every day n8n starts a run, a
    containerised Claude Code generates and self-QCs two
    posts, they land in the sheet as Pending approval, a
    human approves each from a phone, and n8n publishes
    only the approved ones.

#2  [0.3434]  2026-08-12b_hook-score-telegram-analyst....md (chunk 2)
One question, two passages, about four hundred words returned instead of two whole files. The scores are how close each passage is to the question. They are shown on purpose: a weak top score is the signal that the vault has nothing on the subject, and that is worth seeing.
What I got wrong first

I assumed writing something down was the same as remembering it. A job that starts the model fresh every morning has no memory of yesterday, and mine happily produced nine posts covering three ideas, each one three times. My first instinct was a firmer instruction telling it not to repeat itself. That cannot work. The instruction and the input were the same every morning, so the output was too. The fix was a list of what had already shipped, kept outside the repository so a reset cannot wipe it, and a similarity check that stops the run rather than asking politely. I set the cut-off on the real duplicates, which scored 0.50 and above, not on what felt right. Genuinely different topics scored 0.13 and below.

Vault
86 notes · about 75,000 words
Stored facts
225 separate memories
Retrieval
Knowledge graph, plus vectors
Index
ChromaDB · 400-word chunks
Embeddings
On this machine, nothing uploaded
Loaded per session
A map, never the vault
06

A Printed Book, Built Like Software

A 122-page bilingual speaking guide for Singapore’s AEIS entrance exam, typeset from source files, printed in the thousands, and on sale now.

In Print · On Sale
What it saves about 120 hours Of layout and checking, saved Thirty-eight numbered builds before v38 went to the printer. Re-flowing 122 bilingual pages by hand for each editor batch is about three hours a round. Here every batch is an edit and a recompile.
How it was built 75% Built with applied AI A former MOE teacher provides the content. AI rewrites and tightens it, then does the layout and the checks. The cover is about half generated and half Photoshop by hand.
Read the buildHide the build

The hard part is that print has no patches. A web page can be fixed an hour after someone notices. A print run cannot. Every claim in the book had to be true before the file left for the printer, and the layout had to survive being rebuilt from scratch late in the schedule.

The inside of the book is a text file. Typst turns it into a print-ready PDF, so a change from the editor is a small edit and a rebuild, not a person re-flowing 122 pages by hand. Four agents do the chapter work: one writes to the required Cambridge level, one reviews the writing, one places it into the layout, one checks the finished PDF. As everywhere else here, the reviewers cannot edit.

I did not write this book. The author is a former MOE teacher who runs the centre it came from, and the editor works with us. Their changes arrived as dated batches of marked-up screenshots, which I applied to the source. My side was production. The cover art was generated as two separate layers, the children and a faint Singapore skyline behind them, then put together in Photoshop, because the title area needed a person’s eye rather than another prompt. The back cover is built by the same pipeline as the rest of the book, barcode included.

Accuracy is where I was most suspicious. The pronunciation spellings for 158 words came out of a model, and eleven of them were wrong. A line claiming the book had QR linked audio was also invented, and cut, because the author’s material never mentioned audio. A “100 per cent placement” headline came down to the 97 per cent the records actually support.

The printed front cover: two illustrated children in school uniform in front of a faint Singapore skyline, under the title AEIS CEQ Speaking Book. The printed back cover, showing the author profile, the placement-rate panel, both publisher logos and the ISBN barcode.
Front and back of the printed edition. The barcode is drawn from the issued ISBN at build time, so the number under it and the artwork around it cannot drift apart.
What I got wrong first

The source file was not in version control. A tool error wrote over it, there was no history to restore from, and the only complete copy of the book left was a PDF. I rebuilt the source from that PDF and the text came back complete, which is exactly what made it dangerous. Every page with a custom layout had quietly gone back to a default, and the back cover had lost the publisher logo and the ISBN barcode completely. Comparing the text showed none of it. That version was days from a print run of thousands, and the first person to notice a missing barcode would have been the printer. It is tracked now, and after any rebuild every designed page is compared against the last known good PDF as a picture, not as text.

Format
122 pages · English and Chinese
Source
Typst, compiled to print-ready PDF
Cover
Generated layers, composited by hand
ISBN
978-981-94-6269-8
Print run
Thousands of copies, offset
My role
Production, not authorship

How I Work

Engineering philosophy

18 years in technology has taught me that AI is the unpredictable part of any system. I treat a model as an input I do not trust, and put ordinary engineering safeguards around it.

Do not let the model decide

When a wrong answer costs something real, the model should not be the one doing the maths. Let it read and understand: transcripts, yes or no answers, what a sentence means. Then let ordinary code work out the result.

Enforce a mandatory human gate

Letting AI draft on its own saves a lot of time. Letting it publish on its own is a risk to the brand. Drafting and review are separate agents, and the work always stops for a person to approve before anything goes out.

Design for silent failure

AI does not crash when it is wrong. It returns something that looks right, or a tool quietly stops matching what you think it matches. Never rely on one instruction in a prompt for safety. Build separate checks that can each catch it.

Background

Technical & commercial foundation

18 years across code, design and the P&L. That is why these pipelines are secure, usable, and worth what they cost to run.

Building with today: JavaScript & Node · Python · HTML/CSS · n8n · Make.com · Claude Code · agentic workflows · Gemini API · Docker with hardened containers · REST API integrations · Linux & Caddy
Earlier foundation: PHP · MySQL · live database management · WordPress · Magento · UI/UX design

2025 →Applied AI Systems Builder. Leading production AI systems from architecture through to release. I build multi-agent pipelines by directing agents rather than writing every line by hand. The aim is always the same: systems that run without me, and still stop for a person before anything leaves the building.
2021 →Corporate Services Manager. At a Singapore marine and industrial engineering firm, alongside the work above. I report to the Managing Director and Chairman and turn their strategy into how the operation actually runs: administrative workflows, staff scheduling, HR compliance and financial administration. The remit is deliberately mixed. The same week can involve the company servers and web infrastructure, a payroll filing, and a fire safety inspection.
2020 →Head of Product & Technology (Co-Owner). Directing technology, design, marketing, book production, and overall P&L. Scaled a flagship PSLE Oral title to the #1 best-selling spot on Shopee and secured physical distribution across Popular bookstores, managing demand forecasting and print runs of thousands of copies.
2008–20Lead Developer & UI/UX Strategist (Co-Founder). A decade of building for clients and running an agency. Hands on with UI and UX design, HTML/CSS, PHP, live databases, WordPress and Magento. I ran the projects, led the developers, and trained the clients to use what we had built for them. The security habits and usability standards I apply to AI infrastructure today come from here.

Why look for a full-time role when I already co-own a business?

Because the business now runs on the systems above. That was the point of building them. What it cannot give me is harder problems. One small publisher produces a limited supply of them, and building alone means nobody reviews my thinking or pushes it further.

I want to do this full-time, on systems bigger than a company of my own will ever justify, with a team to argue with. I have spent 18 years being the person who owns the outcome, and that does not switch off when the job title changes.

Want systems like these on your team?

I am looking for a full-time role in Singapore, building and running AI systems that hold up in the real world. If you are hiring an Applied AI Engineer, and you want someone with 18 years of commercial judgement who treats a model as something to be checked rather than trusted, I would like to hear from you.

1 →

2 →

3 →

Thank you, that’s sent.

I read everything myself and will reply from hello@ryanchong.me.

Prefer to just email me? hello@ryanchong.me

What you type here goes to me and nobody else. I use it only to reply to you. It is never shared, sold, or added to any mailing list.