Juan Pablo Gallegos → Work → Lina
Lina
Rebuilding a brittle no-code agent into a system I could actually steer.
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.
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.
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.
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.
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.
System shape
Lina is a pipeline, and every stage is something I can inspect on its own:
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.
Key decisions
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.
The merchant catalogue changes every week. Retrieval keeps answers current as data changes, with no retraining and no model drift to manage.
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.
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
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.