跳到主要内容

实战:中国移动AI套餐智能助手

本实战项目将演示如何使用 Spring AI 构建一个中国移动 AI 套餐智能助手,帮助用户选择最适合的手机套餐。

项目需求分析

功能需求

  1. 用户可以咨询套餐详情
  2. 根据用户使用习惯推荐套餐
  3. 解答套餐相关问题
  4. 处理套餐变更请求

技术需求

  1. 使用 Spring AI 集成大语言模型
  2. 实现 RAG 检索增强
  3. 使用 Tool Calling 调用套餐查询接口
  4. 实现角色设定和对话管理

项目结构

src/
├── main/
│ ├── java/
│ │ └── com/example/china_mobile_assistant/
│ │ ├── ChinaMobileAssistantApplication.java
│ │ ├── controller/
│ │ │ └── AssistantController.java
│ │ ├── service/
│ │ │ ├── AssistantService.java
│ │ │ ├── PackageRecommendationService.java
│ │ │ └── PackageQueryService.java
│ │ ├── tool/
│ │ │ └── MobilePackageTools.java
│ │ └── model/
│ │ ├── MobilePackage.java
│ │ └── UserUsage.java
│ └── resources/
│ ├── application.yml
│ ├── prompts/
│ │ └── assistant-prompt.st
│ └── data/
│ └── packages.json
└── pom.xml

核心代码实现

1. 主应用类

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

2. 配置文件

spring:
ai:
openai:
api-key: ${OPENAI_API_KEY}
chat:
options:
model: gpt-3.5-turbo
temperature: 0.7

3. 套餐数据模型

public class MobilePackage {
private String name;
private String description;
private int voiceMinutes;
private int dataGB;
private int smsCount;
private BigDecimal price;
private String features;

// 构造函数、getter 和 setter
}

public class UserUsage {
private int monthlyVoiceMinutes;
private int monthlyDataGB;
private int monthlySmsCount;

// 构造函数、getter 和 setter
}

4. 套餐查询工具

@Component
public class MobilePackageTools {

private final List<MobilePackage> packages;

public MobilePackageTools() {
// 初始化套餐数据
packages = loadPackagesFromJson();
}

@Tool(name = "query_packages", description = "查询所有可用的手机套餐")
public List<MobilePackage> queryAllPackages() {
return new ArrayList<>(packages);
}

@Tool(name = "recommend_package", description = "根据用户使用习惯推荐套餐")
public List<MobilePackage> recommendPackage(
@Param(description = "每月通话分钟数") int voiceMinutes,
@Param(description = "每月数据流量(GB)") int dataGB,
@Param(description = "每月短信条数") int smsCount) {

UserUsage usage = new UserUsage(voiceMinutes, dataGB, smsCount);
return recommendPackages(usage);
}

private List<MobilePackage> recommendPackages(UserUsage usage) {
return packages.stream()
.filter(pkg -> pkg.getVoiceMinutes() >= usage.getMonthlyVoiceMinutes() &&
pkg.getDataGB() >= usage.getMonthlyDataGB() &&
pkg.getSmsCount() >= usage.getMonthlySmsCount())
.sorted(Comparator.comparing(MobilePackage::getPrice))
.limit(3)
.collect(Collectors.toList());
}
}

5. 助手服务类

@Service
public class AssistantService {

private final ChatClient chatClient;
private final List<Tool> tools;

public AssistantService(ChatClient chatClient, List<Tool> tools) {
this.chatClient = chatClient;
this.tools = tools;
}

public String processUserQuery(String userQuery) {
// 设置系统角色
SystemMessage systemMessage = new SystemMessage("""
你是中国移动的智能客服助手,专门帮助用户了解和选择手机套餐。
你需要:
1. 准确回答套餐相关问题
2. 根据用户需求推荐合适套餐
3. 使用专业但友好的语气
4. 在需要时调用工具查询套餐信息
""");

Prompt prompt = new Prompt(
List.of(
systemMessage,
new UserMessage(userQuery)
),
OpenAiChatOptions.builder()
.withTools(tools.stream().map(Tool::getName).collect(Collectors.toList()))
.build()
);

ChatResponse response = chatClient.call(prompt);

// 处理工具调用
if (response.getResult().getOutput().getToolCalls() != null &&
!response.getResult().getOutput().getToolCalls().isEmpty()) {

List<ToolCall> toolCalls = response.getResult().getOutput().getToolCalls();
List<ToolCallResult> toolCallResults = executeToolCalls(toolCalls);

Prompt followUpPrompt = new Prompt(
List.of(
systemMessage,
new UserMessage(userQuery),
response.getResult().getOutput(),
new ToolCallResultMessage(toolCallResults)
)
);

ChatResponse finalResponse = chatClient.call(followUpPrompt);
return finalResponse.getResult().getOutput().getContent();
}

return response.getResult().getOutput().getContent();
}

private List<ToolCallResult> executeToolCalls(List<ToolCall> toolCalls) {
return toolCalls.stream().map(toolCall -> {
try {
Object result = toolCall.execute();
return new ToolCallResult(toolCall, objectMapper.writeValueAsString(result), false, null);
} catch (Exception e) {
return new ToolCallResult(toolCall, null, true, e.getMessage());
}
}).collect(Collectors.toList());
}
}

6. 控制器类

@RestController
@RequestMapping("/api/assistant")
public class AssistantController {

private final AssistantService assistantService;

public AssistantController(AssistantService assistantService) {
this.assistantService = assistantService;
}

@PostMapping("/chat")
public ResponseEntity<String> chat(@RequestBody Map<String, String> request) {
String userQuery = request.get("query");
String response = assistantService.processUserQuery(userQuery);
return ResponseEntity.ok(response);
}
}

测试和部署

1. 本地测试

# 启动应用
./mvnw spring-boot:run

# 测试查询套餐
curl -X POST http://localhost:8080/api/assistant/chat \
-H "Content-Type: application/json" \
-d '{"query":"我想了解一下你们的套餐"}'

# 测试推荐套餐
curl -X POST http://localhost:8080/api/assistant/chat \
-H "Content-Type: application/json" \
-d '{"query":"我每月通话大概200分钟,流量10GB,短信50条,有什么推荐吗?"}'

2. 部署到生产环境

  1. 构建 Docker 镜像
  2. 部署到 Kubernetes 或云平台
  3. 配置监控和日志

项目扩展

1. 集成真实 API

  • 连接中国移动的真实套餐查询接口
  • 实现用户账户绑定和套餐变更

2. 增强用户体验

  • 添加 Web 前端界面
  • 实现多轮对话管理
  • 添加语音交互功能

3. 数据分析

  • 收集用户咨询数据
  • 分析热门问题和推荐效果
  • 持续优化推荐算法

通过这个实战项目,我们展示了如何使用 Spring AI 构建一个功能完整的 AI 助手应用,涵盖了角色设定、工具调用、RAG 检索增强等核心技术。