# Agentic AI

In agentic AI on Memgraph, an agent stores its problem as a reasoning graph
and plans by traversing it instead of by prompting an LLM at each step. Every
decision follows a path in the graph, so you can inspect why the agent chose
it and how it scored against the alternatives.

## How it works

A reasoning graph models the problem like this:

- **Nodes** are states or decision points.
- **Relationships** are the actions available in each state.
- **Properties** are scores, such as expected value, success rate or
  feasibility.

Four graph operations answer the planning questions:

| Operation | What it answers |
| --- | --- |
| **Weighted traversal** | Which multi-step plan has the best score, without LLM calls |
| **Shortest path** | The most efficient route to a goal |
| **Centrality** | Which intermediate states are critical |
| **Community detection** | Which sub-tasks can run in parallel |

Agents that work together also need shared state. In this example,
[MemGQL](https://memgraph.com/docs/memgraph-zero/memgql) provides it: it puts one Bolt and GQL endpoint
in front of several databases, so every agent reaches the same data without
copying it. The example connects two databases:

- **Memgraph** holds the reasoning graph the agents plan over, and runs the
  MAGE algorithms.
- **PostgreSQL** holds the customer records the agents read as shared context.

## Run the example

The example starts Memgraph, PostgreSQL and MemGQL in Docker, creates the
reasoning graph of a customer-support agent, reads customer records through
MemGQL and plans with the four operations. You need
[Docker](https://docs.docker.com/get-docker/), and no API key.

**Linux/macOS**

```bash
curl -sSL https://install.memgraph.com/agentic-ai | bash
```

**Windows**

```powershell
iwr https://install.memgraph.com/agentic-ai/windows -useb | iex
```

The scripts are `agentic-ai.sh` and `agentic-ai.ps1` in the
[memgraph/memgraph-platform](https://github.com/memgraph/memgraph-platform/tree/main/code-examples)
repository. To remove what the example created, download the script and run
it with `clean`; when you run it from the web, it prints the `docker` commands
that do the same.

On Windows:

- If Windows blocks the script, allow scripts for the current session first:
  `Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass`.
- The script mounts two files it generates into the containers, so the drive
  of your current directory must be shared with Docker Desktop, in
  **Settings → Resources → File sharing**. `C:\Users` is shared by default.

## What the example does

The script runs these steps for you. They show what each part of the example
is and what it returns.

### Start the shared data layer

The containers are named `zero-demo-*`, so they don't clash with your own.
Only MemGQL's port, 7688, is published. Memgraph and PostgreSQL are reached
inside the Docker network, so agents use one endpoint:

```bash
docker network create zero-demo-net

docker run -d --name zero-demo-memgraph --network zero-demo-net \
  memgraph/memgraph-mage:3.12.0 --schema-info-enabled=True --log-level=TRACE --also-log-to-stderr

docker run -d --name zero-demo-postgres --network zero-demo-net \
  -e POSTGRES_PASSWORD=postgres \
  -v "$PWD/.memgql-work/init.sql":/docker-entrypoint-initdb.d/init.sql \
  postgres:18

docker run -d --name zero-demo-memgql --network zero-demo-net --stop-timeout 2 -p 7688:7688 \
  --env CONNECTOR_TYPE=multi \
  --env BOLT_LISTEN_ADDR=0.0.0.0:7688 \
  -v "$PWD/.memgql-work/mapping.json":/data/mapping.json \
  memgraph/memgql:0.7.0
```

Register each database with MemGQL and open a named connection to it:

```cypher
ADD CONNECTOR mg TYPE memgraph URI 'zero-demo-memgraph:7687' GRAPH memgraph;
CONNECT mg AS mg_conn;

ADD MAPPING social FROM '/data/mapping.json';
ADD CONNECTOR pg TYPE postgres URI 'host=zero-demo-postgres user=postgres password=postgres dbname=postgres' MAPPING social;
CONNECT pg AS pg_conn;
```

### Create the reasoning graph

States are nodes and actions are scored relationships. The score is the
probability that the action moves the support ticket toward resolution. The
graph has six states and seven actions, including one loop: `Request more
info` sends the ticket back to `Assess severity`, so plans differ in length as
well as score:

```cypher
MERGE (s0:State {name:"Ticket received"});
MERGE (s1:State {name:"Assess severity"});
MERGE (a:State  {name:"Auto-resolve"});
MERGE (e:State  {name:"Escalate to human"});
MERGE (r:State  {name:"Request more info"});
MERGE (d:State  {name:"Resolved"});
MATCH (s0:State{name:"Ticket received"}),(s1:State{name:"Assess severity"})  MERGE (s0)-[:ACTION {name:"triage", score:1.0}]->(s1);
MATCH (s1:State{name:"Assess severity"}),(a:State{name:"Auto-resolve"})      MERGE (s1)-[:ACTION {name:"auto_resolve", score:0.87}]->(a);
MATCH (s1:State{name:"Assess severity"}),(e:State{name:"Escalate to human"}) MERGE (s1)-[:ACTION {name:"escalate", score:0.54}]->(e);
MATCH (s1:State{name:"Assess severity"}),(r:State{name:"Request more info"}) MERGE (s1)-[:ACTION {name:"request_info", score:0.31}]->(r);
MATCH (a:State{name:"Auto-resolve"}),(d:State{name:"Resolved"})              MERGE (a)-[:ACTION {name:"close", score:0.92}]->(d);
MATCH (e:State{name:"Escalate to human"}),(d:State{name:"Resolved"})         MERGE (e)-[:ACTION {name:"human_fix", score:0.95}]->(d);
MATCH (r:State{name:"Request more info"}),(s1:State{name:"Assess severity"}) MERGE (r)-[:ACTION {name:"reassess", score:0.60}]->(s1);
```

### Read shared context through MemGQL

Every agent reads the same data through MemGQL. This query reads customer
records from PostgreSQL without copying them:

```cypher
USE CONNECTION pg_conn
  MATCH (c:Customer)-[:WORKS_AT]->(co:Company)
  WHERE c.tier = 'enterprise'
  RETURN c.name AS customer, c.tier AS tier, co.name AS company;
```

### Plan over the reasoning graph

These queries run in Memgraph, with MAGE algorithms and weighted shortest
path.

**Weighted traversal** ranks whole plans by expected value, without calling an
LLM:

```cypher
MATCH path=(:State {name:"Ticket received"})-[rels:ACTION *1..6]->(:State {name:"Resolved"})
RETURN [n IN nodes(path) | n.name] AS plan,
       round(reduce(p=1.0, r IN rels | p * r.score) * 1000) / 1000 AS expected_value
ORDER BY expected_value DESC LIMIT 4;
```

| plan | expected_value |
| --- | --- |
| Ticket received → Assess severity → Auto-resolve → Resolved | 0.8 |
| Ticket received → Assess severity → Escalate to human → Resolved | 0.513 |
| Ticket received → Assess severity → Request more info → Assess severity → Auto-resolve → Resolved | 0.149 |
| Ticket received → Assess severity → Request more info → Assess severity → Escalate to human → Resolved | 0.095 |

The top row is the chosen plan, and the rows below it are the scored
alternatives, including the longer plans that loop through `Request more
info`. To keep a record of why the plan won, narrow the same query to the
chosen plan and the runner-up:

```cypher
MATCH path=(:State {name:"Ticket received"})-[rels:ACTION *1..6]->(:State {name:"Resolved"})
WITH [n IN nodes(path) | n.name] AS plan, reduce(p=1.0, r IN rels | p * r.score) AS ev
ORDER BY ev DESC LIMIT 2
RETURN plan, round(ev * 1000) / 1000 AS expected_value;
```

**Shortest path** finds the most efficient route to the goal (cost = `1 - score`).
It agrees with the weighted traversal: `Ticket received → Assess severity →
Auto-resolve → Resolved` at a total cost of 0.21:

```cypher
MATCH path=(:State {name:"Ticket received"})-[:ACTION *WSHORTEST (e, n | 1.0 - e.score) total_cost]->(:State {name:"Resolved"})
RETURN [x IN nodes(path) | x.name] AS route, round(total_cost * 1000) / 1000 AS cost;
```

**Centrality** flags the critical intermediate state. Here `Assess severity`
(0.35) is far ahead of `Auto-resolve` and `Escalate to human` (0.075 each),
because every plan, including the loop, passes through it:

```cypher
CALL betweenness_centrality.get() YIELD node, betweenness_centrality
RETURN node.name AS state, round(betweenness_centrality * 1000) / 1000 AS centrality
ORDER BY centrality DESC LIMIT 5;
```

**Community detection** groups sub-tasks a fleet of agents can take in parallel.
On this graph it separates the intake states (`Ticket received`, `Assess
severity`, `Request more info`) from the resolution states (`Auto-resolve`,
`Escalate to human`, `Resolved`):

```cypher
CALL community_detection.get() YIELD node, community_id
RETURN community_id, collect(node.name) AS states ORDER BY community_id;
```

## Explore the data in Memgraph Lab

To see the data, connect Memgraph Lab to MemGQL's endpoint, the same
one every agent uses, and open `http://localhost:3000`:

```bash
docker run -d --name memgql-lab --network zero-demo-net -p 3000:3000 \
  -e QUICK_CONNECT_MG_HOST=zero-demo-memgql -e QUICK_CONNECT_MG_PORT=7688 \
  memgraph/lab:3.12.0
```

## Give agents access through MCP

To let your agents share the data through MCP, run the [Memgraph MCP
server](https://memgraph.com/docs/ai-ecosystem/integrations/mcp) against MemGQL's endpoint,
`bolt://localhost:7688`, and add it to each agent's MCP configuration. The
example doesn't start the MCP server; for a working setup, see
[`agentic-graphrag.sh`](https://github.com/memgraph/memgraph-platform/blob/main/code-examples/agentic-graphrag.sh).

```json
{
  "mcpServers": {
    "memgraph-zero": {
      "url": "http://localhost:8000/mcp/"
    }
  }
}
```

## Limitations

MemGQL is in early development:

- **Analytics run in Memgraph.** MAGE algorithms and weighted shortest path
  run in Memgraph itself. MemGQL sends pattern queries to each database.
- **No authentication.** Run MemGQL only locally.
- **Two databases** in MemGQL Community, and any number in Enterprise.

## Clean up

Download the script and run it with `clean`:

**Linux/macOS**

```bash
./agentic-ai.sh clean
```

**Windows**

```powershell
.\agentic-ai.ps1 clean
```

If you started Memgraph Lab, remove it too:

```bash
docker rm -f memgql-lab
```

## Related

- [Agentic Data Access](https://memgraph.com/docs/memgraph-zero/memgql/use-cases/agentic): How MemGQL
  gives agents one graph over data spread across many backends.
- [Agentic GraphRAG](https://memgraph.com/docs/ai-ecosystem/graph-rag/agentic-graphrag): Let an agent
  pick the right GraphRAG retrieval pipeline for each question.
