はじめに
Dev.toを眺めていたら、アプリケーション内にAI Copilot機能を早く簡単に構築できるツールを見つけたので試してみます。
そのツールの名前がCopilotKitです!
CopilotKitで主にできることは以下です。(公式サイトから)
今回は、公式サイトにある、ToDoアプリにAI Copilot機能を追加するチュートリアルを実施してみます。
環境構築
まずは、Copilot機能を追加するためのToDoアプリを用意して、それぞれセットアップをします。
ToDoアプリのセットアップ
① リポジトリのクローン
git clone -b base-start-here https://github.com/CopilotKit/example-todos-app.git
cd example-todos-app
② 依存性のインストール
npm install
③ ローカルで起動
npm run dev
http://localhost:3000
にアクセスするとToDoアプリが起動しているはずです。
まだただのToDoアプリです。
CopilotKitのセットアップ
① 依存性のインストール
npm install @copilotkit/react-core @copilotkit/react-ui
- @copilotkit/react-core: CopilotKitのコアライブラリで、CopilotKitプロバイダーや便利なフックが含まれています
- @copilotkit/react-ui: CopilotKitのUIライブラリで、サイドバー、チャットポップアップ、テキストエリアなどのCopilotKit UIコンポーネントが含まれています
② CopilotKitプロバイダの導入
CopilotKitを使用するためにはアプリケーションをCopilotKitプロバイダでラップする必要があります。
その際、Copilot CloudのAPIキーが必要なので、取得して <your-copilot-cloud-public-api-key>
の部分に設定してくださいね。
▶ Copilot Cloud APIキー
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
import { Suspense } from "react";
import { CopilotKit } from "@copilotkit/react-core";
const inter = Inter({ subsets: ["latin"] });
export const metadata: Metadata = {
title: "CopilotKit Todos",
description: "A simple todo app using CopilotKit",
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<body className={inter.className}>
<CopilotKit publicApiKey="ck_pub_8874a2eb5442ba759e9d72c59245a77f">
<Suspense>{children}</Suspense>
</CopilotKit>
</body>
</html>
);
}
③ Chat Popupの導入
ポップアップチャットの機能を追加します。
app\page.tsx
"use client";
import { TasksList } from "@/components/TasksList";
import { TasksProvider } from "@/lib/hooks/use-tasks";
import { CopilotPopup } from "@copilotkit/react-ui";
import "@copilotkit/react-ui/styles.css";
export default function Home() {
return (
<>
<TasksProvider>
<TasksList />
</TasksProvider>
<CopilotPopup />
</>
);
}
とても簡単ですね。
再度、http://localhost:3000
にアクセスするとページの右下にチャットのポップアップボタンが表示されていると思います。
今回はポップアップチャット <CopilotPopup/ >
を使用しましたが、その他にも<CopilotSidebar />
や <CopilotChat />
などもあります。
ここまでの状態ですと、ToDoアプリ画面にポップアップが表示され、AIと会話できるだけです。
この後は、自然言語でアプリの状態を操作する実装を追加していきます。
AI Copilot機能の追加
Copilot Readable State
AIを使用してアプリの状態を操作する前に、AI側にアプリの状態を知ってもらう必要があります。
こちらのToDoアプリでは lib/hooks/use-tasks.tsxファイル
内でタスクの管理やタスクの追加・更新・削除メソッドを定義しています。
- タスクの状態変数(
tasks
) - タスクの追加メソッド(
addTask
) - タスクの更新メソッド(
setTaskStatus
) - タスクの削除メソッド(
deleteTask
)
このファイル内に新しく useCopilotReadable
フックを定義していきます。
lib\hooks\use-tasks.tsx
-
description
プロパティにはアプリの状態を知ってもらうためにAIへ渡したデータの意味を記載します -
value
プロパティには状態全体(ここではタスクの状態)をJSON文字列として指定しています
これでAI Copilotは何のタスクがあるか把握できるようになりました。
試しに、タスクは何個ある?と聞いてみてください!
Copilot Actions
最後はCopilot Actionsです。
AI Copilotとタスク管理メソッドを紐づけましょう。
タスクを追加するaddTask
メソッド、タスクを更新するsetTaskStatus
メソッド、タスクを削除する deleteTask
メソッドそれぞれに対して useCopilotAction
を定義しましょう。
lib\hooks\use-tasks.tsxの最終的なコード
import { createContext, useContext, useState, ReactNode } from "react";
import { defaultTasks } from "../default-tasks";
import { Task, TaskStatus } from "../tasks.types";
import { useCopilotReadable, useCopilotAction } from "@copilotkit/react-core";
let nextId = defaultTasks.length + 1;
type TasksContextType = {
tasks: Task[];
addTask: (title: string) => void;
setTaskStatus: (id: number, status: TaskStatus) => void;
deleteTask: (id: number) => void;
};
const TasksContext = createContext<TasksContextType | undefined>(undefined);
export const TasksProvider = ({ children }: { children: ReactNode }) => {
const [tasks, setTasks] = useState<Task[]>(defaultTasks);
useCopilotReadable({
description: "The state of the todo list",
value: JSON.stringify(tasks),
});
useCopilotAction({
name: "addTask",
description: "Adds a task to the todo list",
parameters: [
{
name: "title",
type: "string",
description: "The title of the task",
required: true,
},
],
handler: ({ title }) => {
addTask(title);
console.log("Created");
},
});
useCopilotAction({
name: "deleteTask",
description: "Deletes a task from the todo list",
parameters: [
{
name: "id",
type: "number",
description: "The id of the task",
required: true,
},
],
handler: ({ id }) => {
deleteTask(id);
},
});
useCopilotAction({
name: "setTaskStatus",
description: "Sets the status of a task",
parameters: [
{
name: "id",
type: "number",
description: "The id of the task",
required: true,
},
{
name: "status",
type: "string",
description: "The status of the task",
enum: Object.values(TaskStatus),
required: true,
},
],
handler: ({ id, status }) => {
setTaskStatus(id, status);
},
});
const addTask = (title: string) => {
setTasks([...tasks, { id: nextId++, title, status: TaskStatus.todo }]);
};
const setTaskStatus = (id: number, status: TaskStatus) => {
setTasks(
tasks.map((task) =>
task.id === id ? { ...task, status } : task
)
);
};
const deleteTask = (id: number) => {
setTasks(tasks.filter((task) => task.id !== id));
};
return (
<TasksContext.Provider value={{ tasks, addTask, setTaskStatus, deleteTask }}>
{children}
</TasksContext.Provider>
);
};
export const useTasks = () => {
const context = useContext(TasksContext);
if (context === undefined) {
throw new Error("useTasks must be used within a TasksProvider");
}
return context;
};
この useCopilotAction
がアプリケーションをとても便利なものにしてくれます。
-
name
プロパティはメソッド名を指定しておきます -
description
は先ほどと同じように何をしているのか簡単な記載です -
handler
はuseCopilotAction
がトリガーされたときに呼び出される関数です- タスクの追加・更新・削除はここで実行されます
これでToDoアプリにAI Copilot機能をつけることができました。
試しに、タスクの追加や更新、削除などを自然言語で実施してみてください!
私が初めてこの機能を触ったときは結構感動しました。
今回はテキストで自然言語を入力してアプリを操作できるようになりましたが、将来的には自然言語を発声してアプリを操作できるようになるととても便利ですよね。
今後、このようなAI Nativeなアプリケーションはどんどん増えていくと思いますので、成果物だけでも体感してみてください!
さいごに
これ以上にも、公式サイトからいくつかアイデアが提供されています。
-
useCopilotChatSuggestions
フックを使用して、Copilotに提案を追加する - チャットウィンドウに最初のアシスタントメッセージを追加する
- テキスト入力ホルダーにオートコンプリートを実装する
参考になれば嬉しいです。