Building AI-powered applications has become increasingly important for modern Java developers. With the rise of large language models and AI services, integrating intelligent capabilities into Java applications is no longer a luxury — it’s a necessity for staying competitive.
Spring AI makes this integration seamless by providing a unified framework for building AI-powered applications with Java. Combined with Amazon Bedrock, developers can create sophisticated AI agents that leverage state-of-the-art foundation models without managing complex infrastructure.
In this post, I’ll guide you through creating your first AI agent using Java and Spring AI, connected to Amazon Bedrock. We’ll build a complete application with both REST API and web interface, demonstrating how to integrate AI capabilities into your Java applications.
Overview of the Solution
What is Spring AI?
Spring AI is a framework that brings the familiar Spring programming model to AI applications. It provides:
Unified API: A consistent interface for working with different AI models and providers
Seamless Integration: Native Spring Boot integration with auto-configuration
Multiple Providers: Support for OpenAI, Azure OpenAI, Amazon Bedrock, Ollama, and more
Advanced Features: Built-in support for RAG (Retrieval Augmented Generation), function calling, and chat memory
Production Ready: Observability, error handling, and resilience patterns
The framework abstracts the complexity of working with different AI providers, allowing you to focus on building your application logic rather than dealing with API specifics.
What is Amazon Bedrock?
Amazon Bedrock is a fully managed service that provides access to high-performing foundation models from leading AI companies including Anthropic, Meta, Stability AI, and Amazon’s own models. Key benefits include:
No Infrastructure Management: Serverless architecture with automatic scaling
Multiple Models: Access to various foundation models through a single API
Security & Privacy: Your data stays within your AWS account
Cost Effective: Pay only for what you use with no upfront commitments
We’ll create a Spring Boot application that demonstrates the core concepts of building AI agents.
The application will include:
Spring Boot web application with Thymeleaf templates
This model is offered on Amazon Bedrock and provides an excellent cost/performance ratio and can be recommended as a migration path from proprietary OpenAI models.
Create the Chat Service
The ChatClient interface is the core abstraction in Spring AI that provides:
Unified API: Works with different AI model providers without code changes
Streaming Support: Real-time response streaming for better user experience
Prompt Management: Built-in support for structured prompts and templates
Response Handling: Consistent response format across different models
Key methods include:
call(Prompt prompt): Synchronous response
stream(Prompt prompt): Streaming response
generate(List<Prompt> prompts): Batch processing
Create a service to handle chat interactions with the AI model:
logger.info("ChatService initialized with embedded ChatClient"); }
public String processChat(String prompt) { logger.info("Processing text chat request - prompt: '{}'", prompt); try { varchatResponse= chatClient .prompt().user(prompt) .call() .chatResponse(); return extractTextFromResponse(chatResponse); } catch (Exception e) { logger.error("Error processing chat request", e); return"I don't know - there was an error processing your request."; } }
public String extractTextFromResponse(org.springframework.ai.chat.model.ChatResponse chatResponse) { if (chatResponse != null) { // First try the standard approach Stringtext= chatResponse.getResult().getOutput().getText(); if (text != null && !text.isEmpty()) { return text; }
// Fallback: iterate through generations for models with reasoning content if (!chatResponse.getResults().isEmpty()) { for (var generation : chatResponse.getResults()) { StringtextContent= generation.getOutput().getText(); if (textContent != null && !textContent.isEmpty()) { logger.info("Found text content: '{}'", textContent); return textContent; } } } }
return"I don't know - no response received."; } } EOF
Create the Chat Controller
Create the REST controller that handles chat interactions:
... publicstaticfinalStringSYSTEM_PROMPT=""" You are a helpful and honest AI Agent for our company. You can help with questions related to travel and expenses. Follow these guidelines strictly: 1. ACCURACY FIRST: Only provide information you are confident about based on your training data. 2. ADMIT UNCERTAINTY: If you are unsure about any fact, detail, or answer, respond with "I don't know" or "I'm not certain about that." 3. NO SPECULATION: Do not guess, speculate, or make up information. It's better to say "I don't know" than to provide potentially incorrect information. 4. PARTIAL KNOWLEDGE: If you know some aspects of a topic but not others, clearly state what you know and what you don't know. 5. SOURCES: Do not claim to have access to real-time information, current events after your training cutoff, or specific databases unless explicitly provided. 6. TABLE FORMAT: Always use clean markdown tables for structured data presentation. Example responses: - "I don't know the current stock price of that company." - "I'm not certain about the specific details of that recent event." - "I don't have enough information to answer that question accurately." Remember: Being honest about limitations builds trust. Always choose "I don't know" over potentially incorrect information. """; ... this.chatClient = chatClientBuilder .defaultSystem(SYSTEM_PROMPT) .build(); ...
This gives the AI agent:
A specific business context (Travel and Expenses Agent)
Honesty constraints (admit when it doesn’t know something)
Test the Application
Now you can test the AI Agent using the Web UI:
Hi, my name is Alex. Who are you?
or the REST API directly:
1 2 3 4
curl -X POST http://localhost:8080/api/chat \ -H "Content-Type: application/json" \ -d '{"prompt": Hi, my name is Alex. Who are you?"}' \ --no-buffer
Nice! Now the AI Agent has a persona which is aligned with our requirements!
Let’s continue the chat:
What is my name?
Unfortunately, the AI Agent doesn’t remember our name, even though we provided it.
We will fix this in the next part of the blog series! Stay tuned!
Commit Changes
1 2
git add . git commit -m "Add the Persona"
Cleaning Up
To stop the application, press Ctrl+C in the terminal where it’s running.
Conclusion
In this blog post, we’ve successfully created a complete AI agent application using Java and Spring AI with Amazon Bedrock integration. We’ve covered:
Setting up a Spring Boot project with Spring AI dependencies
Configuring Amazon Bedrock integration
Creating REST APIs with streaming responses
Building a modern web interface with real-time chat
Implementing AI agent personas with system prompts
The application demonstrates the power of Spring AI’s unified programming model, making it easy to integrate sophisticated AI capabilities into Java applications. The streaming responses provide an excellent user experience, while the persona system allows for customized AI behavior.
In the next part of this series, we’ll explore advanced features of the AI agent.
Let’s continue building intelligent Java applications with Spring AI!