# JSON Structure for the Knowledge Graph in Understand-Anything: Complete Schema Guide

> Explore the complete JSON structure for the Understand-Anything knowledge graph. Discover nodes, edges, layers, and tour elements validated by Zod schema.

- Repository: [Yuxiang Lin/Understand-Anything](https://github.com/Lum1104/Understand-Anything)
- Tags: api-reference
- Published: 2026-06-06

---

**The knowledge graph in Understand-Anything is represented as a single JSON object conforming to the `KnowledgeGraph` interface, containing `nodes` (typed code elements), `edges` (relationships), `layers` (logical groupings), and `tour` (learning steps), all validated against a Zod schema.**

The **JSON structure for the knowledge graph** is the canonical data model that powers the Understand-Anything platform, capturing a complete, typed view of a project's codebase, configuration, and domain knowledge. This schema is defined in TypeScript and enforced through runtime validation, ensuring every graph file produced by the analyzer is machine-readable and strongly typed.

## Top-Level JSON Schema

The root object follows the `KnowledgeGraph` interface defined in **[`packages/core/src/types.ts`](https://github.com/Lum1104/Understand-Anything/blob/main/packages/core/src/types.ts)** (lines 90-99). This structure serves as the contract between the analyzer, persistence layer, and dashboard UI.

A valid knowledge graph JSON contains six mandatory top-level properties:

- **`version`** – A string identifier for the graph schema version, enabling migration logic between analyzer versions.
- **`kind`** – An optional discriminator accepting `"codebase"` or `"knowledge"` to indicate the graph's primary domain.
- **`project`** – A `ProjectMeta` object containing repository metadata (name, detected languages, frameworks, analysis timestamp, and commit hash).
- **`nodes`** – An array of `GraphNode` objects representing concrete elements like files, functions, services, or documentation articles.
- **`edges`** – An array of `GraphEdge` objects modeling relationships (imports, calls, depends_on, cites) between nodes.
- **`layers`** – An array of `Layer` objects providing logical groupings of node IDs for high-level architecture views.
- **`tour`** – An array of `TourStep` objects defining ordered learning steps for the "learn" persona experience.

## Node and Edge Specifications

### GraphNode Structure

Each node in the **`nodes`** array conforms to `GraphNode`, defined in **[`packages/core/src/schema.ts`](https://github.com/Lum1104/Understand-Anything/blob/main/packages/core/src/schema.ts)** (lines 68-76). Nodes are strongly typed with 21 canonical types managed through the `NODE_TYPE_ALIASES` mapping.

A complete `GraphNode` includes:

- **`id`** – Unique identifier (typically a stable hash or URI).
- **`type`** – One of 21 canonical types (e.g., `"file"`, `"function"`, `"class"`, `"service"`, `"article"`).
- **`name`** – Human-readable identifier.
- **`filePath`** & **`lineRange`** – Optional source location tracking.
- **`summary`** – AI-generated or human-written description.
- **`tags`** – Arbitrary classification strings.
- **`complexity`** – Calculated metric for code elements.
- **`domainMeta`** or **`knowledgeMeta`** – Extended metadata for specific domains.

### GraphEdge Structure

Relationships are stored in the **`edges`** array as `GraphEdge` objects (**[`packages/core/src/schema.ts`](https://github.com/Lum1104/Understand-Anything/blob/main/packages/core/src/schema.ts)**, lines 88-94), supporting 35 distinct relationship types.

Every edge specifies:

- **`source`** and **`target`** – Node IDs defining the relationship endpoints.
- **`type`** – Relationship classification from 35 enums (e.g., `"imports"`, `"calls"`, `"depends_on"`, `"cites"`).
- **`direction`** – Relationship directionality: `"forward"`, `"backward"`, or `"bidirectional"`.
- **`description`** – Optional human-readable explanation.
- **`weight`** – Numeric confidence score between 0 and 1.

## Validation and Schema Enforcement

Understand-Anything validates every JSON graph against the `KnowledgeGraphSchema` using the **`validateGraph`** function located in **[`packages/core/src/schema.ts`](https://github.com/Lum1104/Understand-Anything/blob/main/packages/core/src/schema.ts)** (lines 98-162). This pipeline ensures data integrity through five stages:

1. **Sanitization** – Cleans optional fields and normalizes enum strings to canonical forms.
2. **Auto-fixing** – Applies defaults for missing values (e.g., `type: "file"` for nodes, `direction: "forward"` for edges).
3. **Alias normalization** – Converts LLM-generated type aliases to canonical enums using `NODE_TYPE_ALIASES` and `EDGE_TYPE_ALIASES`.
4. **Collection validation** – Validates each node and edge, dropping invalid entries while accumulating `issues` for reporting.
5. **Type generation** – Returns a strongly typed `KnowledgeGraph` object on success, or detailed error information on failure.

## Working with the Knowledge Graph JSON

### Loading and Validating a Graph

When consuming a persisted knowledge graph, always validate the JSON before processing. The **`validateGraph`** function from `@understand-anything/core` ensures runtime type safety:

```typescript
import { readFileSync } from "node:fs";
import { validateGraph } from "@understand-anything/core";

const raw = JSON.parse(readFileSync("./.understand-anything/knowledge-graph.json", "utf-8"));
const result = validateGraph(raw);

if (result.success) {
  const graph = result.data; // strongly-typed KnowledgeGraph
  console.log(`Graph version ${graph.version} contains ${graph.nodes.length} nodes`);
} else {
  console.error("Invalid graph:", result.fatal ?? result.errors);
}

```

### Querying Nodes by Type

Filter the `nodes` array using the canonical type enumeration to extract specific code elements:

```typescript
function nodesOfType(graph: KnowledgeGraph, type: NodeType): GraphNode[] {
  return graph.nodes.filter((n) => n.type === type);
}

// Example: extract all functions
const functionNodes = nodesOfType(graph, "function");
console.log(`Found ${functionNodes.length} functions`);

```

### Building Relationship Maps

Transform the flat `edges` array into an adjacency map for efficient graph traversal:

```typescript
function buildAdjacencyMap(graph: KnowledgeGraph): Record<string, string[]> {
  const map: Record<string, string[]> = {};
  for (const edge of graph.edges) {
    if (!map[edge.source]) map[edge.source] = [];
    map[edge.source].push(edge.target);
  }
  return map;
}

const adjacency = buildAdjacencyMap(graph);
console.log(`Node ${graph.nodes[0].id} points to ${adjacency[graph.nodes[0].id]?.length ?? 0} nodes`);

```

### Generating Learning Tours

The `tour` property can be generated programmatically using the `generateHeuristicTour` function, which creates ordered `TourStep` objects for subset graphs:

```typescript
import { generateHeuristicTour } from "@understand-anything/core";

const subsetGraph: KnowledgeGraph = {
  ...graph,
  nodes: graph.nodes.filter((n) => n.type === "function"),
  edges: graph.edges.filter((e) => 
    subsetGraph.nodes.some((n) => n.id === e.source) &&
    subsetGraph.nodes.some((n) => n.id === e.target)
  ),
  layers: [],
  tour: []
};

const tour = generateHeuristicTour(subsetGraph);
console.log(`Generated ${tour.length} tour steps`);

```

## Summary

- The **knowledge graph JSON** follows the `KnowledgeGraph` interface defined in [`packages/core/src/types.ts`](https://github.com/Lum1104/Understand-Anything/blob/main/packages/core/src/types.ts), requiring `version`, `project`, `nodes`, `edges`, `layers`, and `tour` properties.
- **Nodes** support 21 canonical types with metadata fields for source locations, complexity, and domain-specific extensions.
- **Edges** model 35 relationship types with directional semantics and confidence weights between 0 and 1.
- The **`validateGraph`** function in [`packages/core/src/schema.ts`](https://github.com/Lum1104/Understand-Anything/blob/main/packages/core/src/schema.ts) enforces schema compliance through sanitization, auto-fixing, and alias normalization.
- Persistence occurs via [`packages/core/src/persistence/index.ts`](https://github.com/Lum1104/Understand-Anything/blob/main/packages/core/src/persistence/index.ts), while the dashboard consumes the JSON through [`packages/dashboard/src/store.ts`](https://github.com/Lum1104/Understand-Anything/blob/main/packages/dashboard/src/store.ts).

## Frequently Asked Questions

### What are the valid node types in the knowledge graph?

The schema defines **21 canonical node types** including `"file"`, `"function"`, `"class"`, `"interface"`, `"variable"`, `"service"`, `"article"`, and `"database"`. These are enforced through the `NODE_TYPE_ALIASES` mapping in [`packages/core/src/schema.ts`](https://github.com/Lum1104/Understand-Anything/blob/main/packages/core/src/schema.ts), which normalizes LLM-generated variations to these standard types.

### How does Understand-Anything validate the JSON structure?

Validation occurs through the **`validateGraph`** function in [`packages/core/src/schema.ts`](https://github.com/Lum1104/Understand-Anything/blob/main/packages/core/src/schema.ts) (lines 98-162), which uses Zod schemas to check type correctness, auto-fix missing fields, normalize enum aliases, and return either a strongly typed `KnowledgeGraph` object or a detailed error report.

### Where is the knowledge graph JSON stored?

The persistence layer in **[`packages/core/src/persistence/index.ts`](https://github.com/Lum1104/Understand-Anything/blob/main/packages/core/src/persistence/index.ts)** handles reading and writing the JSON file. By default, the analyzer outputs to [`./.understand-anything/knowledge-graph.json`](https://github.com/Lum1104/Understand-Anything/blob/main/./.understand-anything/knowledge-graph.json) in the project root, though this path is configurable through the persistence API.

### Can I extend the knowledge graph with custom node types?

While the schema strictly enforces 21 canonical node types for core functionality, you can attach custom metadata through the **`tags`** array on any node or use **`domainMeta`**/`knowledgeMeta`** fields for domain-specific extensions. For permanent new types, modify the `NODE_TYPE_ALIASES` and `GraphNodeSchema` in [`packages/core/src/schema.ts`](https://github.com/Lum1104/Understand-Anything/blob/main/packages/core/src/schema.ts) and rebuild the analyzer.