实战:中国移动AI套餐智能助手
本实战项目将演示如何使用 Spring AI 构建一个中国移动 AI 套餐智能助手,帮助用户选择最适合的手机套餐。
项目需求分析
功能需求
- 用户可以咨询套餐详情
- 根据用户使用习惯推荐套餐
- 解答套餐相关问题
- 处理套餐变更请求
技术需求
- 使用 Spring AI 集成大语言模型
- 实现 RAG 检索增强
- 使用 Tool Calling 调用套餐查询接口
- 实现角色设定和对话管理
项目结构
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. 部署到生产环境
- 构建 Docker 镜像
- 部署到 Kubernetes 或云平台
- 配置监控和日志
项目扩展
1. 集成真实 API
- 连接中国移动的真实套餐查询接口
- 实现用户账户绑定和套餐变更
2. 增强用户体验
- 添加 Web 前端界面
- 实现多轮对话管理
- 添加语音交互功能
3. 数据分析
- 收集用户咨询数据
- 分析热门问题和推荐效果
- 持续优化推荐算法
通过这个实战项目,我们展示了如何使用 Spring AI 构建一个功能完整的 AI 助手应用,涵盖了角色设定、工具调用、RAG 检索增强等核心技术。