Skip to content

Commit 66727b7

Browse files
committed
后端 - AI 能力接入
接入 langChain4j + 阿里云百炼大模型 能顺利启动,但是逻辑不一定正确
1 parent 7f0477e commit 66727b7

14 files changed

+605
-42
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
### CUSTOM ###
2+
application-local.yml
3+
4+
15
HELP.md
26
target/
37
.mvn/wrapper/maven-wrapper.jar

pom.xml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,16 @@
6868
<artifactId>spring-boot-starter-test</artifactId>
6969
<scope>test</scope>
7070
</dependency>
71+
<dependency>
72+
<groupId>dev.langchain4j</groupId>
73+
<artifactId>langchain4j-community-dashscope-spring-boot-starter</artifactId>
74+
<version>1.4.0-beta10</version>
75+
</dependency>
76+
<dependency>
77+
<groupId>dev.langchain4j</groupId>
78+
<artifactId>langchain4j-reactor</artifactId>
79+
<version>1.4.0-beta10</version>
80+
</dependency>
7181
</dependencies>
7282

7383
<dependencyManagement>
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package com.yupi.codertestbackend.model.dto.ai;
2+
3+
import lombok.Data;
4+
5+
import java.util.List;
6+
7+
/**
8+
* AI生成关卡响应
9+
*/
10+
@Data
11+
public class LevelGenerationResponse {
12+
13+
/**
14+
* 关卡名称
15+
*/
16+
private String levelName;
17+
18+
/**
19+
* 关卡需求描述
20+
*/
21+
private String levelDesc;
22+
23+
/**
24+
* 关卡选项列表
25+
*/
26+
private List<LevelOption> options;
27+
28+
/**
29+
* 难度等级(简单,中等,困难)
30+
*/
31+
private String difficulty;
32+
33+
/**
34+
* 目标薪资范围
35+
*/
36+
private Integer targetSalary;
37+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package com.yupi.codertestbackend.model.dto.ai;
2+
3+
import lombok.Data;
4+
5+
/**
6+
* 关卡选项
7+
*/
8+
@Data
9+
public class LevelOption {
10+
11+
/**
12+
* 选项名称
13+
*/
14+
private String optionName;
15+
16+
/**
17+
* 是否为正确答案
18+
*/
19+
private Boolean trueAnswer;
20+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package com.yupi.codertestbackend.model.dto.ai;
2+
3+
import lombok.Data;
4+
5+
import java.util.List;
6+
7+
/**
8+
* AI生成结果报告响应
9+
*/
10+
@Data
11+
public class ResultReportResponse {
12+
13+
/**
14+
* 本关卡用户作答的分数(满分 100 分)
15+
*/
16+
private Integer score;
17+
18+
/**
19+
* 给本次用户的作答一个评价
20+
*/
21+
private String comment;
22+
23+
/**
24+
* 调整用户当前的薪资(一个具体的加减数字)
25+
*/
26+
private Integer salaryChange;
27+
28+
/**
29+
* 基于用户当前的薪资给出一些投递公司的建议
30+
*/
31+
private String suggest;
32+
33+
/**
34+
* 解释给出当前分数和评价的原因
35+
*/
36+
private String reason;
37+
38+
/**
39+
* 本关卡的正确选项
40+
*/
41+
private List<String> trueOptions;
42+
43+
/**
44+
* 标准的、详细的关卡分析和解读
45+
*/
46+
private String standardAnswer;
47+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package com.yupi.codertestbackend.service.ai;
2+
3+
import com.yupi.codertestbackend.model.dto.ai.LevelGenerationResponse;
4+
5+
/**
6+
* AI生成关卡服务
7+
*/
8+
public interface LevelGenerationAiService {
9+
10+
/**
11+
* 根据用户薪资生成关卡
12+
*
13+
* @param salary 用户当前薪资
14+
* @return 生成的关卡信息
15+
*/
16+
LevelGenerationResponse generateLevel(Integer salary);
17+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.yupi.codertestbackend.service.ai;
2+
3+
import com.yupi.codertestbackend.model.dto.ai.ResultReportResponse;
4+
5+
/**
6+
* AI生成结果报告服务
7+
*/
8+
public interface ResultReportAiService {
9+
10+
/**
11+
* 根据关卡信息和用户作答生成结果报告
12+
*
13+
* @param levelName 关卡名称
14+
* @param levelDesc 关卡需求描述
15+
* @param userOptions 用户选择的选项(JSON字符串)
16+
* @param trueOptions 本关卡的正确选项(JSON字符串)
17+
* @param salary 用户当前薪资
18+
* @return 生成的结果报告
19+
*/
20+
ResultReportResponse generateResultReport(String levelName, String levelDesc,
21+
String userOptions, String trueOptions, Integer salary);
22+
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
package com.yupi.codertestbackend.service.ai.impl;
2+
3+
import com.yupi.codertestbackend.model.dto.ai.LevelGenerationResponse;
4+
import com.yupi.codertestbackend.service.ai.LevelGenerationAiService;
5+
import lombok.extern.slf4j.Slf4j;
6+
import org.springframework.stereotype.Service;
7+
8+
9+
/**
10+
* AI生成关卡服务实现
11+
*/
12+
@Service
13+
@Slf4j
14+
public class LevelGenerationAiServiceImpl implements LevelGenerationAiService {
15+
16+
@Override
17+
public LevelGenerationResponse generateLevel(Integer salary) {
18+
try {
19+
// TODO: 这里应该调用实际的AI服务(如阿里云DashScope)
20+
// 读取提示词文件并构建请求
21+
// String systemPrompt = readPromptFile("prompts/level-generation-system.txt");
22+
// String userPrompt = "当前薪资:" + salary;
23+
24+
// 现在先返回模拟数据
25+
log.info("模拟AI生成关卡,薪资:{}", salary);
26+
27+
return createMockResponse(salary);
28+
29+
} catch (Exception e) {
30+
log.error("生成关卡失败:{}", e.getMessage(), e);
31+
throw new RuntimeException("AI服务调用失败", e);
32+
}
33+
}
34+
35+
36+
/**
37+
* 创建模拟响应(用于测试)
38+
*/
39+
private LevelGenerationResponse createMockResponse(Integer salary) {
40+
// 根据薪资创建不同难度的模拟关卡
41+
LevelGenerationResponse response = new LevelGenerationResponse();
42+
43+
if (salary <= 8000) {
44+
response.setLevelName("基础Web开发项目");
45+
response.setLevelDesc("开发一个简单的博客系统,需要支持用户注册登录、文章发布、评论功能。要求界面简洁,功能完整。");
46+
response.setDifficulty("简单");
47+
} else if (salary <= 15000) {
48+
response.setLevelName("电商平台核心模块设计");
49+
response.setLevelDesc("设计一个电商平台的订单管理系统,需要处理高并发下单、库存管理、支付集成等核心功能。");
50+
response.setDifficulty("中等");
51+
} else {
52+
response.setLevelName("分布式微服务架构设计");
53+
response.setLevelDesc("设计一个大型互联网公司的用户中心微服务架构,需要考虑服务拆分、数据一致性、容灾备份等问题。");
54+
response.setDifficulty("困难");
55+
}
56+
57+
// 设置选项(这里简化处理)
58+
response.setOptions(createMockOptions());
59+
response.setTargetSalary(salary);
60+
61+
return response;
62+
}
63+
64+
/**
65+
* 创建模拟选项
66+
*/
67+
private java.util.List<com.yupi.codertestbackend.model.dto.ai.LevelOption> createMockOptions() {
68+
java.util.List<com.yupi.codertestbackend.model.dto.ai.LevelOption> options = new java.util.ArrayList<>();
69+
70+
// 正确选项
71+
com.yupi.codertestbackend.model.dto.ai.LevelOption option1 = new com.yupi.codertestbackend.model.dto.ai.LevelOption();
72+
option1.setOptionName("Spring Boot框架");
73+
option1.setTrueAnswer(true);
74+
options.add(option1);
75+
76+
com.yupi.codertestbackend.model.dto.ai.LevelOption option2 = new com.yupi.codertestbackend.model.dto.ai.LevelOption();
77+
option2.setOptionName("MySQL数据库");
78+
option2.setTrueAnswer(true);
79+
options.add(option2);
80+
81+
// 干扰选项
82+
com.yupi.codertestbackend.model.dto.ai.LevelOption option3 = new com.yupi.codertestbackend.model.dto.ai.LevelOption();
83+
option3.setOptionName("汇编语言");
84+
option3.setTrueAnswer(false);
85+
options.add(option3);
86+
87+
return options;
88+
}
89+
}
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
package com.yupi.codertestbackend.service.ai.impl;
2+
3+
import com.yupi.codertestbackend.model.dto.ai.ResultReportResponse;
4+
import com.yupi.codertestbackend.service.ai.ResultReportAiService;
5+
import lombok.extern.slf4j.Slf4j;
6+
import org.springframework.stereotype.Service;
7+
8+
import java.util.Arrays;
9+
10+
/**
11+
* AI生成结果报告服务实现
12+
*/
13+
@Service
14+
@Slf4j
15+
public class ResultReportAiServiceImpl implements ResultReportAiService {
16+
17+
@Override
18+
public ResultReportResponse generateResultReport(String levelName, String levelDesc,
19+
String userOptions, String trueOptions, Integer salary) {
20+
try {
21+
// TODO: 这里应该调用实际的AI服务(如阿里云DashScope)
22+
// 读取提示词文件并构建请求
23+
// String systemPrompt = readPromptFile("prompts/result-report-system.txt");
24+
25+
// 现在先返回模拟数据
26+
log.info("模拟AI生成结果报告,关卡:{},薪资:{}", levelName, salary);
27+
28+
return createMockReport(levelName, userOptions, trueOptions, salary);
29+
30+
} catch (Exception e) {
31+
log.error("生成结果报告失败:{}", e.getMessage(), e);
32+
throw new RuntimeException("AI服务调用失败", e);
33+
}
34+
}
35+
36+
37+
/**
38+
* 创建模拟报告(用于测试)
39+
*/
40+
private ResultReportResponse createMockReport(String levelName, String userOptions,
41+
String trueOptions, Integer salary) {
42+
ResultReportResponse response = new ResultReportResponse();
43+
44+
// 模拟评分逻辑
45+
int score = calculateMockScore(userOptions, trueOptions);
46+
response.setScore(score);
47+
48+
// 根据分数生成评价和薪资变化
49+
if (score >= 90) {
50+
response.setComment("恭喜!你的表现非常出色,可以考虑升职加薪了!");
51+
response.setSalaryChange(1000);
52+
response.setSuggest("建议投递:阿巴阿巴集团、企鹅大王科技、字跳跳公司等一线互联网公司");
53+
} else if (score >= 70) {
54+
response.setComment("表现不错,继续努力就能更上一层楼!");
55+
response.setSalaryChange(500);
56+
response.setSuggest("建议投递:美团外卖、滴滴出行、小红薯等知名互联网公司");
57+
} else if (score >= 50) {
58+
response.setComment("还需要继续学习提升,加油!");
59+
response.setSalaryChange(0);
60+
response.setSuggest("建议先在当前公司积累经验,或考虑一些成长型公司");
61+
} else {
62+
response.setComment("需要重新审视自己的技术栈,建议多学习基础知识");
63+
response.setSalaryChange(-500);
64+
response.setSuggest("建议考虑培训机构或者初创公司积累经验");
65+
}
66+
67+
response.setReason(String.format("根据你在%s关卡的表现,得分%d分,主要考虑了技术选型的准确性和实现方案的合理性。",
68+
levelName, score));
69+
70+
// 设置正确选项
71+
response.setTrueOptions(Arrays.asList("Spring Boot框架", "MySQL数据库", "Redis缓存"));
72+
73+
// 设置标准答案解析
74+
response.setStandardAnswer(generateStandardAnswer(levelName));
75+
76+
return response;
77+
}
78+
79+
/**
80+
* 模拟计算分数
81+
*/
82+
private int calculateMockScore(String userOptions, String trueOptions) {
83+
// 简单的模拟评分逻辑
84+
try {
85+
// 这里可以解析JSON并进行对比
86+
// 现在简化处理,随机生成一个合理的分数
87+
return 60 + (int)(Math.random() * 35); // 60-95分之间
88+
} catch (Exception e) {
89+
return 60; // 默认及格分
90+
}
91+
}
92+
93+
/**
94+
* 生成标准答案解析
95+
*/
96+
private String generateStandardAnswer(String levelName) {
97+
return String.format("""
98+
## %s - 标准解决方案
99+
100+
### 技术架构设计
101+
102+
在企业级开发中,这类项目通常采用分层架构设计,包括表现层、业务逻辑层、数据访问层。
103+
104+
**核心技术选型:**
105+
- **后端框架**:Spring Boot提供了快速开发能力,内置了大量企业级特性
106+
- **数据库**:MySQL作为主流关系型数据库,提供ACID特性保证数据一致性
107+
- **缓存层**:Redis用于提升系统性能,减少数据库压力
108+
109+
### 实现关键点
110+
111+
1. **数据库设计**:合理的表结构设计,建立适当的索引提升查询效率
112+
2. **接口设计**:RESTful API设计,保证接口的可维护性和扩展性
113+
3. **安全控制**:实现用户认证授权,防止SQL注入等安全问题
114+
4. **性能优化**:通过缓存、分页、异步处理等方式提升系统性能
115+
116+
### 部署运维
117+
118+
采用Docker容器化部署,配合CI/CD流水线实现自动化部署和运维监控。
119+
120+
这样的技术方案既保证了系统的稳定性,又具备了良好的可扩展性,是企业级项目的标准实践。
121+
""", levelName);
122+
}
123+
}

0 commit comments

Comments
 (0)