長話短說

在本文中,您將了解如何建立基於 AI 的行銷活動管理應用程式,該應用程式可讓您建立和分析廣告活動,從而使您能夠為您的業務做出正確的決策。

我們將介紹如何:

  • 使用 Next.js 建立 Web 應用程式,

  • 使用 CopilotKit 將 AI 助理整合到軟體應用程式中,以及

  • 建立特定於操作的人工智慧副駕駛來處理應用程式中的各種任務。

  • 建立一名競選經理

圖片描述


CopilotKit:建構應用內人工智慧副駕駛的框架

CopilotKit是一個開源的AI副駕駛平台。我們可以輕鬆地將強大的人工智慧整合到您的 React 應用程式中。

建造:

  • ChatBot:上下文感知的應用內聊天機器人,可以在應用程式內執行操作 💬

  • CopilotTextArea:人工智慧驅動的文字字段,具有上下文感知自動完成和插入功能📝

  • 聯合代理:應用程式內人工智慧代理,可以與您的應用程式和使用者互動🤖

https://media.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

{% cta https://git.new/devtoarticle1 %} Star CopilotKit ⭐️ {% endcta %}


先決條件

要完全理解本教程,您需要對 React 或 Next.js 有基本的了解。

我們還將利用以下內容:

  • Radix UI - 用於為應用程式建立可存取的 UI 元件。

  • OpenAI API 金鑰- 使我們能夠使用 GPT 模型執行各種任務。

  • CopilotKit - 一個開源副駕駛框架,用於建立自訂 AI 聊天機器人、應用程式內 AI 代理程式和文字區域。


專案設定和套件安裝

首先,透過在終端機中執行以下程式碼片段來建立 Next.js 應用程式:

npx create-next-app campaign-manager

選擇您首選的配置設定。在本教學中,我們將使用 TypeScript 和 Next.js App Router。

Next.js 應用程式安裝

接下來,將HeroiconsRadix UI及其原始元件安裝到專案中。

npm install @heroicons/react @radix-ui/react-avatar @radix-ui/react-dialog @radix-ui/react-dropdown-menu @radix-ui/react-icons @radix-ui/react-label @radix-ui/react-popover @radix-ui/react-select @radix-ui/react-slot @radix-ui/react-tabs

另外,安裝Recharts 程式庫(一個用於建立互動式圖表的 React 程式庫)以及以下實用程式套件:

npm install recharts class-variance-authority clsx cmdk date-fns lodash react-day-picker tailwind-merge tailwindcss-animate

最後,安裝CopilotKit 軟體套件。這些套件使 AI copilot 能夠從 React 狀態檢索資料並在應用程式中做出決策。

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

恭喜!您現在已準備好建立應用程式。


使用 Next.js 建立 Campaign Manager 應用程式

在本節中,我將引導您建立活動管理器應用程式的使用者介面。

首先,讓我們進行一些初始設定。

src資料夾中建立一個componentslib資料夾。

cd src
mkdir components lib

lib資料夾中,我們將聲明應用程式的靜態類型和預設活動。因此,在lib資料夾中建立data.tstypes.ts檔案。

cd lib
touch data.ts type.ts

將下面的程式碼片段複製到type.ts檔中。它聲明了活動屬性及其資料類型。

export interface Campaign {
    id: string;
    objective?:
        | "brand-awareness"
        | "lead-generation"
        | "sales-conversion"
        | "website-traffic"
        | "engagement";
    title: string;
    keywords: string;
    url: string;
    headline: string;
    description: string;
    budget: number;
    bidStrategy?: "manual-cpc" | "cpa" | "cpm";
    bidAmount?: number;
    segment?: string;
}

為應用程式建立預設的行銷活動清單並將其複製到data.ts檔案中。

import { Campaign } from "./types";

export let DEFAULT_CAMPAIGNS: Campaign[] = [
    {
        id: "1",
        title: "CopilotKit",
        url: "https://www.copilotkit.ai",
        headline: "Copilot Kit - The Open-Source Copilot Framework",
        description:
            "Build, deploy, and operate fully custom AI Copilots. In-app AI chatbots, AI agents, AI Textareas and more.",
        budget: 10000,
        keywords: "AI, chatbot, open-source, copilot, framework",
    },
    {
        id: "2",
        title: "EcoHome Essentials",
        url: "https://www.ecohomeessentials.com",
        headline: "Sustainable Living Made Easy",
        description:
            "Discover our eco-friendly products that make sustainable living effortless. Shop now for green alternatives!",
        budget: 7500,
        keywords: "eco-friendly, sustainable, green products, home essentials",
    },
    {
        id: "3",
        title: "TechGear Solutions",
        url: "https://www.techgearsolutions.com",
        headline: "Innovative Tech for the Modern World",
        description:
            "Find the latest gadgets and tech solutions. Upgrade your life with smart technology today!",
        budget: 12000,
        keywords: "tech, gadgets, innovative, modern, electronics",
    },
    {
        id: "4",
        title: "Global Travels",
        url: "https://www.globaltravels.com",
        headline: "Travel the World with Confidence",
        description:
            "Experience bespoke travel packages tailored to your dreams. Luxury, adventure, relaxation—your journey starts here.",
        budget: 20000,
        keywords: "travel, luxury, adventure, tours, global",
    },
    {
        id: "5",
        title: "FreshFit Meals",
        url: "https://www.freshfitmeals.com",
        headline: "Healthy Eating, Simplified",
        description:
            "Nutritious, delicious meals delivered to your door. Eating well has never been easier or tastier.",
        budget: 5000,
        keywords: "healthy, meals, nutrition, delivery, fit",
    },
];

由於我們使用 Radix UI 建立可以使用 TailwindCSS 輕鬆自訂的基本 UI 元件,因此請在lib資料夾中建立一個utils.ts文件,並將以下程式碼片段複製到該文件中。

//👉🏻 The lib folder now contains 3 files - data.ts, type.ts, util.ts
//👇🏻 Copy the code below into the "lib/util.ts" file.
import { type ClassValue, clsx } from "clsx";
import { twMerge } from "tailwind-merge";

export function cn(...inputs: ClassValue[]) {
    return twMerge(clsx(inputs));
}

export function randomId() {
    return Math.random().toString(36).substring(2, 15);
}

導航到components資料夾並在其中建立其他三個資料夾。

cd components
mkdir app dashboard ui

components/app資料夾將包含應用程式中使用的各種元件,而儀表板資料夾包含某些元素的 UI 元件。

ui資料夾包含使用 Radix UI 建立的多個 UI 元素。將專案儲存庫中的這些元素複製到該資料夾中。

恭喜! ui資料夾應包含必要的 UI 元素。現在,我們可以使用它們來建立應用程式中所需的各種元件。

建立應用程式 UI 元件

在這裡,我將引導您完成為應用程式建立使用者介面的過程。

應用程式使用者介面

首先,導航至app/page.tsx檔案並將以下程式碼片段貼到其中。該文件呈現在components/app資料夾中聲明的 App 元件。

"use client";
import { App } from "@/components/app/App";

export default function DashboardPage() {
    return <App />;
}

components/app資料夾中建立App.tsxCampaignForm.tsxMainNav.tsxUserNav.tsx檔案。

cd components/app
touch App.tsx CampaignForm.tsx MainNav.tsx UserNav.tsx

將下面的程式碼片段複製到App.tsx檔案中。

"use client";
import { DEFAULT_CAMPAIGNS } from "@/lib/data";
import { Campaign } from "@/lib/types";
import { randomId } from "@/lib/utils";
import { Dashboard } from "../dashboard/Dashboard";
import { CampaignForm } from "./CampaignForm";
import { useState } from "react";
import _ from "lodash";

export function App() {
    //👇🏻 default segments
    const [segments, setSegments] = useState<string[]>([
        "Millennials/Female/Urban",
        "Parents/30s/Suburbs",
        "Seniors/Female/Rural",
        "Professionals/40s/Midwest",
        "Gamers/Male",
    ]);

    const [campaigns, setCampaigns] = useState<Campaign[]>(
        _.cloneDeep(DEFAULT_CAMPAIGNS)
    );

    //👇🏻 updates campaign list
    function saveCampaign(campaign: Campaign) {
        //👇🏻 newly created campaign
        if (campaign.id === "") {
            campaign.id = randomId();
            setCampaigns([campaign, ...campaigns]);
        } else {
            //👇🏻 existing campaign - search for the campaign and updates the campaign list
            const index = campaigns.findIndex((c) => c.id === campaign.id);
            if (index === -1) {
                setCampaigns([...campaigns, campaign]);
            } else {
                campaigns[index] = campaign;
                setCampaigns([...campaigns]);
            }
        }
    }

    const [currentCampaign, setCurrentCampaign] = useState<Campaign | undefined>(
        undefined
    );

    return (
        <div className='relative'>
            <CampaignForm
                segments={segments}
                currentCampaign={currentCampaign}
                setCurrentCampaign={setCurrentCampaign}
                saveCampaign={(campaign) => {
                    if (campaign) {
                        saveCampaign(campaign);
                    }
                    setCurrentCampaign(undefined);
                }}
            />
            <Dashboard
                campaigns={campaigns}
                setCurrentCampaign={setCurrentCampaign}
                segments={segments}
                setSegments={setSegments}
            />
        </div>
    );
}
  • 從上面的程式碼片段來看,

  • 我為行銷活動建立了預設細分列表,並對已定義的行銷活動列表進行了深層複製。

  • saveCampaign函數接受行銷活動作為參數。如果行銷活動沒有 ID,則表示它是新建立的,因此會將其新增至行銷活動清單。否則,它會找到該活動並更新其屬性。

  • DashboardCampaignForm元件接受細分和行銷活動作為 props。

Dashboard 元件在儀表板上顯示各種 UI 元素,而CampaignForm 元件使用戶能夠在應用程式中建立和保存新的行銷活動。

您也可以使用GitHub 儲存庫中的程式碼片段來更新儀表板和應用程式元件。

恭喜!您應該有一個有效的 Web 應用程式,可讓使用者查看和建立新的行銷活動。

在接下來的部分中,您將了解如何將 CopilotKit 加入到應用程式中,以根據每個行銷活動的目標和預算進行分析和決策。

應用概述


使用 CopilotKit 透過 AI 分析廣告活動

在這裡,您將學習如何將人工智慧加入到應用程式中,以幫助您分析行銷活動並做出最佳決策。

在繼續之前,請造訪OpenAI 開發者平台並建立一個新的金鑰。

取得 OpenAI API 金鑰

建立一個.env.local檔案並將新建立的金鑰複製到該檔案中。

OPENAI_API_KEY=<YOUR_OPENAI_SECRET_KEY>
OPENAI_MODEL=gpt-4-1106-preview

接下來,您需要為 CopilotKit 建立 API 端點。在 Next.js 應用程式資料夾中,建立一個包含route.ts檔案的api/copilotkit資料夾。

cd app
mkdir api && cd api
mkdir copilotkit && cd copilotkit
touch route.ts

將下面的程式碼片段複製到route.ts檔中。 CopilotKit 後端接受使用者的請求並使用 OpenAI 模型做出決策。

import { CopilotBackend, OpenAIAdapter } from "@copilotkit/backend";

export const runtime = "edge";

export async function POST(req: Request): Promise<Response> {
    const copilotKit = new CopilotBackend({});
    const openaiModel = process.env["OPENAI_MODEL"];

    return copilotKit.response(req, new OpenAIAdapter({ model: openaiModel }));
}

若要將您的應用程式連接到此 API 端點,請更新app/page.tsx文件,如下所示:

"use client";
import { App } from "@/components/app/App";
import { CopilotKit } from "@copilotkit/react-core";
import { CopilotSidebar } from "@copilotkit/react-ui";

export default function DashboardPage() {
    return (
        <CopilotKit url='/api/copilotkit/'>
            <CopilotSidebar
                instructions='Help the user create and manage ad campaigns.'
                defaultOpen={true}
                labels={{
                    title: "Campaign Manager Copilot",
                    initial:
                        "Hello there! I can help you manage your ad campaigns. What campaign would you like to work on?",
                }}
                clickOutsideToClose={false}
            >
                <App />
            </CopilotSidebar>
        </CopilotKit>
    );
}

CopilotKit元件包裝整個應用程式並接受包含 API 端點連結的url屬性。 CopilotSidebar元件為應用程式加入了一個聊天機器人側邊欄面板,使我們能夠向 CopilotKit 提供各種指令。

將 CopilotKit 加入 Next.js

如何讓AI副駕駛執行各種動作

CopilotKit 提供了兩個鉤子,使我們能夠處理使用者的請求並插入應用程式狀態: useCopilotActionuseMakeCopilotReadable

useCopilotAction掛鉤可讓您定義 CopilotKit 執行的動作。它接受包含以下參數的物件:

  • name - 操作的名稱。

  • 描述 - 操作的描述。

  • 參數 - 包含所需參數清單的陣列。

  • render - 預設的自訂函數或字串。

  • handler - 由操作觸發的可執行函數。

useCopilotAction({
    name: "sayHello",
    description: "Say hello to someone.",
    parameters: [
        {
            name: "name",
            type: "string",
            description: "name of the person to say greet",
        },
    ],
    render: "Process greeting message...",
    handler: async ({ name }) => {
        alert(`Hello, ${name}!`);
    },
});

useMakeCopilotReadable掛鉤向 CopilotKit 提供應用程式狀態。

import { useMakeCopilotReadable } from "@copilotkit/react-core";

const appState = ...;
useMakeCopilotReadable(JSON.stringify(appState));

CopilotKit 還允許您為使用者提示提供上下文,使其能夠做出充分且準確的決策。

guidance.tsscript.ts加入到專案內的lib資料夾中,並將此指導腳本建議複製到檔案中,以便 CopilotKit 做出決策。

在應用程式元件中,將當前日期、腳本建議和指導傳遞到 CopilotKit。

import { GUIDELINE } from "@/lib/guideline";
import { SCRIPT_SUGGESTION } from "@/lib/script";
import {
    useCopilotAction,
    useMakeCopilotReadable,
} from "@copilotkit/react-core";

export function App() {
    //-- 👉🏻 ...other component functions

    //👇🏻 Ground the Copilot with domain-specific knowledge for this use-case: marketing campaigns.
    useMakeCopilotReadable(GUIDELINE);
    useMakeCopilotReadable(SCRIPT_SUGGESTION);

    //👇🏻 Provide the Copilot with the current date.
    useMakeCopilotReadable("Today's date is " + new Date().toDateString());

    return (
        <div className='relative'>
            <CampaignForm
                segments={segments}
                currentCampaign={currentCampaign}
                setCurrentCampaign={setCurrentCampaign}
                saveCampaign={(campaign) => {
                    if (campaign) {
                        saveCampaign(campaign);
                    }
                    setCurrentCampaign(undefined);
                }}
            />
            <Dashboard
                campaigns={campaigns}
                setCurrentCampaign={setCurrentCampaign}
                segments={segments}
                setSegments={setSegments}
            />
        </div>
    );
}

App元件中建立一個 CopilotKit 操作,該操作可在使用者提供此類指令時建立新的活動或編輯現有的活動。

useCopilotAction({
    name: "updateCurrentCampaign",
    description:
        "Edit an existing campaign or create a new one. To update only a part of a campaign, provide the id of the campaign to edit and the new values only.",
    parameters: [
        {
            name: "id",
            description:
                "The id of the campaign to edit. If empty, a new campaign will be created",
            type: "string",
        },
        {
            name: "title",
            description: "The title of the campaign",
            type: "string",
            required: false,
        },
        {
            name: "keywords",
            description: "Search keywords for the campaign",
            type: "string",
            required: false,
        },
        {
            name: "url",
            description:
                "The URL to link the ad to. Most of the time, the user will provide this value, leave it empty unless asked by the user.",
            type: "string",
            required: false,
        },
        {
            name: "headline",
            description:
                "The headline displayed in the ad. This should be a 5-10 words",
            type: "string",
            required: false,
        },
        {
            name: "description",
            description:
                "The description displayed in the ad. This should be a short text",
            type: "string",
            required: false,
        },

        {
            name: "budget",
            description: "The budget of the campaign",
            type: "number",
            required: false,
        },
        {
            name: "objective",
            description: "The objective of the campaign",
            type: "string",
            enum: [
                "brand-awareness",
                "lead-generation",
                "sales-conversion",
                "website-traffic",
                "engagement",
            ],
        },

        {
            name: "bidStrategy",
            description: "The bid strategy of the campaign",
            type: "string",
            enum: ["manual-cpc", "cpa", "cpm"],
            required: false,
        },
        {
            name: "bidAmount",
            description: "The bid amount of the campaign",
            type: "number",
            required: false,
        },
        {
            name: "segment",
            description: "The segment of the campaign",
            type: "string",
            required: false,
            enum: segments,
        },
    ],
    handler: (campaign) => {
        const newValue = _.assign(
            _.cloneDeep(currentCampaign),
            _.omitBy(campaign, _.isUndefined)
        ) as Campaign;

        setCurrentCampaign(newValue);
    },
    render: (props) => {
        if (props.status === "complete") {
            return "Campaign updated successfully";
        } else {
            return "Updating campaign";
        }
    },
});

{% 嵌入 https://www.youtube.com/watch?v=gCJpH6Tnj5g %}

新增另一個模擬 API 呼叫的操作,以允許 CopilotKit 從先前建立的活動中檢索歷史資料。

// Provide this component's Copilot with the ability to retrieve historical cost data for certain keywords.
// Will be called automatically when needed by the Copilot.
useCopilotAction({
    name: "retrieveHistoricalData",
    description: "Retrieve historical data for certain keywords",
    parameters: [
        {
            name: "keywords",
            description: "The keywords to retrieve data for",
            type: "string",
        },
        {
            name: "type",
            description: "The type of data to retrieve for the keywords.",
            type: "string",
            enum: ["CPM", "CPA", "CPC"],
        },
    ],
    handler: async ({ type }) => {
        // fake an API call that retrieves historical data for cost for certain keywords based on campaign type (CPM, CPA, CPC)
        await new Promise((resolve) => setTimeout(resolve, 2000));

        function getRandomValue(min: number, max: number) {
            return (Math.random() * (max - min) + min).toFixed(2);
        }

        if (type == "CPM") {
            return getRandomValue(0.5, 10);
        } else if (type == "CPA") {
            return getRandomValue(5, 100);
        } else if (type == "CPC") {
            return getRandomValue(0.2, 2);
        }
    },
    render: (props) => {
        // Custom in-chat component rendering. Different components can be rendered based on the status of the action.
        let label = "Retrieving historical data ...";
        if (props.args.type) {
            label = `Retrieving ${props.args.type} for keywords ...`;
        }
        if (props.status === "complete") {
            label = `Done retrieving ${props.args.type} for keywords.`;
        }

        const done = props.status === "complete";
        return (
            <div className=''>
                <div className=' w-full relative max-w-xs'>
                    <div className='absolute inset-0 h-full w-full bg-gradient-to-r from-blue-500 to-teal-500 transform scale-[0.80] bg-red-500 rounded-full blur-3xl' />
                    <div className='relative shadow-xl bg-gray-900 border border-gray-800  px-4 py-8 h-full overflow-hidden rounded-2xl flex flex-col justify-end items-start'>
                        <h1 className='font-bold text-sm text-white mb-4 relative z-50'>
                            {label}
                        </h1>
                        <p className='font-normal text-base text-teal-200 mb-2 relative z-50 whitespace-pre'>
                            {props.args.type &&
                                `Historical ${props.args.type}: ${props.result || "..."}`}
                        </p>
                    </div>
                </div>
            </div>
        );
    },
});

應用程式預覽

恭喜!您已完成本教學的專案。

結論

CopilotKit是一款令人難以置信的工具,可讓您在幾分鐘內將 AI Copilot 加入到您的產品中。無論您是對人工智慧聊天機器人和助理感興趣,還是對複雜任務的自動化感興趣,CopilotKit 都能讓您輕鬆實現。

如果您需要建立 AI 產品或將 AI 工具整合到您的軟體應用程式中,您應該考慮 CopilotKit。

您可以在 GitHub 上找到本教學的源程式碼:

https://github.com/CopilotKit/campaign-manager-demo

感謝您的閱讀!


原文出處:https://dev.to/copilotkit/build-an-ai-powered-campaign-manager-nextjs-openai-copilotkit-59ii


共有 0 則留言