从对话问答到智能体协作

从左向右渐显的24个教学与科研工具标识矩阵

大学物理教学经验分享

从对话问答到智能体协作

AI辅助教学的实践与反思

AI赋能,究竟改变了什么?

从去年初DeepSeek出圈以来,“AI融合”“AI赋能”被反复提起。
我们做了很多尝试,也学了很多东西:究竟怎样融入教学?

AI融合与AI赋能教学的椭圆形词云:18个主主题与44个细分关键词。点击可查看来源。

对物理教学的初步判断

可视化演示

调参数、看变化、对照公式。
先预测,再观察和解释。

备课与课件制作

早期PPT逻辑混乱、效果浮夸,
仍需要教师重构与精修。

分步答疑与反馈

引导学生说明思路,逐步给提示;
核查答案,避免直接代答。

可视化演示与课件制作,值得优先探索;关键仍是让学生理解物理。

真正的融合,应该“润物无声”

从课程思政得到的启发

从觉得形式化,
到理解自然融入

随着学习,我逐渐认识到:
传播美好的东西,也可以是课程思政。
它可以发生在教学的自然展开中。

我对AI赋能的期待

润物无声

帮助教师把逻辑理顺,把概念讲清,
把难以呈现的过程变得直观。

让学生感受到知识与思考的美。

带着这个想法,回看我的课件探索。

我的课件探索:三个阶段

01 · 手工制作

自己实现教学想法

LaTeX
PowerPoint
Mathematica
AxGlyph
GeoGebra
iSlide

手工重写课件
逐一绘制图形
编程制作演示

02 · 网页对话

有了能讨论的助手

ChatGPT
Gemini
DeepSeek
Quarto
Marp
reveal.js

对话讨论课程逻辑
辅助制作可视化
尝试编写HTML课件

03 · Agent协作

连续执行实际任务

Codex
WorkBuddy
Claude Code
Quarto
Python
JupyterLab

连续处理课程文件
协同制作课件讲义
部署维护课程网站

工具不断变化,想把课讲清楚的要求一直没有变。

今天的分享:五个部分

手工制作:把教学想法逐一实现

01

手工制作

把教学想法逐一实现

从LaTeX Beamer到PowerPoint,公式、图形与演示都亲手完成。

LaTeX Beamer
PowerPoint
Mathematica
GeoGebra
AxGlyph
iSlide

起点:公共课件需要重新整理

旧课件:伽利略相对性原理,大段文字集中在一页
文字密集,课堂上不易抓住重点
旧课件:实际中的一些现象,保留当时的媒体图标
旧媒体与版式需要重新整理

希望公式、图形和动态演示,都能更清楚地服务课堂讲授。

→ 插图与曲线的更新

公共课件:插图与曲线也需要更新

公共课件中的孪生子效应:沿用多年的卡通插图
插图风格陈旧
沿用多年的素材,需要重新设计。
公共课件中的速率分布:手绘曲线有明显折痕
手绘曲线不够平滑
用代码绘图,让曲线更准确、平滑。
公共课件沿用多年,图形、版式和媒体都需要持续更新。

尝试LaTeX Beamer:公式和排版出色,动态演示缺失

手写LaTeX Beamer课件:转动惯量的计算
LaTeX Beamer

公式、图形与章节导航

手工编写内容,统一排版。

当时做出的课件缺少动画和视频,未能满足动态演示的需要。

→ 更多LaTeX Beamer课件

LaTeX Beamer是怎样写出来的?

左:原始LaTeX源码 · 可滚动

\begin{frame}{转动惯量的计算}
  \begin{block}{例题4}
    求长为$ L $、质量为$ m $的均匀细棒对图中不同轴的转动惯量。
  \end{block}\vspace{0.1in}
  \begin{columns}
    \onslide<2->{\column[]{.62\linewidth}
    \textbf{解:}取如图坐标\vspace{-0.12in}
    \begin{equation*}
      \begin{aligned}
        d m &=\lambda\dd x, \quad(\lambda=m/ L) \\
        J_{A} &=\int r^{2}\dd m=\int_{0}^{L} x^{2} \lambda\dd x =\boxed{\dfrac{mL^2}{3}} \\
        J_{C} &=\int r^{2}\dd m =\int_{-\frac{L}{2}}^{\frac{L}{2}} x^{2} \lambda\dd x =\boxed{\dfrac{mL^2}{12}}
      \end{aligned}
    \end{equation*}}
    \column[]{.38\linewidth}
    \includegraphics[width=\linewidth]{例4图.png}
  \end{columns}
  \vspace{0.1in}
\onslide<3->{ 一个有趣的关系:$ \dfrac{mL^2}{3}= \dfrac{mL^2}{12} + m\left(\dfrac{L}{2}\right)^2 $,为什么呢?}
\end{frame}

原frame完整源码 · 向下滚动查看

右:对应的LaTeX Beamer课件

原LaTeX Beamer课件:均匀细棒绕不同转轴的转动惯量,完整展开状态
“转动惯量的计算” · 完整展开状态
公式、插图、双栏布局与分步出现,都要逐项写出。

回到PowerPoint:每一个细节都自己完成

手工重做的PowerPoint课件:四种基本热力学过程
PowerPointPowerPointAxGlyphAxGlyphiSlideiSlideMathematicaMathematicaGeoGebraGeoGebra

重画示意图
重输公式
调整逻辑与排版

→ 更多作品、绘图与演示

AxGlyph:从绘图工作区到课堂示意图

AxGlyph工作区:热力学过程与循环的矢量示意图

坐标、曲线、箭头和标注,需要逐项绘制与调整。

GeoGebra可视化:多普勒效应

录屏一 · 约9秒
录屏二 · 约8秒
GeoGebra用GeoGebra制作可视化,再录屏用于课堂演示。

PowerPoint不能原生嵌入交互式HTML;录成视频后,就失去了现场调参的能力。

手工可视化:简谐运动也能画出轮廓

旧课件中的轮廓拟合示例:照片轮廓与公式叠加
用Mathematica求解参数方程,拟合人物轮廓
轮廓绘制动画 · 10秒
把抽象的叠加过程做成能看见的演示。

网页AI对话:从讨论想法到编写课件

02

网页AI对话

从讨论想法到编写课件

用自然语言梳理课程逻辑,尝试可视化与HTML课件。

ChatGPT
Gemini
DeepSeek
Quarto

有了一个可以反复讨论的备课助手

ChatGPT
Gemini
DeepSeek
网页AI讨论围绕教学目标、概念解释与讲授顺序,反复讨论和修正
  • 我已经有了课件,你有什么改进建议?
  • 这一章的课时如何分配,每次课怎么安排?
  • 学生已经学过什么,下一步适合讲什么?
  • 同一个概念,有没有更容易理解的解释?
  • 自己的理解中,是否还有遗漏的前提?

大学物理机械波 · 开头两轮对话

我

这是我的大学物理机械波这一章的课件,请你给我一些讲课的建议。

ChatGPT头像ChatGPT

我看完后的总体感觉是:这套课件的知识链条很完整,例题也很足,从“机械波基本概念→波函数→波的能量→惠更斯原理→干涉→驻波→多普勒效应”一路推进,和教学日历里的分块也基本一致;但页数较多,课堂上如果完全按 PPT 顺着讲,节奏容易偏满。

我最建议你抓住一条主线来讲:“振动状态怎样在空间中传播”。前半章把“振动”变成“波”,中间讲“波怎样用 y(x,t)y(x,t) 表达、相位怎样传播、能量怎样传播”,后半章再讲“叠加以后会发生什么:干涉、驻波、多普勒”。这样学生不容易觉得这是七块互不相干的内容。

具体讲法上,我会特别强调三个最容易混的点,而且整章反复提醒。第一,波传播不是介质整体迁移;第二,振动曲线和波动曲线不是一回事;第三,波速和质点振动速度不是一回事。你的课件里其实已经有这些材料:机械波产生条件、结论页、波函数物理意义、以及“注意区别波速与质点振动速度”的例题页,都很适合反复回扣。课堂上每讲到新部分,都可以先问一句“这里传播的到底是什么”。

这章里最该多花时间的,我认为是波函数这一段。因为学生后面能不能听懂干涉、驻波、多普勒,根子都在这里。你这套课件里“固定 xx 看振动”“固定 tt 看波形”“x,tx,t 同时变化看波形平移”这一组页非常关键,建议慢讲,不要只推公式,要不停把它翻译成图像语言。25–37 页这一串例题也很适合做“先让学生想 30 秒,再揭答案”的课堂互动。

波的能量、惠更斯原理这两部分建议“重物理意义,轻代数细节”。能量部分真正要学生带走的是:行波里能量在传播,单个介质元的机械能并不守恒;平均能量密度和能流密度才是更重要的量。惠更斯原理那一段则要把它明确讲成光学的前奏:它不仅是“作图法”,更是后面理解衍射、反射、折射,以及再往后波动光学的桥。你课件里山后听广播、波的衍射、反射折射这几页都很适合做跨章节过渡。

干涉和驻波建议放在一起对比着讲,而不是完全分开讲。你的课件里先讲相干条件、相位差、波程差,再讲驻波方程、波节波腹、相位分布、驻波能量,这个顺序是对的。课堂上可以直接在黑板上加一个小对照:行波看“相位传播”,驻波看“分段同步振动”;行波有能量传递,驻波无净能量传播;行波每点振幅相同,驻波振幅随位置变。这样学生通常会一下子清楚很多。

多普勒效应这一段我建议严格按“观察者动 → 波源动 → 二者都动 → 反射测速例题”四步走。你的课件本来就是这么排的,最后还有汽车测速的应用题,逻辑很顺。这里最重要的不是让学生死背总公式,而是让他们先建立“谁在改接收波前密度,谁在改发射波长”的物理图像。这样公式符号更不容易乱。

还有两个很实用的小建议。第一,课件中有几组嵌入式可视化页面,比如驻波、多普勒、半波损失那几页,正式上课前最好准备一份本地截图或短视频备份,避免课堂网络或 Web Viewer 出问题。第二,这章里应用页和完整解题页不少,时间紧时可以适当压缩声强级、超声/次声的延展内容,把时间留给波函数、干涉、驻波这三块最核心的地方。

一句话概括我的建议:这章不要讲成“很多公式”,要讲成“一个振动如何变成一列波,以及这列波在传播、叠加、反射时会出现什么现象”。这样学生会更容易跟上。

你要是接下来准备按“两次课”或者“具体到每一页 PPT 怎么讲”的方式来备课,我可以直接按这份课件给你拆成逐页讲课提纲。

我

按照教学日历来看,这一章总共要上8个课时(每课时45分钟),也就是4次课。你觉得我怎么划分章节比较合理?

ChatGPT头像ChatGPT

按你这份材料来看,日历上的“机械波”原本是按 3 个内容块排的:先讲 6-1 基本概念 + 6-2 波函数,再讲 6-3 波的能量 + 6-4 惠更斯原理/衍射/反射折射 + 6-5 波的干涉,最后讲 6-6 驻波 + 6-7 多普勒效应。同时,教学大纲把这一章的重点明确放在 平面简谐波方程、相干条件及相干叠加、多普勒效应,难点放在 建立平面简谐波方程、相干加强/减弱条件、驻波。

所以如果你现在实际是 8 个课时 = 4 次课,我不建议机械地照日历切成 3 大块去讲,而是建议把中间那一大块拆开。因为从课件结构看,这章本身就是 基本概念 → 波函数 → 能量 → 惠更斯 → 干涉 → 驻波 → 多普勒 这样逐层推进的,里头最容易卡学生的,其实是 波函数/波动方程 和 干涉/驻波 两段,它们都值得单独占一堂。

我会这样分:

第 1 次课:机械波基本概念 + 描述波的物理量 + 波函数建立

这是整章地基。先把“波是什么”讲稳:机械波的产生条件、横波/纵波、平面波/球面波、波长周期频率波速的关系,然后进入一维平面简谐波的波函数,重点讲清楚正向传播、反向传播、以及“波是振动状态和相位的传播,不是介质整体跑过去”。这部分正对应日历里的 6-1、6-2,也是后面所有内容的基础。

第 2 次课:波函数的物理意义深化 + 波动方程 + 波的能量

这一堂建议继续把波函数吃透,而不是一上来就换话题。把“固定 xx 看振动、固定 tt 看波形、x,tx,t 同时变化看波形平移”讲明白,再推到平面简谐波的波动方程。然后顺势转到波的能量、能量密度、能流密度。这样逻辑很顺:先会描述波,再谈波携带什么。课件里这一段衔接本来就很自然。

第 3 次课:惠更斯原理 + 衍射/反射折射 + 波的干涉

这一堂的主线是“单列波怎么传播,几列波相遇后会怎样”。先用惠更斯原理解释传播和衍射,再过渡到干涉。干涉的条件、相位差、波程差、相长相消条件都放这里。这样安排有个好处:它和后面驻波之间形成很自然的承接,因为驻波本质上就是一种特殊干涉。你的日历里本来也把 6-4 和 6-5 放在一起。若你沿用信息类版本里“反射折射看 MOOC”的处理,这堂课就更适合把重心压在惠更斯和干涉上。

第 4 次课:驻波 + 半波损失 + 多普勒效应 + 本章收束

最后一堂用“特殊干涉”把前面收起来,再用多普勒把本章推向应用。先讲驻波的产生、驻波方程、波节波腹、相位分布、驻波中无净能量传播,再讲半波损失。最后讲多普勒效应,按“观察者动—波源动—二者都动—反射测速例题”去收束,效果会比较好。这样也和日历里把 6-6、6-7 放在一起相吻合。

我最推荐的总原则是:

第一堂课一定要把波函数立住。

第三、四堂课一定要把干涉—驻波讲成一条线。

多普勒不要和干涉硬塞在同一堂里,因为学生的思维模式会突然从“相位叠加”切到“相对运动改频率”,容易乱。

所以一句话概括,就是:

第1次:概念+波函数

第2次:波函数深化+波动方程+能量

第3次:惠更斯+衍射/反射折射+干涉

第4次:驻波+半波损失+多普勒+总结

下一步我可以直接按这 4 次课,给你拆成更细的“每次课前 45 分钟讲什么、后 45 分钟讲什么、哪些页快讲、哪些页慢讲”的版本。

网页版AI:描述想法,生成HTML可视化

ChatGPT
Gemini
DeepSeek
网页AI对话自然语言描述需求,AI帮助写代码

我

我是大学老师,正在讲授刚体力学。我想用html动画来把一些物理可视化,你有什么建议?哪些值得可视化,如何可视化的效果最好?

Gemini头像Gemini

作为大学老师,你一定深知刚体力学(Rigid Body Mechanics)的抽象性:学生往往能背下公式,但在脑海中构建物理图像(Physical Intuition)时会感到困难。

HTML5(Canvas/WebGL)配合 JavaScript 是制作教学动画的利器,因为它们无需插件即可在浏览器或 PPT 中直接运行。

以下是我为你整理的可视化建议方案:

1. 哪些内容最值得可视化?

你应该优先选择那些“反直觉”或“高维运动”的知识点:

  • 瞬时转动中心 (Instantaneous Center of Rotation): 这是一个纯几何概念,很难凭空想象。通过动画展示平面运动刚体上每点的速度矢量,并实时汇聚到瞬时中心,能瞬间解开学生的疑惑。
  • 角速度矢量与定点转动: 展示欧拉角(Euler Angles)的演变,或者著名的进动(Precession)与章动(Nutation)。
  • 惯量主轴 (Principal Axes of Inertia): 刚体形状不对称时,三维惯量张量的物理意义。
  • 网球拍效应 (Dzhanibekov Effect / Intermediate Axis Theorem): 绕中间轴转动时的不稳定性。这种动态过程文字完全无法描述。

2. 核心教学模块的设计建议

A. 进动与陀螺效应 (Gyroscopic Effect)

这是刚体力学的重头戏。

  • 可视化重点: 绘制出角动量矢量 LL、力矩矢量 MM 以及角速度矢量 ω\omega。
  • 交互设计: 让学生用鼠标拖动来改变力矩的大小,实时观察进动周期的变化。
B. 滚摆与纯滚动 (Pure Rolling)
  • 可视化重点: 追踪圆盘边缘某一点的轨迹(摆线),并对比滑动与滚动混合时的速度场。
  • 对比教学: 同时展示“纯滚动”与“带滑移滚动”的矢量分解,用不同颜色标注质心速度 vcv_c 和转动速度 ωR\omega R。
C. 碰撞与恢复系数 (Impulse and Momentum)
  • 可视化重点: 刚体在碰撞瞬间的速度突变,以及能量损耗的柱状图实时波动。

3. 技术实现路径:如何效果最好?

如果你想亲自编写或指导助教制作,建议采用以下技术栈:

1. 基础物理引擎:Matter.js 或 P2.js
  • 优点: 专门处理刚体碰撞、摩擦力和约束(Constraint)。
  • 效果: 你只需要设置质量和转动惯量,引擎会自动处理运动微分方程。
2. 三维展示:Three.js
  • 优点: 如果涉及欧拉角、陀螺转动,3D 是必须的。
  • 效果: 可以轻松添加网格(Grid)和矢量箭头(ArrowHelper),这对于展示坐标系变换至关重要。
3. 公式与数据联动:MathJax + Chart.js
  • 建议: 在动画旁边实时显示计算公式。当滑块移动改变质量分布时,公式中的 II(转动惯量)数值实时跳动。这种“参数-图像-公式”的三位一体联动效果最好。

4. 给老师的特别建议

  • “慢动作”与“轨迹留痕”: 物理动画最忌讳太快。务必添加一个“Time Scale”滑块,允许学生以 0.1 倍速观察。同时,给运动轨迹加上轨迹线(Traces),帮助学生建立空间感。
  • 引入“错误示范”: 比如展示一个违反角动量守恒的虚假动画,让学生通过观察找出哪里不符合物理定律。
  • 避免过度美化: 教学动画不需要酷炫的材质,清晰的矢量箭头、直角坐标系和受力分析图比逼真的纹理更有价值。

I=∫r2dmI = \int r^2 dm

您是打算亲自上手写代码,还是想寻找现成的仿真平台来集成到课程中?

与Gemini讨论刚体力学可视化 · 可滚动查看
<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>刚体转动动力学可视化 - 教学演示</title>
    <style>
        body { font-family: sans-serif; display: flex; flex-direction: column; align-items: center; background: #f0f2f5; }
        canvas { background: white; box-shadow: 0 4px 10px rgba(0,0,0,0.1); border-radius: 8px; cursor: crosshair; }
        .controls { margin-top: 20px; padding: 20px; background: white; border-radius: 8px; display: grid; grid-template-columns: 1fr 1fr; gap: 20px; width: 600px; }
        .control-group { display: flex; flex-direction: column; }
        label { font-size: 14px; color: #333; margin-bottom: 5px; }
        .data-panel { font-family: 'Courier New', monospace; margin-top: 10px; color: #007bff; font-weight: bold; }
    </style>
</head>
<body>

<h2>刚体定轴转动演示 ( \(\tau = I \alpha\) )</h2>

<canvas id="rigidBodyCanvas" width="600" height="400"></canvas>

<div class="controls">
    <div class="control-group">
        <label>外力矩 (Torque \(\tau\)): <span id="torqueVal">10</span></label>
        <input type="range" id="torqueRange" min="0" max="50" value="10">
    </div>
    <div class="control-group">
        <label>转动惯量 (Inertia \(I\)): <span id="inertiaVal">100</span></label>
        <input type="range" id="inertiaRange" min="50" max="500" value="100">
    </div>
    <div class="control-group">
        <label>阻尼系数 (Damping): <span id="dampingVal">0.01</span></label>
        <input type="range" id="dampingRange" min="0" max="0.1" step="0.01" value="0.01">
    </div>
    <div class="data-panel">
        角速度 \(\omega\): <span id="omegaDisplay">0.00</span> rad/s
    </div>
</div>

<script>
    const canvas = document.getElementById('rigidBodyCanvas');
    const ctx = canvas.getContext('2d');

    // 物理参数
    let angle = 0;
    let omega = 0; // 角速度
    let alpha = 0; // 角加速度
    
    // UI 控件
    const torqueSlider = document.getElementById('torqueRange');
    const inertiaSlider = document.getElementById('inertiaRange');
    const dampingSlider = document.getElementById('dampingRange');

    function draw() {
        // 清屏
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        const centerX = canvas.width / 2;
        const centerY = canvas.height / 2;
        
        // 获取参数
        const tau = parseFloat(torqueSlider.value);
        const I = parseFloat(inertiaSlider.value);
        const damping = parseFloat(dampingSlider.value);
        
        // 更新 UI 数值显示
        document.getElementById('torqueVal').innerText = tau;
        document.getElementById('inertiaVal').innerText = I;
        document.getElementById('dampingVal').innerText = damping;
        document.getElementById('omegaDisplay').innerText = omega.toFixed(2);

        // --- 物理计算 ---
        // \alpha = (\tau - damping * \omega) / I
        alpha = (tau - damping * omega * 100) / I; 
        omega += alpha;
        angle += omega;

        // --- 绘制刚体 (圆盘) ---
        ctx.save();
        ctx.translate(centerX, centerY);
        ctx.rotate(angle);
        
        // 绘制盘体
        ctx.beginPath();
        ctx.arc(0, 0, 80, 0, Math.PI * 2);
        ctx.fillStyle = '#ecf0f1';
        ctx.fill();
        ctx.strokeStyle = '#2c3e50';
        ctx.lineWidth = 3;
        ctx.stroke();

        // 绘制刻度线(方便观察转动)
        ctx.beginPath();
        ctx.moveTo(0, 0);
        ctx.lineTo(80, 0);
        ctx.strokeStyle = '#34495e';
        ctx.stroke();
        
        // 绘制表示质量分布的点(象征惯量)
        const dotCount = Math.floor(I / 20);
        for(let i=0; i<dotCount; i++) {
            ctx.beginPath();
            ctx.arc(Math.cos(i)*60, Math.sin(i)*60, 3, 0, Math.PI*2);
            ctx.fillStyle = '#95a5a6';
            ctx.fill();
        }
        ctx.restore();

        // --- 绘制矢量分析 ---
        // 1. 力矩方向箭头 (红色)
        if(tau > 0) {
            drawArrow(centerX + 100, centerY - 50, centerX + 100, centerY - 100, 'red', 'Force (F)');
        }

        // 2. 角速度弧线 (蓝色)
        ctx.beginPath();
        ctx.arc(centerX, centerY, 120, -Math.PI/2, -Math.PI/2 + omega * 2, false);
        ctx.strokeStyle = 'rgba(0, 123, 255, 0.5)';
        ctx.lineWidth = 10;
        ctx.stroke();

        requestAnimationFrame(draw);
    }

    function drawArrow(fromx, fromy, tox, toy, color, label){
        const headlen = 10;
        const dx = tox - fromx;
        const dy = toy - fromy;
        const angle = Math.atan2(dy, dx);
        ctx.strokeStyle = color;
        ctx.fillStyle = color;
        ctx.lineWidth = 2;
        ctx.beginPath();
        ctx.moveTo(fromx, fromy);
        ctx.lineTo(tox, toy);
        ctx.stroke();
        ctx.beginPath();
        ctx.moveTo(tox, toy);
        ctx.lineTo(tox - headlen * Math.cos(angle - Math.PI / 6), toy - headlen * Math.sin(angle - Math.PI / 6));
        ctx.lineTo(tox - headlen * Math.cos(angle + Math.PI / 6), toy - headlen * Math.sin(angle + Math.PI / 6));
        ctx.closePath();
        ctx.fill();
        ctx.fillText(label, tox + 5, toy);
    }

    draw();
</script>
</body>
</html>
示例HTML代码 · 可滚动查看 → 进入演示

角动量守恒定律

进动现象

同方向同频率简谐振动合成

驻波的形成与特征

从独立演示,走向初步的HTML课件

Quarto

组织文字、公式、代码与图
尝试HTML课件和文档

Marp

用Markdown组织幻灯片
尝试轻量的课件制作

reveal.js

用HTML组织幻灯片
尝试动画与交互呈现

当时的工作过程AI写代码 → 自己保存与运行 → 反馈修改 → 整理成课件
→ 浏览Quarto官方demo原版演示 · 向右继续报告

LaTeX Equations

MathJax rendering of equations to HTML

\begin{gather*}
a_1=b_1+c_1\\
a_2=b_2+c_2-d_2+e_2
\end{gather*}

\begin{align}
a_{11}& =b_{11}&
  a_{12}& =b_{12}\\
a_{21}& =b_{21}&
  a_{22}& =b_{22}+c_{22}
\end{align}
a1=b1+c1a2=b2+c2−d2+e2\begin{gather*} a_1=b_1+c_1\\ a_2=b_2+c_2-d_2+e_2 \end{gather*} a11=b11a12=b12a21=b21a22=b22+c22\begin{align} a_{11}& =b_{11}& a_{12}& =b_{12}\\ a_{21}& =b_{21}& a_{22}& =b_{22}+c_{22} \end{align}

Interactive Slides

Turn presentations into applications with Observable and Shiny. Use component layout to position inputs and outputs.

Fragments

Incremental text display and animation with fragments:


Fade in

Slide up while fading in

Slide left while fading in

Fade in then semi out

Strike

Highlight red

Auto-Animate

Automatically animate matching elements across slides with Auto-Animate.

Auto-Animate

Automatically animate matching elements across slides with Auto-Animate.

Quarto不只是课件

网页:把课程资源组织成网站

Practical Deep Learning

fast.ai

在页面内滚动浏览

外侧箭头切换课件

打开原站 ↗

当前页可离线阅读
跨页链接需联网

讲义:让课后阅读有完整的上下文

Tufte风格讲义

Quarto官方示例

在页面内滚动浏览

外侧箭头切换课件

打开原站 ↗

当前页可离线阅读
跨页链接需联网

书籍:把多讲内容组织成一本书

Python for Data Analysis, 3E

Wes McKinney

在页面内滚动浏览

外侧箭头切换课件

打开原站 ↗

当前页可离线阅读
跨页链接需联网

论文:连接研究叙述、图表与计算

La Palma Earthquakes

Quarto Manuscripts

在页面内滚动浏览

外侧箭头切换课件

打开原站 ↗

当前页可离线阅读
跨页链接需联网

用纯文本,写出可交互的幻灯片

官方示例源码 · 可滚动查看

index.qmd · 页面与参数控件
---
format: revealjs
---

## Interactive Slides {.smaller transition="slide"}

Turn presentations into applications with Observable and Shiny. Use component layout to position inputs and outputs.

```{r}
ojs_define(actors = data.frame(
  x = rnorm(100),
  y = rnorm(100)
))
```

```{ojs}
//| panel: sidebar
viewof talentWeight = Inputs.range([-2, 2], { value: 0.7, step: 0.01, label: "talent weight" })
viewof looksWeight = Inputs.range([-2, 2], { value: 0.7, step: 0.01, label: "looks weight" })
viewof minimum = Inputs.range([-2, 2], { value: 1, step: 0.01, label: "min fame" })
```

```{ojs}
//| panel: fill
import { plotActors } from './actors.js';
plotActors(actors, talentWeight, looksWeight, minimum)
```

::: footer
Learn more: [Observable](https://quarto.org/docs/interactive/ojs/), [Shiny](https://quarto.org/docs/interactive/shiny/), [Component Layout](https://quarto.org/docs/interactive/layout.html)
:::
actors.js · 绘图函数
import * as regression from 'https://cdn.skypack.dev/d3-regression';
import * as d3 from 'https://cdn.skypack.dev/d3';

export function plotActors(actors, talentWeight, looksWeight, minimum) {
    
  actors = transpose(actors).map(v => ({
    talent: v.x,
    looks: v.y,
    fame: v.x * talentWeight + v.y * looksWeight
  }));

  const w = 600;
  const h = 470;
  const result = d3.create("svg").attr("width", w).attr("height", h);
  const margin = 20;
  const xScale = d3.scaleLinear().domain([-2, 2]).range([margin, w - margin]);
  const yScale = d3.scaleLinear().domain([-2, 2]).range([h - margin, margin]);
  const points = result
    .append("g")
    .selectAll("circle")
    .data(actors)
    .join(enter => {
       const sel = enter
         .append("circle")
         .attr("r", 3)
         .attr("cx", d => xScale(d.talent))
         .attr("cy", d => yScale(d.looks))
         .attr("fill", d3.lab(50, 40, 20));
       return sel.filter(d => d.fame <= minimum)
         .attr("fill", "rgb(200, 200, 200)")
         .attr("r", 2);
    });
    
  const linearRegression = regression.regressionLinear()
    .x(d => d.talent)
    .y(d => d.looks)
    .domain([-2, 2]);

  const chosenActors = actors
    .filter(d => d.fame > minimum);

  const line = result
    .append("g")
    .append("line")
    .attr("stroke", d3.lab(20, 40, 20))
    .attr("stroke-width", 1.5)
    .datum(linearRegression(chosenActors))
    .attr("x1", d => xScale(d[0][0]))
    .attr("x2", d => xScale(d[1][0]))
    .attr("y1", d => yScale(d[0][1]))
    .attr("y2", d => yScale(d[1][1]));


  const xAxis = d3.axisBottom(xScale).ticks(3);
  result.append("g")
    .attr("transform", `translate(0, ${yScale(0)})`)
    .call(xAxis);

  result.append("text")
    .attr("x", xScale(0.05))
    .attr("y", yScale(2))
    .text("Looks");

  result.append("text")
    .attr("y", yScale(0.1))
    .attr("x", xScale(-2))
    .text("Talent");

  const yAxis = d3.axisLeft(yScale).ticks(3);
  result.append("g")
    .attr("transform", `translate(${xScale(0)}, 0)`)
    .call(yAxis);
  
  return result.node();
}

function transpose(df) {
  const keys = Object.keys(df);
  return df[keys[0]]
    .map((v, i) => Object.fromEntries(keys.map(key => [key, df[key][i] || undefined])))
    .filter(v => Object.values(v).every(e => e !== undefined));
}

对应幻灯片 · 拖动滑条试试

标题 → 数据 → 参数控件 → 图形输出官方源码 ↗

工具已经齐备,时间与精力仍是门槛

从讨论思路、生成可视化,到组织课件,工具都已就绪。

已经能做什么

与AI反复讨论教学思路

生成可调参数的演示

用Quarto组织课件与讲义

把资料整理成网页与书籍

全过程仍要自己串起来

整理材料 → 复制代码 → 保存文件

运行检查 → 反馈修改 → 嵌入课件

每个环节都能做,
独立完成一整套,仍耗费大量时间与精力。

能否让AI接着完成这些操作,把更多精力留给教学判断?

智能体协作:从零备课到课程成品

03

智能体协作

从零备课到课程成品

以《量子光学》为例,先看制作过程,再看课件、讲义与课程网站。

Codex
WorkBuddy
Claude Code
Quarto

Agent:从完成单项任务,到协助统筹整个项目

Codex · 本次备课使用的Agent工具以《量子光学》课程建设为例:组织材料、拆解任务并持续推进制作
01

理解项目

读取文稿、图片与大纲
理解课程要求与约定

02

拆解与推进

安排步骤与先后顺序
跟进进度与待办事项

03

执行与检查

修改文件、运行构建
根据结果继续修正

04

协同与维护

联动课件、讲义与网站
复用约定,持续更新

从“给出建议”,到“完成任务”,再到“协助统筹整个项目”。

从零开始:先确定这堂课要解决什么问题

量子光学第二讲 · 怎样补足自旋的前置知识对话节选(……为省略)· 上/下一步切换 · 框内滚动
我

学生不一定学过自旋

Codex

对,这里不能默认学生已经学过自旋。 我之前把“连续自旋分析”当成已有知识的迁移练习,低估了它需要的前置解释。

……

如果直接引入,学生要同时理解内禀角动量、两个测量值、分析轴、本征态,以及磁场如何分束。这样会在已经建立起来的偏振主线上,再开启一套新问题。

因此,我建议调整为:本讲核心推理始终用光子偏振完成;自旋作为后面的拓展例子。

我

但内容好像偏少啊。在量子光学中,自旋本身其实很重要,所以我愿意在合适的时间给大家补一下

Codex

明白,那我们应当在合适的位置补足自旋基础,把它发展成本讲的第二个物理实例。 我刚才把它移到选读,收缩得过多了。学生没学过,意味着这里需要搭桥;而自旋对后续原子、二能级系统和相干控制确实有用。

我

在这里补自旋,会影响叙事逻辑的通顺性吗?好像也可以考虑在量子比特的其他实现处来介绍

Codex

会有一定影响。放在“量子比特的其他实现”处,叙事会更顺,也更容易说明为什么要学自旋。

原因是:讲完三块偏振片时,偏振这条故事还没有结束。学生已经知道怎样计算概率、怎样更新状态,但“为什么概率幅需要复数”“相位到底能测出什么”仍未回答。此时插入SG装置、自旋和角动量,容易让这个尚未解决的问题失去连续性。

如果先把偏振量子比特讲完整,再问“这种结构能否在其他系统中实现”,自旋就有了清楚的进入理由。

……

这里的关键是:先从偏振中抽象出量子比特,再用自旋检验这个抽象是否真正有用。

围绕大纲,搜集与整理教学资料

量子光学第一讲 · 搜集资源并嵌入课件对话节选(……为省略)· 上/下一步切换 · 框内滚动
我

这个有没有可视化?网上能找到视频或者动图资源吗

Codex

有,找到了几个很贴合这一段的资源。我建议先放真实灯丝升温的视频,再用交互演示解释光谱。

资源 内容与用途
BYU:Blackbody radiation(视频) 调节灯泡供电,观察灯丝从暗红开始发亮,并通过光栅观察光谱变化。最贴近这句话。
多伦多大学:黑体辐射演示(视频) 灯丝、调压器和光栅的课堂实验,页面附装置说明,适合连接“看见发光”与“测量光谱”。
PhET:黑体辐射光谱(交互动画) 拖动温度,观察光谱高度、峰的位置和对应颜色怎样变化,适合现场操作。

这一段可以这样讲:

  1. 先看视频:让学生描述颜色和亮度发生了什么变化。
  2. 再拖动温度:在 PhET 中把肉眼看到的变化与整条光谱对应起来。
  3. 最后看实验谱图:提出问题——怎样用一个公式解释这条曲线?

开头也可以随素材改成:“逐渐加热灯泡里的金属丝,它先发出微弱的红光,随后越来越亮……”这样文字和画面就接上了。

继续:将资源加入讲义

我

你帮我把前面两个现象的可视化都加入讲义里面去吧

Codex

我会把黑体辐射和光电效应的实验视频、交互模拟放到各自的公式之前,配上简短的观察和操作提示,让学生先看现象,再读解释。

Codex

已加入第一讲讲义第1.2节,刷新即可查看:

  • 黑体辐射:灯丝加热视频、内嵌 PhET 调温模拟,以及观察提示。
  • 光电效应:锌板实验视频、模拟入口,以及“调亮度—换颜色—比较电流”的操作提示。

两部分都放在公式之前,并补上了一句话总结。光电效应模拟因原站脚本不支持跨站嵌入,采用新标签页打开。已重新生成网站并检查桌面、手机布局;在线资源需要联网。

后续:嵌入课件并检查运行 · 对话节选整理

我

把这些视频和可视化内容嵌入HTML课件中去。

Codex

光电效应已经能在课件里操作了:把红光调到最大亮度,电流仍为零;换成紫光后,电子开始逸出,电流随之出现。现在继续核验黑体、氢原子模拟,以及两个实验视频的实际播放。

Codex

黑体模拟也已经在课件内正常运行,拖动温度计能直接改变谱线和光源颜色。三个模拟都已放进课件资源目录;视频则使用大学网站的原生播放器,正在检查播放进度是否持续前进。

Codex

两个实验视频已实际播放成功:光电效应视频进度持续前进,灯丝视频也播放到了连续光谱画面。氢原子模拟的光源和光谱仪都能在页面内操作。最后检查新版封面、公式和页面边界,并同步使用说明。

制作插图与可视化,再按教学需要修改

量子光学第二、三讲 · 从静态图到交互演示对话节选(……为省略)· 上/下一步切换 · 框内滚动
我

这可以可以做可视化吗?

Codex

可以。这一处适合让学生同时看到A、B两组输入,并用同一个滑块转动测量方向:在H/V方向,两组统计都接近各半;转到正/负45度方向,差别就显现出来。

我会把现有演示改成这种并排对照,加入逐次探测和累计计数,直接放在图后。

Codex

并排演示已加入:每次点击都会给A、B各送入一个新光子,显示单次出口和各自的累计比例。转动测量方向时,两组计数一起清零,避免把不同设置的结果混在一起。

其中A始终输入正45度偏振;B每次先随机选H或V,再计算该光子的探测概率。接下来核对几个关键角度和计数行为。

Codex

已加在这张图后,默认展开。刷新讲义后可以:

  • 两组各测1次,观察单次结果。
  • 各测100或1000次,比较累计比例。
  • 转动测量方向:H/V时两组都趋近各半;正/负45度时,A全部进入正口,B仍趋近各半。

概率、抽样和切换角度清零已核对;最终浏览器显示效果尚未实测。

第三讲 · Bloch球:对话之后,直接操作制作结果

我

这个可视化可以把调参都放到右边,左边的布洛赫球再画大一些。

Codex

我会按课程视觉规范,把滑块、预设态按钮和重置集中到右侧,左侧留给放大的Bloch球;同时检查调参后状态和概率是否仍同步更新。

制作结果 · 可操作的Bloch球

拖动极角与方位角,或选择预设态,观察球面方向与测量概率。

把大纲逐节展开,写成可以连续阅读的讲义

量子光学第三讲 · 从逐段大纲到原子与离子讲义对话节选(……为省略)· 上/下一步切换 · 框内滚动
我

接下来一节,我们要讲什么?你先在对话框里给一个逐段大纲

Codex

下一节讲 “2. 原子与离子:怎样选出一个量子比特?”。

这一节先让学生看清:原子中的0、1对应什么,离子阱负责什么,外场又作用在哪里。建议分成三个小节,共九个正文段落。

2.1 从原子能级到两个编码态

第1段:从已经见过的原子光谱进入。
回顾第一讲的离散谱线:原子只能在某些允许的内部能量状态之间发生跃迁,发射或吸收的光与能量差有关。配一张简洁能级图,唤起已有知识,引出问题:这些不同状态能否用来表示0和1?

第2段:说明“内部态”指什么。
解释我们关心的是原子内部的量子状态,与原子整体在空间中的位置、运动分开描述。能级图的纵轴表示能量,图上的“上、下”不表示原子在空间中上下移动。这里先建立必要的物理对象,不展开原子结构理论。

第3段:在能级图上选出两个编码态。
从多个能级中高亮两个,分别标记为 |0⟩|0\rangle、|1⟩|1\rangle,再写出学生熟悉的叠加态形式。强调这两个标签现在表示原子的两个内部态;此前表示偏振的数学语言可以继续使用,但物理对象已经改变。

……

这一节最适合反复使用同一个离子、同一组选定内部态、同一张能级图。学生先认清对象,后面的Rabi模型就能直接接在这个对象上。

我

逻辑看起来可以,你按照这个思路写进讲义吧,需要插图的地方,用gpt image来生图。我稍后从讲义中来微调。

Codex

第二节正文已写入,分为2.1—2.3三个小节。两张图也已放在对应段落中;离子阱图已改成清楚的横截面,并注明控制与读出分步进行。接下来检查页面、图片放大功能,以及术语和图注是否与正文一致。

对应讲义 · 当前版本节选

2.1 从原子能级到两个编码态

第一讲中,我们见过原子的离散谱线:原子从一个较高能量的内部态跃迁到较低能量的内部态时,可以发射光,光子的能量等于这两个态的能量差。不同跃迁对应不同频率,形成一条条谱线。这说明原子的内部状态能够发生可观测的变化。我们现在关心的是:能否从这些状态中选出两个,分别表示0和1,并控制它们之间的转换?

这里的内部态,描述的是电子的空间分布、自旋等内部自由度的量子状态,与原子整体位于何处、怎样运动分开讨论。能级图用水平线标示具有确定能量的内部态,纵轴向上表示能量增加。例如,同一个原子可以留在实验装置的同一小片区域,内部能量却因为吸收或发射光而发生变化。

选定两个适合编码的正交内部态,分别记为 |0⟩|0\rangle、|1⟩|1\rangle。本节考虑它们具有不同能量的情形,将对应能量记为 E0E_0、E1E_1,并取 E1>E0E_1>E_0。这两个态及其线性组合构成一个编码子空间:整个原子有许多可能的状态,而我们用其中的这个二维部分承载一个量子比特。在这个子空间中,纯态仍然写为

|ψ⟩=α|0⟩+β|1⟩,|α|2+|β|2=1. |\psi\rangle=\alpha|0\rangle+\beta|1\rangle, \qquad |\alpha|^2+|\beta|^2=1.

这里的 α\alpha、β\beta 仍是概率幅;在这两个编码态组成的基下测量,结果概率分别为 |α|2|\alpha|^2、|β|2|\beta|^2。与第二讲相比,态矢量和测量规则保持相同,0和1所对应的物理状态从光子偏振换成了原子内部态。

从讲义到课堂:先规划每一页,再制作课件

量子光学第三讲 · 从讲义主线到逐页规划对话节选(……为省略)· 上/下一步切换 · 框内滚动
我

现在可以依据这个讲义来写课件了吧?你先规划一下课件。

Codex

课件可以沿用现在的讲义主线。我建议把九节组织成几个连续的课堂问题:先明确控制目标,快速并列介绍载体,再讲自由演化和布洛赫球,最后围绕时长、相位、频率三个参数展示控制现象。关键定义和推理留在主讲页,较长代数计算放在可随时跳入、返回的推导页。

我

我的skill有没有关于课件布局和内容组织的明确要求?

Codex

1. 内容组织的明确要求

  • 一页主要推进一个教学步骤。 多个步骤要有意义地分步呈现,或拆页。
  • 先有问题,再引入概念和工具。 学生只凭前文就应能理解为什么需要下一步。
  • 每段、每图、每式都要解决具体理解障碍。 仅仅正确、相关或美观,不足以保留。
  • 当前页提供必要输入。 初态、装置、符号和关键关系应就地出现;必要的精简重复可以保留,不能迫使学生频繁回翻。
  • 比较条件明确。 比较谁、保持什么不变、改变什么、观察什么,都要交代。
  • 核心知识点的位置服从理解顺序。 不能把依赖后文的总结放到开头充当导入。
  • 问题必须得到回答。 算例走完关键步骤,结尾回到开场任务。
  • 分步呈现不能提前泄露答案。 箭头和对应结果一起出现,中间状态也要完整、稳定。

……

所以,我上一版给出的是内容分配框架,还不是完整的页面设计方案。下一步应逐页明确:这页回答什么问题、需要哪些前置输入、主体图是什么、文字放在哪里、按什么顺序出现,以及最后得到什么结论。

第三讲 · Bloch球上的概率与相对相位用一个页面同时呈现球面、状态和测量概率。修改后留存截图 · 页码沿用当时版本 · 点击放大

当时的规划节选 · 页码为暂定

自由演化 → 布洛赫球:每组页面承担什么任务?

暂定页码 页面内容与讲述任务 图或可视化
1 封面,提出“如何控制一个量子比特” 沿用前两讲封面体系
2—3 给出翻转与制备叠加态两个目标;回顾固定主轴的相位元件为什么不能完成所有转换 同一初态、两个目标;相位元件对两个输入的比较
4—5 原子/离子与transmon并列介绍:编码态是什么、用什么驱动、如何选择跃迁 并列载体图;LC与transmon能级交互
6—8 建立无驱动参照:能量如何进入演化规律?为什么概率不变,状态仍可能变化? 两能级与能量矩阵;单一能量态和叠加态的比较
9—12 引入布洛赫球;读懂高度、方位、两极和赤道;把自由演化画成轨迹 态与球面联动;四个赤道态;自由演化动画

成果展示:让课堂讲解与交互演示连在一起

制作成果 · 01 / 03

沿着问题讲授

先提出问题,
再逐步显示推理与结果。

现场调参与比较

改变脉冲时长,
联动观察概率与状态。

按课堂节奏展开

需要时进入详细推导,
讲完再回到主线。

第三讲课件 · 脉冲时长
新窗口 ↗

框内箭头翻页 · 拖动关断时刻观察末态 · 离线演示

成果展示:配套讲义支持课后连续阅读

制作成果 · 02 / 03

补全解释与推导

保留必要的上下文,
支持学生独立复习。

保留图像与交互

边读边观察、调参,
对照文字与现象。

与课件互相配合

围绕同一课程内容,
配合讲授与阅读。

第三讲讲义 · 量子调控
新窗口 ↗

框内滚动与点击

成果展示:通过课程网站统一组织教学材料

制作成果 · 03 / 03

提供统一入口

按讲次组织内容,
找到对应课件与讲义。

关联课程资源

把演示、参考材料
与课堂内容放在一起。

持续更新与维护

沿用项目结构和约定,
协助检查、构建与更新。

量子光学 · 课程网站
新窗口 ↗

课程首页 · 点击资料打开课程网站

实践中的坑:能生成,不等于能上课

04

实践中的坑

能生成,不等于能上课

人工把控质量,用skill持续迭代,让教师始终主导。

把控质量·迭代skill·教师主导

一键生成了,但还不能直接上课

机械波 · 6页选段
1 / 6
展开查看 →
波的能量 · PPT
1 / 9
波的能量 PPT 第1页
展开查看 →
版式与教学逻辑未必符合要求,内容也可能只是材料的堆砌。

一键生成了,但还不能直接上课

机械波 · 1 / 6

一键生成了,但还不能直接上课

机械波 · 2 / 6

一键生成了,但还不能直接上课

机械波 · 3 / 6

一键生成了,但还不能直接上课

机械波 · 4 / 6

一键生成了,但还不能直接上课

机械波 · 5 / 6

一键生成了,但还不能直接上课

机械波 · 6 / 6

一键生成了,但还不能直接上课

波的能量 · PPT · 1 / 9
波的能量 PPT 第1页

一键生成了,但还不能直接上课

波的能量 · PPT · 2 / 9
波的能量 PPT 第2页

一键生成了,但还不能直接上课

波的能量 · PPT · 3 / 9
波的能量 PPT 第3页

一键生成了,但还不能直接上课

波的能量 · PPT · 4 / 9
波的能量 PPT 第4页

一键生成了,但还不能直接上课

波的能量 · PPT · 5 / 9
波的能量 PPT 第5页

一键生成了,但还不能直接上课

波的能量 · PPT · 6 / 9
波的能量 PPT 第6页

一键生成了,但还不能直接上课

波的能量 · PPT · 7 / 9
波的能量 PPT 第7页

一键生成了,但还不能直接上课

波的能量 · PPT · 8 / 9
波的能量 PPT 第8页

一键生成了,但还不能直接上课

波的能量 · PPT · 9 / 9
波的能量 PPT 第9页

AI生成的内容,必须由教师把控质量

生成前先明确范围,生成后再把控质量。

先给范围与依据提供教材、大纲等材料,明确讲什么、讲到什么程度。
内容是否可靠概念、事实与结论,需要人工核对。
是否适合学生深度、顺序与表达,需要教师判断。
课堂是否可用亲自看、亲自操作,再决定如何使用。
教师明确范围与要求,AI完成初稿,再由教师检查、修改并决定采用。

把备课与讲课的经验总结成 skill,持续迭代

skill 是供 Agent 反复使用的工作指南。
把要求、步骤和纠错经验写进去,后续做同类任务时就能复用。

完成备课
与讲课
→
检查结果
发现问题
→
修改内容
更新skill
→
下一讲
继续复用
skill 越完善,一键生成就越有用。要求与经验不断积累,产出更符合教学需要,重复操作与改错的成本也更低。

用好AI,教师必须始终做主导者

教学目标由我确定,
内容取舍由我判断,
交给学生的材料由我负责。

让AI承担执行,让教师主导目标、质量与取舍。

更多尝试:从课题组网站到招生海报

05

更多尝试

从课题组网站到招生海报

把这些方法用到资源组织、成果展示与招生宣传中。

课题组网站·招生海报·更多应用

从制作文件,到发布和维护课题组网站

课题组网站 · 滚动浏览 打开网站 ↗

把资料组织成网站

个人介绍、研究方向、论文成果与团队成员,形成清晰的浏览入口。

让Agent串起制作步骤

整理资料、编写页面、调整导航,再检查和构建。

持续更新与维护

新增论文、成员与招生信息,在已有结构中继续修改。

https://zimin.li

招生海报:同一套内容,三种视觉风格

这份分享,也是一次Codex协作的实践

Codex

本次分享的材料,
均由Codex整理制作。

从开始规划到本次统计

6天15小时

9月23日 22:21 → 9月30日 13:45

Codex累计运行时间

约5小时50分钟

本次对话中151轮已完成任务

运行时间按已完成轮次累计,含工具执行与等待,不含轮次之间的间隔。

我提供材料与经验,决定讲述逻辑;
Codex负责整理、排版、嵌入与修改。

视频分享 · 欢迎交流

打开B站原页 ↗