AI Engineer World's Fair 2025
How agents broke app-level infrastructure
About this talk
GenSX founder Evan Boyle explains why slow, unreliable LLM calls and agent workflows lasting minutes or hours break assumptions inherited from conventional web applications and serverless infrastructure. He compares queues, Airflow, and Temporal; demonstrates background scraping and content-generation experiences; and outlines a React-inspired TypeScript architecture with instrumented OpenAI SDK calls, separate API and compute layers, and Redis Streams.
Chapters
- 0:00Introduction: agents, workflows, and the compute layer
- 1:22LLM latency, outages, and broken infrastructure assumptions
- 3:14Durable execution tools and serverless constraints
- 4:35Background ingestion and long-running agent experiences
- 7:54React-inspired components and instrumented OpenAI integration
- 10:14Decoupled API and compute architecture; GenSX resources
Talk transcript
- 0:00
[notification sound] How agents broke infrastructure. Particularly, we're going to focus on the compute layer today. [mouse clicking]
- 0:11
My name's Evan Boyle. I'm the founder and CEO in GenSX. I was an early employee at Pulumi, and I've spent my entire career working on cloud and developer tools. [keyboard clicking]
- 0:20
Typo warning. In the spirit of embracing AI for this talk, all diagrams are AI-generated, but 4o still has some spelling issues, so thank you for your patience. We all know this journey.
- 0:31
We start off as AI engineers with a simple prompt and a couple of tool calls, and typically, this is enough to raise our ten million dollar seed round. But from there, when rubber re-meets the road, we end up building workflows, right?
- 0:43
We take that fully non-deterministic code and make as much of it deterministic as possible. That might mean chaining a couple of very specific tailored prompts together that we've written evals against, uh, and more carefully controlling the context.
- 0:57
This takes the runtime of our workflows from thirty seconds to a couple of minutes, but eventually, we all end up becoming data engineers because the most challenging part of the problem is getting the right context into the prompts.
- 1:12
And that means that we might have to crawl a user's inbox, ingest code from GitHub, or many other artifacts that require lots and lots of LLM processing.
- 1:22
But our assumptions around infra have changed. In Web 2.0, you would build a simple web service where you'd make an API request, maybe talk to a database to fetch some data, and return all that back in a few tens of milliseconds.
- 1:38
In AI applications, our P1 is a couple of seconds at best, and that's only if you're using a fast model or if you hit a prompt cache. In the previous era of infrastructure, if you had a request that took a couple of seconds, your on-call was getting paged.
- 1:54
Um, and so the infrastructure that was designed for the last ten years of the web is not really designed for the applications that we're building today.
- 2:04
LLM applications are really built on shoddy, uh, foundations. It's really hard to build reliable apps today. And if you're like us and you run a tight ship, you might have a Slack channel that looks like this, where you subscribe to, you know, issues and outages from your dependencies.
- 2:19
But luckily, this one only lasts, you know, an hour. By ten PM, it's resolved. [keyboard clicking]
- 2:24
But oh, at one twenty AM, we're back at it, and four AM, it's still going on. But surely, you know, ChatGPT and OpenAI have, have better availability, right? Well, I wouldn't really trust this ninety-nine point nine percent uptime number, and no, it's not.
- 2:40
Lots of yellow and red in this graph. But maybe we could have failed over to, you know, Gemini during this time period. Nope, we have an outage during the exact same time period.
- 2:51
And even if you don't hit an outage, you still have rate limits to contend with. A lot of these traffic patterns are gonna be extremely bursty as you batch process documents from a user or you onboard new customers, and not everybody has tier five rate limits that require spending thousands of dollars just to get to that point
- 3:09
that you can start experimenting with high levels of traffic.
- 3:14
So we start off nice and happy with our prototype. Maybe we built something on top of the Next.js chatbot template. That's easy, right? But as our workflows start running for minutes and hours, us full stack AI engineers accidentally become data engineers. [keyboard clicking]
- 3:30
So how do people solve this today? You know, there-- this used to be something that was rather niche, ro-long-running workflows, data engineering. So there is an existing set of tools.
- 3:40
People build these Rube Goldberg machines on top of queues like SQS. They might use batch processing data engineering tools like Airflow or durable execution engines like Temporal. But me personally, I'm a TypeScript developer.
- 3:52
I'm a full stack engineer, and frankly, I don't wanna use anything that was designed by a Java engineer. No offense. [keyboard clicking]
- 4:00
I'd much rather use serverless. What about existing serverless providers? They aren't really well suited for these kinds of long-running workflows. Uh, most of them time out after five minutes, and some of them even limit outgoing HTTP requests.
- 4:14
And for all of them, they don't really have native streaming support. Streaming is something that you have to bolt on at the application layer and not something that's a native part of the infrastructure that you're building on top of.
- 4:27
Something that's really important when you're building an application that might run for multiple minutes, users might refresh the page, so you want resumability.
- 4:35
And so let's look at some of these common product experiences. We're gonna look at both onboarding, where we might ingest a bunch of data from the user with an LLM up front, and then also a product experience where we're gonna run an agent that's gonna take multiple minutes, and we have to keep the user engaged during that
- 4:51
time period. So during this onboarding experience, the user puts in their URL, right? And we use a single LLM call to grab some information from that web page and then detect all the pages that we're gonna scrape, right?
- 5:04
And now we've kicked off that scraping job in the background, and it's gonna take multiple minutes. Uh, and we're gonna be making hundreds of LLM calls to extract content from those web pages and enrich them.
- 5:14
And we want the user to be able to start using the product right away. So this ingestion can take, you know, a varying amount of time, but we want users to use the app immediately.
- 5:25
If we wait ten minutes, that means we're gonna have increased fall off in the funnel, so we have to run this in the background, right? And we wanna show users the status of this ingestion as they're using the product.
- 5:35
We want them to know, "Hey, as time goes on, we're gonna enrich more data, and your experience is gonna get better." [keyboard clicking]
- 5:42
Next, this is an example of building a content generation app, right? We're gonna write a blog post, uh, about building high-performance web apps with Vercel and Next.js. And this agent, we tell the user up front, "Sit back and relax.
- 5:56
This is gonna take a couple of minutes." And on the right, we're showing them all of the different steps, right? We're running research. We're writing an outline. And we're writing each section step by step.
- 6:07
Since this takes multiple minutes, it's really important that if the user leaves the page or navigates away, that they don't lose this context, right?
- 6:16
And so that workflow that we built when working on a previous product took three to four minutes, and we really felt a lot of friction experimenting with longer workflows.
- 6:26
Like, we were deterred from making our workflows longer than five-plus minutes because that meant that we would have to make deep infra changes due to limitations from our serverless provider.
- 6:37
Eventually, we did rip it out, and it was a bunch of work, but it took us much longer than we should have to run those experiments, uh, because of the amount of work that was required to m-migrate off of, you know, our easy-to-use serverless offering.
- 6:52
Also, we need to stream both the final content as well as the intermediate status, and if the user refreshes the page and comes back, we want them to see that same thing, just like you get with deep research, right?
- 7:04
And if there's an intermediate error, users are gonna be way more frustrated if it takes them five minutes to get back to that same point, uh, versus if it's just, you know, a simple webpage that you have to refresh or a form that you have to resubmit.
- 7:18
So we built a lot to make this easy in our core product, uh, when we were working on, you know, agentic workflows, uh, and we ended up turning a lot of this into an open source library.
- 7:30
So we built a simple component model that's infra-infrastructure aware, right? Uh, the, the framework itself is very aware of the infrastructure it's running on, and the infrastructure is aware of the framework.
- 7:42
And that's so that we can provide things like resumable streams for intermediate status, uh, and final output, and we call this a bit of an anti-framework. It's unopinionated and focused on building blocks.
- 7:54
Uh, it's-- it takes inspiration from React's component model and applies it to the back end 'cause we know that abstraction is bad when building agents. You don't want to abstract.
- 8:03
You want to share. You want to compose. You want to reuse code. So we have components that are reusable, idempotent, independently testable steps, and then workflows that are collections of components that run together.
- 8:16
So this is a simple component that uses a wrapped version of the OpenAI SDK. It's wrapped so that we can get a bunch of other tooling for retries and tracing and things like that, but it's sa- the same exact OpenAI surface area that you would expect.
- 8:29
We give you full access to the model, so it's just a prompt, a little bit of context that's injects-ingested, and it returns a response. So a simple function that takes in some prompts and returns some output, and it can be independently run or tested.
- 8:43
We can also combine it together into what we call a workflow. This workflow fetches the front page of Hacker News, analyzes those posts, generates reports, writes a tweet, and then edits the report.
- 8:55
And with this, every single step, we're gonna get a retry boundary, an error boundary off each component, and we're gonna get traces, both at the top level of the workflow, but also all of the components that run within it.
- 9:09
Each workflow can be turned into a set of REST APIs automatically by the framework that support synchronous invocation as well as asynchronous invocation and the relevant API so that we can retrieve the intermediate stream and the final output stream if needed.
- 9:27
When we run this workflow, we see that we get a trace. This trace shows us all of the nested components that run inside the workflow, including all the tokens, all the details on the OpenAI call, user messages, system messages, so it makes it super easy to debug.
- 9:42
And we have built-in retries. Every component has a fluent API hung off of it that allows you to configure a component with things like retries and a cache. So if I have one component that's particularly problematic, I can add an exponential retry policy, uh, with...
- 9:57
and, and configure the number of retries that run.
- 10:01
And so this all gets deployed to a serverless platform that we built that's tailor-made for long-running workflows and building agentic UIs, uh, for processes that run in the background.
- 10:14
So we have an API layer and a compute layer that are completely separate, and this is really important for a lot of reasons. The API, the API layer invokes the compute layer and passes it in a Redis Stream ID.
- 10:27
That's the last time that the API layer is gonna have to talk to the compute layer. The rest of it is going to happen via communication with this Redis Stream.
- 10:34
Status is gonna come from the Redis Stream. The output is gonna come from the Redis Stream. And as the sandbox program executes, it's gonna emit heartbeats so that the background processes within the system can monitor and make sure that a workflow runs to completion and doesn't die or doesn't crash.
- 10:51
And if it does, we can automatically restart it or notify a user.
- 10:57
So key architectural points of this is this separation between the API and the compute layer. It allows us to scale things independently, scale the API layer independent of the compute layer.
- 11:07
It also allows us to plug that compute layer, so we can provide, uh, a compute layer by default on top of ECS, but we can allow users to bring their own compute layer as well since it's completely stateless and just talks to the API layer and the Redis Streams to store output.
- 11:23
All that API goes to the Redis Stream, both for sync and async workflows, which means that we get resumability, right? The API layer only reads from the Redis Stream, not the compute layer directly, so that means that we can build UIs that allow users to refresh the page, navigate away, transparently handle errors, uh, and they still get
- 11:41
the full history of status messages and all of the output, um, something that you wouldn't get from a typical serverless like infra platform.
- 11:52
Like we said, key point here is being able to refresh the page, resume directly from the Redis Stream, and get all of your intermediate status messages. None of the work is lost if the new user navigates away or if the web browser terminates the connection to the API server.
- 12:07
So things and lessons to consider when you're building your own infrastructure for agentic workflows. Always start simple. You're not gonna write a workflow that runs for an hour on day one, so don't build for it.
- 12:19
But do plan for a future that's long-running. In my opinion, this is where agents are going, and I think that we can see this with all of the recent coding agents that have come around, experiences like deep research.
- 12:30
Like, the future is giving your agent instructions and letting it go off and do work for you and communicate with you when you need it. And to make that happen, think about keeping your compute and API plane separate and lean on Redis Streams for resumability.
- 12:45
Make it easy to u- for users to navigate away from the page, not lose progress, and handle errors transparently. All this is also to say you gotta take care when deploying.
- 12:55
If you're gonna let your workflows run for sixty minutes, you have to be very, very careful about how you drain workers and how you, uh, do kind of a blue-green deployment pattern.
- 13:04
And overall, the devil is really in the details. Easy to get started, but very hard to get this right.
- 13:11
Now, it's really, really fun to build all of this infrastructure yourself. But if you don't wanna build it yourself, I'd encourage you to check out GenSX on GitHub, where we've implemented a lot of this for you.
- 13:23
Again, my name's Evan. Thanks for having me at this talk, uh, and happy building.