Spring AI के साथ AI-Powered Java Applications बनाना: संपूर्ण गाइड
Spring AI के साथ AI-powered Java applications बनाने के लिए एक संपूर्ण गाइड — ChatClient, prompt templates, structured output, RAG, function calling, advisors, chat memory, embeddings, multi-mod
Spring AI Java Developers के लिए सब कुछ क्यों बदल देता है
Spring AI वही productivity और portability artificial intelligence की दुनिया में लाता है जिसे Spring Boot developers पसंद करते हैं। अपने AI code को एक clean abstraction के against एक बार लिखें, फिर providers को swap करें — OpenAI, Anthropic Claude, Google Gemini, Ollama, AWS Bedrock — एक configuration change के साथ, code rewrite के साथ नहीं।
मई 2025 में 1.0 GA के रूप में released, Spring AI प्रदान करता है: एक unified chat API, Java records में structured output mapping, built-in RAG support, function/tool calling, chat memory, advisors, embeddings, image generation, multi-modality, और evaluation — सब Spring Boot auto-configuration के साथ।
शुरुआत करना
अपने pom.xml में BOM और एक provider starter जोड़ें:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-bom</artifactId>
<version>1.1.4</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!-- Pick ONE provider starter -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-openai</artifactId>
</dependency>
application.yml में configure करें:
spring:
ai:
openai:
api-key: ${OPENAI_API_KEY}
chat:
options:
model: gpt-4o
temperature: 0.7
Core Abstractions: ChatModel, ChatClient, Prompt
Spring AI की शक्ति provider-agnostic interfaces में निहित है। आपका code abstractions के against program करता है; Spring Boot concrete provider को wire in करता है।
ChatClient — Fluent API (अनुशंसित)
@RestController
class ChatController {
private final ChatClient chatClient;
ChatController(ChatClient.Builder builder) {
this.chatClient = builder
.defaultSystem("You are a helpful coding assistant.")
.build();
}
@GetMapping("/chat")
String chat(@RequestParam String message) {
return chatClient.prompt()
.user(message)
.call()
.content();
}
}
Message Types
SystemMessage instructions set करता है। UserMessage user input ले जाता है (multimodal के लिए text + media)। AssistantMessage model replies रखता है। ToolResponseMessage tool/function results return करता है।
Streaming Responses
@GetMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
Flux<String> streamChat(@RequestParam String message) {
return chatClient.prompt()
.user(message)
.stream()
.content();
}
Prompt Templates
Spring AI के PromptTemplate का उपयोग करके variable substitution के साथ prompts को reusable रखें:
// Inline template
String answer = chatClient.prompt()
.user(u -> u
.text("List {count} best practices for {topic}")
.param("count", "5")
.param("topic", "REST API design"))
.call()
.content();
// System prompt template
String systemText = """
You are an expert in {domain}.
Reply in the style of a {style}.
""";
SystemPromptTemplate systemTemplate = new SystemPromptTemplate(systemText);
Message systemMessage = systemTemplate.createMessage(Map.of(
"domain", "distributed systems",
"style", "senior engineer"
));
// Load from classpath resource
@Value("classpath:/prompts/analysis.st")
private Resource analysisTemplate;
PromptTemplate template = new PromptTemplate(analysisTemplate);
Prompt Engineering Best Practices
Specific रहें: model को ठीक-ठीक बताएँ कि आपको क्या format, tone, और constraints चाहिए। System messages का उपयोग करें: system prompt में persona और rules set करें, user content user prompt में। One-shot/few-shot: desired output का एक उदाहरण शामिल करें। Chain-of-thought: complex reasoning के लिए model को "think step by step" करने को कहें। Structured output: JSON request करें और इसे records पर map करें (अगला section देखें)।
Structured Output — AI Responses को Java Records के रूप में
AI-generated text को सीधे typed Java objects में map करें। कोई manual JSON parsing ज़रूरी नहीं।
// Define your record
record BookRecommendation(String title, String author,
String genre, String summary) {}
// Single entity
BookRecommendation book = chatClient.prompt()
.user("Recommend a classic science fiction novel.")
.call()
.entity(BookRecommendation.class);
// List of entities
List<BookRecommendation> books = chatClient.prompt()
.user("Recommend 5 classic sci-fi novels.")
.call()
.entity(new ParameterizedTypeReference<List<BookRecommendation>>() {});
// Map output
Map<String, Object> data = chatClient.prompt()
.user("List the population of Tokyo, London, and New York")
.call()
.entity(new ParameterizedTypeReference<Map<String, Object>>() {});
RAG: Retrieval Augmented Generation
RAG आपके AI को एक vector store से relevant documents retrieve करके और उन्हें prompt में context के रूप में inject करके आपके अपने data का उपयोग करके सवालों का जवाब देने देता है।
Step 1: Document Ingestion (ETL)
@Component
class DocumentIngestionService {
private final VectorStore vectorStore;
DocumentIngestionService(VectorStore vectorStore) {
this.vectorStore = vectorStore;
}
public void ingest(String pdfPath) {
// 1. Read documents (PDF, JSON, HTML, Markdown, DOCX supported)
PagePdfDocumentReader reader = new PagePdfDocumentReader(pdfPath,
PdfDocumentReaderConfig.builder()
.withPagesPerDocument(1).build());
// 2. Split into chunks
TokenTextSplitter splitter = TokenTextSplitter.builder()
.withChunkSize(800)
.withMinChunkSizeChars(350).build();
// 3. Store — embeddings generated automatically
vectorStore.write(splitter.apply(reader.read()));
}
}
Step 2: QuestionAnswerAdvisor के साथ Query करें
ChatResponse response = chatClient.prompt()
.advisors(QuestionAnswerAdvisor.builder(vectorStore)
.searchRequest(SearchRequest.builder()
.similarityThreshold(0.75)
.topK(5).build())
.build())
.user("What does our refund policy say about digital products?")
.call()
.chatResponse();
Query Rewriting के साथ Advanced RAG
Advisor ragAdvisor = RetrievalAugmentationAdvisor.builder()
.queryTransformers(RewriteQueryTransformer.builder()
.chatClientBuilder(chatClientBuilder.build().mutate()).build())
.documentRetriever(VectorStoreDocumentRetriever.builder()
.vectorStore(vectorStore)
.similarityThreshold(0.50)
.topK(5).build())
.build();
String answer = chatClient.prompt()
.advisors(ragAdvisor)
.user("How do I configure SSL?")
.call()
.content();
Vector Store Configuration (PGVector)
# application.yml
spring:
ai:
vectorstore:
pgvector:
initialize-schema: true
dimensions: 1536
distance-type: cosine_distance
Supported vector stores: PGVector, Chroma, Pinecone, Redis, Milvus, Weaviate, Qdrant, Elasticsearch, MongoDB Atlas, Neo4j, और बहुत कुछ।
Function Calling / Tool Use
Real-time data लाने या actions करने के लिए AI models को अपने Java methods invoke करने दें।
@Tool के साथ Declarative
class WeatherTools {
@Tool(description = "Get current weather for a given city")
String getWeather(
@ToolParam(description = "City name") String city,
@ToolParam(description = "Temperature unit", required = false) String unit) {
// Call a real weather API here
return "Weather in %s: 22 degrees %s, sunny."
.formatted(city, unit != null ? unit : "Celsius");
}
}
// Use it — the model decides when to call the function
String response = chatClient.prompt()
.user("What's the weather like in London?")
.tools(new WeatherTools())
.call()
.content();
Spring Beans के रूप में Functions
public record CurrencyRequest(String from, String to, double amount) {}
public record CurrencyResponse(double convertedAmount, double rate) {}
@Bean
@Description("Convert an amount from one currency to another")
Function<CurrencyRequest, CurrencyResponse> convertCurrency() {
return request -> {
double rate = fetchExchangeRate(request.from(), request.to());
return new CurrencyResponse(request.amount() * rate, rate);
};
}
// Reference by bean name
String answer = chatClient.prompt()
.user("Convert 100 USD to EUR")
.toolNames("convertCurrency")
.call()
.content();
Tool Context — अतिरिक्त Data Pass करें
class CustomerTools {
@Tool(description = "Get customer by ID")
Customer getCustomer(Long id, ToolContext ctx) {
String tenantId = (String) ctx.getContext().get("tenantId");
return customerRepo.findByIdAndTenant(id, tenantId);
}
}
String answer = chatClient.prompt()
.user("Tell me about customer #42")
.tools(new CustomerTools())
.toolContext(Map.of("tenantId", "acme-corp"))
.call()
.content();
Advisors — AI Calls के लिए Interceptors
Advisors model तक पहुँचने से पहले prompts को modify करते हैं और वापस आते समय responses को process करते हैं — AI के लिए Spring MVC interceptors की तरह।
Chat Memory — Conversation History
ChatMemory memory = MessageWindowChatMemory.builder()
.chatMemoryRepository(new InMemoryChatMemoryRepository())
.maxMessages(20).build();
ChatClient client = ChatClient.builder(chatModel)
.defaultAdvisors(MessageChatMemoryAdvisor.builder(memory).build())
.build();
// First call
client.prompt().user("My name is Alice")
.advisors(a -> a.param(ChatMemory.CONVERSATION_ID, "session-1"))
.call().content();
// Second call — remembers the name
client.prompt().user("What is my name?")
.advisors(a -> a.param(ChatMemory.CONVERSATION_ID, "session-1"))
.call().content(); // "Your name is Alice"
Custom Advisor — Latency Tracking
public class LatencyAdvisor implements CallAdvisor {
public String getName() { return "LatencyAdvisor"; }
public int getOrder() { return 0; }
public ChatClientResponse adviseCall(ChatClientRequest request,
CallAdvisorChain chain) {
long start = System.currentTimeMillis();
ChatClientResponse response = chain.nextCall(request);
log.info("AI call took {}ms", System.currentTimeMillis() - start);
return response;
}
}
एकाधिक Advisors को Combine करना
ChatClient client = ChatClient.builder(chatModel)
.defaultAdvisors(
MessageChatMemoryAdvisor.builder(memory).build(),
QuestionAnswerAdvisor.builder(vectorStore).build(),
new SimpleLoggerAdvisor(),
new LatencyAdvisor()
).build();
Embeddings
Similarity search, clustering, और RAG के लिए text को numerical vectors में convert करें।
@Service
class EmbeddingService {
private final EmbeddingModel embeddingModel;
// Single text
float[] embed(String text) {
return embeddingModel.embed(text);
}
// Batch
List<float[]> embedBatch(List<String> texts) {
return embeddingModel.embed(texts);
}
// Vector dimensions
int dimensions() { return embeddingModel.dimensions(); }
}
Multi-Modality — Images + Text
GPT-4o, Claude 3, या Gemini जैसे models को text के साथ-साथ images भेजें:
String description = chatClient.prompt()
.user(u -> u
.text("Describe what you see in this image.")
.media(MimeTypeUtils.IMAGE_PNG,
new ClassPathResource("/images/diagram.png")))
.call()
.content();
// From URL
String analysis = chatClient.prompt()
.user(u -> u
.text("What's in this image?")
.media(MimeTypeUtils.IMAGE_JPEG,
URI.create("https://example.com/photo.jpg")))
.call()
.content();
Image Generation
@RestController
class ImageController {
private final ImageModel imageModel;
@GetMapping("/generate-image")
String generateImage(@RequestParam String description) {
ImageResponse response = imageModel.call(
new ImagePrompt(description,
OpenAiImageOptions.builder()
.quality("hd").N(1)
.height(1024).width(1024).build()));
return response.getResult().getOutput().getUrl();
}
}
Evaluation — अपने AI को Test करें
Spring AI relevance check करने और hallucinations पकड़ने के लिए evaluators प्रदान करता है:
// Is the response relevant to the question and context?
RelevancyEvaluator evaluator = new RelevancyEvaluator(ChatClient.builder(chatModel));
EvaluationResponse eval = evaluator.evaluate(
new EvaluationRequest(question, context, aiResponse));
assertThat(eval.isPass()).isTrue();
// Fact-checking — detect hallucinations
FactCheckingEvaluator factChecker = new FactCheckingEvaluator(
ChatClient.builder(chatModel));
EvaluationResponse result = factChecker.evaluate(
new EvaluationRequest(knownFacts, Collections.emptyList(), claim));
assertFalse(result.isPass()); // claim contradicts known facts
Provider Configuration Cheat Sheet
| Provider | Starter Artifact | Key Config |
|---|---|---|
| OpenAI | spring-ai-starter-model-openai | spring.ai.openai.api-key |
| Anthropic Claude | spring-ai-starter-model-anthropic | spring.ai.anthropic.api-key |
| Ollama (Local) | spring-ai-starter-model-ollama | spring.ai.ollama.base-url |
| AWS Bedrock | spring-ai-starter-model-bedrock | spring.ai.bedrock.aws.region |
| Azure OpenAI | spring-ai-starter-model-azure-openai | spring.ai.azure.openai.api-key |
| Google Gemini | spring-ai-starter-model-vertex-ai | spring.ai.vertex.ai.gemini.project-id |
| PGVector | spring-ai-starter-vector-store-pgvector | spring.ai.vectorstore.pgvector.* |
Key Takeaways
Provider-agnostic: एक बार लिखें, config के माध्यम से AI providers को swap करें। कोई vendor lock-in नहीं।
Spring-native: Auto-configuration, dependency injection, profiles — वह सब कुछ जो Spring developers की अपेक्षा करते हैं।
Production-ready patterns: RAG, tool calling, chat memory, advisors, evaluation, और structured output सभी built in हैं।
Simple से शुरू करें: ChatClient.prompt().user("...").call().content() — यह आपका पहला AI call है। ज़रूरत के अनुसार RAG, tools, और memory जोड़ें।
Spring AI AI integration को किसी भी अन्य Spring dependency की तरह महसूस कराता है — starter import करें, configure करें, inject करें, और use करें।