构建一个由人工智能驱动的博客平台(Next.js、Langchain 和 CopilotKit)CopilotKit:开源 Copilot 框架

2025-05-24

构建一个由人工智能驱动的博客平台(Next.js、Langchain 和 CopilotKit)

CopilotKit:开源 Copilot 框架

TL;DR

在本文中,您将学习如何构建一个由人工智能驱动的博客平台,该平台可以搜索网络并研究博客文章的任何主题。

我们将涵盖:

  • 用于应用程序框架的 Next.js 🖥️
  • OpenAI 法学硕士项目
  • LangChain 和 Tavily 打造的网页搜索 AI 代理 🤖
  • 使用 CopilotKit 将 AI 集成到您的应用程序中
  • Supabase 用于存储和检索博客平台文章数据。

图片描述


CopilotKit:开源 Copilot 框架

CopilotKit 是开源的 AI Copilot 框架和平台。我们让您能够轻松地将强大的 AI 集成到您的 React 应用中。

建造:

  • ChatBots💬:具有上下文感知能力的应用内聊天机器人,可以在应用内采取行动

  • CopilotTextArea📝:具有上下文感知自动完成和插入功能的 AI 驱动文本字段

  • 协同代理🤖:应用内 AI 代理,可与你的应用和用户互动。由 LangChain 提供支持。

图片描述

明星 CopilotKit ⭐️

现在回到文章。


先决条件

在开始构建应用程序之前,让我们先看看构建应用程序所需的依赖项或包

  • copilotkit/react-core:CopilotKit 前端包带有反应钩子,用于向副驾驶提供应用程序状态和操作(AI 功能)
  • copilotkit/react-ui:聊天机器人侧边栏 UI 的 CopilotKit 前端包
  • copilotkit/react-textarea:CopilotKit 前端包,用于演示文稿演讲者笔记中的 AI 辅助文本编辑。
  • LangChainJS:由语言模型驱动的应用程序开发框架。
  • Tavily Search API:帮助将 LLM 和 AI 应用程序连接到可信实时知识的 API。

安装所有项目包和依赖项

在安装所有项目包和依赖项之前,让我们首先通过在终端上运行以下命令来创建一个 Nextjs 项目。

npx create-next-app@latest
Enter fullscreen mode Exit fullscreen mode

然后,系统会提示您选择一些选项。请随意标记它们,如下所示。

图片描述

之后,使用您选择的文本编辑器打开新创建的 Nextjs 项目。然后在命令行上运行以下命令来安装所有项目包和依赖项。

npm i @copilotkit/backend @copilotkit/shared @langchain/langgraph @copilotkit/react-core @copilotkit/react-ui @copilotkit/react-textarea @supabase/ssr @supabase/auth-helpers-nextjs
Enter fullscreen mode Exit fullscreen mode

创建博客平台前端

在本节中,我将引导您完成使用静态内容创建博客平台前端的过程,以定义平台的用户界面。

首先,请转到 /[root]/src/app 并创建一个名为的文件夹 components。在 components 文件夹中,创建一个名为 的文件 Article.tsx

之后,将以下代码添加到定义名为 的功能组件的文件中, Article该组件将用于呈现文章创建表单。

"use client";

import { useRef, useState } from "react";

export function Article() {
  // Define state variables for article outline, copilot text, and article title
  const [articleOutline, setArticleOutline] = useState("");
  const [copilotText, setCopilotText] = useState("");
  const [articleTitle, setArticleTitle] = useState("");

  return (
    // Form element for article input
    <form
      action={""}
      className="w-full h-full gap-10 flex flex-col items-center p-10">
      {/* Input field for article title */}
      <div className="flex w-full items-start gap-3">
        <textarea
          className="p-2 w-full h-12 rounded-lg flex-grow overflow-x-auto overflow-y-hidden whitespace-nowrap"
          id="title"
          name="title"
          value={articleTitle}
          placeholder="Article Title"
          onChange={(event) => setArticleTitle(event.target.value)}
        />
      </div>

      {/* Textarea for article content */}
      <textarea
        className="p-4 w-full aspect-square font-bold text-xl bg-slate-800 text-white rounded-lg resize-none"
        id="content"
        name="content"
        value={copilotText}
        placeholder="Write your article content here"
        onChange={(event) => setCopilotText(event.target.value)}
      />

      {/* Publish button */}
      <button
        type="submit"
        className="p-4 w-full !bg-slate-800 text-white rounded-lg">Publish</button>
    </form>
  );
}

Enter fullscreen mode Exit fullscreen mode

接下来,在 components 文件夹中添加另一个文件,并将其命名为 Header.tsx。然后将以下代码添加到定义名为 的功能组件的文件中, Header该组件将呈现博客平台的导航栏。

import Link from "next/link";

export default function Header() {
  return (
    <>
      <header className="flex flex-wrap sm:justify-start sm:flex-nowrap z-50 w-full bg-white border-b border-gray-200 text-sm py-3 sm:py-0 ">
        <nav
          className="relative max-w-7xl w-full mx-auto px-4 sm:flex sm:items-center sm:justify-between sm:px-6 lg:px-8"
          aria-label="Global">
          <div className="flex items-center justify-between">
            <Link
              className="flex-none text-xl font-semibold "
              href="/"
              aria-label="Brand">
              AIBlogging
            </Link>
          </div>
          <div id="navbar-collapse-with-animation" className="">
            <div className="flex flex-col gap-y-4 gap-x-0 mt-5 sm:flex-row sm:items-center sm:justify-end sm:gap-y-0 sm:gap-x-7 sm:mt-0 sm:ps-7">
              <Link
                className="flex items-center font-medium text-gray-500 border-2 border-indigo-600 text-center p-2 rounded-md hover:text-blue-600 sm:border-s sm:my-6 "
                href="/writearticle">
                Create Post
              </Link>
            </div>
          </div>
        </nav>
      </header>
    </>
  );
}
Enter fullscreen mode Exit fullscreen mode

之后,转到 /[root]/src/app 并创建一个名为 的文件夹 writearticle。在该writearticle文件夹中,创建一个名为 file 的文件 。然后将以下代码添加到导入和组件的page.tsx 文件中。该代码随后定义了一个名为 的功能组件,它将渲染导航栏和文章创建表单。ArticleHeaderWriteArticle

import { Article } from "../components/Article";
import Header from "../components/Header";

export default function WriteArticle() {
  return (
    <>
      <Header />
      <Article />
    </>
  );
}

Enter fullscreen mode Exit fullscreen mode

接下来,转到 /[root]/src/page.tsx文件,并添加以下代码,该代码定义一个名为的功能组件,Home该组件呈现博客平台主页,显示已发布文章的列表。

import Image from "next/image";
import Link from "next/link";
import Header from "./components/Header";

const Home = async () => {
  return (
    <>
      <Header />
      <div className="max-w-[85rem] h-full px-4 py-10 sm:px-6 lg:px-8 lg:py-14 mx-auto">
        <div className="grid sm:grid-cols-2 lg:grid-cols-3 gap-6">
          <Link
            key={""}
            className="group flex flex-col h-full bg-white border border-gray-200 hover:border-transparent hover:shadow-lg transition-all duration-300 rounded-xl p-5 "
            href={""}>
            <div className="aspect-w-16 aspect-h-11">
              <Image
                className="object-cover h-48 w-96 rounded-xl"
                src={`https://source.unsplash.com/featured/?${encodeURIComponent(
                  "hello world"
                )}`}
                width={500}
                height={500}
                alt="Image Description"
              />
            </div>
            <div className="my-6">
              <h3 className="text-xl font-semibold text-gray-800 ">
                Hello World
              </h3>
            </div>
          </Link>
        </div>
      </div>
    </>
  );
};

export default Home;
Enter fullscreen mode Exit fullscreen mode

之后,转到next.config.js文件并添加以下代码,允许您使用来自 Unsplash 的图像作为已发布文章的封面图像。

module.exports = {
  images: {
    remotePatterns: [
      {
        protocol: "https",
        hostname: "source.unsplash.com",
      },
    ],
  },
};

Enter fullscreen mode Exit fullscreen mode

npm run dev 最后,在命令行上 运行该命令 ,然后导航到http://localhost:3000/。现在您应该可以在浏览器上查看博客平台前端,如下所示。

图片描述

将博客平台与 CopilotKit 后端集成

在本节中,我将引导您完成博客平台与 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"
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 文件夹中,创建一个名为 的文件 research.ts。然后导航到此 research.ts gist 文件,复制代码并将其添加到 research.ts 文件中。

route.ts 接下来,在文件夹中 创建一个名为的文件 /[root]/src/app/api/copilotkit 。该文件将包含设置后端功能以处理 POST 请求的代码。它有条件地包含一个“研究”操作,该操作针对给定主题执行研究。

现在在文件顶部导入以下模块。

import { CopilotBackend, OpenAIAdapter } from "@copilotkit/backend"; // For backend functionality with CopilotKit.
import { researchWithLangGraph } from "./research"; // Import a custom function for conducting research.
import { AnnotatedFunction } from "@copilotkit/shared"; // For annotating functions with metadata.

Enter fullscreen mode Exit fullscreen mode

在上面的代码下方,定义一个运行时环境变量和一个名为的函数researchAction,使用下面的代码对某个主题进行研究。

// Define a runtime environment variable, indicating the environment where the code is expected to run.
export const runtime = "edge";

// Define an annotated function for research. This object includes metadata and an implementation for the function.
const researchAction: AnnotatedFunction<any> = {
  name: "research", // Function name.
  description: "Call this function to conduct research on a certain topic. Respect other notes about when to call this function", // Function description.
  argumentAnnotations: [ // Annotations for arguments that the function accepts.
    {
      name: "topic", // Argument name.
      type: "string", // Argument type.
      description: "The topic to research. 5 characters or longer.", // Argument description.
      required: true, // Indicates that the argument is required.
    },
  ],
  implementation: async (topic) => { // The actual function implementation.
    console.log("Researching topic: ", topic); // Log the research topic.
    return await researchWithLangGraph(topic); // Call the research function and return its result.
  },
};

Enter fullscreen mode Exit fullscreen mode

然后在上面的代码下添加下面的代码来定义一个处理POST请求的异步函数。

// Define an asynchronous function that handles POST requests.
export async function POST(req: Request): Promise<Response> {
  const actions: AnnotatedFunction<any>[] = []; // Initialize an array to hold actions.

  // Check if a specific environment variable is set, indicating access to certain functionality.
  if (process.env["TAVILY_API_KEY"]) {
    actions.push(researchAction); // Add the research action to the actions array if the condition is true.
  }

  // Instantiate CopilotBackend with the actions defined above.
  const copilotKit = new CopilotBackend({
    actions: actions,
  });

  // Use the CopilotBackend instance to generate a response for the incoming request using an OpenAIAdapter.
  return copilotKit.response(req, new OpenAIAdapter());
}
Enter fullscreen mode Exit fullscreen mode

将博客平台与 CopilotKit 前端集成

在本节中,我将引导您完成将博客平台与 CopilotKit 前端集成的过程,以方便进行博客文章研究和文章大纲生成。我们将使用一个聊天机器人侧边栏组件、一个 Copilot 文本区域组件、一个 useMakeCopilotReadable 钩子(用于向 Copilot 提供应用状态和其他信息)以及一个 useCopilotAction 钩子(用于提供 Copilot 可以调用的操作)。

首先, 在 文件 顶部 导入useMakeCopilotReadable、、和钩子useCopilotActionCopilotTextareaHTMLCopilotTextAreaElement/[root]/src/app/components/Article.tsx

import {
  useMakeCopilotReadable,
  useCopilotAction,
} from "@copilotkit/react-core";
import {
  CopilotTextarea,
  HTMLCopilotTextAreaElement,
} from "@copilotkit/react-textarea";
Enter fullscreen mode Exit fullscreen mode

在 Article 函数内部,在状态变量下方,添加以下代码,该代码使用 useMakeCopilotReadable 钩子添加文章大纲,该大纲将作为应用内聊天机器人的上下文生成。该钩子使副驾驶能够读取文章大纲。

useMakeCopilotReadable("Blog article outline: " + JSON.stringify(articleOutline));

Enter fullscreen mode Exit fullscreen mode

在钩子下面useMakeCopilotReadable ,使用下面的代码创建copilotTextareaRef对名为 的 textarea 元素的引用HTMLCopilotTextAreaElement

const copilotTextareaRef = useRef<HTMLCopilotTextAreaElement>(null);
Enter fullscreen mode Exit fullscreen mode

在上述代码下方,添加以下代码,该代码使用 useCopilotAction 钩子设置一个名为 的操作, researchBlogArticleTopic 该操作将启用博客文章中指定主题的研究。该操作接受两个名为articleTitlearticleOutline的参数,用于生成文章标题和大纲。

该操作包含一个处理函数,该函数根据给定的主题生成文章标题和大纲。在处理函数内部,articleOutline状态会使用新生成的大纲进行更新,同时articleTitle状态也会使用新生成的标题进行更新,如下所示。

useCopilotAction(
    {
      name: "researchBlogArticleTopic",
      description: "Research a given topic for a blog article.",
      parameters: [
        {
          name: "articleTitle",
          type: "string",
          description: "Title for a blog article.",
          required: true,
        },
        {
          name: "articleOutline",
          type: "string",
          description:"Outline for a blog article that shows what the article covers.",
          required: true,
        },
      ],
      handler: async ({ articleOutline, articleTitle }) => {
        setArticleOutline(articleOutline);

        setArticleTitle(articleTitle);
      },
    },
    []
  );
Enter fullscreen mode Exit fullscreen mode

在上面的代码下方,转到表单组件并添加以下CopilotTextarea元素,使您能够向文章内容添加完成、插入和编辑。

<CopilotTextarea
        value={copilotText}
        ref={copilotTextareaRef}
        placeholder="Write your article content here"
        onChange={(event) => setCopilotText(event.target.value)}
        className="p-4 w-full aspect-square font-bold text-xl bg-slate-800 text-white rounded-lg resize-none"
        placeholderStyle={{
          color: "white",
          opacity: 0.5,
        }}
        autosuggestionsConfig={{
          textareaPurpose: articleTitle,
          chatApiConfigs: {
            suggestionsApiConfig: {
              forwardedParams: {
                max_tokens: 5,
                stop: ["\n", ".", ","],
              },
            },
            insertionApiConfig: {},
          },
          debounceTime: 250,
        }}
      />
Enter fullscreen mode Exit fullscreen mode

然后将 Tailwindcss 隐藏类添加到用于保存文章内容的 Textarea 中,如下所示。该 Textarea 将保存文章内容,并在文章发布后将其插入数据库。

{/* Textarea for article content */}
      <textarea
        className="p-4 w-full aspect-square font-bold text-xl bg-slate-800 text-white rounded-lg resize-none hidden"
        id="content"
        name="content"
        value={copilotText}
        placeholder="Write your article content here"
        onChange={(event) => setCopilotText(event.target.value)}
      />
Enter fullscreen mode Exit fullscreen mode

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

import { CopilotKit } from "@copilotkit/react-core";
import { CopilotSidebar } from "@copilotkit/react-ui";
import "@copilotkit/react-ui/styles.css";
import "@copilotkit/react-textarea/styles.css";
Enter fullscreen mode Exit fullscreen mode

然后使用 CopilotKit 和 CopilotSidebar 包装 Article 组件,如下所示。该CopilotKit组件指定 CopilotKit 后端端点 ( ) 的 URL,/api/copilotkit/openai/同时CopilotSidebar渲染应用内聊天机器人,您可以提示用户研究文章中的任何主题。

export default function WriteArticle() {
  return (
    <>
      <Header />
      <CopilotKit url="/api/copilotkit">
        <CopilotSidebar
          instructions="Help the user research a blog article topic."
          defaultOpen={true}
          labels={{
            title: "Blog Article Copilot",
            initial:
              "Hi you! 👋 I can help you research any topic for a blog article.",
          }}
          clickOutsideToClose={false}>
          <Article />
        </CopilotSidebar>
      </CopilotKit>
    </>
  );
}
Enter fullscreen mode Exit fullscreen mode

之后,运行开发服务器并导航至 http://localhost:3000/writearticle。您应该看到应用内聊天机器人已集成到博客平台中。

图片描述

给右侧的聊天机器人一个提示,例如“研究一个关于生成式人工智能的博客文章主题,并给我文章大纲。”聊天机器人将开始研究该主题,然后生成博客标题。

当您开始在编辑器上写作时,您应该会看到内容自动建议,如下所示。

图片描述

将博客平台与 Supabase 数据库集成

在本节中,我将引导您完成将博客平台与 Supabase 数据库集成以插入和获取博客文章数据的过程。

首先,导航至supabase.com并单击主页上的“开始您的项目”按钮。

图片描述

然后创建一个名为AiBloggingPlatform的新项目,如下所示。

图片描述

创建项目后,将您的 Supabase URL 和 API 密钥添加到 env.local 文件中的环境变量中,如下所示。

NEXT_PUBLIC_SUPABASE_URL=Your Supabase URL
NEXT_PUBLIC_SUPABASE_ANON_KEY=Your Supabase API Key
Enter fullscreen mode Exit fullscreen mode

之后,转到 Supabase 上的项目仪表板并打开 SQL 编辑器部分。然后将以下 SQL 代码添加到编辑器中,并单击 CTRL + Enter 键以创建一个名为“articles”的表。articles 表包含 id、title 和 content 行。

create table if not exists
  articles (
    id bigint primary key generated always as identity,
    title text,
    content text
  );
Enter fullscreen mode Exit fullscreen mode

一旦表创建完成,您应该会收到一条成功消息,如下所示。

图片描述

之后,转到/[root]/src/文件夹并创建一个名为 的文件夹utils。在该utils文件夹内,创建一个名为 的文件supabase.ts,并添加以下代码,用于创建并返回 Supabase 客户端。

// Importing necessary functions and types from the Supabase SSR package
import { createServerClient, type CookieOptions } from '@supabase/ssr'

// Define a function named 'supabase' that takes a 'CookieOptions' object as input
export const supabase = (cookies: CookieOptions) => {
    // Retrieve cookies from the provided 'CookieOptions' object
    const cookieStore = cookies()

    // Create and return a Supabase client configured with environment variables and cookie handling
    return createServerClient(
        // Retrieve Supabase URL from environment variables
        process.env.NEXT_PUBLIC_SUPABASE_URL!,
        // Retrieve Supabase anonymous key from environment variables
        process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
        {
            cookies: {
                // Define a custom 'get' function to retrieve cookies by name from the cookie store
                get(name: string) {
                    return cookieStore.get(name)?.value
                },
            },
        }
    )
}

Enter fullscreen mode Exit fullscreen mode

然后转到/[root]/src/app文件夹并创建一个名为的文件夹serveractions。在该serveractions文件夹中,创建一个名为的文件AddArticle.ts,并添加以下代码,将博客文章数据插入 Supabase 数据库。

// Importing necessary functions and modules for server-side operations
"use server";
import { createServerComponentClient } from "@supabase/auth-helpers-nextjs";
import { cookies } from "next/headers";
import { redirect } from "next/navigation";

// Define an asynchronous function named 'addArticle' that takes form data as input
export async function addArticle(formData: any) {
  // Extract title and content from the provided form data
  const title = formData.get("title");
  const content = formData.get("content");

  // Retrieve cookies from the HTTP headers
  const cookieStore = cookies();

  // Create a Supabase client configured with the provided cookies
  const supabase = createServerComponentClient({ cookies: () => cookieStore });

  // Insert the article data into the 'articles' table on Supabase
  const { data, error } = await supabase.from("articles").insert([
    {
      title,
      content,
    },
  ]);

  // Check for errors during the insertion process
  if (error) {
    console.error("Error inserting data", error);
    return;
  }

  // Redirect the user to the home page after successfully adding the article
  redirect("/");

  // Return a success message
  return { message: "Success" };
}
Enter fullscreen mode Exit fullscreen mode

之后,转到/[root]/src/app/components/Article.tsx 文件并导入该addArticle函数。

import { addArticle } from "../serveractions/AddArticle";
Enter fullscreen mode Exit fullscreen mode

然后添加该addArticle函数作为表单操作参数,如下所示。

// Form element for article input
    <form
      action={addArticle}
      className="w-full h-full gap-10 flex flex-col items-center p-10"> 

      </form>
Enter fullscreen mode Exit fullscreen mode

之后,导航到  http://localhost:3000/writearticle,研究您选择的主题,添加文章内容,然后单击底部的发布按钮以发布文章。

然后前往 Supabase 上的项目仪表板,并导航到“表编辑器”部分。您应该会看到文章数据已插入 Supabase 数据库,如下所示。

图片描述

接下来,转到/[root]/src/app/page.tsx文件并在顶部导入 cookies 和 supabase 包。

import { cookies } from "next/headers";
import { supabase } from "@/utils/supabase";
Enter fullscreen mode Exit fullscreen mode

然后在 Home 函数中,添加以下从 Supabase 数据库获取文章数据的代码。

const { data: articles, error } = await supabase(cookies).from('articles').select('*')
Enter fullscreen mode Exit fullscreen mode

之后,更新元素代码如下所示,以在博客平台主页上呈现已发布的文章。

return (
    <>
      <Header />
      <div className="max-w-[85rem] h-full px-4 py-10 sm:px-6 lg:px-8 lg:py-14 mx-auto">
        <div className="grid sm:grid-cols-2 lg:grid-cols-3 gap-6">
          {articles?.map((post: any) => (
            <Link
              key={post.id}
              className="group flex flex-col h-full bg-white border border-gray-200 hover:border-transparent hover:shadow-lg transition-all duration-300 rounded-xl p-5 "
              href={`/posts/${post.id}`}>
              <div className="aspect-w-16 aspect-h-11">
                <Image
                  className="object-cover h-48 w-96 rounded-xl"
                  src={`https://source.unsplash.com/featured/?${encodeURIComponent(
                    post.title
                  )}`}
                  width={500}
                  height={500}
                  alt="Image Description"
                />
              </div>
              <div className="my-6">
                <h3 className="text-xl font-semibold text-gray-800 ">
                  {post.title}
                </h3>
              </div>
            </Link>
          ))}
        </div>
      </div>
    </>
  );
Enter fullscreen mode Exit fullscreen mode

然后导航到  http://localhost:3000您应该会看到您发布的文章,如下所示。

图片描述

之后,转到/[root]/src/app文件夹并创建一个名为的文件夹[id].[id]文件夹中,创建一个名为的文件page.tsx并在顶部导入以下包和组件。

import { supabase } from '@/utils/supabase';
import { cookies } from "next/headers";
import Header from '@/app/components/Header';
Enter fullscreen mode Exit fullscreen mode

在导入下方,定义一个名为“getArticles”的异步函数,该函数根据 id 参数从 supabase 数据库中检索文章数据,如下所示。

// Define an asynchronous function named 'getArticles' that retrieves article data based on the provided parameters
async function getArticles(params: any) {
    // Extract the 'id' parameter from the provided 'params' object
    const { id } = params

    // Retrieve article data from Supabase database where the 'id' matches the provided value
    const { data, error } = await supabase(cookies)
        .from('articles')
        .select('*')
        .eq('id', id)
        .single();

    // Return the retrieved data
    return data
  }
Enter fullscreen mode Exit fullscreen mode

在上面的代码下方,定义一个名为“Post”的函数,该函数以“params”作为属性,如下所示。

// Define a default asynchronous function named 'Post' that takes 'params' as props
export default async function Post({ params }: { params: any }) {
  // Retrieve the post data asynchronously based on the provided 'params'
  const post = await getArticles(params);

  // Return JSX to render the post details
  return (
    <>
      {/* Render the header component */}
      <Header />
      {/* Main content wrapper */}
      <div className="max-w-3xl px-4 pt-6 lg:pt-10 pb-12 sm:px-6 lg:px-8 mx-auto">
        <div className="max-w-2xl">
          <div className="space-y-5 md:space-y-8">
            <div className="space-y-3">
              {/* Render the post title */}
              <h2 className="text-2xl font-bold md:text-3xl dark:text-white">
                {/* Render the post title only if 'post' is truthy */}
                {post && post.title}
              </h2>
              {/* Render the post content */}
              <p className="text-lg text-gray-800 dark:text-gray-200">
                {/* Render the post content only if 'post' is truthy */}
                {post && post.content}
              </p>
            </div>
          </div>
        </div>
      </div>
    </>
  );
}
Enter fullscreen mode Exit fullscreen mode

之后,导航到  http://localhost:3000并单击博客平台主页上显示的文章。

然后您将被重定向到文章的内容,如下所示。

图片描述

结论

总而言之,您可以使用 CopilotKit 构建应用内 AI 聊天机器人,它可以查看当前应用状态并在应用内执行操作。该 AI 聊天机器人可以与您的应用前端、后端以及第三方服务进行通信。

完整源代码:https://github.com/TheGreatBonnie/aipoweredblog

文章来源:https://dev.to/copilotkit/how-to-build-an-ai-powered-blogging-platform-nextjs-langchain-supabase-1hdp
PREV
如何使用 Maybe Finance 和 CopilotKit 构建一个由 AI 驱动的开源财务管理器⚡️
NEXT
如何构建:基于 AI 的 PowerPoint 生成器(Next.js、OpenAI、CopilotKit)TL;DR