Build a Movie Marketing Simulator AI Agent | AI Ave Ep 3 Tutorial
Chapters14
The host introduces the concept of AI agents in Hollywood and sets up prerequisites (GitHub, code editor, Cloudflare, and the Cinear Marketer project) while explaining the basic input-output nature of AI and hinting at the tutorial's hands-on exploration.
A fun, hands-on tour of building and running a Movie Marketing Simulator AI agent with Cloudflare’s Agents SDK, including local dev, multi-agent collaboration, and open-source workflows.
Summary
Cloudflare Developers’ Craig walks through the AI Ave Ep 3 tutorial, showcasing York’s Cinear Marketer app and the underlying Agents SDK. The session blends live coding with demonstrations of deploying, cloning, and running a local Cloudflare-based AI app that generates movie elements like posters, casts, and reviews from a title. We see how multiple agents communicate: a Hollywood agent drives the movie data, while a Reporter agent fetches popular trends to influence casting and descriptions. Craig emphasizes practical steps: set up GitHub, SSH cloning, npm install, and running a local dev server, plus how to expose an API and deploy to Cloudflare. The tutorial also digs into front-end integration (React) and the agent state model, including how state syncs in real time across connected clients. Throughout, York’s app illustrates input/output dynamics in generative AI, the value of “human in the loop,” and how to enable open-source collaboration via forks and PR-style workflows. The guide closes with tips on securing tokens, using dev.vars, and the importance of reading notes and prerequisites for a successful build.
Key Takeaways
- Clone and run the Cinear Marketer repo locally using SSH, then install dependencies with npm and launch the Cloudflare server to test in a real browser at localhost:5174.
- Two Cloudflare agents are used: Hollywood agent (the movie-specific instance) and Reporter agent (gathers trends and actors); they communicate through a shared state and RPC-style calls.
- The app saves generated assets (like posters) to Cloudflare R2 object storage, wiring image hosting directly into the app’s endpoints.
- State in an agent is live across connected clients; changes propagate in real time via WebSocket-backed state synchronization.
- Development best practices include forking versus cloning for open source, using deploy-to-Cloudflare buttons, and storing secrets with dev.vars via Wrangler secret bulk commands.
- Human-in-the-loop design is highlighted as a deliberate choice to keep humans involved in decision points (e.g., regenerating outputs or approving final content).
- The workflow demonstrates how to integrate external tools (e.g., browser rendering via Cloudflare API) and how to securely manage API tokens and environment variables.
Who Is This For?
Frontend and backend developers curious about building persistent, multi-agent AI apps on Cloudflare. Essential for teams exploring AI agents, Open Source workflows, and rapid prototyping of generative content pipelines.
Notable Quotes
"This tutorial is part of a series that accompanies the show AI Ave."
—Craig introduces the series and sets expectations.
"What York has built here is common. AI is all about input and output. You give it some input, some inference happens, and you get output."
—Core AI principle demonstrated in the app.
"There’s a button here for deploy to Cloudflare. This is the way that you want to go if you go do deploy to Cloudflare."
—Showcases deployment convenience in the workflow.
"The state is immediately across all instances, which is very nice."
—Highlights real-time state synchronization across clients.
"This is a human in the loop design. The human still makes decisions at the end."
—Notes on UX and RLHF considerations.
Questions This Video Answers
- How do Cloudflare AI agents synchronize state across multiple clients in real time?
- What is the difference between a Hollywood agent and a Reporter agent in Cloudflare’s AI Ave Cinear setup?
- How can I deploy an AI agent project to Cloudflare using dev.vars and Wrangler secret bulk commands?
- What are best practices for open source collaboration when building Cloudflare-based AI apps?
- How does the Cinear Marketer app generate posters, casts, and reviews from a movie title?
Cloudflare DevelopersAI Agents SDKCinear MarketerHollywood AgentReporter AgentR2 Object StorageWranglerdev.varsBrowser RenderingOpen Source Workflow
Full Transcript
Once again, they have named this year the year of the agent. Hollywood agents, you ask? No, that's a different kind of agent. I'm talking about AI agents. But I guess in this case, I actually am talking about AI Hollywood agents. Hey there, I'm Craig and I'm a developer. This tutorial is part of a series that accompanies the show AI Avenue. If this is your first time here, I highly, highly recommend that you check out the notes attached to this video as well as the introductory video. The course is pretty far along in the series, so I'm going to be relying on some pre-erequisite knowledge from previous tutorials.
So, more specifically for this tutorial, I'm going to ask that you have a GitHub account. I'd love for you to be able to work locally in a codebase, so a code editor of your choosing. I'll be using VS Code. And I'd love for you to have a Cloudflare account as we're going to be checking out the agents SDK. All of these are listed in the notes with links of where to learn more. So, if you're all set, let's get cooking. So, my co-host Yoro is a robot hand. He actually made the app that we're going to check out today.
It's called Cinear Marketer. I think it's loosely based on the old game Sim Cinema, but I can never tell where he gets his inspiration from. But basically, you get to create an entire film based on a simple title. You even get a movie poster. A synopsis is generated, cast is made, and even fake reviews of your fake movie are generated. He then lets you tweak things and regenerate whatever part you want. I got to admit, it's pretty fun. What York has built here is common. AI is all about input and output. You give it some input, some inference happens, and you get output.
You could use that output as future input. It's all pretty magical and it's probably best if I just show it. I can't wait for you to see this. This is so fun. This is York has really built like the ultimate generative uh AI app and I really can't wait for you to see it. So you all you need to do to start the whole process is just come up with a title. So let's do like a a dream. Uh a huge dream. Let's that sounds like a good title, right? A huge dream. I don't even know what that would be.
Let's see what happens. So, uh, immediately it comes in and it starts generating and they're all kind of based on each other. He did this really cool thing where dream big strike loud a description heartwarming uplifting film, A Huge Dream follows a journey of a young aspiring musician who inspired by the likes of K-pop superstars. So, it's using the what's currently popular, A Huge Dream. It's got the gritty level of one to five. Uh, dream big, we strike loud is the name of that. Look at that. It's got this nice little uh huge dream thing here.
It's got the cast. It's gone off and made made a nice cast. Uh, and it's generating it's even generating reviews. Isn't this so cool? Hey, Craig. I thought I was going to do this tutorial. Are you stealing my thunder? Oh, no, no, no, dude. I'm sorry. I'm sorry, York. I'm not stealing your thunder. I just wanted to walk people through how to play with this. So, he made it so that you could like go and you could change, right? So, I could come here. I'm going to change the grittiness level of this. Check this out.
So, so I'm going to unlock the poster, right? So, the poster's unlocked. I'm going to unlock the description and I'm also going to make it a little bit grittier. We're going to keep dream big strike loud. I'm going to make it a little bit dark. Right. So, I'm going to choose this dark thing. York, we might want to change that. So, so here we go. So, we're going to go to three. Let's go to four. Let's go to dark here. All right. So, it's dark and mature with significant intensity. And I have this unlocked. And I have this description unlocked.
We're going to keep the cast the same. And it's going to the cast is going to inform uh what's happening here. Let's see if it changes the dream. A huge dream there. And we could also change this if we wanted to. So it knew it's it's getting the Oh, look at that. He's It's like a fighting movie now. Cutthroat music industry. It's dark and mature tone. So So we've got the ability to do this. And of Oh, you know what we should do? Let's Let's get better reviews now that we did that, too. So we'll do this.
Regenerate the reviews here. Uh because he also does the names on this, which is so fun. This is one of my favorite parts. I'm generating everything here, even those reviewers. So, let's see. We got five out of five. Uh, and it's it's like totally making all of this up. Isn't that wild? Huge room is such a disappointment for me. Phil tries to do too many things at once. It ends up feeling like a jumbled mess. K-pop elements are cheesy and over the top. Oh, so good. Anyway, so so we're using research. We're building this across and you can have this and and kind of follow the pattern that York set out here.
Uh, it's really really fun. And if you go down here at the bottom, you can see that there's this peep the code. So why don't you do that? Go peep this code. And if we do, we can look at the code that exists here. Um, and you'll notice here that there is a button here for deploy to Cloudflare. This is the way that you want to go if you go do deploy to Cloudflare. But I just wanted to say there's a lot of repositories out there of people who have built stuff who did not put the deploy to Cloudflare button there.
So I want to show you how to do that. Outside of that, let's let's let's jump a little bit farther down this. Uh, so up here there's this thing that says code, right? So, so here's the this is my this is the repo that that I jumped into. And there's a thing that says code here. So, I'm going to open up the code. And you're going to see that I want to get this locally. I want to I want to take this locally onto my machine. So, I've got a couple of options here. The GitHub CLI.
If you're just getting started, that's a great way to go. Uh, there's also GitHub desktop or you could download it as a zip if you wanted to. I'm going to show you this way uh using SSH. This is something I have set up on my computer. And um Craig, remember to tell them to check the notes. Yeah, York, I'll tell them to check the notes, buddy. Okay, so you could check the notes however you want to do this. Uh I I use SSH. It's a secure way of doing it because I can always log in.
So I can copy this. I'm going to get this URL, right? I'm going to pop into a terminal. So if I uh just do command space and I do a terminal on my computer, I'm going to open up this new terminal. Let's make this a lot bigger for us here. Now, I happen to in my root directory here, I happen to uh have a directory that I call code. That's where I store stuff. And I'm going to drop it into a folder called scratch. And in here I can do take uh exploration. I'm just going to call it exploration.
Uh that will what take does is it makes a new directory and then it changes into it. So that's what I've done. Uh and I'm just going to clone that. So the way that you do that is you do this get clone and then I'm going to paste what I pulled down. So uh I'm saying I want to make a copy of this locally on my machine. Now the clone will be connected to that repo. So you might want to go if you were going to make changes to it. If you wanted to go make it your own, you'd probably come up here first and you would do a fork.
You could fork it. Now when you copy it from uh using the deploy to Cloudflare button, you make your own copy, but fork will make a fork of this. So you can make changes and if you ever wanted to like maybe maybe York made a bug and you want to fix it for him, maybe you want to help him out here. Uh you could make a commit back to it and we could uh we could update it and then everybody that came to this could do it. So that's kind of what open source is, right?
So, we're it' be an open source way of kind of sharing things, sharing the code as it goes. But what we're going to do first is we're just going to get it here locally and we're not going to make any changes. Uh we're not going to put it in our own personal thing. We're just going to put it here uh uh locally because I just want to explore uh the codebase. So, I'm going to clone that locally. So, what that's going to do is uh I I have my SSH key is protected. I'm going to might put that password in.
And uh so now I have that directory. So, CI AIV send out marketer. Now, what I'm going to do is I'm going to uh just do a quick npm install. Right? So, what that's going to do is it's going to take all the things from the node package manager that's there and it's going to install them here locally. Looks like had had a deprecation uh that was what was there. Don't even know what this is using for QR York. I don't even know what that is for. All right, cool. So, uh let's go ahead and now we will we have that installed and I should be able to make sure that it's running locally.
I can do this npm rundev. And what that will do is it will take the Cloudflare server and it will run it locally, which is super cool. So, it's going to do that. It's going to spin up the server uh and it's going to ask what uh directory I want because I have AI bind bound there. And it's going to say that it's going to my my local host here. So, this is my local host. This is my computer, right? So, I'm going to run this locally on my computer. And if this is a little bit strange to you, that's pretty cool, right?
So you can run a web server locally on your computer and it's here and nobody can hit that, right? I mean like if if you if you sent this to somebody said, "Hey, check this link out, it would hit on their local computer, right?" So that's what this local host is here. And this is the port that it's running on is 5174. You can run multiple uh servers. And actually, if you try to run one of these servers, it would probably spin up another one. I spin up another server. So you just always kind of got going to make sure that you have it working there.
So let's make sure that things are working locally here. So, we're going to say a local win and we'll see what that generates for us. So, it's starting. It's going. It looks like it's a light drama with mild themes. A heartwarming film. Local win. A small town wine grower. A local win. Savor the taste of victory. So, uh that's that's what it came up with. Chris Evans. That's a nice cast. And so, you know, one of the things that I liked about this York, I wanted to tell you this is that it's not actually using that's not really Chris Evans.
Savor the taste of a victory. Savor the taste. Niff or low. So, uh, not it's not perfect, but it's getting the point across. And I I do believe that we could probably pitch with this poster. That's close enough, right? We could probably run that a couple more times until we got one that we really liked. Uh, but that's pretty rad. And, uh, I don't know. The reviews, it's a total disappointment. Thought it was going to be fun and light-hearted. Jack and Sophia felt like an afterthought. And the villain of the story, Victor Vex, was cartoonishly evil.
Well, Victor Vex is played by Javier Bardim. That makes sense, right? Victor X. Anyway, this is super fun. I'm so glad that we got this running locally. All right, before we dive into the code, let's talk a little bit about the agents SDK. The way agents work on the Cloudflare platform is you define how the agent should behave and separate instances of the agent are created and you're able to reference them by name. So in our example, we entered a title and that title became the name of a specific agent. Every movie that we created will have its own agent.
Now in our framework, each agent has its very own database. The database lives within the instance. So it's super fast. Every one of these unique agents also maintains a property called state. If you set that state, it will sync to all the connected clients. I love this because agents are addressable and you can connect to them. Under the covers, it automatically uses a web socket that is abstracted away cleanly for you. here. Let me show you. Okay. So, if we go back and we take a look at my terminal here, you'll see that uh things are running.
Things are running and I have a little some I'm logging some stuff out here. And if I want to jump out of that terminal, uh I can do a control C and that will stop me. Now, uh I want to open this up in my editor, right? Because I want to take a look at this code. So, I'm going to do code and then I'm going to do dot, right? So, I'm going to say this directory here, I want to open that up in Visual Studio Code. Here we go. So um on the left here you'll see some folders and the folder that I want to open up specifically I want to open up this worker and uh this is uh the index file right so this is where we're serving things from and you'll see that there's not much uh there's not much here one of the things that's happening is we're using this agents middleware for hono and I'm saying for all uh routes go ahead and use this agents middleware and what that lets us do is anytime that somebody wants to connect to this because remember these are addressable anything at slash aents/ slash the name uh will access the agent.
So this this puts those on on here. So uh I'll show you here what that feels like. So if we go here under agents and we go under Hollywood here, right? Because it's called the Hollywood agent. It's kind of a nice little joke here. Uh I'm going to scroll down to where it starts here. So this is the Let's make this bigger. Heard your feedback. Uh so so this is what it looks like uh over here. So, uh, we're going to in we're going to say that there's a class called Hollywood agent that extends an agent, right?
So, uh, the way that the way that these agents work is they're going to create a new one of these each time. And there has happens to be a state in here. And this is called Hollywood agent state, which is California. That was a that was a good joke. No. Uh, so the Hollywood agent state is going to be um the state of the the system, right? So, so how we want to store things in and this those things in there like the title and the description, remember we're we're changing those as they go. So, anytime that that state changes, you want to let people who are watching the page know.
So, one of the things that uh we didn't show actually uh and we could and we will is if if I had two open to the same page, right? If I had two that was looking at that movie and I made a change on one of them, it would make a change on the other one. The state is immediately across uh all instances, which is very nice. And it just comes by default with this agent uh SDK. So where should we get started? Let me know if you need a hand, Craig. I will. I'll let you know, buddy.
Uh I think one of the nicest things about this is we're going to we're going to start it out. We're going to start out the state, right? The state of it is going to be set to empty. These are like empty arrays and things. And you'll note here that there's this method that's called there's a there's a decorator here. This with the at sign decorator. It says that this method here called regenerate is callable. So uh what this does is we're going to regenerate based on a movie title. So we're going to pass the movie title into this function called regenerate.
And this is what does all of it actually. So it's going to unlock all this stuff. Nice nice code here. Very legible uh UI. And then we're going to uh generate each element and remove it if it needs to. So if it's not locked, right? Remember we had this locked. If it's not locked, we're going to generate the description. We're going to update the description and then we're going to stop it from saying that it's loading, right? So, so, uh, we're going to load all of them. If they're not there, we're going to say go ahead and load all of them.
And then we're just going to run through, uh, each one of these things and generate the cast and all the reviews and stuff. That's pretty cool. Uh, and then each one of them has their own little um, so so the gritty scale, right? It's going to generate a gritty scale based on the title, I believe. Yeah, on the movie title. So, it says uh, you know, one to five. And it it describes what those are, you know, in pretty nice English, right? Hottest new programming language. And based on the movie title, determine the appropriate gritty scale.
Return only the number and nothing else. So this is not using um this is not using what we've been seeing with structured output. It's just being very specific. And it looks like it works pretty good, right? We saw that happen. The gritty thing came and then it it makes sure uh I guess it makes sure that if it came back and it can't figure out what it is. So if it's not a number is not a number, right? It's going to try to parse the int out of this result here. Uh, and you'll see that we're doing a log here of the result as well.
So, uh, uh, okay. And then the description based on the description. And it's po, you can see that it's pushing in this this popular movie trends. And, uh, we'll take a look at that here a little bit later. But what's happened here is it's using this other agent, right? This agent is called the reporter agent and it's getting popular trends from the reporter agent. So, we have multiple agents here running at once, right? So, we have this agent which uh its name is going to be whatever we name the movie is going to be the name of this agent that we can get access to.
And then there's this reporter agent and it looks like there's only one of them. And I I know that's because that's called default. We'll talk about that here in a bit. And uh it's pushing in it says the title is this and uh the gritty descriptions. And uh oh, cool. It's it's pushing those all into this this thing so that when it goes to generate the description, it comes out uh with with the description that that we saw. Uh and then there's a tagline. You're a you're a marketer. Catchy taglines for movies. Really fun English just kind of thinking about it.
And it's taking it. You can see that it's using it's saying this. Right? So remember that this is the we're looking at a a class right now, right? We're looking at the Hollywood agent class. But when there's an instance, the instance is going to have this uh information on it. Now, what's what's really nice is if anybody ever came back to this site and they went to use it and they pressed a button, it's going to be on. It's going to be as if this thing is alive. The state is going to be here automatically.
It's going to it's going to restore its state. I don't need to hit a database or anything like that. I could and there actually is a database that's available to me here, but I'm just using the state and the state is small enough uh that it's here. And again, when I do the thing, when I do the thing where I set a state. So, so here here's the cast is a little bit more um uh tricky, right? So, we're going to do a scripted name and a suggested actor. That's how it's pulling all that stuff.
And we're using the the uh 70B model here because I I find that the more parameters, this is the number of parameters, the more parameters you you use, the more outside world knowledge it has. So that's that's why I'm using uh this and some of them I'm using llama 4 which is the newer model but it's a 17B model where we have a 70B here. Cool. And uh again the the poster prompt we're showing how to generate a poster and we're going to use uh oh we're using we're doing the poster prompt, right? So here we're using the llama for scout.
We're using the 17B model. Of course you know check the notes you're you might have a newer model here. And when we go to generate the poster, we're just going to take that prompt, right? So, we've generated the poster prompt and we're going to create the poster with that prompt. We are going to go ahead and get the image, right? So, we're going to set set get get a hold of the image that got created here. And with that image response, I'm going to push the body of that into uh this thing called movie posters, which is R2, which is our object storage.
So, we're creating it. I'm calling it a file, and I'm posting in the body there. And then I'm uh sending back this uh images posters file name. And if we look at our index file, if we look at the index file, if somebody ever tries to hit images, posters file name, it will go and get that. It's going to go and grab that that file that we have there. And that's it's going to pull whatever is here. It's going to go hit this is again this is our R2. Check the notes. This is our R2 object storage.
Zero egress fee. So we're going to put uh our image there. And we're going to return it, right? We're going to get it. uh if it if it's not found, we're going to return a 404 not found, right? Otherwise, we're going to return the image and we could cache it. There's a to-do there. We probably could do that. And look at here. AI suggesting that I can implement this with codeex. That's the the open AI uh model uh that was used here. I actually used cloud code while I was building this. Um and I can show you that a little bit too.
So, we'll come and we'll look under uh source here and you'll see that uh this is where the front-end React app is at. And there is this app.tsx. tsx. And if we look at that, there's this router and it says that when we get a movie with the slug, we're going to go to this movie. We're going to get this movie element. That's what we're going to render. And that's here under components. So, components, assets, components. We're going to look at this movie. So, we got source components, movie. And in here is uh pretty neat.
This is this is pretty pretty awesome. I really like how how easy this is to use. Now, if you haven't seen React before, let me explain a little bit about what's going on in here. So, there's a couple of states happening here, and I want you to get your brain around it. So, there's this use state, right? So, we have this use state that comes through. And what's really nice is uh I can get I get back these two I get these structured from use state. I get these two uh uh objects, right? So, I get an object that's called description.
And if any time I call set description, it will tell things that contain this description that it needs to rerender. So this is a state of what just happens inside of normal React. So uh one of the nice things that the agent framework has done is there's a thing called use agent which kind of follows the similar pattern. So uh we're going to make a new agent here. We're going to say use agent. And note that I've got this uh Hollywood agent and Hollywood agent state. And that might feel wild because I'm in the front end but we're talking about things that are defined in the back end.
But what's really nice, if I just import this type, I get this very specific type. These are all exported from that same uh file. So I have a type safe uh connection on my client here, which is really powerful before when you go to build some stuff. And I can't wait to show you what what happens in here. So when state changes right on the server side we saw when it when we change the state when we when we make a change to the state uh all clients that are attached will go ahead and this method will fire this on state update will fire because it will get this new agent state right and again the agent state has the title the description the slug the genre so anytime this agent and we're connecting to it right we're connecting to it by Hollywood agent and the slug that got created so that we slugify the title and That's that's what this is about.
So we get the the slug and uh everyone that's connected to that specific once because it's addressable is going to get that state. So uh the description that we're looking at, right? So that set description. So if the state has a field called description, we're going to call set description and we're going to pass in set uh state.escription. So if we look for description and we look look in here, uh we got a couple things, right? So, so, uh, that that's the title of description. And if it's loading, we're going to do the the filmre spinner or the popcorn spinner there.
And otherwise, we're going to write the description out or we're going to say no description generated yet. So, if React is uh new, you check the notes. I've got a a quick place to get started. Uh, there you don't need to use React. I just think that this is a nice real nice way of showing that. Now, what's super cool, right? What's super cool is we have a form also for that description. So if we keep looking for this description. So let's take a look at how we do this unlock. Right? So when we click when we want to click and we want to unlock it, right?
So we've got this lock icon and this lock icon uh is uh takes this this element here. Let's go take a look at where this lock island lock icon is. So I'm going to press command. I'm going to click it. And we're going to go to where it's defined. Uh and you're going to see that it has unlock input or lock input. And that's going to that's going to change the state on the server, right? Right? It's going to change the state on the server. Let's take a look at what lock input does. So again, command.
I'm going to click into it. We're going to go here. Now that agent from that use agent that we created, it was strongly typed. So it has an agent.stub. And when I call lock, it knows that I can lock any one of those inputs, right? So it knows that this is the method that I can call. And I just call it, right? I call it and it goes. And so like there's that regenerate method, right? the regenerate method is actually on the agent on the Hollywood agent and I'm actually calling it and I'm passing that movie title.
So let's go back. Let's see if we can can go and look at that and see we jumped into the Hollywood agent here and re regenerate as on a callable method. So because it's callable, I'm able to go agent.stub.regenerate. So I'm I'm doing an RPC call a remote procedure call uh to do that. I didn't need to do any API. All that magic is sort of happening and I'm getting the changes back. So this is this really nice uh all things that are connected to this agent are going to get this. I really love this.
Right? So so uh I I can get the tagline or I could update the tagline. Right? So I'm I'm pulling from the form, right? If we're you know we have the form unlocked and we want to do a save tagline and we can see where we call the tagline. So uh the form has an action that says save tagline. So, we're going to edit it. And if we edit it, when we're done editing it, we will do a submit. And it will go and it will do that save tagline. And save tagline just does agent.stub update tagline.
And if we look at this update tagline again, command and you click it callable. It's an update tagline. We're getting the tagline. We're setting the state so that all connected uh objects get the tagline. And then we lock the tagline when we're done. Right? So we we we change the tagline and then we lock it. So let's do that whole step here. I'm going to open up my terminal. So I'm going to go terminal new terminal and I'm going to do npm rundev. Right? We're going to run that locally. So going to go to my local host.
Uh so ready. We're going to go um what should we do this? Let's just say a local host. I wonder what that is about. Wonder what that movie is about. A local host. So uh we're running this locally. Again, open your home. Open your heart. It's a light drama with mild themes. It's a charming town of Willow Creek. A struggling mother named Emma takes a chance on a new job as a local Airbnb host. What a great There she is. Open your heart. And the Cinda, it's not really her. Good job, York. You didn't You didn't steal her face.
John John Cros La is playing here, too. Awesome. Sweet. So, um uh again, the tagline. So, I'm going to unlock this and watch this. Let's let's uh let's I'm gonna So, this has a movie has this here. I'm going to take this. I'm gonna open up another tab. I'm going to open up our local host. So, we have both local hosts, right? So, both of these are connected to that same agent, right? So, they're they're the the React is connected to the same agent. Watch this. Watch when I click this unlock. See how over here it we can lock Oops.
We can we can lock and unlock it, right? And watch this. Open your home. Open your heart. uh open your file system and I'm going to do save. Okay. And you see open your file system. So I am changing this locally. It is going to the server and it's syncing because this has the use state. So anything that happens on the server, the U state comes down. Super powerful. Uh all sorts of applications that you can do here and you didn't have to do any of that wiring for you. It's really nice. Another thing that Clever York did was to set up a research agent.
This can go and hit the internet and gather popular trends and actors and use them to cast and improve the generated movies. It's pretty clever. This will make the whole system continuously get better and look more like what's happening in current pop culture. Let's check out how he did that. So, let's take a look at how York did that research agent. Uh if we come here under uh back under the worker under agents we have Hollywood and we also have reporter uh and they this agent looks similar to what we saw in the beginning right so there's a reporter agent here and it's got a state of trends and actors and it looks like the trend schema is just the synopsis of the film and the actor schema is just the actor's name.
I think I think we have two just very straightforward things here that we're going to go we're going to extract the trends and we're going to extract the actors and we're going to set the state. So anytime somebody calls gather trends uh we're going to do callable and it's going to go it's going to retrieve these popular movies. And one of the things that it's doing that I think is interesting here in your I think this is you you must have been wanting to show off uh some some more features here. Uh we offer an API.
So Cloudflare has this API. If we do this uh uh browser rendering markdown. So you do a you do a post to it, right? So you do this post to that URL and you have a API token. We got to remember to get those later. Uh and we have this we the body uh is uh you pass in the URL that you're looking for. And the URL that I thought that we should go look at is this Rotten Tomatoes page. Right? So we're going to go to this Rotten Tomatoes page. And instead of trying to parse the HTML, I'm just going to grab this as markdown, which is a very popular uh uh way of writing things, but it's very easy for uh the LLM to use that and to to write it out.
So, so it's got all these all this information here. This is currently what's happening um uh here. So if I if I go back to uh the code and we're going to hit that page and we're going to do it and we're going to grab uh the markdown from it. So instead of using a binding there is a browser rendering binding. What's happening here is we're using this uh this API. Okay. So we're going to we need to have these two things. We need to have this uh Cloudflare account uh ID. It's and inside the M environment there and it's also inside the environment here.
Now the way that you do that is through this uh this devars uh example. What we would do if you look at the readme and actually the readme is uh markdown. So readme.md where is that here? Uh you'll see that it says copy.dev.vars.example to dev.vars. So I'm going to do that. I'm going to copy this. Copy paste. And we're going to call this dev.vars. And uh one of the nice things about this is you it's you can't check this in. It's in there. get ignore it will I mean you could you could force it to happen but it's been ignored your git ignore wanted to do that so that's why this one is example and this one is devource this is something you never want to push up your API key so you're going to be using a bunch of different APIs as it goes in or uh um or tokens or things like that so let let me show you how to how to get one of those really quick so if we go to um we go to our dashboard and we come in here we just go to go to I'm going to type API I tokens.
And so this one here, API tokens. There we go. Uh I'm going to create a new token. And I am going to create a custom token. And I'm just going to call this research agent demo. And I'm going to delete this later. So if you see it, don't you don't need to worry about that. Uh and the permissions that we want to do is uh on the account we want to do browser rendering. So, browser rendering uh you can choose uh your your account specifically. Um and then uh you can choose oh so browser rendering read we want and I want uh browser rendering edit I believe browser rendering uh edit and I'll put these instructions in the notes as well.
So, I've got browser rendering read and edit on uh my account here. Uh, and I could say how long I want it to go, but I'm just going to go ahead and do continue to summary. And I'm that looks good to me. I want read and edit. And I'm going do create this. Uh, this is You shouldn't This is what it looks like to do that. So, you can verify this is working. This is actually my API token. I don't want anybody to see this. And I mean you. So, I'm going to delete this when I'm done with this making this script.
But, I'm going to pull this over here. I'm going to copy that and I'm going to paste my API token here and uh get my ID for that. So, I'm going to just click this uh Cloudflare here. I'm going to click this Craig Dennis and I know that up here this is my account ID. This is the account ID that I want because I clicked into the Craig Sennis. So, this is my account ID. I'm going to grab that. I'm going to put that inside of my account ID here. Uh, now if you had both of these in my dev.vars, uh, you'd be able to do awesome stuff.
You'd be able to to to do do my browser rendering. I'm not going to let you do that. So here, so here we go. Uh, I'm going to do mpm rundev now that that's there. And we should see that it's going to say that it loaded it, right? So it's should say using varss define and dev.var. So it's these two, these Cloudflare account ID. And if we look at, let's go back to that researcher agent or reporter agents it's called here. So it's going to retrieve the popular movies. It's going to go it's going to hit that.
It's going to get them back. It's going to get the JSON and it's going to store that uh result here. So what comes back is a JSON uh that has a result that is the thing on markdown. And then we're going to go and we're going to extract the trends from that markdown. Uh let's see what does it say. Uh, so it's going to take this summary. Oh, I think we passed that in, right? So, if we look at what the research is get popular trends, uh, get popular actors. Let's look at here. So, gather trends here.
We're going to retrieve the popular movies. We have the summary. We're going to make sure that we have it. We're going to extract the trends. We're going to extract the actors. Let's make sure it's working. So, so I've got uh I've got the server running. I'm going to uh open that up. And I'm going to go to slash research. You probably want to to protect this, right? So, currently there's nothing there. So, I'm going to click this uh gather trends. And so, it's super cool, Craig. Don't forget to generate your API token. Were you not paying attention?
I already generated the API token, dude. I put it in the thing. Yeah, we got it. We got it. Everybody's got their API token. We're good. Right. You guys have that and you moved it into thedev.vars, right? So, what we're going to do is we're going to take this here and we're going to deploy it. Oh, cool. They came back. So, so, uh, the way that the trends works, uh, your had them just grab, uh, popular trends. So, they've got some nice, nice things to kind of work within and then it listed all the actors that are, uh, currently popular that are out there.
Try to pull them all from that from that, uh, list. Judy Greer, she's so funny. Cool. And so, remember when it was building when we were building the movies, it was actually using that reporter agent is what we called it. Reporter agent, right? So reporter agent get agent by name. So this is from the agents library. So uh get agent by name, right? So uh we're going to get the reporter agent because that's in the bindings, right? So I'll show you how that works here too. And we're going to get the default because there's only one of them.
There's only one of them. So that whenever I talk to that, that's always going to be there. So all of these other agents can talk to this one agent, right? uh and that agent I can make that agent the the agent has a method called um if we're inside of one of these these methods here right so if I'm inside of a like let's just say I was here I could say this dot schedule and I can go and I can schedule a task so I could on a loop every day I could make sure that we update the trends right or every week whenever we want to have those trends update so in the in the reporter we could do that we could go through and schedule when we wanted that to go And then every time I went to access the reporter, I would have the most current trends and I wouldn't need to even think about it.
I could just go and pull it, right? So, so again, so it's it's pulling the state. So, let's do that reporter reporter agent, right? So, I got a hold of it and it said get popular trends and it's just pulling that out. That's all it's doing. Uh, and super nice. So, that's a that's a really neat way to to let uh agents interact with each other is to go across borders like that. And then finally, one thing I wanted to just point out is that I am uh importing the agents, right? And I'm exporting them.
I'm exporting them from my main uh method here. And when I come into my wrangler here, now this might look different. So uh I have a binding for the Hollywood agent. And I've named it Hollywood agent. And when I talk to an agent, check the notes for this. It will be Hollywood- agent, right? For the name of it, reporter- agent. It does the kebab case. So it goes lowercase and then it put it's put dashes between the words but uh so we have the reporter agent and uh the Hollywood agents are the two agents that we have here and we have them set up this way.
These are the buckets that have been built. So you have to have these uh names of these buckets if you want them. And of course there's this routes. Uh you probably don't want to have this. I'm going to comment this out for right now so that we can make this go. Uh so I'm going to go now. I know that it's working and I want to go and do a deploy. Before I deploy it, I want to go and I want to just make sure that I look at the name here. So this this name of this when I go to deploy it will be called Sim Hollywood agent.
Uh let's call this uh my own private Hollywood. Okay. So we're going to do that and I am going to I've I've commented out this routes because this is where mine's hosted. the cinema marketer. I've commented that out. Um, I'm going to do a deploy just because I want to show you something. So, we were usingdev.vars and that doesn't push up our secrets. Um, so in the readme in the future, it's going to say uh secret uh npx wrangler. So, npx telling it to run wrangler do the secret bulk of dev.var. So it'll take the dev.vars file that we put and it will push it up to the server.
Right? So now now there's secrets. So it says it. All right. So if I do a clear and I'm going to do an mpm run deploy. Now that I have the secrets up there, it's going to push them up and I will be able to access them. And that command, this npx wrangler secret bulk devars is in the readme because I'm going to put it in there right now because I think I forgot to put it in there. So there are all the instructions are in here for this tutorial. And if you come under here under deploy, you want to make sure first that you uh do that.
You want to upload your devs because if you don't, just like reminded us, it would say make sure you put your API token in there because otherwise it would be null and your your research agent wouldn't work. So there, there we go. Awesome. This allows us to talk about a few things. The way that you can regenerate or save a certain part of the response helps keep the human involved, right? The human still making decisions. We could very easily not allow that and just let the agent act on its own autonomously. But because we have that interaction, this is called human in the loop.
The user is making decisions on the final product. You'll see this a lot in agents where you don't want it to fully act autonomously. Like for instance, we don't want this sending an email to the Hollywood studios just yet. We want to keep the human in the loop. We'd probably add a submit button to the agent that could very easily kick off a function through RBC and submit it. The kid stays in the picture. Another term, RLHF, reinforcement learning through human feedback. Currently, we're generating those reviews, but we could in fact allow people to rate that generation.
You know, you see that in the UI a lot, like the thumbs up or the thumbs down, and we could store that feedback and then sort to find the top voted agents. And there's a lot of information that we could deduce from the more popular ones. We could use that information to inform and improve how we generate movies in the future. RLHF. The agents SDK is perfect for this because you have these long living agents that you can access forever. There's a ton more information in the notes. And I hope that you're ready to start exploring and building your own agents.
This year, they say, is the year of the agent. It's your year. Seize the opportunity to build one. Thanks for hanging out and we'll see you real soon. [Music]
More from Cloudflare Developers
Get daily recaps from
Cloudflare Developers
AI-powered summaries delivered to your inbox. Save hours every week while staying fully informed.





