🦆 DuckFleet, an agent fleet that hunts loyalty points while you sleep

Why I built it

Building AI agents right now feels a bit like building a website in the early 2000s. Everyone's having a go, a lot of it is throwaway, and somewhere in the pile is the stuff that actually sticks. The use I find interesting is the boring one: agents that do useful, time-costly errands you'd rather not do yourself. The chasing, the comparing, the "is this actually a good deal or does it just look like one."

Collecting loyalty points is exactly that kind of chore. The value is real, but it eats time. In 2025 a $3.50 rubber duck at Big W got briefly famous because, stacked across the right promos, a pile of them earned enough Qantas points for a business-class seat. Real deal, real maths, but catching it meant living on OzBargain at midnight. I didn't want that job, so I built a fleet of agents to do the hunting overnight and tell me in the morning if anything's worth doing.

The part that got interesting was trust. Finding deals is easy. Letting an agent take actions in the real world without babysitting it is not. So DuckFleet is built around restraint as much as capability.

What it does

Every night a Cloud Run Job wakes up and the agents do the grunt work. Scouts read the deal feeds, a valuer runs the stacking maths, a "worth-it" agent weighs drive time and petrol against the reward, and a presenter emails me a ranked brief. I wake up to a short list of what's worth doing, and what got skipped and why.

It doesn't behave like a newsletter. It decides, it refuses, and it can act, all inside guardrails:

  • Forty minutes of driving for a $6 toy? It skips it and says why.
  • I told it no new credit cards, so it passed on a card worth about $1,600 in points, and told me it did.
  • It gives real reasons for skipping, not invented ones. "Velocity isn't a program you collect," rather than a vague "no points."
  • If a deal depends on stock, it can ring the store to check, but only after I approve, only in calling hours, once per store, and it opens by saying it's an AI.
  • It tracks its own cost each run, and on a quiet night with nothing worth doing, it says so instead of burning credit.

How I built it

It runs entirely on Google Cloud, with Twilio as the only outside piece, for the phone call.

  • Vertex AI (Gemini) for the agents, via the Google Agent Development Kit (ADK)
  • Cloud Scheduler and a Cloud Run Job for the nightly, scale-to-zero run
  • Maps Routes API for real drive-time, Cloud Text-to-Speech for the call audio
  • BigQuery for history, Cloud Logging for the audit trail, Secret Manager for credentials
  • Pydantic v2 schemas, with a SequentialAgent wrapping a ParallelAgent of scouts

One rule shaped everything: the model finds the stack, but Python does the arithmetic. The numbers have to be right, so the LLM never does maths it can hand off. Python works out the points, the cents-per-point, then subtracts the real cost of the trip (time plus fuel) before anything reaches me. The fleet runs the same test on itself, value found against compute spent, so it knows when a run wasn't worth doing.

The guardrails are enforced in code. Every real action goes through guardrails/gates.py: ToS filtering, spend caps, preference skips, one call per store, calling hours, AI self-identification, and an audit log. A replay mode runs the whole thing against fixed fixtures, which powers the demo, the eval tests, and an "email me a sample brief" page you reach by scanning a QR. Setup is a conversation ("I collect Qantas and Flybuys, no new cards, $100 a week"), and anyone can deploy their own copy to their own Google Cloud with one click, bringing their own key, so it costs me nothing and stays private to them.

What I learned

The moments that landed in the demo were the ones where the agent said no. Refusing a drive, skipping a card, asking before it dialled. An agent you can trust turned out to be more compelling than one that just does more. Keeping the maths in Python rather than the model is what made the output trustworthy, and it kept the red-team eval tests easy to pass. And being upfront helped: labelling the re-enacted store call as a simulation (real audio, a stand-in on the other end) made it read as more credible, not less.

Challenges

The phone call was the riskiest part, so I timeboxed it and got a real, gated Twilio call working with real TTS audio and every guardrail enforced. Getting honest skip reasons took work too; early versions invented "no points" excuses until I moved that logic into deterministic code. And I had to be strict about scope: no multi-tenant hosting, no loyalty-account logins, nothing that spends money for you. I'd rather ship governed agency done properly than a pile of half-built features.

What's next

  • Value spend you'd make anyway as effectively free, which fixes the "spend $X, get points" offers that currently look worthless.
  • An agent that adapts the profile based on what I actually act on.
  • Redemption-side hunting: where the points can take you, not just how to earn them.
  • Being able to load it from a user's existing gemini apps or gemini AI assistants so the onboarding is even more seamless.

Built With

Share this project:

Updates

Submission history