Video: GenAI and Graph Foundations: Building GraphRAG with Neo4j | Duration: 6928s | Summary: GenAI and Graph Foundations: Building GraphRAG with Neo4j | Chapters: Welcome and Introduction (10.16s), Workshop Introduction (186.905s), RAG and GraphRAG (804.635s), Knowledge Graphs Overview (1179.615s), Environment Setup (1550.08s), Knowledge Graph Construction (1753.035s), Schema Extraction Demo (1949.315s), Building Knowledge Graphs (2149.515s), Language Support & Ontologies (2520.585s), Optimizing Chunk Size (2594.48s), Defining Custom Schemas (3067.005s), Schema Definition (3273.925s), Structured Data Integration (3778.27s), Vector RAG Retrieval (4367.33s), Vector Cipher Retrieval (5026.69s), Text-to-Cypher Retrieval (5750.43s), Q&A Session (6330.925s), Workshop Conclusion (6600.565s), Resources & Next Steps (6717.045s), Closing Remarks (6825.655s)
Transcript for "GenAI and Graph Foundations: Building GraphRAG with Neo4j":
Hello, everybody. Good morning, good evening, good afternoon, and welcome to Road to Notes. I'm super happy to to kick it off today. We did an earlier session this morning already, and now, this is the second round of Jenny I and Graph Foundations with Martin. Martin is a developer advocate at Neo4j. Welcome, Martin. Super happy to see you once more. Thank you, Alex. Yeah. We'll we'll have a good, a good round of, of of a session today, some hands on exercises, some some, some learnings. So you'll be, you know, ideally following along, and you'll join, our our session today with some exercises you can do yourself during the two hour sessions. But there is obviously a possibility for you to ask questions, to give comments, use the chat, let us know where you're from, and, and exchange what you're working on and what you're doing currently with Neo4j. Maybe you're already doing something. If you have any questions, please use the Q and A functionality. I can flag your question as Q and A, but if you put it right there, you won't miss anything. We have our dear colleague, Zaid, in the background here as well who will be answering questions that come in, but we will also answer some live during breaks. And, yeah, the session is obviously recorded. So if you are watching this or want to watch this again afterwards, you will get a link into your inbox sometime tomorrow with the link to the on demand sessions. All the road to node sessions are recorded. So this is obviously the kickoff on the day to day, but we will be doing more every Thursday for the next couple of weeks until the fifth. We'll do, how to prevent hallucinations. We'll do something about knowledge layer. We'll do something about agentic engineering, agentic memory or agent memory, how to do that with Neo four j. So interesting topics. They'll all be at the same time and everybody can join. And if you can't make one, then, yeah, as I said, the on demand page will be there right away so you can join them, or you can watch it at least directly. So if you haven't registered for the upcoming ones, please do so. And, yeah, today we'll dive into a little bit more of a hands on session about what is GraphReg? How does it work? What's a knowledge graph? How do we get your data to an LLM? How does this work? And how can you extract information from the graph in a better way so that you get more precise answers and you can start with this context engine, this knowledge engine for AI systems? And, Martin will give you all the details. We'll guide you through the day. And, I'll be popping in every now and then for questions. So, yeah. Enjoy everybody. Have fun. And over to Thank you, Alex. So just a a, a few. things before, we get started. If you see me looking to my left, this is where the q and a tab is. This is where the chat is. So if you see me look... Looking to my left, that's... That is that is what I'm doing. But, yeah, thank you, Alex, and welcome to Generative AI and Graph Foundations. So first of all, I'm Martin. I'm a developer advocate here at Neo four j. You can find me virtually everywhere online with Martin O'Hanlon. There are very few Martin O'Hanlon's, which makes it useful for me because I tend to get an easy to remember username. So what are we gonna do today? So first of all, we've got a sort of four, four step workshop. So first of all, we're gonna look at what is generative AI, and we're gonna define some terms, make sure that we are all speaking the same the the same language. We'll then, go into a hands on, practical session where we are gonna construct a knowledge graph. We're gonna create use generative AI to turn unstructured and structured data interestingly into a graph. We'll then look at retriever, so how we can connect our knowledge graph to to do generative AI retrieval. And then the last session is what I'm gonna leave leave you with to do in your own time, which is around integrating the retrievers that you create into an agent. So, we are gonna use GraphAcademy today. GraphAcademy is our online online learning platform. It's a way that I can, get... Make sure that you have the content, get your... A Neo four j instance to work with. And you'll see when we get into using GraphAcademy, lessons, practical exercises where you can run code as well. So, let's get straight into it. There are a couple of things that you need to do. So, first of all, the workshop materials are on GraphAcademy. And in order to, get to those workshop materials, you're gonna need to create a GraphAcademy account if you don't already have one. To make things a little bit easier, oops, I have created a document which has got all of the links in it that you may need. And I think Alex is just about to share the link he already has. Thank you very much. So if you go to this link, dev.neo4j.com/workshop-jenai notes, it's been popped into the chat as well. Head over to GraphAcademy and, sign in or create an account. I'm already signed in. That's, I'll sign out and sign and sign myself back in. Sign in with your SSO SSO of choice or, or create a login if you want to. But once you're signed in to, GraphAcademy, we can go we can go off and access the workshop material, which is just here, GraphAcademy and workshops workshop gen AI. Once you get yourself into the workshop material, I'd just like you to enroll. Enroll for free. There'll be no cost, and we'll provide everything that you need to do today. So I'm just gonna pause for a moment, just to kinda make sure that there isn't a whole stream of people having problems. Doesn't look like look like there are. I can see lots of people have joined the notes document, again, which suggests people are following are following the links. But... Yeah. So I'll... Just to, show you the layout of GraphAcademy. So click on this menu in the top left hand corner. We can see the four modules that are part of this workshop, generative AI, knowledge graph construction retrieval, and then agents. We are right at the top, module number one. And in this module, what I'm gonna do is I'm gonna talk to you a little bit about what generative AI is. And at the end of the module, we will create ourselves a development a development a development environment for this workshop. So let's go. Like I say, you can follow along with the content. You have all of the content in front of you that I am going to present. What I am gonna do is I'm gonna use a slide view, just because it's a bit bigger, a bit easier for for me to present, but it is exactly the same content that you have in front of you. So I think it's worth starting off with talking about what is generative AI. And what I wanna do is make sure that we are all using the same terms to mean the same things and we have the same level of understanding before we start. So when I talk talk about generative AI or Gen AI, I'm referring to artificial intelligence systems that are designed to create new content that resembles human made data. So that could be text, images, audio, video, video, code. And by and large, they work in the same way, which is, they take training data. From that training data, they produce a model. And based on that training data, that model can output new content. They are not intelligent in the way that humans are. They do not understand or comprehend the, content that they generate. And the content that they generate is based on statistical patterns and correlations in the training data. So let's be really clear. While they produce coherent output, they lack understanding. Yeah. I think we all know that but it's worth, stating that from the outset. Right? Now we are... During this workshop, we're gonna focus particularly on text generating Gen AI models, large language models. So when I talk about LLMs, that's what I'm talking about. I'm talking about text generating Gen AI models. And, these models, they trained on huge amounts of text data to perform various tasks. And the way a large language model works is a response is a probabilistic continuation of the instructions it receives. So presented with the instruction, continue the sequence a b c, and that LLM could respond with d e f. That is its job. It's given a prompt, and it continues that prompt with the most statistically relevant, response. And when we get an LLM to perform a task, we give it a prompt, and that prompt could be a single a single a single sentence or a significantly bigger, amount amount of context. And, again, the large language model's job is based on its training data is to return the continuation of that text. We should always use caution when using generative AI models. While they have a lot of potential, they are essentially highly complex predictive text machines. They don't understand, the information they output. And, likewise, we should be cautious for many reasons. One of them is access to data. The sources for these models are typically publicly available. Data, often from the Internet, it could be a question... Questionable quality. The thing that we have to remember as well is that that training happens at a point in time. That training data is static and it may not reflect the current state of the world. So, you know, if we ask an LLM model, you know, not an agent but the model itself, you know, tell me about the latest Neo four j features. It may come back and say, here are some old features, with incomplete information based on its training data. LLMs are designed to create human like text and are often fine tuned to be as, as helpful as possible. And this can be often be where, where we output a hallucination. Right? Something which is which is stated as true, yeah, but is in fact, misleading or baseless or just entirely made up. The example I like, is, you know, if we trained an LLM with enough information that said the moon is made of cheese, it would respond in that way as fact. Yeah. However, we can improve the response, responses of LLMs by providing additional context. Right? So if we want to summarize a custom... A company's results, if we provide a stock market report as part of our prompt, yeah, the LLM will do what it's good at, which is reasoning, producing human like text, And based on the additional context it has received, it will probably produce a reasonable response based on based on that information. We can provide context in many different forms. Right? So we could provide a stock market report and also the annual results. And again, if the context is relevant to relevance to the query being... To the question being asked, we can expect to get a better response if we provide additional context within our prompts. So supplying context. Supplying context in your prompts helps LLMs generate more accurate, relevant, trustworthy responses by reducing hallucinations and compensating for the lack of data. That is predominantly what we are going to do in this workshop. We are gonna look at ways that we can provide the right context to an LLM in order to get a better response. I'm just gonna just quickly nip over just to kinda make sure, there is... Yeah. Okay. Sorry. I'm just making sure that, that everybody's, sort of happy and well. Alright. So that's generative AI. You know, the main thrust of this kind of workshop is learning about GraphRag. Before we talk about GraphRag, let's talk about RAG. So retrieval augmented generation is an approach that enhances the responses of LLMs by providing them with relevant up to date information retrieved from external sources. RAG is a process for gaining context to give to an LLM to improve its responses. And the typical Rag process looks like this. Right? Some... A user asks a question. Right? The application, right, will interpret that user that user's that user's request, and use a retriever to search for, typically, data sources, might be APIs, but we'll use a retriever to pull back additional context. Right? That additional context will then enhance the prompt that the user gave it, and that enhanced prompt will be passed to will be passed to the LLM. Typical, rag, rag process. Right? And if we kind of, like, imagine some use cases, so I've got a news chatbot. So what's the latest news on the Olympics? If that news chatbot is gonna use an LLM, that LLM's gonna need some additional information in order to provide a good provide a good response. We could gain that additional information, from an API, maybe a real time, data... Date date data feed. So the Retriever is that key component of the reg process. Right? The Retriever is responsible for retrieving the right amount of information, the right information, from external sources to provide that additional context. And typically, a retriever takes on unstructured input like a question or a prompt and it searches for structured data. And we are gonna look at various methods of, of building retrievers. So we'll look at full text search, vector search, and we're also gonna look at text decipher cipher as well. So we have that... We have our retriever, as part as part of our RAG process. And we... In terms of data sources, anything you like. Right? Common data sources tend to be documents, text, APIs, and knowledge graphs as well. And we're gonna spend a reasonable amount of this workshop looking at how the... At how we can create a knowledge graph. So let's enhance that, that use case we saw saw before of our kind of news chatbot. And let's say that we have multiple sources, of context, might be a news API, might be might be a collection of articles as well. We could take that information, put it into a knowledge graph so we get a, a structured representation of both the article data and that... And the data we're getting from our news, from our news API to provide better context to, to our LLM in order to get a better response. Okay. So that's reg. Let's talk about GraphRag. So GraphRag, or Graph Retrieval Augmented Generation, essentially uses graphs, to provide relevant and useful context. GraphRAG was a term that was coined by Microsoft in a research paper, I think in 2022. I should have looked up the date because I couldn't remember it last time I did this presentation. I think '20... Late twenty twenty two. And essentially what their research showed was, was if you used, graphs, knowledge graphs alongside vector search, you've got much better responses than just vector search on its own. GraphRag has sort of expanded to, to, incorporate lots of other approaches as well. Benefits of GraphRag that were kind of proved during this re... Research, better, better, richer context, accuracy, explainability, flexibility in terms of being able to query, our data sources as well, and also sort of enhanced reasoning, so, removing that black box element. So graph enhanced vector search is, is is is is, I suppose, the the typical, the traditional, graph... GraphRag approach. And if we use that, that model that we looked at earlier, essentially, it works like this. Right? The The user submits a query. We have an application, that you... That can use a vector plus graph retriever. So what the vector plus plus graph retriever will do is it will use the user's questions to find similar nodes. So the nodes that are similar to the use... To to the user's request. And then based on that similar node, it will it will traverse the graph around that node to find related entities and information, to find relevant contextual information. And then we can then use that information, to provide that enhanced prompt to our LLM. And one of the activities we will do is we are gonna build a vector plus graph retriever. Full text search, also a really powerful tool particularly if you want to, find specific information. So you you wanna work for... Look look for, I don't know, maybe a specific company within your within your dataset or a particular individual. Text to Cypher, also an alternative an alternative approach approach in GraphRag. And what Text to Cypher allows you to do is turn a natural language question, so a question such as, you know, how many sales have... Has this person made? Use the use the schema of the graph and the question to turn that into a Cypher statement that we can execute against our graph to provide additional context. Okay. So, we have nearly finished me talking. There's just one last thing I wanna talk about, which is what is a knowledge graph? We have spent a little bit of time, talking about generative AI and how knowledge graphs can help and how knowledge graphs are central to GraphRag approaches. But let's just talk about what they are and provide some definition. So a Knowledge Graph is an organized representation of real world entities and their relationships. So Knowledge Graphs allow us or give us a structured way to represent things, their attributes or properties, and how they relate to each other. And knowledge graphs have been around for a long time. They're not a new thing. Search engines have used knowledge graphs for a long time, particularly to provide information about, like, people, places, things. So if you search for Neo four j, having some structured data, some context about that company. And this is a knowledge graph that could represent, you know, a section of Neo four j. So Neo four j, the company, was founded in and is located in Malmo, which is a location... Also happens to be, located in London. London is the capital of The United Kingdom. There is a blog post about about the company Neo four j that refers to database technology, so on and so forth. So we can see how we can use this structure to represent things and the relationships between them. Knowledge graphs are also incredibly useful when we want to break down sources of information and see how information is related to, see how sources of information are related to each other as well. So for example, if we have multiple sources, we can break those sources down into, into smaller chunks and we can understand how those chunks relate to different topics as well. One of the things that we can use our Knowledge Graph for is to not only describe, is is to not only hold our data, as in our domain information, but also to describe our data. So so to have an ontology or to have a description of the data. So if I kind of imagine lessons within GraphAcademy, every lesson has a type and that type is all content. And I can And I can bring my organizing principles next to my domain information. So I don't have to have them as two separate stores. I can use the one structure to describe not only the data that I'm holding, so for in this case, what courses, what modules, what lessons, but also the type of lesson, lesson that, that... The type of data that lesson is. Yeah. So being able to combine not only your data but also your organizing principles allows you to allows you to query and understand, well, actually, what data do I have but also what is it. So in general applications, knowledge graphs play a crucial role in capturing and organizing important domain specific and proprietary company information. They are not strictly limited to structured data, and we and we can use knowledge graphs to represent less organized or unstructured information as well. So GraphRag, can use knowledge graphs for context and they form the foundation of our applications. So I think that is enough of me talking. What I am going to do now is, if you're following up following along, we are in this last set lesson here. It's GraphRag for Python. And what we're gonna do is we're gonna go through the process of creating and setting up our development environment. So we're in this first module, generative AI, and we're in GraphRag for Python. So just to give you an introduction, the GraphRag for Python package, neo4j graphrag, gives us access to some GenAI functions so that we can use GenAI functions with our Neo4j database. So it's got retrievers, GraphReg pipelines, and also knowledge graph construction. So I am gonna go through the process with you. So I'm gonna create a dev environment and I'm gonna do all the activities with you as well, but I will give sufficient time for everybody to do the activity themselves. So like I said, I've been using the slide view. What I'm gonna do is I'm gonna pop back to the lesson view. So, if you want to follow along, you're gonna have to set up a dev environment. And what what we've done is we've created a repository for you. So it's this workshop gen AI repository. And you can use a GitHub Codespaces and online IDE and workspace, for the... For this workshop. It's gonna automatically clone that repo and set up the the environment for you. All you need to use a GitHub Codespace is a GitHub account. So I'm just gonna go ahead and create a GitHub Codespace. And what our GitHub Codespace is is essentially a dev environment, a dev container in the cloud with an online IDE, looks very similar, to Versus Code, in in a web browser. So what this is this is gonna do is it's gonna take a couple of moments just to clone that repo, set up a container, and it's gonna go through go through the process of creating that environment for us as well. Once you've got your... If you wanna develop on your local machine, there is instructions here for you to do so. Once once we've done that, we're gonna have to set up our environment, and I will go through go through that process as well. I'm just gonna take a moment just to look at any questions that have come through and have a quick look at the chat as well. So, I have a question from Amy. Is the text decipher coming already in? Thank you, Alex, who's who's volunteered. Yes. Already exists, and we will we will create a text decipher retriever as part of this. Can you follow along locally, in desktop two? Yes. There's nothing to stop you from doing that. You will have to modify this, these environment variables to be the location of your, of your instance in in desktop. Just to kinda note, this information here, these the... These credentials here, when you signed into GraphAcademy, GraphAcademy created a Neo four j instance for you for you to use as part of this workshop. So, everybody's, details will be different. I I think that's all I've got in terms of questions. Yeah. Okay. So, okay. Brilliant. And it looks like my, like my container... My code space is just firing up. Just make a little bit of room. You can see it's going through the process of, of setting up the environment for me. So first thing we need to do is, is we need to create this dot e m v file. And this is gonna hold the credentials of our Neo four j database. So, I'll do that now. I'm gonna create a dot e m v file. And I'm gonna copy into it the information that GraphAcademy's giving me. This is this this is the connection information to my Neo4j database. You are gonna need an OpenAI API key. If you go back to this notes document where you, found the links, I have provided an OpenAI key for you. So we can just copy that out of there and pop it into our environment. So that's our setup. We need the Neo four j database, and we need an OpenAI API key. If we go back to the lesson, there is instructions here on how you can test your environment. There is a program called test environment dot p y that's gonna attempt to connect to, sandbox. So here we go. And if, if I run this test environment program If I run this test test test environment program, what I should see is it's gonna run five tests, and I should see okay to tell me that it's... There we go. Ran five ran five tests. Okay. And it's been able to, connect to my instance and connect to OpenAI. So let's just have a quick look, see where we are, and I'll give people a moment. Oh, I've had lots of people joining. Hello hello from New York. Hello. Few questions. Thank you. Yeah. Great. Please please ask questions. It's lovely to see people, people joining joining, the, the the workshop. So if you have just joined, what I'm gonna do is say, you will find all of the course material here. And I'm gonna reshare, the link to this document as well, where you will find... You can log in to GraphAcademy here and access the course content here. And just to recap, when you get into Graph Academy, we are in this lesson here, GraphRack for Python, and we are just setting up an environment. Okay. I'll leave you leave you to do that if you if you haven't already. I'm just gonna move on because there's there's a few things that I need to talk about. So we're gonna move into this next module here, which is knowledge graph construction. And we are going to look at the process of how we can construct a knowledge graph. So we're gonna look at basically the process of constructing a knowledge graph from unstructured data. Our job is to take collection of unstructured data and we're gonna use an LLM to turn that into a knowledge graph. So when we're constructing a knowledge graph, we typically follow these steps. The first thing we're gonna do is we're gonna gather our data. Right? And we're gonna take it from wherever it is, put it into a format that we can use. So we're gonna gather it, we're gonna chunk it, so we're gonna split it into bits. Yep. We're gonna vectorize it, so we're gonna use an embedding model to create vectors from that data. We're then gonna pass that data to an LLM and ask it to extract the nodes and relationships. Once we have our nodes and relationships, we will use that output to generate a graph. So that's the that's the kind of five the five step process we will go through. So if you wanted to construct a knowledge graph based on the Neo4j Wikipedia page, right, you would, right, gather that text. So we're gonna take the text off the page, Neo four j's graph data... Database management system. We would split it into bits. These are quite small chunks. They don't have to be that small. But we would split it into some sort of, split it into sections that make sense. We would then create embeddings and vectors for each for each one of those chunks, essentially turn that text into a list of numbers. And then finally, we would pass that text to an LLM and instruct it to identify entities and relationships within that text and return that data to us. We would then parse that information that came back to the LLM and use that to construct a graph. So in this case, Neo four j is a graph database, was developed by Neo four j Incorporated, a company, and is Neo four j the graph database is implemented in Java, which is a programming language. That's essentially what we are looking to do when we construct a knowledge graph. Okay. So, before we do that, right, let's have a look at how we can use, use this package and how we can actually extract a schema from text. Right. So what we're gonna do is, the way that that that this work, that this workshop works is there is some starter code that I've given you, and I would like you to open it, explore it, use it, and then see how it works. Okay, so we're we're going to start with this program here which is called ExtractSchema. And this code uses this class to extract a schema from some given text. So this extract is going to create a prompt instructing the LLM, it's going to pass the prompt and the text, and then it's gonna return a schema object that describes that, that text. Alright. So if I, if we go to our... I'm gonna make this a little bit bigger because that is impossibly small. So this is the program that we're looking for, this extract schema. And as we can see, we create this schema from Text Extractor. We give it an LLM. So we need a large language model in order to be able to extract extract the text. We define a chunk of text and then we then run it and print and print the schema. So let's give this a run. Let's give this a run. There we go. So we're gonna run it. Oh, hello. And program is run, and it's returned a schema, a graph schema to us. Right? And we can see that it's extracted two nodes. The first one is a graph database management system. The second one is a company. And it's also said, okay, well, there is a relationship, developed by. So we have two nodes, graph database management system, a company, one relationship, and it has defined a pattern that says graph database management system developed by a company. So we can see how we can turn text into a schema. It has pulled out the entities with... Within this, which is a graph database management system, the relationship, developed by and has associated that to a company, which is Neo four j Incorporated. And... Oh, I've lost my head. There we go. Yep. There we go. And we can try that with with with different texts. So, I've provided some example here... Examples here, but you can put your own text in. So the next one, the the Eiffel Tower is a wrought iron lattice tower on the Champ De Mars in Paris, France. So if I run this through that, enter, schema extractor, we should be able to see entities such as, tower, location, city, country. So those are the nodes that... Those are the the the node labels, relationship types such as located it. So, essentially, what it said is there is a tower located in a location, location is located in a city, and the city is located in a country. So it's used that, that text to to generate us a schema. So, yeah. Take a moment, just have a go, run some examples through, and then we'll just have a quick look if there are any questions. So I had a question. Why do we need, an OpenAI LLM? So we are using an LLM. It doesn't have to be an OpenAI LLM. That just happens to be the one that I've used because we are using the LLM to convert our piece of text or to analyze our text and turn that into a graph scheme. Do we get access to API keys? Absolutely. They... As Alex has said, they are, in, the notes document that we just saw. And Zayta said the same. Brilliant. Okay. So we've seen how we can turn text into a schema. What we're gonna look at now is how we can create a graph. So what we're gonna do now is we're gonna take some, take take a text document and we're gonna turn that into a graph. Now, the, the GraphRack for Python package has a class called SimpleKG pipeline. Simple Knowledge Graph pipeline. Simple, I don't think is a great description for it. Simple suggests it can only do simple things. Actually, it's simple because it has a simple interface attached to it. But what the Simple KG pipeline does is it essentially runs runs those four, tasks that we talked about earlier. Loading, splitting, creating embeddings, extracting entities, and then creating the database. And the steps look like this. These are the steps that the simple KG pipeline implements. Again, loading, splitting, chunking, entity relationship, extracting, pruning, so getting rid of dupes, things like that, and then writing. So, this is the activity we are gonna go through. We are gonna take some unstructured data. Now it happens to be, text from one of the GraphAcademy courses. It's a course called Neo Neo4j and Generative AI Fundamentals. So what we're gonna do is we're gonna take tech... The text from that course and turn it into a graph. And we will iterate on this, knowledge graph creation process to improve it over time. So again, off to you. You have a test to do. So again, we'll start with a, some starter code which is this file here, this KG builder. Have a look. Review the code and how we kinda set up this KG pipeline and then I want you to run it. So it's gonna create a graph from a PDF document, and then spend some time reviewing the graph and the entities that it extracts. Like I say, I will run through, run through the process as well, alongside you, but you have all of the information in the lesson, this lesson here, to, to do that process yourself. Alright. So, let's just have a bit of tidy up because I seem to have lots of things open. And we're gonna start with this KG builder, builder builder program, Knowledge Graph Builder. Let's just have a kind of quick look through. So we can see the first first thing we're doing is we are creating a connection to our Neo four j instance. So we're using the credentials that we put into the environment file to create a connection to our database. We're gonna need an LN. In this case, we're gonna use GPT five nano. It's a very small, very quick model, that's that's good for create... For creating these these these knowledge graphs particularly quickly. So we're gonna need an LNM. We're also gonna need an embedding model, and it's the embedding model that turns our text into vectors. And we... And again, we're gonna use an OpenAI model. The the KG builder doesn't, dictate what sort of models you use. You are open to use virtually any model you want. So we create an embedder, and then we create our KG pipeline, our simple KG pipeline. We give it the LLM we wanna use, the database that we want to write to, we give it an embedder, and we tell it, in this case, that we are gonna create our knowledge graph from files. Finally, we give it our file, which in this case happens to be a PDF file. And all the PDF files are in this this data folder here. So let's just have a quick look at look at one of them. So this is this very first document. So this is a PDF document of that course content. It's the raw it's the raw course content that builds that builds the lesson, but we can see, you know, it is essentially unstructured text text based, text based, data. So we take a... Take that PDF document, run it through the KG builder, and then we'll print the result, to see what what we get. So I'm just gonna run it. Right? So I'm gonna take that PDF document with limited information and just see what we get out. Great. Okay. So, it ran. It basically said, well, there are two nodes that have been created, that that need to be resolved and two nodes were created. So it's taken that document and created, albeit, a relatively small graph. But we can explore that knowledge graph using Cypher. So the first thing we can do is actually... Let's have a look at the documents and the chunks. So, we created... There was one document that we used, and essentially created one great big chunk. So it took all that whole document, didn't split it, just created one one great great great big chunk. But what it also did was it used that chunk of data to do some entity and relationship extraction from it. And we can use this Cypher query, which finds a path, goes from the goes goes from the chunk and essentially finds every entity that relates to that chunk and how those entities relate to other entities. So based on that, one document, and no other information, it has created two, two nodes. Essentially, it said that this this, this chunk of text, creates... There is a generative AI, node that describes large language models. So we we've kind of proven that we can we can take unstructured data and that we can build a, and that we can build a knowledge a knowledge graph from it. So, spend it... I'm sure people are still running that. Spend spend a bit of time. I am just gonna have a quick look at some questions and see what, what what what has been coming up. Apart from Python, are these Neo four j libraries available for other programming languages? We have, we have drivers for many, many different programming languages. The knowledge graph construction, piece, is, predominantly for Python right now, albeit it is open source and is... Most of the complexity comes in things like the LMM prompts and the integration. So it's it's, it's it's easily adaptable, I think is what I'm saying. Do I need an ontology? You do not need an ontology. Have a... However, one of the things that we will find as we iterate on this knowledge graph construction process is the the more schema we provide, the better a job the LLM does. And when do I need an ontology? I would say you need an ontology, probably almost immediately if you wanna get get out a knowledge graph, that that fits that fits your use case. But that ontology can be very simple to start with, you know, simply a list of the entities and relationships that you expect. How could you enforce thinking about... Okay. Right. With the schema. We are gonna come to that. If the PDF is multimodal data like like images, what happens then? So you would, if you had a more complex source source data, you would probably look to chunk that in different ways. Maybe have images as separate chunks and use a different embedding model for your images or tables and so on and so forth. Okay. I think most of these... A lot of these questions are relating to how do I define nodes and relationships? Believe me, we will get onto that. Where are we using the cipher in the IDE? So this, this cipher here is is is is just in GraphAcademy. You can run this directly in GraphAcademy. Your dev environment is connected to the same Neo four j instance that that, your GraphAcademy, course is connected to. Is it hard to understand Cypher once you know SQL? I think it's... The starting point is different. So so I find Cypher incredibly intuitive, but what you what you do is you is you define patterns of data that you are looking for rather than in SQL saying, I want data from this table and join these tables. So you describe patterns rather than sources. There are some great courses on GraphAcademy, particularly Cypher Fundamentals, which will which will help help you with that. What is the difference between a simple KG pipeline and manual code to build the knowledge graph? So the simple KG pipeline essentially just links together all of the knowledge graph build build components. You can build your own pipeline if you wanted to. Is there a file size limitation? Not really because essentially what you are doing is is that you are splitting that file down into into smaller bits. The limitation comes being the context window of the LLM rather than, you know, anything that Neo four j for j supplies. Where is the embedding model stored in the chunk node? Yeah. Let's have a look at that. So if we look, this is the chunk node that was created, and we can see for each chunk, there is a SIP, there is there is some text, and there is also an embedding. Structured data, we will come onto come onto. Why do I need to vectorize? It's so we can do semantic search, and we will come onto that later. Is the one we are viewing here, is the KG prepared on top of the PDF files? Yes. Yes. So I have built this knowledge graph as we have been in this session based on top of those, PDF files. Okay. Great. Thank you for the questions. They are super helpful. What I'm gonna do now is I'm gonna move on. So we've kind of proven the process. We know we know this works. But also what we saw, was that, actually we didn't get a lot of data out. We only got a couple of nodes. So one of the... So we're gonna start to iterate on this knowledge graph instruction. And the very first thing we're gonna do is we're gonna change the chunk size. So the chunk size, by default, the chunk size is quite large. And as you can see, we have one document, we ended up with one chunk. The larger the chunk size, the more context the LLLM has, but it often needs less granular data. So what we're gonna do is we're gonna modify that chunk size. So you have a task. Delete the graph. We're gonna start again. We're gonna create a custom fixed size size splitter. We're gonna modify the KG pipeline to use that fixed size splitter. We're gonna run it again and then we're gonna review what happened. Again, I'm gonna go through the process with you but all of the information is in the lesson for you to for you to do the process yourself. So just to recap, we're in this second module and we're on chunk size. So we're just gonna take some time to modify the chunk size. So we're going to reimport everything. Let's delete everything out of our database. There's only four nodes in it at the moment. But we're just going to delete everything and start and start again. So we're gonna need the fix the fix size size splitter. So what I'm gonna do is I'm gonna modify my KG builder to import the fix size splitter and I'm gonna create a text splitter. Now fixed size splitter is probably the... Wait, not probably. It is the simplest type type of chunking, mechanism. There are lots of different chunking strategies, by things like section or by content or by semantic meaning. But fixed size is, is pretty simple and is actually pretty effective as well. So what we're gonna say is we want chunk size to be 500 characters and we want an overlap of a 100 characters. So, the the second, chunk will have an overlap with the first and so on and so forth. So we create our our text splitter. And then to use it, we essentially just update our KG builder to include it as part of its, as part of its setup. So text splitter, use that fixed fixed size fixed size text splitter, and we're gonna run exactly the same program. We use the same file, and we're gonna ask it to create a knowledge graph based on on, on the same file that we did before and give us a chance to kinda look at where where the differences are. So, again, I've just kicked it off. It takes a few moments. It sends on... So it's gonna split that document. It's gonna send it to LLM, do entity and relationship extraction. But immediately what we see is we get a lot more nodes created. Right? So by chunking our our document, we get a more granular, dataset. And we can explore that by using Cypher. So like like, first of all, let's just have a quick look, so we can look at what chunks were created. So we can see, again, there's still one document which is this, generative ai, what's generative ai dot pdf. But we can now see that there are, I think nine different chunks. So this lesson has been split up into nine separate chunks. We have index one to zero to nine. And we can see there are back there are back, 500 characters. And once we've chunk chunked at chunked up our, our text, does the entity extraction. We can then look at the entities that this has created and almost immediately we can see that we have a more sophisticated or certainly a more granular graph. So let's just have a quick zoom in. So there is chunk number three here. So chunk three, Gen AI concept of text data generates human like text. Text data was related to this chunk here. Let's try and find, so, the Gen AI concept of generative AI generates GPT, and that was... So this entity was found in both chunk two and in chunk zero. So again, we can see how, by the impact that chunking has made on our knowledge graph. It has created something which is much much more, granular and has extracted significantly more entities. Okay. Right. Again, I'm just gonna have a quick look through, any questions, from the ones that we have here. Is it is it possible to use a customized matching algo for the node match instead of using the built embeddings and chunks? Yes. Absolutely. Every part of that pipeline... Remember that pipeline diagram I showed you? You can, you can change any part. There is also resolvers. So what resolvers do is is that... Is they look to find duplicates, essentially. Can Can we pay attention to explanations and still have access to the codec? Can we... Yes. Absolutely. Oh, Alex has has responded. Yeah. This course and all of the others are available to you. They are not going away. Okay. So, that was chunk size. A lot of the questions have, have been about, how do I define a schema? How do I give an give an ontology to my knowledge graph construction? So like up until now, the way that we have been creating this knowledge graph has been unconstrained. Meaning essentially what we have done is we've passed this text to the LLM with no other information other than find entities and relationships in in this text and just let it do its thing. It's it's actually not a bad idea for sort of exploration, but almost immediately what you're gonna find is is that it's gonna lead to a graph that is nonspecific, difficult to analyze and query. So what we are gonna do is we're gonna modify this simple KG pipeline to use a custom schema. So we can provide a schema to the pipeline that's gonna, instruct it to find specific nodes. So think people like person, organization, location, particular relationships. So, So, you know, person works at location, and also patterns. How those node types, so those node labels and those relationships are related to each other. So person works at organization, organization is located in location. So we can spend that time, defining what our schema is. And the output is is a is a is a set of entities and relationships that have been extracted from the text that match that schema. And it is the way to develop something that fulfills your use case. So again, same pattern as what we've seen before. There is a task for you to do. We're gonna start with this starter program, kgBuilderSchema. Just to kind of recap where we are in case people have got lost, we're in the second module here, and we're on define a schema. So we're gonna start with, this kg builder schema program, review the code, go through and actually define a set of nodes and relationships and patterns that are relevant to that data, modify, the simple kg pipeline to define it, run it, iterate it, refine it if you want to, and then kind of review the graph and observe how that schema influences the structure. Again, you... So if we look at the lesson content, we are here. This is your task. I will run through it as well, and then I'll I'll I'll take an opportunity to answer answer any questions while people are, are are are doing the activity themselves. Okay. So, we are gonna start with this program here, kgBuilderSchema. And again, it's, the same program that we've seen that we've seen before. We've got our connection to our database. We've got our LLM. We've got our embedder. We've got our splitter. And the simplest thing we can do in terms of defining a schema is essentially just defining a set of node types. So, you know, the content that we've got is all about, is is about generative AI and it's learning content about generative AI. So things that we might be interested from that content are what technologies are referenced, what concepts, maybe examples of how they're used, and and processes as well. So that's the kind of simplest approach we can take. We can just say just extract the node types for me. But we can do more sophisticated things. So, for example, we can, or specify more more node types. Yeah. But what we can also do is... So, for example, benefit. Just say we've provided no no other information other than the node type, but what we can also do is describe that node type. So we can say, okay. Well, I I want you to look for resource entities and this is what a resource entity is. You know, it's a related learning resource such as a book, article, video, video or course. Oops. Apologies. Book article or course. And what we can also do is say, okay. Well, for those resource nodes, these are the properties that I want you to find as well. So I want you to find a name, but actually I also want you to find a URL. So if there's a URL related to that resource, please, please return it. So we can make our node types as complicated as we want them to be. What we can also do is describe relationships. So we can describe nodes, we can also describe relationships. So these are relationships that I'm interested in. And then on top of that we can also describe patterns. How the nodes we are interested in are related to other nodes. So, technology is related to technology. We wanna understand how technology is related to each other. We wanna understand how concepts are related to technologies. Examples, how they are used in technologies. How a process is part of a technology. You kinda get the idea. But we can define a schema using these terms, nodes, relationships, and patterns. And we can be, like I say, pretty sophisticated in terms of how we define each one of them, each one of them. This example is pretty simple, but again, you can be as sophisticated as you think is appropriate for your for your use case. I'm just gonna go through the process of actually updating this program to not only just find these node types but find, all these node types and these relationship types. So I wanna find these nodes, these relationships, and these patterns. So I'm just updating my program to do that. And then finally, I need just need to tell the KG builder the schema that I want to use. So here's the schema, here's the node types, here's the relationship types, and here are the patterns. Now what I want to do is I want to run that program again because I want to observe the results that I see this time. I'm just going to delete my graph again. Let's, start afresh, just make things simple simple to, simple to see the difference. Okay. So I've update... I've updated my KG pipeline to define my schema. Let's give it a run. Again, I'm running it again with exactly the same document. What I have done now though is I have is I have defined the schema. And actually what we see is I get out a slightly smaller, number of nodes to, to previously when I had it un... Unconstrained. But if I look at my graph, so if I have a look at the entities that have been that have been created, I can see that actually now the entities that have been created are challenges, concepts, technologies, and examples. They are the the node labels that I defined as part of my schema. So now what we can see is, chunk number one. There is an example around image synthesis. Image synthesis is used in the technology generative AI. Code generation is used in the technology... Code... Cogeneration, as an example, is used in the the technology generative AI. So we have started to define or to create a set of facts, about our unstructured data that match a schema or an ontology that we have defined. Let's see see what else we can find. So here we go. Chunk number three. Concept of large language models is related to text text text generating models. So again we have defined that process. I'm gonna give you a moment just to kinda go through that and I will just have a quick look at any questions. Is there a similar embedder embedder for Anthropic? Yes. Off the top of my head, I can't remember what their, what their sort of semantic, embedding model is called, but I'm sure that... But I I... There is one. What is the roles of patterns in graph extraction? Wouldn't it be sufficient to only specify nodes and relationship types? You can only specify nodes and relationship types. If you do, you're essentially, leaving the LLM to decide how, the entities, and the relationships go together. And it may be that actually you don't want, so I was trying to find an example. How... You you don't want to know how examples are, how examples are part of processes As an example, that might not be something that you're looking to do. So patterns allow us to specify how, we want, how, entities are related to each other. But again just to clarify, I mean you can just express no types of relationships, and the pipeline will just use them, use them and find any pattern that it can. Okay. Right. Let's just finish off our knowledge graph, our knowledge graph. And we're gonna look at, adding structured data to our knowledge graph. So we are just here around add structured data to the knowledge graph. Again, I'm just gonna pop back to the slides. So let's add our structured data to the knowledge graph. So as we've seen, the graph we create at the moment is solely based on unstructured data. It would be unlikely that we would have no structured data about our data sources, you know, whether that's CSV files, APIs or anything else that's kind of relevant to our domain. So we're gonna look at how we can combine, some structured data alongside our unstructured data. So, in the repository, there is a CSV file that contains metadata about those lessons. So about the lessons the documents were created from. It essentially contains the file name, contains what course that lesson's from, what module it's from, its name, its lesson name, and also the URL to get to that lesson. So we've got some structured data. And what we are gonna do is we are gonna create this model. So we're still gonna have our documents. We're still gonna chunk those documents. We're still gonna have entities that relate to those chunks. But what we're gonna do is we're gonna create some structured data in this lesson node and, define a relationship. This document is a PDF of this lesson, and we're gonna store some structured data about that lesson. Okay. So similar processes before. We have a file to open. I want you to review the code, look at how it how it uses Cypher to create that structured data, run it, and then observe the results. And again, I will do the same thing and then we'll kind of look at look at any questions. Okay. Alright. So we are here. So what we're going to do is we're going to load this structured data. So this is programmed KG Structured Builder. So if we look at KG Structured Builder, again, it's gonna look... Start to look pretty familiar. We've got our connection to our database. We've got our LLM. We've got our embedder. We've got our text splitter. We've got our schema expressed as nodes, relationships, and patterns. And we have our KG pipeline. Right. So the first thing to note is, let's have a look at that CSV file. That CSV file has got our data in it. Yep. We can see. Got lessons. We've got URLs. We've got names. So we are gonna load in that c... That c s... That CSV file. And we're gonna define a cipher statement. So this cipher statement is the is, will create that lesson node, that structured data from that CSV file. So first of all, it matches the document. So we're gonna create the document using the KG pipeline. We're then gonna create a new lesson node and then we're gonna create a relationship between the document and the lesson node. So basically say this document is a PDF of this lesson. And then actually, what we're gonna do now is we're gonna run through all of these PDF documents. We've just been concentrating on one more. I've been iterating the process, but let's... Actually, let's do them all now. So we're gonna say for every document CSV file, use the k g k... KG builder to, to generate the unstructured data, and then create that structured graph using that Cypher statement. And then we'll see, see see what the results are. So this is going to take a couple of minutes to run while it goes through every single one of those documents and, and does the entity and relationship extraction. So I'm just going to give it a run. I'm going to kick it off and then we'll take this opportunity while it while it is running to look at any questions. Yeah. We can see it's kicked off, started off. It's processed document number one, found 39 nodes. It's gonna continue that process, of creating, of going through each one of those documents and creating our graph in the background. Alright. I'll leave that running. Okay. So where are we? Can you build an knowledge graph the other way around using mainly structured data? Yes. Absolutely. Yes. Yes. Absolutely. And, and more often than not, you have more structured data than you have unstructured data. We are concentrating on the unstructured part of this because it tends to be the more complicated aspects. But, yes, whatever structured data you have, you can use that to build your knowledge graph, in order to be able to support whatever use case whatever use case, you have got. So George asks, when a graph already has nodes with stable IDs from a structured source, and the LMA extractor creates new entities from text, how do I make sure that extracted entities to remove it to an existing role instead of creating duplicates? Does the resolver support matching on an existing ID or key or only unnamed fuzzy semantic logic? So, there are many... There are a handful of different resolvers as part of the package. You can build your own. Absolutely, you could build your own. So if you defined your, your, schema for your unstructured data to extract the IDs, you could build your own resolver to say, you know, match on ID and resolve entities, on, you know, on on a fixed ID from your from from your structured data. Is there a way to enforce schemas ontologies in Neo four j? So, so, not specifically a question relate relate to generative generative generative generative AI, but Neo four j by default is, we describe it as schemaless, so you can create any node label with any relationship to anything with any number of properties. However, what you can also do is use graph types and constraints, to say, to, essentially enforce a particular, schema within within within within your graph. Can we process documents in parallel or maybe there's some resource that would be a blocker? No. You can process document documents in parallel. The Neo4j database would certainly not be the blocker in doing that. Neo4j, fully fully ACID compliant database transaction management, all all of the things that you would expect. Instead of PDF, can we pull doc... Docs from Confluence? Yes. Of course, you can. You can pull doc... Documents from, any source. Typically, you know, if we're looking to do entity relationship extraction, typically, you would start with text. So, you know, providing you can convert it to, text, then then, then then that is fine. I said text. There are other method... Methods as well. But, yes, absolutely. There was something else I was going to say. I can't remember what it was there. Oh, what I was gonna say was, can we... Instead of instead of instead of PDF, can we pull docs from from Confluence? Yes. You can. The course, in the full online course in GraphAcademy, which goes through knowledge graph construction, actually has examples of, of different data loaders as well and how you can create your own. Okay. While while I've been talking, the process is finished and we have created, we've been through every one of those documents and created our graph. So let's just have a quick look at what we have got. I'm just gonna scroll down. So this... The structured data that we've added to our graph allows us to query in different ways. So this knowledge... So this query, for example, essentially says, okay. Well, I want you to match technology nodes where the name includes the term knowledge graph. So from our entity extraction, we're finding all of the technologies that contain the name knowledge graph. So we... From our knowledge graph nodes, we are going finding the chunks that those nodes are related to, finding the documents that those chunks are related to, and then finding the lessons, that those, that that those documents relate to. Essentially, allowing me to search for, using our our entities, lessons that relate to knowledge graphs. And I think there's an important point here. Not lessons that contain the term knowledge graph, lessons that relate to knowledge graph as a technology. So we'll just give that we'll give that a run. And, actually, we come back with... There are 12 records, perhaps not unsurprisingly. You know, this is a this is a course about generative AI and about knowledge graphs. And it has returned to us, well, first of all, this is the entity I found, knowledge graphs. This is the lesson, and here is the URL that we got from our from our structure... Our structured data. And, you know, if I was to go to that URL, it's gonna take me to that course, which is a lesson all about creating knowledge graphs. Where were we? We were here. Yeah. But again, we can see how this information is related. And let's change this. So rather than knowledge graph, we're looking for Neo four j. I expect this will return a lot of things. Eight... 16 records. Yeah. So this returns all of the all of, the courses that relate to the, to the technology Neo four j. The other thing we can do is we can use our knowledge graph to actually summarize the content of our lessons. So if we take this the other way. So if we say, okay, well, find all the lessons, find the documents that relate to those lessons, and find the chunks that relate to those, that relate to those documents. We can then use the knowledge graph to say, okay, well show me all of the technologies that are referred to in this chunk and show me all of the concepts that are referred to in these chunks being the two entity types that we extracted. And what we get back, I haven't deduced this so there will be duplicates. But we can see, for example, the lesson what is a knowledge graph, relates to the technology generative AI applications and also knowledge graphs. Let's take another one. The lesson, Vector Retriever, relates to the technology vector databases and the concept similarity search. So again, we can use our graph to not only go to find specific information within our structured data, but we can use it the other way around to understand, you know, in this case, the technologies and concepts, but anything that we feel is is is is important within our unstructured data. Okay. Sorry, I'm just looking again looking at questions. I think we're okay. Alright. So, let's just kind of recap where we are. We're just at the end of this, this this this module on knowledge graph construction. If you want to come back, there is a a nice optional activity that you can do where you create your own knowledge graph. So, you know, find your own text text data, go through the same process, define a schema, and then create your own knowledge graph as well. Alright. Great. But what we are going to do is we are going to move on to our third module, which is all about retrieval. So we're gonna use our knowledge graph to retrieve information, using both vector rag, vector rag, vector plus cipher rag, and we're also gonna create a vector... A text to cipher retriever as well. Let me just make sure there's, any questions. I think we're okay. I think we've gone through the majority at the moment. Alright. Lovely. Okay. I'm gonna move on then. We're back to our slide view. Again, optional activity to create your own knowledge graph. I would really encourage you to do it. It's a great way to understand your data and see how you can create a graph from, from unstructured data. So retrieval. We've created a graph. We should look at how we get data out of it. So the first thing we're gonna do is we're gonna look at vector rag. So we had a look at retrieval augmented generation and the role of retrievers. Right? One of the challenges of RAG is understanding what the user is asking for. Right? So the user typically provides a question, a query, a prompt. Yeah. And we need to use that prompt, that question, to find the correct information that we can pass it to to the LLM. And one of the ways of doing that, is through vector rag and using semantic search. So what we are gonna do is we're gonna explore how that works. So when I say semantic search, again let's define some terms. I'm talking about using search to understand intent and contextual meaning rather than focusing on the individual keywords. So, you know, traditional search focuses on exact match or proximity based algorithms to find similar words. So the example I use quite a lot is, is is apple. If we search for apple, we might get back, results about fruit. However, in semantic search, we are trying to gauge the intent. Actually, are we searching about fruit, the tech company, or is it something entirely different? So the intent is what, drives a semantic search. And we can type... Tailor the results, based on that term and whatever we consider the perceived intent to be. And in order to be able to perform semantic search, we represent our, our data as vectors, as a as a list of numbers. Right? And the more numbers we have, the higher the dimensionality we have. The higher the dimensionality we have, the more fine grained we can be. But also the more dimensions we have, the more expensive it is computet... Computet... Computational. So we've used the word embedding quite a few time... Quite quite quite a few time... Times. And when we use the term embedding within, you know, machine learning, NLP and now, you know, generative AI, what we're talking about is vectors that represent, data. So for example, images, text, audio. Right? And if we create vectors based on our data we can use that to compare two paragraphs of text or two pieces of text to each other. Right? So again going back to that word for, going back to that word apple, if we create a vector for the word apple we can find out how related that word apple is to fruit, technology, color, taste, shape, whatever. Right? And the the way that it does that is if we have two, two sets of vectors for two different words or phrases or or documents, we can measure the distance between them or or the angle as well between them. And words or phrases with similar meanings will be closer together and unrelated things will be further apart. So that's how we can use vectors in order to be, perhaps how we can use vectors in semantic search by creating embeddings for each of each of our pieces of text and seeing how close they are to to to each other. So, semantic search is often employed in vector based RAG and we use it to find contextually similar information. Right? So the way that we do that is we take our source data, we push it through an embedding model, we create an embedding for it, and we store that in a vector index. And we have already done that. Our simple KG pipeline did that. Our source data was our chunks, our embedding model was OpenAI text embedding model, and we stored that against a chunk node as an embedding property. And the process in terms of vector based rank looks like this. So a user asks a question. We use the same embedding model to create a vector for the question. We then compare the question to all of the vectors for for, that we have stored. Yeah. And we, and we return them based on how similar they are to the original question. We then use that to enhance our prompts to, to, provide additional context to the LLM. That is traditional vector based rag. And that is what we are gonna do now. We are gonna build a vector, a vector based rag retriever. So just to kinda recap where we are, we are here. We're on vector plus cipher retriever. We're gonna build one, using that graph rag for Python package that we have been using. Alright. So as we've seen, the chunks in the knowledge graph include vector embeddings. We did have a look at them but, you know, we can... We just say, you know, match c chunk, then find all the chunks and then return return them, say, limit 10. Let's get get the first 10 back. If I select a chunk node, we can see that it has this embedding. This embedding was created by that embedding model as we were building the knowledge graph. Now in order to be able to use, use, those those embedding properties, we need to create a vector index on top of it. A vector index allows us to very quickly search, search search those embeddings and do similarity checks between them. So I'm, create create a vector index. We can see it's gonna be called chunk embedding. It's for the chunk nodes. It's on the embedding property. And we set some, some options. This is the number of dimensions that are in that, that are in that embedding, the number of numbers. Yeah. And we also define a similarity search we wanna use, cosine typically, so cosine or Euclidean. Cosine, very good for semantic search. But I'm just gonna run that to create my index. It doesn't return anything but it does say one index added. So I now have a have a vector index that I can use to search again. Now we can actually search that vector index just using plain Cypher. So what I wanna do is kind of go through this process of showing you how you can create, a, an embedding for a question. In this case, the question is retrieval augmented generation. Then use that embedding to search that vector index to get back some semantically similar information. Okay. So let's just copy that query. Now if we look at this query, it's broken into two halves. The first one is creating an embedding. So we're gonna create an embedding for this, for this piece of text. And then they're gonna use that embedding to then search our vector index and then finally return the text of the chunk and the score, the score being how how similar they are. Now, I do need an OpenAI API key, because I'm gonna be using OpenAI's model or we can use the same API key that we've been using, in our Python program. I'm gonna pop that in there. And let's give it a run and we'll see what happens. So, I mean, pretty quickly it came back and said, okay. Well, based on the embedding for retrieval augmented generation, here is, five chunks of chunks, chunks, chunks of text. It's five because I specified a limit of five. And the first chunk that came back, so it's ordered by score, is a lesson on retrieval augmented generation, the RAG process. Right? RAG process typically involves three main steps, understanding user's query. So that is absolutely relevant. Now the score is a score between one and zero, one being exactly the same so the vectors are the same. Z... The fur... The the lower you get, the the further apart they are. The next one, is with a score of point eight one. What is rag? Graph RAG, let's have a look. The fourth one with a score of point seven six, so is about response generation. It... There is a... It does reference a diagram showing a RAG process. But interestingly, one of the things that I think is interesting about this fourth result that's been returned, it doesn't mention the term retrieval augmented generation at all. It is semantically about the same thing though because it is about the, the LLM rag process. So... And we can change this to whatever we want. So, like, what is hallucination? And I'm gonna get back, chunks of text that relate to hallucination. In fact, we can see this is the, this is the example that was that was in this workshop. Okay. So, that's how we can use vector index. That's in in Neo four j. What we're gonna do now is we are gonna create a vector and Cypher graph rag pipeline. Again, same process as before. We have some starter code. In this case, it's this vector cipher rag program. I want you to review how it works. What it's gonna do is it's gonna do a vector similarity search, find the most relevant chunks for a given query, and then return some data. Again, I will run through the same process. I might actually have a quick look at at any questions before, before I do that and then we will. But again, you can continue with the lesson. So if I just go back to this lesson view to recap, we're in this third module on vector and cipher retrieval. You'll have to create the vector index and then you can, if you want, you can use Cypher to reach... To search it, and then this is the activity to create a vector plus Cypher graphite pipeline. Okay. So we had a question about about about, about different languages. Thank you, Alex. Great great response. And most modern modern LLMs tend to be multilingual. How can the embedding vectors, in Neo four j be encrypted? I suppose there are multiple methods for that, probably. The simplest being you embed them, you encrypt them yourself. However, you are probably gonna find, that it is diff... It is difficult to, do vector search on on them once they are encrypted. My... I don't know your use case. My point of view is is that, essentially, embeddings are essentially unreadable anyway. Right? You know? You can't take an embedding and convert it back to its original text. It shows an error when I create a vector. Maybe I missed a step. Can you tell me that... Maybe if you give an indication in terms of what, what your error was. In order to create the vector, you will have had to have created the knowledge graph. Is it easy to keyword search nodes and combine results from vector search? Yes, absolutely. You know, we are gonna cover it cover it in this but one of the retrievers, in the the GraphReg package is called the hybrid retriever and it does exactly that. It does vector plus full text search, retrieval. What did we use to create the vector index, the same text from the last exercise? So to create the vector index, you can run this piece of Cypher here. To create the embeddings that were created on chunks, that was done as part of the simple k... KG pipeline. Is there a way to compute a hybrid lexical semantic search retrieved by that? Yeah. I mean, one of the things that we'll see when we, create, more sophisticated retrievers, is the way that you can order it by different things. What is the negative side of GraphRag? I mean, that's an interesting question. It is it is more computationally expensive, and you need a graph in order to be able to do that, which means is that you're you're thinking about how about how you model model your data. If you only have simple use cases, maybe you you don't get the benefit from it. But for anything more than simple use cases, GraphRack tends to yield better better better results. Can I pre filter the semantic search by properties of nodes linked to the chunk? Yes. Absolutely. When we do the search here, you can include a where as part of this. Right. Let's go on to the exercise. I'm gonna do the exercise as well. So we're just gonna do this vector cipher rag retriever. There's so many things open. Let's just have a tidy up again. So we're gonna look at this vector plus cipher, rack retriever. So let's just have a quick look at the code. So we can see, again, with our connection to our database, we have an embedder again. We need to use an embedder because we're gonna turn our query, our users query, into an embedding to be able to search the vector in there. We have a retrieval query. The retrieval query is the data, that we, return from our vector search. In this case, it's just the nodes text, the chunk text, and the score. Then we create our retriever. So our retriever needs the database that it's working with, the index name, the embedder, and that retrieval query. And then what we are gonna do is we're gonna wrap this retriever, in a GraphRack pipeline. So essentially we can ask it a natural language question. It's gonna run the retriever and it's gonna pass that it's gonna it's gonna pass that question and the context to an LLM and give us back, and and give us back a response. So that's why we create an LLM, create our GraphRag pipeline, we give it a query and then we use it. So we use our GraphRag retriever, pass it in the text that we want, and then we we should get a response back. So let's just give this a run. So the question is what is a knowledge graph and where can I learn about them? So we're gonna run it, it's gonna do that vector retriever, and it's gonna return some information. We are getting an error back about a deprecated warning. Yeah. It's a... It's an issue with the the GraphRag pipeline, at at the moment. So... But we asked that question. Here is the response. A knowledge graph is an organized representation of real word entities, things like and relationships. You can learn more in this blog post. Right? And one of the things we can do is, as well as printing out just the answer, let's actually print out the context as well because that's gonna allow us to see, actually, you know, based on the question and the context it was given, how did the LLM come up with that come up with that response? So, it's quite... It gets a little bit difficult to see but here is our response and here is our context. So what is a knowledge graph? And we can see that it's returned, some text and a score. And this is essentially what came back from our vector retriever. So how do we make this into a graphRAG retriever? At the moment it's a relatively simple vector retriever. We can do that by enhancing our retrieval query. So going right back to the kind of start when we talked about, you know, the classic graph rag retriever, what we do is we use vector search to find nearby nodes and we then traverse the graph around that to find other information. And we do that practically by, by applying, by updating a retrieval query. So our retrieval query is going to, well, sorry. Retrieval query currently just returns the chunk text and the score. What we're gonna do is we're gonna use our chunk to find what document is part of and to find what's... What lesson is part of. So we're gonna use that, use that structured data. So we're gonna return the chunk text and the score, but also the lesson URL. So a direct a direct link to where that lesson came from. And then we're also gonna use our knowledge graph to say, okay, well, what technologies does that relate to and what concepts does that relate to? So we can turn this relatively simply into a GraphRag Retriever by using our graph to provide additional context. And, yeah, let's use the same question but let's run it again. I am just gonna clear this because it's getting a bit messy. Let's give that a run. So let's just have a quick look and find out where our response is. So our response starts here. A knowledge graph is an organized organized representation. Right? One of the first things that I note about the response that we have now is we now have additional information about where I can learn more. So the most key one being, you can learn more in this Neo four j Graph Academy lesson. That piece of information wasn't prevalent in the response that we had before before, we added in the graph the graph query. And it's got that from our our structured data. It's got that from, the lesson the lesson URL. And if we look through, so here's our retriever results. We... Again, we have the text which is the the chunk text. We also have score. We have the lesson URL where it came from. And we also have the technologies that that are noted and, and the concepts within within within those within those chunks. So what we've done is we've used that graph to provide more sophisticated information in our search. There are other things that we can do. So for example, you know, rather than the kind of relatively simple simple, we can use our graph as well-to-do like a generalized a generalized search. So what I mean by that is we can use our our knowledge graph to define facts. So for example, these... The technology GraphRack for Python leads to the benefit of faster ship new features and high performing and high performing patterns. The process of GraphRag pipelines is part of the technology GraphRag for Python. This... I just scrolled randomly down. That's one of the one. The resource Neo4j documentation cites the technology Neo4j. Now this is, these are entities and relationships, relationships that essentially cite facts within our knowledge graph. So we can use this more sophisticated retrieval pattern as part of our, part of our retrieval query. So let's take our retrieval query and we'll again make it more sophisticated. So we're using our graph in different ways. One of the things that, that you can also do, as part of GraphRag, at the moment, our results are always, ordered by the score from the vector, from the vector search. You can change the order by applying an order by as well. So that allows us to actually change the way that results are returned. Until I change the priority by which results are returned. And again, I can run the same query, and we start to see, again, more sophisticated context being returned. So, for example, this one here, was had... Interestingly, I have no associated entities. Okay. Here we go. So this record here, you can learn more in the Neo4j blog post, had the associate entities of process constructing knowledge graph as part of the technology knowledge graph. So we can start to add this additional context to our graph to allow it to, generate more sophisticated responses. So there are like some other examples here that we can try. So let's change our question. What is hallucination and how can I avoid it? Again, let's look through this barrage of tech... Barrage of text. So hallucination is a... Is when a generative AI model, content sounds plausible, it's misleading. To avoid or reduce, hallucination, provide more context in your prompt, use rag, be aware of LLM limitations. Yeah. So we can use our graph to create more sophisticated context. Just a quick time. Okay. I'm gonna take a moment, while you explore that just to have a look at some questions. So questions come up... That's come up. Do you have a multimodal example? Not as part of this workshop. No. I will signpost you to, another GraphAcademy course, that is called, introduction to unstructured data and vector indexes. And actually part of that course, there is an example using images, and doing semantic search to find similar images as well. I think... Let's just have a quick look. Okay. If you have other questions, please please put them, put put them in, the tab. More than happy to to try and answer your questions. Okay. So, what I'm gonna do is, let's move on to our last, example which is, creating a text to cipher retriever. So, text to cipher... The text to cipher retriever. So essentially what we're gonna do is we're gonna create a GraphRag pipeline, where we can answer natural language questions by generating and executing Cypher queries against our against our knowledge graph. Now Text2Cypher is particularly useful if you want to get precise information out of your graph. So for example things like how many lessons are in a course, what concepts are covered in this module, or like how does this technology relate to this to this technology. And we are gonna, create a text decipher retriever and use it to answer questions, about the data in our knowledge graph. So again, same process. I want you to open up, open up this program. There's a program called text to text to cipher rag. I want you to review the code, have a look at how that text to cipher retrieval works, and there are some examples for you to run and kind of explore. Again, as we're kind of online I'll take the opportunity to actually go through the activity as well and talk you all through that process. So I'll go to the lesson view. We are here, we're in this third module retrieval and we're looking at this text decipher, retriever lesson. So, let's open up this program. And we'll spend a moment just having a look through. So, again, I'm sure some of this is starting to look familiar. We have our connection to our, Neo4j instance. We have an LLM. So our LLM actually in this example is gonna be doing two things for us. The first thing it's gonna do, is we're gonna use our LLM to turn our natural language question at the question that that that our user gives us. We're gonna use that, to turn that question into a cipher statement. And and the way the retriever does that is that it passes to the LLM the question and the schema of the graph. And by using those those those two things, it constructs a cipher statement that matches the query, that that that that the user passes in. One of the things that we can do to help support that process, is that... Is we can provide examples. So if the user inputs find a node with the name... Parameter name, use this type of query. Now these examples are not specific. The user doesn't have to put in find a node with the name, right? Essentially what we're saying is, saying is if you see queries like this, use this matching type type type of Cypher. And essentially what I'm doing through this is through this example is saying, you know, if you're looking to find a node by name, match the node but use a case insensitive search. So use to lower and use contains. Yeah. So we're gonna, use case insensitive and say basically just this name contain is contained within this name. So essentially I create a much more fuzzy, fuzzy search by using contains until lower. Interesting, I could use a full text index here here here here as well. But essentially what I'm doing is I'm giving... Is is I'm providing examples to the Text to Cipher Retriever about my data and about how it can use my data. So I build my retriever, right? I tell it, here's my connection to my database, Here's the LLM I want you to use, and here's a set of examples. In my case, there's... There is there is just one which is this how to use, in set... Case in in, insensitive search. I create my rag pipeline. So my rag pipe... Pipeline is the thing that glues my retriever to an LLM to gain a response. So I give it I give it my retriever and I give it my LLM. I define my question, how many technologies are mentioned in the knowledge graph, and I use my, my GraphRag pipeline to search. Now what I'm gonna do is I'm gonna print out the response. So I I wanna see the response, the ultimate response that comes back from the LLM. But I I also want to see, the cipher that was generated. Yeah. So to... What cipher statement did it did it generate from from that text? And also as a result of running that Cypher statement, what context did we get back? Again, let's just clear this and let's run this. So we're going to run that process, going to pass that pass that query how many technologies are mentioned in a knowledge graph. So here is our ultimate response which is 96 technologies are mentioned in the knowledge graph. And actually we can see that the the Cypher statement it generated was relatively, simple. Match technology nodes, return account as the technology count, and the context that that LLM received was this record of a technology count. Right? And then constructed con... Constructed our response. And then constructed our response. And like I say, text decipher, very good if you're looking for specifics. So how many, what about this, and there are some examples that we can explore. So how does Neo4j relate to relate to other technologies? So we'll use this example as well, give this a run. Sometimes I don't press the button. How does Neo four j relate to relate to other technologies? And again it's gonna use the same process. It's gonna use that natural language question along with, the schema. So the schema gets passed to, to to the LLM. So our ultimate response is, Neo4j is connected to several other technologies and concepts in the context you provided. It's graph database, closely tied to Cypher, often used for... In RAG and the Gen AI ecosystem. Related technologies relate to vector search, vector cipher retriever, so on and so forth. Some pipeline components that you might find interesting, and here's some related tooling. And based on that question, it generated this Cypher statement. So match the technology. We can see where it has taken, my example around if you're searching by name, use case insensitive search. To lower, the name. And it's then used an optional match. So it's basically saying I found the... I find the technology in Neo four j and then go and look for how that's related to other technologies, other concepts, other benefits, related challenges, and where it's part of a part of other processes as well. And then we can see that it... That that the context it retrieves is, well, the technology Neo four j, knowledge graph is related to knowledge graphs and, the technology Neo four j is related to vector cipher, so on and so forth. So we can see how it has taken that natural language query, it's taken the, schema that we generated to generate cipher and then ultimately return a a... Ultimately return a response that matches the context within our graph. Okay. I'm gonna take a moment just to read any queries. Any questions? How do you continue to add incremental data to context and generate graphRAG? Do you have to run the whole process again? Absolutely not. I'm pretty sure. Yes. Yes. Alex has come back and said the same. No. How do I attach policy to a node for governance? I'm... I think what you mean is how to how do I, maybe constrain. So for example, a particular node type has to have, an ID field that has to be unique. I'm guessing that maybe fits fits fits fits your use case in terms of governance. You do that through constraints or you do it through graph types. You know, constraint would be a, if a node has this label, it must have an ID field, and that ID field must be unique for every other node that has that label. Do you have any notes on evaluation? How should we evaluate our GraphArig system, and do you experience create... And how... And do you have experience creating synthetic datasets? So as part of this workshop, no, we don't go go go into into evaluation. My my sort of first leaning point would say would say is, I I would use the same processes to evaluate a GraphRack system as you would for any other, I'm guessing you're talking about Agentic systems, any other, Agentic systems. Do you have any experience creating synthetic datasets? Interestingly, yes. One of our, and the reason I have experience is that one of our courses that's about to be replaced is our graph data modeling course. And as part of that course, you, look to define your own data model as part of that course, and, GraphAcademy creates synthetic sample data for you as part as part of that process. Would adding a detailed description of the schema that is purpose of each node relationship increase the accuracy of Cypher query, translation? I... Yes. But I don't think in the way that you that that that you mean. If we define a schema when we create our our knowledge graph, it is more likely to contain nodes and properties which we, have picked and are consistent and, hence, you will get a better result from your site... From your Cypher generation. The things that you can do, we don't cover it in here. The Cypher Retriever. You can also express a schema to the Cypher Retriever. So at the moment we're just using it, we're using it in its default state and what it does is it... Is before it does the, the cipher generation, it queries the database and says give me the schema. You can provide a schema to the cipher... Text text to cipher retriever as a way of providing additional information which, yeah, absolutely can can can improve the output. One of the things I would say is for very large, very complex schemers, it's often quite useful to have multiple text decipher retrievers that concentrate on specific areas, of the graph and and, you know, use an agent flow, to say, okay, well, use a text decipher retriever if you're use the customer text decipher retriever if you're looking for customers, accounts and products. Use the sales text decipher retriever if you're looking for sales, sales agents or transactions or something. Yep. But yeah. So, yes, you can absolutely define a schema as part of your text decipher retriever and by providing a better schema in your knowledge graph creation will ultimately lead to better query performance as well. Another question about, could you share the repo? Thank you, Alex. Yeah. You'll find it, in, in the course. It's it's it's just it. Alright. Lovely. Okay. So we have reached the end of what I wanted to cover in this in this workshop. We have spent some time looking at what generative AI is, understanding RAG, understanding Graph RAG, constructing a knowledge graph from structured and unstructured data, and then creating retrievers that allow us to be able to, retrieve data from that knowledge graph. There is a final module here on agents, where you can, create an agent that uses those, the the retrievers, that you have created through this through this, workshop. I'd encourage you to do that. It's a really great great way of sort of bringing everything everything together. There are just a couple of things that I need to say before I hand back to, back to Alex, and I will just have a quick skim over just to say... See if there are any other questions. So, final question. So creating the right ontology first is more valuable. I would say, understanding your design, yeah, and, understanding understanding your schema before you start. So understanding your use case is is essential in order to be able to, you know, create a good data model that, that allows you to query efficiently and effectively. What I would also say say is, this is not a one stop shop. So you you will never be in a position where you can define your schema, define your ontology, define it once and it sticks forever. It should always be an iterative process. And I think actually that's where a lot of the a lot of the features within Neo four j for supporting very, very flexible data models will help you iterate on on that. So I wouldn't stress too much about doing huge amounts of design work. I would iterate on that process first of all. Okay. So, yeah, last few things I wanted to talk about. So a plug for GraphAcademy. You have been using it. You have seen me use it as part of this workshop. You will find a lot of courses, that relate to not only generative AI but also to, Neo Neo Neo4j more generally. It is completely free. They are all hands on. They are all practical activities where you do things, do do things to learn. There are lots of learning paths. You know, so if you're interested in generative AI or you're interested in, perform... Writing performant queries, there... You'll find learning paths paths that that will suit you. Also things like graph data science as well. There are free certifications. So, you know, gain your Neo4j certified developer certification as well. And then sort of finally, I just wanted to finish with, this is Rotor Nodes. This is, the start of a series of workshops. Our nodes conference, starts in... I'm sorry, Alex. I'm getting feedback from you. It's very noisy. Oh, really? Yeah. I'm sorry. I do apologize. So, yeah, so, Node's twenty twenty six. It's on November 12. As Alex introduced, there are these sessions leading up to Node, every Thursday, for the next four weeks or three three after this one. It's entirely virtual, entirely free. Come along, and, we would love to see you there. And I think with that, with sort of six minutes to spare, I'm gonna hand back to Alex. Perfect. I hope the feedback is gone. Yeah. Thank you very much, Martin. Thank you very much, everybody, for, attending today, for running with us through the workshop, through the hands on exercises. I hope they were valuable. The workshop on GraphAcademy will be available for you, obviously, as long as you would like it. There are plenty of other courses as Martin showed. So, if you're more interested in driving into this, explore the other workshops. We are doing more Road to Node workshops. This has been the first day, so we haven't missed anything. Next week, we'll do how to prevent hallucinations with Elizabeth on Thursday. So, if you're interested in that and if you haven't registered, please go to the router notes workshop site. As I said in the beginning, everything will be there also on demand. So, if the timing doesn't work on some of the days and you want to watch something afterwards, you can always go there and look at the videos. And, yeah, thank you, Zaid, for answering questions behind the scene, for for joining us today as well. And, yeah, take care, everybody. Have a good rest of the day. Thank you for, for joining. Thank you very much, Martin, for a great, workshop, today and an excellent presentation. And, yeah, see you soon. Take care, Thank. you all very much. Goodbye. Goodbye.