And week three.
Day four is a go.
Let's get started.
So last time we did a stock picker and we just have a little tiny bit more to put into that.
And then we're going to move on with our next project.
A developer agent.
But first another repetition.
I hate to repeat these things, but sometimes it's good to drum it in.
Building a crew project involves five things.
First of all, crew I create crew.
The name of the project to set up your crew, build those directories and those files.
Number two, you find the YAML files for your agents and tasks, and you fill them in to define your
agents and tasks.
Number three, you go to the crew.py module, which is where you actually create the instances.
And you use decorators to identify the agents and tasks that you'll be using.
And then you create your crew itself.
And this is where you can have structured outputs to make sure that the outputs conform to a schema.
And you can use tools, both tools like Serpa, that crew provides for us that run remotely, and then
custom tools that we build locally, like the thing that sends a push notification.
And then number four, you update Main.py to set any inputs so that we can pass something in, configure
the fields that are templated with the curlies.
And finally we run with crew.
I run and off goes our project.
So I now want to cover a feature of crew called memory.
And this is a feature that is a bit more prescriptive, a bit more opinionated in the crew framework.
Memory, of course, is talking about how you provide information, contextual information to Llms each
time you call them, and you can implement that yourself just by storing variables and then passing
them in when you do things like creating tasks so you can do it the sort of manual way.
But the crew framework also comes with some building blocks that lets you use their constructs around
memory out of the box, and that comes with pros and cons.
The pro is that you get up and running quickly, and you can use a lot of the thinking that they put
behind this.
The con is that there's there's a learning curve, and it obscures some of the detail of how prompts
actually work behind the scenes.
So as as with many times when you're adopting a framework like this, it's something to be aware of
the benefits and the trade offs of doing so.
But let's say that we are going to embrace cruise way of handling memory and talk about what it actually
does.
Well, it has five different types of memory, five different frameworks that you can include.
And one of them is called short term memory.
And this is just about storing recent interactions using a vector database in in a in a rag way.
If you're familiar with retrieval augmented generation.
And you don't need to be for this course because we're just going to put the code in there and see it
run.
But if you do no, then this will make more sense.
So this will allow agents to access recent relevant information when they are currently executing.
And then a different concept called long term memory is when more important information is stored in
a SQL database for longer term recall to build up knowledge over over a longer period of time.
And then there's something called entity memory that's very similar to short term memory, actually.
It's it's basically when there's things about people, places and concepts, then those can also be
stored in a Rag database for vector based similarity search and to be included in the context.
And then there's crew describes this as another kind of memory.
But I think it's a bit misleading.
I think what they call contextual memory is just a sort of umbrella term for the short term, long term
and entity memory that can all together be queried and passed in as context when prompting an LM and
crew abstracts all this away from you.
So it's just going to be a few lines of code to have all of these types of memories running.
But in doing so, as I say, big benefit.
A lot of work happens behind the scenes.
And perhaps also there the trade off is that you've got less visibility into it.
So if things don't go the way you want, then it's a bit harder to debug and figure out what's going
on.
And then there is another kind of memory called user memory, which is to store user specific information.
And actually, at least as of now in Crewe, this is a concept that they support and have some frameworks
around, but it's mostly left up to you to be querying user memory and then inserting it into the prompt
or providing it at the right time.
So user memory is a bit of an odd one out here, and I suspect that they're looking to build more into
that in time.
And for now, for the code that we're about to look at, we're just going to really look at contextual
memory.
So short term long term and entity memory and seeing how we can incorporate that into our stock picker
solution.
And so we're back in the stock picker project in cursor.
And we are looking at the crew.py module.
And I'm going to start by putting in some new imports in here, which are interesting ones from crime
memory.
We're going to import long term memory short term memory and entity memory.
The three types we'll be working with.
And I do believe you can also have user memory in there too.
But then you have to manually manage it yourself.
And then from my memory storage rag storage, we're importing a class called Rag storage for vector
based retrieval.
And with that we're also going to import from long term memory SQLite storage, long term memory SQLite
storage object like that a class.
All right.
So that's a few things that we're now going to put to good use.
We're now going to go to the crew function the function that creates the crew within this this module.
And you can see where we made our manager.
And we've got a few more things to make.
As as cursor is trying to prompt us, they're trying to ignore cursors, insisting let's do it ourselves.
All right.
So we are going to to want to be creating a short term memory a long term memory and an entity memory.
And we're going to do them one by one.
So let's start by saying that the short term memory, which is the one that we'll begin with, short
term memory, trying not to press a tab or it's going to fill it all in for me.
But I'm going to I'm going to do it right here.
Short term memory is going to be something which has rag storage.
We we come up with a provider which is OpenAI, and a model, an embedding model to generate vectors
from text.
And we'll be using this one.
And you can substitute in whatever models you would like here.
It's going to be short term.
And we give it a path to where we'd like it to create that memory, that vector store as memory.
And it will use chroma as it happens, something which people who've taken my, uh, alarm engineering
course know very well.
I love chroma.
All right, so that's the short term memory.
Let's also create some long term memory.
So here it is.
The long term memory is going to be just simply creating an instance of this of this class long term
memory SQLite storage.
And we'll give that also a place to go.
We'll make a database file also in the same directory.
So that's the long term memory object.
And now finally, thirdly, we're going to create a, uh, entity memory object.
So entity memory.
And there it is.
So oh I see.
Hang on.
We've got two of them.
Let's do that.
Looks like that's good.
So entity memory is going to be an entity memory object.
It's also going to be a rag storage object.
We give the provider and the embeddings model and we put it in the memory folder.
So here we have our three types our short term memory our long term memory and our entity memory.
And now we get to the place where we create our crew.
And now it's going to be very challenging.
It's not going to be challenging at all.
We're going to say memory equals true.
And we are going to then just do exactly that.
So crew was a little bit off base with the memory equals part.
But it's got the rest of it right.
That's all you need to do.
You set the long term memory the short term memory and the entity memory.
And we are almost done with memory.
Just just as simple as that.
And I said almost because there is just one or rather two very small extra changes we need to make.
We need to go back up in the module to where we created these agents the trading company, the financial
researcher and the stock picker.
And we need to give them memory.
Now what we want is for the trading company finder to have memory.
And we just do it by saying memory equals true.
We don't actually want the researcher to have memory because we want it to go and do research every
time.
But we do want the stock picker to have memory, because we don't want it to recommend the same thing
more than once.
And I don't know if you remember, but in the prompts, in the YAML files, I said a couple of times,
uh, don't, don't recommend the same stock twice and things like that.
And, and surface new companies for the for the trading company finder.
And that would normally be the final change you need to make is go back and make sure that your instructions
and your YAML files are very clearly making sure that it will take advantage of memory.
Because remember, whilst memory, these abstractions are trying to make memory seem quite magical and
taken care of for you.
At the end of the day, memory just means more stuff shoved into the prompt, more relevant context
put into the prompt so that when you call an LLM it has knowledge.
It's in the input is included information about prior conversations or about prior information that
it retrieved.
So with that we have set up set up the memory.
And we are now going to bring up our terminal and then run this.
And so as usual I go into already in the stock picker.
So all I have to do is type a query I run and we'll be good to go.
Let's see what happens.
So just right off the bat, we expect it to be able to take advantage of memory without needing anything
more.
What we should see is it should create a memory directory in here.
And it just has there is a memory directory.
Stuff is going on.
My computer is hard at work and I can see already within memory there is a Croma database that's being
created.
There is a long term memory.
If I expand this, there is indeed a database that's been a SQLite database that's been created there.
And so things are happening and we can see that, that, uh, various companies are being surfaced by
the market watcher and more is going on and we will, uh, let this thing run.
My computer's hard at work, and I will see you when we have a conclusion.
And that definitely took a bit longer.
It was going around around the houses a little bit, but it completed it.
Recommended Microsoft this time.
Remember, don't use this for real decisions.
But it was, uh, entertaining to see it at work and bouncing around between the different agents.
And whilst we don't have as much visibility into what's happening in terms of its use of memory and
what context got provided, we can see that it's certainly built and populated different data stores
and both the short term memory, the long term memory and the entity memory in the Rag chroma data store
that's been created there.
And the main point I want to get across is that, of course you can see the benefits of what this brings
us.
It was so easy to set up quite a complex situation, multiple types of memory with both vector similarity
queries and SQL queries too.
And we didn't need to know anything about it.
We simply created the objects.
The short term long term entity memory objects passed them in.
And then we told our agents we turned memory on by saying memory equals true for the agents that we
wanted to remember things.
And that is a wrap on the stock picker project.
We saw a lot of different aspects of Q AI with this project.
We reminder, we saw structured outputs.
We saw our own homegrown tool as well as Serpa.
We also used the not the sequential but the hierarchical process.
And now we have added in the memory feature all, all the three main types of memory in there as well.
And that is a nice tour of a lot of the functionality in crew.