1. 这篇文章真正要解决的问题
先说结论:Jupyter Notebook 不只是写 Python 的笔记本工具,它是目前最适合把生成式 AI 落地到日常开发工作中的“交互式实验台”。
很多程序员对 Jupyter Notebook 的态度分两种:要么觉得它只是数据分析师和数据科学家的玩具,写工程代码根本用不上;要么觉得 AI 时代该用各种新出现的 AI 编程工具,Jupyter 这种老牌交互式环境已经过时。
这两种判断,在生成式 AI 爆发之后都被推翻了。
为什么这样说?
回想一下,你平时写 AI 相关代码会遇到什么情况:
- 调用大模型 API 时,明明在终端里能跑通,一旦放到脚本里就各种报错。
- 想快速验证一个提示词(Prompt)在不同参数下的效果,却要反复修改代码、重新执行整个脚本。
- 处理一份数据,想把 AI 生成的 JSON 结果可视化看看,得先把结果保存成文件,再用另一个脚本读取。
- 想调试一段内嵌了 AI 调用的业务代码,却看不清每一步的中间输出。
这些痛点,本质上不是代码能力问题,而是工具形态问题。终端脚本是线性执行的,你无法轻易地停在某个变量上观察、修改、再继续;而 Jupyter Notebook 把代码拆成一个个单元格,可以独立运行、重复执行、即时看到输出,这种交互方式恰好和生成式 AI 的“实验-观察-调整”节奏完全匹配。
另外一个更关键的变化是:OpenAI、Anthropic、Hugging Face 等主流 AI 生态的官方示例代码,大量以 Jupyter Notebook 的形式发布。模型评测、RAG 问答、Agent 工具调用、微调数据准备,随便打开一个开源项目,十有八九能在examples目录里看到.ipynb文件。
换句话说,Jupyter Notebook 已经成了生成式 AI 领域的“事实标准演示格式”。不会用它,你连很多官方示例都跑不起来。
这篇文章要解决的就是:如何把 Jupyter Notebook 配置成一个能用于生成式 AI 开发调试的完整环境,从安装、创建内核、安装依赖,到调用大模型 API、处理流式输出、集成工具调用,再到多环境隔离和常见问题排查。读完你可以直接照着一套流程,在手边搭起一个属于自己的 AI 实验环境。
文章不会只讲怎么打开 Notebook 写两行print("hello"),而是从实际需求出发,一步步走完环境配置、代码实现、运行验证和排错的全过程。
2. 环境准备与前置条件
在动手配置之前,先明确我们要搭什么。很多人在“环境配置”这一步就放弃了,不是因为难,而是因为网上的教程版本混乱、工具选择太多,不知道听谁的。
这里直接给出一份保守、稳定、适合生成式 AI 开发的环境清单:
| 组件 | 推荐方案 | 说明 |
|---|---|---|
| 操作系统 | Windows 10/11 / Ubuntu 20.04+ / macOS | 本文以 Windows 为主演示,Linux/macOS 命令基本通用 |
| Python 版本 | Python 3.9 - 3.12 | 太老版本不支持最新依赖,太新版本部分库可能不兼容 |
| 包管理工具 | pip + venv 或 conda | 二选一,新手推荐 Anaconda,工程化推荐 venv |
| Jupyter 环境 | Jupyter Notebook / JupyterLab | 两者可以共存,建议直接使用 JupyterLab |
| AI 相关依赖 | openai、langchain 等 | 按实际项目安装,不要一次装太多 |
| 浏览器 | Chrome / Edge | 不要用太老的浏览器,Jupyter 前端依赖现代浏览器特性 |
关于 Python 版本,这里先给一个明确建议:如果你的电脑上已经有 Anaconda,直接用它创建新的虚拟环境;如果不想装 Anaconda,就用系统 Python 加 venv。不要在系统 Python 里直接pip install jupyter然后把所有包都装到全局环境,这在后续管理项目依赖时会出现严重问题。
Jupyter Notebook 和 JupyterLab 的区别,很多新手会混淆。简单对比一下:
- Jupyter Notebook:经典的单文档交互界面,一个浏览器标签页对应一个
.ipynb文件,操作简单,适合轻量使用。 - JupyterLab:Jupyter 官方打造的下一代集成开发环境,支持多标签页、文件资源管理器、终端、代码高亮、插件系统,更适合做完整项目开发。
从生成式 AI 的开发需求来看,推荐直接选择 JupyterLab。它能在同一个界面里同时打开 Notebook、终端、文本编辑器,一边调试 AI 代码一边看日志,体验接近一个轻量级 IDE。Jupyter Notebook 稍后也可以继续使用,两者共享相同的内核机制,并不冲突。
还有一点需要提前确认:你的网络环境能否访问大模型的 API 服务。生成式 AI 开发免不了调用云端大模型接口,不同服务商的访问要求不同。在使用任何 API 之前,请先确认你使用的服务商提供的接入说明,以及你的网络环境是否满足访问条件。这个前置条件如果没确认好,后面的示例代码即使完全正确,也可能出现连接超时。
3. Jupyter 环境搭建与基础配置
3.1 方案一:使用 Anaconda 安装(推荐新手)
Anaconda 自带 Python、conda 包管理器、Jupyter Notebook、JupyterLab 和大量科学计算库,是最省事的方案。
下载 Anaconda 安装包后,一路按默认选项安装。安装完成后,在命令行执行:
conda --version如果能输出版本号,说明 conda 安装成功。接下来创建一个专门用于 AI 开发的虚拟环境:
conda create -n ai-dev python=3.10 -y conda activate ai-dev简要解释一下这两条命令:
conda create -n ai-dev python=3.10 -y:创建名为ai-dev的虚拟环境,并指定 Python 3.10。conda activate ai-dev:激活这个环境。注意,Windows 命令行和 PowerShell 环境下可能需要先执行conda init初始化 shell。
创建完虚拟环境后,安装 Jupyter 相关组件:
conda install jupyter jupyterlab -y安装完成后,在终端启动:
jupyter lab正常情况下,浏览器会自动打开http://localhost:8888/lab,进入 JupyterLab 界面。
3.2 方案二:使用 venv 安装(推荐工程化)
如果你不喜欢 Anaconda 的“大而全”,更希望保持项目依赖干净,可以使用 Python 自带的venv。
首先确认系统 Python 版本:
python --version然后创建虚拟环境:
python -m venv ai-envWindows 下激活:
ai-env\Scripts\activateLinux/macOS 下激活:
source ai-env/bin/activate激活后,命令行提示符前面会出现(ai-env),表示当前在虚拟环境中。然后安装 Jupyter 和 JupyterLab:
pip install --upgrade pip pip install jupyter jupyterlab同样,启动时执行:
jupyter lab3.3 配置远程访问与固定密码
实际开发中,你可能需要在另一台机器或服务器上访问 Jupyter。默认启动方式只监听本机,不方便远程使用。
生成密码配置文件:
jupyter server password按提示输入两次密码后,会生成一个带哈希值的配置文件。然后执行:
jupyter server --generate-config在生成的配置文件中修改以下几项:
# 文件路径:~/.jupyter/jupyter_server_config.py c.ServerApp.ip = '0.0.0.0' c.ServerApp.port = 8888 c.ServerApp.open_browser = False c.ServerApp.allow_remote_access = True需要说明的是,远程访问 Jupyter 必须考虑安全边界,特别是当 Jupyter 运行在有公网 IP 的云服务器上时,一定要设置强密码、禁用 root 用户直接运行 Notebook,并建议通过 SSH 隧道或内网环境访问,不要直接把 Jupyter 暴露到公网。更稳妥的方式是使用--no-browser参数,仅将 Jupyter 作为本机或内网的开发调试工具使用。
3.4 为虚拟环境创建 Jupyter 内核
这一步是新手最容易忽略的坑。
我们创建了ai-dev或ai-env虚拟环境,但在 JupyterLab 的新建 Notebook 中,通常只看到默认的Python 3内核。如果直接在默认内核里安装 AI 依赖,会装到 base 环境或系统环境,导致虚拟环境里安装的包加载不到。
解决办法是,在激活的虚拟环境中,把当前环境注册为 Jupyter 的内核:
pip install ipykernel python -m ipykernel install --user --name ai-dev --display-name "Python (ai-dev)"参数解释:
--name ai-dev:内核的唯一名称。--display-name "Python (ai-dev)":显示在 Jupyter 界面中的名称。
创建完成后,在 JupyterLab 中新建 Notebook 时,就能看到名为Python (ai-dev)的内核选项。以后每个项目,都可以通过这种方式创建独立内核,避免依赖冲突。
3.5 环境配置的最终检查
完成以上步骤后,建议在 Notebook 中执行以下代码,确认环境正确:
import sys import jupyter print("Python 解释器路径:", sys.executable) print("Python 版本:", sys.version) print("Jupyter 版本:", jupyter.__version__)预期输出中,解释器路径应该指向你的虚拟环境目录,而不是系统 Python 目录。这一步能帮你确认“当前 Notebook 用的到底是哪个环境”,也是排查各种“我怎么装了包但导入失败”问题的入口。
同时要注意,项目的需求依赖建议写进requirements.txt或environment.yml,方便以后重建环境。不要凭记忆手动安装依赖。
4. 生成式 AI 开发的核心概念
配置好 Jupyter 之后,先别急着写代码。要把生成式 AI 开发跑通,需要先理解几个核心概念。这些概念看起来简单,但在实际调试时如果理解不透,很容易被各种报错折磨。
4.1 大模型 API 与提示词
生成式 AI 应用的最基本形式,就是调用大模型 API。你把一段输入文本(Prompt,提示词)发给模型,模型返回一段生成结果。
在 Jupyter 单元格中,调用过程通常是这样:
from openai import OpenAI client = OpenAI(api_key="your-api-key") response = client.chat.completions.create( model="gpt-4o-mini", messages=[ {"role": "system", "content": "你是一个擅长代码审查的助手。"}, {"role": "user", "content": "请帮我解释下面的代码是做什么的:..."} ] ) print(response.choices[0].message.content)这里的messages列表是 Chat Completion API 的核心结构,包含三类角色:
system:系统指令,用来设定模型的行为和身份。user:用户输入,也就是你希望模型回答的问题。assistant:模型的回复,在多轮对话中带上历史回复,让模型记住上下文。
在这个示例中,需要注意 API Key 千万不要直接写在 Notebook 中并提交到代码仓库。更安全的做法是使用环境变量:
import os from openai import OpenAI client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))在终端设置环境变量:
export OPENAI_API_KEY="your-api-key"Windows PowerShell 下:
$env:OPENAI_API_KEY="your-api-key"4.2 流式输出与实时交互
调用大模型时,如果模型生成内容较长,等待完整结果返回会让人感觉“卡住了”。实际上,大模型本身是逐 token 生成内容的,API 也支持流式输出(Stream),像 ChatGPT 那样一个字一个字地出现在屏幕上。
在 Jupyter 中实现流式输出尤其有价值,因为 Notbook 可以逐行显示输出,效果非常直观:
from openai import OpenAI import os client = OpenAI(api_key=os.getenv("OPENAI_API_KEY")) stream = client.chat.completions.create( model="gpt-4o-mini", messages=[{"role": "user", "content": "写一段 Python 代码,实现斐波那契数列。"}], stream=True, ) for chunk in stream: if chunk.choices[0].delta.content is not None: print(chunk.choices[0].delta.content, end="", flush=True)这段代码的核心区别在于:stream=True后,API 返回的是一个生成器对象,可以逐个区块读取内容。flush=True确保内容能实时打印,而不是攒到缓冲区才显示。
这里真正容易踩坑的地方是:部分模型服务商的兼容接口对stream参数的处理方式不完全一致,有的返回delta.content,有的返回choices[0].delta但content为None。如果输出为空,可以先打印一个chunk看完整结构,再决定取值字段。
4.3 上下文管理与多轮对话
很多人把多轮对话理解成“把用户每句话拼接起来发给模型”,这其实不对。正确的做法是,把整个对话历史作为messages列表传给模型,让模型自己理解上下文:
messages = [ {"role": "system", "content": "你是一个 Python 导师,回答要简洁。"}, ] messages.append({"role": "user", "content": "什么是生成式 AI?"}) response = client.chat.completions.create(model="gpt-4o-mini", messages=messages) assistant_reply = response.choices[0].message.content messages.append({"role": "assistant", "content": assistant_reply}) messages.append({"role": "user", "content": "那它和普通 AI 有什么区别?"}) response = client.chat.completions.create(model="gpt-4o-mini", messages=messages) print(response.choices[0].message.content)随着对话轮次增加,messages会越来越长,最终超过模型的最大上下文长度。这时要考虑上下文压缩、摘要或滑动窗口策略。在生成式 AI 应用里,这部分通常需要专门的框架或向量数据库支持,不是简单拼接就能解决的。
4.4 工具调用与 Agent 雏形
生成式 AI 不只是“问答机器”。通过工具调用(Function Calling / Tool Use),模型能够决定在某些时候调用外部函数,比如查询数据库、搜索网页、执行代码,从而完成更复杂的任务。
用通俗的方式理解:模型就像一个聪明的实习生,它能听懂你的需求,但很多具体操作需要调用你提供的工具完成。工具调用就是给这个实习生一套“工具箱”,并告诉他每个工具怎么用。
在 Jupyter 中,你可以非常方便地验证工具调用流程:模型返回一个“意图”,你根据意图执行本地代码,然后把结果返回给模型,让模型根据结果生成最终回复。这种“模型-工具-模型”的循环,就是 Agent 应用的核心机制。
5. Jupyter Notebook 集成生成式 AI 完整示例
理清基础概念后,我们用一个完整示例把整个流程串起来。这个示例虽然不大,但覆盖了生成式 AI 开发的典型套路:环境变量管理、模型调用、流式输出、结构化输出,以及将复杂逻辑封装成类以便在 Jupyter 中反复调试。
5.1 安装依赖
在虚拟环境激活状态下,执行:
pip install openai python-dotenvopenai:OpenAI 官方 Python SDK,目前大多数兼容接口也通过该 SDK 调用。python-dotenv:用于加载.env文件中的环境变量。
然后创建.env文件,放在项目根目录:
# 文件路径:.env OPENAI_API_KEY=your-api-key-here5.2 加载环境变量
在 Jupyter 第一个单元格中:
from dotenv import load_dotenv import os load_dotenv() api_key = os.getenv("OPENAI_API_KEY") print("API Key 是否已加载:", bool(api_key))如果输出True,说明环境变量加载成功。如果输出False,请检查.env文件路径是否与 Notebook 所在目录一致。Jupyter 的工作目录默认是启动时所在的目录,不是 Notebook 文件所在目录,这一点很容易搞混。
5.3 封装一个通用的大模型调用类
为了后续在多个 Notebook 中复用,建议把大模型调用封装成一个简单的类:
# 文件:ai_client.py from openai import OpenAI from dotenv import load_dotenv import os load_dotenv() class AIClient: def __init__(self, model="gpt-4o-mini"): self.client = OpenAI(api_key=os.getenv("OPENAI_API_KEY")) self.model = model def chat(self, messages, stream=False): response = self.client.chat.completions.create( model=self.model, messages=messages, stream=stream, ) return response def stream_chat(self, messages): stream = self.chat(messages, stream=True) collected = [] for chunk in stream: if chunk.choices[0].delta.content is not None: content = chunk.choices[0].delta.content print(content, end="", flush=True) collected.append(content) print() return "".join(collected)在 Jupyter 中导入并使用:
from ai_client import AIClient ai = AIClient(model="gpt-4o-mini") messages = [ {"role": "system", "content": "你是一个代码审查助手,回答使用中文。"}, {"role": "user", "content": "请审查以下 Python 代码,指出潜在问题:\n\ndef calculate_average(nums):\n return sum(nums) / len(nums)"}, ] ai.stream_chat(messages)这个类的好处是:模型名称、API 密钥、调用方式都集中管理,在 Notebook 中调试时只需要修改一个地方。实际项目中,你还可以增加日志、重试、超时控制等功能。
5.4 使用生成式 AI 分析代码文件
现在模拟一个更贴近开发者的场景:我们有一段程序员的代码,希望 AI 帮忙分析复杂度、指出问题并给出优化建议。
先把代码定义为字符串,避免在 Notebook 中创建临时文件:
target_code = """ def fetch_user_data(user_id): conn = create_connection() cursor = conn.cursor() cursor.execute("SELECT * FROM users WHERE id = ?", (user_id,)) rows = cursor.fetchall() result = [] for row in rows: result.append({"id": row[0], "name": row[1], "email": row[2]}) return result """ analysis_prompt = f""" 请对以下代码进行审查,输出 JSON 格式的结果,包含三个字段: - summary: 代码功能概述 - issues: 潜在问题列表 - suggestion: 改进建议 代码: {target_code} """ messages = [ {"role": "system", "content": "你是资深后端工程师,擅长代码审查。"}, {"role": "user", "content": analysis_prompt}, ] response = ai.chat(messages) content = response.choices[0].message.content print(content)这里用了提示词强制要求模型输出 JSON 结构。在实际项目中,更推荐使用 API 的响应格式参数或工具调用来获得稳定的结构化输出,而不是仅靠提示词约束。
5.5 在 Notebook 中绘制结果
生成式 AI 的响应经常包含文本和结构化数据。在 Notebook 中,你可以直接用 Pandas 和 Matplotlib 把 AI 生成的结果可视化,这是终端脚本很难做到的体验。
例如,让 AI 生成一份包含“代码问题严重程度”的 JSON 数据,然后读取并绘图:
import json import pandas as pd import matplotlib.pyplot as plt data = json.loads(content) issues = data.get("issues", []) # 简单统计每个问题的关键词 issue_keywords = [issue[:4] for issue in issues] # 取前4个字作为简易类别 df = pd.DataFrame({"问题": issue_keywords}) df["数量"] = 1 summary_df = df.groupby("问题").count().reset_index() plt.figure(figsize=(8, 4)) plt.bar(summary_df["问题"], summary_df["数量"]) plt.title("代码审查问题统计") plt.xlabel("问题类别") plt.ylabel("数量") plt.xticks(rotation=45) plt.show()这个例子不算复杂,但它展示了 Jupyter 集成生成式 AI 的核心优势:在同一个文档里,完成“生成数据-处理数据-可视化数据”的完整闭环。
6. 运行结果与效果验证
以上代码运行后,我们需要验证是否真的成功了。生成式 AI 开发与普通 Web 开发不同,判断“成功”不只是看有没有报错,还要看输出质量是否符合预期。
6.1 验证模型连接是否成功
最简单的验证方式,是调用一次短文本生成,观察输出:
test_messages = [ {"role": "user", "content": "请回答:1+1等于几?只输出数字。"}, ] response = ai.chat(test_messages) print(response.choices[0].message.content)预期输出:
2如果这一步能输出内容,说明 API 密钥、网络连接、SDK 版本都正常。这是整个 AI 开发流程的“最小可行验证”。
6.2 验证流式输出是否正常
执行 5.3 中的stream_chat方法,如果终端或 Notebook 单元格逐字打印出内容,说明流式输出生效。
如果内容一次性打印,说明flush=True未生效或输出缓冲机制不同。如果完全没有输出,需要检查chunk结构:
stream = ai.chat(test_messages, stream=True) for chunk in stream: print(chunk)观察打印出来的对象结构,确认字段名。不同版本 SDK 的字段结构可能略有不同。
6.3 验证结构化输出是否可解析
在 5.4 节,模型返回的内容是 JSON 字符串。需要验证能否被json.loads解析:
try: parsed = json.loads(content) print("JSON 解析成功") print("字段列表:", list(parsed.keys())) except json.JSONDecodeError as e: print("JSON 解析失败:", e)如果失败,常见原因是模型在 JSON 前后添加了 Markdown 代码块标记,比如:
```json {...}解决办法是清洗内容: ```python def extract_json(text): # 去掉可能的 markdown 标记 if text.startswith("```"): text = text.strip("`") if text.startswith("json"): text = text[4:] return json.loads(text)6.4 验证环境隔离是否生效
在 Jupyter 单元格中执行:
import sys print(sys.executable)如果输出路径指向虚拟环境(如/path/to/ai-env/bin/python或C:\...\ai-env\Scripts\python.exe),说明当前 Notebook 使用的确实是虚拟环境的内核。如果输出指向系统 Python 或 Anaconda base 环境,说明内核选择错误,需要重新执行第 3.4 节的内核创建步骤。
7. 环境配置与 AI 开发常见问题排查
在实际操作中,环境配置和 AI 调用是两大问题高发区。这里整理一份排查清单,按出现频率排序。
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
| Jupyter 启动后浏览器空白 | 浏览器版本过旧、内核崩溃、端口被占用 | 检查浏览器控制台报错;更换浏览器访问 | 更新浏览器;重启 Jupyter;换端口启动jupyter lab --port 8890 |
| Notebook 导入了虚拟环境之外的包 | 当前内核不是目标虚拟环境 | print(sys.executable)查看解释器路径 | 激活虚拟环境后重新执行python -m ipykernel install --user --name my-env,并在 Notebook 中切换内核 |
ModuleNotFoundError: No module named 'openai' | 依赖装错环境 | 查看 pip 安装时的提示路径 | 确认虚拟环境已激活后重新pip install openai |
| API 调用超时 | 网络不通、代理干扰、模型服务端异常 | 先测试网络连通性;查看错误码 | 检查网络环境;重试;使用支持超时参数的 SDK 配置 |
API 返回401 Unauthorized | API Key 错误或未设置 | 打印api_key前缀,确认来源 | 检查.env文件、环境变量是否正确加载 |
API 返回RateLimitError | 触发调用频率限制 | 查看错误响应中的 Retry-After 时间 | 降低调用频率;升级套餐;增加退避重试逻辑 |
| 流式输出没有逐字显示 | 缓冲机制、SDK 版本差异 | 检查flush=True;打印 chunk 结构 | 改用display()方法或在循环中收集后统一显示 |
json.loads解析失败 | 模型输出中包含 Markdown 标记或多余文本 | 打印原始content查看头尾字符 | 编写清洗函数,去除 Markdown 标记后解析 |
7.1 关于ModuleNotFoundError的深层排查
很多人在 Jupyter 中import包失败,但在终端中import成功,这是因为 Jupyter 的内核环境与终端环境不一致。
排查步骤:
- 在 Notebook 中执行
python -c "import sys; print(sys.executable)"。 - 在终端中执行
pip show package-name,查看包安装路径。 - 对比两者路径是否一致。
如果不一致,执行:
# 激活目标环境 conda activate ai-dev # 重新安装 ipykernel 并注册 python -m ipykernel install --user --name ai-dev --display-name "Python (ai-dev)"然后在 JupyterLab 中选择内核:Kernel -> Change Kernel -> Python (ai-dev)。
7.2 关于 Jupyter 启动后空白页
Windows 上经常出现 Jupyter 启动后浏览器打开但页面空白的问题。原因可能是笔记本默认浏览器不支持 WebSocket,或者浏览器插件拦截。
建议按以下顺序排查:
- 手动复制终端输出的
http://localhost:8888/lab地址,在 Chrome 或 Edge 中打开。 - 清除浏览器缓存。
- 查看终端日志,是否出现
KernelRestarter或WebSocket相关错误。 - 如果仍空白,尝试在启动命令中加入
--no-browser后手动打开地址。
7.3 关于 API Key 管理
这里要特别强调:任何形式的 API Key 泄露都可能造成资金损失和安全问题。不要把 Key 写到代码里,更不要直接把.env文件提交到 Git 仓库。建议在.gitignore中添加:
.env *.env同时,在云服务器上运行 Jupyter 时,不要直接用 root 账号启动,建议创建普通用户并限制目录访问权限。
8. 生产环境与工程化最佳实践
如果只是个人学习,把 Jupyter 和生成式 AI 跑通就足够了。但如果你想把这个流程用到团队项目或生产环境中,下面这些实践值得提前了解。
8.1 环境隔离与依赖管理
在生成式 AI 项目中,依赖版本变化非常快。今天能用openaiSDK 的 1.x 版本,明天模型服务商可能就更新接口。所以环境隔离不是可选项,而是必须项。
推荐做法:
- 每个项目单独创建虚拟环境,单独注册 Jupyter 内核。
- 使用
requirements.txt或pyproject.toml锁定依赖版本。 - 定期更新依赖,但更新前先在虚拟环境测试。
- 不要直接在 base 环境安装包。
生成依赖锁定文件的方式:
pip freeze > requirements-lock.txt8.2 提示词版本管理与测试
生成式 AI 应用与传统软件最大的不同:提示词就是代码的一部分,但它很难做单元测试。同一个提示词,换一个模型版本,输出可能完全不一样。
因此,工程化项目中通常会把提示词抽取到单独的模块,并用测试用例维护:
# 文件:prompts.py CODE_REVIEW_SYSTEM_PROMPT = "你是一个资深后端工程师,擅长代码审查。" CODE_REVIEW_USER_PROMPT_TEMPLATE = """ 请对以下代码进行审查,输出 JSON 格式的结果,包含三个字段: - summary: 代码功能概述 - issues: 潜在问题列表 - suggestion: 改进建议 代码: {code} """这样做的价值是:可以在 Notebook 或测试脚本中引用同一个提示词模板,保证线上和实验环境一致。避免在 Notebook 里写死提示词,部署到生产时又复制一份到代码里,最后两边不一致。
8.3 模型调用的可观测性
调用大模型 API 时,一定要记录日志。原因是:大模型接口是黑盒,出错时需要知道请求参数、响应内容、耗时和错误码。
在AIClient中增加简单日志:
import logging import time logger = logging.getLogger(__name__) class AIClient: def __init__(self, model="gpt-4o-mini"): self.client = OpenAI(api_key=os.getenv("OPENAI_API_KEY")) self.model = model def chat(self, messages, stream=False): start_time = time.time() logger.info("开始调用模型 %s,消息数量 %d", self.model, len(messages)) response = self.client.chat.completions.create( model=self.model, messages=messages, stream=stream, ) elapsed = time.time() - start_time logger.info("模型调用完成,耗时 %.2f 秒", elapsed) return response在生产环境中,应把日志输出到收集系统,而不是全部打到控制台。这部分根据团队实际技术栈选择。
8.4 安全与合规提醒
涉及生成式 AI 开发,有几个安全边界必须注意:
- 不要将敏感数据直接发送给大模型 API。在发送前,尽量做脱敏处理。
- 不要自动执行模型生成的代码。模型输出可能包含恶意内容,如果需要执行,必须在沙箱环境中。
- 对模型输出做校验,特别是涉及 SQL、文件路径、命令执行时,禁止直接拼接执行。
- 遵守模型服务商的使用条款,不要批量抓取或滥用接口。
这些提醒看起来很基础,但在实际生产中,正是这些细节决定了系统能否稳定运行。
8.5 Notebook 与生产代码的边界
最后,给一个明确的工程建议:Jupyter Notebook 适合做实验和调试,但不适合直接作为生产代码运行。
如果你已经在 Notebook 中验证了一个 AI 功能,把它迁移到生产时,应该:
- 将核心逻辑抽到 Python 模块或服务中。
- 去掉 Notebook 特有的状态依赖。
- 使用配置管理工具管理环境和密钥。
- 编写自动化测试,至少覆盖“调用成功”“调用失败”“输入为空”三类场景。
- 部署前在实际环境跑一次冒烟测试。
Notebook 的最大价值是让你更快地探索和验证想法;生产系统的稳定性,还是要靠规范的代码和流程来保障。
9. Jupyter Notebook 与 JupyterLab 的选型参考
回到很多新手纠结的问题:Jupyter Notebook 和 JupyterLab 到底选哪个?
给出直接的结论:新项目直接用 JupyterLab,老教程里涉及.ipynb文件的,用 JupyterLab 打开也一样可以运行。两者能处理的文件格式相同,JupyterLab 是 Jupyter Notebook 的超集界面。
不过,如果只是临时打开别人分享的.ipynb文件,看一下运行结果,那么 Jupyter Notebook 更轻量,启动速度更快。另一种情况是,你的项目代码主要是纯 Python 脚本,只有少数几个 Notebook 用来做试验,也可以混合使用。
两者对比:
| 对比项 | Jupyter Notebook | JupyterLab |
|---|---|---|
| 界面形态 | 单文档界面 | 多标签页集成界面 |
| 文件浏览器 | 无 | 有 |
| 终端支持 | 弱 | 内置终端 |
| 插件生态 | 较少 | 丰富 |
| 适用场景 | 轻量查看、简单实验 | 完整开发、调试、AI 项目 |
| 未来趋势 | 维护模式 | 官方主推方向 |
从生成式 AI 开发的实际体验来看,JupyterLab 的多标签页支持非常实用:一个标签页写 Notebook,一个标签页打开终端,一个标签页看文档,效率比来回切换窗口高很多。
10. 总结与后续学习方向
这篇内容差不多把“Jupyter Notebook + 生成式 AI + 环境配置”这条线完整走了一遍:
- 理解了 Jupyter 系列工具在 AI 开发中的定位,它本质上是交互式实验台,和 AI 的探索式工作流非常匹配。
- 完成了从 Anaconda/venv 到 Jupyter 内核注册的环境搭建,解决了“包装错环境”“内核选错”等经典问题。
- 通过完整示例,实现了大模型 API 调用、流式输出、结构化输出、代码审查与结果可视化。
- 整理了常见问题排查表,覆盖环境配置和 API 调用两大高频故障区。
- 探讨了生产环境中的依赖管理、提示词版本管理、日志可观测性、安全边界等工程化问题。
下一步的学习方向,可以根据自己的目标选:
- 想深入理解生成式 AI 的原理:学习 Transformer 的核心架构,理解 Token、注意力机制、上下文窗口等基础概念,这对调优提示词和选择模型有很大帮助。
- 想做 RAG 应用:把 LLM 和向量数据库结合起来,在 Jupyter 中试验文档切分、嵌入、检索的完整流程。
- 想做 Agent 应用:研究工具调用机制,在 Notebook 中搭建一个能自动调用外部函数的 Agent 原型。
- 想进入生产部署:学习如何把 Notebook 中验证过的代码打包成服务,配置 CI/CD,处理模型 API 的并发和降级策略。
一个比较实用的建议是:把你日常开发中的一个低频重复任务,比如代码审查、日志分析、测试用例生成,用 Jupyter + 生成式 AI 做一个原型。花两个小时跑通,感受一下交互式调试带来的效率变化,比看再多教程都有用。环境配置是第一步,也是最容易劝退的一步,现在照着上面的步骤跑通一次,后面就顺畅了。
建议收藏备用,遇到环境问题的时候回来对照排查清单,能省下不少搜索时间。