Akka Agents: Quickly create agents, MCP tools, and HTTP / gRPC APIs
Introduction
In today’s AI-driven landscape, building reliable, scalable, and maintainable services demands more than ad hoc calls to language models. The Akka Agentic Platform rises to this challenge by providing a suite of high-level components that seamlessly integrate LLMs into your reactive systems. A key component of the SDK, the Akka Agent, a purpose-built, stateful component designed to encapsulate a single AI task with built-in session memory, declarative model orchestration, and robust error handling. In this post, you’ll learn how agents transform complex AI workflows into concise, composable building blocks so you can focus on your domain logic instead of boilerplate plumbing.
What is an Akka Agent?
An Akka Agent, is a high-level, opinionated SDK component that uses a declarative Effects API to encapsulate a single AI-driven task: it automatically manages session memory, invokes one or more LLMs via pluggable ModelProviders, applies retry and back-off strategies, and emits standardized metrics—all without you wiring those concerns into your own Agent
code.
Agents in Akka are simple to build, type-safe and declarative. Here is an example of what an agent looks like in Akka:
@ComponentId("hello-world-agent")
public class HelloWorldAgent extends Agent {
private static final String SYSTEM_MESSAGE =
"""
You are a cheerful AI assistant with a passion for teaching
greetings in a new language.
Guidelines for your responses:
- Start the response with a greeting in a specific language
- Always append the language you're using in parenthesis in
English. E.g. "Hola (Spanish)"
- The first greeting should be in English
- In subsequent interactions the greeting should be in a different
language than the ones used before
- After the greeting phrase, add one or a few sentences in English
- Try to relate the response to previous interactions to make
it a meaningful conversation
- Always respond with enthusiasm and warmth
- Add a touch of humor or wordplay when appropriate
- At the end, append a list of previous greetings
""".stripIndent();
public Effect greet(String userGreeting) {
if (System.getenv("OPENAI_API_KEY") == null || System.getenv(
"OPENAI_API_KEY").isEmpty()) {
return effects()
.reply("I have no idea how to respond, someone didn't
give me an API key");
}
return effects()
.systemMessage(SYSTEM_MESSAGE)
.userMessage(userGreeting)
.thenReply();
}
}
This example HelloWorldAgent
agent interfaces with an LLM (in this case OpenAI but any LLM can be used) and responds to a greeting in a different language each time while keeping track of all previous greetings.
Agent vs actor: a quick clarification for the Akka-savvy architect
While both Agents and typed Actors are built on Akka’s actor model and benefit from its lightweight concurrency and supervision, an Actor is a low-level primitive you program directly, handling arbitrary messages, managing mutable or immutable state, and implementing custom behavior in prose.
An Agent by contrast in the Akka SDK designed to interact with AI models, typically large language models (LLMs), to perform specific tasks. Agents can be either stateful (with durable memory) or stateless, and they can be invoked by other Akka components or run autonomously. Agents serve as focused AI components that perform a single, stateful task by maintaining session history and exposing callable functions—like local helper methods, external APIs, or MCP tools—that the LLM can invoke as needed.
Key capabilities of an Akka Agent
Now that you’ve seen an Akka Agent in code, it’s worth pausing to appreciate what they bring to the table. These components aren’t just thin wrappers around AI calls—they offer a full-featured, declarative API for managing session state, invoking models and tools, handling errors, and streaming results. With built-in support for pluggable model providers and seamless session continuity, Agents let you focus on your domain logic instead of boilerplate plumbing. What follows is a closer look at the key capabilities that make them so powerful.
Component identification
Each Agent class is annotated with @ComponentId
as a way to identify the component class and distinguish it from others. With other components like Entities
or Workflows
, we also provide a unique Instance ID, but with agents, you don’t assign a unique ID to each instance. Instead, you provide a session identifier that the Agent binds to. This approach allows multiple components, each with its own @ComponentId
, to operate concurrently within the same shared session context.
Declarative effects API
The Agents effects API provides command handlers that return an Effect<T> (or StreamEffect<T>)
, letting you fluently specify model selection, system/user messages, tool invocations, and response transformations in a type-safe DSL. Following are some of the effects that agents can produce:
- declare which model will be used
- specify system messages, user messages and additional context (prompts)
- configure session memory
- define available tools
- fail a command by returning an error
- return an error message
- transform responses from a model and reply to incoming commands
Session memory management
Session Memory acts as a conversational log, allowing Agents to preserve context over successive exchanges. This capability is crucial for creating Agents that recall earlier interactions, grasp the evolving dialogue, and deliver consistent, context-aware responses.
Whenever an Agent makes a call to an AI model, both the user’s input and the model’s reply are automatically recorded in the session memory. On future requests, these stored messages are passed back to the model as supplementary context, enabling it to build on prior parts of the conversation.
akka.javasdk.agent.memory {
enabled = true
limited-window {
max-size = 156KiB # max history size before oldest message removed
}
}
Above is an example of how you would configure session memory in the application.conf
.
Pluggable model providers
You can define a default AI backend in application.conf and override it per call via the Effects API, choosing from built-in providers (OpenAI, Anthropic, Gemini, etc.) or your own custom implementations. Following is an example of how you could configure a model provider in the application.conf
akka.javasdk {
agent {
model-provider = openai
openai {
model-name = "gpt-4o-mini"
}
}
}
In this case we are using OpenAI’s gpt-4o-mini. You can also use ModelProvider.fromConfig
to pull models from configuration and use different models in different agents.
Tool & function invocation
Akka Agents make it easy to incorporate both local and external functionality into your AI workflows by exposing “tools” that the LLM can invoke as if they were native functions. Under the hood, you annotate your methods or register external service interfaces, and the Agent automatically enriches its prompt with tool definitions and descriptions—giving the model everything it needs to decide which operations to call, and with which parameters. Behind the scenes, the Agent handles instantiation, invocation, and failure management, so you can treat complex integrations as first-class citizen functions in your Effects pipeline.
Some key aspects of tool and function invocation are listed below:
- Contextual tool annotations: Use
@FunctionTool
and@Description
on your methods (or on external service interfaces) to provide the LLM with rich metadata about what each tool does and what parameters it accepts - Dynamic tool registration: Call
.tools(MyService.class)
(or pass an instance) in your Effects builder to register external utilities at runtime—no manual wiring needed - Remote MCP integration: Include tools from other Akka services or third-party MCP servers via
.mcpTools(...)
, with support for custom headers, name filtering, and request/response interceptors - Shared function tools: Define common tools once (e.g., a WeatherService) and reuse them across multiple Agents, promoting consistency and reducing duplication
- Configurable call limits: Control how many successive tool-call steps an LLM can request in a single session using the
akka.javasdk.agent.max-tool-call-steps
setting (default 100)
Built-in error handling
The onFailure
hook in the Agent’s effects API offers extensive error-handling for any failures during model execution, enabling you to define resilient fallback behaviors and deliver informative responses when errors occur.
The onFailure method handles the following categories of exceptions:
- Model related exceptions
- Tool executions exceptions
- Response processing exceptions
- Unknown exceptions
For more information, see the Akka documentation on handling failures
Multi-agent collaboration
In real-world applications, a single Agent rarely works in isolation—complex tasks often demand the collaboration of several specialized Agents. As we saw in our previous blog, Akka Orchestration: guide, moderate, and control long-running systems, by using Akka’s Workflow component, we orchestrate these multi-agent interactions, invoking each Agent in turn (or in parallel), sharing the same session memory, and handling retries, timeouts, and state persistence automatically. Whether you define a static sequence of steps or build a dynamic plan at runtime, the Workflow API ensures that Agents cooperate seamlessly to achieve a common goal while freeing you from boilerplate coordination code.
Key dimensions of multi-agent collaboration include:
- Shared session context: All Agents bound to the same session ID read from and write to the same event-sourced memory, enabling them to build on each other’s outputs and maintain conversational continuity.
- Predefined vs. dynamic orchestration: Use a predefined Workflow to hard-code step order when your process is predictable, or leverage dynamic planning within a Workflow to select and invoke Agents based on runtime criteria (e.g., user intent analysis).
- Durable execution & recovery: Workflows persist their state at each step, automatically retrying failed Agent calls up to your configured limits and failing over to dedicated error steps if needed—so no progress is ever lost.
- Human-in-the-loop support: You can pause a Workflow to await human approval or additional input, then resume exactly where it left off, blending automated Agent collaboration with manual oversight.
Dynamic prompt templates
Rather than embedding prompts directly in your code, you can leverage the built-in prompt template entity. This lets you update prompts on the fly—no restart or redeploy needed—and because the template itself is an entity, every change is recorded, preserving a full history of revisions. Below is an example of prompt templating
@ComponentId("activity-agent")
public class ActivityAgentWithTemplate extends Agent {
public Effect<String> query(String message) {
return effects()
.systemMessageFromTemplate("activity-agent-prompt") (1)
.userMessage(message)//
.thenReply();
}
}
In this example we see the system message (prompt) accessed via a prompt template key.
Agent access: endpoints
Endpoints are how your Agents communicate with external systems, users, or other services. Akka SDK includes endpoint components that enable structured access to your internal components, handling request routing, serialization, and basic observability features.
HTTP endpoints
Provide RESTful APIs using standard HTTP, handling automatic serialization, request routing, and error responses.
gRPC endpoints
Offer efficient, schema-driven APIs based on Protocol Buffers, including built-in streaming and strongly typed client/server stubs.
MCP endpoints
Expose Agent functions to remote LLMs via Model Context Protocol, enabling external models to directly invoke local tools or services.
Conclusion
The Akka Agentic Platform
At Akka, we see Agents as a foundational piece in the broader landscape of agentic AI. Together with Akka Orchestration, Akka Memory, and Akka Streaming, Akka Agents form a complete toolkit for building, operating, and scaling intelligent systems. These systems can take many forms—autonomous (self-planning and self-acting), adaptive (able to adjust goals on the fly), ambient (quietly running in the background), multi-modal (processing audio, video, and sensor data), transactional, analytical, or even digital twins. Whatever the use case, Akka Agents offer a reliable, declarative way to bring stateful, model-driven logic into production.
For more information see our docs.
Final thoughts
As you can see, Akka Agents elevate AI integrations from ad hoc scripts to first-class, production-ready components—packaging statefulness, tooling, error resilience, and observability into a concise, declarative API. By offloading session memory, model orchestration, tool invocation and endpoints to the SDK, you can focus on crafting your business logic while trusting Akka’s battle-tested runtime to handle scaling, persistence, and fault recovery.
Ready to unlock reliable, maintainable agentic AI systems? Give the Akka SDK a try in your next AI service, and experience how they simplify complex AI patterns into reusable, composable building blocks.
Posts by this author