Multi Agent Graph Application

 

                                                image credit: langchain langgraph

Integrating Gemma 3 with LangGraph and Neo4j allows you to build sophisticated AI applications that leverage the strengths of each technology:

  • Gemma 3:
    • Provides powerful language understanding and generation capabilities.
    • Its multimodal abilities and increased context window are very powerful for complex information processing.
  • LangGraph:
    • Enables you to create stateful, multi-actor applications by defining workflows as graphs.
    • This is ideal for building complex AI agents and applications that require multiple steps and interactions.
  • Neo4j:
    • A graph database that excels at storing and querying connected data.
    • It's perfect for knowledge graphs and applications that require understanding relationships between entities.

Here's a conceptual overview of how you can combine these technologies:

1. Data Representation in Neo4j:

  • Store your data as a graph in Neo4j, where nodes represent entities and edges represent relationships.
  • This allows you to capture the rich semantic relationships between your data.
  • Neo4j now has vector indexing capabilities, so you can also store vector embeddings within the Neo4j graph, allowing for hybrid searches.

2. LangGraph Workflows:

  • Use LangGraph to define the workflow of your AI application.
  • This workflow can include steps such as:
    • Receiving user input.
    • Querying Neo4j to retrieve relevant information.
    • Using Gemma 3 to process the retrieved information and generate a response.
    • Updating the Neo4j graph based on the interaction.
    • Using Gemma 3's function calling to interact with tools, or API's.
  • LangGraph can also be used to create memory within the agent, and Neo4j can be used to store that memory in graph format, for long term memory storage.

3. Gemma 3 Integration:

  • Use Gemma 3 to:
    • Understand user queries and generate Cypher queries to retrieve information from Neo4j.
    • Process the results from Neo4j and generate natural language responses.
    • Extract entities and relationships from text to update the Neo4j graph.
    • Use its multimodal abilities to process image and text data, that can then be used to query, or update the Neo4j Graph.

Key Use Cases:

  • Knowledge Graph-Based Question Answering:
    • Build a system that can answer complex questions by querying a knowledge graph stored in Neo4j.
    • Gemma 3 can be used to understand the question and generate a Cypher query, and then to generate a natural language response based on the results.
  • AI Agents with Memory:
    • Create AI agents that can remember past interactions and use that information to provide more relevant responses.
    • Neo4j can be used to store the agent's memory as a graph, and LangGraph can be used to manage the agent's state.
  • Information Extraction and Graph Enrichment:
    • Use Gemma 3 to extract entities and relationships from text and then use that information to enrich the Neo4j graph.
  • Visual Question Answering:
    • Use Gemma 3's multimodal abilities to process images, and then use the information gained from the image to query a Neo4j database.

Important Considerations:

  • Cypher Query Generation:
    • Accurately generating Cypher queries from natural language is crucial.
    • You may need to use techniques such as prompt engineering and few-shot learning to improve the accuracy of Gemma 3's Cypher generation.
  • Data Consistency:
    • Ensure that the data in your Neo4j graph is consistent and accurate.
  • Performance:
    • Optimize your Neo4j queries and Gemma 3 interactions for performance, especially for large datasets.

By combining Gemma 3, LangGraph, and Neo4j, you can create powerful and intelligent AI applications that can understand and reason about complex information.

Example code


from langchain_google_genai import ChatGoogleGenerativeAI

from langgraph.prebuilt import create_react_agent

from langgraph_supervisor import create_supervisor

from neo4j import GraphDatabase

import os


# Neo4j Configuration

NEO4J_URI = os.getenv("NEO4J_URI", "bolt://localhost:7687")  # Replace with your Neo4j URI

NEO4J_USER = os.getenv("NEO4J_USER", "neo4j")  # Replace with your Neo4j username

NEO4J_PASSWORD = os.getenv("NEO4J_PASSWORD", "password")  # Replace with your Neo4j password


# Gemma 3 Model

model = ChatGoogleGenerativeAI(model="gemini-1.0-pro")  # or "gemini-1.0-pro-vision" for multimodal


# Neo4j Interaction Function

def query_neo4j(query: str) -> str:

    """Queries Neo4j and returns the result."""

    try:

        with GraphDatabase.driver(NEO4J_URI, auth=(NEO4J_USER, NEO4J_PASSWORD)) as driver:

            with driver.session() as session:

                result = session.run(query)

                records = [record.data() for record in result]

                return str(records)

    except Exception as e:

        return f"Error querying Neo4j: {e}"


# Example Neo4j Cypher query Function.

def get_faang_headcount() -> str:

    """Retrieves FAANG headcount from Neo4j."""

    query = """

    MATCH (company:Company)-[:HAS_HEADCOUNT]->(headcount:Headcount)

    WHERE company.name IN ['Facebook', 'Apple', 'Amazon', 'Netflix', 'Google']

    RETURN company.name, headcount.value

    """

    return query_neo4j(query)


def sum_list_of_ints(list_of_ints: list) -> int:

    """Sums a list of integers."""

    try:

        return sum(list_of_ints)

    except Exception as e:

        return f"Error summing the list: {e}"


# Agents

neo4j_agent = create_react_agent(

    model=model,

    tools=[get_faang_headcount],

    name="neo4j_expert",

    prompt="You are an expert at querying Neo4j. Only use the neo4j tool. Do not do any math."

)


math_agent = create_react_agent(

    model=model,

    tools=[sum_list_of_ints],

    name="math_expert",

    prompt="You are a math expert. Only use the math tool. Do not use the neo4j tool."

)


# Supervisor Workflow

workflow = create_supervisor(

    agents=[neo4j_agent, math_agent],

    model=model,

    prompt="You are a team supervisor managing a Neo4j expert and a math expert. For data retrieval, use neo4j_expert. For math problems, use math_expert."

)


# Compile and Run

app = workflow.compile()

result = app.invoke({

    "messages": [

        {

            "role": "user",

            "content": "what's the combined headcount of the FAANG companies in 2024?"

        }

    ]

})


print(result)

 

If you want to run locally with Ollama


from langchain_community.chat_models import ChatOllama

from langchain.agents import AgentType, initialize_agent, Tool

from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder

from langchain.schema import SystemMessage

from neo4j import GraphDatabase

import os


# Neo4j Configuration

NEO4J_URI = os.getenv("NEO4J_URI", "bolt://localhost:7687")  # Replace with your Neo4j URI

NEO4J_USER = os.getenv("NEO4J_USER", "neo4j")  # Replace with your Neo4j username

NEO4J_PASSWORD = os.getenv("NEO4J_PASSWORD", "password")  # Replace with your Neo4j password


# Ollama Gemma Model

model = ChatOllama(model="gemma")  # Ensure you have Gemma model downloaded in Ollama


# Neo4j Interaction Function

def query_neo4j(query: str) -> str:

    """Queries Neo4j and returns the result."""

    try:

        with GraphDatabase.driver(NEO4J_URI, auth=(NEO4J_USER, NEO4J_PASSWORD)) as driver:

            with driver.session() as session:

                result = session.run(query)

                records = [record.data() for record in result]

                return str(records)

    except Exception as e:

        return f"Error querying Neo4j: {e}"


# Example Neo4j Cypher query Function.

def get_faang_headcount() -> str:

    """Retrieves FAANG headcount from Neo4j."""

    query = """

    MATCH (company:Company)-[:HAS_HEADCOUNT]->(headcount:Headcount)

    WHERE company.name IN ['Facebook', 'Apple', 'Amazon', 'Netflix', 'Google']

    RETURN company.name, headcount.value

    """

    return query_neo4j(query)


def sum_list_of_ints(list_of_ints: list) -> int:

    """Sums a list of integers."""

    try:

        return sum(list_of_ints)

    except Exception as e:

        return f"Error summing the list: {e}"


# Tools

tools = [

    Tool(

        name="Neo4j_Query",

        func=get_faang_headcount,

        description="Useful for querying Neo4j graph databases.",

    ),

    Tool(

        name="Math_Sum",

        func=sum_list_of_ints,

        description="Useful for summing a list of integers.",

    ),

]


# Prompt template

prompt = ChatPromptTemplate.from_messages(

    [

        SystemMessage(

            content="You are a helpful assistant that can query Neo4j and perform math calculations."

        ),

        MessagesPlaceholder(variable_name="chat_history"),

        ("user", "{input}"),

        MessagesPlaceholder(variable_name="agent_scratchpad"),

    ]

)


# Initialize Agent

agent = initialize_agent(

    tools,

    model,

    agent=AgentType.CHAT_CONVERSATIONAL_REACT_DESCRIPTION,

    verbose=True,

    memory=None,

    prompt=prompt,

)


# Run Agent

result = agent.run("what's the combined headcount of the FAANG companies in 2024?")

print(result)


If you like my tutorial, you can follow me at https://linkedin.com/in/dhirajpatra and check out many other tutorials. Thank you. 

Comments

Popular posts from this blog

Self-contained Raspberry Pi surveillance System Without Continue Internet

COBOT with GenAI and Federated Learning

AI in Education: Embracing Change for Future-Ready Learning