DEV Community

Cover image for We built an AI agent that runs in the cloud, on a schedule, and hands you the finished file
TuringCorp
TuringCorp

Posted on

We built an AI agent that runs in the cloud, on a schedule, and hands you the finished file

We built an AI agent that runs in the cloud, on a schedule, and hands you the finished file

A few months ago we sat down and asked a question that turned out to be more awkward than it looked: what does an AI product look like if you assume the user is not sitting in front of it?

Almost everything in this category is built around a conversation. You open a tab, you type, it answers, you close the tab. That shape is so dominant that it has quietly become the definition of the product. But it has a consequence nobody puts on the box: the work only exists while the person is watching. When you close the tab, the thing stops having opinions.

We wanted the opposite. So we built the whole thing the other way round: the agent lives on our machines, it has a schedule of its own, and the artefact it produces lands in your inbox whether or not you were there to watch it happen.

This is a write-up of what that forced us to build, and where the awkward parts are. It is not a launch post — the product is called CloudPal, it is in a limited preview, and this is really about the architecture decisions that a "always-on agent" makes unavoidable.

The framing we rejected

The obvious way to build this is as a chat app with a cron job bolted on. We tried sketching it and the sketch collapsed immediately, for a reason worth spelling out.

A chat session is the wrong unit of work. Chat sessions have a beginning and an end, they are scoped to a person who is present, and their state is implicitly "whatever still fits in front of the model right now." The moment the primary use case becomes "do this while I sleep," every one of those assumptions fails at once:

  • The work must survive the browser closing, so session state cannot live in the browser.
  • The work takes minutes to tens of minutes, so it cannot be pinned to a synchronous HTTP request.
  • The work has to be reported back somewhere the user will actually look, which is almost never a chat transcript from eight hours ago.
  • And the work has to get better the second time you ask for it, which means the session cannot be the memory.

So the design goal stopped being "a chat product" and became "a task executor that happens to accept instructions in natural language."

Ask for the outcome, not the answer

The first product decision that follows from this is a small one on the surface and a big one everywhere else: the primary output is a file, not a reply.

When you ask a chat assistant to research something, you get an answer. It scrolls. You copy the parts you want into a document. That last step — the copy-paste assembly step — is where most people lose the value, because it is unglamorous work that the machine could have done and didn't.

So we made the deliverable literal. If you ask for a comparison of three approaches, you get a document. If you ask for a briefing on the day's news in a set of topics you follow, you get a briefing that you can forward. If you ask for something to show a colleague, you get a deck with a beginning and an end, not an outline that you have to dress up.

This sounds like a UI preference. It is not. It is a forcing function on the inside of the system: the moment your deliverable is a file, you have to be able to say when it is done. A conversation is never done; it just stops being typed into. A file is done, and if it isn't, you can tell. Half of the engineering pressure in this product comes from that single property.

Scheduling is not a feature, it is the interface

Once the deliverable is a file, the next question is when it gets made. The answer we landed on is deliberately boring: you set a time, and it happens at that time.

What is interesting is how much falls out of taking that seriously.

Time zones stop being cosmetic. A schedule of "eight in the morning" is not a stored timestamp, it is a rule. That means the system needs a real notion of the user's morning, not the server's. If you have ever shipped a daily notification to a global user base, you know how much of a product turns out to be time zone handling. Ours is no exception.

Failure has to be survivable, and it has to be visible. When the user is watching, a failed step can be retried in front of them and nobody needs to know. When the user is asleep, a retry is a decision the system makes on its own, and what it did has to be reconstructed later. We ended up treating the record of a run as part of the product rather than as a debugging aid. If the run took a long way round, the write-up says so.

The unit of work has to be idempotent enough to be safe. A task that runs every morning at eight is not a button press. It is a recurring commitment, and recurring commitments interact badly with anything that isn't replay-safe. This is the least visible part of the work and the part that has cost us the most.

And there is a hard latency budget you can't negotiate with. If the user told you "eight in the morning," arriving at 8:40 is a bug, not a slowdown.

Memory is a first-class subsystem, not a bigger window

Here is the part we cared about most, and the part that made the architecture get strange.

The pitch of most assistants is that they are getting smarter. That is a statement about the model, and the model is not something you or we control — it improves on someone else's schedule and gets cheaper on someone else's roadmap. Betting an identity on it is a bad trade, because everything a model can do today becomes table stakes.

So the thing we chose to invest in is narrower and more durable: how well it knows one specific person.

We gave this its own subsystem rather than treating it as "put more of the conversation back in the prompt." A larger working buffer is a bigger desk, not a better memory. It doesn't decide what matters, it doesn't survive the session ending, and it doesn't accumulate anything across weeks. What we wanted was closer to a set of notes that gains value with time and belongs to exactly one user: your preferences, the way you like documents structured, the topics you actually care about, the corrections you made last month that you should not have to make again.

Two consequences of building it this way, both of which we underestimated:

It changes what a good response looks like. Once the system can remember that you prefer a blunt summary up front, the right answer to the same question is different for you than for someone else. That's a much harder evaluation problem than "did the model answer correctly."

It makes the product less good on day one, and that is intentional. A system that starts by asking you a questionnaire is asking you to do the work of being known. We chose the opposite: start with nothing, be a bit generic for a few days, and get better because you used it. That is a worse demo and a better product, and it is genuinely hard to hold the line on when you are watching a first-time user evaluate you in ninety seconds.

The entrance has to be three actions

Speaking of first-time users. The single most common way we lose people is not that the product fails — it's that they never start.

There is a specific kind of friction that has nothing to do with capability: the blank input box. People who have not used AI much aren't impressed by it, they're intimidated by it. They don't know what to say. They worry about saying it wrong. Someone who has been using these tools for a year has forgotten this feeling entirely, and it is the exact feeling that decides whether a product aimed at ordinary people works.

So we set an explicit budget for the first run: sign up, sign in, say what you need. One step beyond that and we consider it our failure, not the user's. No setup wizard. No picking a plan before you've seen anything. No requirement that you already know what you want to use it for — being vague is a supported input mode, and the system is expected to ask the clarifying questions rather than bounce the request back at you.

The related decision is where it runs. CloudPal is not installed on your computer. It doesn't use your disk, it doesn't need your machine left on, and it doesn't touch your local files — the only thing it produces is what it generates for you, delivered to your inbox or handed back as a download. Close the browser and it is still running. Sign in from a different device and it is the same agent with the same memory. For an always-on product this is not a deployment detail, it is the entire premise: an agent that only exists while your laptop is open is not always on.

What is genuinely hard about this

A few things this shape of product makes hard, in case you are building something similar.

Evaluation stops fitting on a leaderboard. We can measure whether a document was produced on time and whether it matches the ask. We cannot reduce "did it understand what this person wanted" to a single number, and every off-the-shelf score we could adopt measures the part we deliberately chose not to differentiate on.

The interesting failures are quiet. A wrong answer in a chat is visible immediately. A document that is 90% right and misses the one thing that mattered gets sent to someone else and never comes back to us. We think about this a lot.

"Always on" raises the bar on honesty. When the system runs while you sleep, you cannot watch it work. Which means when it does something the long way round, the only honest thing is to say so — and a product that quietly presents the polished version of what happened is training its users to trust a story instead of a record. We would rather hand you the awkward detail. We will get things wrong; we would rather not dress it up.

Where it is now

CloudPal is in a limited preview. New accounts get a dollar of credit, which is enough to actually run the thing and see whether the shape fits how you work, and the number of new accounts per day is capped.

The three things worth trying, if you want to judge the architecture rather than the marketing: give it something you would otherwise spend a morning on and let it land in your inbox; give it a document you need to hand to another human; and then give it the same kind of task a second time, two weeks later, and see whether the second one needed less explaining than the first. That last one is the whole thesis. If it doesn't hold, the rest of it doesn't matter.

The address is CloudPal.TuringCorp.net — create an Agent Pass, sign in, and say one thing you want done.

Top comments (0)