{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "89f63444-1230-4794-ae80-a0554558396a",
   "metadata": {
    "ExecutionIndicator": {
     "show": true
    },
    "execution": {
     "iopub.execute_input": "2026-05-14T12:15:42.284855Z",
     "iopub.status.busy": "2026-05-14T12:15:42.284683Z",
     "iopub.status.idle": "2026-05-14T12:15:46.098730Z",
     "shell.execute_reply": "2026-05-14T12:15:46.098139Z",
     "shell.execute_reply.started": "2026-05-14T12:15:42.284836Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Looking in indexes: https://mirrors.cloud.aliyuncs.com/pypi/simple\n",
      "Requirement already satisfied: neo4j in /usr/local/lib/python3.11/site-packages (6.2.0)\n",
      "Requirement already satisfied: langchain in /usr/local/lib/python3.11/site-packages (1.3.0)\n",
      "Requirement already satisfied: langchain_openai in /usr/local/lib/python3.11/site-packages (1.2.1)\n",
      "Requirement already satisfied: langchain_community in /usr/local/lib/python3.11/site-packages (0.4.1)\n",
      "Requirement already satisfied: langchain-core in /usr/local/lib/python3.11/site-packages (1.4.0)\n",
      "Requirement already satisfied: langchain_neo4j in /usr/local/lib/python3.11/site-packages (0.9.0)\n",
      "Requirement already satisfied: pytz in /usr/local/lib/python3.11/site-packages (from neo4j) (2026.1.post1)\n",
      "Requirement already satisfied: langgraph<1.3.0,>=1.2.0 in /usr/local/lib/python3.11/site-packages (from langchain) (1.2.0)\n",
      "Requirement already satisfied: pydantic<3.0.0,>=2.7.4 in /usr/local/lib/python3.11/site-packages (from langchain) (2.12.3)\n",
      "Requirement already satisfied: openai<3.0.0,>=2.26.0 in /usr/local/lib/python3.11/site-packages (from langchain_openai) (2.26.0)\n",
      "Requirement already satisfied: tiktoken<1.0.0,>=0.7.0 in /usr/local/lib/python3.11/site-packages (from langchain_openai) (0.12.0)\n",
      "Requirement already satisfied: langchain-classic<2.0.0,>=1.0.0 in /usr/local/lib/python3.11/site-packages (from langchain_community) (1.0.7)\n",
      "Requirement already satisfied: SQLAlchemy<3.0.0,>=1.4.0 in /usr/local/lib/python3.11/site-packages (from langchain_community) (2.0.49)\n",
      "Requirement already satisfied: requests<3.0.0,>=2.32.5 in /usr/local/lib/python3.11/site-packages (from langchain_community) (2.32.5)\n",
      "Requirement already satisfied: PyYAML<7.0.0,>=5.3.0 in /usr/local/lib/python3.11/site-packages (from langchain_community) (6.0.3)\n",
      "Requirement already satisfied: aiohttp<4.0.0,>=3.8.3 in /usr/local/lib/python3.11/site-packages (from langchain_community) (3.13.3)\n",
      "Requirement already satisfied: tenacity!=8.4.0,<10.0.0,>=8.1.0 in /usr/local/lib/python3.11/site-packages (from langchain_community) (9.1.4)\n",
      "Requirement already satisfied: dataclasses-json<0.7.0,>=0.6.7 in /usr/local/lib/python3.11/site-packages (from langchain_community) (0.6.7)\n",
      "Requirement already satisfied: pydantic-settings<3.0.0,>=2.10.1 in /usr/local/lib/python3.11/site-packages (from langchain_community) (2.14.1)\n",
      "Requirement already satisfied: langsmith<1.0.0,>=0.1.125 in /usr/local/lib/python3.11/site-packages (from langchain_community) (0.8.4)\n",
      "Requirement already satisfied: httpx-sse<1.0.0,>=0.4.0 in /usr/local/lib/python3.11/site-packages (from langchain_community) (0.4.3)\n",
      "Requirement already satisfied: numpy>=1.26.2 in /usr/local/lib/python3.11/site-packages (from langchain_community) (2.4.4)\n",
      "Requirement already satisfied: jsonpatch<2.0.0,>=1.33.0 in /usr/local/lib/python3.11/site-packages (from langchain-core) (1.33)\n",
      "Requirement already satisfied: langchain-protocol>=0.0.14 in /usr/local/lib/python3.11/site-packages (from langchain-core) (0.0.15)\n",
      "Requirement already satisfied: packaging>=23.2.0 in /usr/local/lib/python3.11/site-packages (from langchain-core) (26.0)\n",
      "Requirement already satisfied: typing-extensions<5.0.0,>=4.7.0 in /usr/local/lib/python3.11/site-packages (from langchain-core) (4.15.0)\n",
      "Requirement already satisfied: uuid-utils<1.0,>=0.12.0 in /usr/local/lib/python3.11/site-packages (from langchain-core) (0.15.0)\n",
      "Requirement already satisfied: neo4j-graphrag<2.0.0,>=1.12.0 in /usr/local/lib/python3.11/site-packages (from langchain_neo4j) (1.16.0)\n",
      "Requirement already satisfied: aiohappyeyeballs>=2.5.0 in /usr/local/lib/python3.11/site-packages (from aiohttp<4.0.0,>=3.8.3->langchain_community) (2.6.1)\n",
      "Requirement already satisfied: aiosignal>=1.4.0 in /usr/local/lib/python3.11/site-packages (from aiohttp<4.0.0,>=3.8.3->langchain_community) (1.4.0)\n",
      "Requirement already satisfied: attrs>=17.3.0 in /usr/local/lib/python3.11/site-packages (from aiohttp<4.0.0,>=3.8.3->langchain_community) (25.4.0)\n",
      "Requirement already satisfied: frozenlist>=1.1.1 in /usr/local/lib/python3.11/site-packages (from aiohttp<4.0.0,>=3.8.3->langchain_community) (1.8.0)\n",
      "Requirement already satisfied: multidict<7.0,>=4.5 in /usr/local/lib/python3.11/site-packages (from aiohttp<4.0.0,>=3.8.3->langchain_community) (6.7.1)\n",
      "Requirement already satisfied: propcache>=0.2.0 in /usr/local/lib/python3.11/site-packages (from aiohttp<4.0.0,>=3.8.3->langchain_community) (0.4.1)\n",
      "Requirement already satisfied: yarl<2.0,>=1.17.0 in /usr/local/lib/python3.11/site-packages (from aiohttp<4.0.0,>=3.8.3->langchain_community) (1.23.0)\n",
      "Requirement already satisfied: marshmallow<4.0.0,>=3.18.0 in /usr/local/lib/python3.11/site-packages (from dataclasses-json<0.7.0,>=0.6.7->langchain_community) (3.26.2)\n",
      "Requirement already satisfied: typing-inspect<1,>=0.4.0 in /usr/local/lib/python3.11/site-packages (from dataclasses-json<0.7.0,>=0.6.7->langchain_community) (0.9.0)\n",
      "Requirement already satisfied: jsonpointer>=1.9 in /usr/local/lib/python3.11/site-packages (from jsonpatch<2.0.0,>=1.33.0->langchain-core) (3.1.1)\n",
      "Requirement already satisfied: langchain-text-splitters<2.0.0,>=1.1.2 in /usr/local/lib/python3.11/site-packages (from langchain-classic<2.0.0,>=1.0.0->langchain_community) (1.1.2)\n",
      "Requirement already satisfied: langgraph-checkpoint<5.0.0,>=4.1.0 in /usr/local/lib/python3.11/site-packages (from langgraph<1.3.0,>=1.2.0->langchain) (4.1.0)\n",
      "Requirement already satisfied: langgraph-prebuilt<1.2.0,>=1.1.0 in /usr/local/lib/python3.11/site-packages (from langgraph<1.3.0,>=1.2.0->langchain) (1.1.0)\n",
      "Requirement already satisfied: langgraph-sdk<0.4.0,>=0.3.0 in /usr/local/lib/python3.11/site-packages (from langgraph<1.3.0,>=1.2.0->langchain) (0.3.14)\n",
      "Requirement already satisfied: xxhash>=3.5.0 in /usr/local/lib/python3.11/site-packages (from langgraph<1.3.0,>=1.2.0->langchain) (3.6.0)\n",
      "Requirement already satisfied: httpx<1,>=0.23.0 in /usr/local/lib/python3.11/site-packages (from langsmith<1.0.0,>=0.1.125->langchain_community) (0.28.1)\n",
      "Requirement already satisfied: orjson>=3.9.14 in /usr/local/lib/python3.11/site-packages (from langsmith<1.0.0,>=0.1.125->langchain_community) (3.11.7)\n",
      "Requirement already satisfied: requests-toolbelt>=1.0.0 in /usr/local/lib/python3.11/site-packages (from langsmith<1.0.0,>=0.1.125->langchain_community) (1.0.0)\n",
      "Requirement already satisfied: zstandard>=0.23.0 in /usr/local/lib/python3.11/site-packages (from langsmith<1.0.0,>=0.1.125->langchain_community) (0.25.0)\n",
      "Requirement already satisfied: fsspec>=2024.9.0 in /usr/local/lib/python3.11/site-packages (from neo4j-graphrag<2.0.0,>=1.12.0->langchain_neo4j) (2025.3.0)\n",
      "Requirement already satisfied: json-repair<1.0.0,>=0.44.1 in /usr/local/lib/python3.11/site-packages (from neo4j-graphrag<2.0.0,>=1.12.0->langchain_neo4j) (0.58.5)\n",
      "Requirement already satisfied: pypdf<7.0.0,>=6.0.0 in /usr/local/lib/python3.11/site-packages (from neo4j-graphrag<2.0.0,>=1.12.0->langchain_neo4j) (6.11.0)\n",
      "Requirement already satisfied: scipy<2.0.0,>=1.13.0 in /usr/local/lib/python3.11/site-packages (from neo4j-graphrag<2.0.0,>=1.12.0->langchain_neo4j) (1.17.1)\n",
      "Requirement already satisfied: types-pyyaml<7.0.0,>=6.0.12.20240917 in /usr/local/lib/python3.11/site-packages (from neo4j-graphrag<2.0.0,>=1.12.0->langchain_neo4j) (6.0.12.20260510)\n",
      "Requirement already satisfied: anyio<5,>=3.5.0 in /usr/local/lib/python3.11/site-packages (from openai<3.0.0,>=2.26.0->langchain_openai) (4.12.1)\n",
      "Requirement already satisfied: distro<2,>=1.7.0 in /usr/local/lib/python3.11/site-packages (from openai<3.0.0,>=2.26.0->langchain_openai) (1.9.0)\n",
      "Requirement already satisfied: jiter<1,>=0.10.0 in /usr/local/lib/python3.11/site-packages (from openai<3.0.0,>=2.26.0->langchain_openai) (0.13.0)\n",
      "Requirement already satisfied: sniffio in /usr/local/lib/python3.11/site-packages (from openai<3.0.0,>=2.26.0->langchain_openai) (1.3.1)\n",
      "Requirement already satisfied: tqdm>4 in /usr/local/lib/python3.11/site-packages (from openai<3.0.0,>=2.26.0->langchain_openai) (4.67.3)\n",
      "Requirement already satisfied: annotated-types>=0.6.0 in /usr/local/lib/python3.11/site-packages (from pydantic<3.0.0,>=2.7.4->langchain) (0.7.0)\n",
      "Requirement already satisfied: pydantic-core==2.41.4 in /usr/local/lib/python3.11/site-packages (from pydantic<3.0.0,>=2.7.4->langchain) (2.41.4)\n",
      "Requirement already satisfied: typing-inspection>=0.4.2 in /usr/local/lib/python3.11/site-packages (from pydantic<3.0.0,>=2.7.4->langchain) (0.4.2)\n",
      "Requirement already satisfied: python-dotenv>=0.21.0 in /usr/local/lib/python3.11/site-packages (from pydantic-settings<3.0.0,>=2.10.1->langchain_community) (1.2.2)\n",
      "Requirement already satisfied: charset_normalizer<4,>=2 in /usr/local/lib/python3.11/site-packages (from requests<3.0.0,>=2.32.5->langchain_community) (3.4.5)\n",
      "Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.11/site-packages (from requests<3.0.0,>=2.32.5->langchain_community) (3.11)\n",
      "Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.11/site-packages (from requests<3.0.0,>=2.32.5->langchain_community) (2.6.3)\n",
      "Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.11/site-packages (from requests<3.0.0,>=2.32.5->langchain_community) (2026.2.25)\n",
      "Requirement already satisfied: greenlet>=1 in /usr/local/lib/python3.11/site-packages (from SQLAlchemy<3.0.0,>=1.4.0->langchain_community) (3.3.2)\n",
      "Requirement already satisfied: regex>=2022.1.18 in /usr/local/lib/python3.11/site-packages (from tiktoken<1.0.0,>=0.7.0->langchain_openai) (2026.2.28)\n",
      "Requirement already satisfied: httpcore==1.* in /usr/local/lib/python3.11/site-packages (from httpx<1,>=0.23.0->langsmith<1.0.0,>=0.1.125->langchain_community) (1.0.9)\n",
      "Requirement already satisfied: h11>=0.16 in /usr/local/lib/python3.11/site-packages (from httpcore==1.*->httpx<1,>=0.23.0->langsmith<1.0.0,>=0.1.125->langchain_community) (0.16.0)\n",
      "Requirement already satisfied: ormsgpack>=1.12.0 in /usr/local/lib/python3.11/site-packages (from langgraph-checkpoint<5.0.0,>=4.1.0->langgraph<1.3.0,>=1.2.0->langchain) (1.12.2)\n",
      "Requirement already satisfied: mypy-extensions>=0.3.0 in /usr/local/lib/python3.11/site-packages (from typing-inspect<1,>=0.4.0->dataclasses-json<0.7.0,>=0.6.7->langchain_community) (1.1.0)\n",
      "\u001b[33mWARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv\u001b[0m\u001b[33m\n",
      "\u001b[0m\n",
      "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m23.3.2\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m26.1.1\u001b[0m\n",
      "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpip install --upgrade pip\u001b[0m\n"
     ]
    }
   ],
   "source": [
    "!pip install neo4j  langchain langchain_openai langchain_community langchain-core langchain_neo4j "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "df817950-3be8-4a23-bc3c-d0c9e05b11ad",
   "metadata": {
    "ExecutionIndicator": {
     "show": true
    },
    "execution": {
     "iopub.execute_input": "2026-05-14T12:16:18.150834Z",
     "iopub.status.busy": "2026-05-14T12:16:18.150629Z",
     "iopub.status.idle": "2026-05-14T12:16:18.154402Z",
     "shell.execute_reply": "2026-05-14T12:16:18.153818Z",
     "shell.execute_reply.started": "2026-05-14T12:16:18.150812Z"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "import os\n",
    "neo4j_url=os.getenv('NEO4J_URI','XXXXXXXXXXXX')#填成你们自己的信息\n",
    "neo4j_username=os.getenv('NEO4J_USERNAME','XXXXXXXX')#填成你们自己的信息\n",
    "neo4j_password=os.getenv('NEO4J_PASSWORD','XXXXXXXX')#填成你们自己的信息\n",
    "neo4j_database = os.getenv('NEO4J_DATABASE','XXXXXXXXX')#填成你们自己的信息"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "71102ef1-94f6-44ee-b893-e48b75c3f5c7",
   "metadata": {
    "ExecutionIndicator": {
     "show": true
    },
    "execution": {
     "iopub.execute_input": "2026-05-14T12:17:21.871283Z",
     "iopub.status.busy": "2026-05-14T12:17:21.871091Z",
     "iopub.status.idle": "2026-05-14T12:17:32.281677Z",
     "shell.execute_reply": "2026-05-14T12:17:32.281108Z",
     "shell.execute_reply.started": "2026-05-14T12:17:21.871266Z"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "from langchain_neo4j import Neo4jGraph\n",
    "graph = Neo4jGraph(url=neo4j_url,username=neo4j_username,password=neo4j_password,database=neo4j_database)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "be693b8f-efd9-4dcd-8b7a-4394ed4c1392",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-05-14T12:18:18.663588Z",
     "iopub.status.busy": "2026-05-14T12:18:18.663420Z",
     "iopub.status.idle": "2026-05-14T12:18:24.571131Z",
     "shell.execute_reply": "2026-05-14T12:18:24.570556Z",
     "shell.execute_reply.started": "2026-05-14T12:18:18.663574Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Node properties:\n",
      "\n",
      "Relationship properties:\n",
      "\n",
      "The relationships:\n",
      "\n"
     ]
    }
   ],
   "source": [
    "graph.refresh_schema()\n",
    "print(graph.schema)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "9cd30872-3c1c-4648-99f9-2d0834c83cfe",
   "metadata": {
    "ExecutionIndicator": {
     "show": true
    },
    "execution": {
     "iopub.execute_input": "2026-05-14T12:18:47.301195Z",
     "iopub.status.busy": "2026-05-14T12:18:47.301022Z",
     "iopub.status.idle": "2026-05-14T12:18:53.085920Z",
     "shell.execute_reply": "2026-05-14T12:18:53.085325Z",
     "shell.execute_reply.started": "2026-05-14T12:18:47.301176Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new GraphCypherQAChain chain...\u001b[0m\n",
      "Generated Cypher:\n",
      "\u001b[32;1m\u001b[1;3mPlease provide the specific details of the schema, including node properties, relationship properties, and the relationships, so I can generate the appropriate Cypher statement.\u001b[0m\n"
     ]
    },
    {
     "ename": "CypherSyntaxError",
     "evalue": "{neo4j_code: Neo.ClientError.Statement.SyntaxError} {message: Invalid input 'Please': expected 'ALTER', 'ORDER BY', 'CALL', 'USING PERIODIC COMMIT', 'CREATE', 'LOAD CSV', 'START DATABASE', 'STOP DATABASE', 'DEALLOCATE', 'DELETE', 'DENY', 'DETACH', 'DROP', 'DRYRUN', 'FINISH', 'FOREACH', 'GRANT', 'INSERT', 'LIMIT', 'MATCH', 'MERGE', 'NODETACH', 'OFFSET', 'OPTIONAL', 'REALLOCATE', 'REMOVE', 'RENAME', 'RETURN', 'REVOKE', 'ENABLE SERVER', 'SET', 'SHOW', 'SKIP', 'TERMINATE', 'UNWIND', 'USE' or 'WITH' (line 1, column 1 (offset: 0))\n\"Please provide the specific details of the schema, including node properties, relationship properties, and the relationships, so I can generate the appropriate Cypher statement.\"\n ^} {gql_status: 42001} {gql_status_description: error: syntax error or access rule violation - invalid syntax}",
     "output_type": "error",
     "traceback": [
      "\u001b[31m---------------------------------------------------------------------------\u001b[39m",
      "\u001b[31mGqlError\u001b[39m                                  Traceback (most recent call last)",
      "\u001b[31mGqlError\u001b[39m: {gql_status: 42I06} {gql_status_description: error: syntax error or access rule violation - invalid input. Invalid input 'Please', expected: 'ALTER', 'ORDER BY', 'CALL', 'USING PERIODIC COMMIT', 'CREATE', 'LOAD CSV', 'START DATABASE', 'STOP DATABASE', 'DEALLOCATE', 'DELETE', 'DENY', 'DETACH', 'DROP', 'DRYRUN', 'FINISH', 'FOREACH', 'GRANT', 'INSERT', 'LIMIT', 'MATCH', 'MERGE', 'NODETACH', 'OFFSET', 'OPTIONAL', 'REALLOCATE', 'REMOVE', 'RENAME', 'RETURN', 'REVOKE', 'ENABLE SERVER', 'SET', 'SHOW', 'SKIP', 'TERMINATE', 'UNWIND', 'USE' or 'WITH'.} {message: 42I06: Invalid input 'Please', expected: 'ALTER', 'ORDER BY', 'CALL', 'USING PERIODIC COMMIT', 'CREATE', 'LOAD CSV', 'START DATABASE', 'STOP DATABASE', 'DEALLOCATE', 'DELETE', 'DENY', 'DETACH', 'DROP', 'DRYRUN', 'FINISH', 'FOREACH', 'GRANT', 'INSERT', 'LIMIT', 'MATCH', 'MERGE', 'NODETACH', 'OFFSET', 'OPTIONAL', 'REALLOCATE', 'REMOVE', 'RENAME', 'RETURN', 'REVOKE', 'ENABLE SERVER', 'SET', 'SHOW', 'SKIP', 'TERMINATE', 'UNWIND', 'USE' or 'WITH'.} {diagnostic_record: {'_classification': 'CLIENT_ERROR', '_position': {'offset': 0, 'column': 1, 'line': 1}, 'OPERATION': '', 'OPERATION_CODE': '0', 'CURRENT_SCHEMA': '/'}} {raw_classification: CLIENT_ERROR}",
      "\nThe above exception was the direct cause of the following exception:\n",
      "\u001b[31mCypherSyntaxError\u001b[39m                         Traceback (most recent call last)",
      "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[6]\u001b[39m\u001b[32m, line 13\u001b[39m\n\u001b[32m      5\u001b[39m chat = ChatOpenAI(\n\u001b[32m      6\u001b[39m     openai_api_key=os.environ[\u001b[33m\"\u001b[39m\u001b[33mOPENAI_API_KEY\u001b[39m\u001b[33m\"\u001b[39m],\n\u001b[32m      7\u001b[39m     model=\u001b[33m'\u001b[39m\u001b[33mgpt-4o-mini\u001b[39m\u001b[33m'\u001b[39m,\n\u001b[32m      8\u001b[39m     temperature=\u001b[32m0\u001b[39m\n\u001b[32m      9\u001b[39m )\n\u001b[32m     10\u001b[39m chain = GraphCypherQAChain.from_llm(\n\u001b[32m     11\u001b[39m     cypher_llm=chat,qa_llm=chat, graph=graph, verbose=\u001b[38;5;28;01mTrue\u001b[39;00m,allow_dangerous_requests=\u001b[38;5;28;01mTrue\u001b[39;00m\n\u001b[32m     12\u001b[39m )\n\u001b[32m---> \u001b[39m\u001b[32m13\u001b[39m result=\u001b[43mchain\u001b[49m\u001b[43m.\u001b[49m\u001b[43minvoke\u001b[49m\u001b[43m(\u001b[49m\u001b[43m{\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mquery\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m}\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m     14\u001b[39m \u001b[38;5;28mprint\u001b[39m(result)\n",
      "\u001b[36mFile \u001b[39m\u001b[32m/usr/local/lib/python3.11/site-packages/langchain_classic/chains/base.py:167\u001b[39m, in \u001b[36mChain.invoke\u001b[39m\u001b[34m(self, input, config, **kwargs)\u001b[39m\n\u001b[32m    164\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m    165\u001b[39m     \u001b[38;5;28mself\u001b[39m._validate_inputs(inputs)\n\u001b[32m    166\u001b[39m     outputs = (\n\u001b[32m--> \u001b[39m\u001b[32m167\u001b[39m         \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_call\u001b[49m\u001b[43m(\u001b[49m\u001b[43minputs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mrun_manager\u001b[49m\u001b[43m=\u001b[49m\u001b[43mrun_manager\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m    168\u001b[39m         \u001b[38;5;28;01mif\u001b[39;00m new_arg_supported\n\u001b[32m    169\u001b[39m         \u001b[38;5;28;01melse\u001b[39;00m \u001b[38;5;28mself\u001b[39m._call(inputs)\n\u001b[32m    170\u001b[39m     )\n\u001b[32m    172\u001b[39m     final_outputs: \u001b[38;5;28mdict\u001b[39m[\u001b[38;5;28mstr\u001b[39m, Any] = \u001b[38;5;28mself\u001b[39m.prep_outputs(\n\u001b[32m    173\u001b[39m         inputs,\n\u001b[32m    174\u001b[39m         outputs,\n\u001b[32m    175\u001b[39m         return_only_outputs,\n\u001b[32m    176\u001b[39m     )\n\u001b[32m    177\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mBaseException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n",
      "\u001b[36mFile \u001b[39m\u001b[32m/usr/local/lib/python3.11/site-packages/langchain_neo4j/chains/graph_qa/cypher.py:359\u001b[39m, in \u001b[36mGraphCypherQAChain._call\u001b[39m\u001b[34m(self, inputs, run_manager)\u001b[39m\n\u001b[32m    356\u001b[39m \u001b[38;5;66;03m# Retrieve and limit the number of results\u001b[39;00m\n\u001b[32m    357\u001b[39m \u001b[38;5;66;03m# Generated Cypher be null if query corrector identifies invalid schema\u001b[39;00m\n\u001b[32m    358\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m generated_cypher:\n\u001b[32m--> \u001b[39m\u001b[32m359\u001b[39m     context = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mgraph\u001b[49m\u001b[43m.\u001b[49m\u001b[43mquery\u001b[49m\u001b[43m(\u001b[49m\u001b[43mgenerated_cypher\u001b[49m\u001b[43m)\u001b[49m[: \u001b[38;5;28mself\u001b[39m.top_k]\n\u001b[32m    360\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m    361\u001b[39m     context = []\n",
      "\u001b[36mFile \u001b[39m\u001b[32m/usr/local/lib/python3.11/site-packages/langchain_neo4j/graphs/neo4j_graph.py:245\u001b[39m, in \u001b[36mNeo4jGraph.query\u001b[39m\u001b[34m(self, query, params, session_params)\u001b[39m\n\u001b[32m    243\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m session_params:\n\u001b[32m    244\u001b[39m     \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m245\u001b[39m         data, _, _ = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_driver\u001b[49m\u001b[43m.\u001b[49m\u001b[43mexecute_query\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m    246\u001b[39m \u001b[43m            \u001b[49m\u001b[43mQuery\u001b[49m\u001b[43m(\u001b[49m\u001b[43mtext\u001b[49m\u001b[43m=\u001b[49m\u001b[43mquery\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m    247\u001b[39m \u001b[43m            \u001b[49m\u001b[43mdatabase_\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_database\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m    248\u001b[39m \u001b[43m            \u001b[49m\u001b[43mparameters_\u001b[49m\u001b[43m=\u001b[49m\u001b[43mparams\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m    249\u001b[39m \u001b[43m        \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m    250\u001b[39m         json_data = [r.data() \u001b[38;5;28;01mfor\u001b[39;00m r \u001b[38;5;129;01min\u001b[39;00m data]\n\u001b[32m    251\u001b[39m         \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m.sanitize:\n",
      "\u001b[36mFile \u001b[39m\u001b[32m/usr/local/lib/python3.11/site-packages/neo4j/_sync/driver.py:950\u001b[39m, in \u001b[36mDriver.execute_query\u001b[39m\u001b[34m(self, query_, parameters_, routing_, database_, impersonated_user_, bookmark_manager_, auth_, result_transformer_, **kwargs)\u001b[39m\n\u001b[32m    946\u001b[39m     \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\n\u001b[32m    947\u001b[39m         \u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mInvalid routing control value: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mrouting_\u001b[38;5;132;01m!r}\u001b[39;00m\u001b[33m\"\u001b[39m\n\u001b[32m    948\u001b[39m     )\n\u001b[32m    949\u001b[39m \u001b[38;5;28;01mwith\u001b[39;00m session._pipelined_begin:\n\u001b[32m--> \u001b[39m\u001b[32m950\u001b[39m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43msession\u001b[49m\u001b[43m.\u001b[49m\u001b[43m_run_transaction\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m    951\u001b[39m \u001b[43m        \u001b[49m\u001b[43maccess_mode\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m    952\u001b[39m \u001b[43m        \u001b[49m\u001b[43mTelemetryAPI\u001b[49m\u001b[43m.\u001b[49m\u001b[43mDRIVER\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m    953\u001b[39m \u001b[43m        \u001b[49m\u001b[43mwork\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m    954\u001b[39m \u001b[43m        \u001b[49m\u001b[43m(\u001b[49m\u001b[43mquery_str\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mparameters\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mresult_transformer_\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m    955\u001b[39m \u001b[43m        \u001b[49m\u001b[43m{\u001b[49m\u001b[43m}\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m    956\u001b[39m \u001b[43m    \u001b[49m\u001b[43m)\u001b[49m\n",
      "\u001b[36mFile \u001b[39m\u001b[32m/usr/local/lib/python3.11/site-packages/neo4j/_sync/work/session.py:577\u001b[39m, in \u001b[36mSession._run_transaction\u001b[39m\u001b[34m(self, access_mode, api, transaction_function, args, kwargs)\u001b[39m\n\u001b[32m    575\u001b[39m tx = \u001b[38;5;28mself\u001b[39m._transaction\n\u001b[32m    576\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m577\u001b[39m     result = \u001b[43mtransaction_function\u001b[49m\u001b[43m(\u001b[49m\u001b[43mtx\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m    578\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m asyncio.CancelledError:\n\u001b[32m    579\u001b[39m     \u001b[38;5;66;03m# if cancellation callback has not been called yet:\u001b[39;00m\n\u001b[32m    580\u001b[39m     \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m._transaction \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n",
      "\u001b[36mFile \u001b[39m\u001b[32m/usr/local/lib/python3.11/site-packages/neo4j/_work/query.py:142\u001b[39m, in \u001b[36munit_of_work.<locals>.wrapper.<locals>.wrapped\u001b[39m\u001b[34m(*args, **kwargs)\u001b[39m\n\u001b[32m    141\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mwrapped\u001b[39m(*args, **kwargs):\n\u001b[32m--> \u001b[39m\u001b[32m142\u001b[39m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mf\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n",
      "\u001b[36mFile \u001b[39m\u001b[32m/usr/local/lib/python3.11/site-packages/neo4j/_sync/driver.py:1302\u001b[39m, in \u001b[36m_work\u001b[39m\u001b[34m(tx, query, parameters, transformer)\u001b[39m\n\u001b[32m   1296\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34m_work\u001b[39m(\n\u001b[32m   1297\u001b[39m     tx: ManagedTransaction,\n\u001b[32m   1298\u001b[39m     query: t.LiteralString,\n\u001b[32m   1299\u001b[39m     parameters: \u001b[38;5;28mdict\u001b[39m[\u001b[38;5;28mstr\u001b[39m, t.Any],\n\u001b[32m   1300\u001b[39m     transformer: t.Callable[[Result], t.Union[_T]],\n\u001b[32m   1301\u001b[39m ) -> _T:\n\u001b[32m-> \u001b[39m\u001b[32m1302\u001b[39m     res = \u001b[43mtx\u001b[49m\u001b[43m.\u001b[49m\u001b[43mrun\u001b[49m\u001b[43m(\u001b[49m\u001b[43mquery\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mparameters\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m   1303\u001b[39m     \u001b[38;5;28;01mreturn\u001b[39;00m transformer(res)\n",
      "\u001b[36mFile \u001b[39m\u001b[32m/usr/local/lib/python3.11/site-packages/neo4j/_sync/work/transaction.py:201\u001b[39m, in \u001b[36mTransactionBase.run\u001b[39m\u001b[34m(self, query, parameters, **kwparameters)\u001b[39m\n\u001b[32m    198\u001b[39m \u001b[38;5;28mself\u001b[39m._results.append(result)\n\u001b[32m    200\u001b[39m parameters = \u001b[38;5;28mdict\u001b[39m(parameters \u001b[38;5;129;01mor\u001b[39;00m {}, **kwparameters)\n\u001b[32m--> \u001b[39m\u001b[32m201\u001b[39m \u001b[43mresult\u001b[49m\u001b[43m.\u001b[49m\u001b[43m_tx_ready_run\u001b[49m\u001b[43m(\u001b[49m\u001b[43mquery\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mparameters\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m    203\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m result\n",
      "\u001b[36mFile \u001b[39m\u001b[32m/usr/local/lib/python3.11/site-packages/neo4j/_sync/work/result.py:180\u001b[39m, in \u001b[36mResult._tx_ready_run\u001b[39m\u001b[34m(self, query, parameters)\u001b[39m\n\u001b[32m    176\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34m_tx_ready_run\u001b[39m(\u001b[38;5;28mself\u001b[39m, query, parameters):\n\u001b[32m    177\u001b[39m     \u001b[38;5;66;03m# BEGIN+RUN does not carry any extra on the RUN message.\u001b[39;00m\n\u001b[32m    178\u001b[39m     \u001b[38;5;66;03m# BEGIN {extra}\u001b[39;00m\n\u001b[32m    179\u001b[39m     \u001b[38;5;66;03m# RUN \"query\" {parameters} {extra}\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m180\u001b[39m     \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_run\u001b[49m\u001b[43m(\u001b[49m\u001b[43mquery\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mparameters\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mNone\u001b[39;49;00m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mNone\u001b[39;49;00m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mNone\u001b[39;49;00m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mNone\u001b[39;49;00m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mNone\u001b[39;49;00m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mNone\u001b[39;49;00m\u001b[43m)\u001b[49m\n",
      "\u001b[36mFile \u001b[39m\u001b[32m/usr/local/lib/python3.11/site-packages/neo4j/_sync/work/result.py:240\u001b[39m, in \u001b[36mResult._run\u001b[39m\u001b[34m(self, query, parameters, db, imp_user, access_mode, bookmarks, notifications_min_severity, notifications_disabled_classifications)\u001b[39m\n\u001b[32m    238\u001b[39m \u001b[38;5;28mself\u001b[39m._pull()\n\u001b[32m    239\u001b[39m \u001b[38;5;28mself\u001b[39m._connection.send_all()\n\u001b[32m--> \u001b[39m\u001b[32m240\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_attach\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n",
      "\u001b[36mFile \u001b[39m\u001b[32m/usr/local/lib/python3.11/site-packages/neo4j/_sync/work/result.py:441\u001b[39m, in \u001b[36mResult._attach\u001b[39m\u001b[34m(self)\u001b[39m\n\u001b[32m    439\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m._exhausted \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mFalse\u001b[39;00m:\n\u001b[32m    440\u001b[39m     \u001b[38;5;28;01mwhile\u001b[39;00m \u001b[38;5;28mself\u001b[39m._attached \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mFalse\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m441\u001b[39m         \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_connection\u001b[49m\u001b[43m.\u001b[49m\u001b[43mfetch_message\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n",
      "\u001b[36mFile \u001b[39m\u001b[32m/usr/local/lib/python3.11/site-packages/neo4j/_sync/io/_common.py:193\u001b[39m, in \u001b[36mConnectionErrorHandler.__getattr__.<locals>.outer.<locals>.inner\u001b[39m\u001b[34m(*args, **kwargs)\u001b[39m\n\u001b[32m    191\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34minner\u001b[39m(*args, **kwargs):\n\u001b[32m    192\u001b[39m     \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m193\u001b[39m         \u001b[43mfunc\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m    194\u001b[39m     \u001b[38;5;28;01mexcept\u001b[39;00m (Neo4jError, ServiceUnavailable, SessionExpired) \u001b[38;5;28;01mas\u001b[39;00m exc:\n\u001b[32m    195\u001b[39m         \u001b[38;5;28;01massert\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m inspect.iscoroutinefunction(\u001b[38;5;28mself\u001b[39m.__on_error)\n",
      "\u001b[36mFile \u001b[39m\u001b[32m/usr/local/lib/python3.11/site-packages/neo4j/_sync/io/_bolt.py:868\u001b[39m, in \u001b[36mBolt.fetch_message\u001b[39m\u001b[34m(self)\u001b[39m\n\u001b[32m    864\u001b[39m \u001b[38;5;66;03m# Receive exactly one message\u001b[39;00m\n\u001b[32m    865\u001b[39m tag, fields = \u001b[38;5;28mself\u001b[39m.inbox.pop(\n\u001b[32m    866\u001b[39m     hydration_hooks=\u001b[38;5;28mself\u001b[39m.responses[\u001b[32m0\u001b[39m].hydration_hooks\n\u001b[32m    867\u001b[39m )\n\u001b[32m--> \u001b[39m\u001b[32m868\u001b[39m res = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_process_message\u001b[49m\u001b[43m(\u001b[49m\u001b[43mtag\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mfields\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m    869\u001b[39m \u001b[38;5;28mself\u001b[39m.idle_since = monotonic()\n\u001b[32m    870\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m res\n",
      "\u001b[36mFile \u001b[39m\u001b[32m/usr/local/lib/python3.11/site-packages/neo4j/_sync/io/_bolt6.py:548\u001b[39m, in \u001b[36mBolt6x0._process_message\u001b[39m\u001b[34m(self, tag, fields)\u001b[39m\n\u001b[32m    546\u001b[39m \u001b[38;5;28mself\u001b[39m._enrich_error_diagnostic_record(summary_metadata)\n\u001b[32m    547\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m548\u001b[39m     \u001b[43mresponse\u001b[49m\u001b[43m.\u001b[49m\u001b[43mon_failure\u001b[49m\u001b[43m(\u001b[49m\u001b[43msummary_metadata\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01mor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43m{\u001b[49m\u001b[43m}\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m    549\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m (ServiceUnavailable, DatabaseUnavailable):\n\u001b[32m    550\u001b[39m     \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m.pool:\n",
      "\u001b[36mFile \u001b[39m\u001b[32m/usr/local/lib/python3.11/site-packages/neo4j/_sync/io/_common.py:263\u001b[39m, in \u001b[36mResponse.on_failure\u001b[39m\u001b[34m(self, metadata)\u001b[39m\n\u001b[32m    261\u001b[39m handler = \u001b[38;5;28mself\u001b[39m.handlers.get(\u001b[33m\"\u001b[39m\u001b[33mon_summary\u001b[39m\u001b[33m\"\u001b[39m)\n\u001b[32m    262\u001b[39m Util.callback(handler)\n\u001b[32m--> \u001b[39m\u001b[32m263\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;28mself\u001b[39m._hydrate_error(metadata)\n",
      "\u001b[31mCypherSyntaxError\u001b[39m: {neo4j_code: Neo.ClientError.Statement.SyntaxError} {message: Invalid input 'Please': expected 'ALTER', 'ORDER BY', 'CALL', 'USING PERIODIC COMMIT', 'CREATE', 'LOAD CSV', 'START DATABASE', 'STOP DATABASE', 'DEALLOCATE', 'DELETE', 'DENY', 'DETACH', 'DROP', 'DRYRUN', 'FINISH', 'FOREACH', 'GRANT', 'INSERT', 'LIMIT', 'MATCH', 'MERGE', 'NODETACH', 'OFFSET', 'OPTIONAL', 'REALLOCATE', 'REMOVE', 'RENAME', 'RETURN', 'REVOKE', 'ENABLE SERVER', 'SET', 'SHOW', 'SKIP', 'TERMINATE', 'UNWIND', 'USE' or 'WITH' (line 1, column 1 (offset: 0))\n\"Please provide the specific details of the schema, including node properties, relationship properties, and the relationships, so I can generate the appropriate Cypher statement.\"\n ^} {gql_status: 42001} {gql_status_description: error: syntax error or access rule violation - invalid syntax}"
     ]
    }
   ],
   "source": [
    "from langchain_neo4j import GraphCypherQAChain\n",
    "from langchain_openai import ChatOpenAI\n",
    "os.environ['OPENAI_API_KEY'] = \"sk-q4U13e0730fabd22176af25b9454c7896610386fc114fi4t\"\n",
    "os.environ[\"OPENAI_API_BASE\"] = \"https://api.gptsapi.net/v1\"\n",
    "chat = ChatOpenAI(\n",
    "    openai_api_key=os.environ[\"OPENAI_API_KEY\"],\n",
    "    model='gpt-4o-mini',\n",
    "    temperature=0\n",
    ")\n",
    "chain = GraphCypherQAChain.from_llm(\n",
    "    cypher_llm=chat,qa_llm=chat, graph=graph, verbose=True,allow_dangerous_requests=True\n",
    ")\n",
    "result=chain.invoke({\"query\": \"\"})\n",
    "print(result)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "78809158-a54d-42d4-b28e-6955a0c73f1c",
   "metadata": {},
   "source": [
    "## 知识图谱构建"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "34d8c645-5ff4-4964-b982-3d1e54124015",
   "metadata": {
    "ExecutionIndicator": {
     "show": true
    },
    "execution": {
     "iopub.execute_input": "2026-05-14T12:18:58.281131Z",
     "iopub.status.busy": "2026-05-14T12:18:58.280965Z",
     "iopub.status.idle": "2026-05-14T12:18:58.291912Z",
     "shell.execute_reply": "2026-05-14T12:18:58.291313Z",
     "shell.execute_reply.started": "2026-05-14T12:18:58.281116Z"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# 常见的数据处理\n",
    "import textwrap\n",
    "\n",
    "# Langchain\n",
    "from langchain_neo4j import Neo4jGraph\n",
    "from langchain_community.vectorstores import Neo4jVector\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "3859ffd3-0414-42ad-985b-3b1ef06298aa",
   "metadata": {
    "ExecutionIndicator": {
     "show": true
    },
    "execution": {
     "iopub.execute_input": "2026-05-14T12:18:59.321136Z",
     "iopub.status.busy": "2026-05-14T12:18:59.320970Z",
     "iopub.status.idle": "2026-05-14T12:19:06.104531Z",
     "shell.execute_reply": "2026-05-14T12:19:06.103989Z",
     "shell.execute_reply.started": "2026-05-14T12:18:59.321120Z"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "graph = Neo4jGraph(\n",
    "    url=neo4j_url, username=neo4j_username, password=neo4j_password, database=neo4j_database\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "71fc9a0c-18cf-4f4a-9903-671a5f840c07",
   "metadata": {
    "ExecutionIndicator": {
     "show": true
    },
    "execution": {
     "iopub.execute_input": "2026-05-14T12:19:08.055453Z",
     "iopub.status.busy": "2026-05-14T12:19:08.055273Z",
     "iopub.status.idle": "2026-05-14T12:19:10.528705Z",
     "shell.execute_reply": "2026-05-14T12:19:10.528124Z",
     "shell.execute_reply.started": "2026-05-14T12:19:08.055438Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "数据插入成功！\n",
      "\n",
      "示例关系：\n",
      "哪吒 -> ENEMY_OF -> 东海龙王三太子\n",
      "李靖 -> FATHER_OF -> 哪吒\n",
      "李靖 -> FATHER_OF -> 金吒\n",
      "李靖 -> FATHER_OF -> 木吒\n",
      "殷夫人 -> MOTHER_OF -> 哪吒\n"
     ]
    }
   ],
   "source": [
    "\n",
    "nezha_data = {\n",
    "    \"nodes\": [\n",
    "        {\"name\": \"哪吒\", \"title\": \"三太子\", \"type\": \"Deity\", \"weapon\": \"火尖枪\"},\n",
    "        {\"name\": \"李靖\", \"title\": \"托塔天王\", \"type\": \"Deity\", \"weapon\": \"七宝玲珑塔\"},\n",
    "        {\"name\": \"殷夫人\", \"title\": \"李靖夫人\", \"type\": \"Human\"},\n",
    "        {\"name\": \"太乙真人\", \"title\": \"昆仑十二金仙\", \"type\": \"Deity\"},\n",
    "        {\"name\": \"东海龙王三太子\", \"title\": \"敖丙\", \"type\": \"Dragon\"},\n",
    "        {\"name\": \"金吒\", \"title\": \"大太子\", \"type\": \"Deity\"},\n",
    "        {\"name\": \"木吒\", \"title\": \"二太子\", \"type\": \"Deity\"}\n",
    "    ],\n",
    "    \"relationships\": [\n",
    "        {\"source\": \"李靖\", \"target\": \"哪吒\", \"type\": \"FATHER_OF\"},\n",
    "        {\"source\": \"殷夫人\", \"target\": \"哪吒\", \"type\": \"MOTHER_OF\"},\n",
    "        {\"source\": \"太乙真人\", \"target\": \"哪吒\", \"type\": \"MASTER_OF\"},\n",
    "        {\"source\": \"哪吒\", \"target\": \"东海龙王三太子\", \"type\": \"ENEMY_OF\"},\n",
    "        {\"source\": \"李靖\", \"target\": \"金吒\", \"type\": \"FATHER_OF\"},\n",
    "        {\"source\": \"李靖\", \"target\": \"木吒\", \"type\": \"FATHER_OF\"},\n",
    "        {\"source\": \"金吒\", \"target\": \"木吒\", \"type\": \"BROTHER_OF\"},\n",
    "        {\"source\": \"金吒\", \"target\": \"哪吒\", \"type\": \"BROTHER_OF\"},\n",
    "        {\"source\": \"木吒\", \"target\": \"哪吒\", \"type\": \"BROTHER_OF\"}\n",
    "    ]\n",
    "}\n",
    "\n",
    "\n",
    "create_nodes = \"\"\"\n",
    "UNWIND $nodes AS node\n",
    "MERGE (n:Person {name: node.name})\n",
    "SET n.title = node.title,\n",
    "    n.type = node.type,\n",
    "    n.weapon = node.weapon\n",
    "\"\"\"\n",
    "\n",
    "\n",
    "\n",
    "create_relationships = \"\"\"\n",
    "UNWIND $rels AS rel\n",
    "MATCH (a:Person {name: rel.source}), (b:Person {name: rel.target})\n",
    "MERGE (a)-[r:RELATIONSHIP {type: rel.type}]->(b)\n",
    "\"\"\"\n",
    "\n",
    "try:\n",
    "    graph.query(create_nodes, params={\"nodes\": nezha_data[\"nodes\"]})\n",
    "    graph.query(create_relationships, params={\"rels\": nezha_data[\"relationships\"]})\n",
    "    print(\"数据插入成功！\")\n",
    "    \n",
    "    # 验证查询\n",
    "    result = graph.query(\"\"\"\n",
    "        MATCH (n:Person)-[r]->(m)\n",
    "        RETURN n.name as source, r.type as relationship, m.name as target\n",
    "        LIMIT 5\n",
    "    \"\"\")\n",
    "    print(\"\\n示例关系：\")\n",
    "    for row in result:\n",
    "        print(f\"{row['source']} -> {row['relationship']} -> {row['target']}\")\n",
    "\n",
    "except Exception as e:\n",
    "    print(f\"插入数据时出错: {e}\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "df536a0a-ac17-47cb-8d59-31b6e369ebe0",
   "metadata": {
    "ExecutionIndicator": {
     "show": true
    },
    "execution": {
     "iopub.execute_input": "2026-05-14T12:19:28.191447Z",
     "iopub.status.busy": "2026-05-14T12:19:28.191241Z",
     "iopub.status.idle": "2026-05-14T12:19:33.220930Z",
     "shell.execute_reply": "2026-05-14T12:19:33.220307Z",
     "shell.execute_reply.started": "2026-05-14T12:19:28.191430Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new GraphCypherQAChain chain...\u001b[0m\n",
      "Generated Cypher:\n",
      "\u001b[32;1m\u001b[1;3mMATCH (n:Character {name: '哪吒'})-[:HAS_BROTHER]->(b:Character) RETURN COUNT(b) AS brotherCount\u001b[0m\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Received notification from DBMS server: <GqlStatusObject gql_status='01N51', status_description='warn: relationship type does not exist. The relationship type `HAS_BROTHER` does not exist in database `0040b08d`. Verify that the spelling is correct.', position=<SummaryInputPosition line=1, column=36, offset=35>, raw_classification='UNRECOGNIZED', classification=<NotificationClassification.UNRECOGNIZED: 'UNRECOGNIZED'>, raw_severity='WARNING', severity=<NotificationSeverity.WARNING: 'WARNING'>, diagnostic_record={'_classification': 'UNRECOGNIZED', '_severity': 'WARNING', '_position': {'offset': 35, 'line': 1, 'column': 36}, 'OPERATION': '', 'OPERATION_CODE': '0', 'CURRENT_SCHEMA': '/'}> for query: \"MATCH (n:Character {name: '哪吒'})-[:HAS_BROTHER]->(b:Character) RETURN COUNT(b) AS brotherCount\"\n",
      "Received notification from DBMS server: <GqlStatusObject gql_status='01N50', status_description='warn: label does not exist. The label `Character` does not exist in database `0040b08d`. Verify that the spelling is correct.', position=<SummaryInputPosition line=1, column=10, offset=9>, raw_classification='UNRECOGNIZED', classification=<NotificationClassification.UNRECOGNIZED: 'UNRECOGNIZED'>, raw_severity='WARNING', severity=<NotificationSeverity.WARNING: 'WARNING'>, diagnostic_record={'_classification': 'UNRECOGNIZED', '_severity': 'WARNING', '_position': {'offset': 9, 'line': 1, 'column': 10}, 'OPERATION': '', 'OPERATION_CODE': '0', 'CURRENT_SCHEMA': '/'}> for query: \"MATCH (n:Character {name: '哪吒'})-[:HAS_BROTHER]->(b:Character) RETURN COUNT(b) AS brotherCount\"\n",
      "Received notification from DBMS server: <GqlStatusObject gql_status='01N50', status_description='warn: label does not exist. The label `Character` does not exist in database `0040b08d`. Verify that the spelling is correct.', position=<SummaryInputPosition line=1, column=53, offset=52>, raw_classification='UNRECOGNIZED', classification=<NotificationClassification.UNRECOGNIZED: 'UNRECOGNIZED'>, raw_severity='WARNING', severity=<NotificationSeverity.WARNING: 'WARNING'>, diagnostic_record={'_classification': 'UNRECOGNIZED', '_severity': 'WARNING', '_position': {'offset': 52, 'line': 1, 'column': 53}, 'OPERATION': '', 'OPERATION_CODE': '0', 'CURRENT_SCHEMA': '/'}> for query: \"MATCH (n:Character {name: '哪吒'})-[:HAS_BROTHER]->(b:Character) RETURN COUNT(b) AS brotherCount\"\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Full Context:\n",
      "\u001b[32;1m\u001b[1;3m[{'brotherCount': 0}]\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished chain.\u001b[0m\n",
      "{'query': '哪吒的兄弟多少人？', 'result': '哪吒没有兄弟。'}\n"
     ]
    }
   ],
   "source": [
    "\n",
    "\n",
    "# 提出一个问题\n",
    "chat = ChatOpenAI(\n",
    "    openai_api_key=os.environ[\"OPENAI_API_KEY\"],\n",
    "    model='gpt-4o-mini',\n",
    "    temperature=0\n",
    ")\n",
    "chain = GraphCypherQAChain.from_llm(\n",
    "    cypher_llm=chat,qa_llm=chat, graph=graph, verbose=True,allow_dangerous_requests=True\n",
    ")\n",
    "result=chain.invoke({\"query\": \"哪吒的兄弟多少人？\"})\n",
    "print(result)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9ca026ff-ec67-40a8-b511-34d484866dd1",
   "metadata": {
    "tags": []
   },
   "source": [
    "## 知识图谱查询优化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "91d74f90-0c7c-4c5d-8a56-bd3aa688927c",
   "metadata": {
    "ExecutionIndicator": {
     "show": true
    },
    "execution": {
     "iopub.execute_input": "2026-05-14T12:19:33.274882Z",
     "iopub.status.busy": "2026-05-14T12:19:33.274709Z",
     "iopub.status.idle": "2026-05-14T12:19:33.304272Z",
     "shell.execute_reply": "2026-05-14T12:19:33.303839Z",
     "shell.execute_reply.started": "2026-05-14T12:19:33.274867Z"
    },
    "scrolled": true,
    "tags": []
   },
   "outputs": [],
   "source": [
    "from langchain_classic.chains import LLMChain\n",
    "from langchain_classic.prompts import PromptTemplate\n",
    "import json\n",
    "\n",
    "class Neo4jQAExpert:\n",
    "    def __init__(self, graph, llm):\n",
    "        self.graph = graph\n",
    "        self.llm = llm\n",
    "        \n",
    "        self.cypher_prompt = PromptTemplate(\n",
    "            input_variables=[\"question\"],  # 仅需问题输入\n",
    "            template=\"\"\"\n",
    "            你是一个Neo4j专家，根据问题生成Cypher查询。\n",
    "            已知数据模型：\n",
    "            - 节点标签：Person\n",
    "            - 节点属性：name, title, type, weapon\n",
    "            - 关系类型：RELATIONSHIP (通过type属性区分具体关系)\n",
    "            \n",
    "            示例问题：哪吒的师傅是谁？\n",
    "            正确查询：MATCH (n:Person {{name:'哪吒'}})<-[:RELATIONSHIP {{type:'MASTER_OF'}}]-(m) RETURN m.name\n",
    "            \n",
    "            当前问题：{question}\n",
    "            生成的Cypher语句：\n",
    "            \"\"\"\n",
    "        )\n",
    "        \n",
    "        self.cypher_chain = LLMChain(\n",
    "            llm=self.llm,\n",
    "            prompt=self.cypher_prompt,\n",
    "            output_key=\"cypher\"\n",
    "        )\n",
    "    \n",
    "    def ask(self, question: str) -> str:\n",
    "        try:\n",
    "            # 生成Cypher\n",
    "            result = self.cypher_chain.invoke({\"question\": question})\n",
    "            cypher = result[\"cypher\"].strip().replace(\"`\", \"\")  # 清理反引号\n",
    "            \n",
    "            # 执行查询\n",
    "            graph_result = self.graph.query(cypher)\n",
    "            \n",
    "            # 格式化结果\n",
    "            return self._format_response(question, graph_result)\n",
    "        except Exception as e:\n",
    "            return f\"执行出错：{str(e)}\"\n",
    "\n",
    "    def _format_response(self, question: str, result: list) -> str:\n",
    "        \"\"\"将数据库结果转换为自然语言\"\"\"\n",
    "        if not result:\n",
    "            return \"未找到相关信息\"\n",
    "            \n",
    "        answer_prompt = \"\"\"\n",
    "        根据以下数据回答问题：\n",
    "        问题：{question}\n",
    "        结果：{result}\n",
    "        \n",
    "        要求：\n",
    "        1. 使用口语化中文\n",
    "        2. 包含具体数据\n",
    "        3. 不超过2句话\n",
    "        \"\"\"\n",
    "        return self.llm.invoke(answer_prompt.format(\n",
    "            question=question,\n",
    "            result=str(result)\n",
    "        ))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "ee99ba0e-39bb-4029-a683-800f8d04d959",
   "metadata": {
    "ExecutionIndicator": {
     "show": true
    },
    "execution": {
     "iopub.execute_input": "2026-05-14T12:19:36.696382Z",
     "iopub.status.busy": "2026-05-14T12:19:36.696197Z",
     "iopub.status.idle": "2026-05-14T12:19:40.381400Z",
     "shell.execute_reply": "2026-05-14T12:19:40.380830Z",
     "shell.execute_reply.started": "2026-05-14T12:19:36.696367Z"
    },
    "scrolled": true,
    "tags": []
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/tmp/ipykernel_7751/2849250777.py:27: LangChainDeprecationWarning: The class `LLMChain` was deprecated in LangChain 0.1.17 and will be removed in 2.0.0. Use `RunnableSequence, e.g., `prompt | llm`` instead.\n",
      "  self.cypher_chain = LLMChain(\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "content='哪吒的兄弟有金吒和木吒。具体来说，金吒和木吒都是他的兄弟。' additional_kwargs={'refusal': None} response_metadata={'token_usage': {'completion_tokens': 31, 'prompt_tokens': 84, 'total_tokens': 115, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0, 'image_tokens': 0, 'text_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0, 'image_tokens': 0, 'text_tokens': 0}}, 'model_provider': 'openai', 'model_name': 'gpt-4o-mini', 'system_fingerprint': 'fp_eb37e061ec', 'id': 'chatcmpl-DfPKNikWnUBpl4x9w4QlUdEItETO1', 'finish_reason': 'stop', 'logprobs': None} id='lc_run--019e266d-9efd-7d30-b3a9-7aa48fbc5ac5-0' tool_calls=[] invalid_tool_calls=[] usage_metadata={'input_tokens': 84, 'output_tokens': 31, 'total_tokens': 115, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}}\n"
     ]
    }
   ],
   "source": [
    "# 初始化使用\n",
    "qa_expert = Neo4jQAExpert(graph=graph, llm=chat)\n",
    "print(qa_expert.ask(\"哪吒的兄弟有哪些？\")) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "a528b9ff-a1b5-4e20-8e88-fc02d5f308f7",
   "metadata": {
    "ExecutionIndicator": {
     "show": true
    },
    "execution": {
     "iopub.execute_input": "2026-05-14T12:19:40.381950Z",
     "iopub.status.busy": "2026-05-14T12:19:40.381829Z",
     "iopub.status.idle": "2026-05-14T12:19:46.940164Z",
     "shell.execute_reply": "2026-05-14T12:19:46.939672Z",
     "shell.execute_reply.started": "2026-05-14T12:19:40.381935Z"
    },
    "scrolled": true,
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "content='哪吒的师傅是太乙真人。这个信息来源于相关的资料。' additional_kwargs={'refusal': None} response_metadata={'token_usage': {'completion_tokens': 20, 'prompt_tokens': 75, 'total_tokens': 95, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0, 'image_tokens': 0, 'text_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0, 'image_tokens': 0, 'text_tokens': 0}}, 'model_provider': 'openai', 'model_name': 'gpt-4o-mini', 'system_fingerprint': 'fp_eb37e061ec', 'id': 'chatcmpl-DfPKTnr2PmCbujTx5ikyTCupELrKo', 'finish_reason': 'stop', 'logprobs': None} id='lc_run--019e266d-b61d-74d1-b71d-45169cc9af36-0' tool_calls=[] invalid_tool_calls=[] usage_metadata={'input_tokens': 75, 'output_tokens': 20, 'total_tokens': 95, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}}\n"
     ]
    }
   ],
   "source": [
    "print(qa_expert.ask(\"哪吒的师傅是谁？\")) "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6504ee4b-1743-4749-81ab-9ab7eef46cfd",
   "metadata": {},
   "source": [
    "## 医学问题实操"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "id": "f743e24d-b550-4838-a35f-3369437d733a",
   "metadata": {
    "ExecutionIndicator": {
     "show": true
    },
    "execution": {
     "iopub.execute_input": "2025-12-04T15:39:35.462387Z",
     "iopub.status.busy": "2025-12-04T15:39:35.462166Z",
     "iopub.status.idle": "2025-12-04T15:39:35.485095Z",
     "shell.execute_reply": "2025-12-04T15:39:35.484423Z",
     "shell.execute_reply.started": "2025-12-04T15:39:35.462371Z"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# 常见的数据处理\n",
    "import textwrap\n",
    "\n",
    "# Langchain\n",
    "from langchain_neo4j import Neo4jGraph\n",
    "from langchain_community.vectorstores import Neo4jVector\n",
    "from langchain_classic.llms import OpenAI"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "e468291c-45d9-4f21-87d7-a6ddf9191601",
   "metadata": {
    "ExecutionIndicator": {
     "show": true
    },
    "execution": {
     "iopub.execute_input": "2026-03-21T08:54:16.974250Z",
     "iopub.status.busy": "2026-03-21T08:54:16.974088Z",
     "iopub.status.idle": "2026-03-21T08:54:23.876435Z",
     "shell.execute_reply": "2026-03-21T08:54:23.875825Z",
     "shell.execute_reply.started": "2026-03-21T08:54:16.974234Z"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "graph = Neo4jGraph(\n",
    "    url=neo4j_url, username=neo4j_username, password=neo4j_password, database=neo4j_database\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "3f5e8638-f04c-4c89-9478-3456e684d1df",
   "metadata": {
    "ExecutionIndicator": {
     "show": true
    },
    "execution": {
     "iopub.execute_input": "2026-03-21T08:54:23.877182Z",
     "iopub.status.busy": "2026-03-21T08:54:23.877050Z",
     "iopub.status.idle": "2026-03-21T08:54:25.869841Z",
     "shell.execute_reply": "2026-03-21T08:54:25.869302Z",
     "shell.execute_reply.started": "2026-03-21T08:54:23.877168Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "节点插入成功！\n",
      "关系插入成功！\n",
      "\n",
      "示例关系：\n",
      "弥漫性大B细胞淋巴瘤 -> HAS_SUBTYPE -> 非特指型\n",
      "弥漫性大B细胞淋巴瘤 -> HAS_SYMPTOM -> 无痛性肿物\n",
      "弥漫性大B细胞淋巴瘤 -> DIAGNOSED_BY -> 病理活检\n",
      "弥漫性大B细胞淋巴瘤 -> TREATED_WITH -> R-CHOP\n",
      "弥漫性大B细胞淋巴瘤 -> HAS_PROGNOSTIC_FACTOR -> IPI\n"
     ]
    }
   ],
   "source": [
    "from neo4j import GraphDatabase\n",
    "import json\n",
    "\n",
    "# 加载知识图谱数据\n",
    "def load_knowledge_graph(file_path):\n",
    "    with open(file_path, \"r\", encoding=\"utf-8\") as f:\n",
    "        return json.load(f)\n",
    "\n",
    "\n",
    "\n",
    "# 创建节点和关系的 Cypher 语句\n",
    "create_nodes = \"\"\"\n",
    "UNWIND $nodes AS node\n",
    "MERGE (n:Entity {name: node.name})\n",
    "SET n.type = node.type,\n",
    "    n.description = node.description\n",
    "\"\"\"\n",
    "\n",
    "create_relationships = \"\"\"\n",
    "UNWIND $rels AS rel\n",
    "MATCH (a:Entity {name: rel.source}), (b:Entity {name: rel.target})\n",
    "MERGE (a)-[r:RELATIONSHIP {type: rel.type}]->(b)\n",
    "\"\"\"\n",
    "\n",
    "# 插入数据到 Neo4j\n",
    "def insert_data_to_neo4j(data):\n",
    "    try:\n",
    "        # 创建节点\n",
    "        graph.query(create_nodes, params={\"nodes\": data[\"nodes\"]})\n",
    "        print(\"节点插入成功！\")\n",
    "        \n",
    "        # 创建关系\n",
    "        graph.query(create_relationships, params={\"rels\": data[\"relationships\"]})\n",
    "        print(\"关系插入成功！\")\n",
    "        \n",
    "        # 验证查询\n",
    "        result = graph.query(\"\"\"\n",
    "            MATCH (n:Entity)-[r]->(m)\n",
    "            RETURN n.name as source, r.type as relationship, m.name as target\n",
    "            LIMIT 5\n",
    "        \"\"\")\n",
    "        print(\"\\n示例关系：\")\n",
    "        for record in result:\n",
    "            print(f\"{record['source']} -> {record['relationship']} -> {record['target']}\")\n",
    "    \n",
    "    except Exception as e:\n",
    "        print(f\"插入数据时出错: {e}\")\n",
    "\n",
    "# 加载知识图谱数据\n",
    "knowledge_graph = load_knowledge_graph(\"dlbcl_knowledge_graph.json\")\n",
    "# 插入数据到 Neo4j\n",
    "insert_data_to_neo4j(knowledge_graph)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "ff1d9505-5bfc-4527-871c-4ef95b3eacad",
   "metadata": {
    "ExecutionIndicator": {
     "show": false
    },
    "execution": {
     "iopub.execute_input": "2026-03-21T08:53:09.228114Z",
     "iopub.status.busy": "2026-03-21T08:53:09.227950Z",
     "iopub.status.idle": "2026-03-21T08:53:14.107043Z",
     "shell.execute_reply": "2026-03-21T08:53:14.106422Z",
     "shell.execute_reply.started": "2026-03-21T08:53:09.228099Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new GraphCypherQAChain chain...\u001b[0m\n",
      "Generated Cypher:\n",
      "\u001b[32;1m\u001b[1;3mMATCH (disease {name: \"弥漫性大B细胞淋巴瘤\"})-[:HAS_TREATMENT]->(treatment) RETURN treatment.name, treatment.description\u001b[0m\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Received notification from DBMS server: <GqlStatusObject gql_status='01N51', status_description='warn: relationship type does not exist. The relationship type `HAS_TREATMENT` does not exist in database `b78b132b`. Verify that the spelling is correct.', position=<SummaryInputPosition line=1, column=40, offset=39>, raw_classification='UNRECOGNIZED', classification=<NotificationClassification.UNRECOGNIZED: 'UNRECOGNIZED'>, raw_severity='WARNING', severity=<NotificationSeverity.WARNING: 'WARNING'>, diagnostic_record={'_classification': 'UNRECOGNIZED', '_severity': 'WARNING', '_position': {'offset': 39, 'line': 1, 'column': 40}, 'OPERATION': '', 'OPERATION_CODE': '0', 'CURRENT_SCHEMA': '/'}> for query: 'MATCH (disease {name: \"弥漫性大B细胞淋巴瘤\"})-[:HAS_TREATMENT]->(treatment) RETURN treatment.name, treatment.description'\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Full Context:\n",
      "\u001b[32;1m\u001b[1;3m[]\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished chain.\u001b[0m\n",
      "{'query': '介绍一下弥漫性大B细胞淋巴瘤的治疗手段', 'result': '我不知道答案。'}\n"
     ]
    }
   ],
   "source": [
    "\n",
    "\n",
    "# 提出一个问题\n",
    "chat = ChatOpenAI(\n",
    "    openai_api_key=os.environ[\"OPENAI_API_KEY\"],\n",
    "    model='gpt-4o-mini',\n",
    "    temperature=0\n",
    ")\n",
    "chain = GraphCypherQAChain.from_llm(\n",
    "    cypher_llm=chat,qa_llm=chat, graph=graph, verbose=True,allow_dangerous_requests=True\n",
    ")\n",
    "result=chain.invoke({\"query\": \"介绍一下弥漫性大B细胞淋巴瘤的治疗手段\"})\n",
    "print(result)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "9e0e1624-ea22-4250-bbbf-e7a04b6cdc57",
   "metadata": {
    "ExecutionIndicator": {
     "show": true
    },
    "execution": {
     "iopub.execute_input": "2026-03-21T08:54:25.870248Z",
     "iopub.status.busy": "2026-03-21T08:54:25.870127Z",
     "iopub.status.idle": "2026-03-21T08:54:25.875726Z",
     "shell.execute_reply": "2026-03-21T08:54:25.875168Z",
     "shell.execute_reply.started": "2026-03-21T08:54:25.870234Z"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "class DLBCLQAExpert:\n",
    "    def __init__(self, graph, llm):\n",
    "        self.graph = graph\n",
    "        self.llm = llm\n",
    "        \n",
    "        # Cypher 生成模板\n",
    "        self.cypher_prompt = PromptTemplate(\n",
    "            input_variables=[\"question\"],  # 仅需问题输入\n",
    "            template=\"\"\"\n",
    "            你是一个Neo4j专家，根据问题生成Cypher查询。\n",
    "            已知数据模型：\n",
    "            - 节点标签：Entity\n",
    "            - 节点属性：name, type, description\n",
    "            - 关系类型：RELATIONSHIP (通过type属性区分具体关系)\n",
    "            \n",
    "            示例问题：弥漫性大B细胞淋巴瘤的治疗方案是什么？\n",
    "            正确查询：MATCH (n:Entity {{name:'弥漫性大B细胞淋巴瘤'}})-[:RELATIONSHIP {{type:'TREATED_WITH'}}]->(m) RETURN m.name\n",
    "            \n",
    "            当前问题：{question}\n",
    "            生成的Cypher语句：\n",
    "            \"\"\"\n",
    "        )\n",
    "        \n",
    "        # Cypher 生成链\n",
    "        self.cypher_chain = LLMChain(\n",
    "            llm=self.llm,\n",
    "            prompt=self.cypher_prompt,\n",
    "            output_key=\"cypher\"\n",
    "        )\n",
    "    \n",
    "    def ask(self, question: str) -> str:\n",
    "        try:\n",
    "            # 生成Cypher\n",
    "            result = self.cypher_chain.invoke({\"question\": question})\n",
    "            cypher = result[\"cypher\"].strip().replace(\"`\", \"\")  # 清理反引号\n",
    "            print(cypher)\n",
    "            # 执行查询\n",
    "            graph_result = self.graph.query(cypher)\n",
    "            \n",
    "            # 格式化结果\n",
    "            return self._format_response(question, graph_result)\n",
    "        except Exception as e:\n",
    "            return f\"执行出错：{str(e)}\"\n",
    "\n",
    "    def _format_response(self, question: str, result: list) -> str:\n",
    "        \"\"\"将数据库结果转换为自然语言\"\"\"\n",
    "        if not result:\n",
    "            return \"未找到相关信息\"\n",
    "            \n",
    "        # 自然语言生成模板\n",
    "        answer_prompt = \"\"\"\n",
    "        根据以下数据回答问题：\n",
    "        问题：{question}\n",
    "        结果：{result}\n",
    "        \n",
    "        要求：\n",
    "        1. 使用口语化中文\n",
    "        2. 包含具体数据\n",
    "        3. 不超过2句话\n",
    "        \"\"\"\n",
    "        return self.llm.invoke(answer_prompt.format(\n",
    "            question=question,\n",
    "            result=str(result)\n",
    "        ))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "f35c24e3-f625-4f42-a02a-153c6e983302",
   "metadata": {
    "ExecutionIndicator": {
     "show": true
    },
    "execution": {
     "iopub.execute_input": "2026-03-21T08:54:27.539706Z",
     "iopub.status.busy": "2026-03-21T08:54:27.539528Z",
     "iopub.status.idle": "2026-03-21T08:54:32.762031Z",
     "shell.execute_reply": "2026-03-21T08:54:32.761330Z",
     "shell.execute_reply.started": "2026-03-21T08:54:27.539689Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "cypher\n",
      "MATCH (n:Entity {name:'弥漫性大B细胞淋巴瘤'})-[:RELATIONSHIP {type:'HAS_RISK_FACTOR'}]->(m) RETURN m.name\n",
      "\n",
      "content='弥漫性大B细胞淋巴瘤的一个主要危险因素是年龄，特别是超过60岁的人群，发病率明显增加。根据统计，60岁以上的患者发病风险比年轻人高出几倍。' additional_kwargs={'refusal': None} response_metadata={'token_usage': {'completion_tokens': 55, 'prompt_tokens': 87, 'total_tokens': 142, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_provider': 'openai', 'model_name': 'gpt-4o-mini', 'system_fingerprint': 'fp_eb37e061ec', 'id': 'chatcmpl-DLmOFJJNvnZ1heB1sWBsSE50EiX9o', 'finish_reason': 'stop', 'logprobs': None} id='lc_run--019d0f9a-6aba-7a01-833e-977893d1264b-0' tool_calls=[] invalid_tool_calls=[] usage_metadata={'input_tokens': 87, 'output_tokens': 55, 'total_tokens': 142, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}}\n"
     ]
    }
   ],
   "source": [
    "# 初始化使用\n",
    "qa_expert = DLBCLQAExpert(graph=graph, llm=chat)\n",
    "print(qa_expert.ask(\"介绍一下弥漫性大B细胞淋巴瘤的危险因素\")) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "58cd6f9c-ceb2-49ac-b498-8ada382fc2ac",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.11"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
