!function(){function t(t){document.documentElement.setAttribute("data-theme",t)}var e=function(){var t=null;try{t=new URLSearchParams(window.location.search).get("docusaurus-theme")}catch(t){}return t}()||function(){var t=null;try{t=localStorage.getItem("theme")}catch(t){}return t}();t(null!==e?e:"light")}(),document.documentElement.setAttribute("data-announcement-bar-initially-dismissed",function(){try{return"true"===localStorage.getItem("docusaurus.announcement.dismiss")}catch(t){}return!1}())

[Skip to main content](#__docusaurus_skipToContent_fallback)

LangChain v0.2 is coming soon! Preview the new docs [here](/v0.2/docs/introduction/).

[

![🦜️🔗 Langchain](/v0.1/img/brand/wordmark.png)![🦜️🔗 Langchain](/v0.1/img/brand/wordmark-dark.png)

](/v0.1/)[Docs](/v0.1/docs/get_started/introduction/)[Use cases](/v0.1/docs/use_cases/)[Integrations](/v0.1/docs/integrations/platforms/)[API Reference](https://api.js.langchain.com)

[More](#)

*   [People](/v0.1/docs/people/)
*   [Community](/v0.1/docs/community/)
*   [Tutorials](/v0.1/docs/additional_resources/tutorials/)
*   [Contributing](/v0.1/docs/contributing/)

[v0.1](#)

*   [v0.2](https://js.langchain.com/v0.2/docs/introduction)
*   [v0.1](/v0.1/docs/get_started/introduction/)

[🦜🔗](#)

*   [LangSmith](https://smith.langchain.com)
*   [LangSmith Docs](https://docs.smith.langchain.com)
*   [LangChain Hub](https://smith.langchain.com/hub)
*   [LangServe](https://github.com/langchain-ai/langserve)
*   [Python Docs](https://python.langchain.com/)

[Chat](https://chatjs.langchain.com)[](https://github.com/langchain-ai/langchainjs)

Search

*   [Use cases](/v0.1/docs/use_cases/)
    
    *   [SQL](/v0.1/docs/use_cases/sql/)
        
    *   [Chatbots](/v0.1/docs/use_cases/chatbots/)
        
    *   [Extraction](/v0.1/docs/use_cases/extraction/)
        
    *   [Query Analysis](/v0.1/docs/use_cases/query_analysis/)
        
    *   [Q&A with RAG](/v0.1/docs/use_cases/question_answering/)
        
    *   [Tool use](/v0.1/docs/use_cases/tool_use/)
        
    *   [Interacting with APIs](/v0.1/docs/use_cases/api/)
    *   [Tabular Question Answering](/v0.1/docs/use_cases/tabular/)
    *   [Graphs](/v0.1/docs/use_cases/graph/)
        
        *   [Quickstart](/v0.1/docs/use_cases/graph/quickstart/)
        *   [Constructing knowledge graphs](/v0.1/docs/use_cases/graph/construction/)
        *   [Mapping values to database](/v0.1/docs/use_cases/graph/mapping/)
        *   [Semantic layer over graph database](/v0.1/docs/use_cases/graph/semantic/)
        *   [Prompting strategies](/v0.1/docs/use_cases/graph/prompting/)
    *   [Summarization](/v0.1/docs/use_cases/summarization/)
    *   [Agent Simulations](/v0.1/docs/use_cases/agent_simulations/)
        
    *   [Autonomous Agents](/v0.1/docs/use_cases/autonomous_agents/)
        
    *   [Code Understanding](/v0.1/docs/use_cases/code_understanding/)
    *   [Audio/Video Structured Extraction](/v0.1/docs/use_cases/media/)

*   [](/v0.1/)
*   [Use cases](/v0.1/docs/use_cases/)
*   [Graphs](/v0.1/docs/use_cases/graph/)
*   Prompting strategies

On this page

Prompting strategies
====================

In this guide we’ll go over prompting strategies to improve graph database query generation. We’ll largely focus on methods for getting relevant database-specific information in your prompt.

Setup[​](#setup "Direct link to Setup")
---------------------------------------

#### Install dependencies[​](#install-dependencies "Direct link to Install dependencies")

tip

See [this section for general instructions on installing integration packages](/v0.1/docs/get_started/installation/#installing-integration-packages).

*   npm
*   yarn
*   pnpm

    npm i langchain @langchain/community @langchain/openai neo4j-driver

    yarn add langchain @langchain/community @langchain/openai neo4j-driver

    pnpm add langchain @langchain/community @langchain/openai neo4j-driver

#### Set environment variables[​](#set-environment-variables "Direct link to Set environment variables")

We’ll use OpenAI in this example:

    OPENAI_API_KEY=your-api-key# Optional, use LangSmith for best-in-class observabilityLANGSMITH_API_KEY=your-api-keyLANGCHAIN_TRACING_V2=true

Next, we need to define Neo4j credentials. Follow [these installation steps](https://neo4j.com/docs/operations-manual/current/installation/) to set up a Neo4j database.

    NEO4J_URI="bolt://localhost:7687"NEO4J_USERNAME="neo4j"NEO4J_PASSWORD="password"

The below example will create a connection with a Neo4j database and will populate it with example data about movies and their actors.

    const url = Deno.env.get("NEO4J_URI");const username = Deno.env.get("NEO4J_USER");const password = Deno.env.get("NEO4J_PASSWORD");

    import "neo4j-driver";import { Neo4jGraph } from "@langchain/community/graphs/neo4j_graph";const graph = await Neo4jGraph.initialize({ url, username, password });// Import movie informationconst moviesQuery = `LOAD CSV WITH HEADERS FROM 'https://raw.githubusercontent.com/tomasonjo/blog-datasets/main/movies/movies_small.csv'AS rowMERGE (m:Movie {id:row.movieId})SET m.released = date(row.released),    m.title = row.title,    m.imdbRating = toFloat(row.imdbRating)FOREACH (director in split(row.director, '|') |     MERGE (p:Person {name:trim(director)})    MERGE (p)-[:DIRECTED]->(m))FOREACH (actor in split(row.actors, '|') |     MERGE (p:Person {name:trim(actor)})    MERGE (p)-[:ACTED_IN]->(m))FOREACH (genre in split(row.genres, '|') |     MERGE (g:Genre {name:trim(genre)})    MERGE (m)-[:IN_GENRE]->(g))`;await graph.query(moviesQuery);

    Schema refreshed successfully.

    []

Filtering graph schema
======================

At times, you may need to focus on a specific subset of the graph schema while generating Cypher statements. Let’s say we are dealing with the following graph schema:

    await graph.refreshSchema();console.log(graph.schema);

    Node properties are the following:Movie {imdbRating: FLOAT, id: STRING, released: DATE, title: STRING}, Person {name: STRING}, Genre {name: STRING}, Chunk {embedding: LIST, id: STRING, text: STRING}Relationship properties are the following:The relationships are the following:(:Movie)-[:IN_GENRE]->(:Genre), (:Person)-[:DIRECTED]->(:Movie), (:Person)-[:ACTED_IN]->(:Movie)

Few-shot examples[​](#few-shot-examples "Direct link to Few-shot examples")
---------------------------------------------------------------------------

Including examples of natural language questions being converted to valid Cypher queries against our database in the prompt will often improve model performance, especially for complex queries.

Let’s say we have the following examples:

    const examples = [  {    question: "How many artists are there?",    query: "MATCH (a:Person)-[:ACTED_IN]->(:Movie) RETURN count(DISTINCT a)",  },  {    question: "Which actors played in the movie Casino?",    query: "MATCH (m:Movie {{title: 'Casino'}})<-[:ACTED_IN]-(a) RETURN a.name",  },  {    question: "How many movies has Tom Hanks acted in?",    query:      "MATCH (a:Person {{name: 'Tom Hanks'}})-[:ACTED_IN]->(m:Movie) RETURN count(m)",  },  {    question: "List all the genres of the movie Schindler's List",    query:      "MATCH (m:Movie {{title: 'Schindler\\'s List'}})-[:IN_GENRE]->(g:Genre) RETURN g.name",  },  {    question:      "Which actors have worked in movies from both the comedy and action genres?",    query:      "MATCH (a:Person)-[:ACTED_IN]->(:Movie)-[:IN_GENRE]->(g1:Genre), (a)-[:ACTED_IN]->(:Movie)-[:IN_GENRE]->(g2:Genre) WHERE g1.name = 'Comedy' AND g2.name = 'Action' RETURN DISTINCT a.name",  },  {    question:      "Which directors have made movies with at least three different actors named 'John'?",    query:      "MATCH (d:Person)-[:DIRECTED]->(m:Movie)<-[:ACTED_IN]-(a:Person) WHERE a.name STARTS WITH 'John' WITH d, COUNT(DISTINCT a) AS JohnsCount WHERE JohnsCount >= 3 RETURN d.name",  },  {    question: "Identify movies where directors also played a role in the film.",    query:      "MATCH (p:Person)-[:DIRECTED]->(m:Movie), (p)-[:ACTED_IN]->(m) RETURN m.title, p.name",  },  {    question:      "Find the actor with the highest number of movies in the database.",    query:      "MATCH (a:Actor)-[:ACTED_IN]->(m:Movie) RETURN a.name, COUNT(m) AS movieCount ORDER BY movieCount DESC LIMIT 1",  },];

We can create a few-shot prompt with them like so:

    import { FewShotPromptTemplate, PromptTemplate } from "@langchain/core/prompts";const examplePrompt = PromptTemplate.fromTemplate(  "User input: {question}\nCypher query: {query}");const prompt = new FewShotPromptTemplate({  examples: examples.slice(0, 5),  examplePrompt,  prefix:    "You are a Neo4j expert. Given an input question, create a syntactically correct Cypher query to run.\n\nHere is the schema information\n{schema}.\n\nBelow are a number of examples of questions and their corresponding Cypher queries.",  suffix: "User input: {question}\nCypher query: ",  inputVariables: ["question", "schema"],});

    console.log(  await prompt.format({    question: "How many artists are there?",    schema: "foo",  }));

    You are a Neo4j expert. Given an input question, create a syntactically correct Cypher query to run.Here is the schema informationfoo.Below are a number of examples of questions and their corresponding Cypher queries.User input: How many artists are there?Cypher query: MATCH (a:Person)-[:ACTED_IN]->(:Movie) RETURN count(DISTINCT a)User input: Which actors played in the movie Casino?Cypher query: MATCH (m:Movie {title: 'Casino'})<-[:ACTED_IN]-(a) RETURN a.nameUser input: How many movies has Tom Hanks acted in?Cypher query: MATCH (a:Person {name: 'Tom Hanks'})-[:ACTED_IN]->(m:Movie) RETURN count(m)User input: List all the genres of the movie Schindler's ListCypher query: MATCH (m:Movie {title: 'Schindler\'s List'})-[:IN_GENRE]->(g:Genre) RETURN g.nameUser input: Which actors have worked in movies from both the comedy and action genres?Cypher query: MATCH (a:Person)-[:ACTED_IN]->(:Movie)-[:IN_GENRE]->(g1:Genre), (a)-[:ACTED_IN]->(:Movie)-[:IN_GENRE]->(g2:Genre) WHERE g1.name = 'Comedy' AND g2.name = 'Action' RETURN DISTINCT a.nameUser input: How many artists are there?Cypher query:

Dynamic few-shot examples[​](#dynamic-few-shot-examples "Direct link to Dynamic few-shot examples")
---------------------------------------------------------------------------------------------------

If we have enough examples, we may want to only include the most relevant ones in the prompt, either because they don’t fit in the model’s context window or because the long tail of examples distracts the model. And specifically, given any input we want to include the examples most relevant to that input.

We can do just this using an ExampleSelector. In this case we’ll use a [SemanticSimilarityExampleSelector](https://api.js.langchain.com/classes/langchain_core_example_selectors.SemanticSimilarityExampleSelector.html), which will store the examples in the vector database of our choosing. At runtime it will perform a similarity search between the input and our examples, and return the most semantically similar ones:

    import { OpenAIEmbeddings } from "@langchain/openai";import { SemanticSimilarityExampleSelector } from "@langchain/core/example_selectors";import { Neo4jVectorStore } from "@langchain/community/vectorstores/neo4j_vector";const exampleSelector = await SemanticSimilarityExampleSelector.fromExamples(  examples,  new OpenAIEmbeddings(),  Neo4jVectorStore,  {    k: 5,    inputKeys: ["question"],    preDeleteCollection: true,    url,    username,    password,  });

    await exampleSelector.selectExamples({  question: "how many artists are there?",});

    [  {    query: "MATCH (a:Person)-[:ACTED_IN]->(:Movie) RETURN count(DISTINCT a)",    question: "How many artists are there?"  },  {    query: "MATCH (a:Person {{name: 'Tom Hanks'}})-[:ACTED_IN]->(m:Movie) RETURN count(m)",    question: "How many movies has Tom Hanks acted in?"  },  {    query: "MATCH (a:Person)-[:ACTED_IN]->(:Movie)-[:IN_GENRE]->(g1:Genre), (a)-[:ACTED_IN]->(:Movie)-[:IN_GENRE"... 84 more characters,    question: "Which actors have worked in movies from both the comedy and action genres?"  },  {    query: "MATCH (d:Person)-[:DIRECTED]->(m:Movie)<-[:ACTED_IN]-(a:Person) WHERE a.name STARTS WITH 'John' WITH"... 71 more characters,    question: "Which directors have made movies with at least three different actors named 'John'?"  },  {    query: "MATCH (a:Actor)-[:ACTED_IN]->(m:Movie) RETURN a.name, COUNT(m) AS movieCount ORDER BY movieCount DES"... 9 more characters,    question: "Find the actor with the highest number of movies in the database."  }]

To use it, we can pass the ExampleSelector directly in to our FewShotPromptTemplate:

    const prompt = new FewShotPromptTemplate({  exampleSelector,  examplePrompt,  prefix:    "You are a Neo4j expert. Given an input question, create a syntactically correct Cypher query to run.\n\nHere is the schema information\n{schema}.\n\nBelow are a number of examples of questions and their corresponding Cypher queries.",  suffix: "User input: {question}\nCypher query: ",  inputVariables: ["question", "schema"],});

    console.log(  await prompt.format({    question: "how many artists are there?",    schema: "foo",  }));

    You are a Neo4j expert. Given an input question, create a syntactically correct Cypher query to run.Here is the schema informationfoo.Below are a number of examples of questions and their corresponding Cypher queries.User input: How many artists are there?Cypher query: MATCH (a:Person)-[:ACTED_IN]->(:Movie) RETURN count(DISTINCT a)User input: How many movies has Tom Hanks acted in?Cypher query: MATCH (a:Person {name: 'Tom Hanks'})-[:ACTED_IN]->(m:Movie) RETURN count(m)User input: Which actors have worked in movies from both the comedy and action genres?Cypher query: MATCH (a:Person)-[:ACTED_IN]->(:Movie)-[:IN_GENRE]->(g1:Genre), (a)-[:ACTED_IN]->(:Movie)-[:IN_GENRE]->(g2:Genre) WHERE g1.name = 'Comedy' AND g2.name = 'Action' RETURN DISTINCT a.nameUser input: Which directors have made movies with at least three different actors named 'John'?Cypher query: MATCH (d:Person)-[:DIRECTED]->(m:Movie)<-[:ACTED_IN]-(a:Person) WHERE a.name STARTS WITH 'John' WITH d, COUNT(DISTINCT a) AS JohnsCount WHERE JohnsCount >= 3 RETURN d.nameUser input: Find the actor with the highest number of movies in the database.Cypher query: MATCH (a:Actor)-[:ACTED_IN]->(m:Movie) RETURN a.name, COUNT(m) AS movieCount ORDER BY movieCount DESC LIMIT 1User input: how many artists are there?Cypher query:

    import { ChatOpenAI } from "@langchain/openai";import { GraphCypherQAChain } from "langchain/chains/graph_qa/cypher";const llm = new ChatOpenAI({  model: "gpt-3.5-turbo",  temperature: 0,});const chain = GraphCypherQAChain.fromLLM({  graph,  llm,  cypherPrompt: prompt,});

    await chain.invoke({  query: "How many actors are in the graph?",});

    { result: "There are 967 actors in the graph." }

* * *

#### Help us out by providing feedback on this documentation page:

[

Previous

Semantic layer over graph database

](/v0.1/docs/use_cases/graph/semantic/)[

Next

Summarization

](/v0.1/docs/use_cases/summarization/)

*   [Setup](#setup)
*   [Few-shot examples](#few-shot-examples)
*   [Dynamic few-shot examples](#dynamic-few-shot-examples)

Community

*   [Discord](https://discord.gg/cU2adEyC7w)
*   [Twitter](https://twitter.com/LangChainAI)

GitHub

*   [Python](https://github.com/langchain-ai/langchain)
*   [JS/TS](https://github.com/langchain-ai/langchainjs)

More

*   [Homepage](https://langchain.com)
*   [Blog](https://blog.langchain.dev)

Copyright © 2024 LangChain, Inc.