为了账号安全,请及时绑定邮箱和手机立即绑定

你离不开的AI行程规划器 😻⚡

想象你正在规划一次完美的假期——两周的欧洲之旅,充满博物馆参观、美食享受和徒步赏景。

选项的数量可能会让人感到不知所措,尤其是从选择参观哪些地标到找寻最佳的就餐地点。

解决方案: 一个由AI驱动的行程规划器,比如我们的CopilotKit 😉。

太酷了!

概要
  • 使用 AI 驱动的行程规划 web 应用,采用 Next.js、TypeScript 和 Tailwind CSS 进行构建。
  • 在行程规划 web 应用中集成 AI 功能,使用 CopilotKit。
  • 使用 Langchain 和 Tavily 从网上收集信息,高效规划您行程的每一个细节。
先决条件

要完全理解本教程,你需要对 React 或 Next.js 有所了解。

以下为构建AI旅行规划器需要用到的工具。

  • Langchain - 提供了一个框架,使AI代理能够搜索网络、研究任何主题或链接并抓取数据。
  • OpenAI API - 提供API密钥,使您可以使用ChatGPT模型执行各种任务。
  • Tavily AI - 一个搜索引擎,使AI代理能够抓取数据并在应用程序中访问实时信息。
  • CopilotKit - 一个开源的副驾框架,用于构建自定义AI聊天机器人、应用程序内的AI代理以及文本区域。
什么是AI小助手?

一个AI助手是在应用程序内的人工智能助理,它帮助用户回答问题和操作。它将大型语言模型的智能直接融入您的应用程序。

一些常见的形式:

  • ChatBot: 能理解上下文的聊天机器人,能够在应用内执行操作 💬
  • AI 自动完成: 由 AI 驱动的输入框,具有上下文感知的自动完成和插入功能 📝
  • CoAgents: 能与您的应用和用户互动的 AI 代理 🤖

CopilotKit 是构建内置 AI 助手的领先、最稳健且最易用的开源框架。您可以在几分钟内在您的应用程序中运行一个完全自定义的 AI 助手。

[![Star CopilotKit](https://imgapi.imooc.com/67048d1e098ee46805000300.jpg)](https://imgapi.imooc.com/67048d1e098ee46805000300.jpg)

注:无文本可译。

快来试试 CopilotKit ⭐️
快来试试 CopilotKit ⭐️

项目搭建和安装包

首先,通过在你的终端输入并执行下面的代码段来创建一个 Next.js 应用。

运行以下命令来创建一个新的 Next.js 应用程序 ai-trip-planner:
npx create-next-app@latest ai-trip-planner

点击这里进入全屏模式,点击这里退出全屏

你可以选择你喜欢的设置。在这次教程里,咱们要用TypeScript(一种编程语言)和Next.js App Router(一个前端开发框架)。

代码

接下来,我们将安装Langchain及其所需的依赖项。

npm install @langchain/langgraph@^0.0.7

运行此命令来安装 @langchain/langgraph 版本 0.0.7 及以上版本。

进入全屏 退出全屏

最后,安装CopilotKit包(或库)。这些包让我们能够从React状态中获取数据,并将AI助手添加到应用程序中。

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

全屏 开屏退出全屏

太好了,现在我们安装完了包,可以开始做AI旅行规划器了。

构建AI驱动的旅行规划前端应用

首先,我会带您一步步了解。我们将从创建具有静态内容的AI驱动的旅行规划器前端开始,以此定义旅行规划器的用户界面。

首先,在你的代码编辑器中打开 [root]/src/app,然后,在这个目录下新建一个名为 components 的文件夹。接着,在这个文件夹中创建一个名为 TripPlan.tsx 的文件。

TripPlan.tsx 文件中加入以下代码,定义一个名为 TripPlan 的 React 函数式组件。


    "use client"; // 这表明这是一个 Next.js 应用中的客户端文件

    import Link from "next/link"; // 从 Next.js 导入用于导航的 Link 组件
    import React, { useState } from "react"; // 导入 React 和 useState 钩子

    // 定义 Todo 条目的结构
    interface Todo {
      time: string;
      activity: string;
      details: string;
    }

    // 定义 TripPlan 组件
    function TripPlan() {
      // 声明一个状态变量 'tripPlan' 用于存储 Todo 条目数组,初始为空
      const [tripPlan, setTripPlan] = useState<Todo[]>([]);

      return (
        <div className="flex flex-col w-full min-h-screen bg-gray-100 dark:bg-gray-800">
          {/* 导航链接 */}
          <header className="flex items-center h-16 px-4 border-b shrink-0 md:px-6 bg-white dark:bg-gray-900">
            <Link
              href="#"
              className="flex items-center gap-2 text-lg font-semibold md:text-base"
              prefetch={false}>
              <span className="sr-only text-gray-500">行程规划页面</span>
              <h1>AI 行程生成工具</h1>
            </Link>
          </header>

          {/* 主内容部分 */}
          <main className="flex-1 p-4 md:p-8 lg:p-10">
            <div className="container mx-auto p-4">
              <h1 className="text-2xl font-bold mb-4">行程规划</h1>
              <div className="overflow-x-auto">
                {/* 展示行程计划的表格 */}
                <table className="min-w-full bg-white border border-gray-300">
                  <thead>
                    <tr>
                      <th className="px-4 py-2 border-b">时间</th>
                      <th className="px-4 py-2 border-b">活动</th>
                      <th className="px-4 py-2 border-b">详情</th>
                    </tr>
                  </thead>
                  <tbody>
                    {/* 遍历 tripPlan 状态并将每个条目展示在表格中 */}
                    {tripPlan.map((item, index) => (
                      <tr
                        key={index}
                        className={index % 2 === 0 ? "bg-gray-100" : "bg-white"}>
                        <td className="px-4 py-2 border-b">{item.time}</td>
                        <td className="px-4 py-2 border-b">{item.activity}</td>
                        <td className="px-4 py-2 border-b">{item.details}</td>
                      </tr>
                    ))}
                  </tbody>
                </table>
              </div>
            </div>
          </main>
        </div>
      );
    }

    export default TripPlan; // 导出 TripPlan 组件作为默认导出

全屏模式 退出全屏

接下来,前往 [root]/src/page.tsx 文件,并在其中添加以下代码来导入 TripPlan 组件,并定义一个名为 Home 的函数式组件。

    import TripPlan from "./components/TripPlan";

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

全屏模式 退出全屏

最后,输入命令 npm run dev,然后访问 http://localhost:3000/

现在你应该在浏览器上查看这款AI行程规划工具的前端,如下图所示。

Code2 图片展示了一些代码片段,点击可以查看详细内容。

恭喜!你现在就可以给AI行程助手添加AI功能啦!

集成AI功能到旅行规划工具中,利用CopilotKit

在这一部分,你将学会如何给AI行程规划工具添加一个AI副驾助手,并利用CopilotKit来规划你的行程。

CopilotKit 提供了前端和后端包包。它们使你能够访问 React 状态,并在后端使用 AI代理处理应用数据。

我们先添加 CopilotKit 的 React 组件到行程规划前端。

将CopilotKit添加到行程规划应用前端部分

在这里,我将带你一步步了解如何把AI行程规划器整合到CopilotKit前端,从而帮助创建行程计划。

首先,请参考下面的代码片段,在 /src/app/components/TripPlan.tsx 文件顶部添加 useCopilotReadableuseCopilotAction 自定义钩子。

    // 导入 CopilotKit 的 React 组件
    import { useCopilotAction, useCopilotReadable } from "@copilotkit/react-core";

点击这里切换到全屏模式,或者退出全屏

TripPlan 函数中的状态变量之后,使用 useCopilotReadable 钩子来添加行程计划,作为提供给应用程序内聊天机器人的上下文。该钩子使行程计划对协作者(copilot)可读,便于理解。

    useCopilotReadable({
        description: "用户的旅行计划详情。",
        value: tripPlan,
      });

进全屏。出全屏。

在上面代码的下面添加如下代码,使用 useCopilotAction 钩子来创建一个名为 createTripPlan 的操作,这将允许创建行程计划。

这个操作接受一个名为 TripDaySchedule 的参数,该参数包含时间、活动以及行程详情。此操作内含一个处理函数,该函数会基于给定的提示生成一个行程计划。

在处理程序中的函数内部,使用新创建的行程计划更新了 tripPlan 状态,如下。


    // 使用 useCopilotAction 钩子来定义一个新的动作
      useCopilotAction(
        {
          name: "createTripPlan", // 动作的名称

          description: "创建一个按照日程安排的旅行计划。", // 动作的描述

          parameters: [
            {
              name: "TripDaySchedule", // 参数的名称
              type: "object[]", // 参数的类型(对象数组)
              description: "一天旅行的日程表。", // 参数的描述

              attributes: [
                {
                  name: "time", // 属性的名称
                  type: "string", // 属性的类型
                  description: "旅行日的活动时间。", // 属性的描述
                },
                {
                  name: "activity", // 属性的名称
                  type: "string", // 属性的类型
                  description: "旅行日特定时段的活动。", // 属性的描述
                },
                {
                  name: "details", // 属性的名称
                  type: "string", // 属性的类型
                  description: "每个活动的详情。", // 属性的描述
                },
              ],
              required: true, // 表示此参数是必需的
            },
          ],

          // 处理函数,利用 TripDaySchedule 参数来设定行程计划
          handler: async ({ TripDaySchedule }) => {
            setTripPlan(TripDaySchedule);
          },

          render: "正在创建您的行程...", // 处理操作时显示的消息
        },
        [] // 依赖数组(此处为空)
      );

切换到全屏 退出全屏

接着,打开/[root]/src/app/page.tsx文件,并在文件顶部导入以下代码中的CopilotKit前端包和样式。

    // 导入 CopilotKit 和 CopilotSidebar 组件
    import { CopilotKit } from "@copilotkit/react-core";
    import { CopilotSidebar } from "@copilotkit/react-ui";

    // 导入样式表
    import "@copilotkit/react-ui/styles.css";

全屏模式 退出全屏

然后使用 CopilotKit 来封装 CopilotSidebarTripPlan 组件,如下面所示。CopilotKit 组件指定了 CopilotKit 后端端点的 URL(例如 /api/copilotkit/),而 CopilotSidebar 渲染出一个应用内的聊天机器人,可以接收你提供的指令以创建行程计划。


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

    // 导出 Home 组件作为默认导出
    export default function Home() {
      return (
        // 包含指向 API 端点的 runtimeUrl 属性的 CopilotKit 组件
        <CopilotKit runtimeUrl="/api/copilotkit">
          {/* CopilotSidebar 组件以提供创建行程计划的说明和 UI */}
          <CopilotSidebar
            instructions={
              "帮助用户创建行程计划,但不要将其添加到响应中。"
            } // 为 copilot 提供的说明
            labels={{
              initial:
                "欢迎使用行程计划应用!请在下方描述您想要的行程详情。",
            }} // 为 copilot UI 提供的标签
            defaultOpen={true} // 侧边栏默认为打开状态
            clickOutsideToClose={false} // 点击侧边栏外部不会关闭
          >
            {/* 在 CopilotSidebar 中渲染 TripPlan 组件 */}
            <TripPlan />
          </CopilotSidebar>
        </CopilotKit>
      );
    }

进入全屏 退出全屏

现在我们需要启动开发服务器并导航到网址 http://localhost:3000

你应该注意到,内置的聊天机器人已经集成到了智能行程规划器中。

代码3 点击查看

将 CopilotKit 后端添加到 AI 驱动的行程计划程序中

下面我将带你一步步完成将行程规划工具与CopilotKit后端集成的过程,该后端处理前端的请求,并提供函数调用服务,支持多种LLM后端,例如GPT。

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


    OPENAI_API_KEY="您的 ChatGPT API 密钥(例如:sk-...)"
    TAVILY_API_KEY="您的 Tavily API 密钥(例如:tk-...)"
    OPENAI_MODEL=gpt-4-1106-preview

点击进入全屏 点击退出全屏

要获取ChatGPT API密钥,请访问“https://platform.openai.com/api-keys”,使文本更符合中文书写规范。

如图所示:
图片描述

要获取Tavily搜索API密钥,请访问https://app.tavily.com/home

Code4 图片链接,点击查看

在那之后,进入/[root]/src/app目录,并在其中创建一个名为api的文件夹。在api文件夹内,再创建一个名为copilotkit的文件夹。

copilotkit 文件夹中,创建一个名为 research.ts 的文件。然后访问 此 research.ts gist 文件,复制代码并粘贴到 research.ts 文件。

现在让我们在/[root]/src/app/api/copilotkit文件夹中创建一个名为route.ts的文件。该文件将包含用于处理POST请求的后端代码。它会根据条件包含一个名为'research'的动作,该动作用于研究给定的主题。


    // 从research模块导入researchWithLangGraph函数
    import { researchWithLangGraph } from "./research";

    // 从@copilotkit/shared包导入Action类型
    import { Action } from "@copilotkit/shared";

    // 从next/server模块导入NextRequest类型
    import { NextRequest } from "next/server";

    // 从@copilotkit/runtime包导入所需模块和类
    import { 
      CopilotRuntime, 
      copilotRuntimeNextJSAppRouterEndpoint, 
      OpenAIAdapter, 
    } from "@copilotkit/runtime";

    // 定义具有Action<any>类型的researchAction对象
    const researchAction: Action<any> = { 
      name: "research", // 动作名称
      description: 
        "调用此函数以研究特定主题。请遵循有关何时调用此函数的其他说明。", // 动作描述
      parameters: [ 
        { 
          name: "topic", // 参数名称
          type: "string", // 参数类型,字符串类型
          description: "要研究的主题。5个字符或更长。", // 参数描述
        }, 
      ],
      // 定义异步的动作处理函数
      handler: async ({ topic }) => { 
        console.log("记录正在研究的主题名称:", topic); // 记录正在研究的主题名称
        return await researchWithLangGraph(topic); // 调用researchWithLangGraph函数并返回其结果
      }, 
    };

    // 定义处理POST请求的POST函数
    export const POST = async (req: NextRequest) => { 
      const actions: Action<any>[] = []; // 初始化一个空数组来存放动作

    // 检查TAVILY_API_KEY环境变量是否已设置且不等于"NONE"
      if ( 
        process.env["TAVILY_API_KEY"] && 
        process.env["TAVILY_API_KEY"] !== "NONE" 
      ) { 
        actions.push(researchAction); // 将研究动作添加到动作数组中
      }

    const openaiModel = process.env["OPENAI_MODEL"]; // 从环境变量中获取OpenAI模型

    // 从copilotRuntimeNextJSAppRouterEndpoint函数解构handleRequest函数
      const { handleRequest } = copilotRuntimeNextJSAppRouterEndpoint({ 
        runtime: new CopilotRuntime({ actions }), // 使用动作创建新的CopilotRuntime实例
        serviceAdapter: new OpenAIAdapter({ model: openaiModel }), // 使用模型创建新的OpenAIAdapter实例
        endpoint: req.nextUrl.pathname, // 将端点设置为当前请求URL路径
      });

    return handleRequest(req); // 调用handleRequest函数并将结果返回
    };

全屏,退出全屏

如何规划旅行

现在打开你之前集成的应用内的聊天机器人,并给它一个提示,如“创建一个去伦敦的旅行计划。”

生成完成后,你应该能看到类似这样的行程规划,如下图所示。

这是代码5的图片 Code5

厉害了!你完成了本教程的项目。

结尾

CopilotKit 是一个超级棒的工具,它允许您在几分钟内将 AI 副驾添加到您的产品中。不管是想用 AI 聊天机器人和助手,还是想自动化复杂任务,CopilotKit 都让你轻松搞定。

如果你需要创建或集成一个AI功能到你的软件应用中,你应该考虑一下CopilotKit。

您可以在GitHub上找到这个教程的源码。

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消