在本文中,您將了解如何建立基於 AI 的行銷活動管理應用程式,該應用程式可讓您建立和分析廣告活動,從而使您能夠為您的業務做出正確的決策。
我們將介紹如何:
使用 Next.js 建立 Web 應用程式,
使用 CopilotKit 將 AI 助理整合到軟體應用程式中,以及
建立特定於操作的人工智慧副駕駛來處理應用程式中的各種任務。
建立一名競選經理
CopilotKit是一個開源的AI副駕駛平台。我們可以輕鬆地將強大的人工智慧整合到您的 React 應用程式中。
建造:
ChatBot:上下文感知的應用內聊天機器人,可以在應用程式內執行操作 💬
CopilotTextArea:人工智慧驅動的文字字段,具有上下文感知自動完成和插入功能📝
聯合代理:應用程式內人工智慧代理,可以與您的應用程式和使用者互動🤖
{% 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。
接下來,將Heroicons 、 Radix 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
恭喜!您現在已準備好建立應用程式。
在本節中,我將引導您建立活動管理器應用程式的使用者介面。
首先,讓我們進行一些初始設定。
在src
資料夾中建立一個components
和lib
資料夾。
cd src
mkdir components lib
在lib
資料夾中,我們將聲明應用程式的靜態類型和預設活動。因此,在lib
資料夾中建立data.ts
和types.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 元素。現在,我們可以使用它們來建立應用程式中所需的各種元件。
在這裡,我將引導您完成為應用程式建立使用者介面的過程。
首先,導航至app/page.tsx
檔案並將以下程式碼片段貼到其中。該文件呈現在components/app
資料夾中聲明的 App 元件。
"use client";
import { App } from "@/components/app/App";
export default function DashboardPage() {
return <App />;
}
在components/app
資料夾中建立App.tsx
、 CampaignForm.tsx
、 MainNav.tsx
和UserNav.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,則表示它是新建立的,因此會將其新增至行銷活動清單。否則,它會找到該活動並更新其屬性。
Dashboard
和CampaignForm
元件接受細分和行銷活動作為 props。
Dashboard 元件在儀表板上顯示各種 UI 元素,而CampaignForm 元件使用戶能夠在應用程式中建立和保存新的行銷活動。
您也可以使用GitHub 儲存庫中的程式碼片段來更新儀表板和應用程式元件。
恭喜!您應該有一個有效的 Web 應用程式,可讓使用者查看和建立新的行銷活動。
在接下來的部分中,您將了解如何將 CopilotKit 加入到應用程式中,以根據每個行銷活動的目標和預算進行分析和決策。
在這裡,您將學習如何將人工智慧加入到應用程式中,以幫助您分析行銷活動並做出最佳決策。
在繼續之前,請造訪OpenAI 開發者平台並建立一個新的金鑰。
建立一個.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 提供了兩個鉤子,使我們能夠處理使用者的請求並插入應用程式狀態: useCopilotAction和useMakeCopilotReadable 。
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.ts
和script.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