About this talk
In this talk, the speaker, Ashita from AWS, discusses the development of agentic applications that can solve real user problems through reasoning and action. She begins by sharing a personal experience of selecting a movie among friends with varying preferences, illustrating the need for a smart application. Traditional apps are reactive, while agentic apps proactively reason and loop through actions based on user goals, tools, and context. The discussion then delves into specific technologies like TypeScript SDK, large language models (LLMs), and the importance of grounding these agents with real data using vector search and knowledge graphs. The speaker provides insights into building an AI agent that understands structured, relationship-aware queries, thereby improving the quality and validity of recommendations. She concludes by reinforcing that better tools can yield better answers and emphasizes the simplicity of on-device agents.
Full transcript
[music] >> Yes, so hi everyone. Uh I'm Ashita from AWS. And today I'll be going through a developer's journey of building smarter applications. Well, and that journey begins on a Friday movie night when I and my friends start having a healthy discussion on what movie we should watch together. So, the criteria for me is pretty simple. The movie should not exceed 150 minutes. Anything above 2 and
1/2 hours and I'm done. Now, my friend Rahul, he's a total sci-fi thriller uh sci-fi and thriller fan. And he does not like any other genre except these two. On the other hand, my friend Ravi has a long list of requirements. He's a big fan of the Nolan's entourage and loves Inception, The Dark Knight, and Interstellar. And he wants at least a familiar face from these three
movies in the movie that he's going to watch. And not only that, he only wants seasoned directors who have directed at least three movies. So, what do I do? I am a developer. And whenever we developers face issues, we build applications. And this time, let us build an agentic application to solve this always occurring problem of deciding which movie we should watch. But before we write any
piece of code, I want to make sure that all of us are on the same page about what an agentic app actually means. So, let us look at what we've been building so far. So, traditional apps are apps where the user does something and the app responds. So, it's basically you tap a button and you get a result. This This traditional app does not think. It just
reacts. And every app that we have built or used, say over the past decade, works like this. But now, we have agentic apps. This is different. What happens here is that the user says something and the agent starts a loop. It reasons about what it just heard and then it goes on to do something. Like it can just pick a tool. It can say decide on a
database query and say to decide to do an API call and then simply runs the tool. It then looks at what came back. And here's the part that matters. You can see the curved arrow on the screen. So, if the result isn't good enough, it goes back to the reasoning step and try something else. You know, maybe it is going to rewrite the query. Maybe it is
going to try picking up a different tool altogether. And the loop that I just showed you, the reason, act, observe, and repeat, let us now zoom in on it a little more to understand how it actually works. You know, like what goes into the agent and what is it that comes out? So, on the left-hand side, you can see three inputs. And the agent will need all
of these three inputs to get started. So, first, we have the goals or the instructions. Now, this is us telling the agent what it needs to do. So, it can be things like, "Help me find a movie for my Friday night." Or say, "Book me a flight to Amsterdam." Or it can be, say, "Register me for Notes AI." So, the agent needs to know what it is
actually working towards. Then, we have tools and their descriptions. So, this is how the agent actually gets hands. So, you give it a list of things it can And that can be as simple as querying a database, calling an API, being able to do web search, or even, say, just send an email. And then, what you do is you describe each of these in simple, plain English.
And what your agent is going to do is that the agent will read those and pick up the right tool for the situation. So, think of it like handing someone a toolbox and a manual. So, they are able to look at the manual, say, figure out which wrench fits, and simply grab it. Then, the third thing is context. And this is everything your agent already knows. So,
all your conversations uh that you've had with the agent, all your user interactions, any relevant documents, whatever the agent already knows is part of context. And this is basically like your background information. So, what happens is without context, the agent is going to scratch uh start from scratch every single time. But with context, it remembers. And context, you can say it's your agent's memory and the knowledge
base. Now, what happens is all these three, the goal instructions, tools and their description, and the context go to the agent. And at the core, we have the brain. Now, the brain here is our large language model. Now, it can be anything. It can be your Claude, it can be your llama, it can be your Nova, whatever you decide to choose. The agent is then going to
package up the goal, the tools and their descriptions, into a single prompt, and it sends it to the LLM. And what is this prompt? So, this prompt is basically saying, "Here's what I need to do. Here is what I can use. Here is what I know so far. What should I do next?" So, our LLM is now going to reason through all of that and come back
with a decision. It'll be either I want to call this tool with these arguments, or say I have enough information and here's my answer. Now, in case it is a tool call, the agent is going to take an action, which means it will do something, which can be like calling an API, querying a database, running a calculation, any of these. And all these actions will happen in
an environment. Now, that environment can be your computer. It can be your cloud service. It can be your AWS console. It can be anywhere. And the agent now isn't just talking about doing something. It is actually doing it. And then we have our loop. So, after the action runs, the agent is going to observe the result. Did my API call work? What data actually came back? Was
there an error? And all these observations are then fed back to the agent. You can see that arrow going back to the agent. And the whole cycle starts again. You have think, act, observe. And until the goal is done or the agent hits a limit that you have set. So, now you could build all of this yourself. The prompt construction, the tool dispatch, the result parsing, the
loop management. But that's a lot of plumbing and undifferentiated heavy lifting. And what we're going to do next is we are going to use a framework that handles it for us. So, we'll be using the Strands agent TypeScript SDK, which is an open source project for building AI agents in TypeScript. So, you can define your tools, point it at a model, and it handles your entire reasoning
loop. The prompt construction, your tool dispatch, result evaluation, and the decision whether to loop again or respond. And it works with React Native, which is why we can run this agent on device. So, well, uh let's start building now. So, the first attempt is using only an LLM. So, now let us look at the actual code here. And this is actually the simplest possible agent that you
can build with Strands. So, you can see we have two imports, agent and the Bedrock model. And both are from the Strands agent SDK. This is the only dependency we have. are going to initialize our underlying This is the brain. And we are pointing it at Claude 3.7 Sonnet on Amazon Bedrock, which is running in US East 1. And the client config that you see, it primarily
helps the client talk to Bedrock directly. And then we're going to create the agent, which will take three things. The model that we just created. Our tool sorry, which is empty here because we are not calling any tools in this attempt. And a system prompt. Which is you are a movie expert, answer questions about this about movies. And this is basically our baseline. So, we are going
to ask our Friday night question. And see what happens when an agent will answer. So, you can see we are uh providing our query here. Find me a sci-fi or thriller under 150 minutes from a director that has directed at least three other movies, where one where at least one cast member has appeared in Interstellar, The Dark Knight, or Inception. And now you can see the response
that the agent has given. So, if you closely look, the agent confidently responds and suggests the movie Transcendence. It claims that Wally Pfister is the director with more than three films directed. But now if you Google or look at any of the official data sources, you will find that Wally has just directed one movie, which is Transcendence. He is actually a cinematographer who frequently collaborates with Nolan.
So though the LLM was pretty confident, it messed up and gave us the wrong And why did this happen? So what just happened with Transcendence isn't a one-off. It's a pattern, and it comes down to what an LLM can and cannot do when it is working alone. So first, it has a knowledge cutoff. Everything it knows comes from training data. And that data has a date on
it. If a movie came out after that date, the LLM will not know that it exists. And even for movies it does know about, the details can be fuzzy. We just saw it confuse a cinematographer with a director. Second, it's stuck inside its own head. It cannot do actions. It cannot search the web. It cannot connect to a database. It cannot call an API. It can't run
code. And it has no interaction with the external environment. So when we asked it to count how many movies Wally Pfister directed, it couldn't actually count. It just guessed. And it guessed wrong. Third, and this is one that really matters for our Friday night problem is that it has no way to guarantee that all the constraints that the three friends wanted to be satisfied are true at
the same time. It does try to satisfy them, but it is doing them from memory one at a time hoping they all line up. There is no verification step and there is no query that checks. And so the takeaway here is pretty clear that we need to give this agent tools. So what do we do next is we decide that let us ground the agent with real
data. So it doesn't have to work from memory. And we use rag here. So when the agent gets a question it searches the embedded movie descriptions for the closest matches and pulls back the most similar results. That's semantic similarity. Finding movies that sound like what you are asking for. So the agent is going to read those results and build its answer from real data instead of memory.
So let us look at the code. So you can see here the model is exactly the same. We are still using 3.7 Sonnet. And the only addition is that we are importing function tool to define our tool that we are going to use. And this is the function tool that we have created. We are giving it a name a description an input schema and a callback. And
the callback is basically the code that will run when the agent calls it. And by reading the description is how the agent decides when to call it. Uh then uh the entire agent code where we are bringing it all together. So, again we have the same agent constructor. Uh we have the same system prompt as well from our attempt one. The only thing that has changed here
is the tools array. It was empty before and now it has search movies. So, the agent basically sees the tool, reads its description, and decide on its own when to use it. We are not specifying that in the prompt. So, let us now see how it works here. So, we are asking the same question, once it gets the query, it thinks that okay, I have a search
tool. I should use it before I try to answer. And then the agent is distilling the question into a search-friendly string, which is like sci-fi thriller short runtime uh director cast interstellar Dark Knight Inception. And this is what it thinks is important. And it is calling search movies with this string. And what the tool then does is that it sends back 10 movies with the closest matching
descriptions. And now our agent has real data to work with. It looks through the results, picks Tenet as the best match, and responds, "Try Tenet. It's a sci-fi thriller by Christopher Nolan." And this is better than our previous attempt. The agent is now looking at real movie data, and not just guessing Tenet actually exists. It is actually a sci-fi thriller. Nolan actually directed it. So far so
good. we start thinking, is the answer actually correct for all the constraints that were there? So let us go through our constraints one by one and see what vector search can actually handle. So we had sci-fi or thriller genre. Genre. The search actually matched sci-fi and thriller in movie descriptions. And Tenet does happen to be a sci-fi But the search wasn't able to actually check an actual
genre tag. It found that the text sounded right. If a movie description mentioned that this is nothing like a typical thriller, vector search might still match it because the word thriller is in there. So it's important to understand that it is matching language, not your metadata. Then we had a condition of under 150 And this is where it clearly fails because Tenet is exactly 150 minutes, not
under 150. And vector search has no way to know that because embeddings don't understand numbers. You can't do less than 150 on a vector. The number 150 and 149 will look almost identical in the embedding space. There is no concept of greater than or less than. Then we had a condition of director with three or more other films. And Nolan has directed plenty of movies, so this
happens to be true. But the search tool didn't count It can't look at a director and count how many directed relationships they It just returned movies that were textually similar to the search query. And Nolan's movies showed up because the query mentioned Interstellar, Dark and Inception. And similarly, it is matching all the movie titles as word, not with your uh cast overlap and trying to find the
acted-in relationships. So, vector search will find movie that sound like what you want, but sounds like and what you want can be very different things. And we need something that understands structure, something that can count relationship, you know, filter numbers, traverse connections, and that's where we'll move next. So, let us look at the question one more time before we move on. This is like any uh normal
question someone would ask, but there are three things that are hiding in it that make it really hard for an LLM or a vector search to answer. So, first is multi-hop, second is relationship-aware, and third is constraint-rich. And let us look at them one by one. So, this is basically our raw data uh with uh the movie title, director, your actors, et cetera. And when I ask
it this question, what genre is The Dark Knight Rises? You can see it's a single hop from your movie title to the genre's column. And this is something any database can handle. Now, say we move to another scenario where I ask which other movies has the director of The Dark Knights Rises directed? And you have two hops here. One from movie to the director, and second director
to the movie. Similarly, if we ask another question where we try to find where a cast member of The Dark Knight Rises has worked with Steven Spielberg, we have three hops Movie to cast to their other movies and then back to the director. Now, you can see how difficult it is for a normal flat table to answer correctly. Now, let's move to relationship aware. So, this is
where uh it recognizes the type of relationship between data points. So, even the hop that we did earlier had some relationship. So, both multi-hop and relationship aware move hand in hand. And then the third criteria that we have is around constraint rich. What this means is that the query will have multiple conditions and all of them must be satisfied simultaneously. As you can see, like these are
the five conditions that we had for our use case. Like the genre, the runtime, the director should have directed more than three movies, there should be at least one shared cast member who has appeared in these three movies. So, when we combine all these three characteristics, multi-hop traversal, relationship awareness, and multiple constraints, we get queries that are easy for us as humans to write, but brutally hard
for normal systems to answer. And this is where we need something that can answer these things and that something is a knowledge graph. So, a knowledge graph is basically a graph where your nodes and edges represent real-world knowledge with semantic meaning. And the nodes here aren't just generic points. They are typed entities like movie, person, genre. And the edges as well aren't just generic connections. They are
labeled relationships, like you have directed by, you have has genre, you have has cast, you have acted in, et cetera. And this is how we also actually think about movies in our head. When someone says Inception, your brain is not pulling a spreadsheet row. Your brain pulls up a web of connections. When I say Inception, your brain thinks of Your brain thinks DiCaprio starred in Inception. Your
brain thinks DiCaprio was also in Catch Me If You Can. And without realizing, you start traversing these nodes and So, okay, once we have built a knowledge graph with these entities and relationships, we now need a mechanism to retrieve the structured data so that we can add it to our context. And it can help agents provide better And this entire process of actually incorporating knowledge graphs is
called graph rag. An agentic graph rag is basically an AI framework where you combine the structured reasoning of knowledge graphs with the autonomous goal-oriented decision-making of LLM-based agents. And you might be wondering how we actually query a knowledge graph. So, to do that, we write a graph query. And since we are using Neo4j as our graph database, the query is in Cypher. But don't worry. Uh you
don't have to learn to write Cypher queries because LLMs are intelligent enough to convert our natural language questions into And the graph will in turn make our LLM generate better results by giving it structured, connected, verifiable facts instead of fuzzy text matches. So, you can actually see how GenAI is helping us make graph data accessible, which in turn is actually enhancing our GenAI applications. So, now let's
go back to our code So, I'll require some new tools for our AI agent. The first tool is the get graph schema, which is going to provide me all the details about the structure of the graph, including node types, relationships, and their properties. The second tool is the execute Cypher tool, which is allowing the agent to read uh to run basically all our Cypher queries against the
Neo4j database and retrieve the results. And the third thing is we are initializing our agent. We are providing it the same LLM backend along with both our new tools and the system prompt. So, now let us see how things are happening under the hood. Once the agent gets the query, it immediately goes, "I need to understand the graph structure first and then generate a Cypher query and
then execute it." So, then it is going ahead, calling our first tool call, which is the get graph schema, and it is uh figuring out how the database looks like. Once it gets back the full structure, so, which will be your nodes, your everything, the agent now knows exactly what it is working with. It knows what properties it can filter on, what relationships it can traverse, and
what nodes it can match. It then goes ahead and uh calls our execute Cypher. So, what it does is it is taking the user's five constraint, looking at the schema it just received, the LLM is writing the Cypher query so that all of it can be addressed, um and it is running the tool. Then our agent is evaluating the result and responding. And if the results come
back empty or didn't look look right for some reason, the agent is going to loop back, refine the query, and it is going to try again. And that's our agentic loop. So, if you compare this to the rag flow, the rag agent just made one tool call, a text search, but this agent is making two tool calls, schema first, and then a precise query. It is learning
the data structure first before writing the Cypher query. So, this is how actually our generated Cypher looks like. And now, let us quickly look at the demo. So, you can see here, once I enter the prompt, behind the scenes, the on-device Trans agent is calling the get graph schema tool. And once it is receiving the get graph schema response, it is taking the user constraints, combining with
the schema, and using our 3.7 Sonnet model to generate the Cypher query. Then, it is sending that Cypher square query to the execute Cypher tool. And in case, say for example, the tool fails to obtain a response, the agent is regenerating the Cypher and calling the execute Cypher tool again. And this is exactly the agentic loop that we were discussing about earlier. And after all this has
been done, after it gets the response, you can see the response here is being displayed. So, it has given us five movie options, which match all of our five criteria. So, uh now coming to the key takeaways, so the first thing is that you don't always need a better or a more expensive So, like you could see in this case, we use the same model for all
our three attempts. And if you have better tools, you can get better answers. If like we saw in our example, the only thing that we changed all across our three examples was the tools array. The second thing is when your data has relationships, you can use a graph. Vector search finds things that sounds familiar, but knowledge graph can find things that are actually connected. And for our
multi-hop constraint rich queries, this is the difference between guessing and knowing. And not only this, the answer is also auditable. It is also easy to explain as you can trace knowledge graph through nodes and edges. And the third is on-device agents are simpler than you think. You like you saw in our example, just a strands SDK with a model, two tools, and the system prompt is all
what it took to build this agentic app. The agent runs completely client side and it streams directly to the user. And with this, we have come to an end for this session. So, you can follow me on LinkedIn and my GitHub handle. And if you want to learn more about how you can leverage Neo4j and Amazon Bedrock for an explainable, secure, and connected generative AI solution, you
can check out this blog. >> [music]
More from this event
See all 37 talks →
NODES AI 2026 - Agentic GraphRAG: Autonomous Knowledge Graph Construction and Adaptive Retrieval
11:51
NODES AI 2026 - Semiont: A Graph Based, AI Native Wiki and Annotator
29:48
NODES AI 2026 - MemMachine: Agents That Learn, Memory That Lasts
30:03
NODES AI 2026 - Ghost-busting with Neo4j Graph Analytics in Snowflake
28:47