掘金 人工智能 10小时前
Spring AI 实战:深度解析“路由工作流模式”,构建可扩展的 AI Agent
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

本文介绍了Spring AI中的路由工作流模式,通过一个电商客服的示例,展示了如何利用大模型智能分类和分发用户请求。该模式通过智能总机的方式,将用户请求路由到合适的"专家"处理,从而提升响应质量和可扩展性。文章详细阐述了路由工作流的定义、应用场景、实现步骤,以及关键代码的解析,帮助读者快速上手,构建智能客服应用。

💡 路由工作流模式的核心在于:它就像一个智能总机,能够利用大模型分析用户请求,并将其精准地分发给最合适的"专家"处理。

💡 实现路由工作流的步骤包括:接收用户输入,LLM分析并决定路由,然后将请求交给专属模块处理,最终生成答复。

💡 路由工作流模式适用于用户请求可清晰分类、避免复杂“万能提示词”以及需要调用不同后端功能或API的场景。

💡 在电商客服案例中,通过定义数据传输对象(DTO)、实现路由工作流核心逻辑、创建Service类,完成了整个应用的构建。

💡 SupportRoutingWorkflow是核心组件,它通过两次LLM调用分别进行路由决策和生成最终回复,并利用supportRoutes Map存储不同"专家"的人设和指令。

今天咱们继续聊 Spring AI 的智能体工作流(Agentic Workflow)系列--路由工作流模式(Routing Workflow Pattern) ,并通过一个电商客服的示例带大家快速上手,看看如何利用它来智能地分类和分发用户请求。

对 Spring AI 其他工作流模式感兴趣的朋友,可以翻翻我之前的文章:

什么是路由工作流模式?

简单来说,路由工作流就像一个智能总机,它利用大模型(LLM)先分析收到的请求(比如用户是想查订单、问产品还是想退货),然后精准地把它转给最懂这个问题的“专家”去处理。

整个流程大致是:

接收用户输入 → LLM分析并决定路由 → 交给专属模块处理 → 生成最终答复

在我们的应用程序中,使用路由工作流模式的好处在于:

什么时候使用它

我总结了几个典型的场景,如果你遇到了,不妨试试路由模式:

案例实践:电商客户支持

光说不练假把式,我们来动手搭一个简单的电商客服应用,看看路由工作流是怎么跑起来的。 这是项目的基本结构,非常标准的 Spring Boot 项目:

spring-ai-routing-workflow├── src│   └── main│       ├── java│       │   └── com│       │       └──autogenerator  │       │               ├── controller│       │               │   └── CustomerSupportController.java│       │               ├── service│       │               │   └── CustomerSupportService.java│       │               ├── workflow│       │               │   └── SupportRoutingWorkflow.java│       │               ├── dto│       │               │   └── InquiryRequest.java│       │               │   └── SupportResponse.java│       │               │   └── RouteClassification.java│       │               ├── SpringAiRoutingWorkflowApplication.java│       └── resources│           └── application.yml└── pom.xml

在这里,我对整个项目的目录结构做一个简要的说明:

第 1 步:Maven 依赖和配置
项目的技术栈是 JDK17 + Spring Boot 3.5 + Spring AI 1.0,大模型我用的是 Google 的 gemini-1.5-flash。关于 Maven 依赖和 application.yml 的具体配置,可以参考我之前写 Chain工作流模式 那篇文章,这里就不重复了。

第 2 步:定义数据传输对象 (DTO)

写业务逻辑前,先把数据结构定好。我这里用了 Java 的 Record,代码简洁,而且数据不可变,很省心。 这个 RouteClassification 就是用来接收 LLM 路由决策结果的。

// 代表LLM做出的路由决策,包括选了哪条路由,以及为什么这么选public record RouteClassification(        String reasoning, // 决策理由        String selectedRoute // 选定的路由名) {}

第 3 步:实现路由工作流

SupportRoutingWorkflow是我们这个模式的核心。它的工作分为两步:第一次调用 LLM 做“路由决策”,第二次调用 LLM 用“专属提示”生成最终回复。

@Componentpublic class SupportRoutingWorkflow {    private final ChatClient chatClient;    // 定义并初始化专属提示的 Map    private final Map<StringString> supportRoutes = getSupportRoutes();    public SupportRoutingWorkflow(ChatClient.Builder chatClientBuilder) {        this.chatClient = chatClientBuilder.build();    }    /**     * 将客户咨询路由给最合适的支持专家。     * 该方法首先分析咨询内容,确定最佳路由,     * 然后使用该路由的专属提示来处理它。     */    public String routeCustomerInquiry(String customerInquiry) {        Assert.hasText(customerInquiry, "Customer inquiry cannot be empty");        // 步骤 1: 确定合适的路由        String selectedRoute = classifyInquiry(customerInquiry, supportRoutes.keySet());        // 步骤 2: 获取所选路由的专属提示        String specializedPrompt = supportRoutes.get(selectedRoute);        if (specializedPrompt == null) {            throw new IllegalArgumentException("Route '" + selectedRoute + "' not found in available routes");        }        // 步骤 3: 使用专属提示处理咨询        return chatClient.prompt()                .user(specializedPrompt + "\n\nCustomer Inquiry: " + customerInquiry)                .call()                .content();    }    /**     * 分析客户咨询并确定最合适的支持路由。     * 使用 LLM 理解上下文并对咨询类型进行分类。     */    private String classifyInquiry(String inquiry, Iterable<String> availableRoutes) {        String classificationPrompt = constructPrompt(inquiry, availableRoutes);        RouteClassification classification = chatClient.prompt()                .user(classificationPrompt)                .call()                .entity(RouteClassification.class);        System.out.println("Routing Decision: " + classification.reasoning());        System.out.println("Selected Route: " + classification.selectedRoute());        return classification.selectedRoute();    }    /**     * 构建一个分类提示,以帮助 LLM 决定哪个支持团队     * 应该处理给定的客户咨询。     */    private String constructPrompt(String inquiry, Iterable<String> availableRoutes) {        return String.format("""                You are a customer support routing system. Analyze the customer inquiry and determine                 which support team should handle it from these options: %s                                Consider:                - Keywords and phrases in the inquiry                - The customer's intent and urgency level                - The type of problem or question being asked                                Respond in JSON format:                {                    "reasoning": "Brief explanation of why this inquiry should go to this team",                    "selectedRoute": "The exact team name from the available options"                }                                Customer Inquiry: %s                """, availableRoutes, inquiry);    }    /**     * 初始化并返回支持路由的提示。     */    private Map<StringStringgetSupportRoutes() {        return Map.of(                "order_support",                """                        You are an Order Support Specialist for an e-commerce platform. Your expertise includes:                        - Order tracking and status updates                        - Shipping and delivery issues                        - Order modifications and cancellations                        - Return and refund processing                                                Guidelines:                        1. Always start with "Order Support Team:"                        2. Be empathetic and understanding about delivery concerns                        3. Provide specific next steps with realistic timelines                        4. Include order tracking information when relevant                        5. Offer proactive solutions for common shipping issues                                                Maintain a helpful and professional tone while focusing on order-related solutions.                        """,                "product_support",                """                        You are a Product Support Specialist with deep knowledge of our product catalog. Your expertise includes:                        - Product specifications and features                        - Compatibility and sizing questions                        - Usage instructions and best practices                        - Product recommendations and alternatives                                                Guidelines:                        1. Always start with "Product Support Team:"                        2. Provide detailed, accurate product information                        3. Include specific examples and use cases                        4. Suggest complementary products when appropriate                        5. Focus on helping customers make informed decisions                                                Be knowledgeable and educational while maintaining enthusiasm for our products.                        """,                "technical_support",                """                        You are a Technical Support Engineer specializing in e-commerce platform issues. Your expertise includes:                        - Website and app functionality problems                        - Account access and login issues                        - Payment processing difficulties                        - System errors and troubleshooting                                                Guidelines:                        1. Always start with "Technical Support Team:"                        2. Provide step-by-step troubleshooting instructions                        3. Include system requirements and compatibility notes                        4. Offer alternative solutions for common problems                        5. Know when to escalate complex technical issues                                                Use clear, technical language while remaining accessible to non-technical users.                        """,                "billing_support",                """                        You are a Billing Support Specialist handling all payment and financial inquiries. Your expertise includes:                        - Payment processing and billing questions                        - Refund and credit requests                        - Subscription and recurring payment management                        - Invoice and receipt issues                                                Guidelines:                        1. Always start with "Billing Support Team:"                        2. Be transparent about charges and fees                        3. Explain billing processes clearly                        4. Provide specific timelines for refunds and credits                        5. Ensure security when discussing financial information                                                Maintain professionalism while being sensitive to financial concerns.                        """        );    }}

代码的关键点:
两次LLM调用:一次是 classifyInquiry 用于决策,一次是 routeCustomerInquiry 的结尾用于生成最终回复。这是路由模式的精髓。
supportRoutes Map:这里存放了每个“专家”的人设和指令(System Prompt)。LLM 路由到哪个专家,我们就给它加载哪套“人设”。

第 4 步:创建 Service 类

接下来创建一个 Service 类,负责将客户的咨询请求委派给路由工作流进行处理。

@Servicepublic class CustomerSupportService {    private final SupportRoutingWorkflow routingWorkflow;    public CustomerSupportService(SupportRoutingWorkflow routingWorkflow) {        this.routingWorkflow = routingWorkflow;    }    /**     * 通过将客户支持咨询路由给合适的专家来处理它。     * 根据咨询类型返回一个专门的响应。     */    public String handleCustomerInquiry(String inquiry) {        return routingWorkflow.routeCustomerInquiry(inquiry);    }}

第 5 步:创建 Controller

现在,我们来创建一个 REST Controller,用它来接收客户的支持咨询,并通过我们的 Service 类返回经过路由和专属处理的答复。其中,InquiryRequest 字段表示客户端发送过来的咨询,SupportResponse 表示专属支持团队返回给客户端的响应文本。

@RestController@RequestMapping("/api/support")public class CustomerSupportController {    private final CustomerSupportService supportService;    public CustomerSupportController(CustomerSupportService supportService) {        this.supportService = supportService;    }    /**     * 用于处理客户支持咨询的端点。     * 系统将自动将咨询路由到合适的支持团队。     */    @PostMapping("/inquiry")    public ResponseEntity<SupportResponsehandleInquiry(@RequestBody InquiryRequest request) {        String response = supportService.handleCustomerInquiry(request.inquiry());        return ResponseEntity.ok(new SupportResponse(response));    }}

第 6 步:应用入口点

最后定义启动 Spring Boot 应用的主类, 用于Spring boot初始化所有组件,并启动内嵌的Tomcat容器。

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

电商客户支持路由工作流是如何运作的?

在这里,我画了一个时序图来解释具体的运作流程。

让我们一步步来看,当收到一个客户咨询时,到底发生了什么:

    发起请求: 客户端向 /api/support/inquiry 发送一个包含客户咨询的 POST 请求。Controller 处理: Controller 接收到请求,提取出咨询文本,并将其转发给 Service 层。Service 协调: CustomerSupportService 调用 SupportRoutingWorkflow 来处理该咨询。咨询分类: 工作流调用 LLM 分析咨询内容,并根据内容判断出最合适的支持团队。选择专属提示: 从预先定义好的路由中,检索出所选团队对应的System prompt。LLM 生成答复: 将咨询内容与专属提示结合发送给 LLM,生成相应的答复。返回响应: 依次通过 Service 和 Controller 返回给客户端,作为最终的支持回复。

现在,我使用浏览器中的http调试工具,用几种不同类型的客户咨询来进行测试:

示例 1: 与订单相关的咨询

发一个关于订单状态的请求,可以看到,系统正确地路由到了 order_support。

示例 2: 关于产品的问题

换一个关于产品兼容性的问题,路由又准确地指向了 product_support。

image

踩坑指南与建议

在实践中,有几个关键点需要注意,可以帮你少走弯路:

    路由提示是关键 :路由器的提示词(Prompt)质量直接决定了系统的“智商”。一定要写清楚,最好给几个例子(few-shot),并强制要求它按指定格式(如JSON)输出。路由的覆盖范围:确保你定义的路由能覆盖绝大多数用户问题。最好加一个“兜底”的路由(比如 general_inquiry),处理那些分不出来的疑难杂症。分类的准确性:上线后要多观察路由的准确性,如果发现经常分错类,就要及时调整路由提示。专家提示词维护:每个专属路由的提示词也需要根据业务变化和用户反馈不断优化引入置信度:在更复杂的系统中,可以让路由 LLM 在返回选择的同时,给出一个置信度分数。分数太低时,可以转人工或者让用户把问题说得更清楚些。

写在最后

Spring AI 路由工作流模式让我们能够很容易的构建通过专属处理来应对多样化输入的智能、可扩展的应用。文章中的电商客服支持应用只是作为一个简单的示例,便于大家理解路由工作流模式。

在实际场景中,我们可以通过集成订单系统、客服知识库RAG 以及在不同的路由模块中混合使用Spring AI Workflow的多种工作流(如链式工作流或并行任务)来处理更复杂的业务流程。

希望今天的分享对你有帮助!接下来我会继续探索Spring AI的其他玩法,欢迎在评论区一起交流讨论!

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

Spring AI 路由工作流 电商客服 大模型
相关文章