LOGAN MULLIGAN / HOW I BUILD AUTOMATION

How I build it.
And how I check it.

The engineering behind the business automation I build: how a project is scoped and tested, what “real checks” means, how retrieval and AI steps earn their place, how the work is traced, and when running AI on your own hardware makes sense.

Written for technical teams and the curious. If you run the business and want the short version, start with what automation does for you, what it costs and how we begin.

01 / FROM SCOPE TO SUPPORT

What goes into a build you can rely on.

This is the engineering behind the investment. From our first working session through handover, I build around your process, the result we agreed on and what your team needs to keep it running.

  1. 01

    Scope the actual problem

    Walk through the work with the person doing it. Identify inputs, handoffs, exceptions, data ownership and the cost of getting it wrong. Agree on what a useful result looks like.

  2. 02

    Map the system

    Document the source of truth, APIs, permissions and dependencies. Decide where ordinary code is enough and where a model’s judgment actually helps. Define the human handoff.

  3. 03

    Build a small, complete path

    Connect the trigger to a real outcome. Use test data, versioned configuration and narrow permissions. Keep credentials out of prompts, workflow exports and source control.

  4. 04

    Try to break it

    Test missing fields, repeated events, stale documents, expired credentials, timeouts and conflicting instructions. Use a fixed evaluation set so an “improvement” has evidence behind it.

  5. 05

    Deploy with a way back

    Stage the release, limit its reach and verify changes against the source system. Document ownership, rollback, recovery and how a person takes over.

  6. 06

    Watch the work, then improve it

    Review success rate, exceptions, cost and latency. An alert should tell someone what failed, what is affected and what to do next. Re-test when prompts, models or source data change.

What “real checks” means

Validate the input. Types, required fields, ranges and business rules. A valid JSON object can still contain a wrong answer.

Make retries safe. Timeouts, bounded backoff and an idempotency key, so the same event does not create two invoices or two jobs.

Control the action. Least privilege, scoped tools and explicit approval for actions that need a person’s judgment.

Verify the result. Read back the affected record, reconcile the outcome and preserve an audit trail. A 200 response is not the whole check.

02 / FOLLOW THE EVIDENCE

Give the answer somewhere to come from.

RAG means retrieval-augmented generation. In plain English: find relevant information first, then use it to help answer the question. It can make your documents useful without retraining a model every time a policy changes.

INTERACTIVE / RETRIEVAL AUGMENTED GENERATION
Before the question: import → clean → split into passages → embed → index. Keep source IDs, versions and permissions with every passage.
STEP 1 / 5

Start with a real question.

“What is our policy for returning a damaged item?” The application identifies the user and which documents they are allowed to see.

EXAMPLE EVIDENCE
Returns policy · §4

Damaged items: retain packaging, record the issue, request a review.

Permission checked · source attached

Illustrative workflow and fictional policy. This demonstration does not send data to an AI model.

The document work matters.

Clean extraction, sensible passage boundaries, source links, dates and permissions all affect the answer. I plan for updates and deletions, too. An old policy that keeps resurfacing is a data problem with an AI interface.

The model can still be wrong.

Retrieval can miss evidence. Documents can disagree. A model can misread a good passage. I check each stage and give the system a way to say it does not have enough information.

Is your team spending its day hunting for answers? Let’s look at the documents, the access rules and the work that comes after the answer.

Talk through my use case
03 / THE TOOLBOX

Choose the tools around the job.

I work across workflow automation, software, infrastructure and AI. The point of knowing the stack is being able to explain which parts a project actually needs.

Orchestration & integration

n8n · Rewst · REST APIs · webhooks · MCP

Connect systems, route work and expose tools with clear inputs and permissions.

Software & data

Python · TypeScript · SQL · Postgres / pgvector · Supabase · Redis

Build the rules, records, retrieval and state that make the workflow dependable.

Delivery & operations

Docker · Git · Cloudflare Workers · queues · CI/CD

Ship repeatable releases, isolate workloads and recover when dependencies fail.

AI & evaluation

Langfuse · embeddings · hybrid RAG · rerankers · local LLMs

Choose the evidence, inspect the model calls and measure whether changes help.

n8n and Rewst

Workflow tools make triggers, integrations and handoffs visible. I treat them as software: named steps, separated environments, credential management, error paths and versioned changes. A failure workflow should point to a recoverable job and a specific next action.

n8n: error handling ↗

MCP: a consistent tool interface

Model Context Protocol gives applications a common way to discover and use tools, resources and prompts. A RAG service can expose a search tool through MCP. I still own the authorization, input limits, timeouts, logging and approval rules around it.

MCP: architecture ↗

MCP, drawn out.

Inside the AI app, one MCP client talks to each MCP server, and each server reaches one tool. Requests that only read go straight through. Requests that change something wait for a person’s OK.

Diagram / MCP, drawn out
In the appIn your AI appServersMCP serversToolsYour tools
The host · one MCP client per serverAI assistantOne app, four separate connections. Each server only sees its own tool. Changes wait for your OK.
  • MCP clientone per serverCalendar serverread events, find free timeCalendarread only
  • MCP clientone per serverCRM serverfind a customer, create a jobCRMchanges ask you first
  • MCP clientone per serverDocs serversearch and read filesDocumentsread only
  • MCP clientone per serverEmail serverdraft and sendEmailchanges ask you first

Drawn from the MCP specification, revision 2026-07-28: one client per server inside the host, and a person able to deny any tool call. What is MCP? A plain-English guide

04 / START WITH THE BASICS

First, what is a token?

Before we talk about model speed or context windows, this part matters. A token is a unit the model processes. It might represent a word, part of a word, punctuation or bytes. One word does not always equal one token.

Text becomes numbers before it becomes an answer.

A tokenizer converts text into token IDs. Byte-pair encoding, or BPE, builds a vocabulary by repeatedly merging frequent symbol pairs during training. At inference, the learned merge rules split new text into pieces the model knows.

Tokenization varies by model and language. Code, unusual identifiers and long documents can use very different token counts from ordinary prose. I use the actual model’s tokenizer when the budget matters.

Input tokens affect prompt processing, context usage and cost. Output tokens affect how long generation continues. The context window is shared by instructions, history, retrieved material, tool results and the response budget.

Hugging Face: BPE tokenization ↗
TOY BPE VOCABULARY
“lower”
lower

Start with symbols. In byte-level BPE, the base vocabulary represents bytes; text encoding and pre-tokenization come first.

A small teaching vocabulary, not the output of a production tokenizer. Real splits and token IDs depend on the model.

05 / RETRIEVAL ENGINEERING

Better retrieval is a measured tradeoff.

Embedding dimensions, search effort, reranking and context size all affect the path to an answer. I change one thing at a time and measure both quality and latency on representative questions.

01 / REPRESENTATION

Embedding dimensionality

An embedding is a numerical representation used to compare meaning. More dimensions mean more vector storage and distance-computation work; they do not automatically mean better retrieval. Model quality, domain fit and chunking matter too.

For uncompressed float32 vectors, raw storage is roughly documents × dimensions × 4 bytes, before index and metadata overhead. Dimension reduction must be supported by the embedding model and validated on the task.

02 / SEARCH EFFORT

HNSW and efSearch

HNSW is a graph-based approximate nearest-neighbor index. The search walks the graph instead of comparing every vector. efSearch controls the search candidate-list size; pgvector calls it hnsw.ef_search.

Increasing it generally trades more search work for better recall. It is different from the number of results returned, top-k. Selective filters can leave too few matches; inspect filtering and iterative scan behavior in the actual database.

03 / QUALITY

ANN recall and hybrid search

Approximate search can miss neighbors. ANN recall@k compares its results with an exact-search reference under the same filters. That measures index fidelity; a labeled relevance set tells us whether the retrieved passages actually help answer the question.

Combine lexical retrieval, often BM25, with semantic retrieval when exact IDs and meaning both matter. Reciprocal rank fusion can merge ranked lists without pretending their raw scores are directly comparable.

04 / PRECISION

Cross-encoder reranking

A cross-encoder reads a query and passage together to score their relevance. It can reorder candidates more precisely than comparing independently created embeddings, at the cost of extra model work.

Candidate count, passage length, batching and hardware determine that cost. Rerank a bounded set, evaluate answer quality and trace the stage. Better ordering is valuable only if the overall response still meets the project’s goals.

Technical references: pgvector HNSW · Sentence Transformers cross-encoders · Supabase hybrid search

06 / SHOW ME THE TRACE

“The AI is slow” is not a diagnosis.

I want to see the wait, the retrieval, the model call and the first useful response separately. Otherwise we are guessing at the bottleneck.

TRACE LAB / ILLUSTRATIVE TIMINGS
REQUEST → FIRST CONTENT TOKEN0.785s

Same pipeline.
Different place to investigate.

Authorize / MCP
35 ms
Embed question
70 ms
Hybrid retrieval
120 ms
Cross-encoder
110 ms
Inference queue
90 ms
Prefill → first token
360 ms

The model’s prefill is the longest span here. Check context length and cache reuse before changing the vector index.

Hand-set, sequential timings for explanation. These are not production measurements, p95 results or performance predictions. Real spans can overlap.

TTFB

First byte

Time until the response starts arriving. A header or empty stream event can arrive before there is anything useful to read.

TTFT

First content token

Time until generated content starts. Define the boundary: model-call TTFT and the user’s request-to-first-token time are different measurements.

p95

The slower end

The time at or below which 95% of measured requests fall. Segment by workload and load; a single fast demo is not a p95 measurement.

What I put in Langfuse

One trace per request or workflow run, with separate observations for retrieval, reranking, each model call and each tool action. I attach prompt and model versions, token usage, latency, errors and evaluation results, with sensitive content redacted.

For a hybrid RAG pipeline behind MCP, I trace the boundary call and each internal stage. I record the first generated content timestamp, retrieval settings and source IDs so an answer can be investigated later.

Langfuse: trace structure ↗

How I find the bottleneck

Start with slow requests in the relevant p95 cohort. Compare them with normal requests. Check which spans expanded, then correlate with inference-server metrics: queue depth, prefill time, running requests and KV-cache pressure.

Changing efSearch might help retrieval time while hurting recall. A larger rerank batch might improve relevance while increasing TTFT. I compare end-to-end latency and quality before calling either one an improvement.

vLLM: serving metrics ↗
Define the clock. I use TTFB for the HTTP response, TTFT for the first generated content token, and a separately named time-to-first-useful-result for the application. A custom “TTIFB” metric needs an explicit definition. Flush timing and network buffering can make server and browser measurements disagree.
07 / ON-PREM AI & LLMs

Your hardware. Your constraints. A deliberate choice.

Running a model locally can keep inference and data inside your environment. It also means owning capacity, updates, monitoring, access control and recovery. I work through that tradeoff before recommending the hardware.

Start with the workload: model quality, number of users, context length, response time and data boundaries. Then size the machine. “The model fits” is only the first question.

INT4: smaller weights, real tradeoffs

Four-bit weight quantization reduces the storage used for model weights. An 8-billion-parameter model is roughly 4 GB of raw 4-bit weights versus 16 GB at 16 bits, in decimal units, before scales, unquantized tensors and runtime overhead.

It does not make the entire application four times smaller or faster. Quantization format, kernels and hardware matter, and quality can change. I test task accuracy and throughput with the actual serving stack.

KV cache: the memory that grows with use

Autoregressive models retain attention keys and values so earlier tokens do not have to be recomputed at every step. This cache grows with sequence length and concurrent requests. Weight-only INT4 does not automatically make the KV cache four-bit.

A useful sizing estimate is 2 × layers × KV heads × head dimension × cached tokens × bytes per element, summed across active sequences. Architecture, cache sharing and implementation change the details. Memory pressure can force queuing, eviction or offload, each with a latency cost.

Transformers: KV-cache strategies ↗
SPARSE COMPUTE ≠ SMALL MEMORY

Mixture of experts, without the magic.

In a sparse MoE model, a learned router selects a subset of expert networks for each token. That reduces active computation relative to using every expert. The full set of weights still has to be available in memory or through an offloading strategy.

“Active parameters” helps explain compute. “Total parameters” matters for weight storage. Experts are learned components, not little people assigned to specific subjects. Routing, shared layers, interconnect bandwidth and expert imbalance all affect serving behavior.

Mixtral of Experts: original paper ↗
MIXTURE OF EXPERTS / CONCEPTUAL2 of 8 selected
Token 1Learned router
E1stored
E2active
E3stored
E4stored
E5stored
E6active
E7stored
E8stored

Illustrative routes, not a model inference. Real expert counts, shared experts and routing rules vary by architecture.

Local is a deployment boundary, not a privacy guarantee. Check outbound integrations, remote embeddings, backups, telemetry and logs. Docker, a local runtime such as llama.cpp or vLLM, and an open-weight model still need secure configuration, license review and an operational owner.
08 / KEEPING UP, WITH A FILTER

Jev: a different shape of AI decision.

Released into early access September 15, 2026 · Note updated October 1, 2026

TypeSafe introduced Jev as its first public “System One Model,” built for structured decisions with probability and confidence information. Its announcement describes a different training approach, Reinforcement Learning for Calibrated Decisions, or RLCD.

What interests me is the interface: a bounded decision that software can use directly. Routing, classification and scoring can fit that shape well. A system may not need to generate a paragraph just to choose the next step.

That changes what I would evaluate: decision accuracy, calibration, cost of a wrong action and the threshold for human review. A correctly typed decision can still be wrong. I would validate those thresholds on the actual workload and monitor them after deployment.

Read TypeSafe’s dated release announcement ↗
THE DESIGN QUESTION
Input + bounded question
Typed decision + uncertainty
Verified actionHuman review

Choose thresholds from evaluation data and the consequence of being wrong.

LET’S MAKE IT USEFUL

You’ve seen how I build. Let’s talk about what you need.

Bring me the task that keeps coming back, the handoff that keeps breaking or the process that is holding the business back. We’ll sit down, put numbers around the problem and work out a plan worth investing in.

Plan my automation
FOR TECHNICAL TEAMS

Want to talk through the engineering?

Let’s discuss the design choices: evaluation, tool boundaries, retrieval quality, serving constraints and the traces that prove where the time went.

Email Logan at info@sunnyshoresit.com