CtrlK
BlogDocsLog inGet started
Tessl Logo

giuseppe-trisciuoglio/developer-kit

Comprehensive developer toolkit providing reusable skills for Java/Spring Boot, TypeScript/NestJS/React/Next.js, Python, PHP, AWS CloudFormation, AI/RAG, DevOps, and more.

82

Quality

82%

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Risky

Do not use without reviewing

Validation failed for skills in this tile
One or more skills have errors that need to be fixed before they can move to Implementation and Discovery review.
Overview
Quality
Evals
Security
Files

examples.mdplugins/developer-kit-java/skills/langchain4j-spring-boot-integration/references/

LangChain4j Spring Boot Integration - Examples

Comprehensive implementation examples for Spring Boot integration with LangChain4j.

Basic Setup Example

Complete Spring Boot Application

@SpringBootApplication
public class Langchain4jApplication {

    public static void main(String[] args) {
        SpringApplication.run(Langchain4jApplication.class, args);
    }
}

@Configuration
public class AiConfiguration {

    @Bean
    @Profile("openai")
    public ChatModel openAiChatModel(@Value("${langchain4j.open-ai.chat-model.api-key}") String apiKey) {
        return OpenAiChatModel.builder()
                .apiKey(apiKey)
                .modelName("gpt-4o-mini")
                .temperature(0.7)
                .maxTokens(1000)
                .logRequests(true)
                .logResponses(true)
                .build();
    }

    @Bean
    public EmbeddingModel openAiEmbeddingModel(@Value("${langchain4j.open-ai.embedding-model.api-key}") String apiKey) {
        return OpenAiEmbeddingModel.builder()
                .apiKey(apiKey)
                .modelName("text-embedding-3-small")
                .dimensions(1536)
                .build();
    }
}

@AiService
interface CustomerSupportAssistant {

    @SystemMessage("You are a helpful customer support agent for TechCorp. " +
                  "Be polite, professional, and try to resolve customer issues efficiently. " +
                  "If you cannot resolve an issue, escalate to a human agent.")
    String handleInquiry(String customerMessage);

    @UserMessage("Analyze this customer feedback and extract sentiment: {{feedback}}")
    @SystemMessage("Return only: POSITIVE, NEGATIVE, or NEUTRAL")
    String analyzeSentiment(String feedback);

    @UserMessage("Extract key entities from this text: {{text}}")
    @SystemMessage("Return a JSON object with entities as keys and their types as values")
    String extractEntities(String text);
}

@RestController
@RequestMapping("/api/support")
@RequiredArgsConstructor
public class CustomerSupportController {

    private final CustomerSupportAssistant assistant;

    @PostMapping("/inquiry")
    public ResponseEntity<SupportResponse> handleInquiry(@RequestBody @Valid SupportRequest request) {
        String response = assistant.handleInquiry(request.getMessage());
        return ResponseEntity.ok(new SupportResponse(response, Instant.now()));
    }

    @PostMapping("/sentiment")
    public ResponseEntity<SentimentResponse> analyzeSentiment(@RequestBody @Valid SentimentRequest request) {
        String sentiment = assistant.analyzeSentiment(request.getFeedback());
        return ResponseEntity.ok(new SentimentResponse(sentiment, Instant.now()));
    }

    @PostMapping("/entities")
    public ResponseEntity<EntitiesResponse> extractEntities(@RequestBody @Valid EntitiesRequest request) {
        String entities = assistant.extractEntities(request.getText());
        return ResponseEntity.ok(new EntitiesResponse(entities, Instant.now()));
    }
}

// DTO Classes
record SupportRequest(String message) {}
record SupportResponse(String response, Instant timestamp) {}

record SentimentRequest(String feedback) {}
record SentimentResponse(String sentiment, Instant timestamp) {}

record EntitiesRequest(String text) {}
record EntitiesResponse(String entities, Instant timestamp) {}

2. Custom AI Service Bean Configuration

Scenario: Configure AI services as Spring beans.

@Configuration
public class AiConfig {
    
    @Bean
    public ChatModel chatModel() {
        return OpenAiChatModel.builder()
            .apiKey(System.getenv("OPENAI_API_KEY"))
            .modelName("gpt-4o-mini")
            .temperature(0.7)
            .build();
    }
    
    @Bean
    public EmbeddingModel embeddingModel() {
        return OpenAiEmbeddingModel.builder()
            .apiKey(System.getenv("OPENAI_API_KEY"))
            .modelName("text-embedding-3-small")
            .build();
    }
    
    @Bean
    public DocumentAssistant documentAssistant(ChatModel chatModel) {
        return AiServices.builder(DocumentAssistant.class)
            .chatModel(chatModel)
            .chatMemory(MessageWindowChatMemory.withMaxMessages(10))
            .build();
    }
}

interface DocumentAssistant {
    String chat(String message);
}

3. REST API with AI Service

Scenario: Expose AI functionality via REST endpoints.

@RestController
@RequestMapping("/api/chat")
public class ChatController {
    
    private final ChatAssistant assistant;
    
    @Autowired
    public ChatController(ChatAssistant assistant) {
        this.assistant = assistant;
    }
    
    @PostMapping
    public ResponseEntity<ChatResponse> chat(@RequestBody ChatRequest request) {
        try {
            String response = assistant.chat(request.getMessage());
            return ResponseEntity.ok(new ChatResponse(response));
        } catch (Exception e) {
            return ResponseEntity.internalServerError()
                .body(new ChatResponse("Error: " + e.getMessage()));
        }
    }
    
    @PostMapping("/stream")
    public ResponseEntity<StreamingResponseBody> streamChat(@RequestBody ChatRequest request) {
        return ResponseEntity.ok(outputStream -> {
            var streamAssistant = streamingAssistant;
            var stream = streamAssistant.streamChat(request.getMessage());
            
            stream.onNext(token -> {
                try {
                    outputStream.write(token.getBytes());
                    outputStream.flush();
                } catch (IOException e) {
                    // Handle write error
                }
            }).start();
        });
    }
}

@Data
class ChatRequest {
    private String message;
}

@Data
class ChatResponse {
    private String response;
}

4. Service with RAG Integration

Scenario: Service layer with document search and retrieval.

@Service
public class KnowledgeBaseService {
    
    private final DocumentAssistant assistant;
    private final EmbeddingStore<TextSegment> embeddingStore;
    private final EmbeddingModel embeddingModel;
    
    @Autowired
    public KnowledgeBaseService(
            DocumentAssistant assistant,
            EmbeddingStore<TextSegment> embeddingStore,
            EmbeddingModel embeddingModel) {
        this.assistant = assistant;
        this.embeddingStore = embeddingStore;
        this.embeddingModel = embeddingModel;
    }
    
    public void ingestDocument(String content, Map<String, Object> metadata) {
        var document = Document.from(content);
        document.metadata().putAll(metadata);
        
        var ingestor = EmbeddingStoreIngestor.builder()
            .embeddingModel(embeddingModel)
            .embeddingStore(embeddingStore)
            .documentSplitter(DocumentSplitters.recursive(500, 50))
            .build();
        
        ingestor.ingest(document);
    }
    
    public String answerQuestion(String question) {
        return assistant.answerAbout(question);
    }
}

interface DocumentAssistant {
    String answerAbout(String question);
}

5. Scheduled Task for Document Updates

Scenario: Periodically update knowledge base.

@Service
public class DocumentUpdateService {
    
    private final EmbeddingStore<TextSegment> embeddingStore;
    private final EmbeddingModel embeddingModel;
    
    @Autowired
    public DocumentUpdateService(
            EmbeddingStore<TextSegment> embeddingStore,
            EmbeddingModel embeddingModel) {
        this.embeddingStore = embeddingStore;
        this.embeddingModel = embeddingModel;
    }
    
    @Scheduled(fixedRate = 86400000)  // Daily
    public void updateDocuments() {
        var documents = fetchLatestDocuments();
        
        var ingestor = EmbeddingStoreIngestor.builder()
            .embeddingModel(embeddingModel)
            .embeddingStore(embeddingStore)
            .build();
        
        documents.forEach(ingestor::ingest);
        logger.info("Documents updated successfully");
    }
    
    private List<Document> fetchLatestDocuments() {
        // Fetch from database or external API
        return Collections.emptyList();
    }
}

6. Controller with Tool Integration

Scenario: AI service with business logic tools.

@Service
public class BusinessLogicService {
    
    @Tool("Get user by ID")
    public User getUser(@P("user ID") String userId) {
        // Implementation
        return new User(userId);
    }
    
    @Tool("Calculate discount")
    public double calculateDiscount(@P("purchase amount") double amount) {
        if (amount > 1000) return 0.15;
        if (amount > 500) return 0.10;
        return 0.05;
    }
}

@Service
public class ToolAssistant {
    
    private final ChatModel chatModel;
    private final BusinessLogicService businessLogic;
    
    @Autowired
    public ToolAssistant(ChatModel chatModel, BusinessLogicService businessLogic) {
        this.chatModel = chatModel;
        this.businessLogic = businessLogic;
    }
    
    public String processRequest(String request) {
        return AiServices.builder(Assistant.class)
            .chatModel(chatModel)
            .tools(businessLogic)
            .build()
            .chat(request);
    }
}

interface Assistant {
    String chat(String message);
}

7. Error Handling with Spring Exception Handler

Scenario: Centralized error handling for AI services.

@ControllerAdvice
public class AiExceptionHandler {
    
    @ExceptionHandler(IllegalArgumentException.class)
    public ResponseEntity<ErrorResponse> handleBadRequest(IllegalArgumentException e) {
        return ResponseEntity.badRequest()
            .body(new ErrorResponse("Invalid input: " + e.getMessage()));
    }
    
    @ExceptionHandler(Exception.class)
    public ResponseEntity<ErrorResponse> handleError(Exception e) {
        logger.error("Error in AI service", e);
        return ResponseEntity.internalServerError()
            .body(new ErrorResponse("An error occurred: " + e.getMessage()));
    }
}

@Data
class ErrorResponse {
    private String message;
}

8. Configuration Properties

Scenario: Externalize AI configuration.

@Configuration
@ConfigurationProperties(prefix = "app.ai")
@Data
public class AiProperties {
    private String openaiApiKey;
    private String openaiModel = "gpt-4o-mini";
    private double temperature = 0.7;
    private int maxTokens = 2000;
    private String embeddingModel = "text-embedding-3-small";
    private int memorySize = 10;
    private String vectorStoreType = "in-memory";
}

// application.yml
app:
  ai:
    openai-api-key: ${OPENAI_API_KEY}
    openai-model: gpt-4o-mini
    temperature: 0.7
    max-tokens: 2000
    embedding-model: text-embedding-3-small
    memory-size: 10
    vector-store-type: pinecone

9. Integration Testing

Scenario: Test AI services with Spring Boot Test.

@SpringBootTest
class ChatServiceTest {
    
    @MockBean
    private ChatModel chatModel;
    
    @Autowired
    private ChatService chatService;
    
    @Test
    void testChat() {
        when(chatModel.chat("Hello"))
            .thenReturn("Hi there!");
        
        String response = chatService.chat("Hello");
        assertEquals("Hi there!", response);
    }
}

10. Async Processing with CompletableFuture

Scenario: Non-blocking AI service calls.

@Service
@EnableAsync
public class AsyncChatService {
    
    private final ChatModel chatModel;
    
    @Autowired
    public AsyncChatService(ChatModel chatModel) {
        this.chatModel = chatModel;
    }
    
    @Async
    public CompletableFuture<String> chatAsync(String message) {
        try {
            String response = chatModel.chat(message);
            return CompletableFuture.completedFuture(response);
        } catch (Exception e) {
            return CompletableFuture.failedFuture(e);
        }
    }
}

// Usage in controller
@RestController
public class AsyncController {
    
    @Autowired
    private AsyncChatService asyncChatService;
    
    @PostMapping("/chat/async")
    public CompletableFuture<ResponseEntity<String>> chatAsync(@RequestBody ChatRequest request) {
        return asyncChatService.chatAsync(request.getMessage())
            .thenApply(ResponseEntity::ok)
            .exceptionally(e -> ResponseEntity.internalServerError().build());
    }
}

Configuration Examples

Maven Dependency

<dependency>
    <groupId>dev.langchain4j</groupId>
    <artifactId>langchain4j-spring-boot-starter</artifactId>
    <version>0.27.0</version>
</dependency>

Gradle

implementation 'dev.langchain4j:langchain4j-spring-boot-starter:0.27.0'

plugins

developer-kit-java

skills

langchain4j-spring-boot-integration

README.md

tile.json