back to index

LangGraph Deep Dive: Build Better Agents


Chapters

0:0 LangGraph Agents
2:4 LangGraph Agent Overview
4:46 Short History of Agents and ReAct
7:58 Agents as Graphs
10:18 LangGraph
12:41 Research Agent Components
14:30 Building the RAG Pipeline
17:28 LangGraph Graph State
18:56 Custom Agent Tools
19:10 ArXiv Paper Fetch Tool
21:22 Web Search Tool
22:42 RAG Tools
23:57 Final Answer Tool
25:10 Agent Decision Making
30:16 LangGraph Router and Nodes
33:0 Building the LangGraph Graph
36:52 Building the Research Agent Report
39:39 Testing the Research Agent
43:42 Final Notes on Agentic Graphs

Whisper Transcript | Transcript Only Page

00:00:00.000 | Today we're going to be taking a look at how we can use line graph to build more advanced agents.
00:00:07.760 | Specifically we're going to be focusing on the line graph that is compatible with the v2 of
00:00:13.040 | line chain. So it's all the most recent methods and ways of doing things in the library and we're
00:00:19.520 | going to be building a research agent which gives us a bit more complexity in the agent graph that
00:00:27.760 | we're going to be building. Now when I say research agent what I am referring to is essentially these
00:00:34.320 | multi-step AI agents similar to you know like a conversational react agent but rather than
00:00:42.320 | aiming to provide fast sort of back and forth conversation they aim to provide more in-depth
00:00:50.400 | detailed responses to a user. So in most cases what we would find is that people don't mind
00:00:59.760 | a research agent taking a little bit longer to respond if that means that it is going to
00:01:06.320 | reference multiple sources and provide all of this well researched information back to us. So
00:01:13.440 | we can afford to wait a few extra seconds and because we have less time pressure with these
00:01:20.240 | research agents that also means that we can design them to work through multiple research steps where
00:01:27.040 | it's referencing these different sources and it can also go through those different sources
00:01:32.160 | multiple times you know we can do a google search you can reference archive papers and it can keep
00:01:37.360 | doing that and so on and so on. Now at the same time we might also want to make our research agent
00:01:43.360 | conversational so we would still in many cases want to allow a user to chat with the research
00:01:53.680 | agent. So as part of the graph that we're going to build for the research agent we also want you
00:02:02.160 | know just something simple where it can respond. Okay so let's start by taking a quick look at the
00:02:08.240 | graph that we're going to be building. So we have the obviously the start of the graph over here
00:02:15.600 | which is where we start and this goes down into what we call the oracle down here. Now the oracle
00:02:24.800 | is like our decision maker it's an llm with a prompt and with access to each of these different
00:02:32.640 | nodes that you can see. So the right search filter, right search, fetch archive, web search,
00:02:38.560 | and final answer. So the oracle can decide okay given the user's query which comes in from up here
00:02:48.160 | what should I do? Okay so for example if I say something like hello how are you? Hopefully
00:02:56.160 | what it will do is it will go over to the final answer over here and then we're going to just
00:03:02.720 | provide an answer and end the execution of the graph. But if I ask something that requires
00:03:10.320 | a little more detail for example I ask about a particular llm what we might want to do first is
00:03:18.080 | okay we do a web search find out about the llm that will return information to the oracle and
00:03:23.920 | the oracle will decide okay do I have enough information here or is there anything in these
00:03:31.040 | results are particularly interesting like for example is there an archive paper mentioned in
00:03:36.720 | these google results. If so it's you know it might just decide to give us an answer straight away or
00:03:44.560 | it might decide oh okay let's go and refer to our archive papers database which we do have within
00:03:54.560 | the rag components so one of these two and we also can fetch the archive paper directly but this is
00:04:00.800 | just a summary. So we could refer to any of these so maybe it wants to have a look at the summary
00:04:07.040 | okay so have a look at summary it says okay this is relevant cool now what I'm going to do is I'm
00:04:13.360 | going to refer to my rag search with a filter okay so the filter that it has here allows it to filter
00:04:20.080 | for a specific paper and that might return you know all of the information it needs and then
00:04:26.880 | that point it would come over to our final answer and basically build us this little research report
00:04:34.640 | and submit everything to us. So that's what we're building there are a fair few steps here and yeah
00:04:42.720 | a fair few nodes that we need to build in order for all this to work but before we do jump into
00:04:48.160 | actually building that graph I want to talk a little bit more about graphs for agents and just
00:04:58.400 | line graph at a higher level. So using almost like a graph-based approach to building agents is
00:05:06.720 | relatively new at least I haven't seen it for a very long time and what we had before was
00:05:14.720 | just more like okay we have this way of executing agents or we have this way
00:05:19.600 | and the most popular of those sort of agent execution frameworks that we've seen is called
00:05:26.080 | React. Now what React does is encourages an LLM to break down its generation steps into these
00:05:36.080 | iterative reasoning and action steps. The reasoning step encourages the LLM to outline the steps it
00:05:45.280 | should take in order to fulfill some objective and that is what you can see with the thought
00:05:51.440 | steps here and then the action or acting steps are where the LLM will call a particular tool or
00:06:03.760 | function as we can see with the act steps here. So when that tool is called so for example here
00:06:14.400 | we have this search Apple remote we of course return some observation from that which is what
00:06:21.760 | we're getting here and that is fed back into the LLM so it now has more information and that is
00:06:28.880 | very typical. That sort of React framework has been around for a long or at least a fairly long
00:06:35.760 | time and has by and large been the most popular of agent types and this agent type in some form
00:06:44.560 | or another found its way into most of the popular libraries so Lang chain, LLM index, Haystack,
00:06:50.560 | they all ended up with React or React-like agents. Now the way that most of those frameworks
00:06:58.480 | implemented React is with this object-oriented approach which is nice because it just kind of
00:07:04.960 | works very easily and you just plug in a few parameters like you plug in your system prompt,
00:07:10.400 | you plug in some tools and it can just go but it doesn't leave much in the way of flexibility
00:07:17.680 | and also just for us to understand what is actually going on you know we're not really
00:07:25.200 | doing anything we're just defining an object in one of these frameworks and then the rest is done
00:07:30.640 | for us so it means that we miss out on a lot of the logic that is going on behind the scenes
00:07:36.560 | and makes it very hard to adjust that for our own particular use cases and an interesting solution
00:07:46.000 | to that problem is to rather than building agents in this object-oriented approach
00:07:53.360 | to instead view agents as graphs so even the React agent we can represent it as a graph which is
00:08:03.600 | what we're doing here so in this React-like agent graph we have our input from the user up at the
00:08:10.560 | top that goes into our LLM right then we are asking the LLM to kind of reason and act in the same step
00:08:19.040 | here it's React-like it's not necessarily React and what it is doing is saying okay I have this
00:08:26.720 | input and I have these tools available to me which is either tool A, tool B or a final answer output
00:08:35.920 | which of those should I use in order to produce an answer so maybe it needs to use tool A so it
00:08:43.520 | would go down generate the action to use tool A and we would return the observation back to the
00:08:50.960 | LLM then it can go ahead it can maybe use another tool again right it could use tool B get more
00:08:58.080 | information and then you can say okay I'm done now I will go through to my final answer and return
00:09:06.160 | the output to the user so you know that's just a React-like agent built as a graph and when you
00:09:17.040 | really look at it it's not all that different from the research agent that we're building again it's
00:09:24.080 | similar in some ways to a React agent but we just have far more flexibility in what we're doing here
00:09:31.360 | so you know if we really wanted we could add another step or we could modify this graph we
00:09:37.680 | could say okay if you do a web search you always after doing a web search must do a rep search
00:09:44.720 | and then only after doing that you can come back to the oracle right we could do things to modify
00:09:52.400 | that graph make it far more specific to our use case and we can also just see what is going on
00:10:00.000 | so for that reason I really like the graph-based approach to building agents I think it is
00:10:07.440 | probably the way to go when you need something more custom you need transparency and you just
00:10:14.160 | want that you know degree of control over what you're doing so that brings us over to LandGraph
00:10:20.960 | so LandGraph is from LangChain and the whole point of LandGraph is to allow you to build agents
00:10:29.120 | as graphs okay as far as I'm aware it's the most popular of the frameworks that are built for
00:10:38.560 | graph-based agents and it allows us to get far more fine-grained control over what we are building
00:10:48.880 | so let's just set a very high level have a quick look at a few different components
00:10:54.240 | that we would find in LandGraph now to understand LandGraph and of course just behold our agent as
00:11:02.240 | well I'm going to be going through this notebook here you can find a link to this notebook in
00:11:08.880 | either the description video or I will leave a link in the comments below as well so getting
00:11:15.280 | started we will just need to install a few prerequisites so I'm going to go ahead and do
00:11:21.120 | that so we have this install graphviz libgraphviz basically all of the things that we need here
00:11:28.640 | are just so we can visualize the the graph that we're going to be building you don't need to
00:11:36.720 | install these if you're just building stuff with LandGraph it's purely if you want to see
00:11:42.720 | the graph that you're building which I think is to be fair very useful when you are
00:11:48.080 | developing something just so you can understand what you've actually built because sometimes
00:11:54.080 | it's not that clear from the code so visualizing things helps a ton now there are quite a few
00:12:01.440 | python libraries that we're going to be using here because we're quite doing a lot of stuff
00:12:05.840 | so we're going to go ahead and install those we have hungerface datasets obviously for the data
00:12:12.160 | that we're going to be putting into the red components we have a pinecone for the red
00:12:17.920 | components openai the llm of course just line chain in general note that we are using v2 of
00:12:25.520 | line chain here we have LandGraph semantic router for the encoders serve api for the google search
00:12:35.040 | api same here and then pygraph is for visualizing the asian graph now before we start building
00:12:43.200 | different components i will just very high level again go through what each of these components
00:12:49.600 | that you're going to do so we have the archive paper fetch component here so what this is going
00:12:56.080 | to do is given an archive paper id is going to return the abstract of that paper to ilm web
00:13:04.160 | search over here is going to provide our lm with access to google search for more general purpose
00:13:11.680 | queries we have the reg search component here so we're going to be constructing a knowledge base
00:13:18.400 | containing ai archive papers and this tool is the access route for our lm to this information
00:13:29.200 | and also very similar is the reg search with filter component and this is exactly the same
00:13:37.680 | it is accessing the same knowledge base but it also adds a filter parameter so that for example
00:13:44.960 | in the web search if the agent finds a archive id that it would like to filter for it can do so with
00:13:53.120 | this tool then finally we also have the final answer component over here so this is basically
00:14:00.560 | a custom format for our final answer and that custom format looks like this so it's going to
00:14:10.480 | output a introduction research steps report conclusion and any sources that the agent use
00:14:19.600 | and it will output all this in a in a json format and we just simply reformat that into the format
00:14:25.840 | there this sort of plain text format after the fact so we're going to set up the knowledge base
00:14:32.960 | first to do that we're going to use pinecone and also this ai archive two chunks data set
00:14:43.200 | so it's basically a pre-built pre-chunked data set of ai archive papers
00:14:49.840 | take a moment to download and what you're going to see in there
00:14:55.680 | is stuff like this so this is actually i think it's the authors and the abstract of the mixture
00:15:04.320 | of experts paper this is all being constructed using semantic chunking so yeah you're basically
00:15:12.240 | the chunks that you'll see they vary in size but they for the most part should be relatively
00:15:18.320 | concise in what they are talking about which is ideally what we want with chunks so first thing
00:15:26.320 | we'll need to do is build a knowledge base for that we need the embedding model so we're going
00:15:32.400 | to be using open ai's text embedding through small so you will need an open ai api key
00:15:38.000 | which you would get from here we enter and then we also get a pinecone api key as well
00:15:47.520 | okay so we've entered that now we are going to be connecting to
00:15:53.840 | i think us east one is the free region so we should use that and what we're going to do is just
00:16:03.120 | create a new index so to create an index we do need dimensionalities from our encoder
00:16:09.280 | so we get that one five three six and then we create this index okay so dimensionality is
00:16:17.600 | with index name you can make that whatever you like the metric should be cosine or dot product
00:16:24.320 | i think you might also be able to use euclidean with embed three and then we're just specifying
00:16:30.880 | that we'd like to use serverless here so we run all of that i already have this index created
00:16:36.960 | so well you can see that here basically i already have uh the vectors are in there ten thousand
00:16:44.400 | and yeah that's already great so the ten thousand i have here comes from here so you can index the
00:16:56.480 | full data set but i think it's two hundred thousand records which will just take a little
00:17:01.440 | bit of time again you can it's up to you but it's time also the the cost of embedding so it's up to
00:17:10.320 | you but ten thousand is fine for this example so you just need to run this i'm not going to rerun
00:17:16.640 | it because i already have my records in there and with that our knowledge base is ready and we can
00:17:22.960 | just move on to all of the the graph stuff so the first thing is the graph state now the core
00:17:30.880 | of a graph in line graph is the agent state the state is a mutable object that we use to track
00:17:38.880 | the current state of the agent execution as we pass through the graph we can include different
00:17:46.000 | parameters within this agent state but in our example i want to be very minimal and just include
00:17:52.640 | what we what we really need for this example so in here we have the input which is the actually the
00:18:00.800 | input from the user we have the chat history so you know we do want to have this as more
00:18:06.880 | of a conversational research agent we have the chat history in there and intermediate steps which
00:18:12.640 | is where i'm going to be tracking what is going on within the graph so we have all of that the i say
00:18:18.320 | probably the main confusing thing here would be this operator add thing here and how we are
00:18:24.960 | constructing intermediate steps so essentially this operator add tells line graph or the graph
00:18:32.480 | within line graph that when we are passing things back to the intermediate steps parameter of our
00:18:39.840 | state we don't replace intermediate steps with the new information we actually add that information
00:18:48.240 | to a list okay so it's probably the the main slightly different thing to be aware of there
00:18:56.560 | now we're going to go ahead and start building our custom tools so as i mentioned before we have
00:19:01.920 | those different components first of those is relatively straightforward so we'll build that
00:19:08.240 | first we have the archive paper fetch so the fetch archive tool is where we given a archive id we're
00:19:19.280 | going to return the abstract for that paper and all we do is we import requests let's uh we're
00:19:26.800 | going to test it with this with a mixture of paper here and all we really need is this okay so we're
00:19:33.280 | just sending a get request to the export archive site and we pass in the archive id and when we do
00:19:42.080 | that we should get something like this now this isn't everything let me expand this it's relatively
00:19:50.000 | big you see there's quite a lot going on there so what we need to do is within this mess we need to
00:19:58.560 | extract what we actually want which is the abstract which is somewhere in here i'm not entirely sure
00:20:06.320 | where uh but we can extract that with this regex here okay so we use that and there we go that's
00:20:20.640 | our abstract so relatively straightforward tool it just takes in the archive id and we're going
00:20:28.960 | to get the abstract for a paper now the way that line graph works is that it expects all this to
00:20:35.360 | be built into a tool which is essentially a function like this which consumes a particular
00:20:42.640 | value which is the archive id in this case and it is decorated with the tool decorator
00:20:50.400 | from line chain we specify the name of our tool here which is i'm just using i'm keeping things
00:20:56.640 | simple we're using the same name for the tool as we use as for the name of the function so i'm going
00:21:03.520 | to run that and with that our tool is ready and we can test it so to run any tool we have to run
00:21:11.280 | invoke then we pass input and to input we pass a dictionary which must align with the parameters
00:21:19.520 | that we've set for that particular function so we do that the next component that we want to be using
00:21:25.280 | is web search so web search we're going to be using the set api and for that again we do actually
00:21:31.680 | need an api key so to get that api key i don't remember exactly where it is i'll give you the
00:21:38.800 | link okay so you'll need to create an account and go to here so surf api dot com slash manage api key
00:21:46.240 | then you'll get an api key and just enter in here
00:21:49.440 | okay so basically we do a search like this so we have a query we're querying for coffee here
00:21:59.840 | and we'll get all of our results in a dictionary here now what we do want to do here is restructure
00:22:08.400 | this into a string that is a bit more readable so that's what i'm doing here and let's see what we
00:22:14.560 | get so using that we're going to get something like this right cool so we have that and again
00:22:22.880 | we're going to put all that into a tool one thing that i actually didn't mention before is that we
00:22:27.680 | also use a dark string in our tool to provide a description to our lm of you know when to use the
00:22:35.920 | tool how to use the tool and so on so same thing we initialize that now the rag tools we have two
00:22:45.360 | of them we have the just the right search and we also have the right search with a filter so let's
00:22:50.960 | go through that we are going to actually come to that in a moment we'll create the tools first
00:22:59.040 | so to create the tool i have a query this is the filter one so we have query which is natural
00:23:04.400 | language string and we also have the archive id that we'd like to filter for all we do is we encode
00:23:11.200 | the query to create a query vector we query we include our filter so we have that here and then
00:23:19.120 | from that we're going to use this format rag context to format the responses into again another
00:23:26.000 | string okay so you see that here so title content archive id and any related papers to that what we
00:23:34.240 | return we also have the same here we have rag search and it does the exact same thing but it
00:23:40.560 | just doesn't have the archive id filter and it also returns a fewer top k here i'm not actually
00:23:48.800 | sure why i did that but yeah i'm going to keep it but you can adjust those if you'd like to return
00:23:54.400 | more stuff you can but yeah we have that so finally we have the final answer which is you know the way
00:24:03.280 | that i've done it here is is basically another tool and the reason that i've set it up as a
00:24:09.200 | tool is because we have this particular structure that i want our llm to output everything in we're
00:24:15.760 | also using the doc string here to describe a little bit of what we want for all of this so
00:24:21.120 | yeah we have all that but yeah that's it so we construct that and actually this bit here isn't
00:24:29.760 | even used you can just remove that it doesn't matter i'm returning nothing here and the reason
00:24:36.480 | i'm returning nothing is because we're actually going to return what the llm generates to use this
00:24:42.240 | tool out of our graph okay and then we have another function you'll see in a moment that will
00:24:48.080 | take that structure and reformat it as we would like it we could also do that restructuring in
00:24:56.400 | here and just return a string but i've just left it outside the graph for now okay so that is all
00:25:03.280 | of our components so we have covered basically all of these here they're all done next let's take a
00:25:11.600 | look at the oracle which is the main decision maker in our graph oracle is built from a few
00:25:18.400 | main components okay so we have obviously lm the prompt which you can see here and of course just
00:25:28.400 | binding that lm to all of our tools and then putting that all together so there's a few parts
00:25:34.480 | we'll go through very quickly here the first is yes the prompt so we are using blank chains you
00:25:42.960 | know prompting uh system here so using the chat prop template we also include these messages
00:25:51.840 | placeholder because that's where we're going to put in our chat history and we're also going to
00:25:56.960 | add in a few other variables as well so we have system prompt and chat history followed by our
00:26:06.800 | most recent user input which comes in here and then we follow that up with the scratch pad now
00:26:13.360 | the scratch pad is essentially where we're going to be putting all the intermediate steps for our
00:26:19.360 | agent so yeah you can imagine okay you have your system prompt you have the chat history you have
00:26:25.680 | the most recent interaction from the user and then following that we're going to be adding
00:26:30.000 | assistant messages that are saying okay i'm going to go do this search i've got this information
00:26:35.680 | so on and so on so yep that is our prompt then we want to set up our lm now the lm we're just using
00:26:45.040 | gb4o here there's nothing yeah nothing special going on there but the one thing that is important
00:26:52.320 | if i come down to i need to import something quickly
00:27:02.000 | so we run that
00:27:05.120 | okay so the part of this is important is we have this tool choice option here and what that tool
00:27:16.240 | choice any is doing is essentially telling our lm that we have to use a tool all right because
00:27:23.280 | otherwise the lm may use a tool okay it may use one of the components or it may just generate
00:27:30.080 | some text and we don't want it to be generating text we want it to always be using a tool and the
00:27:37.920 | reason for that is even if it does just want to respond it has to go through the final answer tool
00:27:44.880 | to respond so we're just forcing it to always use a tool so that is what our tool choice any
00:27:51.760 | does here and we can go through the rest of this quickly as well so we have yes the lm the tools
00:27:59.040 | the scratch pad here is basically looking at all of the intermediate steps that we've been taking
00:28:04.320 | and reformatting them into a string here so we see that the name of the tool that was used
00:28:11.440 | the input to that tool and the result of that tool okay so the output from that tool and we just put
00:28:18.720 | all that together into the string which goes into that agent scratch pad section so this bit here
00:28:25.040 | and then here we're using the line chain expression language to basically put everything together so
00:28:33.600 | our oracle consists of these input parameters we have input chat history and scratch pad
00:28:39.440 | these are all fed into our prompt okay so the prompt if i come to here you can see that we have
00:28:46.080 | chat history input and scratch pad the exact same parameters that we're using here so they need to
00:28:54.960 | align so yep they populate our prompt and then the prompt is passed over to our lm which also
00:29:02.160 | has access to the tools that we have defined here okay and that's it so that is our that's our
00:29:10.160 | oracle now we can test it very quickly to just confirm that it works so we run this okay and
00:29:17.920 | we basically get a ton of output here and this is the output that we're getting from our model okay
00:29:24.320 | so the output the uh ai message which is just empty because what we really want here is we
00:29:32.160 | want to see what the oracle is deciding to use so we can go here right you can see the name
00:29:40.720 | is reg search so it's deciding to use the reg search tool here we are not trying this to give
00:29:46.240 | us facts about dogs so it's not perfect usage but anyway we have the reg search tool and the query
00:29:54.240 | so the input query is interesting facts about dogs and it's going to go and search for that
00:29:59.680 | okay there we go we can and you can keep rerunning that and seeing what it comes out with it will
00:30:09.920 | probably vary every now and again because there is of course some degree of randomness in there
00:30:16.400 | now our agent the oracle is going to be outputting a decision to use a tool so when it outputs that
00:30:25.040 | decision to use a tool we want to be having a look at what is output and saying okay it wants to use
00:30:30.240 | the right search tool let's go and execute the right search tool it wants to go use the web
00:30:34.720 | search tool we go and execute that so that is what our router will be doing so that is what
00:30:43.040 | we can see down here okay so the router is literally consuming the state it's looking at
00:30:51.520 | the most recent intermediate step which will be will have been output by our run oracle function
00:30:58.720 | here right you can see that it returns the intermediate steps which is the action out
00:31:06.880 | and we're just going to be returning the name of the tool that we got from the oracle so we'd run
00:31:13.200 | that we don't need these extra cells and with that the only remaining thing that we need to
00:31:22.080 | you know turn into a function and which we will use to add to our graph in a moment
00:31:28.160 | is the run tool function now the run tool function we could basically we could split
00:31:33.840 | all of our tools into multiple functions kind of like how we have our own function for the run
00:31:39.680 | oracle here but all of these tools can be executed using the same bit of code so there's no real
00:31:46.400 | reason to do that so instead i just define a single function that will handle all of those
00:31:54.480 | tools so again that's taking the state looking at the most recent intermediate step we look at the
00:32:02.080 | tool name and the tool input which has been generated by our oracle i'm going to print this
00:32:09.360 | out so that we can see what is actually happening when this is running and then we would here
00:32:16.000 | tool string to function is just this dictionary here this is basically going to take the tool
00:32:22.560 | name map it to a function and then we're going to invoke it with the input that we have from here
00:32:29.280 | so we run all that then we create this agent action object which basically is just a way of
00:32:36.720 | us describing or you're having a object that describes what happened or what tool we use
00:32:46.320 | what the inputs to that tool were and the observation i the log that we got back from it
00:32:52.640 | and then after that is done we pass all of that information back to our intermediate sets
00:32:58.400 | so we run that and now we can define our graph so we have you know all the components there
00:33:04.720 | they're already now it's time to define the graph so for the graph we already have the
00:33:10.640 | agent state that we've defined so we actually need that agent state to initialize our graph
00:33:17.040 | so we use a state graph object and then once we have our initialized graph that graph is empty
00:33:25.600 | right it doesn't know you know all the stuff we've just done or the components we've defined
00:33:29.760 | so we need to then tell it which components we have defined and start adding all of those so
00:33:38.000 | we do that using the graph add node method and what we're going to do is just take our our string
00:33:46.400 | and we're going to map it to the function that would run that tool okay so or run that tool or
00:33:53.920 | run that component okay so for oracle we would be hitting the run oracle function for these ones
00:34:01.120 | here so rag search filter rag search so on and so on as i mentioned before they can all be executed
00:34:06.720 | using the exact same bit of code so that's exactly what we do here we just pass in the run tool
00:34:12.800 | function so we do that we define all of our nodes there then the next step is to define okay which
00:34:20.640 | one of those nodes is our entry point you know where does the graph start okay and that is of
00:34:27.520 | course our oracle right we saw the graph earlier here so we're always starting okay we start with
00:34:32.640 | the start where we import our query and that goes directly to the oracle so in reality the oracle is
00:34:38.480 | our entry point okay then we have the following our oracle we don't just have you know one direction
00:34:48.880 | to go we have many different directions and the way that we set that up is we use our router and
00:34:54.720 | we have what are called conditional edges which are basically these dotted lines here so we add
00:34:59.200 | those conditional edges the source for where we're starting from there is our oracle and the thing
00:35:08.320 | that decides which path we should take is our router so our oracle outputs the tool name and
00:35:15.280 | our router basically passes that tool name and then directs us in whichever direction we should
00:35:20.960 | go then we need to add edges from our tools back to the oracle so if you see on here we have these
00:35:27.040 | you know the full lines here that's basically saying okay if we are at one of these tools we
00:35:32.800 | need to go back to the oracle like it can't go anywhere else so it's not a conditional edge
00:35:36.960 | it isn't dotted it is a a normal edge i.e when you're at this component this is where you're
00:35:44.240 | going next and all of these components except from final answer go back to the oracle and that
00:35:50.720 | is what we have defined here so we say for tool object in tools if it is not the final answer
00:35:57.440 | we're going to add an edge from the tool name of the tool object name back to the oracle that's
00:36:04.960 | what we do and then finally we have the final edge which goes from our final answer to the end node
00:36:12.560 | which is exactly what you can see from here all the way over to our end node there okay and that
00:36:20.480 | is the definition of our graph we can just confirm that it looks about right which we do here okay
00:36:31.360 | actually the oracle has a conditional edge over to the end i'm not sure why that is but for the
00:36:37.040 | most part this is what we're looking for so we're gonna stick with that and yeah i mean everything
00:36:44.240 | is compiled we can see the graph looks about right and yeah we can we just go ahead and try it out
00:36:52.000 | now so let's see what that looks like we'll go to the first question again not on topic for our
00:36:59.600 | ai researcher but it's we'll just try it so tell me something interesting about dogs let's run that
00:37:05.600 | okay and we can see all the steps that are you know being processed and that is because i have
00:37:13.840 | put a load of print statements in throughout the code so we can see that it's hitting the oracle
00:37:18.400 | it's going to rag search and it's invoking this query interesting facts about dogs right it's
00:37:25.360 | probably not finding much so then it's going to the web search well actually sorry it goes back
00:37:32.720 | to the run oracle then it goes to web search performs the same and at this point it probably
00:37:39.440 | has some interesting information so we go back to the oracle and the oracle says okay we have
00:37:44.880 | the information let's go and invoke the final answer and then the final answer as you can see
00:37:50.560 | right we have this introduction and we'll go through so on and so on we have the research
00:37:57.520 | steps and basically we have all like that full format that i mentioned before so with that full
00:38:07.360 | format i'm going to define a function that will build the report and just format it into a nicer
00:38:14.400 | like more easy to read format so that is within this boat report it's going to consume the output
00:38:22.160 | from our graph and it's going to restructure everything into this here so let's see what
00:38:29.760 | it came up with for the first question okay so we can see there's quite a bit in there given the
00:38:37.120 | question as well so introduction dogs are fascinating creatures i've been companions
00:38:41.280 | of humans for thousands of years so on and so on you know it's a real introduction the research
00:38:48.240 | steps that were performed so it actually says okay i went to archive for academic papers or
00:38:55.040 | research related to interesting facts about dogs then it performed a web search to gather general
00:39:02.000 | knowledge and fun facts about dogs from various reputable sources then it gives you the little
00:39:07.440 | report here which is i think looks pretty good and then we have a little conclusion
00:39:15.440 | finally we have our sources okay so we can actually see from the sources i didn't really rely
00:39:22.560 | so much on the archive papers which is not surprising given that they are ai archive
00:39:28.160 | papers but we can see most of these are i well i assume all of these are actually coming from the
00:39:32.960 | web search tool so yeah that is our first little research report let's try something a little more
00:39:41.360 | on topic although so quite general and broad we're going to ask it to tell us about ai so let's run
00:39:47.680 | this so it goes with right search first the query is just ai then we go back to the oracle
00:39:56.800 | then we have web search then back to the oracle again we have right search filter so it's ready
00:40:03.840 | you know it's it's going for it here so it's looking at this paper which i assume is gone
00:40:09.600 | from the references of the previous oh probably from the web search step or maybe even the right
00:40:15.040 | search step as well so yep it's going for this archive paper then we're going for another archive
00:40:21.760 | paper here and finally we have our final answer so this there's a lot of information coming in
00:40:30.640 | from here so let's see what we let's see what we get there
00:40:34.160 | all right nice so we have nice little introduction the three steps that perform so specialist search
00:40:46.160 | on ai using archive database web search to gather general information and then filtered specific
00:40:52.000 | archive papers to extract detailed insights on ai related topics cool now we have the report
00:40:57.680 | so i'm not gonna go through all of that um but just a high level it looks kind of relevant so
00:41:10.560 | nice has some like recent stuff in here gpt4 we have
00:41:16.080 | chat gpt and pi3 in there so it's getting some relatively recent information then we have the
00:41:25.520 | sources so this is probably the most interesting bit to me so you know what have we got here so
00:41:29.840 | an in-depth survey of large language model based ai agents seems pretty relevant and cognitive
00:41:39.440 | architectures for language agents another kind of interesting sounding paper we have the wikipedia
00:41:46.400 | page for ai and google cloud what is what is ai so yeah some i think good sources there
00:41:52.880 | let's try one more so we'll get a little more specific on this one so i want to ask what is
00:42:01.120 | rag let's see what we see what we get so we are running the oracle it goes to rag search asking
00:42:12.240 | about rag go back to the oracle then we have web search again asking about rag goes back to the
00:42:21.120 | oracle again and from now it's like okay final answer so it seems to have had enough with that
00:42:28.800 | let's see what we get nice okay so rag is an advanced technique in the field of ai
00:42:40.640 | integrating external knowledge sources cool research steps specialized search using the
00:42:47.840 | rag search tool perform the web search to obtain general knowledge and additional perspectives on
00:42:53.600 | rag from various sources compiled and synthesized information to provide a comprehensive understanding
00:43:00.080 | of rag we have the little report here looks reasonable two main components retriever and
00:43:08.800 | generator nice and yes addressing the limitations of traditional lms so on and so on and then we
00:43:17.600 | have all of these sources here so we have all from autogen simply retrieve aws nvidia google
00:43:24.720 | cloud and ibm okay so the autogen here is that oh and both of these sorry both of these seem to be
00:43:32.320 | the archive papers that they they have found and then the rest of these are i assume from the web
00:43:38.560 | search so it looks pretty good so you can already see that well langreth was pretty nice in allowing
00:43:48.160 | us to build a relatively complex agent structure and it was at least in my opinion far more
00:43:55.760 | transparent in what you're building like we know what prompts are where we know what tools we're
00:44:02.080 | using and we can modify the order and the structure of you know when and where we are using those
00:44:08.480 | tools which is is nice to have and something that is kind of hidden away when you're using you know
00:44:16.000 | the more typical or the past approach of like react agents as objects or classes in python
00:44:25.760 | and yeah we've seen how that all goes together quite nicely to build a research agent which from
00:44:32.000 | what we've seen like given we didn't really work much on tweaking it it worked pretty well like it
00:44:37.920 | was going to different sources it was doing like the web search the rag search and then like going
00:44:44.640 | through and filtering for specific papers to get more information and you know that was with just a
00:44:50.320 | few quick tries so it's hard to say how it would perform use with you know a broader set of
00:44:57.840 | questions but just from those quick experiments that seems pretty cool in my opinion now i think
00:45:06.960 | this sort of approach to pairing both graphs and agents it's just nice for all the reasons i just
00:45:15.680 | mentioned it works well and it's not just line graph that does it i mean line graph is probably
00:45:21.920 | the best known library but i'm also aware that haystack have something in there at least and i
00:45:27.200 | believe llama index either have or they might be putting something together i'm not sure but i've
00:45:32.880 | heard something about llama index in that space as well so they're probably things i'll look into
00:45:40.080 | in the future but for now i'm gonna leave it with line graph and this research agent so
00:45:46.400 | yeah i hope all this has been useful and interesting thank you very much for watching
00:45:52.800 | and i will see you again in the next one bye