back to indexLangGraph 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
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: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