# Knowledge graphs: follow a relationship to its evidence

An original LockedIn Labs workshop for forward deployed engineers. Plan for about 45 minutes. You need Python 3.11+ with its standard-library SQLite module. Everything runs in memory using fictional services and documents; no account, package installation, model, cloud or customer data is involved.

## 1. Start with what a knowledge graph is

A **knowledge graph is a representation of things and the relationships between them**. The things are entities, often drawn as nodes. Relationships are edges, drawn as arrows when direction matters. A graph database is one way to store this representation; a graph is not itself a programming language or an AI agent.

Think about a dependency map you might sketch during an incident. “Procedure search depends on Source catalog” is one relationship. If Draft assistant depends on Procedure search, you can follow two relationships to find a possible indirect dependency. Crossing one relationship is called a hop.

That helps an FDE ask better questions: which services are connected to a changing source, which owner should be consulted, and which evidence supports the connection? It does not tell you by itself which services actually fail. Caches, fallbacks, schedules and deployment differences can change the operational effect.

An arrow is a claim. Store its relationship type, direction, source and version. A sentence saying a service “may use” a database is not enough to assert that it does. A model extracting that sentence would not remove the uncertainty.

## 2. Follow the relationship and its source

The fictional desk has a Source catalog, Procedure search, Draft assistant and Service desk. All arrows mean **depends on**, pointing from a dependent to what it uses. The question is: which services have a documented dependency path to Source catalog?

Start at Source catalog and look for incoming arrows. This walks the dependency direction backwards to discover dependents. Keep the returned path in the normal reading order: Service desk → Draft assistant → Procedure search → Source catalog. The model endpoint branch is not on a path to the catalog.

The visual below replays actual results from the downloadable SQL. Read the map, select a returned path, then inspect every supporting source. Change the case and explain why the answer changes before looking at the feedback.

## 3. Run the SQLite proof lab

Download `fde-graph-retrieval.py` using the card below. Open a terminal in the folder containing the file. Use your installed Python 3.11+ command; `python3` is the example here.

```shell
python3 fde-graph-retrieval.py run --case baseline
python3 fde-graph-retrieval.py run --case one-hop
python3 fde-graph-retrieval.py run --case withdrawn
python3 fde-graph-retrieval.py run --case unverified
python3 fde-graph-retrieval.py run --case cycle
python3 fde-graph-retrieval.py test
```

The program creates real SQLite tables and executes a recursive query. The browser is a replay; your terminal runs the query. `paths` contains the returned node IDs, edge IDs and number of hops. For each edge, look up the source in `SOURCES`. `eligibleEdges` includes relationships that pass the rules even if they do not belong to a returned path.

| Case | Predict before running | What to examine |
| --- | --- | --- |
| baseline | Which three services connect to the catalog? | Direct and indirect paths, with E1–E3 supporting the longest path. |
| one-hop | Does a missing indirect result mean independence? | The deliberate one-hop boundary. |
| withdrawn | What happens when S3 is unavailable? | E3 is excluded before traversal; paths needing it disappear. |
| unverified | What changes if the query trusts an unreviewed claim? | The deliberately weakened rule admits E5 and Billing export. |
| cycle | Will the query revisit Source catalog forever? | A visited-node guard stops repetition; it does not validate the design. |

The evidence rule also excludes a retired source and another workspace at every hop, including in the deliberately weakened verification case. These fixture predicates illustrate scoped retrieval; they are not a production identity provider or a substitute for per-document authorization.

## 4. Read the query as a process

Open the file and locate `ELIGIBLE`, `QUERY` and `retrieve`. First make a set of usable edges: both endpoint entities and the supporting source must belong to the selected workspace; the source must be current and available; the relationship must be `DEPENDS_ON`; and its claim must be verified. The deliberately weakened case changes only the final condition.

The recursive common table expression, or CTE, starts with Source catalog. Each iteration finds an eligible incoming edge, prepends its origin and edge ID to the current path, and increases the hop count. It extends a path only below the hop limit and only if the origin has not already appeared in that path. The final query returns non-empty paths in a deterministic order.

```sql
FROM walk w JOIN eligible e ON e.target = w.node
WHERE w.depth < :max_hops
  AND instr(w.node_path, '|' || e.origin || '|') = 0
```

This is an excerpt from the actual query. The `:max_hops`, target and workspace values are bound parameters, not concatenated SQL. The delimiter representation is suitable for these fixed synthetic IDs; a general implementation needs an unambiguous path representation for arbitrary IDs. SQLite's instruction budget is an additional backstop in this lab. Large branching graphs need explicit work limits, query planning and evaluation of partial results.

## 5. Change the evidence yourself

First vary the traversal without editing the code:

```shell
python3 fde-graph-retrieval.py run --case baseline --max-hops 2
```

Predict which path disappears and explain why the underlying service map has not changed. Now save a separate copy of the Python file and change S2's source state from `available` to `withdrawn` in `SOURCES`. Run the baseline in that changed copy. Procedure search should remain, while Draft assistant and Service desk lose their supporting path. Compare this with withdrawing S3, which removes all three paths.

In another disposable copy, change E3's relationship type from `DEPENDS_ON` to `MENTIONS`. A mention is not a dependency, so the traversal should stop using E3. Preserve the original file and record both diffs. The built-in tests assume the original fixture and should flag these changes; do not weaken them to make your altered fixture look unchanged.

Write a short evidence note containing the business question, query scope, changed input, actual returned paths, source versions, and what remains unknown. Ask a reviewer to challenge one claim: does the cited text really establish the relationship, and what operational observation would confirm its effect?

## 6. Separate the four meanings of graph

| Name | What it represents or does | Why it matters here |
| --- | --- | --- |
| Knowledge graph | Entities and typed relationships with provenance. | This lab retrieves supported dependency paths. |
| HNSW index | A graph structure used for approximate nearest-neighbor vector search. | Neighboring vectors do not inherently encode business dependencies. |
| LangGraph | A framework for stateful workflow and agent orchestration. | Its execution graph controls steps; it is not this source-of-evidence graph. |
| Microsoft GraphRAG | A retrieval and generation approach with indexing and several query modes. | Its local and global approaches involve more than this SQL traversal. |

Our lab supplies a structured evidence packet. An optional later model step could explain the packet with citations, but that would add answer-generation and citation-fidelity checks. This exercise does not run extraction, entity resolution, community reports or generation, and is not a complete implementation of Microsoft GraphRAG.

Use graph retrieval when your questions need represented relationships and you can maintain their evidence. Start with authorized SQL for exact facts, or a lexical/vector baseline for passages. Compare alternatives against independent expected evidence, including missing links, outdated sources, ambiguous names, denied access, cycles and no-answer questions. Additional machinery needs to correct an observed failure.

Continue with the [hybrid-search lab](/training/guides/hybrid-search) to compare passage rankings, or [evaluation science](/training/guides/evaluation-science) to design a fair experiment.

## 7. Primary references and your handoff

The original lesson and fictional examples are authored by LockedIn Labs. These primary references were checked on 23 October 2026:

- [SQLite: recursive common table expressions and graph queries](https://sqlite.org/lang_with.html) — the engine feature used by the lab.
- [Microsoft GraphRAG query overview](https://microsoft.github.io/graphrag/query/overview/) — distinctions between local, global, DRIFT and basic search.
- [LangGraph overview](https://docs.langchain.com/oss/python/langgraph/overview) — workflow orchestration terminology.

Keep your predictions, actual SQL outputs, changed-copy diffs and evidence note. A successful local run demonstrates this fixture and query; production permissions, scale, source lifecycle, entity resolution and operational impact remain separate engineering work.
