如何使用 Maybe Finance 和 CopilotKit 构建一个由 AI 驱动的开源财务管理器⚡️

2025-05-24

如何使用 Maybe Finance 和 CopilotKit 构建一个由 AI 驱动的开源财务管理器⚡️

TL;DR

在本教程中,我们将引导您逐步构建由AI 驱动的投资和储蓄 Copilot ,以帮助您使用Maybe Finance、Nextjs 和CopilotKit 🪁规划储蓄和投资

金融

以下是我们将要介绍的内容:

  • 为 AI Investment & Savings Copilot 构建 Next.js 项目。
  • 将 CopilotKit UI 组件和 API 端点添加到您的应用。
  • 集成 Maybe Finance API 以提供个性化的投资和储蓄见解。

以下是人工智能金融应用程序实施的预览:

让我们开始吧!

CopilotKit 是什么

CopilotKit 是一个用于构建用户交互代理和副驾驶的全栈框架。它为代理提供了使用应用程序的工具,并提供了一个 功能丰富的 SDK  ,支持各种 AI 副驾驶用例,包括 情境感知、 副驾驶操作和 生成式 UI

副驾驶套件

这使您可以定义副驾驶的角色,而无需处理复杂的设置或集成。

查看 CopilotKit 的 GitHub ⭐️

Maybe Finance 是什么?

或许金融

Maybe Finance是个人理财的开源操作系统,提供安全管理、规划和优化您的储蓄和投资的工具。

在我们的项目中,我们将利用 Maybe Finance 的实时数据和分析来增强我们的副驾驶的洞察力,帮助用户优化他们的储蓄和投资。

先决条件

在开始之前,请确保您已:

技术知识

  • 对 Next.js 和 React 有中级理解
  • TypeScript 基础知识
  • 熟悉 MongoDB

所需帐户

开发环境

  • Node.js 18+ 和 npm
  • 代码编辑器(推荐使用 VS Code)

一旦你解决了这个问题,我们就会开始开发!🚀

这是我们将要构建的 Web 应用程序

金融人工智能


设置项目

1.创建一个新的 Next.js 项目

打开终端并运行此命令来创建一个新的 Next.js 项目

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

命令终端

导航到项目目录并启动开发服务器:

cd finance_ai
npm run dev
Enter fullscreen mode Exit fullscreen mode

您的应用程序现在应该在http://localhost:3000上运行

初始应用程序正在运行

2.安装软件包

接下来,让我们安装该项目所需的依赖项。这些包括:

  • CopilotKit 包。
  • Axios(用于获取 API)
  • Shadcn/ui(用于预构建的 UI 组件)
  • Recharts(用于图表表示)

运行以下命令来安装它们:

npm install @copilotkit/react-ui @copilotkit/react-core axios
Enter fullscreen mode Exit fullscreen mode

然后,对于 Shadcn UI,运行此命令

npx shadcn@latest add button card input label badge tabs

Enter fullscreen mode Exit fullscreen mode

注意:如果您使用的是 CopilotKit Cloud,则无需包含运行时包,因为 CopilotKit Cloud 会自动管理运行时环境。但是,如果您自行托管后端,则可能需要手动处理运行时配置。在本教程中,我们将重点介绍自行托管,但请记住,CopilotKit Cloud 是一个可以简化运行时管理的选项。

现在,让我们设置项目结构。我们将创建的关键文件和目录包括:

  • src/app/ui/service/index.ts– 处理 API 调用以获取财务数据。
  • src/app/ui/components/FinanceCopilot.tsx– 我们人工智能财务助理的主要 UI 组件。
  • src/app/lib/types/investment.ts– 为投资和储蓄数据定义 TypeScript 类型。
  • src/app/lib/data/mockData.ts– 包含用于测试的财务数据。
  • src/app/api/copilotkit/route.ts– CopilotKit 的 API 端点。
  • src/app/api/finance/route.ts– 用于获取财务见解的 API。

项目结构

下面是我们的应用程序的文件树:

项目


构建金融AI前端

1. 设置全球供应商layout.tsx

首先,请访问cloud.copilotkit.ai获取您的 CopilotKit Cloud 密钥,用于身份验证和 API 访问。您可以使用 GitHub 或 Google 注册。

副驾驶套件

然后,复制您的 API 密钥并将其保存到您的.env文件中。然后,更新您的全局布局,使用 CopilotKit 提供程序包装您的应用。这样,Copilot 功能便可在整个应用中使用。

API

现在已设置完毕,在此目录中输入以下代码finance_ai/app/layout.tsx

import { Metadata } from "next";
import { Geist, Geist_Mono } from "next/font/google";
import "./globals.css";
import { CopilotKit } from "@copilotkit/react-core";
import "@copilotkit/react-ui/styles.css";

// Load fonts for styling
const geistSans = Geist({
  variable: "--font-geist-sans",
  subsets: ["latin"],
});
const geistMono = Geist_Mono({
  variable: "--font-geist-mono",
  subsets: ["latin"],
});

// Metadata for SEO and display
export const metadata: Metadata = {
  title: "Coyamin - AI Investment Copilot",
  description: "Make informed financial decisions with AI-powered insights.",
};

// Retrieve the Copilot API key from environment variables
const copilotApiKey = process.env.NEXT_PUBLIC_COPILOTKIT_API_KEY;

export default function RootLayout({
  children,
}: Readonly<{ children: React.ReactNode }>) {
  return (
    <html lang="en">
      <body className={`${geistSans.variable} ${geistMono.variable} antialiased`}>
        {/* Conditionally wrap with CopilotKit if the API key is available */}
        {copilotApiKey ? (
          <CopilotKit publicApiKey={copilotApiKey}>{children}</CopilotKit>
        ) : (
          <>{children}</>
        )}
      </body>
    </html>
  );
}
Enter fullscreen mode Exit fullscreen mode

在上面的代码中,我们首先导入全局样式和字体,确保整个应用程序的设计一致。

接下来,我们将应用程序与CopilotKit提供商一起包装以使用 API 密钥;<CopilotKitProvider apiKey={process.env.NEXT_PUBLIC_COPILOTKIT_API_KEY}><App /> </CopilotKitProvider>

此设置使得 AI 功能可在应用程序的所有组件中访问。

2. 创建登录和入门屏幕

要创建登录表单组件,请在中输入以下代码app/api/auth/[...nextauth]/route.ts

import NextAuth from "next-auth";
import GoogleProvider from "next-auth/providers/google";
import { PrismaAdapter } from "@auth/prisma-adapter";
import { prisma } from "@/lib/db";

export const authOptions = {
  adapter: PrismaAdapter(prisma),
  providers: [
    GoogleProvider({
      clientId: process.env.GOOGLE_CLIENT_ID as string,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET as string,
    }),
  ],
  callbacks: {
    async session({ session, user }) {
      if (session?.user) {
        session.user.id = user.id;
        session.user.isOnboarded = user.isOnboarded;
      }
      return session;
    },
  },
  pages: {
    signIn: "/",
  },
};

const handler = NextAuth(authOptions);
export { handler as GET, handler as POST };

Enter fullscreen mode Exit fullscreen mode

身份验证页面分为两个选项卡:登录和注册。每个表单都使用带标签的输入字段和一个按钮,该按钮在身份验证成功后会重定向到入门页面。

授权

入职页面

入职页面有一个聊天界面,作为入职流程的一部分,它会询问财务目标、风险承受能力和投资偏好等问题。

app/onboarding目录中,创建一个page.tsx文件并输入以下代码:

"use client"

import { useState, useEffect } from "react"
import { useRouter } from "next/navigation"
import { Button } from "@/components/ui/button"
import { Card, CardContent } from "@/components/ui/card"
import { Badge } from "@/components/ui/badge"
import { ArrowRight, Bot, User, Sparkles } from "lucide-react"

interface Message {
  type: "bot" | "user"
  content: string
  options?: string[]
}

export default function OnboardingChat() {
  const router = useRouter()
  const [messages, setMessages] = useState<Message[]>([
    {
      type: "bot",
      content: "Welcome to Coyamin! I'm your AI Investment & Savings Copilot. Let's set up your financial profile. What are your main financial goals?",
      options: [
        "Short-term savings (1-2 years)",
        "Long-term investments (5+ years)",
        "Retirement planning",
        "Emergency fund",
        "Wealth building",
      ],
    },
  ])
  const [currentStep, setCurrentStep] = useState(0)
  const [selectedOptions, setSelectedOptions] = useState<Record<number, string[]>>({})

Enter fullscreen mode Exit fullscreen mode

在这里,我们导入 Shadcn UI 按钮、卡片和徽章组件,并添加状态管理,import { useState, useEffect } from "react".我们还包含一个OnboardingChat()带有消息的功能来欢迎用户并询问他们的财务目标,他们可以从选项中进行选择,如下所示:

沙德恩

处理用户选择和聊天流程

当您选择一个选项时,聊天机器人会动态响应并逐步引导您完成不同的入职阶段。我们还提供了一个下拉菜单,用于解释每个风险承受等级:

  // Define the steps of the onboarding process
  const steps = [
    { title: "Financial Goals", progress: 33 },
    { title: "Risk Tolerance", progress: 66 },
    { title: "Investment Preferences", progress: 100 },
  ];

  const handleOptionSelect = (option: string) => {
    setMessages((prev) => [...prev, { type: "user", content: option }]);
    setSelectedOptions((prev) => ({
      ...prev,
      [currentStep]: [...(prev[currentStep] || []), option],
    }));

    setTimeout(() => {
      if (currentStep === 0) {
        setMessages((prev) => [
          ...prev,
          {
            type: "bot",
            content: "Great choice! Now, what's your risk tolerance level?",
            options: ["Conservative (Low Risk)", "Moderate (Medium Risk)", "Aggressive (High Risk)"],
          },
        ]);
        setCurrentStep(1);
      } else if (currentStep === 1) {
        setMessages((prev) => [
          ...prev,
          {
            type: "bot",
            content: "Perfect! Finally, which investment types interest you? (You can select multiple)",
            options: ["Stocks", "ETFs", "Bonds", "Crypto", "Real Estate", "Mutual Funds"],
          },
        ]);
        setCurrentStep(2);
      } else if (currentStep === 2) {
        setMessages((prev) => [
          ...prev,
          {
            type: "bot",
            content: "Thanks! I'll now create your personalized investment profile based on your preferences.",
          },
        ]);
        setTimeout(() => {
          router.push("/dashboard");
        }, 1500);
      }
    }, 500);
  };

Enter fullscreen mode Exit fullscreen mode

3.创建仪表板

仪表板显示财务概览和 AI 生成的建议。请在app/dashboard/page.tsx

将仪表板包装器与 CopilotKit 侧边栏集成,
这会将整个仪表板与CopilotSidebar组件包装在一起,并为仪表板内容设置主弹性容器。

"use client"

import { CopilotSidebar } from "@copilotkit/react-ui";

export default function DashboardPage() {
  return (
    <CopilotSidebar
      defaultOpen={true}
      instructions="You are assisting the user as best as you can. Answer in the best way possible given the data you have."
      labels={{
        title: "Coyamin Assistant",
        initial: "How can I help you today?",
      }}
    >
      {/* Main container: fills the available viewport height */}
      <div className="flex h-[calc(100vh-3.5rem)]">
        <div className="flex-1 p-4 sm:p-6 lg:p-8 overflow-auto">
          {/* Dashboard content goes here */}
        </div>
      </div>
    </CopilotSidebar>
  );
}

Enter fullscreen mode Exit fullscreen mode

提供CopilotSidebar持久的 AI 聊天界面,而弹性容器(div带有flex h-[calc(100vh-3.5rem)])确保仪表板占据视口的整个高度减去标题偏移量。

此外,内部容器(<div className="flex-1 p-4 sm:p-6 lg:p-8 overflow-auto">)有填充且可滚动,可用于容纳概览和图表组件。

在仪表板中实现概览卡

仪表板的“概览”部分定义了一个卡片网格,每个卡片显示一个关键的财务指标,例如总余额、投资、每月储蓄和风险评分

仍在page.tsx文件中,输入以下代码

<div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
  <Card>
    <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
      <CardTitle className="text-sm font-medium">Total Balance</CardTitle>
    </CardHeader>
    <CardContent>
      <div className="text-xl sm:text-2xl font-bold">$45,231.89</div>
      <p className="text-xs sm:text-sm text-muted-foreground">+20.1% from last month</p>
    </CardContent>
  </Card>
  <Card>
    <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
      <CardTitle className="text-sm font-medium">Investments</CardTitle>
    </CardHeader>
    <CardContent>
      <div className="text-xl sm:text-2xl font-bold">$32,123.45</div>
      <p className="text-xs sm:text-sm text-muted-foreground">78 active positions</p>
    </CardContent>
  </Card>
  <Card>
    <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
      <CardTitle className="text-sm font-medium">Monthly Savings</CardTitle>
    </CardHeader>
    <CardContent>
      <div className="text-xl sm:text-2xl font-bold">$2,400.00</div>
      <p className="text-xs sm:text-sm text-muted-foreground">+12% from last month</p>
    </CardContent>
  </Card>
  <Card>
    <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
      <CardTitle className="text-sm font-medium">Risk Score</CardTitle>
    </CardHeader>
    <CardContent>
      <div className="text-xl sm:text-2xl font-bold">7.2/10</div>
      <p className="text-xs sm:text-sm text-muted-foreground">Moderate risk profile</p>
    </CardContent>
  </Card>
</div>
Enter fullscreen mode Exit fullscreen mode

每个卡片都由标签的标题()和指标值及描述的内容( )Card组成。网格布局()是为了确保卡片间距均匀且响应迅速。CardHeaderCardTitleCardContentgrid gap-4 sm:grid-cols-2 lg:grid-cols-4

使用 Rechart 添加图表
我们使用 Recharts 在应用程序中创建两种类型的图表:用于投资组合概览的折线图和用于资产配置的饼图。这些图表旨在清晰地呈现财务趋势和资产分布。有关 Recharts 的更多详细信息,请参阅Recharts 文档

运行此命令来安装 Recharts:

 npm install recharts
Enter fullscreen mode Exit fullscreen mode

然后将此代码添加到page.tsx仪表板目录中的文件中:

import {
  LineChart,
  Line,
  XAxis,
  YAxis,
  CartesianGrid,
  Tooltip,
  ResponsiveContainer,
  PieChart,
  Pie,
  Cell,
} from "recharts";

const chartData = [
  { name: "Jan", value: 4000 },
  { name: "Feb", value: 3000 },
  { name: "Mar", value: 2000 },
  { name: "Apr", value: 2780 },
  { name: "May", value: 1890 },
  { name: "Jun", value: 2390 },
];

const pieData = [
  { name: "Stocks", value: 400 },
  { name: "Bonds", value: 300 },
  { name: "Real Estate", value: 300 },
  { name: "Crypto", value: 200 },
];

const COLORS = ["#0088FE", "#00C49F", "#FFBB28", "#FF8042"];

export default function ChartsSection() {
  return (
    <div className="grid gap-4 sm:grid-cols-1 md:grid-cols-2 lg:grid-cols-7 mt-4">
      {/* Portfolio Overview - Line Chart */}
      <div className="col-span-1 md:col-span-2 lg:col-span-4">
        <div className="border rounded shadow p-4">
          <h3 className="text-lg font-semibold mb-2">Portfolio Overview</h3>
          <ResponsiveContainer width="100%" height="250px">
            <LineChart data={chartData}>
              <CartesianGrid strokeDasharray="3 3" />
              <XAxis dataKey="name" />
              <YAxis />
              <Tooltip />
              <Line type="monotone" dataKey="value" stroke="#8884d8" />
            </LineChart>
          </ResponsiveContainer>
        </div>
      </div>

      {/* Asset Allocation - Pie Chart */}
      <div className="col-span-1 md:col-span-2 lg:col-span-3">
        <div className="border rounded shadow p-4">
          <h3 className="text-lg font-semibold mb-2">Asset Allocation</h3>
          <ResponsiveContainer width="100%" height="250px">
            <PieChart>
              <Pie data={pieData} innerRadius={50} outerRadius={80} paddingAngle={5} dataKey="value">
                {pieData.map((entry, index) => (
                  <Cell key={`cell-${index}`} fill={COLORS[index % COLORS.length]} />
                ))}
              </Pie>
              <Tooltip />
            </PieChart>
          </ResponsiveContainer>
        </div>
      </div>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

在上面的代码中,折线图(投资组合概览)使用ResponsiveContainer来确保图表完全响应。该LineChart组件使用 来绘制数据以CartesianGrid供视觉参考,而XAxis和 则YAxis提供标签以提高可读性。以这种模块化方式使用 Recharts 可以使代码保持清晰易维护。

然后,更新pages/index.tsx以在主应用程序中显示仪表板。

import Dashboard from '../components/Dashboard';

export default function Home() {
  return (
    <main className="min-h-screen bg-gray-100 p-10">
      <Dashboard />
    </main>
  );
}
Enter fullscreen mode Exit fullscreen mode

仪表板

4.设置后端端点

CopilotKit 端点

在 中pages/api/copilotkit.ts,设置后端端点以处理来自 Copilot UI 的请求。此端点会将请求转发到我们的 AI 引擎(并与 Maybe Finance 交互):

import { NextApiRequest, NextApiResponse } from 'next';
import { copilotRuntimeNextJSAppRouterEndpoint } from '@copilotkit/runtime';

Enter fullscreen mode Exit fullscreen mode

或许金融 API 端点

现在,让我们将 Maybe Finance 与 Coyamin 应用程序集成。我们将创建多个 API 路由,作为前端和 Maybe Finance API 之间的安全中介。

首先,设置环境变量来存储我们的 API 凭证:

API_KEY=your_maybe_finance_api_key
BASE_URL=https://api.synthfinance.com
Enter fullscreen mode Exit fullscreen mode

Synth Finance

我们将创建一系列 API 路由,作为我们的财务数据管道。每条路由将处理特定类型的财务数据:

货币信息 API
用于获取聊天过程中所需的各种货币信息。请route.ts在目录中创建一个文件app/api/rates/live

import { NextResponse } from "next/server";
import axios from "axios";

const API_KEY = process.env.API_KEY;
const BASE_URL = process.env.BASE_URL;

export async function GET(req: Request) {
  try {
    const { searchParams } = new URL(req.url);
    const to = searchParams.get("to");

    if (!to) {
      return NextResponse.json(
        { message: "Missing required query parameter: to" },
        { status: 400 }
      );
    }

    const response = await axios.get(`${BASE_URL}/rates/live`, {
      params: { to },
      headers: {
        Authorization: `Bearer ${API_KEY}`,
        Accept: "application/json",
      },
    });

    return NextResponse.json(response.data, { status: 200 });
  } catch (error: unknown) {
    if(error instanceof Error) {
      return NextResponse.json(
        { message: "Error fetching live rates", error: error.message },
        { status: 500 }
      );
    }
    return NextResponse.json(
      { message: "Error fetching live rates"},
      { status: 500 }
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

此端点允许您查看货币价值和投资机会如何随时间变化,以便做出数据驱动的决策。


5.运行应用程序

启动你的开发服务器:

npm run dev
Enter fullscreen mode Exit fullscreen mode

在浏览器中打开http://localhost:3000。您应该会看到带有 Copilot 侧边栏的仪表板。登录后,完成新手入门聊天,然后与 Copilot 进行交互,即可获取由 CopilotKit 和 Maybe Finance 提供支持的财务洞察。

注册页面

注册页面

入职

金融人工智能


最终成果是一个使用 CopilotKit 功能齐全的 AI 驱动财务应用程序:

要从GitHub克隆项目并在本地运行,请打开终端并运行以下命令:

git clone https://github.com/Tabintel/finance_ai.git
Enter fullscreen mode Exit fullscreen mode

然后运行npm install以安装项目所需的所有依赖项并npm run dev运行 Web 应用程序。

概括

在本指南中,我们介绍了使用CopilotKitMaybe Finance构建 AI 驱动的投资和储蓄 Copilot 的过程,以帮助用户有效地规划他们的财务。

虽然我们已经介绍了主要功能,但这仅仅是个开始 - CopilotKit 支持无数由 AI 驱动的用例,从个性化财务助理到金融科技应用程序中的智能自动化。

点击此处查看 GitHub 上的完整源代码

在Twitter上关注 CopilotKit并打招呼,如果您想构建一些很酷的东西,请加入Discord社区。

文章来源:https://dev.to/copilotkit/how-to-build-an-ai-powered-open-source-financial-manager-using-maybe-finance-copilotkit-4441
PREV
如何构建:与你的简历聊天(Next.js、OpenAI 和 CopilotKit)TL;DR
NEXT
构建一个由人工智能驱动的博客平台(Next.js、Langchain 和 CopilotKit)CopilotKit:开源 Copilot 框架