How the Layer-Detector Identifies API, Service, and Data Layers in Understand-Anything

The layer-detector uses a two-stage heuristic that matches directory name keywords against ordered patterns in LAYER_PATTERNS, falling back to a generic Core layer for unmatched files, with optional LLM-driven classification for complex cases.

The layer-detector in the Egonex-AI/Understand-Anything repository automatically discovers architectural layers by analyzing file paths within a knowledge graph. Implemented in understand-anything-plugin/packages/core/src/analyzer/layer-detector.ts, this module categorizes code into layers like API, Service, and Data through static pattern matching, with an optional LLM-based fallback for non-standard architectures.

Pattern-Based Heuristic Matching with LAYER_PATTERNS

The core detection logic relies on a constant called LAYER_PATTERNS defined at lines 16-66 of layer-detector.ts. This ordered array maps directory-name keywords to canonical architectural layers, ensuring the first matching pattern wins when scanning file paths.

Ordered Pattern Priority

Each entry in LAYER_PATTERNS supplies a set of directory patterns, a canonical layer name, and a descriptive label. Because the array is ordered, the detector prioritizes earlier matches, preventing ambiguous classifications when directory names could map to multiple layers. This deterministic approach ensures consistent results across repeated scans of the same codebase.

Supported Architectural Layers

The predefined patterns cover standard architectural tiers including API (HTTP endpoints, route handlers), Service (business logic), Data (persistence, models), and UI (user interface components). Each pattern set includes common directory naming conventions—such as api, services, data, or models—allowing the detector to recognize both singular and plural directory names.

Path-Segment Inspection and Normalization

When processing a file node, the layer-detector normalizes the file path and splits it into segments for inspection, as implemented in the matchFileToLayer function (lines 80-96).

Directory Name Normalization

The detector processes the filePath property of each node, converting path segments into comparable strings. It scans each segment against the LAYER_PATTERNS entries, comparing directory names to identify which architectural layer owns the file.

Plural Form Handling

The matching logic recognizes both singular and plural forms of directory names. If a segment equals a pattern exactly or matches its plural variant, the corresponding layer name is returned. Files that fail to match any pattern—or those lacking a filePath property—automatically fall back to the generic Core layer classification.

The detectLayers Function and Core Fallback

The detectLayers function (lines 105-127) orchestrates the classification process across the entire knowledge graph.

Grouping Nodes by Layer

The function iterates over all file-type nodes in the graph, invoking matchFileToLayer for each. It collects node IDs by their derived layer names, then constructs an array of Layer objects containing the layer name, description, and associated file references.

Unmatched File Handling

Unmatched files and pathless nodes are deliberately placed in the Core layer. This ensures every file in the knowledge graph receives a classification while maintaining clear separation between recognized architectural tiers and generic application code.

LLM-Driven Layer Detection Fallback

Beyond static heuristics, the module supports intelligent classification through LLM inference when directory structures deviate from standard conventions.

Building the Detection Prompt

The buildLayerDetectionPrompt function generates a structured prompt containing the knowledge graph context, which can be sent to models like Claude or GPT-4. This allows the system to propose custom layer definitions when static patterns prove insufficient.

Parsing and Applying LLM Responses

After receiving the LLM's JSON response, parseLayerDetectionResponse validates and extracts layer definitions. The applyLLMLayers function then applies these definitions to the graph nodes, overriding or supplementing the heuristic results. This hybrid approach combines the speed of pattern matching with the flexibility of AI-driven analysis.

Practical Implementation Examples

Use the detectLayers function to classify an existing knowledge graph:

import { detectLayers } from "./layer-detector";
import type { KnowledgeGraph } from "./types";

// Suppose `graph` is a KnowledgeGraph built from a project scan
const layers = detectLayers(graph);

// Print a summary
layers.forEach(l => {
  console.log(`🧱 ${l.name} – ${l.description} (${l.nodeIds.length} files)`);
});

/* Example output
🧱 API Layer – HTTP endpoints, route handlers, and API controllers (12 files)
🧱 Service Layer – Business logic and application services (8 files)
🧱 Data Layer – Data models, database access, and persistence (5 files)
🧱 Core – Core application files (20 files)
*/

For LLM-driven classification:

import {
  buildLayerDetectionPrompt,
  parseLayerDetectionResponse,
  applyLLMLayers,
} from "./layer-detector";

// Generate a prompt for the LLM (e.g. Claude, GPT‑4)
const prompt = buildLayerDetectionPrompt(graph);
// → send `prompt` to the LLM and obtain `response` (JSON string)

// Parse the LLM reply
const llmLayers = parseLayerDetectionResponse(response);
if (llmLayers) {
  const customLayers = applyLLMLayers(graph, llmLayers);
  // `customLayers` now reflects the LLM‑assigned layers
}

Summary

  • The layer-detector in understand-anything-plugin/packages/core/src/analyzer/layer-detector.ts identifies architectural layers through ordered pattern matching against the LAYER_PATTERNS constant.
  • Path segments are normalized and checked against directory keywords, with plural form support, defaulting unmatched files to the Core layer.
  • The detectLayers function processes entire knowledge graphs, grouping file nodes by their derived layer classifications.
  • Optional LLM integration via buildLayerDetectionPrompt, parseLayerDetectionResponse, and applyLLMLayers enables custom layer detection for non-standard project structures.
  • Unit tests in understand-anything-plugin/packages/core/src/__tests__/layer-detector.test.ts validate expected behavior and edge-case handling.

Frequently Asked Questions

How does the layer-detector handle files that don't match any pattern?

Files that fail to match any entry in LAYER_PATTERNS, or those lacking a filePath property, are automatically assigned to the Core layer. This ensures complete graph coverage while distinguishing unrecognized files from explicitly categorized architectural layers.

What happens when multiple patterns match a single file path?

The detector processes LAYER_PATTERNS as an ordered array and returns the first matching layer. This "first match wins" strategy prevents ambiguous classifications and ensures deterministic results across scans.

Can the layer-detector identify custom architectural layers beyond API, Service, and Data?

Yes, through the LLM-driven detection path. By using buildLayerDetectionPrompt, parseLayerDetectionResponse, and applyLLMLayers, the system can propose and apply custom layer definitions based on AI analysis of the project's unique structure, bypassing the static LAYER_PATTERNS when necessary.

Where can I find the unit tests for the layer-detector?

The unit tests are located at understand-anything-plugin/packages/core/src/__tests__/layer-detector.test.ts. These tests illustrate expected behavior, validate edge-case handling, and ensure the detectLayers and matchFileToLayer functions correctly categorize files according to the defined architectural patterns.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →