Spring AI Alibaba builds a flight ticket assistant (practical version)

Written by
Audrey Miles
Updated on:June-27th-2025
Recommendation

Master the Spring AI Alibaba framework and build an efficient air ticket assistant application.

Core content:
1. Spring AI Alibaba project background and advantages
2. Detailed step-by-step guidance: from pulling the project to backend startup
3. pom.xml file interpretation and key configuration parameter description

Yang Fangxian
Founder of 53A/Most Valuable Expert of Tencent Cloud (TVP)
Background: The Spring AI Alibaba open source project is built on Spring AI and is the best practice of Alibaba Cloud Tongyi series models and services in the field of Java AI application development. It provides high-level AI API abstraction and cloud-native infrastructure integration solutions to help developers quickly build AI applications.
Step 1: Pull the project
Spring AI Alibaba official documentation: https://java2ai.com/docs/1.0.0-M5.1/overview/?spm=4347728f.7a696532.0.0.55ca6e97w8zCXV
Since Github requires magic, you can join the technical group to get it.
Step 2: Start
rear end:
front end:
page:
Step 3: Interpretation
pom.xml
<properties> <java.version>17</java.version> <vaadin.version>24.4.7</vaadin.version> <maven-deploy-plugin.version>3.1.1</maven-deploy-plugin.version> <spring-ai-alibaba.version>1.0.0-M6.1</spring-ai-alibaba.version></properties>
The jdk version is no less than 17, the spring-ai-alibaba version is 1.0.0-M6.1, and it is developed based on Spring Boot 3.x.
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webflux</artifactId></dependency>
Based on responsive programming
AssistantConfig
@Configuration@Slf4jpublic  class  AssistantConfig  {    /**     * Flight Assistant     *     *  @param  modelBuilder     *  @param  vectorStore     *  @param  chatMemory     */    @Bean    public  ChatClient  getChatClient (ChatClient.Builder modelBuilder, VectorStore vectorStore, ChatMemory chatMemory)  {        log.info( "Flight Assistant Configuration CustomerSupportAssistant().." );        ChatClient  chatClient  =  modelBuilder                .defaultSystem( """                        	You are a customer chat support agent for the airline "Flight-Booking". Please respond in a friendly, helpful and pleasant manner.                        	You are interacting with customers through a live chat system.                        	You can support the operations of querying the reservation details of existing tickets, changing the ticket date, cancelling the ticket reservation, etc. The remaining functions will be added in subsequent versions. If the questions asked by users are not supported, please inform us of the details.                            Before providing operations such as ticket booking details inquiry, ticket date change, ticket booking cancellation, etc., you must always obtain the following information from the user: booking number, customer name.                            After querying information for users, the content of each field needs to be displayed in separate lines. When displaying the content in separate lines, pay attention to keeping the style consistent. You need to use - separate lines display. Other formats are not acceptable.                            Before asking the user, please check the message history to obtain the booking number, customer name, etc., and try to avoid repeated inquiries that may cause trouble to the user.                            Before changing your booking, you must ensure that the terms allow you to do so.                            If the change requires a fee, you must obtain the user's consent before proceeding.                            Use the provided functions to get booking details, change bookings, and cancel bookings.                            If necessary, you can call the corresponding function to assist in completion.                            Please speak Chinese.                            Today's date is {current_date}.                        """)                .defaultAdvisors(                        // Session memory                        new  PromptChatMemoryAdvisor (chatMemory),
                        // Storage, based on RAG                        new  QuestionAnswerAdvisor (vectorStore, SearchRequest.builder().topK( 4 ).similarityThresholdAll().build()),
                        // logger log printing                        new  SimpleLoggerAdvisor ()                )                .defaultFunctions(                        "getBookingDetails" ,                        "changeBooking" ,                        "cancelBooking"                )                .build();        return  chatClient;    }
    @Bean    CommandLineRunner  ingestTermOfServiceToVectorStore (EmbeddingModel embeddingModel, VectorStore vectorStore,                                                       @Value("classpath:rag/terms-of-service.txt")  Resource termsOfServiceDocs) {        log.info( "Vector data storage.." );        return  args -> {            // Ingest the document into the vector store            vectorStore.write( new  TokenTextSplitter ().transform( new  TextReader (termsOfServiceDocs).read()));
            vectorStore.similaritySearch( "Canceling Bookings" ).forEach(doc -> {                log.info( "Similar Document: {}" , doc.getText());            });        };    }
    @Bean    public  VectorStore  vectorStore (EmbeddingModel embeddingModel)  {        log.info( "vectorStore initialized.." );        return  SimpleVectorStore.builder(embeddingModel).build();    }
    @Bean    public  ChatMemory  chatMemory ()  {        log.info( "chatMemory().." );        return  new  InMemoryChatMemory ();    }
    @Bean    @ConditionalOnMissingBean    public  RestClient.Builder  restClientBuilder ()  {        log.info( "restClientBuilder().." );        return  RestClient.builder();    }}
This configuration configures the system role before using chatClient. Based on the RAG mode, it feeds the big model ticket assistant with the rules it should have. ChatMemory enables it to have chat memory function, and Function Calling supports function calling.
AssistantController
@RequestMapping(path = "/chat", produces = MediaType.TEXT_EVENT_STREAM_VALUE)public Flux<String> chat(String chatId, String userMessage) { return assistantService.chat(chatId, userMessage);}
This section is based on streaming answers. ChatId marks a conversation. This demonstration project is for connecting to a database. All data is temporary. You can create a table to store conversations and message records based on business needs.
AssistantServiceImpl
     /** * User conversation * * @param chatId * @param userMessageContent * @return */ public Flux<String> chat(String chatId, String userMessageContent) { log.info("User conversation ID: {}", chatId); return this.chatClient.prompt() .system(s -> s.param("current_date", LocalDate.now().toString())) .user(userMessageContent) .advisors(a -> a.param(CHAT_MEMORY_CONVERSATION_ID_KEY, chatId).param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 100)) .stream() .content(); }
Note: current_date is passed as a parameter. Careful friends will notice that this parameter is included in the prompt of AssistantConfig. You can pass it according to your needs, such as controlling user permissions.
BookingTools[Core]
@Bean@Description("Get flight booking details")public Function<BookingDetailsRequest, BookingDetails> getBookingDetails() { log.info("Get flight booking details 1..");return request -> { log.info("Get flight booking details 2..");try {return flightBookingService.getBookingDetails(request.bookingNumber(), request.name()); } catch (Exception e) { logger.warn("Booking details: {}", NestedExceptionUtils.getMostSpecificCause(e).getMessage());return new BookingDetails(request.bookingNumber(), request.name(), null, null, null, null, null); } };}
public record BookingDetailsRequest(String bookingNumber, String name) {}
Take the "Get Ticket Information" function as an example, and the same goes for other functions; the BookingTools class adds the Configuration annotation, which means that it will be initialized when the project starts. If you focus on business, the @Service annotation can also be implemented!
The request body record is available in jdk17, which simplifies the creation of entity classes. The parameter bookingNumber is the booking number, and name is the user name.
You can use the MCP function to rewrite the code based on annotations such as @Tool to implement the function.
Step 4: Use
So far, we have built a smart ticket assistant using Spring AI Alibaba. However, when applied to actual needs, the large model always makes mistakes when processing the time [hours, minutes, seconds] provided by users. We welcome everyone to provide solutions!