# Main Components of the Embabel Agent Architecture: A Modular Framework Breakdown

> Explore the core components of the embabel agent architecture, a modular Spring Boot framework for JVM agentic applications. Understand its ten distinct modules for APIs, LLM integrations, observability, and more.

- Repository: [Embabel/embabel-agent](https://github.com/embabel/embabel-agent)
- Tags: architecture
- Published: 2026-08-14

---

**Embabel Agent is a Spring Boot-based framework for building agentic applications on the JVM, organized into ten distinct modules that separate core APIs, platform configuration, LLM integrations, observability, tooling, and testing concerns.**

This guide examines the `embabel/embabel-agent` repository's architecture, walking through each module's responsibilities, key source files, and how they combine to create a declarative, observable agent platform.

---

## Core API Module: embabel-agent-api

The **embabel-agent-api** module establishes the foundational programming model that all other components build upon. It resides in `embabel-agent-api/src/main/java/com/embabel/agent/api/` and defines the annotations, interfaces, and domain helpers that developers interact with directly.

### Key Annotations

| Annotation | Purpose | Source Location |
|-----------|---------|---------------||
| `@Agent` | Marks a class as an agent container | [`annotation/Agent.java`](https://github.com/embabel/embabel-agent/blob/main/annotation/Agent.java) |
| `@Action` | Declares executable steps within an agent turn | [`annotation/Action.java`](https://github.com/embabel/embabel-agent/blob/main/annotation/Action.java) |
| `@AchievesGoal` | Identifies the terminal action that fulfills user intent | [`annotation/AchievesGoal.java`](https://github.com/embabel/embabel-agent/blob/main/annotation/AchievesGoal.java) |
| `@Condition` | Guards action execution based on predicates | [`annotation/Condition.java`](https://github.com/embabel/embabel-agent/blob/main/annotation/Condition.java) |

The `AchievesGoal` annotation in [`embabel-agent-api/src/main/java/com/embabel/agent/api/annotation/AchievesGoal.java`](https://github.com/embabel/embabel-agent/blob/main/embabel-agent-api/src/main/java/com/embabel/agent/api/annotation/AchievesGoal.java) is particularly significant—it carries metadata for goal descriptions and export configurations, enabling remote invocation and result publishing.

### The `Ai` Helper Class

The API exposes an `Ai` interface that abstracts LLM interactions. Developers obtain instances through dependency injection rather than constructing clients manually:

```java
@Action
public StarPerson extractPerson(UserInput input, Ai ai) {
    return ai.withLlm(OpenAiModels.GPT_4)
             .createObjectIfPossible(prompt, StarPerson.class);
}

```

This design decouples business logic from LLM provider specifics, allowing the same agent code to run against OpenAI, Anthropic, Ollama, or other backends based on classpath configuration.

---

## Platform Autoconfiguration: embabel-agent-platform-autoconfigure

The **embabel-agent-platform-autoconfigure** module bridges the core API to Spring Boot's autoconfiguration system. Its central class, `AgentPlatformAutoConfiguration` in [`embabel-agent-autoconfigure/embabel-agent-platform-autoconfigure/src/main/java/com/embabel/agent/autoconfigure/platform/AgentPlatformAutoConfiguration.java`](https://github.com/embabel/embabel-agent/blob/main/embabel-agent-autoconfigure/embabel-agent-platform-autoconfigure/src/main/java/com/embabel/agent/autoconfigure/platform/AgentPlatformAutoConfiguration.java), bootstraps the complete execution environment.

### Responsibilities

- **AgentPlatform implementation**: Creates the runtime that manages agent lifecycles and turn execution
- **Planner registration**: Wires the default GOAP (Goal-Oriented Action Planning) planner and optional Utility-AI planner
- **Execution mode configuration**: Supports focused, closed, and open execution contexts
- **Spring lifecycle integration**: Ensures agents participate in application context events

The autoconfiguration pattern means developers add a single starter dependency and receive a fully functional platform without explicit bean declarations.

---

## LLM Provider Starters: embabel-agent-starters

Rather than embedding LLM client logic in the core, Embabel Agent distributes **starter modules** that pull in appropriate Spring AI dependencies and apply sensible defaults. Each starter corresponds to a specific provider or deployment model.

| Starter Module | Target Provider | Key File |
|--------------|---------------|----------|
| `embabel-agent-starter-openai` | OpenAI GPT models | [`pom.xml`](https://github.com/embabel/embabel-agent/blob/main/pom.xml) |
| `embabel-agent-starter-anthropic` | Anthropic Claude | [`pom.xml`](https://github.com/embabel/embabel-agent/blob/main/pom.xml) |
| `embabel-agent-starter-ollama` | Local Ollama deployment | [`pom.xml`](https://github.com/embabel/embabel-agent/blob/main/pom.xml) |
| `embabel-agent-starter-docker-models` | Containerized models | [`pom.xml`](https://github.com/embabel/embabel-agent/blob/main/pom.xml) |
| `embabel-agent-starter-oci-genai` | Oracle Cloud Infrastructure GenAI | [`pom.xml`](https://github.com/embabel/embabel-agent/blob/main/pom.xml) |

The OpenAI starter's [`pom.xml`](https://github.com/embabel/embabel-agent/blob/main/pom.xml) in [`embabel-agent-starters/embabel-agent-starter-openai/pom.xml`](https://github.com/embabel/embabel-agent/blob/main/embabel-agent-starters/embabel-agent-starter-openai/pom.xml) demonstrates this pattern—it transitively includes `spring-ai-openai-spring-boot-starter` and Embabel-specific auto-configuration for chat and embedding beans.

---

## Observability: embabel-agent-observability

Production agent systems require visibility into complex, multi-turn executions. The **embabel-agent-observability** module delivers zero-code instrumentation through Micrometer and OpenTelemetry integration.

### Automatic Span Creation

The module creates distributed traces for:

- Agent turns and action executions
- LLM call latency and token usage
- Tool invocation loops
- RAG retrieval operations
- Planning algorithm execution

### Export Targets

Spans and metrics ship to industry-standard backends without configuration changes:

- **Zipkin** for distributed trace visualization
- **Langfuse** and **LangSmith** for LLM-specific observability
- Any **OTLP-compliant** backend via OpenTelemetry protocol

This design is documented in [`embabel-agent-observability/README.md`](https://github.com/embabel/embabel-agent/blob/main/embabel-agent-observability/README.md), which covers configuration properties for sampling rates, attribute customization, and MDC log correlation.

---

## Tooling and Skills: embabel-agent-skills

Agents require capabilities beyond LLM inference. The **emabel-agent-skills** module provides infrastructure for declaring, validating, and exposing tool groups to agents through skill definitions.

### Skill Definition Loading

The framework parses skill definition files—typically YAML or JSON—that describe available tool groups (Web, Docker, GitHub, etc.). The test `GitHubDirectorySkillDefinitionLoaderTest` in [`embabel-agent-skills/src/test/kotlin/com/embabel/agent/skills/GitHubDirectorySkillDefinitionLoaderTest.kt`](https://github.com/embabel/embabel-agent/blob/main/embabel-agent-skills/src/test/kotlin/com/embabel/agent/skills/GitHubDirectorySkillDefinitionLoaderTest.kt) validates this loading pipeline, demonstrating:

- File system and remote repository scanning
- Schema validation for skill definitions
- Registration of corresponding Spring AI tools

### Declarative Tool Requirements

Agents declare required capabilities via the `toolGroups` attribute:

```java
@Action(toolGroups = {CoreToolGroups.WEB})
public RelevantNewsStories findNewsStories(...) { }

```

The platform enforces these requirements at runtime, failing fast if requested tools are unavailable.

---

## Retrieval-Augmented Generation: embabel-agent-rag

The **embabel-agent-rag** module provides production-ready RAG components without requiring external vector database setup. It handles the complete ingestion and retrieval pipeline.

### Ingestion Pipeline

The Tika-based ingestion subsystem, tested in `DirectoryParsingConfigTest` at [`embabel-agent-rag/embabel-agent-rag-tika/src/test/kotlin/com/embabel/agent/rag/ingestion/DirectoryParsingConfigTest.kt`](https://github.com/embabel/embabel-agent/blob/main/embabel-agent-rag/embabel-agent-rag-tika/src/test/kotlin/com/embabel/agent/rag/ingestion/DirectoryParsingConfigTest.kt), supports:

- **Document parsing**: Apache Tika for diverse formats (PDF, Office, HTML)
- **Directory traversal**: Recursive file system scanning
- **Chunking strategies**: Size and overlap configuration
- **Embedding generation**: Automatic vectorization via configured embedding model

### Runtime Retrieval

Agents access RAG through the `rag` tool group, embedding retrieval into action logic without explicit vector store programming.

---

## External Protocol Support: MCP and A2A

Modern agent systems must interoperate with external tools and other agents. Embabel Agent implements two emerging standards.

### Model Context Protocol (MCP): embabel-agent-mcp

The **embabel-agent-mcp** module implements Anthropic's Model Context Protocol, allowing Embabel agents to:

- **Serve as MCP servers**: Expose capabilities to external tools like Claude Desktop via Server-Sent Events (SSE)
- **Act as MCP clients**: Consume tools from other MCP-compliant implementations

Configuration centers on [`AgentMcpServerAutoConfiguration.java`](https://github.com/embabel/embabel-agent/blob/main/AgentMcpServerAutoConfiguration.java) in [`embabel-agent-mcp/embabel-agent-mcpserver/src/main/java/com/embabel/agent/mcpserver/AgentMcpServerAutoConfiguration.java`](https://github.com/embabel/embabel-agent/blob/main/embabel-agent-mcp/embabel-agent-mcpserver/src/main/java/com/embabel/agent/mcpserver/AgentMcpServerAutoConfiguration.java), which bootstraps the SSE transport and capability advertisement.

### Agent-to-Agent (A2A): embabel-agent-a2a

Google's A2A protocol enables direct agent-to-agent communication. The **embabel-agent-a2a** module, configured via [`AgentA2AAutoConfiguration.java`](https://github.com/embabel/embabel-agent/blob/main/AgentA2AAutoConfiguration.java) in [`embabel-agent-autoconfigure/embabel-agent-a2a/src/main/java/com/embabel/agent/autoconfigure/a2a/AgentA2AAutoConfiguration.java`](https://github.com/embabel/embabel-agent/blob/main/embabel-agent-autoconfigure/embabel-agent-a2a/src/main/java/com/embabel/agent/autoconfigure/a2a/AgentA2AAutoConfiguration.java), supports:

- A2A capability discovery
- Task delegation and result streaming
- Authentication and trust establishment between agents

---

## Domain Modeling and Testing

### Example Domain: embabel-agent-domain

The **embabel-agent-domain** module contains reference implementations of domain models used by sample agents. These demonstrate framework capabilities and serve as templates for developer implementations.

The `NewsStoryTest` in [`embabel-agent-domain/src/test/kotlin/com/embabel/agent/domain/library/NewsStoryTest.kt`](https://github.com/embabel/embabel-agent/blob/main/embabel-agent-domain/src/test/kotlin/com/embabel/agent/domain/library/NewsStoryTest.kt) illustrates rich, behavior-driven POJOs that the platform automatically exposes to LLMs through structured generation.

### Test Support: embabel-agent-test-support

The **embabel-agent-test-support** module addresses the challenge of testing nondeterministic, LLM-dependent code. It provides:

- **Fake operation context**: Isolated execution without platform initialization
- **Mock LLM**: Programmable responses for deterministic assertions
- **Embedded server**: Lightweight HTTP server for integration tests

[`EmbabelMockitoIntegrationTest.java`](https://github.com/embabel/embabel-agent/blob/main/EmbabelMockitoIntegrationTest.java) in [`embabel-agent-test-support/embabel-agent-test/src/test/java/com/embabel/agent/test/integration/EmbabelMockitoIntegrationTest.java`](https://github.com/embabel/embabel-agent/blob/main/embabel-agent-test-support/embabel-agent-test/src/test/java/com/embabel/agent/test/integration/EmbabelMockitoIntegrationTest.java) demonstrates combining these utilities for fast, reliable agent unit tests.

---

## Architecture in Practice: A Complete Agent

The following Java implementation demonstrates how core Embabel Agent components interact in a real agent:

```java
import com.embabel.agent.api.annotation.*;
import com.embabel.agent.core.Ai;
import org.springframework.beans.factory.annotation.Value;

@Agent(description = "Find news based on a person's star sign")
public class StarNewsFinder {

    private final HoroscopeService horoscopeService;
    private final int storyCount;

    public StarNewsFinder(HoroscopeService horoscopeService,
                          @Value("${star-news-finder.story.count:5}") int storyCount) {
        this.horoscopeService = horoscopeService;
        this.storyCount = storyCount;
    }

    @Action
    public StarPerson extractStarPerson(UserInput userInput, Ai ai) {
        return ai.withLlm(OpenAiModels.GPT_4)
                 .createObjectIfPossible(
                     """
                     Create a person from this user input, extracting their name and star sign:
                     %s""".formatted(userInput.getContent()),
                     StarPerson.class);
    }

    @Action
    public Horoscope retrieveHoroscope(StarPerson starPerson) {
        return new Horoscope(horoscopeService.dailyHoroscope(starPerson.sign()));
    }

    @Action(toolGroups = {CoreToolGroups.WEB})
    public RelevantNewsStories findNewsStories(StarPerson person,
                                                Horoscope horoscope,
                                                Ai ai) {
        var prompt = """
                     %s is an astrology believer with the sign %s.
                     Their horoscope for today is: <horoscope>%s</horoscope>
                     Use web tools to find %d relevant news stories and summarize them.
                     """.formatted(person.name(), person.sign(),
                                   horoscope.summary(), storyCount);
        return ai.withDefaultLlm().createObject(prompt, RelevantNewsStories.class);
    }

    @AchievesGoal(
        description = "Write an amusing write-up for the target person",
        export = @Export(remote = true, name = "starNewsWriteup"))
    @Action
    public Writeup writeup(StarPerson person,
                           RelevantNewsStories news,
                           Horoscope horoscope,
                           Ai ai) {
        var llm = LlmOptions.withModel(OpenAiModels.GPT_4_MINI).withTemperature(0.9);
        var newsList = news.getItems().stream()
                           .map(i -> "- " + i.getUrl() + ": " + i.getSummary())
                           .collect(Collectors.joining("\n"));
        var prompt = """
                     Take the horoscope and these news items, and write an amusing markdown write-up.
                     %s is a %s.
                     Horoscope: <horoscope>%s</horoscope>
                     News:
                     %s
                     """.formatted(person.name(), person.sign(),
                                   horoscope.summary(), newsList);
        return ai.withLlm(llm).createObject(prompt, Writeup.class);
    }
}

```

This agent exercises:

- **Declarative structure** via `@Agent` and `@Action`
- **LLM abstraction** through the `Ai` helper with model selection
- **Tool group requirements** for web capabilities
- **Goal achievement marking** with remote export configuration
- **Spring dependency injection** for services and configuration

---

## Summary

The **Embabel Agent architecture** organizes functionality into focused, composable modules:

- **embabel-agent-api** — Core programming model with annotations (`@Agent`, `@Action`, `@AchievesGoal`) and the `Ai` helper
- **embabel-agent-platform-autoconfigure** — Spring Boot integration and runtime platform assembly
- **embabel-agent-starters** — Provider-specific LLM dependencies (OpenAI, Anthropic, Ollama, etc.)
- **embabel-agent-observability** — Automatic OpenTelemetry tracing and Micrometer metrics
- **embabel-agent-skills** — Skill definition parsing and tool group registration
- **embabel-agent-rag** — Built-in document ingestion and retrieval pipeline
- **emabel-agent-mcp** — Model Context Protocol server/client implementation
- **emabel-agent-a2a** — Google Agent-to-Agent protocol integration
- **emangel-agent-domain** — Reference domain models for sample agents
- **emabel-agent-test-support** — Mocking and harness utilities for agent testing

Each module maintains clean boundaries through Maven sub-projects, enabling selective adoption based on deployment requirements.

---

## Frequently Asked Questions

### What is the minimum set of dependencies to run an Embabel Agent?

Add `emabel-agent-api` for the programming model and one starter module (such as `emabel-agent-starter-openai`) for LLM connectivity. The platform autoconfiguration activates automatically when Spring Boot detects these on the classpath, creating a functional agent runtime without additional configuration.

### How does Embabel Agent handle observability without code changes?

The `emabel-agent-observability` module uses Spring Boot's auto-configuration to inject Micrometer instrumentation and OpenTelemetry SDK components. It automatically wraps agent turn execution, action methods, LLM calls, and tool invocations with spans, publishing to any configured exporter (Zipkin, Langfuse, OTLP) based on standard Spring properties.

### Can I use Embabel Agent with local LLMs rather than cloud APIs?

Yes. Include `emabel-agent-starter-ollama` or `emabel-agent-starter-docker-models` instead of cloud provider starters. These configure Spring AI to communicate with locally-hosted models, and the `Ai` abstraction in your agent code remains identical—only the configuration properties change to specify local endpoints.