从崩溃到流畅:我在 Cursor IDE 中结合 Jupyter Notebooks 与 LLM 的工作流

问题:LLM 和 Jupyter Notebooks 天生不太合拍

那天凌晨两点,我终于承认自己搞不定了。我的基因测序分析卡住了,因为 Cursor IDE 里的 LLM 助手没办法稳定解析 Jupyter notebook 那套复杂的 JSON 结构。每次我试图让 AI 帮我改可视化代码,最后得到的都是坏掉的 JSON,连文件都打不开。我也试过只贴代码片段,但那样又丢掉了数据预处理的上下文。与此同时,我桌面上一直开着三个窗口: 浏览器里的 Jupyter、用来“认真写代码”的 VSCode,以及另一个写文档的编辑器。Jupyter 格式和 LLM 的不兼容,再加上不断切换上下文,让复杂数据工作变得非常痛苦。就连 Iris 这种简单基准数据集,这个根本性问题也一样在拖慢我。

听起来熟悉吗?数据科学工作流在上下文切换这件事上尤其折磨人。你会不停在下面这些工具间来回跳:

  • 写“正式代码”的编辑器
  • 用于探索的 Jupyter notebook
  • 用来整理分享结论的文档工具
  • 画图用的可视化软件
  • 浏览器里打开的 ChatGPT 和 Claude

每一次切换都会消耗宝贵的脑力,也会给探索过程增加摩擦。但如果有一种更好的方法呢?

更喜欢视频教程? 我录了整套流程的分步视频演示。观看 Jupyter Notebooks in Cursor IDE Tutorial with AI-Powered Data Analysis,直接看这些技巧怎么实际工作。

Cursor IDE 中结合数据可视化的 Jupyter 最终工作流效果

发现:在 Cursor IDE 中把数据科学工作流统一起来

后来我撞见了一个彻底改变工作流的方案:直接在 Cursor IDE 里使用 Jupyter notebook,再叠加 AI 的能力。这个做法把几件重要的东西合在了一起:

  • Jupyter 基于 cell 的交互式执行
  • 真正 IDE 才有的编辑、导航和重构能力
  • 能理解代码也能理解数据分析语境的 AI 助手
  • 对版本控制更友好的纯文本文件格式

看完这篇文章后,你会看到我怎样搭出一个统一环境,让我能够:

  • 用很少的手写代码分析数据并生成可视化
  • 做出能揭示隐藏模式的 3D 图表
  • 把发现直接写在代码旁边
  • 用一条命令导出专业级报告
  • 全程不再频繁切换工具

如果你也受够了不断切换工具,那我们开始吧。

在 Cursor IDE 中准备 Jupyter 环境

每段冒险都需要准备工作。要在 Cursor IDE 里顺利用 Jupyter,我们需要先装对工具、配好环境。

安装 Jupyter 扩展

魔法从 Cursor IDE 的 Jupyter 扩展开始:

  1. 打开 Cursor IDE,创建项目目录
  2. 进入侧边栏的 Extensions
  3. 搜索 “Jupyter”,找到官方扩展
  4. 点击 “Install”

这个扩展是传统 notebook 和 IDE 之间的桥梁。它带来一个很关键的能力:你可以在普通 Python 文件里用特殊标记创建可执行 cell。也就是说,不再需要结构复杂的 .ipynb 文件,而是可以直接用纯文本 Python 文件加上少量标记。

如果你想了解 Jupyter Notebook 本身的能力,可以看 官方文档

准备 Python 环境

扩展装好之后,下一步是准备一个干净的 Python 环境:

python -m venv .venv

接着创建一个 pyproject.toml 来管理依赖:

[build-system]
requires = ["setuptools>=42.0", "wheel"]
build-backend = "setuptools.build_meta"

[project]
name = "jupyter-cursor-project"
version = "0.1.0"
description = "Data analysis with Jupyter in Cursor IDE"
   
[tool.poetry.dependencies]
python = "^3.9"
jupyter = "^1.0.0"
pandas = "^2.1.0"
numpy = "^1.25.0"
matplotlib = "^3.8.0"
seaborn = "^0.13.0"
scikit-learn = "^1.2.0"

然后安装依赖:

pip install -e .

我也是踩坑之后才学会的:版本冲突会带来很诡异的报错。只要 AI 给你生成了导入某个库的代码,就先确认那个库真的安装在当前环境里。

创建第一个 Notebook:纯文本的力量

传统 Jupyter notebook 使用 .ipynb 格式,本质上是一个复杂 JSON。它既不适合直接编辑,也很难让 AI 在不弄坏结构的前提下修改。相比之下,我们可以用一种更适合 LLM 的纯文本方式,同时保留 notebook 的交互式体验。

原始 Jupyter Notebook 的问题

下面是一个传统 .ipynb 文件在文本编辑器里长什么样:

{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# My Notebook Title\n",
        "This is a markdown cell with text."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": ["Hello, world!"]
        }
      ],
      "source": [
        "print(\"Hello, world!\")"
      ]
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 4
}

这类结构对 LLM 来说尤其难处理,原因包括:

传统 Jupyter notebook 文件的复杂 JSON 结构

  1. JSON 里充满与内容本身无关的符号和嵌套层级
  2. 每个 cell 的内容是字符串数组,并带换行和引号转义
  3. 代码和输出分散在不同位置
  4. 想做一个小修改,都得理解整套 JSON schema
  5. 内容稍微改一点,整个 diff 就可能变得很大

所以 LLM 很容易在修改过程中把结构弄坏,最后生成无法打开的 notebook。

Cell 标记的魔法

创建一个 main.py 文件,加入第一个 cell:

# %%
# Import necessary libraries
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

# Display settings for better visualization
pd.set_option('display.max_columns', None)
plt.style.use('ggplot')

print("Environment ready for data analysis!")

看到最上面的 # %% 了吗?它就是关键标记。Jupyter 扩展会把它识别成一个代码 cell。加上这个标记后,编辑器旁边会出现运行按钮,你可以只执行这一段,输出直接显示在编辑器里。

接着再加一个 markdown cell:

# %% [markdown]
"""
# Iris Dataset Analysis

This notebook explores the famous Iris flower dataset to understand:
- The relationships between different flower measurements
- How these measurements can distinguish between species
- Which features provide the best separation between species

Each flower in the dataset belongs to one of three species:
1. Setosa
2. Versicolor
3. Virginica
"""

这里的组合非常强: 可执行代码和完整文档都在同一个纯文本文件里。没有特殊格式,也没有浏览器编辑的限制,对版本控制也非常友好。

在后面的 notebook 里,我会遵循这样的结构:

  • # %% 写代码 cell
  • # %% [markdown] 和三引号写说明
  • 按照“载入数据 → 探索 → 可视化”的顺序组织
  • 把过程和发现直接写在文件里

释放 LLM 助手:让 AI 成为你的数据科学搭档

真正让这套工作流发生质变的,是它和 Cursor AI Composer 的结合。它不只是自动补全,而更像一个能合作的搭档。

Agent Mode:AI 数据分析伙伴

在 Cursor IDE 中点击 “Composer”,再切换到 “Agent Mode”。这会启用一个更强的 AI 助手,它可以:

  • 在多轮交互中保持上下文
  • 理解你的数据集和分析目标
  • 直接生成符合 Jupyter 语法的完整代码 cell
  • 生成贴合你数据的可视化

先让它导入一个数据集:

Please import the Iris dataset in this notebook format

AI 会生成一个完整可执行的 cell:

# %%
# Import necessary libraries
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris

# Load the Iris dataset
iris = load_iris()

# Convert to pandas DataFrame
df = pd.DataFrame(data=iris.data, columns=iris.feature_names)
df['species'] = iris.target

# Display the first few rows
print(df.head())

只是一句提示词,就得到一个排版正确、能直接运行的 cell。你不需要去记住每一个函数名和参数。

更有意思的是,当我让它生成可视化时:

Generate a 3D scatter plot for the iris dataset showing the three species in different colors

AI 会生成一个带旋转效果的 3D 可视化:

展示 Iris 数据集聚类的 3D 散点图

# %%
# Create 3D scatter plot
from mpl_toolkits.mplot3d import Axes3D

# Create figure and 3D axis
fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111, projection='3d')

# Get the three species
species_names = iris.target_names
colors = ['blue', 'red', 'green']

# Plot each species with a different color
for species_id, species_name in enumerate(species_names):
    # Filter data for this species
    species_data = df[df['species'] == species_id]
    
    # Plot this species
    ax.scatter(
        species_data['sepal length (cm)'],
        species_data['sepal width (cm)'],
        species_data['petal length (cm)'],
        c=colors[species_id],
        label=species_name,
        s=60,
        alpha=0.8
    )

# Set labels and title
ax.set_xlabel('Sepal Length (cm)')
ax.set_ylabel('Sepal Width (cm)')
ax.set_zlabel('Petal Length (cm)')
ax.set_title('3D Scatter Plot of Iris Dataset')
ax.legend()

# Add rotation for better visualization
for angle in range(0, 360, 5):
    ax.view_init(30, angle)
    plt.draw()
    plt.pause(0.001)

plt.show()

这已经不是一个简单图表,而是一个能从多个角度观察数据的动画 3D 散点图,而且标签、颜色、格式都已经处理好了。

用 Cursor Rules 引导 LLM 生成更好的代码

后来我发现,还可以通过在项目根目录创建 .cursorrules 文件,让 AI 生成的代码更贴近我的偏好。这个文件本质上就是告诉模型,我希望它按什么方式写代码。

如果你想系统了解 Cursor rules,可以看我另一篇关于 如何优化 Cursor AI 编码规则 的文章。

例如,我加入了这样的规则:

<cursorrules_code_style>
- Prefer functional programming over OOP
- Use pure functions with clear input/output
- Use strict typing for all variables and functions
</cursorrules_code_style>

<cursorrules_python_specifics>
- Prefer Pydantic over TypedDict for data models
- Use pyproject.toml over requirements.txt
- For complex structures, avoid generic collections
</cursorrules_python_specifics>

加上这些规则之后,AI 开始稳定生成更符合我偏好的类型安全代码:

# %%
# Define a Pydantic model for better type safety
from pydantic import BaseModel
from typing import List, Optional

class IrisFeatures(BaseModel):
    sepal_length: float
    sepal_width: float
    petal_length: float
    petal_width: float
    species: int
    species_name: Optional[str] = None

# Function to convert DataFrame rows to Pydantic models
def convert_to_models(df: pd.DataFrame) -> List[IrisFeatures]:
    species_map = {0: "setosa", 1: "versicolor", 2: "virginica"}
    
    return [
        IrisFeatures(
            sepal_length=row["sepal length (cm)"],
            sepal_width=row["sepal width (cm)"],
            petal_length=row["petal length (cm)"],
            petal_width=row["petal width (cm)"],
            species=row["species"],
            species_name=species_map[row["species"]]
        )
        for _, row in df.iterrows()
    ]

# Convert a sample for demonstration
iris_models = convert_to_models(df.head())
for model in iris_models:
    print(model)

模型基本完全按照规则来写:类型更清晰、代码风格更一致,也更接近我想要的函数式方向。

探索 Iris 数据集:开始真正的数据分析

环境准备好、AI 助手也就位后,就可以真正开始分析经典的 Iris 数据集了。

先看看数据本身

数据已经加载好了,先看结构:

# %%
# Get basic information about the dataset
print("Dataset shape:", df.shape)
print("\nClass distribution:")
print(df['species'].value_counts())

# Create a more readable species column
species_names = {0: 'setosa', 1: 'versicolor', 2: 'virginica'}
df['species_name'] = df['species'].map(species_names)

# Display descriptive statistics
print("\nDescriptive statistics:")
print(df.describe())

这告诉我们数据集有 150 条样本,每个物种 50 条,一共有 4 个花朵特征。接着我用 boxplot 看不同物种的分布差异:

# %%
# Create boxplots for each feature by species
plt.figure(figsize=(12, 10))

for i, feature in enumerate(iris.feature_names):
    plt.subplot(2, 2, i+1)
    sns.boxplot(x='species_name', y=feature, data=df)
    plt.title(f'Distribution of {feature} by Species')
    plt.xticks(rotation=45)

plt.tight_layout()
plt.show()

这些图很快揭示出几个明显模式:Setosa 的花萼更宽但花瓣更小,Virginica 的花瓣整体最大。那到底哪些特征最能区分不同物种?

找出隐藏模式

为了回答这个问题,我们需要看特征之间的关系:

# %%
# Create a pairplot to visualize relationships between features
sns.pairplot(df, hue='species_name', height=2.5)
plt.suptitle('Iris Dataset Pairwise Relationships', y=1.02)
plt.show()

这个 pairplot 非常直观,它一次性展示了所有特征两两之间的关系,而且按物种着色。你可以立刻看到:

  1. 只要图里包含花瓣相关特征,Setosa 基本都和其他两类完全分开
  2. Versicolor 和 Virginica 有一定重叠,但仍然能区分
  3. 花瓣长度和宽度是区分三类物种最有效的特征

如果想看更深入的数据分析与可视化方法,可以参考 scikit-learn User Guide

解决 Jupyter 集成中的障碍:依赖问题排查

任何工作流升级都会遇到坑。我在做更复杂的可视化时,就遇到了 Seaborn 导入报错:

ImportError: Seaborn not valid package style

这是数据科学环境里很常见的问题:包版本不兼容。为了定位问题,我又加了一个 cell 来检查当前环境中的版本:

# %%
# Check installed package versions
import pkg_resources
print("Installed packages:")
for package in ['numpy', 'pandas', 'matplotlib', 'seaborn', 'scikit-learn']:
    try:
        version = pkg_resources.get_distribution(package).version
        print(f"{package}: {version}")
    except pkg_resources.DistributionNotFound:
        print(f"{package}: Not installed")

最后我发现是 Seaborn 和 NumPy 版本不兼容。解决办法也很直接,使用 Cursor 的弹出终端:

  1. 点击底部面板的终端图标
  2. 选择 “Pop out terminal”
  3. 执行更新命令:
    pip install seaborn --upgrade
    

这里正是 Cursor IDE 的优势所在:我不需要切换工具,也不用离开分析上下文,就能直接修好依赖问题。

更好的是,我还可以把错误信息直接丢给 AI,它通常会给出非常接近正确答案的修复命令。弹出终端 + AI 助手的组合,让排障速度明显快了很多。

做出真正有洞察的可视化

环境稳定之后,我想做一些不只是“能画出来”,而是真的能帮助理解数据模式的图表。

从简单图表到 3D 可视化

我先从花瓣尺寸的散点图开始:

# %%
# Create a scatter plot of petal dimensions
plt.figure(figsize=(10, 6))
for species_id, species_name in enumerate(iris.target_names):
    species_data = df[df['species'] == species_id]
    plt.scatter(
        species_data['petal length (cm)'],
        species_data['petal width (cm)'],
        label=species_name,
        alpha=0.7,
        s=70
    )

plt.title('Petal Dimensions by Species')
plt.xlabel('Petal Length (cm)')
plt.ylabel('Petal Width (cm)')
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()

这个图很快就能看出 Setosa 在左下角形成了一个非常紧的簇。

然后我又画了相关性热力图:

# %%
# Calculate correlation matrix
correlation_matrix = df.drop(columns=['species_name']).corr()

# Create a heatmap
plt.figure(figsize=(10, 8))
sns.heatmap(
    correlation_matrix, 
    annot=True,
    cmap='coolwarm',
    linewidths=0.5,
    vmin=-1, 
    vmax=1
)
plt.title('Correlation Matrix of Iris Features')
plt.show()

热力图显示花瓣长度和花瓣宽度有很强的相关性,相关系数达到 0.96。

不过最令人印象深刻的仍然是前面那张旋转 3D 散点图。它在不同视角下会出现几个“刚好完全分开”的角度,让你看见静态二维图难以察觉的模式。

这就是交互式数据可视化的价值:它把抽象数字变成直观感受。

分享分析结果:从探索到展示

当我得到这些结论之后,下一步就是把结果分享给没有 Python 或 Jupyter 环境的同事。这时 Jupyter 扩展的导出能力就非常重要。

生成专业报告

为了生成可分享的报告,我会这样做:

  1. 确认所有 cell 都已经执行过,输出都可见
  2. 增加 markdown cell,解释方法和结论
  3. 使用 Jupyter 扩展的 “Export as HTML”
  4. 在浏览器中打开导出的 HTML,再用 “Save as PDF”

将 Jupyter notebook 导出为专业 PDF 报告

最终生成的报告会包含代码、文字说明和可视化,而且任何人都可以直接查看。因为前面在 markdown 上做了整齐排版,所以标题、列表、强调样式在导出后依然保持得很好。

如果我要把报告发给非技术背景的人看,我通常会把图表尺寸设得更适合展示,比如:

plt.figure(figsize=(10, 6), dpi=300)

这样导出的 PDF 更清晰,也更适合打印。

至于 3D 图,我会在导出之前先把视角停在最能说明问题的角度,因为 PDF 里最终只能保留静态画面。

工作流的变化:在 Cursor IDE 中做 LLM 加持的数据分析

回头看,这个变化其实很大。以前我要在三个工具之间来回切换,现在整个流程都能在一个环境里完成:

  1. Explore: 用 AI 帮我载入数据、搭出初始可视化
  2. Discover: 用 Jupyter 的 cell 执行方式不断细化分析
  3. Document: 直接把结论写在代码旁边
  4. Share: 用一条导出命令生成完整报告

Jupyter 的交互性、Cursor IDE 的编辑能力,以及 AI 助手三者结合之后,原本频繁打断专注的摩擦几乎都消失了。

还有一个额外好处:因为我用的是纯文本文件,而不是原始 .ipynb,整个分析过程终于能被 Git 正常管理。我可以清楚看到版本之间到底改了什么,也能避免 notebook 常见的合并冲突。

这种方式不只是节省时间,它实际上改变了我做数据分析的方式。因为不再被不断切换工具打断,我能更长时间保持 flow state,让探索顺着洞察自然往前走。

如果你也厌倦了为数据工作同时管理一堆工具,我很建议你试试这个集成方案。在 Cursor IDE 中配置好 Jupyter,用上 AI 助手,再体验一次真正顺畅的统一工作流。

对比:传统 Jupyter 与 LLM 增强的 Cursor IDE

下面这张表可以快速总结两种方式的差别:

FeatureTraditional Jupyter NotebooksCursor IDE with Plain Text Jupyter
File FormatComplex JSON (.ipynb)Plain text Python (.py)
Version ControlDifficult (large diffs, merge conflicts)Excellent (standard git workflow)
IDE FeaturesLimited code navigation and refactoringFull IDE capabilities (search, replace, navigation)
AI AssistanceLimitedPowerful LLM integration with context awareness
Cell ExecutionBrowser-based interfaceNative IDE environment
Context SwitchingRequired for advanced editingEverything in one environment
PerformanceCan be slow with large notebooksNative editor performance
DebuggingLimited debugging capabilitiesFull IDE debugging tools
Export OptionsHTML, PDF, various formatsSame capabilities through extension
CollaborationChallenging with version controlStandard code collaboration workflows
DependenciesManaged in separate environment filesIntegrated environment management
Hidden State IssuesCommon problem with out-of-order executionReduced by linear execution encouragement
Markdown SupportNativeThrough cell markers with same capabilities
TypecheckingNoneFull IDE static analysis support
Extension EcosystemJupyter extensionsIDE extensions + Jupyter extensions

这也是为什么我觉得 Cursor IDE 的做法更适合严肃的数据分析工作,尤其是在 AI 已经加入工作流之后。

如果你想更深入了解 Jupyter 整个生态的架构,可以看 Project Jupyter Documentation

视频教程:完整观看 Jupyter + Cursor IDE 工作流

如果你更喜欢视频形式,我也做了一个完整教程,覆盖本文中的所有内容:

Jupyter Notebooks in Cursor IDE 视频教程

视频中会逐步展示如何在 Cursor IDE 中设置并使用 Jupyter notebooks、AI 集成如何工作、如何生成可视化,以及如何导出结果,同时全程保持在一个统一环境里。

Artículos Relacionados

[zh]
[Article]
嘲讽自己手艺的创作者:喜剧演员拆解喜剧、工程师自动取代自己,以及 Factorio 如何把这种冲动变成游戏

嘲讽自己手艺的创作者:喜剧演员拆解喜剧、工程师自动取代自己,以及 Factorio 如何把这种冲动变成游戏

这篇文章梳理一种反复出现的创作者模式:喜剧演员用喜剧拆解喜剧,管理者搭系统削弱自己的位置,工程师用 AI 和自动化替代程序员,连 Factorio 这样的游戏也把“让玩家不再必要”做成乐趣,并解释为什么人们明知自己在构建替代品,仍会为这种优雅、递归又近乎自我消解的创造冲动感到满足。

[zh]
[Article]
Cursor IDE AI编码规则深度优化:提升开发效率与代码质量的最佳实践指南 - 专业开发者必备

Cursor IDE AI编码规则深度优化:提升开发效率与代码质量的最佳实践指南 - 专业开发者必备

经过实战检验的Cursor IDE AI编码规则配置,通过定制代码风格和错误处理模式提升AI编程效率,实现高质量代码输出。本文详细解析了如何通过三级规则体系优化开发流程,提升代码质量与团队协作效率,适合专业开发者参考。了解如何通过最佳实践提升开发效率与代码质量,并优化日常开发流程。

[zh]
[Article]
Claude Code AI规则与 CLAUDE.md 全局指令指南:跨仓库保持稳定编码风格与最小改动

Claude Code AI规则与 CLAUDE.md 全局指令指南:跨仓库保持稳定编码风格与最小改动

我的 Claude Code AI 规则实践:通过全局 CLAUDE.md 拆分个人偏好与项目规范,让代理在不同仓库中持续遵循同一套编码风格、错误处理原则、最小改动习惯与终端工作方式,从一开始就减少重复沟通、上下文漂移,以及每次新会话里反复解释相同要求、重复修正相同行为的长期成本。

[zh]
[Article]
我是如何用 AI 管理个人支出、银行账户、预算预测、多币种记账和财务自动化工作流的完整方法与实战经验

我是如何用 AI 管理个人支出、银行账户、预算预测、多币种记账和财务自动化工作流的完整方法与实战经验

我用 AI 搭建了一套完整的个人财务系统,用来自动整理银行流水、分类支出、核对账户余额,并维护滚动 12 个月预算预测,覆盖多币种记账、开源工具、自动化流程、月度复盘、大额消费决策、账户对账与长期现金流规划,同时支持每周导入交易,让个人理财像公司预算管理一样清晰可控,也更方便复盘与储蓄安排。

关于作者

Kirill Markin

Kirill Markin

CTO

ex-ozma.io 创始人

人工智能与数据工程专家

9,500+
subscribers

Compartir este artículo