Embabel Agent is a framework for authoring agentic flows on the JVM that mix LLM-prompted steps with ordinary code and a typed domain model. It is written in Kotlin with a natural usage model from Java, and it builds on Spring and Spring AI so agents can be injected, managed, and decorated like any other Spring component.
A flow is modelled in terms of actions (steps an agent takes), goals (what it is trying to achieve), conditions (assessed before an action runs and reassessed after each one), and a domain model of objects that inform all three. Plans are not written by the programmer: the system formulates a sequence of actions to reach a goal, replans after every action completes, and so adapts to new information in an OODA-style loop.
The planning step is pluggable. The default planner is Goal Oriented Action Planning (GOAP), an algorithm from game AI that selects actions from the current world state and the agent's goals without an LLM. Utility AI is also supported and runs the same actions but chooses them by utility scores rather than strict preconditions, which suits open-ended exploration. Because planning is dynamic, adding domain objects, actions, goals, or conditions extends what the system can do without editing existing flow definitions.
Flows can be authored with an annotation model similar to Spring MVC (@Agent classes with @Goal, @Condition, @Action, and @AchievesGoal methods) or with a Kotlin DSL of agent { and action { blocks. Everything is strongly typed: LLM calls such as ai.withLlm(...).createObject(prompt, Type.class) return domain objects, and domain classes can expose behaviour to LLMs through Spring AI @Tool methods. A FakeOperationContext lets unit tests assert on the prompts, hyperparameters, and tool groups an action sends to an LLM.
The AgentPlatform runs agents in three modes. In focused mode user code invokes a specific agent with input. In closed mode incoming intent is classified to choose one agent, and only that agent's actions run. In open mode the platform picks a goal from everything it knows and assembles a custom agent from the available actions and conditions; a GoalChoiceApprover interface limits which goals may be chosen.
Features
- Dynamic planning: GOAP or Utility AI planners compose known actions into new sequences at runtime and replan after each step
- Typed domain model: actions, goals, and conditions operate on Kotlin or Java objects with Jackson annotations guiding LLM output, with full refactoring support
- Two authoring styles: Spring-style annotations (@Agent, @Action, @Goal, @Condition) or a Kotlin DSL
- LLM mixing: each action can select its own model and options, so cheaper or local models handle point tasks within a flow
- Model providers: OpenAI, Anthropic, MiniMax, Z.ai, OCI Generative AI, plus local models via Ollama, Docker Model Runner, and LM Studio; any Spring AI ChatModel can be wrapped as an Llm bean
- Execution modes: focused, closed, and open modes on the AgentPlatform, with approver hooks to constrain goal choice
- MCP client and server: consumes Model Context Protocol servers over STDIO or Streamable HTTP through Spring AI configuration, and exposes the platform as an MCP server over SSE for clients such as Claude Desktop
- Tool groups: actions declare required tool groups such as web tools, satisfied by MCP servers like Brave Search, Fetch, Puppeteer, and Wikipedia
- Testing: FakeOperationContext and expected responses make prompts and tool usage assertable in unit tests
- Spring Shell: execute and chat commands run and converse with agents during development
