Skip to content

Commit

Permalink
Added remaining langchain-community code
Browse files Browse the repository at this point in the history
  • Loading branch information
alexthomas93 committed Nov 20, 2024
1 parent 036bdc9 commit 7d2170b
Show file tree
Hide file tree
Showing 10 changed files with 162 additions and 18 deletions.
10 changes: 5 additions & 5 deletions libs/neo4j/langchain_neo4j/chains/graph_qa/cypher.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,6 @@

from langchain.chains.base import Chain
from langchain.chains.llm import LLMChain
from langchain_community.chains.graph_qa.prompts import (
CYPHER_GENERATION_PROMPT,
CYPHER_QA_PROMPT,
)
from langchain_community.graphs.graph_store import GraphStore
from langchain_core.callbacks import CallbackManagerForChainRun
from langchain_core.language_models import BaseLanguageModel
from langchain_core.messages import (
Expand All @@ -34,6 +29,11 @@
CypherQueryCorrector,
Schema,
)
from langchain_neo4j.chains.graph_qa.prompts import (
CYPHER_GENERATION_PROMPT,
CYPHER_QA_PROMPT,
)
from langchain_neo4j.graphs.graph_store import GraphStore

INTERMEDIATE_STEPS_KEY = "intermediate_steps"

Expand Down
41 changes: 41 additions & 0 deletions libs/neo4j/langchain_neo4j/chains/graph_qa/prompts.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# flake8: noqa
from langchain_core.prompts.prompt import PromptTemplate

CYPHER_GENERATION_TEMPLATE = """Task:Generate Cypher statement to query a graph database.
Instructions:
Use only the provided relationship types and properties in the schema.
Do not use any other relationship types or properties that are not provided.
Schema:
{schema}
Note: Do not include any explanations or apologies in your responses.
Do not respond to any questions that might ask anything else than for you to construct a Cypher statement.
Do not include any text except the generated Cypher statement.
The question is:
{question}"""

CYPHER_GENERATION_PROMPT = PromptTemplate(
input_variables=["schema", "question"], template=CYPHER_GENERATION_TEMPLATE
)

CYPHER_QA_TEMPLATE = """You are an assistant that helps to form nice and human understandable answers.
The information part contains the provided information that you must use to construct an answer.
The provided information is authoritative, you must never doubt it or try to use your internal knowledge to correct it.
Make the answer sound as a response to the question. Do not mention that you based the result on the given information.
Here is an example:
Question: Which managers own Neo4j stocks?
Context:[manager:CTL LLC, manager:JANE STREET GROUP LLC]
Helpful Answer: CTL LLC, JANE STREET GROUP LLC owns Neo4j stocks.
Follow this example when generating answers.
If the provided information is empty, say that you don't know the answer.
Information:
{context}
Question: {question}
Helpful Answer:"""

CYPHER_QA_PROMPT = PromptTemplate(
input_variables=["context", "question"], template=CYPHER_QA_TEMPLATE
)
51 changes: 51 additions & 0 deletions libs/neo4j/langchain_neo4j/graphs/graph_document.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
from __future__ import annotations

from typing import List, Union

from langchain_core.documents import Document
from langchain_core.load.serializable import Serializable
from pydantic import Field


class Node(Serializable):
"""Represents a node in a graph with associated properties.
Attributes:
id (Union[str, int]): A unique identifier for the node.
type (str): The type or label of the node, default is "Node".
properties (dict): Additional properties and metadata associated with the node.
"""

id: Union[str, int]
type: str = "Node"
properties: dict = Field(default_factory=dict)


class Relationship(Serializable):
"""Represents a directed relationship between two nodes in a graph.
Attributes:
source (Node): The source node of the relationship.
target (Node): The target node of the relationship.
type (str): The type of the relationship.
properties (dict): Additional properties associated with the relationship.
"""

source: Node
target: Node
type: str
properties: dict = Field(default_factory=dict)


class GraphDocument(Serializable):
"""Represents a graph document consisting of nodes and relationships.
Attributes:
nodes (List[Node]): A list of nodes in the graph.
relationships (List[Relationship]): A list of relationships in the graph.
source (Document): The document from which the graph information is derived.
"""

nodes: List[Node]
relationships: List[Relationship]
source: Document
37 changes: 37 additions & 0 deletions libs/neo4j/langchain_neo4j/graphs/graph_store.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
from abc import abstractmethod
from typing import Any, Dict, List

from langchain_neo4j.graphs.graph_document import GraphDocument


class GraphStore:
"""Abstract class for graph operations."""

@property
@abstractmethod
def get_schema(self) -> str:
"""Return the schema of the Graph database"""
pass

@property
@abstractmethod
def get_structured_schema(self) -> Dict[str, Any]:
"""Return the schema of the Graph database"""
pass

@abstractmethod
def query(self, query: str, params: dict = {}) -> List[Dict[str, Any]]:
"""Query the graph."""
pass

@abstractmethod
def refresh_schema(self) -> None:
"""Refresh the graph schema information."""
pass

@abstractmethod
def add_graph_documents(
self, graph_documents: List[GraphDocument], include_source: bool = False
) -> None:
"""Take GraphDocument as input as uses it to construct a graph."""
pass
5 changes: 3 additions & 2 deletions libs/neo4j/langchain_neo4j/graphs/neo4j_graph.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
from hashlib import md5
from typing import Any, Dict, List, Optional

from langchain_community.graphs.graph_document import GraphDocument
from langchain_community.graphs.graph_store import GraphStore
from langchain_core.utils import get_from_dict_or_env

from langchain_neo4j.graphs.graph_document import GraphDocument
from langchain_neo4j.graphs.graph_store import GraphStore

BASE_ENTITY_LABEL = "__Entity__"
EXCLUDED_LABELS = ["_Bloom_Perspective_", "_Bloom_Scene_"]
EXCLUDED_RELS = ["_Bloom_HAS_SCENE_"]
Expand Down
11 changes: 5 additions & 6 deletions libs/neo4j/langchain_neo4j/vectorstores/neo4j_vector.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,14 @@
)

import numpy as np
from langchain_community.vectorstores.utils import (
DistanceStrategy,
maximal_marginal_relevance,
)
from langchain_core.documents import Document
from langchain_core.embeddings import Embeddings
from langchain_core.utils import get_from_dict_or_env
from langchain_core.vectorstores import VectorStore
from langchain_core.vectorstores.utils import maximal_marginal_relevance

from langchain_neo4j.graphs.neo4j_graph import Neo4jGraph
from langchain_neo4j.vectorstores.utils import DistanceStrategy

DEFAULT_DISTANCE_STRATEGY = DistanceStrategy.COSINE
DISTANCE_MAPPING = {
Expand Down Expand Up @@ -468,7 +466,7 @@ class Neo4jVector(VectorStore):
.. code-block:: python
from langchain_neo4j import Neo4jVector
from langchain_community.embeddings.openai import OpenAIEmbeddings
from langchain_openai import OpenAIEmbeddings
url="bolt://localhost:7687"
username="neo4j"
Expand Down Expand Up @@ -1253,7 +1251,8 @@ def from_embeddings(
.. code-block:: python
from langchain_neo4j import Neo4jVector
from langchain_community.embeddings import OpenAIEmbeddings
from langchain_openai import OpenAIEmbeddings
embeddings = OpenAIEmbeddings()
text_embeddings = embeddings.embed_documents(texts)
text_embedding_pairs = list(zip(texts, text_embeddings))
Expand Down
12 changes: 12 additions & 0 deletions libs/neo4j/langchain_neo4j/vectorstores/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from enum import Enum


class DistanceStrategy(str, Enum):
"""Enumerator of the Distance strategies for calculating distances
between vectors."""

EUCLIDEAN_DISTANCE = "EUCLIDEAN_DISTANCE"
MAX_INNER_PRODUCT = "MAX_INNER_PRODUCT"
DOT_PRODUCT = "DOT_PRODUCT"
JACCARD = "JACCARD"
COSINE = "COSINE"
2 changes: 1 addition & 1 deletion libs/neo4j/tests/integration_tests/graphs/test_neo4j.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import os

from langchain_community.graphs.graph_document import GraphDocument, Node, Relationship
from langchain_core.documents import Document

from langchain_neo4j import Neo4jGraph
from langchain_neo4j.graphs.graph_document import GraphDocument, Node, Relationship
from langchain_neo4j.graphs.neo4j_graph import (
BASE_ENTITY_LABEL,
node_properties_query,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
from math import isclose
from typing import Any, Dict, List, cast

from langchain_community.vectorstores.utils import DistanceStrategy
from langchain_core.documents import Document
from yaml import safe_load

Expand All @@ -14,6 +13,7 @@
SearchType,
_get_search_index_query,
)
from langchain_neo4j.vectorstores.utils import DistanceStrategy
from tests.integration_tests.vectorstores.fake_embeddings import (
AngularTwoDimensionalEmbeddings,
FakeEmbeddings,
Expand Down
9 changes: 6 additions & 3 deletions libs/neo4j/tests/unit_tests/chains/test_graph_qa.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@
from csv import DictReader
from typing import Any, Dict, List

from langchain.chains.graph_qa.prompts import CYPHER_GENERATION_PROMPT, CYPHER_QA_PROMPT
from langchain.memory import ConversationBufferMemory, ReadOnlySharedMemory
from langchain_community.graphs.graph_document import GraphDocument
from langchain_community.graphs.graph_store import GraphStore
from langchain_core.prompts import PromptTemplate

from langchain_neo4j.chains.graph_qa.cypher import (
Expand All @@ -17,6 +14,12 @@
CypherQueryCorrector,
Schema,
)
from langchain_neo4j.chains.graph_qa.prompts import (
CYPHER_GENERATION_PROMPT,
CYPHER_QA_PROMPT,
)
from langchain_neo4j.graphs.graph_document import GraphDocument
from langchain_neo4j.graphs.graph_store import GraphStore
from tests.unit_tests.llms.fake_llm import FakeLLM


Expand Down

0 comments on commit 7d2170b

Please sign in to comment.