1. 项目概述:一个帮你“算账”的AI编程助手数据可视化工具
如果你和我一样,日常重度依赖Cursor这类AI编程助手,那你肯定也好奇过:我这个月到底用了多少token?GPT-4和Claude哪个用得多?我的使用习惯有没有规律?钱都花在哪儿了?这些问题,光看Cursor后台那个简单的表格,总感觉隔靴搔痒,不够直观。直到我发现了这个叫“Cursor Usage Visualizer”的开源项目,它完美地解决了我的痛点——一个完全在浏览器里运行的React应用,能把Cursor导出的CSV数据,变成一张张清晰、交互性强的图表,让你对自己的AI编程习惯了如指掌。
简单来说,它就是一个专为Cursor用户打造的“数据仪表盘”。你不需要懂复杂的数据库或数据分析工具,只需要把你从Cursor后台导出的那个usage.csv文件拖进去,它就能立刻为你生成成本趋势图、模型使用分布图、日历热力图等一系列可视化报告。最让我安心的是,它完全在本地运行,你的使用数据不会上传到任何第三方服务器,隐私性拉满。对于想优化AI工具使用成本、了解自己编码习惯,或者单纯想看看自己有多“肝”的开发者来说,这绝对是个宝藏工具。
2. 核心功能与设计思路拆解
2.1 为什么我们需要这样一个可视化工具?
Cursor作为一款优秀的AI编程助手,其后台确实提供了基础的数据导出功能。但原始CSV文件存在几个明显的“阅读障碍”:首先,数据是冰冷的数字和日期,缺乏直观性,你很难一眼看出自己哪几天用得最猛,或者成本在哪个时间段突然飙升。其次,它没有聚合和对比分析,比如你想比较GPT-4和Claude-3在不同类型任务上的token消耗差异,就得自己写脚本或者手动在Excel里折腾,非常麻烦。
这个可视化工具的设计思路,正是为了解决这些痛点。它的核心目标不是创造新数据,而是将已有的数据“翻译”成人类大脑更容易理解的视觉语言。通过时间序列图,你可以看到趋势;通过饼图或柱状图,你可以看到构成比例;通过日历热力图,你可以感知到行为模式。这种设计极大地降低了数据分析的门槛,让每个开发者都能成为自己AI使用行为的“分析师”。
2.2 技术栈选型的背后考量
项目选用了非常现代且高效的React技术栈组合,这背后有清晰的逻辑:
- React 19 + TypeScript + Vite:这是当前构建高性能、类型安全前端应用的事实标准组合。React 19提供了最新的并发特性与优化,TypeScript能在开发阶段就捕获大量潜在的类型错误,对于处理CSV数据这种结构化信息尤其重要,能确保数据流转过程中的类型安全。Vite作为构建工具,提供了极快的冷启动和热更新速度,让开发体验非常流畅。
- Tailwind CSS:选择Tailwind而非传统的CSS-in-JS方案(如styled-components),我认为是出于开发效率和样式一致性的考虑。Tailwind的实用类(Utility-First)范式,使得构建这种数据仪表盘所需的复杂布局和响应式设计变得异常快速,且能保证整个应用的视觉风格高度统一。
- Recharts:在众多图表库中选中Recharts,是一个务实的选择。它基于D3.js构建,功能强大,但封装了更React友好的声明式API。对于这个项目需要的折线图、面积图、饼图、柱状图等标准图表类型,Recharts完全够用,且文档齐全、社区活跃,能有效降低开发复杂度和维护成本。
- Lucide React:一套简洁美观的开源图标库,用于补充界面中的各种操作和状态图标(如上传、下载、筛选等),能保持视觉风格的一致性,且比引入整个FontAwesome或Ant Design图标库要轻量得多。
这个技术栈组合,确保了项目在拥有良好开发体验和代码质量的同时,最终产物的体积和性能也足够优秀,符合其“轻量级本地工具”的定位。
注意:这个技术栈的选择也暗示了项目的目标用户——主要是具备现代Web开发认知的开发者。虽然使用者无需懂技术,但项目的构建和潜在的二开,需要一定的前端基础。
3. 项目结构与核心模块深度解析
让我们深入代码仓库,看看这个工具是如何被组织起来的。清晰的结构是项目可维护性和可扩展性的基石。
3.1 目录结构:职责分离的典范
项目的目录结构遵循了React社区常见的功能文件夹(Feature-based)或领域驱动设计思路,将不同职责的代码清晰地分隔开:
├── components/ # 所有React组件 │ ├── FileUpload.tsx # 文件上传入口,处理用户CSV文件的拖拽/选择 │ ├── Dashboard.tsx # 仪表盘主视图,整合所有图表和摘要卡片 │ ├── LinkBuilder.tsx # 自定义导出链接生成器,解决Cursor后台30天限制 │ └── ui/ # 可复用的基础UI组件,如StatCard(数据统计卡片) │ └── charts/ # 所有可视化图表组件,每个图表独立封装 ├── utils/ │ └── parser.ts # 核心数据处理器,负责CSV解析、清洗、聚合计算 ├── types.ts # 集中管理的TypeScript类型定义 ├── App.tsx # 应用根组件,管理全局状态(如已解析的数据) └── README.md # 项目说明文档这种结构的优势在于:
- 高内聚:所有与图表相关的逻辑都在
components/charts/里,所有工具函数都在utils/里,修改一个功能时,影响范围非常明确。 - 低耦合:
Dashboard.tsx只需要引入各个图表组件,而不需要关心它们内部如何绘制。parser.ts独立工作,只要输入输出格式不变,其内部算法优化不会影响UI组件。 - 易于测试:像
parser.ts这样的纯函数模块,可以非常方便地编写单元测试,确保数据转换逻辑的准确性。
3.2 核心模块:utils/parser.ts数据转换引擎
这是整个应用的“大脑”。它的任务是把Cursor导出的原始CSV字符串,转换成前端图表组件可以直接消费的、结构化的数据格式。我们来看看它大概需要做什么:
- 解析CSV:使用如
PapaParse这样的库或原生方法,将CSV文本解析成JavaScript对象数组。每一行变成一个对象,键名对应CSV的表头(Date,Model,Cost等)。 - 数据清洗与标准化:
- 日期格式化:将
Date字段统一转换为JavaScript的Date对象或ISO字符串,便于后续按时间排序和分组。 - 数字转换:将
Cost、Total Tokens等字符串转换为number类型。 - 空值处理:处理可能存在的缺失值或无效行。
- 日期格式化:将
- 数据聚合与计算:
- 按日聚合:为了生成时间序列图,需要把同一天的所有记录,按
Cost和Total Tokens进行求和。 - 按模型聚合:为了生成模型分布图,需要统计每个
Model出现的总次数、总成本、总token数。 - 总计计算:计算整个时间段内的总成本、总token数、总请求数。
- Token细分:将
Input (w/ Cache Write)、Input (w/o Cache Write)、Cache Read、Output Tokens进行汇总,用于展示token类型构成。
- 按日聚合:为了生成时间序列图,需要把同一天的所有记录,按
- 输出结构化数据:最终,这个模块会返回一个精心设计的数据对象,可能长这样:
{ summary: { totalCost: number, totalTokens: number, totalRequests: number }, dailyData: Array<{ date: string, cost: number, tokens: number }>, modelData: Array<{ name: string, value: number, cost: number }>, tokenBreakdown: { input: number, cachedRead: number, output: number }, calendarHeatmapData: Array<{ date: string, count: number }> // 用于热力图,count可以是请求次数 }
这个模块的设计质量直接决定了应用的准确性和性能。一个优秀的parser应该做到高效、健壮(能容忍一定格式偏差)、类型安全。
3.3 核心模块:components/charts/可视化层
这是项目的“面子”,负责将parser处理好的数据渲染成直观的图表。每个图表组件都应该是一个独立的、接受特定props的React组件。
- TimeSeriesChart.tsx:接收
dailyData,使用Recharts的LineChart或AreaChart组件,X轴为时间,Y轴可以做成双Y轴,分别表示成本和token数。这里的关键是处理日期显示的格式和密度,避免重叠。 - ModelStatsChart.tsx:接收
modelData,可以使用PieChart展示模型使用次数的分布,用BarChart对比不同模型的总成本,让用户一目了然哪个模型最“烧钱”。 - CalendarHeatmap.tsx:这是最具特色的组件。它接收
calendarHeatmapData,模仿GitHub贡献图的效果,将一年中的每一天渲染成一个色块,颜色深浅代表当天使用的活跃度(如请求次数或总token数)。实现这个可能需要一些自定义的SVG绘制逻辑,或者寻找专门的日历热力图库进行集成。 - TokenBreakdownChart.tsx:接收
tokenBreakdown,用一个RadialBarChart(径向条形图)或堆叠的BarChart来展示输入、缓存、输出token的构成比例。
每个图表组件内部,除了Recharts的配置,还应包含一些交互增强,比如鼠标悬浮显示详细数据的Tooltip,以及可以切换显示/隐藏数据系列的图例Legend。
4. 从零到一:完整实操搭建与使用指南
光看代码结构可能还有点虚,我们一步步来,看看如何把这个项目跑起来,并真正用起来。
4.1 本地开发环境搭建
首先,你需要一个基本的Node.js开发环境。
获取项目代码:
# 使用git克隆仓库(假设你已fork或拥有权限) git clone https://github.com/thanhtunguet/cursor-usage-visualizer.git cd cursor-usage-visualizer或者,直接在GitHub仓库页面点击“Code” -> “Download ZIP”,然后解压到本地目录。
安装依赖: 项目根目录下肯定有一个
package.json文件,里面声明了所有依赖(React, Recharts, Tailwind等)。运行以下命令安装它们:npm install # 或者如果你使用yarn yarn install这个过程会根据你的网络状况持续几分钟。完成后,会生成一个
node_modules文件夹。启动开发服务器:
npm run devVite会快速启动一个本地开发服务器。通常终端会输出类似
Local: http://localhost:5173的信息。用浏览器打开这个链接,你应该就能看到应用界面了。Vite的热重载(Hot Module Replacement)功能意味着你修改代码后,页面会即时刷新,无需手动重启。
4.2 获取并导入你的Cursor使用数据
这是使用这个工具的关键一步。
登录Cursor并导出数据:
- 打开 Cursor 并登录你的账户。
- 点击左下角的设置(Settings)图标。
- 在设置菜单中,找到“Account”(账户)或“Billing”(账单)相关选项。
- 寻找名为“Export Usage Data”(导出使用数据)或类似字样的按钮。点击它,Cursor会生成一个CSV文件并下载到你的电脑,通常命名为
usage.csv。
理解CSV内容: 用Excel或文本编辑器打开这个
usage.csv,你会看到类似下面的列:Date Kind Model Max Mode Input (w/ Cache Write) Input (w/o Cache Write) Cache Read Output Tokens Total Tokens Cost 2024-05-01 Completion gpt-4 FALSE 120 100 20 50 170 0.0034 每一行代表一次AI请求记录,包含了时间、类型、模型、token细分和成本。 在可视化工具中导入:
- 回到你刚刚打开的浏览器页面(
http://localhost:5173)。 - 页面中央应该会有一个非常醒目的文件上传区域,可能写着“Drag & drop your usage.csv here”或者“Click to upload”。
- 将你下载的
usage.csv文件拖拽到该区域,或者点击后从文件选择器中找到它。 - 上传成功后,页面会自动刷新,所有的图表和数据摘要都会瞬间呈现出来。
- 回到你刚刚打开的浏览器页面(
4.3 深度使用与数据分析技巧
上传数据后,你就可以开始探索了。这里分享几个我常用的分析角度:
- 成本监控:直接看“Time Series Chart”(时间序列图)。折线的高低起伏就是你每日的成本波动。重点关注那些突然的“尖峰”,点击或悬停查看那天发生了什么。是不是那天在调试一个复杂问题,频繁使用了GPT-4的Max Mode?
- 模型效率分析:切换到“Model Statistics”(模型统计)图表。对比GPT-4、Claude-3等不同模型的“单次请求平均成本”或“每千token成本”。你可能会发现,对于一些简单的代码补全(Completion),使用更便宜的模型(如Claude Haiku)性价比更高;而对于复杂的代码解释或重构(Chat),GPT-4虽然贵但效果更好。这能指导你未来更智能地切换模型。
- 习惯洞察:“Calendar Heatmap”(日历热力图)是最有趣的。它像你的编程“健身记录”。颜色越深的日子,代表你使用Cursor越频繁。看看是不是每周一颜色特别深(处理周末积压的问题)?或者周末也有颜色(在side project上加班)?这能帮你了解自己的工作节奏。
- Token优化:查看“Token Breakdown”(Token细分)。如果“Cache Read”的比例非常高,说明Cursor的缓存机制为你省了不少钱,这是好事。如果“Output Tokens”比例异常高,可能意味着你经常让AI生成大段代码,可以反思一下是否可以通过更精准的提问来减少不必要的输出。
实操心得:第一次分析自己的数据时,我震惊地发现,有几天超过50%的成本都花在了几次“Max Mode”的对话上。这促使我养成了一个习惯:在开启Max Mode进行长对话前,先问自己“这个问题真的需要上下文那么长的深度思考吗?”,很多时候,拆分成几个小问题分别提问,总成本反而更低,效果也不差。
5. 核心功能实现细节与扩展思路
5.1 自定义日期范围导出链接生成器
这是一个非常贴心的功能。因为Cursor后台的导出界面通常只允许导出最近30天的数据。如果你想分析去年整个季度的使用情况,就没办法一次性导出。
LinkBuilder.tsx组件解决了这个问题。它的原理其实不复杂:
- 界面:提供一个开始日期和结束日期的选择器(Date Picker)。
- 逻辑:根据用户选择的日期范围,按照Cursor官方导出API(如果有)或已知的URL参数格式,拼接出一个特定的URL。
- 输出:将这个生成的URL展示给用户,并提供一个“一键复制”按钮。用户点击这个链接,理论上就会跳转到Cursor的导出页面,并预填好日期范围,直接触发下载。
这个功能需要逆向工程Cursor的导出逻辑,或者依赖社区发现的稳定参数。实现时需要注意日期格式的转换(如YYYY-MM-DD)和URL编码。
5.2 实现完全离线的本地运行能力
这是该项目隐私安全的基石。实现“完全在浏览器中运行”依赖于几个关键技术点:
- 无后端(Serverless):整个项目就是一堆静态文件(HTML, JS, CSS)。
npm run build命令会使用Vite将这些资源打包优化,然后你可以直接把dist文件夹里的内容部署到任何静态托管服务(如GitHub Pages, Vercel, Netlify),甚至直接在本地用浏览器打开index.html文件运行。 - 前端文件处理:通过HTML5的
FileReaderAPI读取用户上传的CSV文件内容,将其转化为文本字符串。 - 内存计算:所有的解析、聚合、计算逻辑(即
parser.ts)都通过JavaScript在用户的浏览器标签页内完成。数据只存在于当前页面的内存中。 - 数据生命周期:页面刷新或关闭,所有数据随之消失。没有任何数据被发送到网络。这也意味着,如果你想多次分析,每次都需要重新上传文件。
5.3 性能优化与大数据量处理
如果你的Cursor使用非常频繁,导出的CSV可能有几万行。在前端一次性处理这么多数据,可能会造成页面卡顿。这里有几个优化思路:
- Web Worker:将最耗时的CSV解析和聚合计算任务放到Web Worker线程中执行,避免阻塞主线程导致页面无响应。
- 虚拟滚动/分页:对于渲染大量数据点的图表(如365天的热力图),可以考虑只渲染可视区域内的元素。
- 数据采样:对于时间跨度很长的折线图,当数据点过于密集时,可以自动进行降采样(例如,将每周数据聚合成一个点),在保持趋势的前提下提升渲染性能。
- 惰性加载:初始只加载摘要和最近一个月的数据,当用户需要查看更早的历史时,再动态解析对应的数据部分。
6. 常见问题、排查技巧与二次开发建议
6.1 使用中常见问题速查表
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
| 上传CSV后页面空白或报错 | 1. CSV文件格式不对(非Cursor导出) 2. CSV文件编码问题(如含BOM) 3. 文件损坏 | 1. 确认是从Cursor官方设置中导出的usage.csv。2. 用文本编辑器(如VS Code)打开CSV,右下角查看编码,尝试另存为 UTF-8格式。3. 重新从Cursor导出一次。 |
| 图表显示“No Data” | 1. 文件上传失败 2. parser.ts未能识别数据列 | 1. 检查浏览器控制台(F12)有无错误。 2. 打开 parser.ts,对比CSV表头与代码中预期的列名是否完全一致(注意空格和括号)。 |
| 日历热力图颜色全一样 | 数据中每日的“活跃度”值差异太小,或计算逻辑有误 | 检查calendarHeatmapData的生成逻辑,确保count值能正确反映活跃度差异。可考虑对数据进行标准化处理。 |
本地运行npm install失败 | 1. Node.js版本过低 2. 网络问题 3. 依赖冲突 | 1. 使用node -v检查版本,确保是18或更高。2. 切换npm源或使用科学上网工具。 3. 删除 node_modules和package-lock.json,重新npm install。 |
| 构建后页面资源加载404 | 部署路径问题(非根目录) | 在vite.config.ts中配置base选项为你的子路径,如base: '/your-repo-name/'。 |
6.2 二次开发与功能增强思路
这个项目是一个很好的起点,你可以基于它打造更个性化的分析工具。
- 集成更多数据源:修改
parser.ts,使其也能解析其他AI编程工具(如GitHub Copilot、CodeWhisperer)的导出数据,做一个统一的AI编程成本分析平台。 - 添加预测功能:基于历史成本数据,使用简单的线性回归或时间序列分析库(如
timeseries-analysis),预测下个月的可能花费,并设置预算警报。 - 增强图表交互:为时间序列图添加“下钻”功能。点击图表上的某一天,下方显示该天所有详细的请求记录列表。
- 导出分析报告:集成一个前端PDF生成库(如
jsPDF、html2canvas),允许用户将当前的仪表盘视图保存为PDF报告,方便分享或存档。 - 个性化主题:利用Tailwind CSS的深色模式支持,或者让用户自定义图表配色方案。
6.3 隐私安全再强调与最佳实践
虽然项目本身是本地运行的,但在二次开发或部署时仍需注意:
- 不要添加后端:一旦你添加了服务器将用户数据上传,这个工具的“隐私安全”核心卖点就消失了。如果必须存储,明确告知用户,并提供数据清除选项。
- 代码审计:如果你是从第三方处获取的构建后版本,而非自己从源码构建,理论上存在被注入恶意代码的风险(虽然概率极低)。最安全的方式始终是自己克隆源码、审查、然后构建。
- 浏览器扩展:一个更进阶的思路是开发一个浏览器扩展,在访问Cursor使用页面时自动抓取数据并展示图表,实现“一键分析”,完全跳过导出-上传的步骤。但这需要更复杂的权限和与特定网站的DOM交互。
这个项目的价值在于它用一个相对简单的技术栈,解决了一个非常具体且普遍的开发者痛点。它不仅是工具,也是一个学习现代React数据可视化应用的优秀样板。通过阅读和修改它的代码,你能深入理解如何将原始数据、业务逻辑、可视化呈现优雅地结合在一起。