Video

Demo: Build and deploy a multi-agent system with Akka - Complete

3 minute read

In this demo, we build, run and evaluate an agentic system with Akka and Claude Code. It contains agents, memory, endpoints, orchestration, and streaming. The system is deployed as a 3 node cluster for resilience, and then deployed into GCP and AWS for multi-region failover and disaster recovery.

Generate agent

Use akka-context folder that contains Akka SDK documentation and check Agent 
docs.
Create an Akka SDK agent named `GreetingAgent` that assists users in learning 
greetings in different languages.
- **Input:** A string question.
- **Output:** Returns an `Effect<String>`.
- method with name `ask`
- Do not perform any environment variables check.
- Do not add JavaDoc annotations
- place it into com.example.application package
- system message should be a static variable
- **Guidelines for system prompt:**
  - The user must provide a language.
  - Always append the language used in parentheses in English (e.g., "Bonjour 
  (French)").
  - At the end of each response, append a list of previous greetings used in 
  the current session.

Test agent

Use akka-context folder that contains Akka SDK documentation and check Agent
integration test docs.
Develop only one integration test for `GreetingAgent` in the `com.example` 
package, named `IntegrationTest`.
- Include a `TestModelProvider` to mock the model with a fixed response.
- Ensure all necessary classes are properly imported.

Add endpoint

Use akka-context folder that contains Akka SDK documentation and check Endpoint 
docs and how to call an Agent.
Implement an HTTP endpoint `GreetingAgentEndpoint` with the following 
specifications:
- **Base path:** `/chat`
- **Endpoint:** POST `/ask`
- **Request:** Accepts a JSON record `QueryRequest` with fields `String userId` 
and `String question`. 
- Put the QueryRequest in the GreetingAgentEndpoint class
- The agent should use `userId` as the sessionId and `question` as the 
user message.
- add acl for all access

Add MCP server

Use akka-context folder that contains Akka SDK documentation and check 
MCPEndpoint docs
Create an MCP server endpoint named `UserNameMcpEndpoint` for retrieving 
user's name based on `userId`.
- Place the implementation in the `com.example.api` package.
- Provide a mock implementation that returns a random name for each query.
- add all needed annotations (class and method)
- use MCP Tool annotations with all required parameters including the 
McpEndpoint annotation

Add MCP tool to an agent

Use akka-context folder that contains Akka SDK documentation and check how 
to configure MCP tools for an Agent
Update the `GreetingAgent` to display the user's name during the first 
interaction, for example: "Hello <user name>!".
- Configure GreetingAgent to use `UserNameMcpEndpoint` as an MCP tool. No need 
to use AllowedToolNames. Use the service name specified by the `artifactId` 
in `pom.xml`.
- set `userId` from context().sessionId().
- Add the `userId` to the user message in the following format: 
"userId:<userID>;question:
- update system prompt accordingly 

Add streaming

Use akka-context folder that contains Akka SDK documentation and check Agent 
and Endpoint streaming support.
Replace the `GreetingAgent`'s `greet` method with a streaming response.
- Update the `GreetingAgentEndpoint`'s `ask` endpoint to use the streaming 
response from `GreetingAgent` and wrap it with Server-Sent Events (SSE), 
returning an `akka.http.javadsl.model.HttpResponse`.
- Remove all non-streaming methods from both `GreetingAgent` and 
`GreetingAgentEndpoint`.
- Update the integration test to use the streaming agent. Do not modify the 
`TestModelProvider`.
**Example usage in the integration test:**
var tokenStream = componentClient
    .forAgent()
    .inSession(sessionId)
    .tokenStream(HelloWorldAgent::streamGreet)
    .source(userGreeting);

// Run the stream and collect the tokens into a List
List<String> tokens = tokenStream
    .toMat(Sink.seq(), Keep.right())
    .run(testKit.getMaterializer())
    .toCompletableFuture()
    .get();

When AI Needs an SLA