Spring AI Spring Boot Auto Configuration modules providing automatic setup for AI models, vector stores, MCP, and retry capabilities
Full application implementations using Spring AI Spring Boot Auto Configuration.
Complete application with vector store, embeddings, and chat.
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-openai-spring-boot-starter</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-pgvector-store-spring-boot-starter</artifactId>
<version>1.1.2</version>
</dependency>
</dependencies>spring:
ai:
openai:
api-key: ${OPENAI_API_KEY}
chat:
options:
model: gpt-4
temperature: 0.3
embedding:
options:
model: text-embedding-ada-002
vectorstore:
pgvector:
initialize-schema: true
index-type: HNSW
dimensions: 1536
retry:
max-attempts: 5
on-http-codes: 429,503
datasource:
url: jdbc:postgresql://localhost:5432/docs_db
username: postgres
password: postgres
management:
endpoints:
web:
exposure:
include: health,metrics
metrics:
export:
prometheus:
enabled: true@RestController
@RequestMapping("/api")
public class DocsSearchController {
private final ChatClient chatClient;
private final VectorStore vectorStore;
public DocsSearchController(
ChatClient.Builder builder,
VectorStore vectorStore) {
this.chatClient = builder.build();
this.vectorStore = vectorStore;
}
@PostMapping("/search")
public AnswerResponse search(@RequestBody SearchRequest request) {
// Retrieve relevant docs
List<Document> docs = vectorStore.similaritySearch(
SearchRequest.query(request.query())
.withTopK(3)
.withSimilarityThreshold(0.7)
);
if (docs.isEmpty()) {
return new AnswerResponse(
"No relevant documentation found.",
List.of()
);
}
// Build context and generate answer
String context = docs.stream()
.map(Document::getContent)
.collect(Collectors.joining("\n\n"));
String answer = chatClient.prompt()
.user("""
Based on this documentation:
%s
Answer: %s
""".formatted(context, request.query()))
.call()
.content();
return new AnswerResponse(
answer,
docs.stream()
.map(d -> d.getMetadata().get("source"))
.collect(Collectors.toList())
);
}
@PostMapping("/index")
public IndexResponse indexDocuments(
@RequestBody List<DocumentContent> documents) {
List<Document> docs = documents.stream()
.map(d -> {
Document doc = new Document(d.content());
doc.getMetadata().put("source", d.source());
doc.getMetadata().put("title", d.title());
return doc;
})
.collect(Collectors.toList());
vectorStore.add(docs);
return new IndexResponse(docs.size());
}
record SearchRequest(String query) {}
record AnswerResponse(String answer, List<Object> sources) {}
record DocumentContent(String content, String source, String title) {}
record IndexResponse(int indexed) {}
}Chat application with persistent conversation history.
spring:
ai:
openai:
api-key: ${OPENAI_API_KEY}
chat:
options:
model: gpt-4
chat:
client:
enabled: true
memory:
repository:
mongodb:
create-indices: true
ttl: 168h # 7 days
observations:
log-prompt: false
include-error-logging: true
data:
mongodb:
uri: mongodb://localhost:27017/chatdb@RestController
@RequestMapping("/api/chat")
public class ConversationalChatController {
private final ChatClient chatClient;
private final ChatMemory chatMemory;
public ConversationalChatController(
ChatClient.Builder builder,
ChatMemory chatMemory) {
this.chatClient = builder
.defaultSystem("You are a helpful assistant")
.build();
this.chatMemory = chatMemory;
}
@PostMapping
public ChatResponse chat(@RequestBody ChatRequest request) {
// Get conversation history
List<Message> history = chatMemory.get(
request.sessionId()
);
// Generate response with history
String response = chatClient.prompt()
.user(request.message())
.messages(history)
.call()
.content();
// Store conversation
chatMemory.add(request.sessionId(),
new UserMessage(request.message()));
chatMemory.add(request.sessionId(),
new AssistantMessage(response));
return new ChatResponse(response);
}
@DeleteMapping("/{sessionId}")
public void clearHistory(@PathVariable String sessionId) {
chatMemory.clear(sessionId);
}
record ChatRequest(String sessionId, String message) {}
record ChatResponse(String response) {}
}Application using MCP tools for extended capabilities.
spring:
ai:
openai:
api-key: ${OPENAI_API_KEY}
chat:
options:
model: gpt-4
mcp:
client:
enabled: true
type: SYNC
stdio:
connections:
filesystem:
command: node
args: [./mcp-servers/filesystem.js]
database:
command: python
args: [./mcp-servers/database.py]
env:
DB_URL: postgresql://localhost:5432/appdb
toolcallback:
enabled: true@Service
public class McpEnhancedService {
private final ChatClient chatClient;
private final List<McpSyncClient> mcpClients;
public McpEnhancedService(
ChatClient.Builder builder,
SyncMcpToolCallbackProvider mcpTools,
List<McpSyncClient> mcpClients) {
this.chatClient = builder
.defaultFunctions(mcpTools.getToolCallbacks())
.build();
this.mcpClients = mcpClients;
}
public String chat(String message) {
// AI can call MCP tools (read files, query databases, etc.)
return chatClient.prompt()
.user(message)
.call()
.content();
}
public List<String> getAvailableCapabilities() {
List<String> capabilities = new ArrayList<>();
for (McpSyncClient client : mcpClients) {
McpSchema.ListToolsResult tools = client.listTools();
tools.tools().forEach(tool ->
capabilities.add(tool.name() + ": " + tool.description())
);
}
return capabilities;
}
}