← All AI Engineer talks

AI Engineer World's Fair 2025

Intro to GraphRAG

About this talk

Neo4j product specialist Zach Blumenfeld leads a hands-on introductory GraphRAG workshop covering hosted Jupyter setup, knowledge graph construction from structured and unstructured data, Cypher queries, graph pattern matching, vector search, embeddings, and community detection. Exercises explore resume-derived graph data and conclude with references to Neo4j MCP servers, ADK examples, and further knowledge graph construction.

Chapters

  1. 0:00Workshop introduction and hands-on environment setup
  2. 11:56Graph construction, Cypher queries, and retrieval foundations
  3. 38:29Community detection, graph schemas, and agent patterns
  4. 55:17Resume ingestion, graph updates, and later workshop modules
  5. 1:18:01Closing resources: Neo4j MCP servers and ADK examples

Talk transcript

  1. 0:00

    [upbeat music] So as you come in, we have here a server set up with everything you'll need if you wanna follow along.

  2. 0:23

    You should have gotten a Post-it note. If you don't, just raise your hand and my colleague Alex over here will come find you and we'll provide you with one.

  3. 0:31

    Uh, basically what you're gonna do is you're just gonna go, if you have a number one sixty or below, you go to this link here, the QR code on top as well.

  4. 0:41

    Um, and if you have a number that's two oh one or above, you go to the second link or the QR code. From there, I'll give you some directions.

  5. 0:48

    You're gonna have to clone a repo, um, and then you're just gonna have to move an environments file over really quick. Also, for everything in this deck, I did create a workshop GraphRAG intro Slack channel, so if you're part of the AIE, uh, Slack group, you can also go there and just grab this deck, um, and, you

  6. 1:05

    know, get the links or however, however you'd like to do that. So we'll get started here, I think in just a couple of minutes.

  7. 1:11

    How about the-

  8. 1:12

    Oh, right. So your... Sorry. Your nu- your number will give you your username and your password. Basically, it's attendee, all lowercase, then your number. That'll be both your username and your password when you sign in.

  9. 1:34

    The other link that you should try to open as well is the, um, browser preview, but I'll walk you through that here in a second. I'll give it just another minute here for everyone, uh, to file in and get situated.

  10. 1:50

    Sorry, what is the username and password?

  11. 1:52

    The username and password is gonna be attendee, all lowercase, and then the number that you have. Both the username and the password are the same.

  12. 2:01

    Is that a great question if these are gonna be live, um, after the session, the notebooks?

  13. 2:07

    So the notebooks, uh, the servers will be down, um, after the session, but we-- you have the GitHub link you can go back to. Um, so the code is, is there for you to use.

  14. 2:18

    Um, it's just that the environment won't be available afterward.

  15. 2:20

    Okay.

  16. 2:27

    All righty, so I'm gonna go ahead and get started here. I'll leave this screen for a second, so if you wanna grab the QR codes here, now would be the time to do it.

  17. 2:36

    Um, obviously, you can go to the Slack channel and also pick up this deck.

  18. 2:41

    All righty. So we're going to do an intro to GraphRAG workshop today. Um, I was debating what to actually put in this workshop since everything's changing so quickly, um, and some of my colleagues convinced me not to make it too complicated.

  19. 3:00

    So this course is gonna be very much an introductory level course. Um, if you wanna look at sort of more advanced GraphRAG techniques, integrations with things like MCP, we have that at our booth.

  20. 3:13

    Um, and we have some other things that we're doing, other events, um, tomorrow that will go over some of that stuff, and I'll have links to all of that, uh, as we go through.

  21. 3:21

    But basically, what we're gonna do is we're gonna get everything set up. Hopefully, that should only take a few more minutes, and then we have three modules. We're gonna go over some graph basics.

  22. 3:31

    We'll be using Neo4j today, so it's a graph database. Just how to query that, kind of how to, you know, construct, um, your logic to retrieve data. We'll go over, um, another module on unstructured data, um, and how to do entity extraction.

  23. 3:52

    People already know about Neo4j? Can we get a quick show of hands real quick for that?

  24. 3:55

    How many people know about Neo4j? All righty. How many people have, by the way, used Neo4j, like have written Cypher queries?

  25. 4:07

    Okay, so some folks in here. And then how, how many people have used LangChain before?

  26. 4:13

    Okay. So, so a fair number of you. Okay. That's good to know. Um, and then in our, in our third module, we'll actually go over, we'll use LaneGraph. We'll build a very simple agent that will use some retrieval tools, and you'll get to see how some of that works, and we'll wrap up after that with some resources.

  27. 4:29

    So make sure to ask questions straight away. Raise your hand. I'll stop intermittently. Um, we only have eighty minutes, though, so I wanna make sure if you do have a question, um, go ahead and raise it and we'll get that answered 'cause we're gonna be moving through the material, um, a little bit quickly.

  28. 4:44

    Um, as I said before, we have two Jupyter server set up, so you don't need to pip install anything. Um, you can go ahead and connect to these notebooks.

  29. 4:53

    Attendees, I already explained, you should have a number. If you don't, go ahead and raise your hand. Um, the username and password is just gonna be attendee followed by your number.

  30. 5:02

    One sixty and less, you go to that first link. Two oh one and larger, you go to the second link. Um, there's also, I-- if you can, go ahead and open browser.neo4j.io/preview.

  31. 5:14

    Um, I'll show you in a little bit. You're gonna log into that as well. That will let you visualize the graph a little bit better as we start putting data inside of it.

  32. 5:23

    You said to raise your hand if you don't have a number?

  33. 5:25

    Yes.

  34. 5:26

    Okay.

  35. 5:27

    All right. So Alex, um, if we can get a number over here.

  36. 5:36

    All righty. Once you're inside of your environment, what I want you to do is these two commands. So you're gonna open up a terminal window in Jupyter. You can do that by pressing the little plus sign.

  37. 5:50

    I want you to Git clone. The command should actually be in the README. It should say Git clone, and it will give you the link to the repository that you need to clone.

  38. 5:58

    And once you do that, I want you to copy the workshop file over into that GenAI workshop talent folder. That environment file, ws.env, is gonna have information to a database that's already set up.

  39. 6:11

    It'll also have an OpenAI key inside of it that we'll be able to use for the workshop.

  40. 6:18

    So just to show you what this looks like, um,

  41. 6:24

    if I go over here and I look at my, my terminal, right? I've already done this.

  42. 6:31

    Make this a little bit bigger. You just go ahead and Git clone.

  43. 6:36

    Um, if you go to the README that was, um, in the main folder, this README here, it has the, uh,

  44. 6:45

    the, um, the GitHub URL. So you just basically go Git clone, um, and then... Oops. And then after that, you just copy that workshop file into that GenAI workshop talent directory.

  45. 7:00

    So you'll get this GenAI workshop talent. It's like a subdirectory in here, and you just have to copy that file, and that will have, um, resources that you'll need to log into, uh, the browser and for you to connect to your notebooks.

  46. 7:14

    The other link, um, that is inside of that deck is this browser.neo4j.preview link. Um, basically that will give you a way to visualize the graph. So what you will do, if I go ahead and disconnect, um, and maybe I,

  47. 7:32

    um, go to connect to an instance. So you should get a screen that looks like this, and then that workshop file will have... And it should actually be the same thing for you guys.

  48. 7:41

    It should be the attendee, the number, and then the same thing for the password. So go ahead and make sure you do that because then you'll be able to visualize the graph a little bit better.

  49. 7:54

    Any questions so far?

  50. 7:56

    Yeah. What's the login [keyboard clacking] for the Jupyter environment?

  51. 7:59

    So for the Jupyter environment, if you got your number, it's attendee, all lowercase,

  52. 8:05

    and then your number for both the username and the password.

  53. 8:12

    Sorry, where's the connection URL for this?

  54. 8:17

    Um.

  55. 8:18

    It's in the WS, WS.env or dot one. Okay.

  56. 8:22

    Yeah. WS.env for the, for the Neo4j browser.

  57. 8:26

    Thank you. Sorry, JupyterHub is what? Jupyter Notebook?

  58. 8:32

    So it's, um, right here. So it's basically going to be your username... Or sorry. It's going to be the attendee, all lowercase, so then the number that you receive for both the username and the password.

  59. 8:47

    That's it?

  60. 8:47

    Yeah. And if, if you, um, wanna come back to this, if you have, if you're connected through Slack, the workshop GraphRAG intro, you can go there and you can pick up the slides as we move on, so then that way you just have a constant reference back to it.

  61. 9:05

    Um, so while everyone gets set up here, I'll talk a little bit about just what GraphRAG is in general to kinda motivate what we're doing here. So this is, um, an architecture actually, um, that represents what some of our customers do.

  62. 9:20

    It's a very common, um, architecture for GraphRAG users. It's generalized. And basically, the idea is that you have your agent over there, you have your AI models and your, your UI.

  63. 9:32

    So like all the normal things that you might think of if you're putting together a knowledge assistant. Um, but then there's this knowledge graph thing in the middle, and that knowledge graph thing you can ingest both unstructured and structured data into that.

  64. 9:44

    So unstructured being things like documents and PDFs and that sort of stuff, and then structured being tables like CSVs or stuff from a relational database or what have you.

  65. 9:54

    Um, and so there's a big question of like, "Well, why in, you know, the heck do we need this like knowledge graph thing in the middle?" Right? Like we have agents, we can have tools, and we can go pick stuff from data sources.

  66. 10:07

    Um, and so the idea with this is that if you have a use case and you kind of know the types of questions that you wanna answer with your agents, by taking your data and decomposing even a very simple knowledge graph to start, um, you're gonna be able to expose, um, a lot of the sort of domain

  67. 10:24

    logic that you'd want to apply through the model of your data. Um, so the idea is like we'll see when we build a skills graph, we'll make some relationships about people knowing skills, and by making that schema available to the agent and making tools available to the agent, um, you're gonna be able to have a lot more

  68. 10:40

    control over how data is retrieved, more accurately explain the retrieval logic better. Um, and we see this as especially important as we start moving more and more into this agentic world, 'cause it's not like a one-shot vector search anymore, right?

  69. 10:54

    We're starting to see that now when we get questions or prompts handed to, um, an agentic workflow, those start to get broken down in various ways. Um, and when you have a knowledge graph, it just lets you, um, offer retrieval logic to complement that in, in a, in a much more, uh, simple and, and in my opinion,

  70. 11:11

    a better manner. And today we're gonna be looking at a skills and employee graph. Uh, so basically what we'll-- The use case we'll be looking at is you're building a knowledge assistant to help with things like searching for talent, aligning and analyzing skills within an organization, um, and doing things like staffing and team formation and substitutions and

  71. 11:33

    things of that nature. And so I'm gonna present a little bit about what we're gonna go through in these modules first. So I'll do some stuff inside of ADK.

  72. 11:44

    Hopefully it won't take too long. I just wanna kinda talk to you about Cypher and some of the things that you'll be seeing, and then we'll go ahead and get hands-on here pretty quickly.

  73. 11:56

    Um, so we're gonna talk about creating a graph. We'll start with some structured data here just to keep things simple. I'll introduce unstructured data a little bit later. Some basic Cypher queries, some algorithms, and we'll get into some vector search and semantic stuff.

  74. 12:10

    Um, so a knowledge graph basically, um, when we think about it, a knowledge graph generally is devi- is defined as some, as design patterns to organize and access interrelated data.

  75. 12:21

    And at Neo4j, we model the data inside of the databases, what's called a property graph, and this consists of three primary elements. So the first are nodes. These are like your nouns.

  76. 12:32

    These are your people, places, and things. Next are your relationships. These are how things are related together, hence the name. Um, and often will be like verbs. So person knows person, person lives with person, person drives or owns a car.

  77. 12:49

    And both of the, um, nodes and relationships can have properties, which are just attributes. They can be strings, they can be numbers, they can be arrays of things, and they can be vectors as well.

  78. 13:02

    So we can store vectors for-- We've had for a long time inside of Neo4j, um, and you can do search over these things.

  79. 13:10

    Now, the, uh, query language that we're going to use to access the database is called Cypher, and I know a lot of you raised your hands in the beginning, so you already have some familiarity with this.

  80. 13:22

    Um, but Cypher k-kind of looks like ASCII text. So the idea, right, is that, um, it has this SQL-esque kind of feel to it, but you get to write these statements like if you see match person KNOWS skill, um, basically you're connecting a person node to a skills node through that knows relationship.

  81. 13:41

    So it reads kind of very, um, literally in the way that it's written. Um, nodes have what's called labels, uh, which is sort of like it would be the equivalent of a type of table within a SQL database of basically what type of entity it is.

  82. 13:57

    Um, and then as I said before, they have properties. So for example, you can identify by a property like name, um, and you can have s-variables like P and S, which refer to the actual, um, entity as you start to write your query more.

  83. 14:12

    So this is not gonna be a course on writing Cypher, right? 'Cause we can make a, an eighty-minute course just on, like, how are we gonna make Cypher queries.

  84. 14:20

    Um, but we, we'll be walking through these queries. So don't expect to, like, be, if you haven't seen Cypher before, to be a super expert in the Cypher query language when we're done.

  85. 14:30

    Um, but just know that this is kind of how it works, and then as you go through, hopefully you'll get a better understanding and a feel for how these queries, uh, work and, and the types of data that can be returned as you run them.

  86. 14:42

    Um, and so I'm sure r-- Is everyone pretty familiar with vector searching here at this point? Yeah, I, I have a feeling this audience probably would be. So I won't spend too long on this, right?

  87. 14:53

    I think we all kinda know what embeddings are. It's basically a type of data compression. You can apply them to all sorts of things, right? Text, audio, you can even apply them to graphs.

  88. 15:04

    Um, oftentimes it's just gonna be a vector of numbers, and then you can use that to find similar things within that domain space. So find texts that are similar, uh, semantically, not just lex-lexically, like b- actually based on, um, the types of things that they're talking about.

  89. 15:20

    Um, and within Neo4j, you have search indices, including vector. So there's range indices, you have uniqueness constraints, you're able to search text, you're able to do full text with Lucene.

  90. 15:31

    Um, and then we also have approximate nearest neighbor vector search as well that we'll be leveraging, um, as we go through in combination with the Cypher queries that we were just looking at to do graph traversals.

  91. 15:43

    Um, the next thing to know about is that in addition to being able to query the database, we also have analytics. So we have graph analytics powered on the database that lets you do different types of data enrichment, um, and do more graph global type of analytics.

  92. 16:00

    So finding which nodes are most central according to different algorithms, doing things like community detection, how do you cluster the graph, finding paths between nodes, doing different types of embeddings.

  93. 16:11

    Um, so we have a lot of those algorithms, and we'll be touching on them very, very briefly today in the first module just to show that, you know, once you have a knowledge graph, you can start enriching that data and then actually using things like, we'll see, in our case, we'll be using community detection, um, where we'll

  94. 16:28

    be summarizing skills inside of our graph, and then we'll be able to pass that on to an agent to actually use that to explain, um, some parts of our graph, uh, for our use case.

  95. 16:41

    All righty. So with that in mind, we'll go ahead here and jump into the first notebook. Um, are there any questions before we dive in?

  96. 16:50

    Is anyone still-- Okay. Yes, over here.

  97. 16:54

    Can you give us the link, please?

  98. 16:55

    Um, yes. Do you have, uh... Let me just go back here

  99. 17:00

    to the... So, and this is available in the Slack channel too. If you don't have a number, um, my colleague Alex over there can go ahead and grab one for you.

  100. 17:22

    Um, we're in the workshop GraphRAG intro Slack channel, so you can go there to grab the deck and all the links. But basically, if your number is one sixty or below, you go to that first Jupyter server.

  101. 17:33

    If it's two oh one, um, or above, you go to the second one. Um, you use attendee, all lowercase, and then your number as both your username and your password.

  102. 17:42

    You'll do that for the Jupyter notebook and then also for the Neo4j browser if you wanna follow along with visualizing, um, the graph as we go through.

  103. 17:52

    Any other... Yes?

  104. 17:54

    I know this is a intro-- introduction to, uh, GraphRAG. So, um, but maybe, like, you know, when you're building these, these graphs, uh, I see you have, you have like a small, small, uh, graph.

  105. 18:06

    Uh, have you, like, you know, prioritized whether you should like big, big graphs, like, you know, uh, one that contains more than skill or, or like make smaller graphs?

  106. 18:17

    Is there any, uh, this thing-

  107. 18:18

    So your question is about data modeling and whether-- how do you prioritize making one graph versus multiple graphs? Um- I mean, it's a good question. I think in general, for a lot of what we're seeing with agents, I find it's helpful to have a smaller data model if possible, um, especially if you're doing different types of dynamic

  108. 18:38

    query generation. Um, so to keep that in mind. But as things are getting better, we can pull back the graph schema and, and offer it to agents, and I'm-- we're noticing that as agents sort of keep iter...

  109. 18:49

    or as language models really keep iterating, they're starting to get better and better at interpreting. So whenever you wanna do traversals in a low latency way between two data points, those things really should go in the same graph, and then it's a question as far as what you make a label versus a property, um, i-in that scenario.

  110. 19:07

    So we'll go through some of it, and then if you wanna talk after and come by our booth, we can have a more sort of use case-focused conversation. Anything else?

  111. 19:16

    All righty. So I'm gonna go ahead here and then dive into the notebook.

  112. 19:22

    So for our first notebook... Can go ahead and restart. That's fine.

  113. 19:34

    All righty. So you're just gonna come down here and start, um... and remember we're in the, uh, talent subfolder. So there's two workshops in here. The one we'll be doing is called Talent.

  114. 19:49

    Um, if you're in the other one, it's-- there's also some interesting stuff in there, but, uh, you won't be able to follow along. All righty, so looks like I'm running now.

  115. 19:57

    So basically, what I'm gonna do is I'm gonna get my environments file here, and I'm just gonna load it. If you, um, don't have the environments file, just go ahead and move it.

  116. 20:08

    It's in the root directory. Just go ahead and move it into this subdirectory. It's this ws.env file.

  117. 20:16

    Um, and basically what we're gonna do first is we're just going to load our skills datasets. It's gonna be a table.

  118. 20:24

    And if we look at that table, um, we're going to have, uh, basically three fields.

  119. 20:32

    There's the, um, an email field, a name field, and then just a list of skills for the person. And as I said before, I'll-- we'll go into a little bit of detail here around how you might extract this from documents like resumes, um, in a second.

  120. 20:47

    Um, but basically for now, because we're interested in sort of this skills, um, mapping and team formation and staffing kind of use case, we're starting with this sort of very simple dataset to get us started.

  121. 21:01

    Um, and so there's a couple steps here that just go through basically organizing the data to make it easy to load, and then we're gonna start to create our graph.

  122. 21:13

    And so a lot of this is just what we'd call, like, basic kind of Neo4j data loading. We're gonna create chunks out of our data frame. You're gonna, um, basically check to make sure you've got nothing in your database.

  123. 21:27

    I do have stuff in my database 'cause I was just running this before, um, but that's on me because I was just running the course before. Yours should say zero.

  124. 21:35

    Now, the first thing we do is set a constraint. So basically, inside of Neo4j, whenever you create nodes, um, if you have what's called a node key constraint or a uniqueness constraint, it's basically saying, in this case, that the email has to be unique and non-null for all your, um, for all your people, and that will make

  125. 21:56

    it so that it's very fast to match on people and do merging operations. So a lot of times people will say, "Well, Neo4j is really slow," um, and that's often because of simple mistakes like not setting a constraint and then you're going to have to do very complex searches in the database every time you search on a

  126. 22:13

    user rather than having it, um, in an index that's unique.

  127. 22:17

    Um, and then you also do the same for skill because our data model is gonna be person and skill, so we have two types of nodes.

  128. 22:25

    Um, and when we do that, we'll go ahead and have two constraints here inside of the database. You'll see for skill and for person. Um, after that, we'll go ahead and start loading our nodes, um, and our relationships.

  129. 22:40

    So the way that this query works, and I, I guess I won't run it even though it, it won't actually change anything in my database. But what we're doing here is we're looping through chunks of our data frame and we're saying, "Hey, merge a person on email, set their name," and then for that list of skills, basically,

  130. 22:59

    you're going to merge a skill on a skill name, and then you're gonna merge here that the person knows that skill. So it's gonna create this graph pattern of person knows skill in the database.

  131. 23:10

    Once you run that, what you can do is if you have that browser window open that we were going over before, is I can go ahead and copy one of these, or maybe I'll just take, I'll take this one.

  132. 23:23

    Well, I'll go ahead and take this one first.

  133. 23:26

    What this will show you inside of the database

  134. 23:30

    is if I just match people, I'll get my people back here,

  135. 23:35

    and I may have lost... Oh, cool, I still have my internet connection. All right. So I can go ahead and see that I have my people. They have their names and their email addresses.

  136. 23:44

    Um, you can do the same thing for matching skills,

  137. 23:48

    and then, um, you can also look for relationships. So this gets into that pattern matching that we were talking about before with Cypher. This is a very simple version of matching a path.

  138. 23:58

    So I'm saying P, which is path, is equal to node, connect to knows, connects to another node, and I'm saying limit twenty-five, and that will return a graph where I get to see all these different relationships.

  139. 24:12

    Looks like my internet connection is still somewhat slow, but I get it back here. So you'll see I'll get my people. I'll get that knows relationship. Then in this case, this person knows API design, Tableau, Flask, um, and you'll see different skills pop up here inside of your graph.

  140. 24:31

    Um, and there's, you know, you can, you can go ahead and run these through what, through our driver here as well to look at the data, um, pull back the different people that are in there, um, and find out what skills they have and such.

  141. 24:45

    We do here.

  142. 24:49

    Question.

  143. 24:49

    Yeah.

  144. 24:50

    When you say knows, is that... You're just making up a term. Like, that could be any string, or is knows, like, a specific Neo4j concept?

  145. 24:57

    Knows is a relationship type. We are making it up. So our, our domain model that we have, um, I can actually call it here, and mine is gonna show more than yours if you run the same command 'cause it has the, um, some other later stuff that we do in the course.

  146. 25:15

    But basically, you have person KNOWS skill. That's our data model. So you can say person HAS skill, would be another way to put it, right? Um-

  147. 25:26

    But the word knows is just something that you, you could change that word and-

  148. 25:29

    Exactly

  149. 25:30

    ... there's an edge there.

  150. 25:31

    Exactly, yeah. And it's, it's actually funny because this is becoming even more important, um, now that we're using, uh, LLMs to design queries because, like, the language that you use is sort of like an annotation for the model, right?

  151. 25:47

    So that starts to become very interesting. All righty. So there's some Cypher queries here that I'll go ahead and run through really quick, and I may, uh, depending on time, need to, need to kinda speed things up through this notebook 'cause I wanna make sure that we actually get to the agent at the end.

  152. 26:08

    Um-

  153. 26:08

    How did you say we can visualize the graph again?

  154. 26:11

    So, um, if you go into the, uh, the deck, there's this link browser.neo4j.io/preview, and then I think it's just your username and your password. Um, but you can also look inside of your, um, workshop environment file, and it will have that information there.

  155. 26:31

    You just use your username and your password and your URI information, um, which you get here. So you get your URI, then your username and your password.

  156. 26:43

    All righty, so like I said, we'll go through some of these. So for example, we can count in Cypher, so we can say MATCH person KNOWS skill. We can get back the name, and we can count the distinct people, uh, basically here for, for each skill.

  157. 26:58

    So basically what we're doing here is you can think of it as, like, okay, I've got all my skills and I'm gonna count the distinct people that know that skill.

  158. 27:05

    It's very simply what we're doing. When we get that back, we'll see kind of what our most popular skills are here, um, going down, and they're all kind of tech-focused.

  159. 27:16

    We can also ask different types of multi-hop questions, which is very interesting. So for example, I'll take this and I'll copy it over to my browser 'cause it's, it's interesting to see these visually.

  160. 27:27

    Um, but what we're asking here is we're gonna, we're gonna take this person, um, named Lucy, and I'm just gonna ask, you know, what people are kind of similar to Lucy in terms of knowing the same skills, right?

  161. 27:44

    So I can go ahead and run that, and then what I'll get is I'll get Lucy here. I'll get all of her skills, and then I'll get all the other people that know those skills here, right?

  162. 27:55

    Um, and you can build on that iteratively. So I can, if I go back here, I can also say, well, now I wanna know all of those skills or all of those people, and I wanna know basically,

  163. 28:08

    I'm gonna add at the end of that query, um, I get they know a certain skill, and then I wanna get all of those people, and then I wanna get all the skills they know.

  164. 28:17

    So I'm basically adding this and what skills do these other people know to the query. And then I'll get a very large graph back. But the idea with this is that once we have this logic extracted from whatever our original data source is, we can now control at a much more fine-tuned level how we define what a

  165. 28:36

    similar person is or what a similar skill is because we have this ability to traverse over the graph, um, and apply, um, concrete logic. It's basically like having your information in a symbolic versus just a sub-symbolic vector.

  166. 28:50

    Um, and so, you know, you'll get a lot of stuff back because now we're looking at people and all the other skills that they know, and I can go in here and find the most central skills among these people, right?

  167. 29:00

    Like for example, Scrum is very central among this group, um, because there's, there's a lot of people that know that skill. So I'm figuring out about this local community that sort of, uh, knows the similar skills to Lucy.

  168. 29:14

    Um, and, and in here, it's just some examples of running that, uh, same logic, um, basically inside of the, inside of the notebook. Yes.

  169. 29:25

    Um, at the end do I get only the table and the row? I don't see the graph.

  170. 29:29

    So, um, to get to the graph, basically, uh, what you're going to do is you're gonna go to this Neo4j browser link.

  171. 29:35

    I'm over there. I'm over there. I mean, on the, on the UI.

  172. 29:39

    Oh, I see. Um-

  173. 29:40

    Here. Oh, all right.

  174. 29:41

    So-

  175. 29:41

    See the graph now, yeah

  176. 29:42

    ... you table, then graph, and then sometimes if you're not returning nodes, it will only return a table. Like, if I said, you know, return, um-

  177. 29:50

    I think I re- I just put the same query as you.

  178. 29:54

    Yeah. Okay.

  179. 29:55

    You did. Oh.

  180. 29:58

    Okay. Yeah, so if you, if you just say return P, um, in that case it should return, it should return the path. Sometimes if you don't see it, it's because you're returning, like, just a name or something.

  181. 30:09

    Um, and then in that case it'll, like, just show you a list of names.

  182. 30:13

    Oh. Thank you. That's helpful.

  183. 30:14

    Follow-up question. What is a distinct doing in this case? Um,

  184. 30:20

    and I don't have a distinct here. You just delete, you just delete it. Oh yeah, I did. Yeah. Um,

  185. 30:28

    I don't know if it's completely necessary for this one actually. Um-

  186. 30:34

    Yeah, I don't think it is completely necessary for this one. Um, there are times when you do very complicated, especially we'll see that there are a couple other examples where we do, like, multi-hop paths, and there's a chance with some of those that you'll get basically two paths that are the same, um, in which case having the

  187. 30:51

    distinct there just allows you to, um, filter it better.

  188. 30:56

    Question.

  189. 30:56

    Yep.

  190. 30:56

    Um, so how, how good are any of the LLMs is in writing those, uh, Cypher, uh, queries?

  191. 31:05

    So that's hard to say. They're getting better. Um, a lot of it depends on the complexity of your schema. Um, and basically, you know, we see for simpler aggregation queries or when you have a lot of prompt engineering around doing different types of path queries that are very specific on a smaller model, they can do well.

  192. 31:23

    Um, we do often recommend that you have your own expert tools if there's, like, a really complicated type of traversal that you wanna do. So right, you can write your own Python functions or you can have your own MCP server that will just have, like, your, you know, set of functions for your more complicated traversals.

  193. 31:39

    Uh, we also see, too, you can sort of restrict the options for LLM. So instead of writing a complete query, you can say, "Hey, like, there's, you know, these, you know, three types of general patterns," you know, and, and write that part of the pattern and then it will go into this other query.

  194. 31:54

    So you can do stuff like that to help it. Um, we've also done, we've had fine-tuned models that we just released, um, I think back in April. Um, they're on, they're fine-tuned from Gemma.

  195. 32:04

    They're on Hugging Face. Um, so you can try using those as well. They can do a little bit better. We're not gonna use them here though, unfortunately, 'cause we're using a bunch of OpenAI, uh, OpenAI models for this.

  196. 32:18

    Um, all righty. So a lot of this, um, as, as I was just going over, is basically just running these queries. Um, returning, in this case the distinct is important to return a distinct name because you might actually get to the same person multiple times.

  197. 32:35

    Um, so if you're just returning a name and a, an, um, of a skill, right? Then it's important to, um, to, to use distinct in that case. So we get all the distinct skills that basically showed up in the graph we were just looking at.

  198. 32:50

    Um, another thing that might be important for our use case is finding similar people. Um, so this is, again, using that, uh, query that we were just going over to find.

  199. 33:00

    We used Lucy before, but now we can actually, uh, parameterize that here, um, and then basically go no skill, and then we can match, um, basically from that skill going to another person, and we can sort of count number of shared skills between people.

  200. 33:19

    Um, and so when we do that, right,

  201. 33:23

    um, we can go ahead and see, in this case, um, like, the number of shared skills between, um, between different individuals.

  202. 33:32

    Um, and we do it again here, I think, for, um, a different, uh, set of people. I think this just counts most skills shared between any two people. Um, so you can kind of see that here.

  203. 33:45

    Again, just another way to measure similarity beyond just semantic similarity, measuring actually, um, what we have from our model in terms of exact shared skills.

  204. 33:57

    Um, and as we go through this, some of the things that we can do to help speed up our queries, and this is, this is sort of optional, but if we know that we're going to, um, sort of look for similar skill sets a lot, we can create a similar skill relationship inside of our graph.

  205. 34:12

    Um, so basically we can match two different people, um, and then we can merge, uh, a similar skill set basically bet- based on, um, an overlap of the, um, of a skill count.

  206. 34:26

    So we have our data frame locally that we can use for that, that we, that we were just looking, we basically just pulled it back when we were looking at those similar skills, and what that's gonna do is it's just gonna create, again, this, uh, relationship that has similar skill set between people.

  207. 34:42

    Um, and if I were to look at that, it will, um...

  208. 34:47

    Go over to my browser. We'll go ahead and see.

  209. 34:57

    You know, I can have a similar skill. Some of these are overlap one, others will be greater, um, inside of here. I think they go up to three. Um, so it's, all this is doing is basically saying, "Hey, if two people, like, what is their overlap?"

  210. 35:10

    So we don't have to do that full traversal over and over again if we don't want to, um, with that similar skill set relationship.

  211. 35:18

    Um, the next thing I wanted to show you and it-

  212. 35:21

    Question.

  213. 35:21

    Yes.

  214. 35:21

    So, but if you do this, you need to... Like, this is static, and if you want to update what's the overlap, you need to run this query again.

  215. 35:28

    You would need to run that query over again, yeah. So I mean, it, it depends on how often your data gets updated. There's nothing actually wrong with doing the multi-hop query over and over again.

  216. 35:40

    Um, the graph database is designed to handle that. So if you had a situation where you had a graph that was, um, constantly getting updated, you a- you might not even need to create this relationship.

  217. 35:52

    Um, the next thing that I wanted to show you, um, was how our graph analytics works, um, inside of Neo4j and basically using that to, uh, enrich the graph.

  218. 36:03

    So this is, um, basically creating what we call a, a GDS or a graph data science client. Uh, and what's going, what we're basically doing here is we're creating something called a projection, and then we're running a l- algorithm called Liden.

  219. 36:19

    Um, for the GraphRAG community, are you all have, have, how many people here have heard of Liden as an algorithm?

  220. 36:26

    Okay, so just, just a few people. How many people have heard of Louvain as a graph algorithm?

  221. 36:32

    Okay, so we got a couple people. Basically what this algorithm does is it breaks the graph down into a hierarchy. So it will start by, um, basically- Breaking the graph into a few big communities and then going into smaller communities, and what it's trying to do is optimize what we call modularity, and it's basically this metric that

  222. 36:52

    says, "Hey, I wanna create these clusters in my graph where the connections within the cluster are very high and connections across clusters are very low." So I'm creating these modules, and basically what I do by creating these, um, and I'm using that similar skill set relationship.

  223. 37:09

    So this is another important reason to create it, 'cause if you do, um, analytics on your graph, um, it can help with those analytics running a little bit better.

  224. 37:16

    'Cause I have person connects to another person with a similar skill set, um, and by running this Leiden algorithm, basically what we get is, uh, a bunch of communities that reflect people within the communities knowing similar skills.

  225. 37:33

    Um, so this is all simulated data, but basically if I go down to, um... And I'll skip over some of this. We do some checks around, like, how good the communities are.

  226. 37:46

    I'd encourage you to run this just so that the agent works well at the end. Um, but the-- what I wanted to show you here is this, uh, graphic right here.

  227. 37:56

    So what this is, this graphic is looking at, because basically we wrote this community ID property back to the graph, and you get these different community IDs, and then you get to see which communities in a heat map have the most skills in a certain, in a certain area.

  228. 38:11

    So this data is randomly generated, so a lot of these patterns are gonna look maybe a little bit funky if you were to really dig into them. But the idea is that, um, as you have very-- if-- as you have more relevant data and realistic data, this can actually show you, like, your data engineers are here, right?

  229. 38:29

    And your front end guys and front end folks are over here, and then your ML people are over here. So you can start to see that within the graph, um, and really break that down.

  230. 38:40

    Um, but do go ahead and run everything here, um, through the G.drop so that you have that property. Uh, another way that we can break down,

  231. 38:50

    uh, sort of different groups inside of the graph is to look at... Go ahead, sorry.

  232. 38:55

    Uh, I just had, uh, one question regarding, like, when, when do you, uh, customize your graph? Like, for example, the community detection algorithm that you're running-

  233. 39:02

    Yeah

  234. 39:03

    ... and when do you just let the agents just-- Is there any,

  235. 39:08

    you know, again, uh, heuristics where you, where you say, "Okay, well, actually it's better to invest time in figuring out whether we should, uh, you know, improve our graph rather than just-"

  236. 39:19

    Well, I think it depends on your use case, right? Like, if you're very interested in, you know, saying, "Hey, I wanna understand, like, the skill communities inside of my company," right?

  237. 39:29

    If that's, like, a question that's gonna come up frequently, then using something like graph analytics can be very beneficial, right? Because you can do basically, like, employee segmentation, and you can understand performance with inside of different groups and stuff.

  238. 39:42

    We see it oftentimes used for customer segmentation and recommendation systems, and that sort of thing too. Um, at the same time, if you're just like, "Hey, I just want to, like, look for matches of different people with similar skills," then maybe you don't need community detection for that, 'cause that's just, like, a pairing exercise, right?

  239. 39:59

    Um, so I'd say you use it whenever you wanna do some sort of clustering analysis and persist that and then sort of even have visibility and I guess the, the confidence in knowing that there was some way that you did that, right?

  240. 40:12

    And it's not just up to the model that's just making stuff up around how that works, right?

  241. 40:17

    So basically you look at, uh, what the users are doing and then try to see if you need to build-

  242. 40:23

    Yeah. [crosstalking] Yeah. Yeah.

  243. 40:25

    Thanks.

  244. 40:29

    Yes.

  245. 40:31

    S- since the communities are based on their skills, right? What is the heat map showing us? Secondary skills?

  246. 40:40

    The heat map is showing you how often different skills show up with inside of each community.

  247. 40:48

    Aren't the communities based on what skills they have?

  248. 40:52

    Yeah. So, like, the first community, for example, is it looks like either Tableau or Swift, right?

  249. 40:58

    So basically, like, we could use this to name those communities for understanding.

  250. 41:02

    Yeah. To understand, like, the skill breakdown within each community. And again, this is generated data, so this is a little bit random, right? Um, but you can imagine that in a non-random scenario, what you're probably gonna end up seeing is, like, if you have a lot of product managers versus a lot of, you know, um, like, front

  251. 41:21

    end developers versus, you know, like, DevOps folks, like, you'll see that grouping start to emerge.

  252. 41:28

    Yes.

  253. 41:28

    Yeah. Two connected questions. One, do you have any different, uh, best practices for data modeling for an agent to understand the data model or just general graph best practices around creating data models?

  254. 41:41

    Um, yeah, I mean, I'd say a lot of the agent stuff is evolving super, super quickly, um, you know, as LLMs keep changing and getting better. Um, we've had for a long time guides on how to do, like, data migration from relational systems to graph and how to think about that.

  255. 41:58

    There's a certain way in graph how you think about, again, like, nodes being nouns, relationships being verbs, and how to connect those together. For agents, I think it's really nice when the data model reflects a natural language, right?

  256. 42:10

    So person knows skill. It's a very natural language way of, you know, saying something that dir- that translates directly to a data model. Um, and as I was saying before, simpler data models seem to work better when you do, like, dynamic query generation.

  257. 42:24

    Um, so there's stuff like that, and the rest of it is I know, like, the it depends answer is, like, you know, such a cop-out. But it is true that, like, depending on the type of retrievers that you have, the size of your data, um, the cardinality of different categories of things in your data, right?

  258. 42:42

    Like, you know, you generally don't want, if you can avoid it, to have hundreds or thousands of no labels, 'cause it's just a lot. So then you make them properties.

  259. 42:50

    So there's a lot of stuff like that to consider. So I don't know if that answers your question, um, but-

  260. 43:02

    About the data model. Like, what sort of schema file would you give it, or what sort of, um, what do you generate within WMTA? Or what does it seem effective-

  261. 43:11

    So, yeah, we'll see at the end of module three, which we might not have time to get to, but you'll see it in the code, and I'll, I'll show it really quick, is that there's...

  262. 43:19

    You can, from the graph schema, there's, um, functions that we have to pull back the node labels and the relationship types. So you can create a sort of JSON representation, right, of what the graph schema looks like, um, and then combine it with specific prompts.

  263. 43:32

    So then it's like, "Okay, I follow that." Another, um, thing to do that helps even more is if you have a graph data model that's not gonna change a lot over time, where you know you can just pull it and it will be the same for a while, is you can annotate that schema.

  264. 43:45

    So you can say, like, for specific properties or node labels or relationship types, "Hey, this thing does this." And when you ingest data, make sure you, you know, put it here, and when you pull data, make sure you can, you know, go on different paths.

  265. 43:58

    The other thing is putting in, like we had person, know, skill. Putting those actual query patterns into the schema as well helps a lot because the model can read that and then understand how to do that traversal better.

  266. 44:11

    All right. Anything else? All right, cool. Um, so we're actually getting close on time, so I'm gonna go pretty quickly through the rest of this. Um, but hopefully, um,

  267. 44:25

    it, it'll be pretty understandable. So there's another way that we can start, um, thinking about skills and relationships between skills, is how they're semantically similar. Um, so basically what we can do is actually make embeddings on our skills.

  268. 44:40

    So there's another file in here, um, that basically has a CSV file that you read into this notebook that has skills and descriptions and an embedding. So which, which field here do you think we embedded, the skills or the description, and why, right?

  269. 44:58

    So one of the things is when you have really short names, like R is a... technically a programming language, although a lot of people don't love it. I love R.

  270. 45:08

    Um-

  271. 45:09

    AWS.

  272. 45:11

    AWS. Like, they're very short, right? So having descriptions about those, uh, skill names. If you embed those, it provides a more informative embedding, right? So that's the whole idea there.

  273. 45:23

    So basically, we give each skill a description, and then we embed that description. And what we're seeing inside of this is we're actually going to, um... And these are all text embedding ADA, so they're, so they're 1536.

  274. 45:36

    Um, we're gonna go ahead and create a vector property. Um, this is just loading those up in chunks. Um, and then we're gonna set the description as well. And after we do that, um, we'll basically have, I think we create our vector index down here that we call a skills embedding.

  275. 45:56

    Once that's set up, basically what we're able to do, and you'll see it show up here, we'll get that skills embedding index, is we're now going to be able to do vector search on skills inside of the graph.

  276. 46:09

    So if I have Python as a skill, and I go ahead and I'll use this command in Cypher to search the skills embedding, pull back the ten most relevant skills.

  277. 46:18

    Um, and you'll see here it'll, it'll bring some skills back. Um, here it's, like, Ruby and Java. We got Pandas at least. That's good. Django, PyTorch. Um, so some of these are better than others, but the point is that we can go ahead and apply these vectors, um, and then pull information back with vector search.

  278. 46:39

    And another interesting thing that we can do, um, as well

  279. 46:45

    i- is we can, if I had something that wasn't in the database, like say I'm just looking for API coding, right, and I searched that as a term. Basically what I'm doing here is I'm using the OpenAI, uh, client here to just embed this model, or I might be using actually LangChain up here.

  280. 47:02

    Looks like it's LangChain. Um, and then I'm doing a search on the database to pull back relevant skills with a certain similarity threshold, and I'll get back API design and JavaScript for that API coding example.

  281. 47:15

    Um, and what I can actually do in this case is I can say, "Well, I have this ability to do semantic similarity in the database." I can actually write a relationship that's just similar semantic, and I can attach a score to that.

  282. 47:32

    Um, so there's some advantages to doing this, but a big one is visualization and also clustering. So if I were to take this command, which takes a semantal-- similar semantic relationship, and I go into my graph,

  283. 47:49

    and I just put that in here, and I just return all basically the skills that are semantically similar.

  284. 47:57

    This internet speeds up hopefully. And I zoom in. I'll start to see sort of interesting groupings here. So

  285. 48:09

    I'll start to see, for example, that I get my cloud skills here, Azure, AWS, cloud architecture, all in one place. Similarly, like I have Flask and Django here connected.

  286. 48:20

    I've got my data analytics groups. There's like Tableau, Power BI, data visualization. Um, and then I've got a big grouping over here. So you see like you have your JVM languages, like your Java and Scala and Kotlin here.

  287. 48:33

    Um, and then I've got, you know, my Python stuff here with Pandas. And then if I go up in this group that's connected, right, I've got my Java, and then I've got like all this front-end, you know, frameworks and stuff up here.

  288. 48:46

    Um, so don't underestimate the power of being able to visualize similarities. Very important because I can create communities from these. I can use this for customized scoring in my retrieval queries, which we'll see.

  289. 49:00

    Um, but the other really cool thing is that, um, if for some reason, like maybe I don't think- Java should be connected to Python, I can control that. I can remove that relationship.

  290. 49:12

    And then every time I do similarity relationships, I have control over that and I can filter that, right? Um, so that's just some important things to keep in mind about how you can, uh, sort of use vectors and graphs together.

  291. 49:27

    Uh-

  292. 49:27

    Yes. Quick question. Uh, is it only when you do semant- uh, semantic similarity, is it only to visualize or are there any other use cases?

  293. 49:35

    We'll see in a bit here because basically what, what we can do, and I'll answer this actually as I, as I go down, um, I can pull back this semantic similarity relationship here, but what I can start to do, um, which is actually pretty cool, is I can start creating these, um, sort of customized scorings between things

  294. 49:57

    that kind of balance the, like, the semantic similarity versus hard rela- like, skill matches, and I can weight that if I wanted to in a, in a custom way.

  295. 50:07

    So you can use it in your retrieval patterns as well to improve things.

  296. 50:12

    Um, yep.

  297. 50:14

    For a typical retrieval pattern, would you go directly in Neo4j or would you do vector search first, look at the entities, and then find similar entities, and then do maybe vector search again?

  298. 50:25

    Do you use both typically or?

  299. 50:27

    You ... So you can use both. Um, so there's a lot of workflows, 'cause now you can compose things together into multi- multiple steps, right? So you can definitely do something where you can pull similar skills and then look for people, right?

  300. 50:39

    And it just depends on how you break down those functions for the agents. Sometimes if you know that, like, there's a very specific pattern that you want to follow, like here this is a very ...

  301. 50:49

    This looks like a really big query. It's somewhat intimidating, but it's actually not that complicated. Like, what you're doing here is you're just sort of doing a weighting between the semantic similarity and a hard, like, s- overlap with similar skill sets.

  302. 51:03

    Like, that might be a case where it act- coupling that logic together might make sense. Like, if there's a very specific type of metric that you want for similarity.

  303. 51:12

    But what, what if you're coming from, like ... When you're coming from, you have a query and let's say you have an assistant and you have a much larger, uh, ontology.

  304. 51:19

    Mm-hmm.

  305. 51:20

    Um, that's like, "Tell me about people with certain skills." Um, how do you know that these are even the entities that you're looking at? Uh, w- w- what's the first step when you go from query to retrieval?

  306. 51:32

    How do you break it into the entities to know that this is the type of query it should be or this is the query that you should be doing anyway?

  307. 51:38

    Does that make sense?

  308. 51:38

    Yeah. I mean, w- why don't we revisit that when we get to the third module? The second module s- should be really quick, and then we c- you can see some of the functions in the third module, and then that might help me answer that question a little bit better.

  309. 51:50

    I think I know where you're going, but maybe seeing that will help.

  310. 51:55

    Um, so as I said before, this is doing kind of like a, a balance between the semantic similarity and sort of a, a hard overlap of skills, and then you can use that to kind of weight, you know, how you want to find similar people inside of the graph.

  311. 52:13

    Um, so you can, you can start balancing both sort of the vector search similarity and the, uh, similarity that, uh, just happens with inside of the hard matches. And another cool thing about a graph database specifically is ...

  312. 52:27

    I'll go ahead and take this query here,

  313. 52:30

    um, just so you can see what this looks like.

  314. 52:33

    Oh, go ahead.

  315. 52:35

    Feel free to push this question, but are you gonna talk a little bit about, um, I guess the trade-offs between doing the vector embedding within Neo4j versus maintaining a separate, like Postgres database for that research?

  316. 52:47

    Yeah. I mean, you could go either way, right? So some of, a lot of this, to be honest, will come down to cost considerations. Like, how expensive is it in Neo4j versus how expensive is it inside of Postgres, and that varies a lot depending on the type of infrastructure you have.

  317. 53:02

    Having everything in one place means that you ... It's a little bit ... You don't have to, like, sync your data, right? And then you also, the query latency is, at least in theory, gonna be lower because you're just querying from the same database.

  318. 53:15

    Um, but if you already have data in Postgres maybe or you already have a specialized vector database, you also don't have to migrate your data necessarily to Neo4j to make that work.

  319. 53:25

    So yeah, I'd say a lot of it actually, it's performance, but it's really, like, cost per performance, right, is kind of what you're thinking about in terms of what d- what does each deployment cost.

  320. 53:38

    Um, so this query here, um, is actually, I'm taking, I'm looking for similarity between two people, and then you see I have this like star dot dot thing here.

  321. 53:48

    And basically, with a graph, you're allowed to do what's called variable length queries. So I'm saying, "Hey, go out on similar semantic, but you're allowed to go out anywhere from zero to two hops between these skill sets before you find a connection between John and Matthew," um, here.

  322. 54:05

    And then I can also union it against just the plain, you know, person knows same skill. Um, and when we get that back, we'll see, right, like you get Matthew over here.

  323. 54:16

    Matthew knows React. John knows HTML. And then those are sort of similar because they both have a semantic similarity to JavaScript. Same thing here. You see we have this, uh, semantic similarity, but this is only one hop.

  324. 54:30

    This is where the variable hop comes in. So you can start to control, like, these, you know, sort of how far out you can go on, on either of these paths to be able to pull back similarities between people.

  325. 54:42

    Um, so it's just an advantage of a graph database.

  326. 54:47

    Then I think might wanna finish it off for this notebook. Um, I would take a break, except that, uh, we only have 23 more minutes.

  327. 55:00

    So what do you say? Should we just power through the last 20 minutes, you think? Yeah. Let's, let's, let's do that. So- Now I, we, we looked at some of the advantages of using the graph and the semantic similarity inside of the graph, and now we'll talk a little bit about our second module here.

  328. 55:17

    And I won't go over to the slides, 'cause I think for you guys I can probably just hop right into the notebook, uh, around, well, what if we have just resumes, right?

  329. 55:26

    We don't have a CSV file. So this is gonna be a simple example that will show you, um, basically how to take the data, um, from text and turn it into useful data for the graph.

  330. 55:37

    So again, like if you're, if you're going through and running this live, you're just connecting to your same workshop file, which you should have from before. Testing the connection, making sure you can count.

  331. 55:49

    Now you should actually get 154 nodes. So here, and if you come by our booth, we can show you much more, uh, sort of exciting examples than, than the two text, uh, blobs that we have here.

  332. 56:02

    Um, but here we have two different bios. Um, and basically the way that you can do this, and if you've already done some entity extraction, you're probably already familiar with this workflow, is we can define our domain model, um, in terms of, uh, Pydantic classes.

  333. 56:17

    Uh, so here, basically, I'm gonna define my person with a name and an email, and then a list of skills, um, and then I have the skills field here.

  334. 56:29

    Um, if you add relationship properties, you would have like a nose. Maybe like in a more complicated model, nose as a relationship would also have like a proficiency property, in which case this would be a list of, you know, nose skills, and then you would have...

  335. 56:46

    A nose skill would have a class, um, would have a skill property inside of it. But you can see this is a very simple example. So all we're doing here is we're defining a list of skills that someone can have.

  336. 56:56

    Skills just has the name property, and then we can create this person list. And then once we have our, uh, Pydantic, uh, class defined, uh, we can create our system message, uh, to basically be a prompt for our model.

  337. 57:10

    Um, and then we can use, in this case, I used, uh, four one here, um, and we gave it the documents to, uh, to ingest, and then it will spit out at the end of this some JSON, uh, with those two people.

  338. 57:25

    So we had two documents, each one, um, corresponded to one person, and then we got our emails and skills, um, with all their different names and such. Um, and once we have that, right, um, it's, it's from there it's pretty trivial to load in, and it's very similar to what we did last time.

  339. 57:44

    Um, in fact, if we go down to our graph creation here, we'll see, uh, this isn't exactly the query that we had, but, uh, it's very similar where we've basically...

  340. 57:53

    We're ingesting one person at a time, merging on that, uh, email address which we have indexed, sending the name, and then for each of the skills, that's sort of a list inside of there, um, we're gonna go ahead and merge, uh, the skill name and then that nose property connecting them together.

  341. 58:12

    Um, and then of course I could go back to the graph and I can say, um, "These are Neo4j employees that I loaded." Um, but I can go ahead and look for one of them in the graph, and I should get them back here, um, where I have them and I have the different skills, uh, that they

  342. 58:30

    went ahead and, uh, picked up, um, that I can put inside of the database. So, um, very, very simple. Uh, we have, um, our own, um, GraphRAG Python package as well, which is very good for...

  343. 58:46

    And, and also our Knowledge Graph Builder, if you look at some of the code that we used, um, to implement that, which is kind of like a reference UI, um, which has more sort of examples around if you wanted to do things like document chunking with overlap.

  344. 58:58

    Um, you know, and, and of course also doing like multi-threading with Async and stuff like that, so you're not just, you know, doing a four loop, you know, over, over a bunch of, over a bunch of bios.

  345. 59:10

    So we have all of that. If you stop by the booth, we'll, we can, we can give you more around that. Um, but like I said, especially for this crowd, because you guys are already familiar with this, um, you know, this is, this is a very short module.

  346. 59:22

    And yes?

  347. 59:22

    So we've just gone through two resumes, added them to the graph. Do we now need to go recluster our data and re-embed it and, and do that, or?

  348. 59:32

    So, so we would have to do that, yes. So ideally, I would have done this in an, in an order where I would have done this first and then we've, we've got...

  349. 59:40

    We would have gone through like the clustering.

  350. 59:42

    You're materializing new relationships in with weights on them.

  351. 59:46

    We're, we're putting new relationships in. These don't have weights on them, but if we wanted to reformulate our communities, um-

  352. 59:54

    These are-

  353. 59:54

    Here you go, sir. Then everyone can hear you.

  354. 59:56

    Thank you. So, so the, the communities... Kind of following what you're doing. You're adding extra links in between the nodes that have weights on them, whether it's for semantic distance for skills, or whether it's for pr- you know, you're, you are X hops away from somebody else in terms of some other distance computation that you've materialized.

  355. 1:00:19

    Yeah. So we would, we would ideally rerun that in a recurring way a- as we upload data, right? So because I created-- I did, in this case, create, I think, some new skills in addition to the people.

  356. 1:00:32

    So, like, has same, has similar skill set that we, we, we would redo that, and then we would get a couple more relationships there. Um, the semantic one, if we created new skills, we would create new semantic relationships between the skills.

  357. 1:00:47

    Yes.

  358. 1:00:47

    Okay. Thank you.

  359. 1:00:50

    Cheers.

  360. 1:00:56

    All right. Any other questions before we move on?

  361. 1:01:01

    I'm ready.

  362. 1:01:02

    All right. Well, then that was a, uh, a very quick module. So I'll go over and cover, um, just some other topics around this very, very quickly.

  363. 1:01:14

    Inside of my, inside of my slides here.

  364. 1:01:18

    Um, so what we saw was an example where I'd call it entity extraction or named entity recognition, where we were taking a document and we were literally breaking out people, places, and things, and relationships from within that document.

  365. 1:01:34

    Um, there's other things that we can do, like for example, if we have certain types of documents, like from a catalog, or in this case RFPs, um, we can start to break things out by actual document structure.

  366. 1:01:47

    So I'm only gonna walk through this just so you understand that there's different types of extraction that we can do to create graphs. Um, for example, if you know what the anatomy of a document is, like in this case if we have an RFP, um, we know that this RFP is gonna be designed in a way where

  367. 1:02:03

    there'll be different sections, that we have an intro, objective, proposal, and subsections within that. We can actually create a graph out of those things too. So this is another way that we can do, um ...

  368. 1:02:15

    I would call it more like document extraction, um, where we're actually putting the, the metadata of the document and modeling it as a graph. Uh, and the advantage of doing things this way is that basically as you start to embed these different pieces, um, and put them into a knowledge graph, um, you can basically do these patterns

  369. 1:02:37

    where you can do these searches on either entities that come from different chunks, um, and you can sort of go up and down, uh, these, uh, document hierarchies to find things, which can be very helpful if you have documents that always have repeated structure, um, so you know that entity sometime connects between those, the structures of those

  370. 1:02:57

    documents. You can start to incorporate that inside of your, um, graph retrieval queries. Um, and then it also gives you a way to do community summaries, 'cause we saw Leiden before.

  371. 1:03:10

    Um, but also if you have documents that give you a natural, uh, hierarchy, um, you have a way of also summarizing information, um, across those documents as well. Um, yep.

  372. 1:03:21

    Why do you have entities and, um, documents and chunks in the same ontology, as opposed to extracting entities and, um, and just creating a separate ontology separate from documents and chunks?

  373. 1:03:33

    Why do you combine the two?

  374. 1:03:35

    Well, I think when they're combined, you, you can just do traversals between them. So-

  375. 1:03:40

    What do you have, like, what's an example of a, of a traversal you, traversal that you wanna do between entities and chunks?

  376. 1:03:45

    An example that you wanna do between a traversal of entities and chunks? Like, I say, like, legal contracts is a good example, where if you know, like, you wanna search for different legal clauses, but then, like the expiry date, that might be somewhere else.

  377. 1:03:57

    So, like, that, that would be one example.

  378. 1:04:00

    Yeah. Thank you.

  379. 1:04:02

    Yeah. Yes.

  380. 1:04:03

    So just making sure I understand. So, like-

  381. 1:04:05

    There's one.

  382. 1:04:05

    Yeah, sure. So just wanna make sure I'm, uh, clear on what you're talking about traversing the document. So in a legal document, say, like a data protection clause across multiple vendors or something like that, and comparing the language?

  383. 1:04:18

    Like, is that a use case?

  384. 1:04:21

    Yeah.

  385. 1:04:22

    Yeah. Okay.

  386. 1:04:23

    Yeah, so that and then, like, you know, so there might be like, um, like a perpetuity piece or like, you know-

  387. 1:04:30

    Whatever

  388. 1:04:30

    ... dates and different things, and then being able to kind of traverse over that document to find that in addition to the entities.

  389. 1:04:40

    Anything else? All right. All righty, so I just wanted to introduce that as, as another example of how to do things, um, for the third module, because we're already at 10:07.

  390. 1:04:53

    So let me just go ahead and jump into the thing so you'll get to see it.

  391. 1:04:59

    Uh, we'll go over to module three. And this is gonna be very simple. So has, has that... Who here, and we probably asked this in the beginning, I think we already asked how many people have experience building agents.

  392. 1:05:10

    This is gonna be very simple. It's just gonna be a LaneGraph agent that we're gonna, that we're gonna make here. Um, basically what we're going to do is, again, a similar setup with our environments file.

  393. 1:05:22

    We're gonna connect to Neo4j, test our connection. Um, there's gonna be four tools that we wanna build. We wanna be able to retrieve the skills of a person. We wanna be able to retrieve similar skills to other skills.

  394. 1:05:38

    Similar people, like if we wanted to find out who's another good person to work on a thing. Um, and then retrieve people based on a set of skills. And in this example, um, we're basically going to, um, do a lot of tools first.

  395. 1:05:54

    So at the end of this notebook, there's gonna be like that text to Cypher stuff where you get the schema back. But here what we're gonna go over first is actually going to be putting these different tools together.

  396. 1:06:05

    Um, and we do that by graph patterns, and it's the same graph patterns that we've been going over. Uh, so for example here, right, if we just wanna find, um, the skills that someone knows, it's very simple, right?

  397. 1:06:15

    Just person matching to their skills. Um, and as you go down this notebook, basically what you're seeing is all the different patterns. So the second is retrieving people with similar skills.

  398. 1:06:27

    And here we're actually going to use the, um, the vector index and that similar semantic relationship. Um, so we're basically going to pull, um... Actually, this one is searching for people with skills.

  399. 1:06:40

    I apologize. So in this one, the, this is, um,

  400. 1:06:45

    you're gonna look for skills. So for example, you, if a user puts in different skills, those might not match the skills we have inside of the database exactly word for word.

  401. 1:06:55

    So you're gonna use vector search to pull out, um, the specific skills and what's semantically similar to those skills, and we can do some scoring thresholds in here to pull back exactly what we want.

  402. 1:07:07

    Um, and then that will go ahead and return some skills. So if, if we had, for example, right, like this continuous delivery, cloud native, and security, um, this would be like the types of skills that we pull back from that.

  403. 1:07:20

    The person similarity. Um, there's a few different ways that we can do that, and we've talked about that a lot towards the beginning. Um, we can do it by community.

  404. 1:07:31

    So we can look for people that know different skills. We can get all of their names, and then we can look for, um, that Leiden community that we created.

  405. 1:07:41

    We can look for all the skills that those people know, and basically what we're doing at that point is we're looking for people inside of the same, uh, skills, uh, community.

  406. 1:07:51

    Um, but the other way that you can do that is, um, you can look for similar skill sets, um, using the, uh, similar skill set relationship, so the hard-coded relationship that we've made from before, uh, which basically looks at, hey, how many-- how-- what's the actual skill overlap if you just looked at, um, who knows what inside

  407. 1:08:11

    of the graph? Um, and that will bring back, um, some answers here between-- So we were looking at John Garcia, and we're saying, "Hey, find similar people," and then we can get like a score count of overlap, um, to the, to the different people here.

  408. 1:08:26

    Um, and then we can start adding in that semantic similarity. So this is where we get this big query, right? But what this query is actually doing is it's sort of balancing between the, um, similar skill set and semantically similar skill set.

  409. 1:08:41

    So it's kind of taking both those scores and adding them together. Um, and then from there we get, uh, a floating number score, um, and a little bit of a different answer that's not just based on hard skill connections, but also skills that are kinda close together.

  410. 1:08:56

    Um, and we can weight those independently as well. Um, and we can also recommend people given a set of skills. So if we have a set of skills here, um, we can just do, uh, a vector search on, um, on those skills.

  411. 1:09:12

    Um, and then-- Actually, this one... Combination of person given skills. Skills.

  412. 1:09:22

    Yeah, here it is. Um, so basically, um, the query was broken out into two parts just because this is, this is kind of a big thing to look at.

  413. 1:09:31

    But the idea with this is we can get, um... We can basically do vector search on skills, get semantically similar skills, um, and then a find person who knows those skills.

  414. 1:09:41

    So very similar to some of the last ones. Um, and then we can get a skill count for all of those groups and get people back. Um, when we actually define the functions for our agent, um, we're going to create here, um, a skills object, which basically is just gonna help us, um, with some of our function

  415. 1:10:00

    arguments and returns. Uh, but basically first tool, retrieve skills of person, very simple query. Um, and then we'll have, uh, down here for tool two, for tool two, when we say find similar skills, um, what we're gonna look at here is again that query where we're gonna do that semantic similarity between skills.

  416. 1:10:22

    So we're gonna do a vector search to find skills, and then we're gonna go out one hop on semantic similarity. Um, and then we're basically gonna collect everything and return it.

  417. 1:10:32

    And then for the third one, we're gonna do that weighting, um, because this tool three is gonna be for person similarity. We're gonna do that weighting between the similar semantic and the similar skill set with that larger query.

  418. 1:10:46

    And then I know I'm going through this kinda quickly. For the fourth one where we say find person based on skills, here again our entry point is gonna be a vector search on skills, um, going out to match those semantically similar skills.

  419. 1:11:00

    But then kind of at the end of that, uh, we'll add on a traversal that will attach the person to knowing those skills, count who knows the most, and then effectively return that.

  420. 1:11:11

    So those are the four tools that we're gonna end up using for this agent. Um, when we set up the agent here, if you're familiar with, uh, how LangGraph works, basically, uh, we, we get our LLM, we test that it's alive, we define our list of tools.

  421. 1:11:28

    We can, if we didn't wanna do this in an agentic way, right, we can just bind our tools to our LLM, um, and we can, we can invoke our LLM with tools.

  422. 1:11:38

    Um, but what we're going to do instead, because this is just showing invoking the different, the different tools, um, is we are gonna go and run it with an agent.

  423. 1:11:49

    So we're gonna use create React agent, which comes from LangGraph. Um, it's one of their pre-built agent, um, that uses the, the React, um, I don't know if you'd call it a framework, but, um, sort of that methodology, uh, to build an agent.

  424. 1:12:05

    And effectively, um, once we do that, we give it the LLM, we give it the four tools, uh, that we had, and then, um, we can see that here we're just testing, we're saying hi, and we're just making sure we get some response back.

  425. 1:12:21

    There's a utility function here just to make it easier running in the notebook, um, which will basically just, you know, do this, some of the, um, some of the streaming methodology.

  426. 1:12:31

    So I can just say, "Hey, what skills, um, does Christophe have?" And then if I run that, and I don't know if I need to rerun my agent here.

  427. 1:12:40

    Looks like not. Everything's running. Um, so you'll see it says, uh, when I ran that, and actually I ran it for the wrong question.

  428. 1:12:52

    Here, what skills does Christophe have? Person named Christophe, and then it will bring back his skills. So you see there it will choose to use the, uh, retrieve skills of person.

  429. 1:13:04

    Um, and similarly, if I went down and I said, you know, "What skills are similar to Power BI and data visualization?" Um, it'll go through and choose the appropriate, um,

  430. 1:13:17

    you know, the, the appropriate tool for the job. So in this case- Uh, find similar skills. It'll pull those back, and you'll see going down, right, if I said, "Well, what person has similar skills to, you know, this other person here?"

  431. 1:13:32

    Um, then it will know, oh, I need person similarity. So it will go ahead and use that specific tool. So in this case, what we're doing is we're providing a bunch of tools that are presumably expert tools that we can give to the model, and then it will know that, okay, I have to go ahead and pull

  432. 1:13:46

    those, um, those specific tools to be able to, uh, provide a response.

  433. 1:13:52

    And then there's a little app down here as well if you wanted to run the, uh, chatbot. So,

  434. 1:13:58

    um, it's a little Gradio app here. Um, but basically if I ran that, I can go ahead and come in here, and then I can have a little conversation with it.

  435. 1:14:11

    So this is very small, but what skills are similar? You know, I can go ahead and ask it in here, and then provided everything's working, it'll go ahead and choose the appropriate tool, and then I can say, "Well, who knows," um, you know, um, maybe I'll just say those skills, and it should,

  436. 1:14:34

    um, go ahead and pull the appropriate tool to be able to find out who knows all these different skills, right? And if I go back to my, uh, to my example here, I should see the query logic that it used.

  437. 1:14:48

    So first, you know, it said find similar skills to what I just mentioned, 'cause I asked about Power BI, and then after that, I asked about, uh, people who know skills, so it said, "Find persons based on similar skills."

  438. 1:15:01

    And likewise, I can say, you know, "Who is, um, similar to those people

  439. 1:15:09

    in the graph?" And it will likewise go through, and it should, you know, understand that it needs to use the find other similar persons tools, um, to be able to do that.

  440. 1:15:23

    So you'll see if I, if I was to keep going down,

  441. 1:15:27

    I should get calls, um, here to find persons with similar... We have it here. Yeah, person similarity. So it just called the person similarity for each person.

  442. 1:15:40

    Um, and I know we only have a few minutes left. Uh, there is, if you wanted to run this further, basically, um, I have a text-to-Cypher example. So this is where I'll have an example of passing it the annotated schema.

  443. 1:15:53

    So this is getting to kind of what you were asking about, right? Um, where I've provided these descriptions. Um, so it's sort of like annotations for the schema as well.

  444. 1:16:04

    And then I can go ahead and give that to an aggregation query function that will have... There's also an LLM inside of here that will create the Cypher. Um, but you can see in here I asked it some questions like describe communities.

  445. 1:16:17

    It was able to understand that it needed to grab, you know, the, the match person knows skill, and then it needed to grab the lighting community. So it, it knew from the schema, right, that it needed to generate this Cypher.

  446. 1:16:30

    Um, and there's a couple more examples of that in the notebook. Um, are there any quest- I know I just went over a lot. Um,

  447. 1:16:37

    are there any questions from that that are worth answering now while we have just a couple minutes left?

  448. 1:16:43

    How long will the- Got it. Got you. Sorry, so slow. Oh, I didn't even know you were here. Yeah. How long will the, uh, Jupyter server be up if we wanna play with this?

  449. 1:16:53

    Jupyter server is gonna go down very quickly. But if you look at the deck, at the end of the deck, I have a link to the code, and the data's all in GitHub too.

  450. 1:17:04

    So basically, if, if you go here, that's the GitHub repository, so you can play with it. I-

  451. 1:17:11

    How do we get the deck?

  452. 1:17:12

    What's that? The, the deck is in the s- Do you have access to the Slack channel?

  453. 1:17:16

    Yes.

  454. 1:17:17

    So the deck is in the Slack channel. Um, and I, I'll go ahead and, and jump to that in a second. But there's the GitHub repository. You can use Aura, um, console.

  455. 1:17:29

    We have a free trial that you can use. You can just set up a cloud database, and you can load the data into there. Um, also before you guys leave, there's a meetup happening tomorrow.

  456. 1:17:40

    Um-

  457. 1:17:41

    It's today. It's tonight.

  458. 1:17:42

    It's tonight?

  459. 1:17:42

    Tomorrow's tonight, yeah.

  460. 1:17:43

    Oh, sorry. Tonight at 5:00. Um, that... And there's a link there for more information on that. Um, and then we also have another workshop at, uh, 1:00 where today was very simple, like we're gonna go over more graph analytics type of stuff in that workshop.

  461. 1:18:01

    So like the community stuff that I was doing, we're gonna dive more into depth on that in that workshop. Um, other than that, uh, come by our booth if you have more questions.

  462. 1:18:13

    We're gonna be wherever right there is. I don't think we have a big expo hall, but if you wanna see Neo4j MCP servers, ADK examples, more knowledge graph construction, um, all a great, uh, you know, place to come to ask all those types of questions. [outro music]