Juan Pablo Gallegos Work Lina

Lina

Rebuilding a brittle no-code agent into a system I could actually steer.

AI / Backend Engineer · Freelance 2025 Python LangChain RAG WhatsApp
Role
AI / Backend Engineer
Duration
3 months
Stack
Python · LangChain · pgvector
Context
WhatsApp commerce agent
Proof summary

What changed before the long read

The case is not “AI agent built.” It is a live agent moved from demo fragility into an owned, inspectable production system.

Migration
No downtime while roughly fifteen merchants kept using Lina daily.
Control
A no-code wrapper became an owned Python and LangChain stack.
Operability
Bad answers became traceable through persisted state and stage-level logs.
01

Context

Lina is a WhatsApp agent that recommends local businesses inside a normal chat — find a florist, a hardware store, a place that fixes phones — and routes shoppers to merchants who pay to be listed.

By the time I joined it was already in daily use by around fifteen merchants. It was real, it had users, and it was held together with tape.

02

Problem

Lina had been built as a no-code wrapper: a chain of third-party blocks wired together in a visual flow. It worked for the demo and kept working until it didn't.

There was no way to debug a bad answer, no test surface, and no real visibility into why the agent did what it did. Adding a merchant or tuning a recommendation meant clicking through a flowchart and hoping nothing downstream broke.

03

Constraints

Live merchants depended on Lina every day, so the migration could not go dark — the new system had to take over without a visible gap.

The WhatsApp Business API sets its own rules: session windows, template messages, and rate limits that the design had to respect.

This was a solo freelance engagement measured in weeks, not quarters. The rebuild had to reach feature parity fast and stay maintainable by one person.

04

Role

I was the sole engineer. I re-architected Lina from scratch on a Python and LangChain stack, designed the retrieval layer, and owned the WhatsApp integration, deployment, and observability end to end.

05

System shape

Lina is a pipeline, and every stage is something I can inspect on its own:

Inbound webhook
Normalize
Intent + RAG
Compose
WhatsApp send

An inbound message is normalized, classified for intent, and answered with retrieval-augmented generation over the merchant catalogue stored in pgvector. A response composer shapes the reply, and a send adapter wraps the WhatsApp API so the agent core never imports it directly.

Conversation state is persisted per phone number, and every stage logs its input and output — so a bad answer is a thing I can trace, not a mystery.

Trace surface
Observable pipeline
Inbound
Normalize before reasoning. WhatsApp payloads become a predictable message shape before the agent core sees them.
Retrieval
Separate data failures from model failures. Intent, merchant lookup, and answer composition can be inspected independently.
Boundary
Keep provider quirks outside the core. The WhatsApp adapter owns session windows, templates, and send semantics.
06

Key decisions

Decision 01
Owned code over no-code

Once real users arrive, predictability and debuggability beat speed-to-first-demo. A no-code flow is a great way to find the product and a poor way to keep it running.

Decision 02
RAG over fine-tuning

The merchant catalogue changes every week. Retrieval keeps answers current as data changes, with no retraining and no model drift to manage.

Decision 03
Provider behind an adapter

WhatsApp send and receive are wrapped behind an adapter, so the agent core is fully testable without touching the live API and provider quirks stay in one file.

07

Trade-offs

Gained

  • Every answer is traceable end to end
  • Adding a merchant is a data change, not a flowchart edit
  • A deterministic test harness around the agent core
  • Provider quirks isolated in one adapter

Cost

  • More infrastructure to run than a hosted no-code flow
  • A solo-maintained stack with a single owner
  • Cold-start engineering time before reaching parity
08

Outcome

Lina migrated off the no-code wrapper with no downtime and stayed in daily use by its roughly fifteen merchants throughout. Answers became debuggable and improvable, and the system finally had a foundation that could grow past the demo it started as.

09

Lessons

1
No-code is an excellent way to discover a product and a dangerous way to operate one once people depend on it.
2
Retrieval quality is a data problem long before it is a model problem — most of the wins came from the catalogue, not the LLM.
3
In a solo engagement, observability is the feature that lets you sleep. You cannot staff your way out of a bad night, so the system has to explain itself.