# How Layer Detection Maps Code to Architectural Tiers in Understand-Anything

> Discover how Understand-Anything maps code to architectural tiers using heuristic directory matching and optional LLM refinement. Unlock better code comprehension.

- Repository: [Egonex/Understand-Anything](https://github.com/Egonex-AI/Understand-Anything)
- Tags: architecture
- Published: 2026-06-25

---

**The layer detection system in Understand-Anything assigns every file node in the knowledge graph to a logical architectural tier using heuristic directory-pattern matching, with optional LLM-driven refinement for custom mappings.**

In the `Egonex-AI/Understand-Anything` repository, the analyzer component automatically infers architectural layers from project structure. This capability bridges the gap between raw file paths and high-level architectural understanding, enabling the tool to categorize code into logical tiers such as API, Service, and Data layers.

## Heuristic Directory-Pattern Matching

The primary mechanism for layer detection relies on predefined folder patterns that map directory names to architectural tiers.

### The LAYER_PATTERNS Configuration

The system uses a built-in `LAYER_PATTERNS` list defined in [`layer-detector.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/layer-detector.ts) (lines 16-67) to identify which folders belong to specific layers. Common mappings include:

- `"routes"` → **API Layer**
- `"service"` → **Service Layer**
- `"model"` → **Data Layer**

These patterns include plural forms and cover conventional naming conventions for controllers, repositories, utilities, and UI components.

### Path Normalization and Segment Matching

The `matchFileToLayer(filePath)` function (lines 80-95) normalizes file paths, splits them into segments, and checks each segment against the pattern list. The first matching pattern wins, returning the corresponding layer name. Files that fail to match any pattern are assigned to the fallback **Core** layer.

This implementation iterates over path segments sequentially, ensuring predictable assignment based on the most specific directory match encountered first.

## LLM-Driven Refinement

When heuristic matching proves insufficient, the system can leverage language models to propose custom layer definitions based on actual file contents and project context.

### Building the Detection Prompt

The `buildLayerDetectionPrompt` function (lines 150-169) constructs a markdown-formatted prompt containing an indented list of all file paths from the knowledge graph. This prompt is sent to the LLM to solicit architectural analysis and layer categorization suggestions.

### Parsing and Applying LLM Suggestions

After receiving the LLM response, `parseLayerDetectionResponse` (lines 174-200) extracts JSON arrays from raw or fenced-code blocks, validating each layer entry against expected schema.

The `applyLLMLayers` function (lines 222-284) then matches file paths against the LLM-provided `filePatterns`. Files matching a pattern are assigned to that layer, while unassigned files are placed in an **Other** layer. This refinement process allows the system to adapt to domain-specific architectures that fall outside standard conventions.

## Implementation Workflow

The complete layer detection workflow follows this sequence:

1. **Graph Construction** - Build the knowledge graph with file nodes from the codebase
2. **Heuristic Detection** - Execute `detectLayers(graph)` (lines 100-144) to create a `Map<string, string[]>` of layer names to node IDs, generating `Layer` objects with IDs created via `toLayerId`
3. **Optional LLM Refinement** - Build the prompt, send to LLM, parse response, and apply custom layers using `applyLLMLayers`

The `detectLayers` function handles the initial pass, constructing layer objects and ensuring every file receives a tier assignment, either through pattern matching or the Core fallback.

## Practical Code Examples

The following TypeScript examples demonstrate the layer detection API using the core analyzer functions:

```ts
import { detectLayers, buildLayerDetectionPrompt, parseLayerDetectionResponse, applyLLMLayers } from '@understand-anything/core/analyzer';
import type { KnowledgeGraph } from '@understand-anything/core/types';

// Example: a tiny synthetic graph
const graph: KnowledgeGraph = {
  nodes: [
    { id: '1', type: 'file', filePath: 'src/routes/user.ts' },
    { id: '2', type: 'file', filePath: 'src/service/auth.ts' },
    { id: '3', type: 'file', filePath: 'src/model/user.ts' },
    { id: '4', type: 'file', filePath: 'src/ui/dashboard.vue' },
    { id: '5', type: 'file', filePath: 'src/util/helpers.ts' },
  ],
  edges: [],
};

// 1️⃣ Heuristic detection
const heuristic = detectLayers(graph);
console.log('Heuristic layers →', heuristic.map(l => l.name));
/* → ["API Layer","Service Layer","Data Layer","UI Layer","Utility Layer"] */

// 2️⃣ LLM‑driven detection (pseudo‑LLM call)
const prompt = buildLayerDetectionPrompt(graph);
console.log('Prompt sent to LLM:', prompt);

// Assume `llmResponse` is the raw string returned by the model:
const llmResponse = `
[
  { "name": "API", "description": "HTTP entry points", "filePatterns": ["src/routes/"] },
  { "name": "Domain", "description": "Business logic", "filePatterns": ["src/service/","src/model/"] },
  { "name": "Presentation", "description": "UI components", "filePatterns": ["src/ui/"] }
]
`;
const llmLayers = parseLayerDetectionResponse(llmResponse);
if (llmLayers) {
  const refined = applyLLMLayers(graph, llmLayers);
  console.log('LLM‑refined layers →', refined.map(l => l.name));
  // → ["API","Domain","Presentation","Other"]
}

```

## Key Implementation Files

The layer detection logic spans several files within the `understand-anything-plugin` package:

| File | Role | Location |
|------|------|----------|
| [`layer-detector.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/layer-detector.ts) | Core implementation of heuristic detection, LLM prompt building, response parsing, and layer application | [`packages/core/src/analyzer/layer-detector.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/packages/core/src/analyzer/layer-detector.ts) |
| [`types.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/types.ts) | TypeScript definitions for `KnowledgeGraph` and `Layer` interfaces | [`packages/core/src/types.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/packages/core/src/types.ts) |
| [`layerStats.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/layerStats.ts) | Utility for aggregating statistics per layer dashboard visualization | [`packages/dashboard/src/utils/layerStats.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/packages/dashboard/src/utils/layerStats.ts) |
| [`layer-detector.test.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/layer-detector.test.ts) | Unit tests ensuring pattern matching accuracy and fallback behavior | [`packages/core/src/__tests__/layer-detector.test.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/packages/core/src/__tests__/layer-detector.test.ts) |

## Summary

- **Layer detection** in Understand-Anything uses a two-tier approach: heuristic pattern matching followed by optional LLM refinement.
- The `matchFileToLayer` function in [`layer-detector.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/layer-detector.ts) handles directory-segment matching against `LAYER_PATTERNS`, with **Core** as the fallback tier.
- **LLM-driven refinement** allows custom architectural mappings through `buildLayerDetectionPrompt`, `parseLayerDetectionResponse`, and `applyLLMLayers`.
- Files processed via LLM methods that match no patterns are assigned to an **Other** layer.
- The system generates `Layer` objects with unique IDs via `toLayerId`, storing mappings as `Map<string, string[]>` of layer names to node IDs.

## Frequently Asked Questions

### How does the layer detector handle files in unconventional directory structures?

Files that do not match any entry in the `LAYER_PATTERNS` list are automatically assigned to the **Core** layer during heuristic detection. When using LLM refinement, unmatched files are placed in an **Other** layer, ensuring every file node receives a tier assignment regardless of naming conventions.

### Can I customize the layer patterns without using the LLM feature?

Yes. The `LAYER_PATTERNS` constant in [`layer-detector.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/layer-detector.ts) (lines 16-67) can be modified to include custom folder names and layer mappings. Patterns are checked sequentially, so you can prioritize specific directories by ordering them earlier in the array.

### What format does the LLM need to return for layer detection?

The LLM must return a JSON array where each object contains `name`, `description`, and `filePatterns` properties. The `parseLayerDetectionResponse` function (lines 174-200) handles both raw JSON and fenced code blocks (triple backticks), validating the structure before applying the mappings via `applyLLMLayers`.

### How does layer detection impact the Understand-Anything dashboard?

After layers are resolved, the [`layerStats.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/layerStats.ts) utility aggregates code metrics per tier for visualization. This allows the dashboard to display architectural statistics—such as file count and complexity distribution—across the API, Service, Data, and other detected layers, providing high-level architectural insights derived from the `detectLayers` output.