AI岗位推荐,修改候选岗位池2000
This commit is contained in:
@@ -614,7 +614,7 @@ public class JobService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 求职助手岗位推荐
|
* 求职助手岗位推荐
|
||||||
* <p>1. 查求职意向构造筛选条件(无意向则不设条件) 2. 排除已推荐的+已投递的 3. 取前35条候选 4. AI精筛返回8-10个</p>
|
* <p>1. 查求职意向构造筛选条件(无意向则不设条件) 2. 排除已推荐的+已投递的 3. 取2000条候选池 4. 随机取100条 5. AI精筛返回8-10个</p>
|
||||||
*/
|
*/
|
||||||
public JobAgentRecommendDto recommendJobs(JobAgentRecommendParam param, Long userId) {
|
public JobAgentRecommendDto recommendJobs(JobAgentRecommendParam param, Long userId) {
|
||||||
StopWatch sw = new StopWatch("recommendJobs");
|
StopWatch sw = new StopWatch("recommendJobs");
|
||||||
@@ -627,12 +627,13 @@ public class JobService {
|
|||||||
// 2. 构造查询参数
|
// 2. 构造查询参数
|
||||||
JobQueryParam queryParam = new JobQueryParam();
|
JobQueryParam queryParam = new JobQueryParam();
|
||||||
queryParam.setPageNum(1);
|
queryParam.setPageNum(1);
|
||||||
queryParam.setPageSize(100);
|
queryParam.setPageSize(2000);
|
||||||
if (intention != null) {
|
if (intention != null) {
|
||||||
queryParam.setCategoryIds(intention.getCategoryIds());
|
queryParam.setCategoryIds(intention.getCategoryIds());
|
||||||
queryParam.setRegionCodes(intention.getRegionCodes());
|
queryParam.setRegionCodes(intention.getRegionCodes());
|
||||||
queryParam.setIndustryIds(intention.getIndustryIds());
|
queryParam.setIndustryIds(intention.getIndustryIds());
|
||||||
queryParam.setEmploymentType(intention.getEmploymentType());
|
queryParam.setEmploymentType(intention.getEmploymentType());
|
||||||
|
queryParam.setRecruitCategory(intention.getRecruitCategory());
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. 合并排除列表:入参传的 + 已投递/待投递的
|
// 3. 合并排除列表:入参传的 + 已投递/待投递的
|
||||||
@@ -646,7 +647,7 @@ public class JobService {
|
|||||||
applications.forEach(a -> excludeIds.add(a.getJobId()));
|
applications.forEach(a -> excludeIds.add(a.getJobId()));
|
||||||
queryParam.setExcludeJobIds(excludeIds);
|
queryParam.setExcludeJobIds(excludeIds);
|
||||||
|
|
||||||
// 4. 查询候选岗位(完整列表数据)
|
// 4. 查询候选池(2000条)
|
||||||
sw.start("查候选岗位");
|
sw.start("查候选岗位");
|
||||||
PageResult<JobDto> candidates = listJobs(queryParam, userId);
|
PageResult<JobDto> candidates = listJobs(queryParam, userId);
|
||||||
sw.stop();
|
sw.stop();
|
||||||
@@ -657,27 +658,34 @@ public class JobService {
|
|||||||
return dto;
|
return dto;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5. 批量查岗位详情(title + description + requirement)
|
// 5. 随机取100条作为AI候选
|
||||||
|
List<JobDto> candidateList = new ArrayList<>(candidates.getList());
|
||||||
|
Collections.shuffle(candidateList);
|
||||||
|
if (candidateList.size() > 100) {
|
||||||
|
candidateList = candidateList.subList(0, 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6. 批量查岗位详情(title + description + requirement)
|
||||||
sw.start("查岗位详情");
|
sw.start("查岗位详情");
|
||||||
List<Long> candidateJobIds = candidates.getList().stream().map(JobDto::getId).collect(Collectors.toList());
|
List<Long> candidateJobIds = candidateList.stream().map(JobDto::getId).collect(Collectors.toList());
|
||||||
List<Job> jobDetails = jobMapper.selectList(new LambdaQueryWrapper<Job>().in(Job::getId, candidateJobIds).select(Job::getId, Job::getTitle, Job::getDescription, Job::getRequirement));
|
List<Job> jobDetails = jobMapper.selectList(new LambdaQueryWrapper<Job>().in(Job::getId, candidateJobIds).select(Job::getId, Job::getTitle, Job::getDescription, Job::getRequirement));
|
||||||
Map<Long, Job> jobDetailMap = jobDetails.stream().collect(Collectors.toMap(Job::getId, j -> j));
|
Map<Long, Job> jobDetailMap = jobDetails.stream().collect(Collectors.toMap(Job::getId, j -> j));
|
||||||
sw.stop();
|
sw.stop();
|
||||||
|
|
||||||
// 6. 构造别名映射(短序号 → 真实ID)和候选岗位映射
|
// 7. 构造别名映射(短序号 → 真实ID)和候选岗位映射
|
||||||
Map<Integer, Long> aliasToRealId = new HashMap<>();
|
Map<Integer, Long> aliasToRealId = new HashMap<>();
|
||||||
Map<Long, JobDto> candidateMap = new HashMap<>();
|
Map<Long, JobDto> candidateMap = new HashMap<>();
|
||||||
int seq = 1;
|
int seq = 1;
|
||||||
for (JobDto dto : candidates.getList()) {
|
for (JobDto dto : candidateList) {
|
||||||
aliasToRealId.put(seq, dto.getId());
|
aliasToRealId.put(seq, dto.getId());
|
||||||
candidateMap.put(dto.getId(), dto);
|
candidateMap.put(dto.getId(), dto);
|
||||||
seq++;
|
seq++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 7. 构造AI输入(用短序号替代19位雪花ID,减少token消耗)
|
// 8. 构造AI输入(用短序号替代19位雪花ID,减少token消耗)
|
||||||
StringBuilder jobInfo = new StringBuilder();
|
StringBuilder jobInfo = new StringBuilder();
|
||||||
seq = 1;
|
seq = 1;
|
||||||
for (JobDto dto : candidates.getList()) {
|
for (JobDto dto : candidateList) {
|
||||||
Job detail = jobDetailMap.get(dto.getId());
|
Job detail = jobDetailMap.get(dto.getId());
|
||||||
jobInfo.append("ID:").append(seq++)
|
jobInfo.append("ID:").append(seq++)
|
||||||
.append("\n标题:").append(dto.getTitle())
|
.append("\n标题:").append(dto.getTitle())
|
||||||
@@ -695,7 +703,7 @@ public class JobService {
|
|||||||
"只返回JSON,不要其他内容。";
|
"只返回JSON,不要其他内容。";
|
||||||
String userMessage = "【用户偏好(仅供参考)】\n" + preferenceInfo + "\n\n【候选岗位】\n" + jobInfo;
|
String userMessage = "【用户偏好(仅供参考)】\n" + preferenceInfo + "\n\n【候选岗位】\n" + jobInfo;
|
||||||
|
|
||||||
// 8. 调用AI
|
// 9. 调用AI
|
||||||
sw.start("AI调用");
|
sw.start("AI调用");
|
||||||
String aiResponse = aiChatAbility.chat("job-recommend", systemPrompt, userMessage);
|
String aiResponse = aiChatAbility.chat("job-recommend", systemPrompt, userMessage);
|
||||||
String json = AiResponseCleanTool.clean(aiResponse);
|
String json = AiResponseCleanTool.clean(aiResponse);
|
||||||
@@ -703,7 +711,7 @@ public class JobService {
|
|||||||
|
|
||||||
log.info("recommendJobs耗时统计:\n{}", sw.prettyPrint());
|
log.info("recommendJobs耗时统计:\n{}", sw.prettyPrint());
|
||||||
|
|
||||||
// 9. 解析AI返回,别名映射回真实ID,过滤出选中的岗位
|
// 10. 解析AI返回,别名映射回真实ID,过滤出选中的岗位
|
||||||
try {
|
try {
|
||||||
JsonNode root = HttpTool.objectMapper.readTree(json);
|
JsonNode root = HttpTool.objectMapper.readTree(json);
|
||||||
String summary = root.path("summary").asText("为你精选了合适的岗位");
|
String summary = root.path("summary").asText("为你精选了合适的岗位");
|
||||||
|
|||||||
Reference in New Issue
Block a user