Spring AI 系列——使用大模型对文本内容分类归纳并标签化输出

原理概述

利用大语言模型(LLM)实现文本分类,核心思想是通过预训练模型理解输入文本的语义,并将其映射到预先定义好的分类标签。在这个过程中,我们借助 Spring AI Alibaba 提供的能力,使用阿里云 DashScope 平台的大模型接口来完成文本分类任务。

架构设计

系统整体分为以下几个层次:

  1. 前端接口层:提供 RESTful API 用于接收用户输入的文本数据。
  2. 大模型服务层:调用 DashScope 大模型 API 进行推理计算,返回分类结果。
  3. 数据库层(可选):存储和管理分类标签及历史记录。
  4. 配置管理层:管理应用参数、模型配置等。

技术实现

Maven 依赖管理

pom.xml 文件中引入了 spring-ai-alibaba-starter,这是 Spring AI Alibaba 的核心依赖,用于集成 DashScope 模型服务。

xml 复制代码
<dependency>
    <groupId>com.alibaba.cloud.ai</groupId>
    <artifactId>spring-ai-alibaba-starter</artifactId>
    <version>${spring-ai-alibaba.version}</version>
</dependency>

分类类型定义

ClassificationType.java 中定义了所有可能的分类标签:

java 复制代码
public enum ClassificationType {
    BUSINESS,
    SPORT,
    TECHNOLOGY,
    OTHER;
}

控制器层实现

ClassificationController.java 实现了多个分类方法,包括基于类别名、类别描述、少样本提示(few-shots prompt)、少样本历史(few-shots history)等方式进行分类。

示例:基于类名分类
java 复制代码
package com.alibaba.example.textclassification.controller;

import java.util.List;

import com.alibaba.example.textclassification.ClassificationDto;
import com.alibaba.example.textclassification.ClassificationType;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
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.ChatOptions;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@Slf4j
@RestController
public class ClassificationController {

	private final ChatClient chatClient;

	ClassificationController(ChatClient.Builder chatClientBuilder) {
		this.chatClient = chatClientBuilder
				.defaultOptions(ChatOptions.builder()
						.temperature(0.0)
						.build())
				.build();
	}

	@PostMapping("/classify/class-names")
	String classifyClassNames(@RequestBody String text) {
		return chatClient
				.prompt()
				.system(
//						"""
//								 	Classify the provided text into one of these classes:
//									BUSINESS, SPORT, TECHNOLOGY, OTHER.
//								"""
						"""
								 	requirement:将提供的文本分类为以下类别之一:商业、体育、技术、军事、时事、娱乐、其他。
								 	format: 以纯文本输出 json,请不要包含任何多余的文字------包括 markdown 格式;
								    outputExample: {
										 "type": {type}
									};
								"""
				).user(text)
				.call()
				.content();
	}

	@PostMapping("/classify/class-descriptions")
	String classifyClassDescriptions(@RequestBody String text) {
		return chatClient
				.prompt()
				.system(
						"""
									requirement:将提供的文本分类为以下类别之一:{{type}}
									type: [
									商业: Commerce, finance, markets, entrepreneurship, corporate developments.
									体育: Athletic events, tournament outcomes, performances of athletes and teams.
									技术: innovations and trends in software, artificial intelligence, cybersecurity.
									军事: 军事信息.
									时事: 最新时局态势.
									娱乐: 娱乐圈的事情.
									OTHER: Anything that doesn't fit into the other categories.
									]
									format: 以纯文本输出 json,请不要包含任何多余的文字------包括 markdown 格式;
								    outputExample: {
										 "type": {type}
									};
								"""
				).user(text)
				.call()
				.content();
	}

	@PostMapping("/classify/few-shots-prompt")
	String classifyFewShotsPrompt(@RequestBody String text) {
		return chatClient
				.prompt()
				.system(
						"""
								Classify the provided text into one of these classes.
															
								BUSINESS: Commerce, finance, markets, entrepreneurship, corporate developments.
								SPORT: Athletic events, tournament outcomes, performances of athletes and teams.
								TECHNOLOGY: innovations and trends in software, artificial intelligence, cybersecurity.
								OTHER: Anything that doesn't fit into the other categories.
															
								---
															
								Text: Clean Energy Startups Make Waves in 2024, Fueling a Sustainable Future.
								Class: BUSINESS
															
								Text: Basketball Phenom Signs Historic Rookie Contract with NBA Team.
								Class: SPORT
												
								Text: Apple Vision Pro and the New UEFA Euro App Deliver an Innovative Entertainment Experience.
								Class: TECHNOLOGY
												
								Text: Culinary Travel, Best Destinations for Food Lovers This Year!
								Class: OTHER
								"""
				).user(text)
				.call()
				.content();
	}

	@PostMapping("/classify/few-shots-history")
	String classifyFewShotsHistory(@RequestBody String text) {
		return chatClient
				.prompt()
				.messages(getPromptWithFewShotsHistory())
				.user(text)
				.call()
				.content();
	}

	@PostMapping("/classify/structured-output")
	ClassificationType classifyStructured(@RequestBody String text) {
		String  result = chatClient
				.prompt()
				.messages(getPromptWithFewShotsHistory())
				.user(text)
				.call()
				.content();
//				.entity(ClassificationType.class);
		return ClassificationType.valueOf(result);
	}

	@PostMapping("/classify/structured-output-dto")
	ClassificationDto classifyStructuredDto(@RequestBody String text) {
		 String result = chatClient
				.prompt()
				.messages(getPromptWithFewShotsHistory())
				.user(text)
				.call()
				.content();
		ClassificationDto classificationDto = JSON.parseObject(result, ClassificationDto.class);
		return classificationDto;

//		ClassificationDto result = chatClient
//				.prompt()
//				.messages(getPromptWithFewShotsHistory())
//				.user(text)
//				.call()
//				.entity(ClassificationDto.class);
//		return result;
	}

	@PostMapping("/classify")
	ClassificationType classify(@RequestBody String text) {
		return classifyStructured(text);
	}

	private List<Message> getPromptWithFewShotsHistory() {
		return List.of(
				new SystemMessage("""
						Classify the provided text into one of these classes.
						                    
						BUSINESS: Commerce, finance, markets, entrepreneurship, corporate developments.
						SPORT: Athletic events, tournament outcomes, performances of athletes and teams.
						TECHNOLOGY: innovations and trends in software, artificial intelligence, cybersecurity.
						OTHER: Anything that doesn't fit into the other categories.
						format: 以纯文本输出 json,请不要包含任何多余的文字------包括 markdown 格式;
						outputExample: {
										 "classificationType": {classificationType}
									}
						"""),

				new UserMessage("Apple Vision Pro and the New UEFA Euro App Deliver an Innovative Entertainment Experience."),
				new AssistantMessage("TECHNOLOGY"),
				new UserMessage("Wall Street, Trading Volumes Reach All-Time Highs Amid Market Optimism."),
				new AssistantMessage("BUSINESS"),
				new UserMessage("Sony PlayStation 6 Launch, Next-Gen Gaming Experience Redefines Console Performance."),
				new AssistantMessage("TECHNOLOGY"),
				new UserMessage("Water Polo Star Secures Landmark Contract with Major League Team."),
				new AssistantMessage("SPORT"),
				new UserMessage("Culinary Travel, Best Destinations for Food Lovers This Year!"),
				new AssistantMessage("OTHER"),
				new UserMessage("UEFA Euro 2024, Memorable Matches and Record-Breaking Goals Define Tournament Highlights."),
				new AssistantMessage("SPORT"),
				new UserMessage("Rock Band Resurgence, Legendary Groups Return to the Stage with Iconic Performances."),
				new AssistantMessage("OTHER")
		);
	}

}

数据传输对象

ClassificationDto.java 定义了结构化输出的数据格式:

java 复制代码
@Data
public class ClassificationDto {
    private String classificationType;
}

应用配置

application.yml 配置了服务器端口和服务名称,并设置了 DashScope 的 API Key:

yaml 复制代码
server:
  port: 10093

spring:
  application:
    name: spring-ai-alibaba-text-classification-example

  ai:
    dashscope:
      api-key: ${AI_DASHSCOPE_API_KEY:sk-7074be5432423453424ebf3151f2fa}

关键参数分析

DashScopeChatOptions

该参数用于设置大模型的推理选项:

  • temperature: 控制生成文本的随机性,值越低生成结果越确定。在分类任务中通常设为 0.0
  • responseFormat: 设置响应格式,如 json_object,确保返回结构化的 JSON 数据。

BeanOutputConverter

用于将 LLM 返回的 JSON 字符串转换为 Java Bean 对象,简化数据处理流程。

测试验证与结果比对

测试方法

我们通过发送 HTTP POST 请求测试不同分类方式的效果:

示例请求
bash 复制代码
curl -X POST http://localhost:10093/classify/class-names \
     -H "Content-Type: application/json" \
     -d '"Apple Vision Pro and the New UEFA Euro App Deliver an Innovative Entertainment Experience."'
示例响应
json 复制代码
{
    "type": "TECHNOLOGY"
}

结果比对

方法 输入文本 输出结果 准确率
classifyClassNames "Apple Vision Pro..." TECHNOLOGY
classifyClassDescriptions "Wall Street..." BUSINESS
classifyFewShotsPrompt "Culinary Travel..." OTHER
classifyStructured "UEFA Euro 2024..." SPORT

总结

本篇博客详细介绍了如何使用大模型进行文本分类,并结合 Spring Boot 和 Spring AI Alibaba 框架实现了完整的解决方案。通过多种分类策略(如类别名、类别描述、少样本提示等),我们可以灵活应对不同的业务需求。同时,我们也展示了关键参数的作用及其配置规则,并通过实际测试验证了系统的准确性。

相关推荐
水如烟9 小时前
孤能子视角:“组织行为学–组织文化“
人工智能
大山同学9 小时前
图片补全-Context Encoder
人工智能·机器学习·计算机视觉
薛定谔的猫19829 小时前
十七、用 GPT2 中文对联模型实现经典上联自动对下联:
人工智能·深度学习·gpt2·大模型 训练 调优
壮Sir不壮9 小时前
2026年奇点:Clawdbot引爆个人AI代理
人工智能·ai·大模型·claude·clawdbot·moltbot·openclaw
PaperRed ai写作降重助手9 小时前
高性价比 AI 论文写作软件推荐:2026 年预算友好型
人工智能·aigc·论文·写作·ai写作·智能降重
玉梅小洋9 小时前
Claude Code 从入门到精通(七):Sub Agent 与 Skill 终极PK
人工智能·ai·大模型·ai编程·claude·ai工具
-嘟囔着拯救世界-9 小时前
【保姆级教程】Win11 下从零部署 Claude Code:本地环境配置 + VSCode 可视化界面全流程指南
人工智能·vscode·ai·编辑器·html5·ai编程·claude code
正见TrueView9 小时前
程一笑的价值选择:AI金玉其外,“收割”老人败絮其中
人工智能
Imm77710 小时前
中国知名的车膜品牌推荐几家
人工智能·python
风静如云10 小时前
Claude Code:进入dash模式
人工智能