Skip to content

Latest commit

 

History

History
117 lines (82 loc) · 4.49 KB

File metadata and controls

117 lines (82 loc) · 4.49 KB

FastMemory Production Scaling: Graph Database Integration

When transitioning from local file-based memory to large-scale production deployments, FastMemory leverages its hierarchical Topology ontology to seed directly into Graph Databases. This allows AI agents to persist, traverse, and execute partial updates on a massive, distributed cognitive graph over time.

This guide demonstrates how to deploy FastMemory at scale using Neo4J.


🏗️ 1. Why Neo4J for FastMemory?

FastMemory acts as the Compute Engine—it mathematically derives isolated Functional Blocks (using Louvain clustering) from raw text. However, for a persistent, multi-agent AI brain, you need a Storage Engine.

Neo4J perfectly mirrors the exact node-edge topology generated by fastmemory:

  • Nodes: C_ (Components), B_ (Blocks), F_ (Functions), D_ (Data), A_ (Access), E_ (Events).
  • Edges: CONTAINS, USES, REQUIRES, TRIGGERS.

By pushing the FastMemory JSON output directly into Neo4J, your AI agents can perform real-time localized graph traversals using Cypher, without holding the entire memory hierarchy in RAM.


🚀 2. Neo4J Ingestion Pipeline

To push a FastMemory Topology graph into Neo4J, you simply pipe the JSON output of the fastmemory build command into a lightweight ingestion script.

2.1. Initial Graph Ingestion (Python)

# Generate the clustered cognitive graph
$ fastmemory build data/context.md > fastmemory_output.json

Use the snippet below to ingest fastmemory_output.json into Neo4J using the official neo4j Python driver:

import json
from neo4j import GraphDatabase

URI = "neo4j://localhost:7687"
AUTH = ("neo4j", "your_secure_password")

def ingest_fastmemory_graph(tx, nodes, edges):
    # 1. Create Nodes
    for node in nodes:
        # We store the node ID and its community cluster ID
        query = (
            "MERGE (n:MemoryNode {id: $id}) "
            "SET n.cluster = $cluster, n.name = $id"
        )
        tx.run(query, id=node["id"], cluster=node["group"])

    # 2. Create Directed Relationships
    for edge in edges:
        query = (
            "MATCH (source:MemoryNode {id: $source_id}) "
            "MATCH (target:MemoryNode {id: $target_id}) "
            "MERGE (source)-[:CONNECTS_TO]->(target)"
        )
        tx.run(query, source_id=edge["source"], target_id=edge["target"])

# Execute the transaction
with open("fastmemory_output.json", "r") as f:
    graph_data = json.load(f)

with GraphDatabase.driver(URI, auth=AUTH) as driver:
    with driver.session() as session:
        session.execute_write(ingest_fastmemory_graph, graph_data["nodes"], graph_data["links"])
        
print("Successfully ingested FastMemory Topology Graph into Neo4J!")

🔄 3. Partial Updates & Live Syncing

As your codebase, SaaS platform, or agent logic changes, you don't need to rebuild the entire Neo4J database. FastMemory's isolated Block topology allows you to execute Partial Updates.

If the underlying markdown for a specific component (e.g., the PaymentGateway Action) changes:

  1. Re-run fastmemory build specifically on the changed subset.
  2. The Louvain engine will isolate the local topology.
  3. Update Neo4J by merging on node IDs and deleting stale edges.

3.1. Partial Update Cypher Pattern

// 1. Unwind the new FastMemory partial patch
UNWIND $patch_data AS node_data

// 2. Identify and MERGE the updated nodes
MERGE (n:MemoryNode {id: node_data.id})
SET n.cluster = node_data.cluster, n.updated_at = timestamp()

// 3. Clear old relationships specifically for updated nodes
WITH n, node_data
OPTIONAL MATCH (n)-[r:CONNECTS_TO]->()
DELETE r

// 4. Re-establish the new logical edges
WITH n, node_data
UNWIND node_data.targets AS target_id
MATCH (target:MemoryNode {id: target_id})
MERGE (n)-[:CONNECTS_TO]->(target)

🧠 4. AI Agent Traversal in Production

Once the FastMemory graph is running on Neo4J, your AI agents (via LangChain, LlamaIndex, or raw MCP) no longer need to perform computationally heavy vector-similarity searches.

When an agent needs to execute an action (e.g., Issue_Refund), it simply queries the graph explicitly for the context block and access constraints:

MATCH (f:MemoryNode {id: "F_Issue_Refund"})-[:CONNECTS_TO*1..3]-(related)
RETURN f, related

This returns exactly the Data (D_Payment_Transaction), the required Access restrictions (A_Role_Billing_Admin), and the Events that will trigger (E_Refund_Receipt_Sent)—completely eliminating hallucinations!