场景

SpringBoot+LangChain4j+Ollama实现Function Calling工具调用-仿智能客服示例:

https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/160409823

在之前的学习中,我们已经掌握了如何使用单个 AiService 构建智能客服、工具调用。

但一个真正的智能系统,往往需要多个 AI 模型或服务协同完成复杂任务。

在 LangChain4j 中,这种将多个 AI 服务“链接”起来形成流水线的技术,

通常被称作服务编排(Orchestration)或链式调用(Chaining)。

它可以分为两种实现思路:

开发者主导的的确定性编排和 AI 主导的自决策模式。

链式调用:AI 服务的流水线

“链”是 LangChain4j 的核心,它将多个操作(如模型调用、知识检索、工具调用)串联成一个完整的流程。

对于 Java 开发者来说,这就像定义一套标准的程序。

“链式调用”的核心思想是为每个任务配备最专业的 AI 服务,并由你作为“总指挥”来定义它们的工作顺序。

AiServices:

这是构建 AI 服务的主要工具,你之前接触的 RAG 服务就是通过它构建的。

ModelRouter(模型路由器):

这是 LangChain4j 中一个专门的组件,它的作用是作为一个智能的“API 网关”,将用户请求动态地路由到最合适的模型。

例如,它可以实现故障转移(Failover)和负载均衡等策略。

Agent & AgenticScope (实验性功能):

这是 LangChain4j 1.0.0-beta4 版本中的一个虚拟概念,旨在让 AI 自主决定如何组织任务。

开发者通过声明的工作流(Flow),AI 可以在大框架内自主决策和调用。

如果你的项目追求极致的灵活性和 AI 自主性,可以关注 langchain4j-agentic 模块的后续发展。

注:

博客:
https://blog.csdn.net/badao_liumang_qizhi

实现

实战示例:打造一个支持多步处理的智能客服工作流

想象这样一个场景:

你的智能客服需要处理各种任务,例如“查询订单状态”。

这个看似简单的任务,实际上可以由多个 AI 服务协作完成。

我们可以定义一个由“意图识别”与“专业服务”串联起的客服流。

1. 项目依赖 (pom.xml 核心部分)

    <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>
        <!-- 核心:用于启用 @AiService 声明式 AI 服务 -->
        <dependency>
            <groupId>dev.langchain4j</groupId>
            <artifactId>langchain4j-spring-boot-starter</artifactId>
        </dependency>
        <!-- 具体模型:用于集成本地 Ollama 服务 -->
        <dependency>
            <groupId>dev.langchain4j</groupId>
            <artifactId>langchain4j-ollama-spring-boot-starter</artifactId>
        </dependency>
    </dependencies>

2. 配置文件 (application.yml)

​
langchain4j:
  ollama:
    chat-model:
      base-url: http://localhost:11434
      model-name: qwen2:7b
      temperature: 0.7
      timeout: PT120S           # 总超时时间 120 秒
      connect-timeout: PT10S    # 连接超时 10 秒
      read-timeout: PT120S      # 读取超时 120 秒
      log-requests: true
      log-responses: true

​

3. 任务类型枚举

public enum CustomerServiceTask {
    CHECK_ORDER,      // 查订单
    APPLY_COUPON,     // 领优惠券
    TALK_TO_HUMAN,    // 转人工
    UNKNOWN
}

4. 意图分类 AI 服务接口

import com.badao.ai.enums.CustomerServiceTask;
import dev.langchain4j.service.SystemMessage;
import dev.langchain4j.service.UserMessage;

public interface IntentClassifier {
    @SystemMessage("""
            你是一个智能客服意图分类器。请将用户的问题归类为以下类型之一,只输出枚举名,不要输出任何其他内容:
            - CHECK_ORDER: 用户想查询订单状态、物流信息。
            - APPLY_COUPON: 用户想领取、查询优惠券。
            - TALK_TO_HUMAN: 用户要求转接人工客服,或表达不满、投诉。
            - UNKNOWN: 其他无关问题。
            示例:
            用户:我的订单123456到了吗? -> CHECK_ORDER
            用户:领张优惠券 -> APPLY_COUPON
            用户:我要投诉!转人工! -> TALK_TO_HUMAN
            """)
    CustomerServiceTask classify(@UserMessage String userMessage);
}

5. 业务服务类(订单服务)

import dev.langchain4j.agent.tool.P;
import dev.langchain4j.agent.tool.Tool;
import org.springframework.stereotype.Component;

@Component
public class OrderService {

    // 模拟订单数据
    @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. 专门处理订单查询的 AI 服务接口

import dev.langchain4j.service.SystemMessage;
import dev.langchain4j.service.UserMessage;

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

注意:

实际调用工具需要在实现中注册,见配置类。

7. Spring 配置类:构建 AI 服务并注册工具

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) {
        // 将 OrderService 中的方法作为工具注入
        return AiServices.builder(OrderAssistant.class)
                .chatModel(chatModel)
                .tools(orderService)   // 注册工具实例
                .build();
    }
}

注意:

需要确保 OrderService 中的方法使用了 @Tool 注解

8. 控制器(Agent 调度器)

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. 意图识别
        CustomerServiceTask task = classifier.classify(message);
        System.out.println("识别意图: " + task);

        // 2. 根据意图调度
        switch (task) {
            case CHECK_ORDER:
                return orderAssistant.chat(message);
            case APPLY_COUPON:
                // 这里可以注入另一个优惠券助手,为了简洁直接模拟
                return "正在为您查询优惠券,请稍后...";
            case TALK_TO_HUMAN:
                return "正在为您转接人工客服,请耐心等待...";
            default:
                return "抱歉,我不太明白您的意思。您可以试试查询订单、领取优惠券或转人工。";
        }
    }
}

9. 测试

启动应用后,使用 curl 测试:

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

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

预期效果

订单查询:调用 orderAssistant,模型会提取订单号并调用 getOrderStatus 工具,返回订单状态。

优惠券领取:走简化分支,返回提示(可扩展专用助手)。

转人工:直接返回转接提示。

关键点总结

意图识别:使用低 temperature 的模型确保分类稳定。

工具注册:通过 .tools(orderService) 将所有 @Tool 方法注册给 AI 服务。

分派策略:Controller 根据枚举结果调用不同的专业 AI 服务或业务逻辑。

扩展性:可以轻松增加更多任务类型和对应的助手服务,符合开闭原则。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐