构建 AI 驱动的简历和求职信生成器(CopilotKit、LangChain、Tavily 和 Next.js)
CopilotKit:用于构建应用内 AI 副驾驶的开源框架
TL;DR
对于有抱负的开发人员来说,构建一个伟大的项目是最好的简历。
好吧,今天我们将一举两得;我将教你如何构建一个尖端的、由人工智能驱动的应用程序,该应用程序将根据你的 LinkedIn、GitHub 和 X 生成你的简历和求职信。
这个项目和你随后的简历将会让任何雇主惊叹不已。
我们将介绍如何:
- 使用 Next.js、TypeScript 和 Tailwind CSS 构建简历和求职信生成器 Web 应用程序。
- 使用 CopilotKit 将 AI 功能集成到简历和求职信生成器中。
- 使用 Langchain 和 Tavily 来抓取您的 LinkedIn、GitHub 或 X 个人资料内容。
CopilotKit:用于构建应用内 AI 副驾驶的开源框架
CopilotKit 是一个 开源的 AI 副驾驶平台。我们可以轻松地将强大的 AI 集成到你的 React 应用中。
建造:
- ChatBot:具有上下文感知能力的应用内聊天机器人,可以在应用内采取行动💬
- CopilotTextArea:具有上下文感知自动完成和插入功能的 AI 驱动文本字段📝
- 合作代理:可以与您的应用和用户交互的应用内 AI 代理🤖
先决条件
要完全理解本教程,您需要对 React 或 Next.js 有基本的了解。
以下是构建人工智能简历和求职信生成器所需的工具:
- React Markdown - 一个 React 组件,可以为其提供一串 markdown 以安全地呈现为 React 元素。
- Langchain—— 提供一个框架,使 AI 代理能够搜索网络、研究和抓取任何主题或链接。
- OpenAI API - 提供 API 密钥,使您能够使用 ChatGPT 模型执行各种任务。
- Tavily AI—— 一种搜索引擎,使 AI 代理能够进行研究或抓取数据并访问应用程序内的实时知识。
- CopilotKit - 一个开源副驾驶框架,用于构建自定义 AI 聊天机器人、应用内 AI 代理和文本区域。
项目设置和包安装
首先,通过在终端中运行以下代码片段来创建 Next.js 应用程序:
npx create-next-app@latest airesumecoverlettergenerator
选择您喜欢的配置设置。在本教程中,我们将使用 TypeScript 和 Next.js App Router。
接下来,安装 React Markdown 和 OpenAI 包及其依赖项。
npm i react-markdown openai
最后,安装 CopilotKit 软件包。这些软件包使我们能够从 React 状态中检索数据,并将 AI Copilot 添加到应用程序中。
npm install @copilotkit/react-ui @copilotkit/react-core @copilotkit/backend
恭喜!现在您可以构建一个由 AI 驱动的简历和求职信生成器了。
构建简历和求职信生成器前端
在本节中,我将引导您完成创建简历和求职信生成器前端的过程,并使用静态内容来定义生成器的用户界面。
首先, /[root]/src/app
在代码编辑器中创建一个名为 的文件夹 components
。在 components 文件夹中,创建一个名为 Resume.tsx
在该 Resume.tsx
文件中,添加以下代码,定义一个名为的 React 功能组件 Resume
。
"use client";
// Import React and necessary hooks from the react library
import React from "react";
import { useState } from "react";
// Import the ReactMarkdown component to render markdown content
import ReactMarkdown from "react-markdown";
// Import the Link component from Next.js for navigation
import Link from "next/link";
function Resume() {
// State variables to store the resume and cover letter content
const [coverLetter, setCoverLetter] = useState("");
const [resume, setResume] = useState("");
return (
// Main container with flex layout, full width, and minimum height of screen
<div className="flex flex-col w-full min-h-screen bg-gray-100 dark:bg-gray-800">
{/* Header section with a fixed height, padding, and border at the bottom */}
<header className="flex items-center h-16 px-4 border-b shrink-0 md:px-6 bg-white dark:bg-gray-900">
{/* Link component for navigation with custom styles */}
<Link
href="#"
className="flex items-center gap-2 text-lg font-semibold md:text-base"
prefetch={false}>
<span className="sr-only text-gray-500">Resume Dashboard</span>
<h1>Resume & Cover Letter Generator</h1>
</Link>
</header>
{/* Main content area with padding */}
<main className="flex-1 p-4 md:p-8 lg:p-10">
{/* Container for the content with maximum width and centered alignment */}
<div className="max-w-4xl mx-auto grid gap-8">
{/* Section for displaying the resume */}
<section>
<div className="bg-white dark:bg-gray-900 rounded-lg shadow-sm">
<div className="p-6 md:p-8">
<h2 className="text-lg font-bold">Resume</h2>
<div className="my-6" />
<div className="grid gap-6">
{/* Conditional rendering of the resume content */}
{resume ? (
<ReactMarkdown>{resume}</ReactMarkdown>
) : (
<div>No Resume To Display</div>
)}
</div>
</div>
</div>
</section>
{/* Section for displaying the cover letter */}
<section>
<div className="bg-white dark:bg-gray-900 rounded-lg shadow-sm">
<div className="p-6 md:p-8">
<h2 className="text-lg font-bold">Cover Letter</h2>
<div className="my-6" />
<div className="grid gap-4">
{/* Conditional rendering of the cover letter content */}
{coverLetter ? (
<ReactMarkdown>{coverLetter}</ReactMarkdown>
) : (
<div>No Cover Letter To Display</div>
)}
</div>
</div>
</div>
</section>
</div>
</main>
</div>
);
}
export default Resume;
接下来,转到 /[root]/src/page.tsx
文件,并添加以下代码,导入 Resume
组件并定义一个名为的功能组件 Home
。
import Resume from "./components/Resume";
export default function Home() {
return <Resume />;
}
npm run dev
最后,在命令行上 运行该命令 ,然后导航到http://localhost:3000/。
现在您应该在浏览器上查看简历和求职信生成器前端,如下所示。
恭喜!现在,您可以将 AI 功能添加到 AI 驱动的简历和求职信生成器中了。
使用 CopilotKit 将 AI 功能集成到简历和求职信生成器中
在本节中,您将学习如何将 AI 副驾驶添加到简历和求职信生成器,以使用 CopilotKit 生成简历和求职信。
CopilotKit 提供前端和 后端 软件包。它们使您能够接入 React 状态并使用 AI 代理在后端处理应用程序数据。
首先,让我们将 CopilotKit React 组件添加到简历和求职信生成器前端。
将 CopilotKit 添加到待办事项列表生成器前端
在这里,我将引导您完成将简历和求职信生成器与 CopilotKit 前端集成的过程,以促进简历和求职信的生成。
首先,使用下面的代码片段 在文件顶部 导入useCopilotReadable
、和 、自定义挂钩 。useCopilotAction
/src/app/components/Resume.tsx
import { useCopilotAction, useCopilotReadable } from "@copilotkit/react-core";
在函数内部 Resume
,在状态变量下方,添加以下代码,该代码使用 useCopilotReadable
钩子添加将作为应用内聊天机器人上下文生成的简历和求职信。该钩子使副驾驶能够读取简历和求职信。
useCopilotReadable({
description: "The user's cover letter.",
value: coverLetter,
});
useCopilotReadable({
description: "The user's resume.",
value: resume,
});
在上面的代码下方,添加以下代码,该代码使用 useCopilotAction
钩子来设置一个名为的操作, createCoverLetterAndResume
这将启用简历和求职信的生成。
该操作接受两个参数,分别称为coverLetterMarkdown
和resumeMarkdown
,用于生成简历和求职信。它包含一个处理函数,用于根据给定的提示生成简历和求职信。
在处理程序函数内部, coverLetter
状态resume
会使用新生成的简历和求职信标记进行更新,如下所示。
useCopilotAction(
{
// Define the name of the action
name: "createCoverLetterAndResume",
// Provide a description for the action
description: "Create a cover letter and resume for a job application.",
// Define the parameters required for the action
parameters: [
{
// Name of the first parameter
name: "coverLetterMarkdown",
// Type of the first parameter
type: "string",
// Description of the first parameter
description:
"Markdown text for a cover letter to introduce yourself and briefly summarize your professional background.",
// Mark the first parameter as required
required: true,
},
{
// Name of the second parameter
name: "resumeMarkdown",
// Type of the second parameter
type: "string",
// Description of the second parameter
description:
"Markdown text for a resume that displays your professional background and relevant skills.",
// Mark the second parameter as required
required: true,
},
],
// Define the handler function to be executed when the action is called
handler: async ({ coverLetterMarkdown, resumeMarkdown }) => {
// Update the state with the provided cover letter markdown text
setCoverLetter(coverLetterMarkdown);
// Update the state with the provided resume markdown text
setResume(resumeMarkdown);
},
},
// Empty dependency array, indicating this effect does not depend on any props or state
[],
);
之后,转到 /[root]/src/app/page.tsx
文件并使用以下代码在顶部导入 CopilotKit 前端包和样式。
import { CopilotKit } from "@copilotkit/react-core";
import { CopilotSidebar } from "@copilotkit/react-ui";
import "@copilotkit/react-ui/styles.css";
然后使用 CopilotKit
包装 CopilotSidebar
和 Resume
组件,如下所示。 组件指定 CopilotKit 后端端点 ( ) CopilotKit
的 URL,而 则 渲染应用内聊天机器人,您可以向其提供生成简历和求职信的提示。/api/copilotkit/
CopilotSidebar
export default function Home() {
return (
<CopilotKit runtimeUrl="/api/copilotkit">
<CopilotSidebar
instructions={"Help the user create a cover letter and resume"}
labels={{
initial:
"Welcome to the cover letter app! Add your LinkedIn, X, or GitHub profile link below.",
}}
defaultOpen={true}
clickOutsideToClose={false}>
<Resume />
</CopilotSidebar>
</CopilotKit>
);
}
之后,运行开发服务器并导航至 http://localhost:3000。您应该看到应用内聊天机器人已集成到简历和求职信生成器中。
将 CopilotKit 后端添加到博客
在这里,我将引导您完成简历和求职信生成器与 CopilotKit 后端集成的过程,该后端处理来自前端的请求,并提供函数调用和各种 LLM 后端(例如 GPT)。
此外,我们还将集成一个名为 Tavily 的 AI 代理,它可以抓取网络上任何给定链接上的内容。
首先,在根目录中创建一个名为 的文件 。然后在保存您的 搜索 API 密钥.env.local
的文件中添加以下环境变量 。ChatGPT
Tavily
OPENAI_API_KEY="Your ChatGPT API key"
TAVILY_API_KEY="Your Tavily Search API key"
OPENAI_MODEL=gpt-4-1106-preview
要获取 ChatGPT API 密钥,请导航至 https://platform.openai.com/api-keys。
要获取 Tavily Search API 密钥,请导航至 https://app.tavily.com/home
然后,转到 /[root]/src/app
并创建一个名为 的文件夹 api
。在该 api
文件夹中,创建一个名为 的文件夹 copilotkit
。
在该 copilotkit
文件夹中,创建一个名为 的文件 tavily.ts
并添加以下代码。该代码定义了一个异步函数scrape
,该函数以链接作为输入,将此链接发送到 Tavily API,处理 JSON 响应,然后使用 OpenAI 的语言模型以简单的英语生成响应摘要。
// Import the OpenAI library
import OpenAI from "openai";
// Define an asynchronous function named `scrape` that takes a search query string as an argument
export async function scrape(query: string) {
// Send a POST request to the specified API endpoint with the search query and other parameters
const response = await fetch("https://api.tavily.com/search", {
method: "POST", // HTTP method
headers: {
"Content-Type": "application/json", // Specify the request content type as JSON
},
body: JSON.stringify({
api_key: process.env.TAVILY_API_KEY, // API key from environment variables
query, // The search query passed to the function
search_depth: "basic", // Search depth parameter
include_answer: true, // Include the answer in the response
include_images: false, // Do not include images in the response
include_raw_content: false, // Do not include raw content in the response
max_results: 20, // Limit the number of results to 20
}),
});
// Parse the JSON response from the API
const responseJson = await response.json();
// Instantiate the OpenAI class
const openai = new OpenAI();
// Use the OpenAI API to create a completion based on the JSON response
const completion = await openai.chat.completions.create({
messages: [
{
role: "system", // Set the role of the message to system
content: `Summarize the following JSON to answer the research query \`"${query}"\`: ${JSON.stringify(
responseJson
)} in plain English.`, // Provide the JSON response to be summarized
},
],
model: process.env.OPENAI_MODEL || "gpt-4", // Specify the OpenAI model, defaulting to GPT-4 if not set in environment variables
});
// Return the content of the first message choice from the completion response
return completion.choices[0].message.content;
}
route.ts
接下来,在文件夹中 创建一个名为 的文件 copilotkit
,并添加以下代码。该代码使用 CopilotKit 框架设置抓取操作,以根据给定链接获取并汇总内容。
然后,它定义一个操作来调用 scrape 函数并返回结果。如果所需的 API 密钥可用,它会将此操作添加到 CopilotKit 运行时,并使用环境变量中指定的 OpenAI 模型响应 POST 请求。
// Import necessary modules and functions
import { CopilotRuntime, OpenAIAdapter } from "@copilotkit/backend";
import { Action } from "@copilotkit/shared";
import { scrape } from "./tavily"; // Import the previously defined scrape function
// Define a scraping action with its name, description, parameters, and handler function
const scrapingAction: Action<any> = {
name: "scrapeContent", // Name of the action
description: "Call this function to scrape content from a url in a query.", // Description of the action
parameters: [
{
name: "query", // Name of the parameter
type: "string", // Type of the parameter
description:
"The query for scraping content. 5 characters or longer. Might be multiple words", // Description of the parameter
},
],
// Handler function to execute when the action is called
handler: async ({ query }) => {
console.log("Scraping query: ", query); // Log the query to the console
const result = await scrape(query); // Call the scrape function with the query and await the result
console.log("Scraping result: ", result); // Log the result to the console
return result; // Return the result
},
};
// Define an asynchronous POST function to handle POST requests
export async function POST(req: Request): Promise<Response> {
const actions: Action<any>[] = []; // Initialize an empty array to store actions
// Check if the TAVILY_API_KEY environment variable is set
if (process.env["TAVILY_API_KEY"]) {
actions.push(scrapingAction); // Add the scraping action to the actions array
}
// Create a new instance of CopilotRuntime with the defined actions
const copilotKit = new CopilotRuntime({
actions: actions,
});
const openaiModel = process.env["OPENAI_MODEL"]; // Get the OpenAI model from environment variables
// Return the response from CopilotKit, using the OpenAIAdapter with the specified model
return copilotKit.response(req, new OpenAIAdapter({ model: openaiModel }));
}
如何生成简历和求职信
现在转到您之前集成的应用内聊天机器人并添加 LinkedIn、GitHub 或 X 个人资料链接,然后按 Enter 键。
添加链接后,聊天机器人将使用 LangChain 和 Tavily 从链接配置文件中抓取内容。然后,它将使用这些内容生成简历和求职信。
生成的简历应如下所示。
生成的求职信应如下所示。
恭喜!您已完成本教程的项目。
结论
您现在可以构建一个出色的人工智能简历生成器,既可以磨练您的人工智能构建技能,又可以简化您的求职过程!
如果您喜欢这篇文章,请记得点赞并保存,并告诉我您接下来想看到哪些主题。
文章来源:https://dev.to/copilotkit/build-an-ai-powered-resume-cover-letter-generator-copilotkit-langchain-tavily-nextjs-1nkc