CtrlK
CommunityDocumentationLog inGet started
Tessl Logo

tessl/maven-org-springframework-ai--spring-ai-azure-openai

Spring AI integration for Azure OpenAI services providing chat completion, text embeddings, image generation, and audio transcription with GPT, DALL-E, and Whisper models

Overview
Eval results
Files

real-world-scenarios.mddocs/examples/

Real-World Scenarios

Production-ready examples for common use cases.

Customer Support Chatbot

Build an intelligent customer support system with context and memory.

@Service
public class CustomerSupportService {
    
    @Autowired
    private AzureOpenAiChatModel chatModel;
    
    @Autowired
    private AzureOpenAiEmbeddingModel embeddingModel;
    
    private final Map<String, List<Message>> sessions = new ConcurrentHashMap<>();
    
    public String handleCustomerQuery(String sessionId, String query) {
        // Get or create conversation history
        List<Message> history = sessions.computeIfAbsent(
            sessionId,
            k -> new ArrayList<>()
        );
        
        // Retrieve relevant knowledge base articles
        EmbeddingResponse queryEmbedding = embeddingModel.call(
            new EmbeddingRequest(List.of(query), null)
        );
        List<String> relevantArticles = searchKnowledgeBase(
            queryEmbedding.getResults().get(0).getOutput()
        );
        
        // Build context-aware prompt
        String context = "Knowledge Base:\n" + String.join("\n", relevantArticles);
        String systemPrompt = "You are a helpful customer support agent. " +
            "Use the knowledge base to answer questions accurately. " +
            "If you don't know, say so.\n\n" + context;
        
        // Add to conversation
        if (history.isEmpty()) {
            history.add(new SystemMessage(systemPrompt));
        }
        history.add(new UserMessage(query));
        
        // Generate response
        ChatResponse response = chatModel.call(new Prompt(history));
        String answer = response.getResult().getOutput().getText();
        
        // Update history
        history.add(new AssistantMessage(answer));
        
        // Limit history size
        if (history.size() > 20) {
            history = history.subList(history.size() - 20, history.size());
            sessions.put(sessionId, history);
        }
        
        return answer;
    }
}

Document Analysis and Summarization

Analyze large documents and generate summaries.

@Service
public class DocumentAnalysisService {
    
    @Autowired
    private AzureOpenAiChatModel chatModel;
    
    @Autowired
    private AzureOpenAiEmbeddingModel embeddingModel;
    
    public DocumentSummary analyzeDocument(String document) {
        // Split into chunks if too long
        List<String> chunks = splitIntoChunks(document, 4000);
        
        // Summarize each chunk
        List<String> chunkSummaries = chunks.stream()
            .map(chunk -> {
                AzureOpenAiChatOptions options = AzureOpenAiChatOptions.builder()
                    .temperature(0.3)  // Low temp for factual summaries
                    .maxTokens(500)
                    .build();
                
                Prompt prompt = new Prompt(
                    "Summarize this text concisely:\n\n" + chunk,
                    options
                );
                return chatModel.call(prompt)
                    .getResult()
                    .getOutput()
                    .getText();
            })
            .collect(Collectors.toList());
        
        // Generate final summary
        String combinedSummaries = String.join("\n\n", chunkSummaries);
        Prompt finalPrompt = new Prompt(
            "Create a comprehensive summary from these section summaries:\n\n" +
            combinedSummaries
        );
        String finalSummary = chatModel.call(finalPrompt)
            .getResult()
            .getOutput()
            .getText();
        
        // Extract key points with structured output
        Map<String, Object> schema = Map.of(
            "type", "object",
            "properties", Map.of(
                "key_points", Map.of(
                    "type", "array",
                    "items", Map.of("type", "string")
                ),
                "topics", Map.of(
                    "type", "array",
                    "items", Map.of("type", "string")
                ),
                "sentiment", Map.of("type", "string")
            )
        );
        
        AzureOpenAiResponseFormat format = AzureOpenAiResponseFormat.builder()
            .type(AzureOpenAiResponseFormat.Type.JSON_SCHEMA)
            .jsonSchema(AzureOpenAiResponseFormat.JsonSchema.builder()
                .name("DocumentAnalysis")
                .schema(schema)
                .strict(true)
                .build())
            .build();
        
        AzureOpenAiChatOptions analysisOptions = AzureOpenAiChatOptions.builder()
            .responseFormat(format)
            .build();
        
        Prompt analysisPrompt = new Prompt(
            "Analyze this document and extract key points, topics, and sentiment:\n\n" +
            finalSummary,
            analysisOptions
        );
        String analysisJson = chatModel.call(analysisPrompt)
            .getResult()
            .getOutput()
            .getText();
        
        return new DocumentSummary(finalSummary, analysisJson);
    }
}

Intelligent Search Engine

Build a semantic search engine with re-ranking.

@Service
public class SemanticSearchService {
    
    @Autowired
    private AzureOpenAiEmbeddingModel embeddingModel;
    
    @Autowired
    private AzureOpenAiChatModel chatModel;
    
    private final VectorDatabase vectorDb;
    
    public List<SearchResult> search(String query, int topK) {
        // 1. Generate query embedding
        EmbeddingResponse queryEmbedding = embeddingModel.call(
            new EmbeddingRequest(
                List.of(query),
                AzureOpenAiEmbeddingOptions.builder()
                    .inputType("query")
                    .build()
            )
        );
        
        // 2. Vector similarity search
        List<Document> candidates = vectorDb.similaritySearch(
            queryEmbedding.getResults().get(0).getOutput(),
            topK * 3  // Get more candidates for re-ranking
        );
        
        // 3. Re-rank with LLM
        String reRankPrompt = buildReRankPrompt(query, candidates);
        AzureOpenAiChatOptions options = AzureOpenAiChatOptions.builder()
            .temperature(0.0)
            .responseFormat(AzureOpenAiResponseFormat.builder()
                .type(AzureOpenAiResponseFormat.Type.JSON_OBJECT)
                .build())
            .build();
        
        Prompt prompt = new Prompt(reRankPrompt, options);
        String reRankedJson = chatModel.call(prompt)
            .getResult()
            .getOutput()
            .getText();
        
        // 4. Parse and return top results
        return parseReRankedResults(reRankedJson, topK);
    }
    
    public void indexDocuments(List<String> documents) {
        // Batch embed documents
        EmbeddingResponse embeddings = embeddingModel.call(
            new EmbeddingRequest(
                documents,
                AzureOpenAiEmbeddingOptions.builder()
                    .inputType("document")
                    .build()
            )
        );
        
        // Store in vector database
        for (int i = 0; i < documents.size(); i++) {
            vectorDb.store(
                documents.get(i),
                embeddings.getResults().get(i).getOutput()
            );
        }
    }
}

Content Generation Platform

Generate blog posts, social media content, and images.

@Service
public class ContentGenerationService {
    
    @Autowired
    private AzureOpenAiChatModel chatModel;
    
    @Autowired
    private AzureOpenAiImageModel imageModel;
    
    public BlogPost generateBlogPost(String topic, String targetAudience) {
        // 1. Generate outline
        Prompt outlinePrompt = new Prompt(
            String.format(
                "Create a detailed blog post outline about '%s' for %s. " +
                "Include 5-7 main sections with subsections.",
                topic, targetAudience
            )
        );
        String outline = chatModel.call(outlinePrompt)
            .getResult()
            .getOutput()
            .getText();
        
        // 2. Generate full content
        AzureOpenAiChatOptions contentOptions = AzureOpenAiChatOptions.builder()
            .temperature(0.8)  // More creative
            .maxTokens(3000)
            .build();
        
        Prompt contentPrompt = new Prompt(
            String.format(
                "Write a comprehensive blog post based on this outline:\n\n%s\n\n" +
                "Make it engaging, informative, and suitable for %s.",
                outline, targetAudience
            ),
            contentOptions
        );
        
        StringBuilder fullContent = new StringBuilder();
        Flux<ChatResponse> stream = chatModel.stream(contentPrompt);
        stream.subscribe(chunk -> {
            String token = chunk.getResult().getOutput().getText();
            if (token != null) {
                fullContent.append(token);
            }
        });
        
        // 3. Generate featured image
        Prompt imagePrompt = new ImagePrompt(
            String.format(
                "Professional blog header image for article about %s, " +
                "modern design, high quality, suitable for tech blog",
                topic
            )
        );
        
        AzureOpenAiImageOptions imageOptions = AzureOpenAiImageOptions.builder()
            .width(1792)
            .height(1024)
            .style("natural")
            .build();
        imageOptions.setQuality("hd");
        
        ImageResponse imageResponse = imageModel.call(imagePrompt);
        String imageUrl = imageResponse.getResult().getOutput().getUrl();
        
        // 4. Generate social media snippets
        Prompt socialPrompt = new Prompt(
            "Create 3 engaging social media posts (Twitter, LinkedIn, Facebook) " +
            "to promote this blog post:\n\n" + fullContent.toString()
        );
        String socialSnippets = chatModel.call(socialPrompt)
            .getResult()
            .getOutput()
            .getText();
        
        return new BlogPost(
            topic,
            fullContent.toString(),
            imageUrl,
            socialSnippets
        );
    }
}

Meeting Transcription and Analysis

Transcribe meetings and generate actionable insights.

@Service
public class MeetingAnalysisService {
    
    @Autowired
    private AzureOpenAiAudioTranscriptionModel transcriptionModel;
    
    @Autowired
    private AzureOpenAiChatModel chatModel;
    
    public MeetingReport analyzeMeeting(Resource audioFile) {
        // 1. Transcribe with timestamps
        AzureOpenAiAudioTranscriptionOptions options =
            AzureOpenAiAudioTranscriptionOptions.builder()
                .language("en")
                .responseFormat(
                    AzureOpenAiAudioTranscriptionOptions
                        .TranscriptResponseFormat.VERBOSE_JSON
                )
                .granularityType(List.of(
                    AzureOpenAiAudioTranscriptionOptions.GranularityType.SEGMENT
                ))
                .temperature(0.0f)
                .build();
        
        AudioTranscriptionPrompt prompt = new AudioTranscriptionPrompt(
            audioFile,
            options
        );
        AudioTranscriptionResponse response = transcriptionModel.call(prompt);
        String transcript = response.getResult().getOutput();
        
        // 2. Extract action items
        Map<String, Object> actionSchema = Map.of(
            "type", "object",
            "properties", Map.of(
                "action_items", Map.of(
                    "type", "array",
                    "items", Map.of(
                        "type", "object",
                        "properties", Map.of(
                            "task", Map.of("type", "string"),
                            "assignee", Map.of("type", "string"),
                            "deadline", Map.of("type", "string")
                        )
                    )
                ),
                "decisions", Map.of(
                    "type", "array",
                    "items", Map.of("type", "string")
                ),
                "topics", Map.of(
                    "type", "array",
                    "items", Map.of("type", "string")
                )
            )
        );
        
        AzureOpenAiResponseFormat format = AzureOpenAiResponseFormat.builder()
            .type(AzureOpenAiResponseFormat.Type.JSON_SCHEMA)
            .jsonSchema(AzureOpenAiResponseFormat.JsonSchema.builder()
                .name("MeetingAnalysis")
                .schema(actionSchema)
                .strict(true)
                .build())
            .build();
        
        AzureOpenAiChatOptions analysisOptions = AzureOpenAiChatOptions.builder()
            .responseFormat(format)
            .temperature(0.0)
            .build();
        
        Prompt analysisPrompt = new Prompt(
            "Analyze this meeting transcript and extract action items, " +
            "decisions made, and topics discussed:\n\n" + transcript,
            analysisOptions
        );
        String analysisJson = chatModel.call(analysisPrompt)
            .getResult()
            .getOutput()
            .getText();
        
        // 3. Generate summary
        Prompt summaryPrompt = new Prompt(
            "Create a concise executive summary of this meeting:\n\n" + transcript
        );
        String summary = chatModel.call(summaryPrompt)
            .getResult()
            .getOutput()
            .getText();
        
        return new MeetingReport(transcript, summary, analysisJson);
    }
}

E-commerce Product Recommendations

Build personalized product recommendations.

@Service
public class RecommendationService {
    
    @Autowired
    private AzureOpenAiEmbeddingModel embeddingModel;
    
    @Autowired
    private AzureOpenAiChatModel chatModel;
    
    public List<Product> getRecommendations(
        User user,
        List<Product> browsedProducts,
        int count
    ) {
        // 1. Create user profile embedding
        String userProfile = buildUserProfile(user, browsedProducts);
        EmbeddingResponse profileEmbedding = embeddingModel.call(
            new EmbeddingRequest(List.of(userProfile), null)
        );
        
        // 2. Find similar products
        List<Product> candidates = findSimilarProducts(
            profileEmbedding.getResults().get(0).getOutput(),
            count * 5
        );
        
        // 3. Use LLM to rank and explain
        String rankingPrompt = buildRankingPrompt(user, candidates);
        AzureOpenAiChatOptions options = AzureOpenAiChatOptions.builder()
            .temperature(0.3)
            .responseFormat(AzureOpenAiResponseFormat.builder()
                .type(AzureOpenAiResponseFormat.Type.JSON_OBJECT)
                .build())
            .build();
        
        Prompt prompt = new Prompt(rankingPrompt, options);
        String rankedJson = chatModel.call(prompt)
            .getResult()
            .getOutput()
            .getText();
        
        return parseRecommendations(rankedJson, count);
    }
    
    public void indexProducts(List<Product> products) {
        // Batch embed product descriptions
        List<String> descriptions = products.stream()
            .map(p -> p.getName() + " " + p.getDescription())
            .collect(Collectors.toList());
        
        EmbeddingResponse embeddings = embeddingModel.call(
            new EmbeddingRequest(descriptions, null)
        );
        
        // Store embeddings
        for (int i = 0; i < products.size(); i++) {
            productIndex.store(
                products.get(i),
                embeddings.getResults().get(i).getOutput()
            );
        }
    }
}

Automated Code Review Assistant

Review code and provide suggestions.

@Service
public class CodeReviewService {
    
    @Autowired
    private AzureOpenAiChatModel chatModel;
    
    public CodeReviewResult reviewCode(String code, String language) {
        // Define review schema
        Map<String, Object> schema = Map.of(
            "type", "object",
            "properties", Map.of(
                "issues", Map.of(
                    "type", "array",
                    "items", Map.of(
                        "type", "object",
                        "properties", Map.of(
                            "severity", Map.of("type", "string"),
                            "line", Map.of("type", "integer"),
                            "description", Map.of("type", "string"),
                            "suggestion", Map.of("type", "string")
                        )
                    )
                ),
                "score", Map.of("type", "integer"),
                "summary", Map.of("type", "string")
            )
        );
        
        AzureOpenAiResponseFormat format = AzureOpenAiResponseFormat.builder()
            .type(AzureOpenAiResponseFormat.Type.JSON_SCHEMA)
            .jsonSchema(AzureOpenAiResponseFormat.JsonSchema.builder()
                .name("CodeReview")
                .schema(schema)
                .strict(true)
                .build())
            .build();
        
        AzureOpenAiChatOptions options = AzureOpenAiChatOptions.builder()
            .responseFormat(format)
            .temperature(0.0)
            .build();
        
        Prompt prompt = new Prompt(
            String.format(
                "Review this %s code for:\n" +
                "- Security vulnerabilities\n" +
                "- Performance issues\n" +
                "- Code quality\n" +
                "- Best practices\n\n" +
                "Code:\n```%s\n%s\n```",
                language, language, code
            ),
            options
        );
        
        String reviewJson = chatModel.call(prompt)
            .getResult()
            .getOutput()
            .getText();
        
        return parseCodeReview(reviewJson);
    }
}

Next Steps

  • Edge Cases - Handle advanced scenarios
  • Integration Patterns - Combine capabilities
  • Performance Guide - Optimize for production
tessl i tessl/maven-org-springframework-ai--spring-ai-azure-openai@1.1.1

docs

examples

edge-cases.md

real-world-scenarios.md

index.md

tile.json