Spring Boot, LangChain4j & Ollama: Chain for Intent Recognition and Task Dispatch

The article demonstrates how to construct a Spring Boot application that orchestrates multiple AI services using LangChain4j and Ollama, defining intent‑classification and tool‑based assistants, registering them as beans, and routing user requests through a controller to achieve multi‑step intent recognition and task dispatch in a simulated intelligent customer‑service workflow.

The Dominant Programmer
The Dominant Programmer
The Dominant Programmer
Spring Boot, LangChain4j & Ollama: Chain for Intent Recognition and Task Dispatch

In this tutorial the author shows how to build a Spring Boot project that chains several AI services with LangChain4j and Ollama to emulate an intelligent customer‑service system. The author first explains that real‑world AI systems often require multiple models or services working together, and that LangChain4j calls this "service orchestration" or "chaining". Two implementation philosophies are described: a developer‑driven deterministic orchestration and an AI‑driven self‑decision mode.

Core concepts

The "chain" is the central abstraction in LangChain4j; it links operations such as model calls, knowledge retrieval, and tool invocation into a single workflow. For Java developers it resembles defining a standard program where each task is assigned the most suitable AI service, and the developer acts as the overall commander.

Key components introduced are:

AiServices : the primary builder for AI services; the author previously used it to create a RAG service.

ModelRouter : a LangChain4j component that works like an intelligent API gateway, dynamically routing requests to the best model and supporting failover and load‑balancing strategies.

Agent & AgenticScope (experimental in version 1.0.0‑beta4): a virtual concept that lets the AI decide how to organise tasks via a declared workflow (Flow). The author notes that projects seeking maximal flexibility can follow the upcoming langchain4j‑agentic module.

Implementation steps

1. Maven dependencies (pom.xml core part)

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.2.5</version>
</parent>
<groupId>com.example</groupId>
<artifactId>spring-langchain4j-ollama-tool-chain</artifactId>
<version>1.0</version>
<properties>
    <java.version>17</java.version>
    <langchain4j.version>1.0.1</langchain4j.version>
</properties>
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>dev.langchain4j</groupId>
            <artifactId>langchain4j-bom</artifactId>
            <version>${langchain4j.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- Enable @AiService declarative AI services -->
    <dependency>
        <groupId>dev.langchain4j</groupId>
        <artifactId>langchain4j-spring-boot-starter</artifactId>
    </dependency>
    <!-- Integrate local Ollama model -->
    <dependency>
        <groupId>dev.langchain4j</groupId>
        <artifactId>langchain4j-ollama-spring-boot-starter</artifactId>
    </dependency>
</dependencies>

2. Configuration file (application.yml)

langchain4j:
  ollama:
    chat-model:
      base-url: http://localhost:11434
      model-name: qwen2:7b
      temperature: 0.7
      timeout: PT120S          # total timeout 120 seconds
      connect-timeout: PT10S   # connection timeout 10 seconds
      read-timeout: PT120S     # read timeout 120 seconds
      log-requests: true
      log-responses: true

3. Task‑type enum

public enum CustomerServiceTask {
    CHECK_ORDER,      // query order status
    APPLY_COUPON,    // claim coupon
    TALK_TO_HUMAN,   // hand over to human agent
    UNKNOWN
}

4. Intent‑classification AI service interface

import com.badao.ai.enums.CustomerServiceTask;
import dev.langchain4j.service.SystemMessage;
import dev.langchain4j.service.UserMessage;
public interface IntentClassifier {
    @SystemMessage("""
            You are an intelligent customer‑service intent classifier. Classify the user question into one of the following enum values and output only the enum name:
            - CHECK_ORDER: user wants to query order status or logistics.
            - APPLY_COUPON: user wants to claim or query a coupon.
            - TALK_TO_HUMAN: user requests a human agent or complains.
            - UNKNOWN: other unrelated questions.
            Examples:
            User: 我的订单123456到了吗? -> CHECK_ORDER
            User: 领张优惠券 -> APPLY_COUPON
            User: 我要投诉!转人工! -> TALK_TO_HUMAN
            """)
    CustomerServiceTask classify(@UserMessage String userMessage);
}

5. Business service class (order service) with @Tool methods

import dev.langchain4j.agent.tool.P;
import dev.langchain4j.agent.tool.Tool;
import org.springframework.stereotype.Component;
@Component
public class OrderService {
    // Simulated order data
    @Tool("根据订单号查询订单状态")
    public String getOrderStatus(@P("订单号,例如 123456") String orderId) {
        return "订单 " + orderId + " 当前状态:已发货,物流单号 SF123456789";
    }
    @Tool("根据用户ID查询可用优惠券")
    public String getCoupon(@P("用户ID") String userId) {
        return "用户 " + userId + " 当前可用优惠券:满100减10元券一张";
    }
}

6. Dedicated AI service for order queries

import dev.langchain4j.service.SystemMessage;
import dev.langchain4j.service.UserMessage;
public interface OrderAssistant {
    @SystemMessage("你是订单助手。根据用户输入提取订单号,调用 getOrderStatus 工具查询状态。如果用户没有提供订单号,请询问。")
    String chat(@UserMessage String userMessage);
}

7. Spring configuration class that builds the AI services and registers tools

import com.badao.ai.service.IntentClassifier;
import com.badao.ai.service.OrderAssistant;
import com.badao.ai.service.OrderService;
import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.service.AiServices;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AiServiceConfig {
    @Bean
    public IntentClassifier intentClassifier(ChatModel chatModel) {
        return AiServices.builder(IntentClassifier.class)
                .chatModel(chatModel)
                .build();
    }
    @Bean
    public OrderAssistant orderAssistant(ChatModel chatModel, OrderService orderService) {
        // Register OrderService methods as tools
        return AiServices.builder(OrderAssistant.class)
                .chatModel(chatModel)
                .tools(orderService)
                .build();
    }
}

8. Controller (Agent dispatcher)

import com.badao.ai.service.IntentClassifier;
import com.badao.ai.enums.CustomerServiceTask;
import com.badao.ai.service.OrderAssistant;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class CustomerServiceController {
    private final IntentClassifier classifier;
    private final OrderAssistant orderAssistant;
    public CustomerServiceController(IntentClassifier classifier, OrderAssistant orderAssistant) {
        this.classifier = classifier;
        this.orderAssistant = orderAssistant;
    }
    @GetMapping("/customer/chat")
    public String chat(@RequestParam("message") String message) {
        // 1. Intent recognition
        CustomerServiceTask task = classifier.classify(message);
        System.out.println("识别意图: " + task);
        // 2. Dispatch based on intent
        switch (task) {
            case CHECK_ORDER:
                return orderAssistant.chat(message);
            case APPLY_COUPON:
                // Simplified branch; could inject a dedicated coupon assistant
                return "正在为您查询优惠券,请稍后...";
            case TALK_TO_HUMAN:
                return "正在为您转接人工客服,请耐心等待...";
            default:
                return "抱歉,我不太明白您的意思。您可以试试查询订单、领取优惠券或转人工。";
        }
    }
}

9. Testing the workflow

After starting the application, the author uses curl to verify each scenario:

# Query order
curl "http://localhost:885/customer/chat?message= 我的订单123456现在什么状态?"

# Claim coupon
curl "http://localhost:885/customer/chat?message= 我想领一张优惠券"

Expected results:

Order query : the orderAssistant extracts the order number, calls getOrderStatus, and returns the simulated status.

Coupon claim : a simplified branch returns a placeholder message (can be extended with a dedicated assistant).

Human hand‑off : returns a hand‑off prompt.

Key takeaways

Intent classification uses a low‑temperature model to keep predictions stable.

Tool registration is performed via .tools(orderService), exposing all @Tool methods to the AI service.

The controller dispatches to different assistants based on the enum result, illustrating a clear separation of concerns.

The architecture is easily extensible: new task types and corresponding assistants can be added without modifying existing code, adhering to the open‑closed principle.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

spring-bootTool CallingIntent ClassificationOllamaLangChain4jAI orchestration
The Dominant Programmer
Written by

The Dominant Programmer

Resources and tutorials for programmers' advanced learning journey. Advanced tracks in Java, Python, and C#. Blog: https://blog.csdn.net/badao_liumang_qizhi

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.