This commit is contained in:
张成
2025-11-24 13:23:42 +08:00
commit 5d7444cd65
156 changed files with 50653 additions and 0 deletions

View File

@@ -0,0 +1,289 @@
const axios = require('axios');
const config = require('../../../config/config');
const logs = require('../logProxy');
/**
* DeepSeek大模型服务
* 集成DeepSeek API提供智能化的岗位筛选、聊天生成、简历分析等功能
*/
class aiService {
constructor() {
this.apiKey = config.deepseekApiKey || process.env.DEEPSEEK_API_KEY;
this.apiUrl = config.deepseekApiUrl || 'https://api.deepseek.com/v1/chat/completions';
this.model = config.deepseekModel || 'deepseek-chat';
this.maxRetries = 3;
}
/**
* 调用DeepSeek API
* @param {string} prompt - 提示词
* @param {object} options - 配置选项
* @returns {Promise<object>} API响应结果
*/
async callAPI(prompt, options = {}) {
const requestData = {
model: this.model,
messages: [
{
role: 'system',
content: options.systemPrompt || '你是一个专业的招聘顾问,擅长分析岗位信息、生成聊天内容和分析简历匹配度。'
},
{
role: 'user',
content: prompt
}
],
temperature: options.temperature || 0.7,
max_tokens: options.maxTokens || 2000,
top_p: options.topP || 0.9
};
for (let attempt = 1; attempt <= this.maxRetries; attempt++) {
try {
const response = await axios.post(this.apiUrl, requestData, {
headers: {
'Authorization': `Bearer ${this.apiKey}`,
'Content-Type': 'application/json'
},
timeout: 30000
});
return {
data: response.data,
content: response.data.choices?.[0]?.message?.content || ''
};
} catch (error) {
console.log(`DeepSeek API调用失败 (尝试 ${attempt}/${this.maxRetries}): ${error.message}`);
if (attempt === this.maxRetries) {
throw new Error(error.message);
}
// 等待后重试
await new Promise(resolve => setTimeout(resolve, 1000 * attempt));
}
}
}
/**
* 岗位智能筛选
* @param {object} jobInfo - 岗位信息
* @param {object} resumeInfo - 简历信息
* @returns {Promise<object>} 筛选结果
*/
async analyzeJob(jobInfo, resumeInfo) {
const prompt = `
请分析以下岗位信息,并给出详细的评估结果:
岗位信息:
- 公司名称:${jobInfo.companyName || '未知'}
- 职位名称:${jobInfo.jobTitle || '未知'}
- 薪资范围:${jobInfo.salary || '未知'}
- 工作地点:${jobInfo.location || '未知'}
- 岗位描述:${jobInfo.description || '未知'}
- 技能要求:${jobInfo.skills || '未知'}
简历信息:
- 技能标签:${resumeInfo.skills || '未知'}
- 工作经验:${resumeInfo.experience || '未知'}
- 教育背景:${resumeInfo.education || '未知'}
- 期望薪资:${resumeInfo.expectedSalary || '未知'}
请从以下维度进行分析:
1. 技能匹配度0-100分
2. 经验匹配度0-100分
3. 薪资合理性0-100分
4. 公司质量评估0-100分
5. 是否为外包岗位(是/否)
6. 综合推荐指数0-100分
7. 详细分析说明
8. 投递建议
请以JSON格式返回结果。
`;
const result = await this.callAPI(prompt, {
systemPrompt: '你是一个专业的招聘分析师,擅长评估岗位与简历的匹配度。请提供客观、专业的分析结果。',
temperature: 0.3
});
try {
// 尝试解析JSON响应
const analysis = JSON.parse(result.content);
return {
analysis: analysis
};
} catch (parseError) {
// 如果解析失败,返回原始内容
return {
analysis: {
content: result.content,
parseError: true
}
};
}
}
/**
* 生成个性化聊天内容
* @param {object} jobInfo - 岗位信息
* @param {object} resumeInfo - 简历信息
* @param {string} chatType - 聊天类型 (greeting/interview/followup)
* @returns {Promise<object>} 聊天内容
*/
async generateChatContent(jobInfo, resumeInfo, chatType = 'greeting') {
const chatTypeMap = {
'greeting': '初次打招呼',
'interview': '面试邀约',
'followup': '跟进沟通'
};
const prompt = `
请为以下场景生成个性化的聊天内容:
聊天类型:${chatTypeMap[chatType] || chatType}
岗位信息:
- 公司名称:${jobInfo.companyName || '未知'}
- 职位名称:${jobInfo.jobTitle || '未知'}
- 技能要求:${jobInfo.skills || '未知'}
简历信息:
- 技能标签:${resumeInfo.skills || '未知'}
- 工作经验:${resumeInfo.experience || '未知'}
- 项目经验:${resumeInfo.projects || '未知'}
要求:
1. 内容要自然、专业、个性化
2. 突出简历与岗位的匹配点
3. 避免过于机械化的表达
4. 长度控制在100-200字
5. 体现求职者的诚意和热情
请直接返回聊天内容,不需要其他格式。
`;
const result = await this.callAPI(prompt, {
systemPrompt: '你是一个专业的招聘沟通专家,擅长生成自然、专业的求职聊天内容。',
temperature: 0.8
});
return result;
}
/**
* 分析简历要素
* @param {string} resumeText - 简历文本内容
* @returns {Promise<object>} 简历分析结果
*/
async analyzeResume(resumeText) {
const prompt = `
请分析以下简历内容,提取核心要素:
简历内容:
${resumeText}
请提取以下信息:
1. 技能标签(编程语言、框架、工具等)
2. 工作经验(年限、行业、项目等)
3. 教育背景(学历、专业、证书等)
4. 期望薪资范围
5. 期望工作地点
6. 核心优势
7. 职业发展方向
请以JSON格式返回结果。
`;
const result = await this.callAPI(prompt, {
systemPrompt: '你是一个专业的简历分析师,擅长提取简历的核心要素和关键信息。',
temperature: 0.2
});
try {
const analysis = JSON.parse(result.content);
return {
analysis: analysis
};
} catch (parseError) {
return {
analysis: {
content: result.content,
parseError: true
}
};
}
}
/**
* 生成面试邀约内容
* @param {object} jobInfo - 岗位信息
* @param {object} chatHistory - 聊天历史
* @returns {Promise<object>} 面试邀约内容
*/
async generateInterviewInvitation(jobInfo, chatHistory) {
const prompt = `
请基于以下信息生成面试邀约内容:
岗位信息:
- 公司名称:${jobInfo.companyName || '未知'}
- 职位名称:${jobInfo.jobTitle || '未知'}
- 工作地点:${jobInfo.location || '未知'}
聊天历史:
${chatHistory || '无'}
要求:
1. 表达面试邀约的诚意
2. 提供灵活的时间选择
3. 说明面试形式和地点
4. 体现对候选人的重视
5. 语言自然、专业
请直接返回面试邀约内容。
`;
const result = await this.callAPI(prompt, {
systemPrompt: '你是一个专业的HR擅长生成面试邀约内容。',
temperature: 0.6
});
return result;
}
/**
* 识别外包岗位
* @param {object} jobInfo - 岗位信息
* @returns {Promise<object>} 外包识别结果
*/
async identifyOutsourcingJob(jobInfo) {
const prompt = `
请分析以下岗位信息,判断是否为外包岗位:
岗位信息:
- 公司名称:${jobInfo.companyName || '未知'}
- 职位名称:${jobInfo.jobTitle || '未知'}
- 岗位描述:${jobInfo.description || '未知'}
- 技能要求:${jobInfo.skills || '未知'}
- 工作地点:${jobInfo.location || '未知'}
外包岗位特征:
1. 公司名称包含"外包"、"派遣"、"人力"等关键词
2. 岗位描述提到"项目外包"、"驻场开发"等
3. 技能要求过于宽泛或具体
4. 工作地点频繁变动
5. 薪资结构不明确
请判断是否为外包岗位,并给出详细分析。
`;
const result = await this.callAPI(prompt, {
systemPrompt: '你是一个专业的岗位分析师,擅长识别外包岗位的特征。',
temperature: 0.3
});
return result;
}
}
module.exports = new aiService();