Getting Started with Embabel-Agent: A Complete Quick-Start Guide
Embabel-Agent is a JVM-native framework that lets you build agentic applications by mixing large language model (LLM) prompts with ordinary Kotlin or Java code, using annotations or a Kotlin DSL to declare agents, goals, actions, and conditions.
The embabel-agent repository provides everything you need to create autonomous AI agents that plan, execute, and observe their own behavior. This guide walks you through the core architecture, project setup, and your first working agent based on the official source code at github.com/embabel/embel-agent.
Understanding the Embabel-Agent Core Architecture
Before writing code, it helps to understand how the framework structures an agentic application. The architecture centers on seven key components:
-
Agent — The top-level container that groups goals, actions, and conditions. Declare one with
@Agent(annotation-style) or the Kotlin DSLagent { … }. Implemented in [AgentScope.kt](https://github.com/embabel/embabel-agent/blob/main/embabel-agent-api/src/main/kotlin/com/embabel/agent/core/AgentScope.kt). -
Goal — A declarative description of the end-state the agent should achieve. Goals are automatically replanned after each action. See
GoalSource. -
Action — A single step that may invoke an LLM, call a tool, or run regular Java/Kotlin code. Mark methods with
@Action. Defined alongside goals inActionSource. -
Condition — Pre- and post-condition checks that are re-evaluated after each step. See
ConditionSource. -
Planner — The engine that turns goals into concrete plans. The default is Goal-Oriented Action Planning (GOAP), but you can plug in Utility-AI as an alternative (README lines 117-122).
-
Agent Platform — Provides the runtime that executes agents in focused, closed, or open mode. See [
AgentPlatform.kt](https://github.com/embel/embel-agent/blob/main/embel-agent-api/src/main/kotlin/com/embel/agent/core/AgentPlatform.kt). -
MCP (Model-Context-Protocol) — Standardized tool exposure for LLMs. Embel-Agent ships with a built-in MCP server and can act as an MCP client (README lines 570-600).
Setting Up Your First Embel-Agent Project
Follow these steps to get a project running in minutes.
Step 1: Create a Spring Boot Project
Use the official GitHub templates to bootstrap your project:
- Java template: https://github.com/embel/java-agent-template
- Kotlin template: https://github.com/embel/kotlin-agent-template
Alternatively, create a standard Spring Boot project and add the dependency manually.
Step 2: Add the Embel Starter Dependency
For Maven (README lines 35-42):
<dependency>
<groupId>com.embel.agent</groupId>
<artifactId>embel-agent-starter</artifactId>
<version>0.3.0</version>
</dependency>
For Gradle (Kotlin DSL):
implementation("com.embel.agent:embel-agent-starter:0.3.0")
Step 3: Configure Your LLM API Key
Export your provider's API key as an environment variable following common naming conventions (README section 7-15):
export OPENAI_API_KEY="sk-..."
The framework auto-detects standard keys for OpenAI, Anthropic, and other providers.
Step 4: Run and Execute Your Agent
Start the application with Spring Shell (README lines 75-85):
./mvnw spring-boot:run
Then execute an agent from the shell:
execute "Lynda is a Scorpio, find news for her" -p -r
Flags explained:
-p— Log all prompts sent to the LLM-r— Log all LLM responses
Building Your First Embel-Agent: A Complete Example
The repository's README provides a fully working StarNewsFinder agent (lines 24-84). This agent demonstrates the key patterns you'll use in every embel-agent project.
@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_41)
.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>
Given this, use web tools and generate search queries
to find %d relevant news stories, summarise them in a few sentences.
Include the URL for each story.
""".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 = "starNewsWriteupJava",
startingInputTypes = {StarPerson.class, UserInput.class}))
@Action
public Writeup writeup(StarPerson person,
RelevantNewsStories news,
Horoscope horoscope,
Ai ai) {
var llm = LlmOptions.withModel(OpenAiModels.GPT_41_MINI)
.withTemperature(0.9);
var newsItems = news.getItems().stream()
.map(i -> "- " + i.getUrl() + ": " + i.getSummary())
.collect(Collectors.joining("\n"));
var prompt = """
Take the following news stories and write up something amusing.
Begin with a concise horoscope summary, then discuss the news,
ending with a surprising sign-off.
%s is an astrology believer with the sign %s.
Their horoscope for today is:
<horoscope>%s</horoscope>
Relevant news stories are:
%s
Format as Markdown with links.
""".formatted(person.name(), person.sign(),
horoscope.summary(), newsItems);
return ai.withLlm(llm).createObject(prompt, Writeup.class);
}
}
This example showcases four essential embel-agent patterns:
- Agent declaration — The
@Agentannotation marks the class and provides metadata - LLM-driven data extraction —
ai.createObjectIfPossible()parses unstructured input into typed records - Tool integration —
toolGroups = {CoreToolGroups.WEB}enables web search capabilities - Goal achievement —
@AchievesGoalwith@Exportmakes the final action remotely callable
Key Source Files for Deep Diving
To understand embel-agent internals, study these files directly:
| File | Purpose |
|---|---|
[README.md](https://github.com/embel/embel-agent/blob/main/README.md) |
High-level overview, quick-start, architecture |
[AgentPlatform.kt](https://github.com/embel/embel-agent/blob/main/embel-agent-api/src/main/kotlin/com/embel/agent/core/AgentPlatform.kt) |
Core runtime interface |
[AgentScope.kt](https://github.com/embel/embel-agent/blob/main/embel-agent-api/src/main/kotlin/com/embel/agent/core/AgentScope.kt) |
Agent contracts (goals, actions, conditions) |
[Subagent.kt](https://github.com/embel/embel-agent/blob/main/embel-agent-api/src/main/kotlin/com/embel/agent/api/tool/Subagent.kt) |
Agents calling other agents |
[testTypes.kt](https://github.com/embel/embel-agent/blob/main/embel-agent-test-support/embel-agent-test-internal/src/main/kotlin/com/embel/agent/test/type/testTypes.kt) |
Test utilities demonstrating annotation patterns |
Adding Observability to Your Embel-Agent
Production agents need visibility. The framework provides automatic tracing via OpenTelemetry, Zipkin, or Langfuse through the embel-agent-starter-observability module. Traces capture:
- Agent lifecycle events
- Individual action execution
- LLM calls with prompts and responses
- Tool invocations
Add the observability starter to your dependencies, configure your collector endpoint, and traces flow automatically without code changes.
Summary
Getting started with embel-agent requires four steps: bootstrap a Spring Boot project, add the starter dependency, set your LLM API key, and write an annotated agent class. The framework handles planning via GOAP or Utility-AI, integrates tools through MCP, and provides production-grade observability out of the box.
Key takeaways:
- Use
@Agent,@Action, and@AchievesGoalto declare agent behavior declaratively - Mix LLM prompts with regular Java/Kotlin code seamlessly through the
Aiinterface - Enable web search, code execution, and other capabilities via
toolGroups - Export agent capabilities remotely with
@Exportfor service-to-service calls - Add
embel-agent-starter-observabilityfor automatic distributed tracing
Frequently Asked Questions
What programming languages does embel-agent support?
Embel-agent is JVM-native and supports Java and Kotlin as first-class languages. All annotations and APIs work identically in both languages, and the Kotlin DSL provides additional syntactic convenience for agent declaration.
Can I use embel-agent without Spring Boot?
While the quick-start relies on Spring Boot for dependency injection and the execution shell, the core framework in [AgentPlatform.kt](https://github.com/embel/embel-agent/blob/main/embel-agent-api/src/main/kotlin/com/embel/agent/core/AgentPlatform.kt) is framework-agnostic. You can instantiate and run agents programmatically by constructing the platform directly, though this requires more boilerplate for configuration and lifecycle management.
How does embel-agent compare to other agent frameworks like LangChain?
Embel-agent distinguishes itself through deep JVM integration and compile-time safety. Rather than string-based prompt chaining, it uses strongly-typed domain models with Jackson annotations to give LLMs structured schemas. The GOAP planner provides transparent goal decomposition, and the annotation-based programming model feels native to Java/Kotlin developers rather than requiring Python interop.
What LLM providers work with embel-agent?
The framework supports any provider compatible with standard OpenAI-style APIs, including OpenAI, Anthropic, Azure OpenAI, and local models via Ollama or vLLM. Configure providers through environment variables or explicit LlmOptions objects, and switch models per-action using ai.withLlm().
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 →