In this lesson, you'll use Amazon Bedrock to create a simple cloud-based agent. You'll also explore how you can invoke the agent and see its trace so that you can review it's agenetic workflow. Let's jump in. So the first thing that we need to do and the first thing that we're going to do in every lesson of this course, is to import, the import the boto3 library, which is the SDK for AWS running in Python. So shift enter on that to run that. And now we need to create ourselves a client object. That's how Boto3 works is that we create client objects to connect to the various AWS services that we can connect to. So let's give it a service name. And we're going to say that this is the bedrock and this is the bedrock agent. So in the previous short course we connected to bedrock. And to bedrock runtime. Now we're connecting to Bedrock Agent in order to configure the Bedrock agent service. We're going to give it a region that we're working in. And so we're going to tell it that we're working in US West 2, which is the Oregon region. And let's load that into a reference so that we can get hold of it and shift enter. And we've got ourselves a client. So we're going to use this client to connect to AWS and configure our agent inside of AWS. So just to reiterate the code that we're writing here is configuring an agent running in the cloud that can run at production scale. It's not going to run inside of our notebook. So let's go ahead and do just that. Let's go ahead and create the agent. And this is actually pretty simple. So let's use the Bedrock Agent client. And we're going to call create agent. Now obviously we have to pass in some variables some parameters. So let's do that. So agent name is the first one to pass in. So what do we want to call this agent? And this is not something that the agent itself will know. This is just something for us. I'm going to call this agent the Mugs customer support agent because I have a mug business. I don't know if I told you that. And I want an agent, which is kind of help me with the customer support for my mug business. Okay, now let's go on with the other parameters. So we need to give it a foundation model. So this is going to point to a particular large language model that's part of Amazon Bedrock that it's going to use for the language understanding of how this agent works. So I'm just going to paste this ID in here. There are a few different that we could use. And you can find these inside of the AWS documentation. But I'm going to use the Anthropic Claude 3 haiku model, which is a small, fast and very capable model. Okay. Next, I need to pass it in some instructions. So these instructions you can think of as the system prompt. How is this agent going to behave. So I had to actually have some of these already here. So let me just go and copy and paste these in. Now this is very short. Honestly, we would want something much more verbose and much more descriptive to help the agent to understand what it's going to do, but for now, this will be fine. So you're an advanced AI agent acting as a frontline customer support agent. Okay, so it's an agent to help me with my customer support in my mug business. So let's carry on. And let's add in the last thing that we need in the configuration for our agent. And that is a resource role. Now once been created for us inside of this environment for this lesson. And it has a role Arn which we pulled in from an environment variable. So this role is a definition of the security configuration for this agent. So it tells the agent or it defines for the agent what services it can connect into. And pretty much it just gives it access to this particular language model and nothing else. So we're operating on the principle of least privilege. So we only have access to what we need to get access to. All right. Well, that's going to create our agent. That's it. That's all we have to do. Now you may have noticed that we've not given it any tools. So in Amazon bedrock agents we call these actions and they're parts of action groups. We're going to look at that in the next lesson. But for now we're just going to create this basic empty agent. And then we're going to see how we can actually invoke it and communicate with it. So let's load this into a variable so that we can actually get access to it. And so once we've created it we can call it and use it with that. All right let's press shift enter on that. And that's it. We've done it. Well not quite. So there is a lifecycle for the agents inside of Amazon bedrock agents. And so at the moment, this will be set there in the creating state I think. Let's have a look. So let's open this up. Let's print this to the screen. And what you can see here is a couple of useful things. So we have an agent ID, which is something that we'll use later. And we have this agent status and it's currently creating. Now, what's going to be the next state? Well it's going to be the state of not prepared. So if we look at a high-level at the lifecycle of the agent, it goes from creating to not prepared, and then we can prepare it which will send it to, as you might imagine, prepared. Then once it's in the prepared state, we then can create an alias for it. And this alias is essentially the production endpoint that we can use. And it means that we can implement some version control, and we can have some stability on our production endpoint versus sending a new version through the pipeline and making some adjustments to the agent at a later state. Now, it's important for us that we don't carry on until we get to the not-prepared state. So we need to look for that. So I'm going to go ahead and store the agent ID in a variable here. I'm so I'm just going to grab the response that we created before grab out of that the agent ID which is the agent and then the agent ID. So we'll get this variable here. So this is useful for us. So that's stored. And I've got a bunch of helper functions for this notebook which are going to help us in this lesson and in the subsequent lessons for waiting for things like this to enter the prepared state. So let me just import the helper functions. And in the next lessons I'll just do this right up the top. And then I'm going to paste in here the wait for agent status. This is a helper function. We're going to pass it in the agent ID, and we're waiting for this to be not prepared. Now, I've explained this and taken all this time telling you all about it, but if you are running this code through without following the video and waiting all this time, then you might find that this is necessary just to pause the code execution essentially. So let's run this, and I'll just scroll up and you notice that it's already in this not prepared state. Okay. That's actually a good thing. That's what we want it to be. So it's gone from creating to not prepared. So the next thing we need to do is we need to prepare the agent. And this is as simple as you maybe imagine. So we're going to say bedrock agent which again is our client that we created. And we're going to call prepare agent. Okay. And obviously we need to pass in something so it knows which agent. And obviously that's going to be the agent ID. Agent ID which we've stored in a variable before. So that's all we need to do. So if I press shift enter on that, you can see that it's now in the preparing state. So we have a draft version and a preparing state. And guess what? I have a helper function for us again to now wait for it to be prepared. So let me shift enter on that. Did I get there in time? No, it's already prepared. Okay. But you did see it was preparing and now it's prepared again. If we ran this code from top to bottom, know, doing that thing where you just run all cells, then this would just prevent you from moving on to the next step before it's ready. So, as I said before, the next thing to do is to create an alias. Because we actually want to invoke this agent. We want to have a conversation with it, even though that will be a very simple conversation, because it's got no actions yet. And we can create the alias now because our agent is prepared, we can now create our alias. So let's do that. I'm going to use my bedrock agent again, and we're going to create Agent Alias. And again we need to pass in some parameters. So we need to pass in the agent and agent ID so that we can define which one we're talking about. Of course. And then we also need to pass in a name for the alias. So I'm going to put in here agent alias name. And well, you can put in any agent alias name you want. I have no imagination. So I'm going to put in my agent alias. That'll do. All right, so with that, let's just, give that a variable to stick the response into so that we can work with it. And we've got everything we need. So bedrock agent create agent alias passing in the ID and a name. And this time, before we run this, let's just add in a little bit of extra code. So this is where the agent alias ID is going to come from. So we're going to get this from our response here. We're going to get the agent alias, agent alias ID. And we can store a store that in a variable. And yeah I've got a helper function here for wait for agent alias status. So it is going to enter into the prepared state. I'm doing it all as one cell this time. Just so that you can actually see this running and you'll see it, with the different statuses. Okay. Now let's run this. So we'll wait. So it's gone into the creating state and creating state. You see it does work. And then it goes into the prepared state, which is what we were waiting for. So now we have an alias that has been prepared. And with a prepared alias we can actually start using the agent. So let's do that. And we need a new client to do this. So let's go ahead and call Boto3. Going to create a new client. And this one actually will service name. And this one is going to be the bedrock agent runtime. So similar kind of setup to before in the previous course when we did Bedrock and Bedrock Runtime. Now we have Bedrock Agent and Bedrock Agent Runtime. So obviously this is what we're going to use to actually interact with a running agent. So we need a region name as well. And we're going to use US West 2 again okay. My all set up there. Yep. That's all good. I do want to store that in a variable again so that we can make use out of it. So let me go ahead and just do that. So we have bedrock agent runtime is going to be this client here. So let's run that. And now we're ready to go. And in a syntax that should be coming familiar to you, we're going to call Bedrock Agent Runtime. And we're going to call Invoke Agent, which is pretty much all we need to do. But obviously we need to pass in some parameters. So let's set these up. The first thing is we do need to tell it which agent. So I'm going to put in agent ID agent ID here. So this is a variable we've defined previously of course. And so that it defines which agent we're going to call. But we also want to do the same thing for the alias ID and you note that before we did actually store that in a variable called agent alias ID, so we could go ahead and use that, then we need to give it a message. Or we need to send some sort of request into our agent. We need to prompt it essentially. And we do that through Input text. And we need to pass it in a string of some sort. So I just want to break this out. I'm just going to put this above our definition here. So let me just put that up here. So this is my support message that's come in to my support agent. So hello, I bought a mug from your store yesterday and it broke. I want to return it. Okay, so a simple, simple thing, that actually, this agent's going to struggle with. Right? Because it's not got access to any actions to actually do anything. There's no agentic workflow, but it should respond. So let's go and load that into there. So that's our message. Some more things that we need. So we do need to set up a session for this. So the session will be maintained and the conversation history will be stored inside of the agent inside of the service. So we don't have to have to store the conversation history ourselves. We can use the conversation history will be stored inside of the agent itself in the cloud. So we need to provide it with a sessionId So let's go ahead and do that. And for this, I'm going to use, a uuid. Let me just insert a cell above. We're going to import uuid. And then I can insert this up here as well there okay. So I have a session ID uuid to something unique that we can use. So let me put that in there. And then a couple of extra settings here. I'm just going to paste these in. We can look at these in more detail later. End session false. So I want to continue having a conversation. But that is how I could end the session if I wanted to and enable trace. We're going to have that false for now as well. I'll show you what that looks like in a moment. Okay. So let's go ahead and run this. But before I do that, I just want to store the response in something. There we go. So invoke agent response is going to hold the response back from that. And that's all we need to do. So let's press shift enter on wow I need to do this one first because I haven't actually done that one yet. So import uuid and then this one. And I should now have some kind of response. Now if I go in and print this out or just allow us to have a look at this, we see this, response comes back. It's actually an event stream. So we can't just print this out. We actually need to go and inspect the event stream and basically pull items off this stream. So let's go and do that. And I'm just going to go and grab this completion out of the response. So I'm just going to get my event stream here. And it's just going to grab that particular completion just makes it a bit easier for me. So shift enter. And then what we can say is for every event, inside of this event stream, we essentially want to be able to print the output. So let's just do a very simple, print event and see what happens. So if we run this, then we actually only have one main event that's come back from this stream. And you can see it's called a chunk. Inside of that it's got some bytes and then it's got a response that's come back from the agent. Let's see what it said. It said "apologies. It seems I'm having trouble. Invoking the necessary functions to assist you." Okay. So the agent knows that it should have access to some functions, but at the moment, this is a super, super, super simple agent which has nothing. It can't do anything. And so this is an entirely reasonable response. But the question is how did it figure that out? How did it figure out that it's not got actions that it can do and figure out what the response was going to be? And we can see a little bit more of that if we enable trace. So let me set that to true. And then I'm going to rerun this cell. And that's going to restate the message. It's going to set up a new session ID. So we're not carrying on. And essentially we're going to have another conversation. So let me rerun that cell. So now with enable trace including true. I'll go back and get my event stream again and let's print everything out. Now this is going to be a lot. But don't worry, I've got a helper function that can help us pass through a lot of this stuff. So inside of here. Well, let's just pick apart a little bit of it. You can see some stuff in here which will look familiar. here, look, the system prompt that we were talking about before, you're an advanced AI agent acting as a frontline customer support agent. We put that in. That was something that we added in. But all the rest of it, actually we didn't. And this is actually part of a template which is inside of a service which explains what an agent is and how it should behave, the fact that it might get some parameters coming in, that it might have some functions that it can use, and really it needs functions in order to be practically useful. It doesn't have any of those at the moment, which is why we're not getting a great response. But you can see all of these things in here. So that template is there. It is actually something that we can change to if we wanted to do so. But what we can do as well as we can add some tools to this so that it can be a more useful agent. And obviously, there's all of this trace information here which isn't beautifully printed out. Again, we'll have a look at a helper function in just a moment, but it goes all the way through all of the different, iterative steps, if you like to actually getting a response. All right. Let's quickly look at the helper function that I've got that will help us pass through some of this. And then we'll get to the next lesson where we can actually add some actions. So let me just restate the message and a new session ID so that we can again basically start again. And this time I'm going to call invoke agent and print, which is a helper function I've got you pass in very similar parameters here. So we've got the agent ID, the alias, the session ID the message and enable trace is set to true. So let me just run this cell because I haven't done that yet. And then let me go ahead and run this. And you can see a streaming response come back which is slightly nicer to look at. So we have the initial question from the user as in my support request. So I want to return my mug. And the agent says it's thought processes. So we can see that that was all in that, output that we saw before. I was just a little bit difficult to see. So it says, okay, let's see how I can assist you with returning your purchase. I need to gather some more information. And basically, yeah, the thought process it goes through, which it's going to realize that it can't really do an awful lot. So. "I apologize. I'm unable to directly access your order details..." blah blah, blah, blah, blah. Okay, so that's sort of shown us a little bit more of the reasoning and the thought process that the agent's gone through. It doesn't have any actions that it can do. I feel a bit sorry for it. So let's go to the next lesson and we'll add some actions into our agent.