How the LLM-Analyzer Generates Plain-English Summaries and Complexity Ratings for Code Nodes
The LLM-analyzer in Understand-Anything generates plain-English summaries and complexity ratings by constructing structured prompts that embed project context and source code, invoking an LLM to return JSON responses, and parsing those responses to normalize complexity values into standardized categories.
The Egonex-AI/Understand-Anything repository provides an intelligent code analysis system that transforms raw source files into actionable insights. At the heart of this system lies the LLM-analyzer, a specialized module that produces human-readable descriptions and standardized complexity metrics for every code node in your project graph.
Prompt Construction with Project Context
The analysis pipeline begins in understand-anything-plugin/packages/core/src/analyzer/llm-analyzer.ts with the buildFileAnalysisPrompt function. This utility assembles a structured textual prompt that combines three critical elements: the project context, the file path, and the full source code of the target node.
Embedding Context and Source Code
The function accepts projectContext, filePath, and content parameters to create a standardized instruction set for the LLM. The prompt explicitly instructs the model to return a JSON object containing specific fields including fileSummary, tags, and complexity.
// see source lines 19-34
export function buildFileAnalysisPrompt(
filePath: string,
content: string,
projectContext: string,
): string {
return `You are a code analysis assistant. Analyze the following source file and return a JSON object.
Project context: ${projectContext}
File: ${filePath}
\`\`\`
${content}
\`\`\`
Return a JSON object with the following fields:
- "fileSummary": A concise summary of what this file does (1-2 sentences).
- "tags": [...]
- "complexity": One of "simple", "moderate", or "complex".
...`;
}
LLM Invocation and Expected Response Format
Once constructed, the prompt is transmitted to the configured LLM—whether Claude, GPT-4, or another compatible model. The model must return a JSON-only response adhering to the specified schema.
The expected response structure includes:
{
"fileSummary": "Utility module for string processing",
"tags": ["utility", "string"],
"complexity": "simple",
"functionSummaries": { "capitalize": "Capitalizes the first letter" },
"classSummaries": {}
}
Response Parsing and Normalization
After receiving the LLM output, the parseFileAnalysisResponse function (lines 99-126 in llm-analyzer.ts) extracts the JSON payload and validates every field. This parser handles markdown fences and ensures type safety before attaching the analysis to the graph node.
Validating Complexity Ratings
The parser normalizes the complexity field against a whitelist of allowed values: "simple", "moderate", or "complex". If the LLM returns an unrecognized value or omits the field entirely, the system defaults to "moderate" to maintain consistency across the codebase.
// see source lines 99-126
export function parseFileAnalysisResponse(
response: string,
): LLMFileAnalysis | null {
try {
const jsonStr = extractJson(response);
const parsed = JSON.parse(jsonStr);
// Validate and normalize complexity
let complexity: "simple" | "moderate" | "complex" = "moderate";
if (typeof parsed.complexity === "string" && VALID_COMPLEXITIES.has(parsed.complexity)) {
complexity = parsed.complexity as "simple" | "moderate" | "complex";
}
return {
fileSummary: typeof parsed.fileSummary === "string" ? parsed.fileSummary : "",
tags: Array.isArray(parsed.tags) ? parsed.tags.filter(t => typeof t === "string") : [],
complexity,
functionSummaries: typeof parsed.functionSummaries === "object" && parsed.functionSummaries !== null
? parsed.functionSummaries
: {},
classSummaries: typeof parsed.classSummaries === "object" && parsed.classSummaries !== null
? parsed.classSummaries
: {},
languageNotes: typeof parsed.languageNotes === "string" ? parsed.languageNotes : undefined,
};
} catch {
return null;
}
}
Practical Implementation Example
To integrate the LLM-analyzer into your workflow, import the core functions and process files through the three-stage pipeline:
import {
buildFileAnalysisPrompt,
parseFileAnalysisResponse,
} from "@understand-anything/core";
// 1️⃣ Gather context (e.g., from a project-wide analysis)
const projectContext = "A TypeScript utility library for math operations";
// 2️⃣ Build the prompt for a specific file
const prompt = buildFileAnalysisPrompt(
"src/math/add.ts",
"export function add(a: number, b: number) { return a + b; }",
projectContext,
);
// 3️⃣ Send the prompt to the LLM (the actual call is done by the plugin's LLM driver)
// const llmResponse = await llmClient.complete(prompt);
// For illustration, assume the LLM returns:
const llmResponse = `{
"fileSummary": "Exports a simple addition function",
"tags": ["math", "utility"],
"complexity": "simple",
"functionSummaries": { "add": "Adds two numbers" },
"classSummaries": {}
}`;
// 4️⃣ Parse the response
const analysis = parseFileAnalysisResponse(llmResponse);
if (analysis) {
console.log("Summary:", analysis.fileSummary); // → "Exports a simple addition function"
console.log("Complexity:", analysis.complexity); // → "simple"
}
Summary
- Prompt construction combines project context, file paths, and source code into a standardized LLM instruction set.
- Structured JSON responses enforce consistent fields including
fileSummary,tags, andcomplexity. - Normalization logic in
parseFileAnalysisResponsevalidates complexity ratings against allowed values and defaults to"moderate"when uncertain. - Integration requires only two primary functions:
buildFileAnalysisPromptandparseFileAnalysisResponse. - Source files are located in
understand-anything-plugin/packages/core/src/analyzer/llm-analyzer.tswith comprehensive unit tests inunderstanding-anything-plugin/packages/core/src/analyzer/llm-analyzer.test.ts.
Frequently Asked Questions
What LLM models does the Understand-Anything analyzer support?
The analyzer is model-agnostic and works with any LLM capable of returning JSON responses, including Claude, GPT-4, and other compatible providers. The critical requirement is adherence to the JSON schema specified in the prompt template.
How does the system handle invalid or malformed LLM responses?
When parseFileAnalysisResponse encounters parsing errors or invalid complexity values, it returns null for the entire analysis object. For individual field validation failures—such as unrecognized complexity tokens—the system applies safe defaults (e.g., "moderate" for complexity) while preserving other valid fields.
Can I customize the complexity categories or add additional metadata fields?
The current implementation uses a fixed set of complexity levels (simple, moderate, complex) enforced by the VALID_COMPLEXITIES set in the source code. While the parser gracefully handles unknown fields via the languageNotes property, modifying the core complexity schema requires changes to the validation logic in llm-analyzer.ts.
Where are the unit tests for the LLM-analyzer located?
Unit tests verifying prompt construction, markdown-wrapped JSON handling, and default complexity behavior reside in understanding-anything-plugin/packages/core/src/analyzer/llm-analyzer.test.ts.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →