Providing Example Cypher Statements

So far, the bot has handled everything that we’ve had to throw at it. But we have only been asking simple questions.

Six Degrees

Let’s play the Six Degrees of Kevin Bacon game. Let’s pick an Actor at random and ask the Chatbot to identify the connections.

How many degrees of separation are there between
Viola Davis and Kevin Bacon?

Console Output
> Entering new AgentExecutor chain...
```json
{
    "action": "Cypher QA",
    "action_input": "How many degrees separation are there between Viola Davis and Kevin Bacon?"
}
```
> Entering new GraphCypherQAChain chain...
Generated Cypher:
cypher
MATCH p = shortestPath(
(viola:Person {name: "Viola Davis"})-[:ACTED_IN|DIRECTED*]-(kevin:Person {name: "Kevin Bacon"})
)
RETURN length(p) as degrees_of_separation
Full Context:
[{'degrees_of_separation': 6}]
> Finished chain.
Observation: {'query': 'How many degrees of separation are there between Viola Davis and Kevin Bacon?', 'result': 'There are 6 degrees of separation between Viola Davis and Kevin Bacon.'}
Thought:```json
{
    "action": "Final Answer",
    "action_input": "There are 6 degrees of separation between Viola Davis and Kevin Bacon."
}
```
> Finished chain.

The agent provides the correct answer, six, but the game also requires that you name the movies that connect them. The output in the console shows that the path length is returned, but there is no information about the movies in that path.

To help the LLM, we can provide an example in the prompt to demonstrate how Cypher queries should be written.

Here is a query containing all of the information required to help the LLM solve the problem.

cypher
Six Degrees Query
MATCH path = shortestPath(
  (p1:Person {{name: "Viola Davis"}})-[:ACTED_IN|DIRECTED*]-(p2:Person {{name: "Kevin Bacon"}})
)
WITH path, p1, p2, relationships(path) AS rels
RETURN
  p1 {{ .name, .born, link:'https://www.themoviedb.org/person/'+ p1.tmdbId }} AS start,
  p2 {{ .name, .born, link:'https://www.themoviedb.org/person/'+ p2.tmdbId }} AS end,
  reduce(output = '', i in range(0, length(path)-1) |
    output + CASE
      WHEN i = 0 THEN
       startNode(rels[i]).name + CASE WHEN type(rels[i]) = 'ACTED_IN' THEN ' played '+ rels[i].role +' in 'ELSE ' directed ' END + endNode(rels[i]).title
       ELSE
         ' with '+ startNode(rels[i]).name + ', who '+ CASE WHEN type(rels[i]) = 'ACTED_IN' THEN 'played '+ rels[i].role +' in '
    ELSE 'directed '
      END + endNode(rels[i]).title
      END
  ) AS pathBetweenPeople

I can’t imagine how much training it would take to get an LLM to write a reduce function like that…​

Solution

Add the above Cypher statement to the CYPHER_GENERATION_TEMPLATE string, along with a description of what type of question the query can help with.

cypher
Adding a Few-Shot Example
Unresolved directive in lesson.adoc - include::https://raw.githubusercontent.com/neo4j-graphacademy/app-python/main/solutions/tools/fewshot.py[tag=prompt]

The rest of the code will remain the same.

Braces

Braces in prompt templates are treated as placeholders.

You must escape any braces that you use in example Cypher statements. When escaping braces, { becomes {{ and } becomes }}.

Adding Additional Examples

You can add as many few-shot examples to the prompt as necessary. But beware, most LLM providers charge you are charged per token, and the larger the prompt, the higher the cost.

If you require many few-shot examples, you can always create multiple tools that call an instance of GraphCypherQAChain with a different Cypher generation prompt.

Testing the Change

If you now ask the bot the same question, you should get a greatly improved answer.

Console Output
> Entering new AgentExecutor chain...
```json
{
    "action": "Cypher QA",
    "action_input": "How many degrees of separation are there between Viola Davis and Kevin Bacon?"
}
```
> Entering new GraphCypherQAChain chain...
Generated Cypher:
cypher
MATCH path = shortestPath(
(p1:Person {name: "Viola Davis"})-[:ACTED_IN|DIRECTED*]-(p2:Person {name: "Kevin Bacon"})
)
WITH path, p1, p2, relationships(path) AS rels
RETURN
p1 { .name, .born, link:'https://www.themoviedb.org/person/'+ p1.tmdbId } AS start,
p2 { .name, .born, link:'https://www.themoviedb.org/person/'+ p2.tmdbId } AS end,
reduce(output = '', i in range(0, length(path)-1) |
    output + CASE
    WHEN i = 0 THEN
    startNode(rels[i]).name + CASE WHEN type(rels[i]) = 'ACTED_IN' THEN ' played '+ rels[i].role +' in 'ELSE ' directed ' END + endNode(rels[i]).title
    ELSE
        ' with '+ startNode(rels[i]).name + ', who '+ CASE WHEN type(rels[i]) = 'ACTED_IN' THEN 'played '+ rels[i].role +' in '
    ELSE 'directed '
    END + endNode(rels[i]).title
    END
) AS pathBetweenPeople
Full Context:
[{'start': {'born': neo4j.time.Date(1965, 8, 11), 'link': 'https://www.themoviedb.org/person/19492', 'name': 'Viola Davis'}, 'end': {'born': neo4j.time.Date(1958, 7, 8), 'link': 'https://www.themoviedb.org/person/4724', 'name': 'Kevin Bacon'}, 'pathBetweenPeople': 'Viola Davis played Carol Barrett in Blackhat with Chris Hemsworth, who played Nicholas Hathaway in Blackhat with Chris Hemsworth, who played The Huntsman in Snow White and the Huntsman with Charlize Theron, who played Queen Ravenna in Snow White and the Huntsman with Charlize Theron, who played Karen Jennings in Trapped with Kevin Bacon, who played Joe Hickey in Trapped'}]
> Finished chain.
Observation: {'query': 'How many degrees of separation are there between Viola Davis and Kevin Bacon?', 'result': 'There are three degrees of separation between Viola Davis and Kevin Bacon. Viola Davis co-starred with Chris Hemsworth in Blackhat, Chris Hemsworth co-starred with Charlize Theron in Snow White and the Huntsman, and Charlize Theron co-starred with Kevin Bacon in Trapped.'}
Thought:```json
{
    "action": "Final Answer",
    "action_input": "There are three degrees of separation between Viola Davis and Kevin Bacon. Viola Davis co-starred with Chris Hemsworth in Blackhat, Chris Hemsworth co-starred with Charlize Theron in Snow White and the Huntsman, and Charlize Theron co-starred with Kevin Bacon in Trapped."
}
```
> Finished chain.

Did you get a better answer? Once you have completed the steps, click the button below to mark the lesson as completed.

Summary

In this challenge, you provided the LLM with an example Cypher statement to answer a specific type of question.

Chatbot

Hi, I am an Educational Learning Assistant for Intelligent Network Exploration. You can call me E.L.A.I.N.E.

How can I help you today?