构建 AI 驱动的简历和求职信生成器(CopilotKit、LangChain、Tavily 和 Next.js)CopilotKit:用于构建应用内 AI 副驾驶员的开源框架

2025-05-24

构建 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 代理🤖

https://media2.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx3us3vc140aun0dvrdof.gif

明星 CopilotKit ⭐️


先决条件

要完全理解本教程,您需要对 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


Enter fullscreen mode Exit fullscreen mode

选择您喜欢的配置设置。在本教程中,我们将使用 TypeScript 和 Next.js App Router。

图片描述

接下来,安装 React Markdown 和 OpenAI 包及其依赖项。



npm i react-markdown openai


Enter fullscreen mode Exit fullscreen mode

最后,安装 CopilotKit 软件包。这些软件包使我们能够从 React 状态中检索数据,并将 AI Copilot 添加到应用程序中。



npm install @copilotkit/react-ui @copilotkit/react-core @copilotkit/backend


Enter fullscreen mode Exit fullscreen mode

恭喜!现在您可以构建一个由 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;


Enter fullscreen mode Exit fullscreen mode

接下来,转到 /[root]/src/page.tsx 文件,并添加以下代码,导入 Resume 组件并定义一个名为的功能组件 Home



import Resume from "./components/Resume";

export default function Home() {
  return <Resume />;
}


Enter fullscreen mode Exit fullscreen mode

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";


Enter fullscreen mode Exit fullscreen mode

在函数内部 Resume ,在状态变量下方,添加以下代码,该代码使用 useCopilotReadable 钩子添加将作为应用内聊天机器人上下文生成的简历和求职信。该钩子使副驾驶能够读取简历和求职信。



useCopilotReadable({
    description: "The user's cover letter.",
    value: coverLetter,
  });

  useCopilotReadable({
    description: "The user's resume.",
    value: resume,
  });


Enter fullscreen mode Exit fullscreen mode

在上面的代码下方,添加以下代码,该代码使用 useCopilotAction 钩子来设置一个名为的操作, createCoverLetterAndResume 这将启用简历和求职信的生成。

该操作接受两个参数,分别称为coverLetterMarkdownresumeMarkdown,用于生成简历和求职信。它包含一个处理函数,用于根据给定的提示生成简历和求职信。

在处理程序函数内部, 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
  [],
);


Enter fullscreen mode Exit fullscreen mode

之后,转到 /[root]/src/app/page.tsx 文件并使用以下代码在顶部导入 CopilotKit 前端包和样式。



import { CopilotKit } from "@copilotkit/react-core";
import { CopilotSidebar } from "@copilotkit/react-ui";
import "@copilotkit/react-ui/styles.css";


Enter fullscreen mode Exit fullscreen mode

然后使用 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>
  );
}


Enter fullscreen mode Exit fullscreen mode

之后,运行开发服务器并导航至 http://localhost:3000。您应该看到应用内聊天机器人已集成到简历和求职信生成器中。

图片描述

将 CopilotKit 后端添加到博客

在这里,我将引导您完成简历和求职信生成器与 CopilotKit 后端集成的过程,该后端处理来自前端的请求,并提供函数调用和各种 LLM 后端(例如 GPT)。

此外,我们还将集成一个名为 Tavily 的 AI 代理,它可以抓取网络上任何给定链接上的内容。

首先,在根目录中创建一个名为 的文件 。然后在保存您的 搜索 API 密钥.env.local 的文件中添加以下环境变量  。ChatGPTTavily




OPENAI_API_KEY="Your ChatGPT API key"
TAVILY_API_KEY="Your Tavily Search API key"
OPENAI_MODEL=gpt-4-1106-preview


Enter fullscreen mode Exit fullscreen mode

要获取 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;
}



Enter fullscreen mode Exit fullscreen mode

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 }));
}

Enter fullscreen mode Exit fullscreen mode




如何生成简历和求职信

现在转到您之前集成的应用内聊天机器人并添加 LinkedIn、GitHub 或 X 个人资料链接,然后按 Enter 键。

添加链接后,聊天机器人将使用 LangChain 和 Tavily 从链接配置文件中抓取内容。然后,它将使用这些内容生成简历和求职信。

生成的简历应如下所示。

图片描述

生成的求职信应如下所示。

图片描述

恭喜!您已完成本教程的项目。

结论

您现在可以构建一个出色的人工智能简历生成器,既可以磨练您的人工智能构建技能,又可以简化您的求职过程!

如果您喜欢这篇文章,请记得点赞并保存,并告诉我您接下来想看到哪些主题。

文章来源:https://dev.to/copilotkit/build-an-ai-powered-resume-cover-letter-generator-copilotkit-langchain-tavily-nextjs-1nkc
PREV
构建基于 AI 的社交媒体帖子调度程序(Twitter API、Next.js 和 Copilotkit)
NEXT
如何让 AI 融入你的用户(Next.js、OpenAI、CopilotKit)