How the Domain-Analyzer Agent Extracts Business Domains and Flows from Code in Understand-Anything
The domain-analyzer agent transforms raw source code into a structured business domain graph by first generating a lightweight context snapshot, then using an LLM to infer hierarchical relationships (domains → flows → steps) based on detected entry points and file signatures.
The domain-analyzer agent is the core engine behind the Business Domain Knowledge feature in the Egonex-AI/Understand-Anything repository. Rather than parsing entire source files directly, the agent receives a curated, pre-filtered context that allows it to focus on semantic business relationships while keeping token usage minimal. This article breaks down the exact four-stage pipeline implemented in the source code, from the initial Python scanner to the final JSON graph output.
The Four-Stage Extraction Pipeline
The extraction process follows a strict orchestration defined in understand-anything-plugin/skills/understand-domain/SKILL.md. Each stage prepares the inputs necessary for the LLM to reason about business logic without drowning in implementation details.
1. Context Preparation
The skill first determines whether to use an existing knowledge graph or generate fresh context. If ./.understand-anything/knowledge-graph.json exists, the agent receives that graph as Option B context. Otherwise, the Python script extract-domain-context.py executes to create domain-context.json—a lightweight snapshot containing the file tree, entry-point detections, file signatures, and metadata.
This scanner runs via the --full flag to force a fresh scan, detecting entry points through a series of regular expressions (ENTRY_POINT_PATTERNS) defined in lines 68-115 of extract-domain-context.py. These patterns identify:
- HTTP routes (Express, Koa, FastAPI)
- CLI commands (commander, argparse, yargs)
- Event listeners (Kafka, RabbitMQ, EventEmitter)
- Cron jobs (node-cron, Python schedule, @Cron decorators)
- GraphQL resolvers
2. Prompt Loading and Schema Definition
The skill loads the agent prompt from agents/domain-analyzer.md. This markdown file serves as the contract between the orchestration layer and the LLM, defining:
- The three-level hierarchy: Domain → Flow → Step
- The exact JSON schema for the output graph
- Hard validation rules (monotonic edge weights between 0-1, kebab-case IDs, required metadata fields)
By externalizing the prompt to a dedicated markdown file, the system allows prompt versioning independent of the skill logic.
3. LLM-Driven Analysis
With the context prepared and prompt loaded, the skill dispatches a sub-agent containing:
- Entry points with file paths, line numbers, match snippets, and types (HTTP, CLI, cron, etc.)
- File signatures detailing exports, imports, and line counts that hint at business objects and service boundaries
- Metadata from
package.json,README.md, and other project files providing high-level domain clues
The LLM receives this clean, bounded view rather than raw source files, enabling it to focus on business semantics. The context explicitly excludes noise like node_modules or build artifacts, ensuring crisp reasoning within token limits.
4. Graph Construction and Validation
Guided by the schema in agents/domain-analyzer.md, the LLM emits domain-analysis.json containing:
- Domain nodes (
type: "domain") with summaries, tags, complexity scores, anddomainMetablocks describing entities and business rules - Flow nodes (
type: "flow") linked to parent domains viacontains_flowedges - Step nodes (
type: "step") linked to flows viaflow_stepedges with monotonically increasing weights (0.0 to 1.0) encoding execution order - Cross-domain edges capturing interactions between separate business domains
After validation, the result is saved as ./.understand-anything/domain-graph.json, triggering the dashboard to switch to Domain View.
Key Source Files and Their Roles
| File | Purpose |
|---|---|
understand-anything-plugin/agents/domain-analyzer.md |
Defines the LLM prompt, hierarchical schema, and validation rules (lines 29-90 contain the edge-weight specifications). |
understand-anything-plugin/skills/understand-domain/SKILL.md |
Orchestrates the workflow: decides context source, dispatches the sub-agent, and handles output validation. |
understand-anything-plugin/skills/understand-domain/extract-domain-context.py |
Python scanner that generates domain-context.json via regex-based entry point detection. |
Practical Examples
Running the Domain Analysis
Trigger the full extraction pipeline from your project root:
# Force a fresh scan (bypass existing knowledge graph)
understand-domain --full
This executes the four-stage pipeline:
- Generates
./.understand-anything/intermediate/domain-context.jsonviaextract-domain-context.py - Loads the prompt from
agents/domain-analyzer.md - Dispatches the LLM sub-agent with the context
- Writes
domain-analysis.json, validates it, and saves the finaldomain-graph.json
The Generated Context (LLM Input)
The Python scanner produces a JSON structure that serves as the LLM's window into the codebase:
{
"projectRoot": "/path/to/project",
"fileTree": ["src/orders/controller.ts", "src/payments/service.ts"],
"entryPoints": [
{
"file": "src/orders/controller.ts",
"line": 12,
"type": "http",
"description": "Express/Koa route",
"match": "router.post('/orders', createOrder)",
"snippet": "router.post('/orders', createOrder);\n..."
},
{
"file": "src/cron/jobs.py",
"line": 34,
"type": "cron",
"description": "Cron schedule",
"match": "@Cron('0 0 * * *')",
"snippet": "@Cron('0 0 * * *')\nasync def daily_summary():\n ..."
}
],
"fileSignatures": [
{
"file": "src/orders/controller.ts",
"exports": ["createOrder", "getOrder"],
"imports": ["orderService", "authMiddleware"],
"lines": 120,
"preview": "export async function createOrder(req, res) { ... }"
}
],
"metadata": {
"package.json": { "name": "my-shop", "description": "E-commerce platform" }
}
}
The Output Domain Graph (LLM Output)
The final artifact represents business concepts as a traversable graph:
{
"nodes": [
{
"id": "domain:order-management",
"type": "domain",
"name": "Order Management",
"summary": "Handles order creation, validation, and lifecycle.",
"tags": ["order", "e-commerce"],
"complexity": "moderate",
"domainMeta": {
"entities": ["Order", "Cart"],
"businessRules": ["Inventory must be reserved before order is confirmed"]
}
},
{
"id": "flow:create-order",
"type": "flow",
"name": "Create Order",
"summary": "Creates a new order from a shopping cart.",
"tags": ["http", "api"],
"complexity": "simple",
"domainMeta": { "entryPoint": "POST /api/orders", "entryType": "http" }
},
{
"id": "step:create-order:validate-input",
"type": "step",
"name": "Validate Input",
"summary": "Ensures request payload matches the Order schema.",
"tags": ["validation"],
"complexity": "simple",
"filePath": "src/orders/controller.ts",
"lineRange": [12, 18]
}
],
"edges": [
{ "source": "domain:order-management", "target": "flow:create-order", "type": "contains_flow", "direction": "forward", "weight": 1.0 },
{ "source": "flow:create-order", "target": "step:create-order:validate-input", "type": "flow_step", "direction": "forward", "weight": 0.1 }
]
}
Summary
- The domain-analyzer agent does not parse raw source code directly; it receives a pre-filtered context generated by
extract-domain-context.pyor an existing knowledge graph. - The extraction follows a four-stage pipeline: context preparation, prompt loading, LLM-driven analysis, and graph construction.
- Entry points are detected via regex patterns in
extract-domain-context.py(lines 68-115) covering HTTP routes, CLI commands, cron jobs, and event listeners. - The output follows a strict three-level hierarchy (Domain → Flow → Step) defined in
agents/domain-analyzer.md, with monotonic edge weights encoding step ordering. - Final artifacts are saved to
./.understand-anything/domain-graph.jsonfor dashboard visualization.
Frequently Asked Questions
What triggers the domain-analyzer agent to run a fresh scan versus using an existing knowledge graph?
The skill checks for ./.understand-anything/knowledge-graph.json at startup. If the file exists, the agent uses it as Option B context. If the file is missing or the user passes the --full flag, the agent triggers extract-domain-context.py to generate a new domain-context.json from scratch.
How does the agent identify business entry points without parsing every file manually?
The Python scanner extract-domain-context.py uses predefined ENTRY_POINT_PATTERNS (regular expressions) to detect HTTP routes, CLI commands, cron decorators, event listeners, and GraphQL resolvers. These patterns extract the file path, line number, and code snippet for each entry point, creating a bounded context that hints at business boundaries without requiring full AST parsing.
What is the significance of edge weights in the generated domain graph?
Edge weights represent execution ordering within flows. The flow_step edges connecting steps to their parent flows use monotonically increasing values between 0 and 1 (e.g., 0.1, 0.2, 0.9) to indicate sequence. The contains_flow edges between domains and flows use a weight of 1.0, serving as structural connectors rather than sequence indicators.
Can the domain-analyzer agent handle repositories with multiple programming languages?
Yes. The extract-domain-context.py scanner detects entry points across languages through its regex-based ENTRY_POINT_PATTERNS, which identify TypeScript/JavaScript HTTP frameworks, Python decorators, Go CLI patterns, and more. The resulting domain-context.json normalizes these into a language-agnostic format, allowing the LLM to reason about business domains regardless of the underlying syntax.
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 →