> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bsyncs.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Graph QA

> Answer complex relational questions using multi-hop traversal over your Neo4j knowledge graph.

<Note>**Cost:** 10 operations per call. Available on **Starter plan and above**.</Note>

## `POST /brain/retrieve/graph-qa`

Graph QA is the highest-intelligence retrieval mode. Instead of simple vector similarity, it:

1. **Finds seed entities** — uses vector search to locate the starting nodes most relevant to your question
2. **Traverses the graph** — BFS expansion up to `max_hops` hops from each seed
3. **Grounds the answer** — passes only the traversed facts to the LLM, forcing a fact-grounded response with zero hallucination

This is ideal for questions that require **connecting multiple pieces of information** stored across different ingestion sessions.

***

## Request body

```json theme={null}
{
  "query": "Which engineers are connected to the PostgreSQL migration and what were their roles?",
  "max_hops": 3,
  "k": 10
}
```

| Field      | Type     | Required | Default | Description                                                   |
| ---------- | -------- | -------- | ------- | ------------------------------------------------------------- |
| `query`    | `string` | ✓        | —       | Natural language question to answer from the knowledge graph. |
| `max_hops` | `int`    |          | `3`     | Graph traversal depth (1–5). Higher = more connected context. |
| `k`        | `int`    |          | `10`    | Max facts to retrieve (1–50).                                 |
| `persona`  | `string` |          | `null`  | Restrict graph traversal to a persona.                        |

***

## Response

```json theme={null}
{
  "answer": "Based on the knowledge graph [1][3], Sarah Jenkins led the PostgreSQL migration as Lead Engineer. She worked alongside Alex Chen (Database Administrator) [2] and the migration was approved by Mark Liu (CTO) [4]. The migration involved moving from MySQL to PostgreSQL for improved JSONB support.",
  "facts_used": 12
}
```

| Field        | Type     | Description                                                                 |
| ------------ | -------- | --------------------------------------------------------------------------- |
| `answer`     | `string` | LLM-generated answer grounded in retrieved graph facts. Cites fact numbers. |
| `facts_used` | `int`    | Number of graph facts passed to the LLM as context.                         |

***

## Code examples

<CodeGroup>
  ```python Python SDK theme={null}
  from atlas_mem import AtlasMem

  brain = AtlasMem(api_key="atlas_...", base_url="https://api.bsyncs.com", user_id="user-123")

  # Ask a multi-hop question
  answer = brain.ask("Which engineers worked on the PostgreSQL migration?")
  print(answer)

  # With deeper traversal
  answer = brain.ask(
      "What is the relationship between Sarah Jenkins and the payment infrastructure?",
      max_hops=4,
  )
  print(answer)
  ```

  ```python Python (requests) theme={null}
  import requests

  response = requests.post(
      "https://api.bsyncs.com/brain/retrieve/graph-qa",
      headers={
          "x-api-key": "atlas_your_key_here",
          "Content-Type": "application/json",
      },
      json={
          "query": "Which engineers worked on the PostgreSQL migration?",
          "max_hops": 3,
          "k": 10,
      }
  )
  data = response.json()
  print(data["answer"])
  ```

  ```bash cURL theme={null}
  curl -X POST https://api.bsyncs.com/brain/retrieve/graph-qa \
    -H "x-api-key: atlas_your_key_here" \
    -H "Content-Type: application/json" \
    -d '{
      "query": "Which engineers worked on the PostgreSQL migration?",
      "max_hops": 3
    }'
  ```

  ```typescript TypeScript (fetch) theme={null}
  const response = await fetch("https://api.bsyncs.com/brain/retrieve/graph-qa", {
    method: "POST",
    headers: {
      "x-api-key": "atlas_your_key_here",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      query: "Which engineers worked on the PostgreSQL migration?",
      max_hops: 3,
      k: 10,
    }),
  });

  const { answer, facts_used } = await response.json();
  console.log(answer);
  ```
</CodeGroup>

***

## Graph QA vs. regular retrieve

| Feature            | `retrieve`                               | `graph-qa`                         |
| ------------------ | ---------------------------------------- | ---------------------------------- |
| **Memory sources** | Episodic + Semantic + Working            | Semantic graph only                |
| **Answer type**    | Ranked facts list                        | Natural language answer            |
| **Multi-hop**      | Optional                                 | Always                             |
| **LLM call**       | Optional (compression)                   | Always                             |
| **Best for**       | Injecting context into your own LLM call | Direct factual Q\&A from the graph |
| **Cost**           | 2 ops                                    | 10 ops                             |

Use `retrieve` when you want to **control the LLM call yourself**. Use `graph-qa` when you want Atlas to **answer the question directly**.

***

## Example — building a Q\&A agent

```python theme={null}
from atlas_mem import AtlasMem

brain = AtlasMem(
    api_key="atlas_...",
    base_url="https://api.bsyncs.com",
    user_id="user-123",
)

# First, build up knowledge
brain.add("Sarah Jenkins is the Lead Engineer at Acme Corp.")
brain.add("Sarah led the PostgreSQL migration in Q3 2024.")
brain.add("The PostgreSQL migration improved query performance by 60%.")
brain.add("Alex Chen is the Database Administrator who executed the migration.")
brain.add("The migration was approved by Mark Liu, CTO of Acme Corp.")

# Now ask relational questions — no LLM key needed on your side
print(brain.ask("Who approved the database migration?"))
# → "The database migration was approved by Mark Liu, the CTO of Acme Corp. [4]"

print(brain.ask("What was the outcome of the PostgreSQL migration?"))
# → "The PostgreSQL migration improved query performance by 60%. [3]"

print(brain.ask("How is Sarah Jenkins connected to the CTO?"))
# → "Sarah Jenkins, as Lead Engineer, led the PostgreSQL migration which was approved by Mark Liu (CTO). [1][4][5]"
```

***

## Guardrails

Graph QA has built-in prompt injection protection:

* Facts are **numbered and sandboxed** — the LLM is instructed to cite by number, not quote
* Instructions embedded in stored facts (e.g. *"ignore previous instructions"*) are **stripped** before being passed to the LLM
* Results are **scoped to your `user_id`** — the traversal query includes `user_id` filters at every hop, so cross-tenant leakage is impossible at the database level

<Warning>
  Graph QA requires `OPENAI_API_KEY` to be set on the server. If it is unavailable, the endpoint returns `{"answer": "", "error": "LLM not available"}`. In this case, use the `retrieve` endpoint instead and pass the facts to your own LLM.
</Warning>
