Issue with GraphRAG Query Using LangChain & Neo4j Knowledge Graph Builder

Hello,

I'm building a DeFi AI application and want to use the Neo4j Graph Platform to store knowledge in a graph-based system.

So far, I have used the langchain.js framework along with the Neo4j LLM Knowledge Graph Builder to experiment with different ways of creating the best graph structure based on WhitePaper inputs.

I decided to use the Neo4j Knowledge Graph Builder, which generated a graph based on 10 DeFi app WhitePapers.


The issue I’m facing is related to the GraphRAG Query I am trying to run on this graph using the @langchain/community framework. Specifically, I’m using the langchain/chains/graph_qa/cypher tutorials from langchain.

When running the following code, I consistently get the INVALID_PROMPT_INPUT error (error details here), and I am unable to modify anything to resolve it.

import { Neo4jGraph } from "@langchain/community/graphs/neo4j_graph";
import { ChatOpenAI } from "@langchain/openai";
import { GraphCypherQAChain } from "@langchain/community/chains/graph_qa/cypher";
import { FewShotPromptTemplate, PromptTemplate } from "@langchain/core/prompts";
import { neo4jConfigAura } from '../config/neo4j-config-aura.js';
import { OpenAIEmbeddings } from "@langchain/openai";
import { SemanticSimilarityExampleSelector } from "@langchain/core/example_selectors";
import { Neo4jVectorStore } from "@langchain/community/vectorstores/neo4j_vector";

// Examples of questions and their corresponding Cypher queries
const examples = [
    {
        question: "What are all the whitepapers connected to the Knowledge node?",
        query: "MATCH (k:Knowledge)<-[:PART_OF]-(wp) RETURN wp.name"
    },
    {
        question: "Show me all relationships of the Uniswap whitepaper",
        query: "MATCH (wp:Document {name: 'Uniswap'})-[r]-() RETURN wp.name, type(r)"
    },
    {
        question: "What are the technical features described in the Uniswap whitepaper?", 
        query: "MATCH (d:Document {name: 'Uniswap'})-[:CONTAINS]->(f) RETURN f.name, f.description"
    },
    {
        question: "Who are the authors of the Uniswap whitepaper?",
        query: "MATCH (d:Document {name: 'Uniswap'})-[:AUTHORED_BY]->(p:PERSON) RETURN p.name, p.role"
    },
    {
        question: "What are the different protocol versions mentioned?",
        query: "MATCH (d:Document)-[:INTRODUCES]->(v:VERSION) RETURN d.name, v.version, v.description"
    },
    {
        question: "What components require other components in the architecture?",
        query: "MATCH (c1:COMPONENT)-[:REQUIRES]->(c2:COMPONENT) RETURN c1.name, c2.name"
    },
    {
        question: "What features were improved between protocol versions?",
        query: "MATCH (v1:VERSION)-[:IMPROVES]->(f:FEATURE)<-[:INTRODUCES]-(v2:VERSION) RETURN v1.version, v2.version, f.name"
    },
    {
        question: "List all components that are part of the core protocol",
        query: "MATCH (c:COMPONENT)-[:PART_OF]->(p:PROTOCOL) RETURN c.name, p.name"
    }
];

async function setupChain() {
    try {
        const graph = await Neo4jGraph.initialize(neo4jConfigAura);
        await graph.refreshSchema();
        const schema = graph.getSchema();

        const examplePrompt = PromptTemplate.fromTemplate(
            "User input: {question}\nCypher query: {query}"
        );

        const exampleSelector = await SemanticSimilarityExampleSelector.fromExamples(
            examples,
            new OpenAIEmbeddings(),
            Neo4jVectorStore,
            {
                k: 5,
                inputKeys: ["question"],
                preDeleteCollection: true,
                url: neo4jConfigAura.url,
                username: neo4jConfigAura.username,
                password: neo4jConfigAura.password
            }
        );

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

        const chain = GraphCypherQAChain.fromLLM({
            graph,
            llm: new ChatOpenAI({
                model: "gpt-3.5-turbo",
                temperature: 0,
            }),
            cypherPrompt: promptWithExampleSelector
        });

        return chain;
    } catch (error) {
        console.error("Initialization error:", error);
        throw error;
    }
}

async function queryGraph(question) {
    try {
        const chain = await setupChain();
        if (!chain) throw new Error("Failed to initialize chain");
        
        const response = await chain.invoke({ query: question });
        console.log("\nAnswer:", response.result);
    } catch (error) {
        console.error("Query error:", error);
        if (error.message) console.error("Error details:", error.message);
    }
}

// Usage example
await queryGraph("What are the core features of AAVE V1?");
// await queryGraph("Show me the technical features of Uniswap V4");
// await queryGraph("What are the similarities between Aave and Uniswap?");

Additional Context

I have successfully tested this functionality within the chatbot of the LLM Graph Builder, where it performs as expected. However, when running my code, I am unable to resolve the INVALID_PROMPT_INPUT error.

Any insights or suggestions would be greatly appreciated!

Thanks for your help,
Paul