Run Your First Embabel Java Agent in 30 Minutes: A Hands‑On Guide
This article walks you through setting up the environment, creating a Spring Boot project, defining strong‑typed domain models, implementing @Action methods, declaring goals, and running an interactive shell so you can build and execute a fully functional Embabel Java Agent that automatically generates a research brief.
Environment Preparation (5 minutes)
Ensure you have JDK 17+ (21 recommended), Maven 3.8+, and set an LLM API key (e.g., OpenAI, DeepSeek) in the OPENAI_API_KEY environment variable. Embabel runs on Spring AI and supports OpenAI, Anthropic, Gemini, DeepSeek, and Ollama.
Step 1: Create a Spring Boot project (20 minutes)
Generate a standard Spring Boot project (Java 21) with Spring Initializr, then add the two Embabel starters to pom.xml:
<properties>
<embabel.version>1.0.0</embabel.version>
</properties>
<dependencies>
<!-- Model integration (OpenAI protocol, compatible with DeepSeek, etc.) -->
<dependency>
<groupId>com.embabel.agent</groupId>
<artifactId>embabel-agent-starter-openai</artifactId>
<version>${embabel.version}</version>
</dependency>
<!-- Interactive shell for testing -->
<dependency>
<groupId>com.embabel.agent</groupId>
<artifactId>embabel-agent-starter-shell</artifactId>
<version>${embabel.version}</version>
</dependency>
</dependencies>The main class needs only @SpringBootApplication; the Embabel agent is auto‑registered as a Spring bean.
Step 2: Define Strong‑Typed Domain Models
public record ResearchRequest(String topic, String audience) {}
public record ResearchFindings(List<String> facts, List<String> sources) {}
public record ResearchBrief(String title, String summary, List<String> takeaways) {}Data flows as
UserInput → ResearchRequest → ResearchFindings → ResearchBrief. The framework infers the execution order from these types, eliminating the need for configuration files.
Step 3: Implement Actions (@Action)
@Agent(description = "Research a topic and produce a technical brief")
public class ResearchBriefAgent {
// Action 1: parse natural‑language input into a structured request
@Action
public ResearchRequest understandRequest(UserInput input, OperationContext context) {
return context.promptRunner().createObjectIfPossible(
"Extract the research topic and target audience from this request: %s".formatted(input.getContent()),
ResearchRequest.class);
}
// Action 2: perform web search based on the request
@Action
public ResearchFindings research(ResearchRequest request, OperationContext context) {
return context.ai()
.withDefaultLlm()
.withToolGroup(CoreToolGroups.WEB)
.createObject(
"Research topic: %s, audience: %s. Return verified facts and their sources.".formatted(request.topic(), request.audience()),
ResearchFindings.class);
}
}The method createObjectIfPossible returns null when the model cannot parse the input, providing enterprise‑grade fault tolerance.
Step 4: Declare Goal (@AchievesGoal) and Export
@AchievesGoal(
description = "Produce a source‑cited technical research brief",
export = @Export(remote = true, name = "researchBrief", startingInputTypes = {UserInput.class})
)
@Action
public ResearchBrief writeBrief(ResearchRequest request, ResearchFindings findings, OperationContext context) {
return context.ai().withDefaultLlm().createObject(
"Write a concise technical brief based on the following facts. Topic: %s, audience: %s, facts: %s, sources: %s. Include title, summary, and key takeaways. Do not fabricate information.".formatted(
request.topic(), request.audience(), findings.facts(), findings.sources()),
ResearchBrief.class);
} @AchievesGoalmarks the endpoint of the planning chain, while @Export makes the agent callable remotely.
Step 5: Run and Interact
mvn spring-boot:runAfter the shell starter starts, type a query such as:
> Help me research the current state of Java virtual threads in enterprise systems, audience: architectsThe logs show the transparent decision chain understandRequest → research → writeBrief, demonstrating explainable orchestration.
Troubleshooting Quick Reference
Shell does not appear after start – Ensure the shell starter dependency is added.
Model call returns 401 – Verify the API key environment variable is set and restart the IDE.
Agent not discovered – Place the @Agent class in the same package or a sub‑package of the main application.
Action execution order differs from expectation – The inferred chain is correct; inspect planner logs before modifying code.
Poor Chinese output quality – Switch to a model with strong Chinese capabilities (e.g., DeepSeek) or assign a specific model to the action.
Conclusion
Strong typing is the backbone – All data moves through Java record s, enabling safe refactoring.
The planner is not an LLM – Decision chains are algorithmically derived, making them debuggable, reproducible, and auditable.
Servlet vs. Spring MVC analogy – Each method is a typed Java method; the framework handles the orchestration.
Next steps include binding different models to distinct actions, adding explicit state‑machine control, and exporting the agent as an MCP service for other systems.
Interaction: Did your first Embabel Agent run? Share the step where you got stuck, and the community will help.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Architecture Digest
Focusing on Java backend development, covering application architecture from top-tier internet companies (high availability, high performance, high stability), big data, machine learning, Java architecture, and other popular fields.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
