diff --git a/spring-ai-alibaba-examples/README-zh.md b/spring-ai-alibaba-examples/README-zh.md new file mode 100644 index 0000000..0a5d20f --- /dev/null +++ b/spring-ai-alibaba-examples/README-zh.md @@ -0,0 +1,14 @@ +## Spring AI Alibaba Example + +该目录包含演示 Spring AI Alibaba 的基本和高级用法的示例。 + +这里的所有示例都被设计为独立的 maven 项目,可以独立复制和导入。因此建议将整个示例目录或每个特定示例子目录作为单独的 Maven 项目导入, +以体验 Spring AI Alibaba 开发框架的能力。 + +* Client API 示例:此 Example 主要演示使用 Client API(高级 API) 调用模型; +* Model API 示例:此 Example 主要演示使用 Model API(低级 API) 调用模型; +* 函数调用示例:此 Example 主要演示如何使用 Function Calling 增强 LLM 能力; +* 结构化输出示例:此 Example 主要演示如何使用 Structured Output ,将 LLM 输出转为 Java Bean; +* Prompt 示例:此 Example 主要演示如何使用 Prompt Template 构建动态 Prompt 等,其他 Prompt 用法; +* RAG 示例:此 Example 演示 RAG(检索增强)应用的构建示例。 +* Flight Booking Playground:一个高级示例,同时展示了 Prompt 模板、Function Calling、Chat Memory 和 RAG 的使用。 diff --git a/spring-ai-alibaba-examples/README.md b/spring-ai-alibaba-examples/README.md index ef9129e..c9d95d2 100644 --- a/spring-ai-alibaba-examples/README.md +++ b/spring-ai-alibaba-examples/README.md @@ -1,11 +1,14 @@ -This directory contains examples demonstrating basic and advanced usages of Spring AI Alibaba. +## Spring AI Alibaba Example -All the examples here are designed to be independent maven projects that can be copied and imported independently. So it's recommended to import the whole example directory or each specific example sub-directory as a separate maven project. +This directory contains examples that demonstrate basic and advanced usage of Spring AI Alibaba. -* Hello World -* Chat Model -* Function Calling -* Structured Output -* Prompt -* RAG -* Flight Booking Playground, an advanced example showcasing usage of prompt template, function calling, chat memory and rag at the same time. \ No newline at end of file +All examples here are designed as independent Maven projects that can be copied and imported independently. Therefore, it is recommended to import the entire example directory or each specific example subdirectory as a separate Maven project, +to experience the capabilities of the Spring AI Alibaba development framework. + +* Client API Example: This Example mainly demonstrates the use of Client API (advanced API) to call the model; +* Model API Example: This Example mainly demonstrates the use of Model API (low-level API) to call the model; +* Function Calling Example: This Example mainly demonstrates how to use Function Calling to enhance LLM capabilities; +* Structured Output Example: This Example mainly demonstrates how to use Structured Output to convert LLM output to Java Bean; +* Prompt Example: This Example mainly demonstrates how to use Prompt Template to build dynamic Prompt, etc., and other Prompt usage; +* RAG Example: This Example demonstrates the construction example of RAG (retrieval enhancement) application. +* Flight Booking Playground: An advanced example that also demonstrates the use of Prompt templates, Function Calling, Chat Memory, and RAG. diff --git a/spring-ai-alibaba-examples/helloworld-example/pom.xml b/spring-ai-alibaba-examples/client-api-example/pom.xml similarity index 97% rename from spring-ai-alibaba-examples/helloworld-example/pom.xml rename to spring-ai-alibaba-examples/client-api-example/pom.xml index 0b39213..dfb64ba 100644 --- a/spring-ai-alibaba-examples/helloworld-example/pom.xml +++ b/spring-ai-alibaba-examples/client-api-example/pom.xml @@ -9,7 +9,7 @@ com.alibaba.cloud.ai - helloworld-example + client-api-example 0.0.1-SNAPSHOT helloworld-example Demo project for Spring AI Alibaba diff --git a/spring-ai-alibaba-examples/helloworld-example/src/main/java/com/alibaba/cloud/ai/example/helloworld/ChatController.java b/spring-ai-alibaba-examples/client-api-example/src/main/java/com/alibaba/cloud/ai/example/helloworld/ChatController.java similarity index 100% rename from spring-ai-alibaba-examples/helloworld-example/src/main/java/com/alibaba/cloud/ai/example/helloworld/ChatController.java rename to spring-ai-alibaba-examples/client-api-example/src/main/java/com/alibaba/cloud/ai/example/helloworld/ChatController.java diff --git a/spring-ai-alibaba-examples/helloworld-example/src/main/java/com/alibaba/cloud/ai/example/helloworld/HelloWorldExampleApplication.java b/spring-ai-alibaba-examples/client-api-example/src/main/java/com/alibaba/cloud/ai/example/helloworld/HelloWorldExampleApplication.java similarity index 100% rename from spring-ai-alibaba-examples/helloworld-example/src/main/java/com/alibaba/cloud/ai/example/helloworld/HelloWorldExampleApplication.java rename to spring-ai-alibaba-examples/client-api-example/src/main/java/com/alibaba/cloud/ai/example/helloworld/HelloWorldExampleApplication.java diff --git a/spring-ai-alibaba-examples/helloworld-example/src/main/resources/application.yml b/spring-ai-alibaba-examples/client-api-example/src/main/resources/application.yml similarity index 100% rename from spring-ai-alibaba-examples/helloworld-example/src/main/resources/application.yml rename to spring-ai-alibaba-examples/client-api-example/src/main/resources/application.yml diff --git a/spring-ai-alibaba-examples/chatmodel-example/pom.xml b/spring-ai-alibaba-examples/module-api-example/pom.xml similarity index 96% rename from spring-ai-alibaba-examples/chatmodel-example/pom.xml rename to spring-ai-alibaba-examples/module-api-example/pom.xml index feef24a..287e257 100644 --- a/spring-ai-alibaba-examples/chatmodel-example/pom.xml +++ b/spring-ai-alibaba-examples/module-api-example/pom.xml @@ -2,14 +2,15 @@ 4.0.0 + org.springframework.boot spring-boot-starter-parent 3.3.3 - com.alibaba.cloud.ai - chatmodel-example + + module-api-example 0.0.1-SNAPSHOT chatmodel-example Demo project for Spring AI Alibaba diff --git a/spring-ai-alibaba-examples/chatmodel-example/src/main/java/com/alibaba/cloud/ai/example/model/AudioModelController.java b/spring-ai-alibaba-examples/module-api-example/src/main/java/com/alibaba/cloud/ai/example/model/AudioModelController.java similarity index 100% rename from spring-ai-alibaba-examples/chatmodel-example/src/main/java/com/alibaba/cloud/ai/example/model/AudioModelController.java rename to spring-ai-alibaba-examples/module-api-example/src/main/java/com/alibaba/cloud/ai/example/model/AudioModelController.java diff --git a/spring-ai-alibaba-examples/chatmodel-example/src/main/java/com/alibaba/cloud/ai/example/model/ChatModelController.java b/spring-ai-alibaba-examples/module-api-example/src/main/java/com/alibaba/cloud/ai/example/model/ChatModelController.java similarity index 100% rename from spring-ai-alibaba-examples/chatmodel-example/src/main/java/com/alibaba/cloud/ai/example/model/ChatModelController.java rename to spring-ai-alibaba-examples/module-api-example/src/main/java/com/alibaba/cloud/ai/example/model/ChatModelController.java diff --git a/spring-ai-alibaba-examples/chatmodel-example/src/main/java/com/alibaba/cloud/ai/example/model/ChatModelExampleApplication.java b/spring-ai-alibaba-examples/module-api-example/src/main/java/com/alibaba/cloud/ai/example/model/ChatModelExampleApplication.java similarity index 100% rename from spring-ai-alibaba-examples/chatmodel-example/src/main/java/com/alibaba/cloud/ai/example/model/ChatModelExampleApplication.java rename to spring-ai-alibaba-examples/module-api-example/src/main/java/com/alibaba/cloud/ai/example/model/ChatModelExampleApplication.java diff --git a/spring-ai-alibaba-examples/chatmodel-example/src/main/java/com/alibaba/cloud/ai/example/model/ImageModelController.java b/spring-ai-alibaba-examples/module-api-example/src/main/java/com/alibaba/cloud/ai/example/model/ImageModelController.java similarity index 100% rename from spring-ai-alibaba-examples/chatmodel-example/src/main/java/com/alibaba/cloud/ai/example/model/ImageModelController.java rename to spring-ai-alibaba-examples/module-api-example/src/main/java/com/alibaba/cloud/ai/example/model/ImageModelController.java diff --git a/spring-ai-alibaba-examples/chatmodel-example/src/main/resources/application.yml b/spring-ai-alibaba-examples/module-api-example/src/main/resources/application.yml similarity index 100% rename from spring-ai-alibaba-examples/chatmodel-example/src/main/resources/application.yml rename to spring-ai-alibaba-examples/module-api-example/src/main/resources/application.yml diff --git a/spring-ai-alibaba-examples/pom.xml b/spring-ai-alibaba-examples/pom.xml index 2de1a38..8d26b1c 100644 --- a/spring-ai-alibaba-examples/pom.xml +++ b/spring-ai-alibaba-examples/pom.xml @@ -15,13 +15,14 @@ - helloworld-example - chatmodel-example + client-api-example + module-api-example prompt-example function-calling-example rag-example output-parser-example playground-flight-booking + usercase-example diff --git a/spring-ai-alibaba-examples/usercase-example/generate-sql-queries/pom.xml b/spring-ai-alibaba-examples/usercase-example/generate-sql-queries/pom.xml new file mode 100644 index 0000000..8ce20d9 --- /dev/null +++ b/spring-ai-alibaba-examples/usercase-example/generate-sql-queries/pom.xml @@ -0,0 +1,80 @@ + + + 4.0.0 + + + org.springframework.boot + spring-boot-starter-parent + 3.3.3 + + + + Generate SQL Queries + generate-sql-queries + + + UTF-8 + UTF-8 + 17 + 17 + 3.1.1 + + + 1.0.0-M2 + + + + + com.alibaba.cloud.ai + spring-ai-alibaba-starter + ${spring-ai-alibaba.version} + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-jdbc + + + + com.h2database + h2 + runtime + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + org.apache.maven.plugins + maven-deploy-plugin + ${maven-deploy-plugin.version} + + true + + + + + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + + + diff --git a/spring-ai-alibaba-examples/usercase-example/generate-sql-queries/src/main/java/com/alibaba/cloud/ai/sql/AIApplication.java b/spring-ai-alibaba-examples/usercase-example/generate-sql-queries/src/main/java/com/alibaba/cloud/ai/sql/AIApplication.java new file mode 100644 index 0000000..2f0ddc5 --- /dev/null +++ b/spring-ai-alibaba-examples/usercase-example/generate-sql-queries/src/main/java/com/alibaba/cloud/ai/sql/AIApplication.java @@ -0,0 +1,13 @@ +package com.alibaba.cloud.ai.sql; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class AIApplication { + + public static void main(String[] args) { + + SpringApplication.run(AIApplication.class, args); + } +} diff --git a/spring-ai-alibaba-examples/usercase-example/generate-sql-queries/src/main/java/com/alibaba/cloud/ai/sql/controller/SQLController.java b/spring-ai-alibaba-examples/usercase-example/generate-sql-queries/src/main/java/com/alibaba/cloud/ai/sql/controller/SQLController.java new file mode 100644 index 0000000..7521446 --- /dev/null +++ b/spring-ai-alibaba-examples/usercase-example/generate-sql-queries/src/main/java/com/alibaba/cloud/ai/sql/controller/SQLController.java @@ -0,0 +1,31 @@ +package com.alibaba.cloud.ai.sql.controller; + +import com.alibaba.cloud.ai.sql.entity.Request; +import com.alibaba.cloud.ai.sql.entity.Response; +import com.alibaba.cloud.ai.sql.service.SQLService; +import jakarta.annotation.Resource; +import org.springframework.web.bind.annotation.*; + +import java.io.IOException; +import java.util.Objects; + +@RestController +@RequestMapping("/ai/sql") +public class SQLController { + + @Resource + private SQLService sqlService; + + @GetMapping + public Response sql(Request request) throws IOException { + + Response response = sqlService.sql(request); + + if (Objects.isNull(response)) { + throw new RuntimeException("SQL Example throw exception"); + } + + return response; + } + +} diff --git a/spring-ai-alibaba-examples/usercase-example/generate-sql-queries/src/main/java/com/alibaba/cloud/ai/sql/entity/Request.java b/spring-ai-alibaba-examples/usercase-example/generate-sql-queries/src/main/java/com/alibaba/cloud/ai/sql/entity/Request.java new file mode 100644 index 0000000..a5115f3 --- /dev/null +++ b/spring-ai-alibaba-examples/usercase-example/generate-sql-queries/src/main/java/com/alibaba/cloud/ai/sql/entity/Request.java @@ -0,0 +1,3 @@ +package com.alibaba.cloud.ai.sql.entity; + +public record Request(String text) {} diff --git a/spring-ai-alibaba-examples/usercase-example/generate-sql-queries/src/main/java/com/alibaba/cloud/ai/sql/entity/Response.java b/spring-ai-alibaba-examples/usercase-example/generate-sql-queries/src/main/java/com/alibaba/cloud/ai/sql/entity/Response.java new file mode 100644 index 0000000..c71e2d6 --- /dev/null +++ b/spring-ai-alibaba-examples/usercase-example/generate-sql-queries/src/main/java/com/alibaba/cloud/ai/sql/entity/Response.java @@ -0,0 +1,6 @@ +package com.alibaba.cloud.ai.sql.entity; + +import java.util.List; +import java.util.Map; + +public record Response(String sqlQuery, List> results) { } diff --git a/spring-ai-alibaba-examples/usercase-example/generate-sql-queries/src/main/java/com/alibaba/cloud/ai/sql/service/SQLService.java b/spring-ai-alibaba-examples/usercase-example/generate-sql-queries/src/main/java/com/alibaba/cloud/ai/sql/service/SQLService.java new file mode 100644 index 0000000..c22ff74 --- /dev/null +++ b/spring-ai-alibaba-examples/usercase-example/generate-sql-queries/src/main/java/com/alibaba/cloud/ai/sql/service/SQLService.java @@ -0,0 +1,53 @@ +package com.alibaba.cloud.ai.sql.service; + +import com.alibaba.cloud.ai.sql.entity.Request; +import com.alibaba.cloud.ai.sql.entity.Response; +import org.springframework.ai.chat.client.ChatClient; +import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.io.Resource; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Service; + +import java.io.IOException; +import java.nio.charset.Charset; + +@Service +public class SQLService { + + @Value("classpath:schema.sql") + private Resource ddlResource; + + @Value("classpath:/prompt/sql-queries.st") + private Resource sqlPromptTemplateResource; + + private final ChatClient aiClient; + private final JdbcTemplate jdbcTemplate; + + public SQLService(ChatClient.Builder aiClientBuilder, JdbcTemplate jdbcTemplate) { + this.aiClient = aiClientBuilder.build(); + this.jdbcTemplate = jdbcTemplate; + } + + public Response sql(Request request) throws IOException { + String schema = ddlResource.getContentAsString(Charset.defaultCharset()); + + String query = aiClient.prompt() + .advisors(new SimpleLoggerAdvisor()) + .user(userSpec -> userSpec + .text(sqlPromptTemplateResource) + .param("question", request.text()) + .param("ddl", schema) + ) + .call() + .content(); + + if (query.toLowerCase().startsWith("select")) { + + return new Response(query, jdbcTemplate.queryForList(query)); + } + + throw new RuntimeException(query); + } + +} diff --git a/spring-ai-alibaba-examples/usercase-example/generate-sql-queries/src/main/resources/application.yml b/spring-ai-alibaba-examples/usercase-example/generate-sql-queries/src/main/resources/application.yml new file mode 100644 index 0000000..6b47d61 --- /dev/null +++ b/spring-ai-alibaba-examples/usercase-example/generate-sql-queries/src/main/resources/application.yml @@ -0,0 +1,10 @@ +server: + port: 8081 + +spring: + application: + name: generate-sql-queries + + ai: + dashscope: + api-key: ${AI_DASHSCOPE_API_KEY} diff --git a/spring-ai-alibaba-examples/usercase-example/generate-sql-queries/src/main/resources/data.sql b/spring-ai-alibaba-examples/usercase-example/generate-sql-queries/src/main/resources/data.sql new file mode 100644 index 0000000..745385b --- /dev/null +++ b/spring-ai-alibaba-examples/usercase-example/generate-sql-queries/src/main/resources/data.sql @@ -0,0 +1,30 @@ +INSERT INTO TBL_USER (username, email, password) +VALUES + ('user1', 'user1@example.com', 'password1'), + ('user2', 'user2@example.com', 'password2'), + ('user3', 'user3@example.com', 'password3'), + ('user4', 'user4@example.com', 'password4'), + ('user5', 'user5@example.com', 'password5'), + ('user6', 'user6@example.com', 'password6'), + ('user7', 'user7@example.com', 'password7'), + ('user8', 'user8@example.com', 'password8'), + ('user9', 'user9@example.com', 'password9'), + ('user10', 'user10@example.com', 'password10'); + +INSERT INTO TBL_ACCOUNT (accountNumber, user_id, balance, openDate) +VALUES + ('ACC001', 1, 1000.00, '2024-07-09'), + ('ACC002', 1, 500.00, '2024-07-10'), + ('ACC003', 2, 1500.00, '2024-07-09'), + ('ACC004', 2, 200.00, '2024-07-10'), + ('ACC005', 3, 800.00, '2024-07-09'), + ('ACC006', 4, 3000.00, '2024-07-09'), + ('ACC007', 4, 100.00, '2024-07-10'), + ('ACC008', 5, 250.00, '2024-07-09'), + ('ACC009', 6, 1800.00, '2024-07-09'), + ('ACC010', 6, 700.00, '2024-07-10'), + ('ACC011', 7, 500.00, '2024-07-09'), + ('ACC012', 8, 1200.00, '2024-07-09'), + ('ACC013', 9, 900.00, '2024-07-09'), + ('ACC014', 9, 300.00, '2024-07-10'), + ('ACC015', 10, 2000.00, '2024-07-09'); diff --git a/spring-ai-alibaba-examples/usercase-example/generate-sql-queries/src/main/resources/prompt/sql-queries.st b/spring-ai-alibaba-examples/usercase-example/generate-sql-queries/src/main/resources/prompt/sql-queries.st new file mode 100644 index 0000000..4e31ac1 --- /dev/null +++ b/spring-ai-alibaba-examples/usercase-example/generate-sql-queries/src/main/resources/prompt/sql-queries.st @@ -0,0 +1,11 @@ +Given the DDL in the DDL section, write an SQL query that answers the asked question in the QUESTION section. +Only produce select queries. Do not append any text or markup in the start or end of response. +Remove the markups such as ``` , sql , \n as well. +If the question would result in an insert, update, or delete, or if the query would alter the DDL in any way, say that the operation isn't supported. +If the question can't be answered, say that the DDL doesn't support answering that question. + +QUESTION +{question} + +DDL +{ddl} diff --git a/spring-ai-alibaba-examples/usercase-example/generate-sql-queries/src/main/resources/schema.sql b/spring-ai-alibaba-examples/usercase-example/generate-sql-queries/src/main/resources/schema.sql new file mode 100644 index 0000000..79c3222 --- /dev/null +++ b/spring-ai-alibaba-examples/usercase-example/generate-sql-queries/src/main/resources/schema.sql @@ -0,0 +1,17 @@ +create table TBL_USER ( + id int not null auto_increment, + username varchar(255) not null, + email varchar(255) not null, + password varchar(255) not null, + primary key (id) +); + +create table TBL_ACCOUNT ( + id int not null auto_increment, + accountNumber varchar(255) not null, + user_id int not null, + balance decimal(10, 2) not null, + openDate date not null, + primary key (id), + foreign key (user_id) references TBL_USER(id) +); diff --git a/spring-ai-alibaba-examples/usercase-example/pom.xml b/spring-ai-alibaba-examples/usercase-example/pom.xml new file mode 100644 index 0000000..0e1de11 --- /dev/null +++ b/spring-ai-alibaba-examples/usercase-example/pom.xml @@ -0,0 +1,16 @@ + + + 4.0.0 + + User Cases Examples + usercase-example + pom + + + text-classifier + generate-sql-queries + + + diff --git a/spring-ai-alibaba-examples/usercase-example/text-classifier/pom.xml b/spring-ai-alibaba-examples/usercase-example/text-classifier/pom.xml new file mode 100644 index 0000000..a92d9d0 --- /dev/null +++ b/spring-ai-alibaba-examples/usercase-example/text-classifier/pom.xml @@ -0,0 +1,69 @@ + + + 4.0.0 + + + org.springframework.boot + spring-boot-starter-parent + 3.3.3 + + + + Text Classifier + text-classifier + + + UTF-8 + UTF-8 + 17 + 17 + 3.1.1 + + + 1.0.0-M2 + + + + + com.alibaba.cloud.ai + spring-ai-alibaba-starter + ${spring-ai-alibaba.version} + + + + org.springframework.boot + spring-boot-starter-web + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + org.apache.maven.plugins + maven-deploy-plugin + ${maven-deploy-plugin.version} + + true + + + + + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + + + diff --git a/spring-ai-alibaba-examples/usercase-example/text-classifier/src/main/java/com/alibaba/cloud/ai/text/AIApplication.java b/spring-ai-alibaba-examples/usercase-example/text-classifier/src/main/java/com/alibaba/cloud/ai/text/AIApplication.java new file mode 100644 index 0000000..e0b015b --- /dev/null +++ b/spring-ai-alibaba-examples/usercase-example/text-classifier/src/main/java/com/alibaba/cloud/ai/text/AIApplication.java @@ -0,0 +1,13 @@ +package com.alibaba.cloud.ai.text; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class AIApplication { + + public static void main(String[] args) { + + SpringApplication.run(AIApplication.class, args); + } +} diff --git a/spring-ai-alibaba-examples/usercase-example/text-classifier/src/main/java/com/alibaba/cloud/ai/text/controller/TextController.java b/spring-ai-alibaba-examples/usercase-example/text-classifier/src/main/java/com/alibaba/cloud/ai/text/controller/TextController.java new file mode 100644 index 0000000..b279aca --- /dev/null +++ b/spring-ai-alibaba-examples/usercase-example/text-classifier/src/main/java/com/alibaba/cloud/ai/text/controller/TextController.java @@ -0,0 +1,43 @@ +package com.alibaba.cloud.ai.text.controller; + +import com.alibaba.cloud.ai.text.enums.TextClassifierTypes; +import com.alibaba.cloud.ai.text.service.TextService; +import jakarta.annotation.Resource; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/ai/text") +public class TextController { + + @Resource + private TextService textService; + + @GetMapping + public String classify(String text) { + return textService.classifyEmotion(text); + } + + @GetMapping("/structured-output") + public TextClassifierTypes classifyStructured(String text) { + + return textService.classifyEmotionStructured(text); + } + + @GetMapping("/with-hints") + public String classifyWithHints(String text) { + return textService.classifyEmotionWithHints(text); + } + + @GetMapping("/few-shots-prompt") + public String classifyFewShotsPrompt(String text) { + return textService.classifyEmotionWithFewShotsPrompt(text); + } + + @GetMapping("/few-shots-history") + public String classifyFewShotsHistory(String text) { + return textService.classifyEmotionWithFewShotsHistory(text); + } + +} diff --git a/spring-ai-alibaba-examples/usercase-example/text-classifier/src/main/java/com/alibaba/cloud/ai/text/enums/TextClassifierTypes.java b/spring-ai-alibaba-examples/usercase-example/text-classifier/src/main/java/com/alibaba/cloud/ai/text/enums/TextClassifierTypes.java new file mode 100644 index 0000000..7cad5ec --- /dev/null +++ b/spring-ai-alibaba-examples/usercase-example/text-classifier/src/main/java/com/alibaba/cloud/ai/text/enums/TextClassifierTypes.java @@ -0,0 +1,19 @@ +package com.alibaba.cloud.ai.text.enums; + +public enum TextClassifierTypes { + + /** + * 积极 + */ + POSITIVE, + + /** + * 消极 + */ + NEGATIVE, + + /** + * 中性 + */ + NEUTRAL +} diff --git a/spring-ai-alibaba-examples/usercase-example/text-classifier/src/main/java/com/alibaba/cloud/ai/text/service/TextService.java b/spring-ai-alibaba-examples/usercase-example/text-classifier/src/main/java/com/alibaba/cloud/ai/text/service/TextService.java new file mode 100644 index 0000000..6509003 --- /dev/null +++ b/spring-ai-alibaba-examples/usercase-example/text-classifier/src/main/java/com/alibaba/cloud/ai/text/service/TextService.java @@ -0,0 +1,141 @@ +package com.alibaba.cloud.ai.text.service; + +import com.alibaba.cloud.ai.text.enums.TextClassifierTypes; +import org.springframework.ai.chat.client.ChatClient; +import org.springframework.ai.chat.messages.AssistantMessage; +import org.springframework.ai.chat.messages.Message; +import org.springframework.ai.chat.messages.SystemMessage; +import org.springframework.ai.chat.messages.UserMessage; +import org.springframework.ai.chat.prompt.ChatOptionsBuilder; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public class TextService { + + private final ChatClient chatClient; + + private TextService(ChatClient.Builder chatClientBuilder) { + this.chatClient = chatClientBuilder + .defaultOptions(ChatOptionsBuilder.builder() + .withTemperature(0.0f) + .build()) + .build(); + } + + public String classifyEmotion(String text) { + return chatClient + .prompt() + .system(""" + Classify the provided text into one of these classes: + POSITIVE, NEGATIVE, NEUTRAL + """) + .user(text) + .call() + .content(); + } + + public TextClassifierTypes classifyEmotionStructured(String text) { + return chatClient + .prompt() + .system(""" + Classify the provided text into one of these classes: + POSITIVE, NEGATIVE, NEUTRAL + """) + .user(text) + .call() + .entity(TextClassifierTypes.class); + } + + public String classifyEmotionWithHints(String text) { + return chatClient + .prompt() + .system(""" + Classify the provided text into one of these classes. + + POSITIVE: Happy, excellent, reliable, durable, efficient, innovative, intuitive, exceptional, high-quality, impressive, user-friendly. + NEGATIVE: Unhappy, sad, Defective, unreliable, disappointing, frustrating, complicated, poor-quality + NEUTRAL: OK, ordinary, plain, regular, standard, average, common, typical, normal, indifferent + """) + .user(text) + .call() + .content(); + } + + public String classifyEmotionWithFewShotsPrompt(String text) { + return chatClient + .prompt() + .system(""" + Classify the provided text into one of these classes. + + POSITIVE: Happy, excellent, reliable, durable, efficient, innovative, intuitive, exceptional, high-quality, impressive, user-friendly. + NEGATIVE: Unhappy, sad, Defective, unreliable, disappointing, frustrating, complicated, poor-quality + NEUTRAL: OK, ordinary, plain, regular, standard, average, common, typical, normal, indifferent + + --- + + Text: The product is highly efficient and user-friendly. + Class: POSITIVE + + Text: The service was disappointing and frustrating. + Class: NEGATIVE + + Text: The performance is average, just as expected. + Class: NEUTRAL + + Text: The software is intuitive and impressive. + Class: POSITIVE + + Text: The device is defective and complicated to use. + Class: NEGATIVE + + Text: The overall experience was plain and ordinary. + Class: NEUTRAL + """) + .user(text) + .call() + .content(); + } + + public String classifyEmotionWithFewShotsHistory(String text) { + return chatClient + .prompt() + .messages(getPromptWithFewShotsHistory()) + .user(text) + .call() + .content(); + } + + private List getPromptWithFewShotsHistory() { + return List.of( + new SystemMessage(""" + Classify the provided text into one of these classes. + + POSITIVE: Happy, excellent, reliable, durable, efficient, innovative, intuitive, exceptional, high-quality, impressive, user-friendly. + NEGATIVE: Unhappy, sad, Defective, unreliable, disappointing, frustrating, complicated, poor-quality + NEUTRAL: OK, ordinary, plain, regular, standard, average, common, typical, normal, indifferent + """), + + new UserMessage("The product is highly efficient and user-friendly."), + new AssistantMessage("POSITIVE"), + + new UserMessage("The service was disappointing and frustrating."), + new AssistantMessage("NEGATIVE"), + + new UserMessage("The performance is average, just as expected."), + new AssistantMessage("NEUTRAL"), + + new UserMessage("The software is intuitive and impressive."), + new AssistantMessage("POSITIVE"), + + new UserMessage("The device is defective and complicated to use."), + new AssistantMessage("NEGATIVE"), + + new UserMessage("The overall experience was plain and ordinary."), + new AssistantMessage("NEUTRAL") + ); + + } + +} diff --git a/spring-ai-alibaba-examples/usercase-example/text-classifier/src/main/resources/application.yml b/spring-ai-alibaba-examples/usercase-example/text-classifier/src/main/resources/application.yml new file mode 100644 index 0000000..4a65bdb --- /dev/null +++ b/spring-ai-alibaba-examples/usercase-example/text-classifier/src/main/resources/application.yml @@ -0,0 +1,10 @@ +server: + port: 8082 + +spring: + application: + name: text-classifier + + ai: + dashscope: + api-key: ${AI_DASHSCOPE_API_KEY}