大型语言模型(例如GPT-3)对于简化常规任务很有用。例如,我们可以使用非结构化的数据,例如PDF中的工作申请人的简历,并将其转换为结构化数据,并将其填充到我们的申请人跟踪系统(ATS)(例如Greenhouse)或可行。
。在本文中,我将向您展示一个node.js应用程序。但是,尽管GPT-3简化了常规数据输入作业,但作为开发人员,我们仍然需要连接所有相应的API以下载申请人的简历,从PDF获取文本,然后将数据放在ATS上。幸运的是,Superface使我们摆脱了这种常规的API接线。我们在许多API提供商中提供统一的界面。例如,从可行的人HR切换为一行更改。
让我们检查一下此应用程序执行的步骤:
- 加载了从申请人跟踪系统(ATS)(例如可行或温室)申请给定工作的候选人的简历。
- 将简历转换为文本并将文本解析为可读的数据。
- 使用从CV获得的数据更新ATS中的候选人。
您可以在CV Analyzer repository中找到完整的应用程序。它使用以下软件包:
- @superfaceai/one-sdk -Superface OnesDK用于与ATS,OpenAI和CloudMersive SaaS提供商集成。
- node-fetch -nodefetch用于获取简历文档。
- dotenv -dotenv用于加载环境变量。
- inquirer-询问器.js用于构建交互式用户界面。
我们还依靠Superface Catalog的这些用例:
在此演示中,我们使用Workable作为ATS,Cloudmersive将候选人的简历转换为纯文本,而OpenAI提供商将CV转换为结构化数据。但是您不仅限于这三个提供商。对于ATS用例,您还可以使用Breezy HR,Greenhouse和many others。
设置应用程序
- 克隆应用程序存储库并输入其目录。
git clone git@github.com:superfaceai/cv-analyzer.git
cd cv-analyzer
- 安装依赖项。
npm install
- 为提供者创建帐户(如果您还没有):
- 可行的优惠15 days free trial。需要一个工作电子邮件地址来创建帐户。
- CloudMersive的free tier限制为每月800个请求。
- OpenAi在头三个月内提供free trial的free trial,免费信用$ 18。
- 复制示例
.env
文件。
cp .env.example .env
- 设置
.env
文件中提供商的凭据和集成参数。
- Get Workable Access Token and Subdomain.
- 创建CloudMersive Free Tier Key。
- Create OpenAI Secret API Key.
-
创建一个工作位置并在可行的ATS中添加新候选人。
-
启动应用程序。
npm start
应用程序启动后,它将向您显示候选人列表。当您选择一个时,它将通过从其CV中解析的数据更新候选人的条目。
应用程序如何工作
该应用程序的主要流在src/index.js文件中,该文件调用src/use_cases.js文件中定义的用例。
选择候选人并获得其简历
首先,我们列出所选职位的开放职位和候选人。这是用List Jobs用例来处理的;一旦用户选择职位职位,我们将使用List Candidates用例与工作位置的各个ID:
exports.listCandidates = async (sdk, providerOptions, jobId) => {
const listCandidatesProfile = await sdk.getProfile(
'recruitment/list-candidates@1.0.0'
);
const listCandidatesResult = await listCandidatesProfile
.getUseCase('ListCandidates')
.perform(
{
jobId,
},
providerOptions
);
return listCandidatesResult.unwrap().candidates;
};
我们使用选定候选人的ID,并使用Get CV用例使用候选人的简历获取文档的URL(通常是PDF,但ATS也可以接受其他格式):
exports.getCVUrl = async (sdk, providerOptions, candidateId) => {
const getCVProfile = await sdk.getProfile('recruitment/get-cv@1.0.0');
const getCVResult = await getCVProfile.getUseCase('GetCV').perform(
{
candidateId,
},
providerOptions
);
return getCVResult.unwrap().cv.documentUrl;
};
将简历转换为文本
现在,我们知道候选人的简历可以下载哪里,但是我们需要以某种方式从中提取文本。我们使用Convert Document to Text用例来获取文档并将其上传到转换提供商(在此示例中cloudMersive)并获取纯文本以返回。
exports.convertCVToText = async (sdk, providerOptions, cvDocumentUrl) => {
const docToTextProfile = await sdk.getProfile(
'file-conversion/doc-to-text@1.0.0'
);
const fetchDocumentResponse = await fetch(cvDocumentUrl);
if (!fetchDocumentResponse.body) {
console.error('Failed to fetch CV document.');
return;
}
const result = await docToTextProfile
.getUseCase('ConvertDocumentToText')
.perform(
{
fileName: 'cv.pdf',
content: BinaryData.fromStream(fetchDocumentResponse.body),
},
providerOptions
);
return result.unwrap().text;
};
提取结构化数据
现在是时候采用AI魔术了!我们通过Text Completion用例使用OpenAI的GPT-3模型。我们为模型提供了一个提示,解释了我们需要返回的特定数据作为JSON:
exports.analyzeCV = async (sdk, providerOptions, cvText) => {
try {
const generateTextProfile = await sdk.getProfile('ai/generate-text@1.0.0');
const promptCommand = `Parse following job applicant resume and return json object with properties
{
"firstName", "lastName", "address", "phone",
"education":
[{"school", "fieldOfStudy", "studiedFrom_ISO8601":"YYYY-MM-DD", "studiedTill_ISO8601":"YYYY-MM-DD"}],
"workHistory":
[{"company", "position", "summary", "workedFrom_ISO8601:"YYYY-MM-DD"", "workedTill_ISO8601":"YYYY-MM-DD"}]
}. `;
const result = await generateTextProfile.getUseCase('CompleteText').perform(
{
prompt: promptCommand + cvText,
creativity: 0.8,
approxMaxWords: 1000,
model: 'large',
},
providerOptions
);
analyzeCVOutcome = result.unwrap();
} catch (error) {
console.error('Failed to analyze CV.', error);
}
// ...
};
如果分析顺利进行,并且模型完成了我们的提示,我们将返回的完成将其转换为JSON:
const parsedCV = JSON.parse(analyzeCVOutcome.completions[0]);
const mappedCV = {
...parsedCV,
education: parsedCV.education?.map(school => {
return {
school: school.school,
degree: school.degree,
fieldOfStudy: school.fieldOfStudy,
startedAt: school.studiedFrom_ISO8601,
endedAt: school.studiedTill_ISO8601,
};
}),
workHistory: parsedCV.workHistory?.map(work => {
// ...
}),
};
return mappedCV;
更新候选数据
现在,我们有一个带有从简历中提取结构化数据的JSON,我们可以使用Update Candidate用例将数据发送回ATS,以更新候选人的数据:
exports.updateCandidate = async (sdk, providerOptions, candidate) => {
const profile = await sdk.getProfile('recruitment/update-candidate@1.0.0');
const result = await profile
.getUseCase('UpdateCandidate')
.perform(candidate, providerOptions);
result.unwrap();
return true;
};
使用另一个ATS?
如果您查看代码,则不会提及可行,云代理或OpenAI。那是因为用例以提供商中立的方式设计。对于ATS,我们使用unified terminology,因此,如果您需要使用其他ATS,则无需重写整个应用程序。相反,您可以在src/index.js文件中更改atsProviderOptions
:
// Options for Workable
const atsProviderOptions = {
provider: 'workable',
parameters: {
SUBDOMAIN: process.env.WORKABLE_SUBDOMAIN,
},
security: {
bearer_token: {
token: process.env.WORKABLE_TOKEN,
},
},
};
,如果您想使用,例如Breezy HR,请将atsProviderOptions
设置为这样:
// Options for Breezy HR
const atsProviderOptions = {
provider: 'breezy-hr',
parameters: {
COMPANY_ID: process.env.BREEZY_HR_COMPANY_ID,
ACCESS_TOKEN: process.env.BREEZY_HR_ACCESS_TOKEN,
},
};
下一步
在此演示应用程序中,我们使用了来自3个不同API提供商的6种不同API用例,而从未查看API文档。这是超级表面的优点。
您是否需要集成申请人跟踪系统,例如可行,杠杆或SAP SuccessFactors?查看我们的Applicant Tracking Systems integrations。而且不要错过Superface catalog中的其他集成。