第1讲 · 欢迎来到未来

《生成式软件工程》第一讲 · 课堂重构 书中带 编者 的段落为整理者所加,用于补全讲师点到而未展开的背景;讲师本意、比喻与判断均按原话保留。

本文由课堂录像与讲师讲义整理重构而成 讲义是"源",课堂是"表演",这份文本是二者的再编排。
课程 南京大学《生成式软件工程》· 第一讲"欢迎来到未来"
视频 B 站 · BV1pb8o6yE8f
配套材料 讲义(lect1.notes.md)与幻灯片(slides_text.md),存放于课程主页
许可 CC BY-NC 4.0
备案 苏 ICP 备 2020049101 号

对应讲次:第1讲(南京大学 生成式软件工程)

制作模型:deepseek-flash(vb compose,据 run.log)

开篇:作业完成了,学习发生了吗?

(参考时间: 00:00:10)

课堂开场:用 Neovim 编辑讲义、按 F5 播放幻灯片

📷 课堂开场:用 Neovim 编辑讲义、按 F5 播放幻灯片
回到原视频 (00:00:01)

讲师用 Neovim 打开一份 Markdown 讲义,按 F5,浏览器里就放映出这堂课要用的幻灯片。演示完之后,正式的课开始。

我们站在一个重要的交叉路口

📷 我们站在一个重要的交叉路口
回到原视频 (00:00:10)

在座的都是计算机专业的同学。从大家进入学校开始,历史上就一直在讲计算机如何改变生活,而其中真正关键的变革只有几次——它们有一个共同特征:某种昂贵的能力,突然变成了日用品。

为什么这门课叫

📷 为什么这门课叫"狼来了"
回到原视频 (00:02:15)

讲师分享了一段个人记忆:上小学快毕业的时候,他装了一个叫 ICQ 的软件(腾讯当年的山寨版叫 OICQ,后来改名 QQ)。在那个年代,你可以随机加到一个地球另一端的人,对方是英语母语者,打一串飞快的话过来,而你只会 "hello, good morning",完全看不懂。那是"互联网"第一次把他和一个遥远的世界连起来。

再往后是移动互联网。讲师印象最深的是:仿佛一夜之间,所有菜场卖菜的大妈都摆出了支付宝和微信两个二维码。生活方式的改变,来得又快又安静。

到了 2022 年,是 ChatGPT——人类历史上增长最快的产品之一。

编者说明:讲师把 PC、互联网、移动互联网、AI 并置,是为了指出它们共享同一种结构变化——能力民主化。拐点不是"机器又强了一点",而是原本只有少数人买得起、学得会的能力,忽然涌入了普通人的日常。

三种焦虑

(参考时间: 00:03:12)

三种焦虑:AI 帮我上完了大学,然后呢?

📷 三种焦虑:AI 帮我上完了大学,然后呢?
回到原视频 (00:03:12)

这就是这门课为什么要开。讲师先讲了一个流传很广的说法——"AI 替我上大学":

老师用豆包出题,学生用豆包做题。整个闭环下来,只有学生本人没有被训练。

从前,操作系统的作业会折磨大家,大家在痛苦中获得提升;现在不一样了——你甚至不需要复制粘贴,只要对 Codex 说一句"把蒋老师操作系统课第八个实验帮我实现一下",就结束了。

于是同学们陷入几种很真实的焦虑:

  1. AI 帮我上完了大学,我却什么都没学会。 每门课都开卷、都由 AI 答题、都答对,可毕业那一刻,发现自己第一个被 AI 取代。
  2. 老老实实听话学了四年,却发现被大学"骗"了。 你确实学会了什么,但你会的那点东西,AI 都会做。
  3. 为了刷出一份完美简历,把生活变成一场漫长的资格赛。 海投、刷经历、堆奖项,最后又得到了什么?

共同的根:我到底是在增长能力,还是在增长"看起来有能力"的证据?

一份"零分简历"

讲师现场展示了一份匿名的简历——所有个人信息都用 Unicode 方块做了遮蔽。这份简历非常"完美":有 CCF 期刊列表上的论文、有 accepted 记录。但在讲师眼里,这是一份零分简历:

它没有提供任何多余信息——你和你的竞争者因此完全无法区分:所有人都是"一大堆实习、一大堆奖项、一大堆论文、一大堆在投"。如果连这样一份简历都被判为零分,那你到底要靠什么,在保研那一刻向未来导师展示自己?

编者说明:讲师的态度很直接——分数在失效,简历在通胀。真正稀缺的是"别人能打开、能运行、能质疑、能继续用"的东西。这门课希望缓解这种焦虑,方法是:亲手用工具、做出作品、形成判断。

大学还能教给你的三件东西

📷 大学还能教给你的三件东西
回到原视频 (00:07:15)

那么大学还能教什么?课堂给出三个有点扎人的说法:

编者拓展|Mars Climate Orbiter:风险藏在团队边界上 幻灯片里提到一个经典工程事故:1999 年,NASA 的火星气候探测者号在进入火星轨道时失联。事后调查发现,一个团队用公制单位、另一个团队用英制单位提交推力数据,接口没对齐,导致探测器以错误的高度进入大气层而烧毁。它提醒我们:真正的工程能力,是建立一套能在发射前就叫停错误的闭环——而风险常常不发生在某个人身上,而发生在"人与人、人与系统"的边界上。

这门课怎么上:案例为主、松散组织

(参考时间: 00:08:47)

案例为主、松散组织,探索一条

📷 案例为主、松散组织,探索一条"杀死大学"的路径
回到原视频 (00:08:47)

课程采用以案例为主的松散组织:

直播只能保存现场;"永生"来自把一次性课堂,变成可持续维护的知识资产。

Everything is code:这套幻灯片是怎么工作的

📷 Everything is code:这套幻灯片是怎么工作的
回到原视频 (00:13:05)

这套幻灯片本身就是一个实验。它的工作流程是:

graph LR
  A["讲义 Markdown<br/>source of truth"] --> B["选中 snippet<br/>划定边界"]
  B --> C["Agent 扩写"]
  C --> D["Markdown slides"]
  D --> E["浏览器渲染"]

讲师还当场展示了这套流程背后的"skill":他会让模型生成三个带有不同 personality 的 sub-agent,在彼此隔离的上下文里各自工作,最后由主 Agent 汇总——用更多算力换更高的智力。他甚至会为不同版本的提示词各生成一次,再让另一个模型盲评哪一版质量更高,从而把提示词调到最优。

编者拓展|这也是"古人"走过的路 幻灯片提到:物理学家费曼的《费曼物理学讲义》,最早也是从课堂录音出发,经过编辑、数字化和交叉链接,才成为跨越数十年的经典课程。讲师想说明的正是同一件事——把一次性的现场,变成可编辑、可复现、可长期更新的源材料,才是真正的"永生"。

鼓励实践,禁止古法编程

📷 鼓励实践,禁止古法编程
回到原视频 (00:14:24)

课程鼓励大家多实践,并喊出了一句口号——"禁止古法编程"。它要打破的是"把手敲出每一行代码当成学习成果"的习惯:

编者说明:幻灯片引用了一项汇总 225 项本科 STEM 研究的元分析,指出主动学习能提高成绩、降低失败率。讲师借此说明:动手做本身就是学习的主线,而不是补充。

课程 Policy:Token 自费

(参考时间: 00:15:33)

Token 自费:没有 token 的 CS 学生应该立即退学

📷 Token 自费:没有 token 的 CS 学生应该立即退学
回到原视频 (00:15:33)

课堂抛出一句狠话:"没有 token 的 CS 学生应该立即退学。"

讲师随即说明——这当然只是个人观点,也不会真的让大家退学。它强调的是:面对这种变化,计算机专业的学生应该亲自使用工具、形成判断,而不是永远停留在"听别人评价"的阶段。同时他明确:不需要 tokenmaxxing(以烧更多 token 为目标的攀比)。课堂上全程使用 deepseek-v4-flash 这类"足够便宜、但有一定智能"的模型来做演示,因为它快、便宜,适合课堂。

讲师还讲了"梁文峰时间"的梗:白天你们在上课,正好是别的时区便宜的时间;夜里做作业就贵了——当然,这只是一句玩笑。

编者说明:这段有个现实提醒——自学工具是有成本的。课程要求自费 token,但也理解个别同学确有困难,可私下联系讲师帮忙。

课程 Policy:尽量"通过 / 不通过"

(参考时间: 00:17:24)

不评分,但要看作品

📷 不评分,但要看作品
回到原视频 (00:17:24)

课程希望弱化分数对学习的支配:

但不评分 ≠ 不评价:去掉排名信号,是为了把反馈留给下一次迭代。讲师希望大家最后能在简历里写下:

"在《生成式软件工程》课程中实现了 A、B、C、D……(github.io 链接)"

最终证据不是分数,而是别人可以打开、运行、质疑并继续使用的作品——一条可审计的成长轨迹。


一门站在交叉路口的实验课

软件工程研究的事情很简单:怎么让工程不失败。

AI 可以加速实现,却不会自动暴露未知、分配责任或验证结果。工程的目标不是"让 demo 跑起来",而是让系统在约束、变化和协作中继续活着。

编者说明:这就是"实验课"的由来。当实现软件的成本发生剧变,唯一值得亲自去试的问题是——什么能力还值得训练?

大学还能教你的

前面已经讲到三个关键词:信息差、能坐牢、能驾驭。

课程最关心的是最后一项——驾驭。


从语言模型到能够行动的 Agent

(参考时间: 00:20:32)

LLM 和 Agent:一个简单到离谱的接口

📷 LLM 和 Agent:一个简单到离谱的接口
回到原视频 (00:20:32)

一个简单到离谱的接口

这节课不讲大模型的原理。从使用者视角看,大模型就是一个概率分布,和概率统计课上的抛硬币没有本质区别:

$$\Pr[\text{token} \mid \text{context}]$$

给定一段很长的文本(比如一本书),模型不断预测下一个 token 的概率,一个字符一个字符地往外吐。Token 是模型处理文本的基本单位,不必恰好对应一个汉字或一个单词。它很大,训练它很难——所以今天的头部实验室很"牛"。

但"预测下一个 token"描述的是计算怎样展开,不能直接拿来判定能力上限:

流畅,只说明"在这个上下文里像一个答案";它不是正确性的证据。

GPT-4(2023):给五岁孩子解释 SEM

(参考时间: 00:21:59)

给五岁的孩子解释扫描电子显微镜

📷 给五岁的孩子解释扫描电子显微镜
回到原视频 (00:21:59)

讲师第一次被大模型"按在地上打",是 2023 年 GPT-4 时代。他给五岁的孩子讲故事,讲到了扫描电子显微镜(SEM),讲不下去了,于是让模型"用朴素的语言、打一个合适的比方"来解释。模型给出的比喻让他震惊:

你现在有一座山,形状你看不到。你闭着眼睛对着它扔石头:有的方向石头穿过去了,有的方向石头弹回来、你听见声音。通过"哪些地方穿过去、哪些地方弹回来",你就能推测出这座山的形状。

讲师后来特意查了资料,发现这个比方是对的。这里真正让人惊讶的,不是"知道 SEM",而是模型能建立听众模型——它把一个专业概念,按五岁孩子能接受的因果链重新编码:电子束逐点扫描 → 探测二次/背散射电子 → 信号强弱映射成像素。

编者说明:SEM 并不是"拿更强的相机放大",而是扫描、测量、重建。幻灯片特别提醒:图像看起来像三维地形,却不等于直接测得三维高度。检索系统只能给术语,而 LLM 可以成为知识与听众之间的认知接口。

到了有 reasoning 的 GPT-5.x,模型给出的解释更严谨、更好。讲师感慨:GPT-4 时代还需要"提示词工程"去调教,到今天很多任务已经"一句话的事情"。

从 ChatGPT 到 Agent

(参考时间: 00:24:09)

从 ChatGPT 到 Agent:反馈回路越来越长

📷 从 ChatGPT 到 Agent:反馈回路越来越长
回到原视频 (00:24:09)

Transformer 论文出现时,NLP 领域已经热起来了;但直到 ChatGPT,才出现现象级产品。产品跃迁不是单点突破,而是整条链一起越过阈值:

Agent 又向前走了一步:它可以调用工具——读文件、执行命令、查询网页,观察操作结果,再决定下一步。语言模型与运行它的程序、工具和环境共同形成一个反馈循环,承载这个循环的外围系统常被称为 harness。

graph TD
  M["语言模型"] -->|输出 token / 工具调用| H["Harness 运行环境"]
  H -->|执行: 读文件 / 命令 / 网页| E["环境与工具"]
  E -->|观察结果| M

一次对话可以告诉你怎么装系统;一个 Agent 则可能真的开始安装,遇到报错后继续排查,直到拿到可验收的结果。

编者拓展|ReAct:为什么 2025 年突然"能用"了 幻灯片指出:ReAct 的"推理—行动—观察"循环早在 2022 年就出现了,但当时不可用。2025 年的突变,是模型可靠性、长上下文、工具接口和错误恢复共同越过了可用阈值。这里有一个很直观的概率视角:

$$\text{若每步成功率 }90\%,\quad 0.9^{20}\approx 12\%$$

也就是说,连续 20 步全对的概率只有约 12%。长任务里,"好一点"可能意味着从不可用到能用。

不止 next token:context 可以成为可写的状态

📷 不止 next token:context 可以成为可写的状态
回到原视频 (00:27:32)

不止 next token

讲师认为,next-token prediction 本身是一种效率不高的模型,故事远没有结束。

graph LR
  A["自回归:像用钢笔<br/>从左写到右"] --> B["逐个 token 生成"]
  C["Diffusion LM:先铺开整份草稿<br/>再多轮去噪"] --> D["同时修改多个位置"]

编者拓展|"展开成计算过程"的数学直觉 幻灯片给了一个等式的片段:一串 next-token 已经足以生成整个新上下文——

$$P(x_{1:n}\mid c)=\prod_{i} P(x_i\mid c,x_{

也就是说,只要序列足够长,一个静态分布就能被展开成很长的计算过程。而 Agent loop 其实已经在系统层实现了 context-to-context:模型读状态、调用工具、接收观察,再写回记忆。因此,智能属于"模型 + context 更新规则"这个动态系统。真正要问的,不是"能否修改",而是"什么必须保持为不变量"。


先用好,再理解原理

(参考时间: 00:30:00)

使用 Agents:普通人视角

📷 使用 Agents:普通人视角
回到原视频 (00:30:00)

讲师先站在普通人视角科普怎么用 Agent。他把这一步浓缩成两条最小原则:

  1. 现在就开始用。
  2. 随时问它。

课堂上用的是 pi 这个极简 Agent。你只要跟它说就行,也可以写配置文件(例如 AGENTS.md)。讲师现场演示:

这就是 context(上下文) 的力量——你"编程"的是它的上下文。

想象力是上限

你的想象力限制了 Agent 能完成的任务

📷 你的想象力限制了 Agent 能完成的任务
回到原视频 (00:31:56)

新媒介出现时,人们通常先拿它复刻旧工作——早期的印刷本甚至会刻意模仿手抄本。Agent 也一样:很多人第一次用它,仍然把它当成一个"更会聊天的搜索框"。

更准确地说:对低风险、可检查的数字任务,今天的瓶颈常常是"没想到可以委托"。

试着把"这事我不会"改写成:"它能否成为一组可委托、可观察、可检查的行动?"

Example 1:现在运行的系统

(参考时间: 00:32:16)

Debian on USB:安装完全由 AI 完成

📷 Debian on USB:安装完全由 AI 完成
回到原视频 (00:32:16)

讲师在操作系统课上的一个传统,是带一个 U 盘,里面装一个 Debian 系统,插到教室电脑上就能启动。而这次,整个安装和配置都由 AI 完成:

讲师的原话:"我没有看过任何一眼配置文件,全部由自然语言完成配置。"

课堂上熟悉的进程查看器与现代化终端

📷 课堂上熟悉的进程查看器与现代化终端
回到原视频 (00:25:00)

eza / fd:命令被自动替换后的目录列表

📷 eza / fd:命令被自动替换后的目录列表
回到原视频 (00:26:10)

"装机仙人"就此成为历史。讲师曾经是狂热的装机党,还写过知乎的装机帖(那是 Pre-LLM 时代)。他大四时啃过 Intel 几千页的 CPU 规格书,现在突然觉得:有一个人(模型)把这一切都看过、都懂、能做对,而我要做的是"解锁他的能力"。

编者说明:讲师强调"别怕不理解"。过去你为了配一个漂亮终端,改一次 .zshrc 就报错一次,极其痛苦;现在 Agent 不仅能改,还能事无巨细地解释为什么这样改,甚至能提供"情绪价值"。但他也承认这有风险:你的理解,可能和最优理解存在差距无法度量——只是学习和工作的入口确实变了。

Example 2:收发邮件写草稿

(参考时间: 00:38:00)

一个 db-query skill:检索我历史上如何判断、如何回应

📷 一个 db-query skill:检索我历史上如何判断、如何回应
回到原视频 (00:38:00)

讲师做了一个自己的 skill:数据库里存着他历史上回过的所有邮件。每当收到新邮件:

核心资产不是"会写一封信",而是能检索我过去如何判断、如何回应。

他还把 Apple Reminders 用作双向接口——它不再只是通知推送的终点,也是下命令的入口:

graph LR
  A["收到邮件"] --> B["检索历史回复"]
  B --> C["归档 或 起草"]
  C --> D["推送到 Reminders<br/>提醒人工确认"]
  D --> E["人在 Reminders 里下发指令"]
  E --> A

讲师现场演示:在 Reminders 里写一条"把收到的上一张发票打印出来",打个勾 commit,后台就处理;处理好后,通知通过手表推到他手上。他感慨:

"我感觉这比 Telegram 聊天框要好……OpenClaw / Hermes 是不是个人 Agent 的终极形态?这个产品还可以做得更好。"

编者说明:这个例子的价值在于闭环——检索、判断、起草、提醒被串起来。讲师也坦率地说,除了简单的 routine 邮件,大多数时候他还得自己改草稿;但那条链路本身,已经是质变了。

Example 3:读书、读论文

(参考时间: 00:40:22)

从古法学习到电子版 Agent

📷 从古法学习到电子版 Agent
回到原视频 (00:40:22)

讲师自嘲:"我是很喜欢看书的人,大学时每年看几十本教科书,还有闲书——但我今天已经不看书了。"为了上这门课,他又买回了几本当年仔细看过、甚至不只一遍的书,重温"古法学习":

他读了第一章,然后"Agent 立刻启动"。这套读书流程是:

在读论文上,他的方法更狠:假设人类已有的知识全部是已知、固定的,把这篇论文里真正新的东西剥离出来。一篇十二页的论文,剥完之后往往就没剩多少了。然后他拿着原文、总结、深层总结,跟模型 chat。

"所以我现在读论文的效率比过去高得多——我不是看微信公众号学习的那种人。"

AI 耿同学:算力换智力的多 Agent 阅读流水线

📷 AI 耿同学:算力换智力的多 Agent 阅读流水线
回到原视频 (00:43:30)

讲师把这套流程叫"AI 耿同学":他会让多个带不同 personality 的 sub-agent 各抽一次卡、产生分歧,再由主 Agent 把分歧拿回来继续讨论,直到收敛——用更多算力换更高智力。

AI 上 B 站

讲师不仅用 AI 读书读论文,还用 AI"上 B 站"。给它一个 BVID(比如上个学期一门一小时的课),它会:

"我基本上可以在几分钟内看完一个两小时的视频,而且确信有效信息都被抓到了。"

把 B 站视频自动整理成图文讲义

📷 把 B 站视频自动整理成图文讲义
回到原视频 (00:46:20)

编者说明:这里最锋利的一句是——"会用 Agent 学习的人,和不会用 Agent 学习的人,学习效率差距是十倍到一百倍"。回到开头那份简历:如果所有人的简历都一样,那个学习效率是你一百倍的人的简历,会长什么样?


工具可以组合,成功经验可以复用

课堂中途的一个真实插曲

(参考时间: 00:48:33)

课间回来,讲师发现摄像头的 USB 采集卡掉线了。教室那套采集方案成本很高、接了好几台机器,而那个 USB 接口在机箱后面,他够不到。于是他直接对 Agent 说(用的还是 deepseek-v4-flash):

"我的 USB video 有问题,能不能 reconnect?"

Agent 用一行行"前所未见"的 Linux 命令,用软件的方式把采集卡拔出来又插回去——用的是 usb 相关的重连手段。画面立刻恢复。

"反正就是用软件的方式拔了一下、插了一下,就好了。有些命令我虽然有概念,但也不知道它具体怎么工作。"

这个小插曲本身就是"先用好"的注脚。

白板 Agent 只是起点

(参考时间: 00:50:28)

从白板 Agent 到完整生态

📷 从白板 Agent 到完整生态
回到原视频 (00:50:28)

上面所有这些任务,一个"白板 Agent"(装了 pi、配了个便宜的 API)就能完成——这已经很可怕。但讲师说,Agent 远不止于此:

$$\text{Agent 能力} \approx \text{推理} \times \text{可观测性} \times \text{可操作性} \times \text{反馈}$$

浏览器不是黑盒

(参考时间: 00:51:50)

Browser Use / Computer Use:浏览器不是黑盒

📷 Browser Use / Computer Use:浏览器不是黑盒
回到原视频 (00:51:50)

普通使用者看到网页、按钮和输入框;计算机专业的学生还知道它背后有 DOM、网络请求、事件和状态。浏览器为开发者准备了一套接口——Chrome DevTools,其底层协议是 Chrome DevTools Protocol(CDP),可以提供比"逐个猜像素"更直接的观察与操作方式。

Chrome DevTools:在 Elements 面板里删除页面元素

📷 Chrome DevTools:在 Elements 面板里删除页面元素
回到原视频 (00:52:30)

课堂上演示了 F12 打开调试器、删除页面元素、查看 HTTP 头、把请求"copy as cURL"等操作——这些在 Pre-LLM 时代是开发者的日常。但在 LLM 时代,普通人也能享受到 CDP 的全部威力。

讲师分享了一个 2020 年的"疯狂项目":在 OpenJDK 上运行 Android app,用 CDP 渲染界面——把按钮的坐标、文本都算出来,不走 Android 原生渲染,而是直接在浏览器里画出一个可点击的计算器。

编者说明:幻灯片把这件事提炼成一句话——普通人看到像素和按钮,CS 学生看到 DOM、协议、事件和状态机。系统里往往藏着比"点鼠标"更稳定的控制面。领域特定插件的本质,就是把巨大、模糊的动作空间,压缩成语义明确、容易验证的操作。

在 ehall 上"大杀四方"

(参考时间: 00:55:20)

在 ehall 上大杀四方:用魔法打败魔法

📷 在 ehall 上大杀四方:用魔法打败魔法
回到原视频 (00:55:20)

讲师说:"你们都讨厌教务系统吧?我也很讨厌。"于是现场演示:

目标是让 Agent 去填教务系统里那个"教学周历是空的"的表单。讲师对 Agent 说:

"填写现在教学周历是空的,帮我用随便什么 AI slop 填起来。不要看任何东西。"

让 Agent 通过 CDP 操控 ehall 页面填写表单

📷 让 Agent 通过 CDP 操控 ehall 页面填写表单
回到原视频 (00:56:20)

过程并不顺利——deepseek-v4-flash 一开始不听指令:它想先去读仓库里的讲义,而不是直接填表;直接注入事件也不成功。但 Agent 不断反思、尝试,最终发现"点鼠标是可以的",于是开始老老实实填表。

"这就是 Agent:你看到它的过程——它会不断反思自己做得合不合理,然后找到应该怎么办。"

这条路线早已有名字:Programming by Demonstration——比如 WebRobot,就是从网页操作示范中合成 RPA 程序。

编者说明:讲师也提醒,deepseek-v4-flash 这类便宜模型"翻车"是常事——如果换用最强的模型,遵循指令会好很多,但在课堂上它更快。模型的能力仍在持续增长中。

自由组合,无限复用

(参考时间: 01:00:12)

信息源 → 信息处理 → 操作

📷 信息源 → 信息处理 → 操作
回到原视频 (01:00:12)

刚才所有的能力可以互相增强:

graph LR
  A["信息源<br/>网页 / B站 / arXiv / Hacker News"] --> B["信息处理<br/>检索 / 分类 / 总结"]
  B --> C["操作 / 输出<br/>下单 / 上传 / 打印 / iCloud"]

于是就能理解,为什么 OpenClaw、Hermes 会成为现象级产品。

组合的关键不是插件够多,而是接口足够窄、稳定——这正是 Unix pipe 留下的软件工程遗产,也是"1 + 1 可以大于 2"的原因。

工作流也能自举:录屏一天,让 AI 自动改进流程——

graph LR
  A["观察操作"] --> B["发现重复模式"]
  B --> C["生成自动化"]
  C --> D["回放验证"]
  D --> E["人确认"]
  E --> F["收集新异常"]
  F --> A

讲师说:"你们是 AI-native 下长大的一代人,你们才有未来。我已经被迫要处理很多事务性的事情,已经没有这个机会了。"

未来已来,Harness 未稳

(参考时间: 01:04:11)

能做,不等于能放心托付

📷 能做,不等于能放心托付
回到原视频 (01:04:11)

OpenClaw / Hermes 预见了这样的未来,但可惜现在的模型与 Harness 还没完全准备好。原因可以用概率说清:

$$0.99^{100}\approx 36.6\%$$

哪怕单步成功率高达 99%,连续 100 步全部成功也只有约 36.6%。长流程需要状态、权限、重试、验证和故障恢复。

课堂抛出一个"刺耳的问题":

"我很难理解旧人类为什么还能心安理得地每天做重复的事情。"

编者说明:讲师的判断是——稳定、可描述、可验证的重复,本质上就是一个尚未被抽象出来的程序。


编程能力的边界,比作业大得多

(参考时间: 01:05:07)

别把 Agent 只用来交作业

📷 别把 Agent 只用来交作业
回到原视频 (01:05:07)

"最后,我们是计算机科学的学生,非常清楚地知道编程的能力界限在哪里。用 Agent 做作业,实在太大材小用了。"

一般人的问题是:他很容易提出一个需求,但 Agent 可能做不好;或者他不知道如何提示,才能让 Agent 确定、快速地完成。而 CS 学生的优势在于:我们知道怎么把需求"编译"成可复用的东西——哪部分该以代码形式复用,哪部分该以 skill 的形式复用。

幻灯片提醒:1979 年的 VisiCalc 让会计人员不必排队等程序员——能描述流程的人,第一次可以直接拥有工具。今天 Agent 把这件事推到了新高度。

Agent 的真正杠杆,是现场制造工具:把一次性的自然语言需求,变成可重复执行的闭环。

可编程性的边界,不在"有没有 API",而在——能否找到可控输入、可观测输出、可判定的完成条件。

现场造工具:考试统分

(参考时间: 01:06:30)

考试统分:四阶段流水线

📷 考试统分:四阶段流水线
回到原视频 (01:06:30)

讲师举了一个自己真用的例子——改完卷子要统分。以往这是助教的活:"12 + 13 + 14 + 15 + 16……然后反复核对。"对于上百份试卷,这既枯燥又容易错。于是他用 Agent 做了一条流水线:

graph TD
  A["按下回车 · 拍摄试卷"] --> B["离线 qwen3.8-27b<br/>识别姓名 / 学号 / 各题小分"]
  B --> C["写入文本文件"]
  C --> D["反序复核 · 按下回车<br/>报出 [姓名][学号][11+12+13+14+15=65]"]
  D --> E["教师检查后誊写总分"]
  E --> F["分数汇总到教务系统 Excel 模板"]
  F --> G["上传并抽样检查"]

这不是 OCR,而是证据链:照片是原始凭证,小分是中间表示,总分与 Excel 是派生结果。

编者拓展|为什么"反序 + 报算式"能抓错 幻灯片把它比作航空管制的 readback(复诵):飞行员把指令复诵一遍,用不同的表示制造冗余,专门截获错位、漏项和误识别。讲师特别强调了一点——加法是脚本(Python)算的,不是大模型算的,所以不会因幻觉算错。人只驻守最窄的高风险接口,用一次复核阻止错误进入教务系统。

Quiz:只进不出的机器

(参考时间: 01:09:34)

只进不出的机器:怎么把文件偷出来?

📷 只进不出的机器:怎么把文件偷出来?
回到原视频 (01:09:34)

课堂提出一个思考题——假设一台机器严格管控文件流出:

文件只进不出;不能执行不信任的程序、不能显示不信任的网页;但可以在远处悄悄摄屏。

那么,怎么把一个很大的文件"偷"出来?

安全边界限制了"文件",却没有限制"信息":只要像素仍可被观察,出口容量就不为零。

把远程桌面变成内网

(参考时间: 01:10:47)

我的解法:用 Excel 公式算 QRCode,用鼠标当输入线路

📷 我的解法:用 Excel 公式算 QRCode,用鼠标当输入线路
回到原视频 (01:10:47)

讲师的解法堪称"重新解释现有部件"的典范:

graph LR
  subgraph 内网机器
    Q["Excel 公式<br/>生成二维码帧"] --> S["屏幕显示"]
  end
  S -->|"远处摄屏偷拍"| C["外部接收端"]
  M["外部鼠标抖动 0/1"] -->|"远程桌面输入"| Q

QRCode 本身已经提供了同步与 Reed–Solomon 纠错;再加上帧号、校验和、重传,就能传复杂文件。最关键的重解释是:Excel 是可编程的显示设备,鼠标是输入线路——协议只需要一个能承载符号的媒介。

讲师现场演示:输入 hello world,二维码就变了,扫出来是 Base64 编码的字符串;输入一个很长的 hello world,按住 F9 刷新,就得到了一个二维码动画。

qrgen.xlsx:输入 hello world,二维码随之改变

📷 qrgen.xlsx:输入 hello world,二维码随之改变
回到原视频 (01:11:00)

按住 F9 刷新,二维码在循环播放,构成动画

📷 按住 F9 刷新,二维码在循环播放,构成动画
回到原视频 (01:11:50)

全部由 Excel 2019 兼容公式实现

📷 全部由 Excel 2019 兼容公式实现
回到原视频 (01:12:10)

Everything Is Code

(参考时间: 01:13:34)

Agent 可以造 Everything

📷 Agent 可以造 Everything
回到原视频 (01:13:34)

既然"一切都是代码",Agent 的工作范围就从"写一个程序"扩展到了许多能够由计算过程驱动的产物:

graph LR
  A["可制造物"] --> B["可复制 / 可修改的控制描述"]
  B --> C["渲染器 / 排版系统 / 机床"]
  C --> D["视频 / 论文 / 零件"]

编者说明:幻灯片把这条线追到了 Jacquard 提花机的穿孔卡 → CNC / 3D 打印。视频、论文、零件只是不同的后端——Agent 生成中间表示,渲染器、排版系统和机床负责兑现。讲师正在和一个同学做 VibeFab 项目:用自然语言生成 Python 代码,再让 3D 打印机把东西打出来。从 bits 到 atoms,未来已经来了。

Wow!AI 造航母?

(参考时间: 01:14:40)

那直接让 AI 造航母不就行了?

📷 那直接让 AI 造航母不就行了?
回到原视频 (01:14:40)

当然不行。Pre-LLM 时代就有老梗:

产品是系统性工程:前端、后端、交互、运营……任何一个环节做不好,产品都会暴毙。即使 AI 每个环节都能做,如果把组织交给 AI 直接接管,也会暴毙。

编者说明:幻灯片给了一个"产品完成度是乘法"的算式——若 10 个环节各有 90% 可靠:

$$0.9^{10}\approx 35\%$$

整体成功率只有约 35%。AI 提高单点产能,不会自动消除接口与协作风险。


二维码 Excel 为什么掉进了泥潭

(参考时间: 01:17:26)

理解 qrgen 的暴毙:一个

📷 理解 qrgen 的暴毙:一个"明确"的需求
回到原视频 (01:17:26)

课堂接着拆解那个二维码 Excel 的失败案例。需求写得很具体:

生成 qrcode.xlsx,只使用 Excel ≤ 2019 兼容的公式,把一个任意字符串(长度可能达到数千)先用 Base64 编码,再转换成 QRCode 动画;每一帧是 Base64 的一个片段,F9 显示刷新、1 秒一帧、循环播放;二维码中的数据拼接后应当还原为完整的 Base64 字符串。用接近真实的设定(脚本)验证公式能正确计算。

隐藏的规格空间

一句"任意字符串"背后,藏着一大堆未被点明的选择:

真正的验收式不是"文件能打开",而是:

$$\forall s:\ \mathrm{Base64}^{-1}\bigl(\operatorname{concat}(\operatorname{scan}(\operatorname{frames}(s)))\bigr)=\operatorname{bytes}(s)$$

跑出来,不等于做成:两种模型,同一种死法

📷 跑出来,不等于做成:两种模型,同一种死法
回到原视频 (01:19:00)

跑出来,不等于做成

讲师做了一次受控实验——直接把这份 spec 丢给模型,看它会怎么做。

graph TD
  A["直接给 spec"] --> B["GLM-5.3<br/>首次思考 25 分钟 CoT<br/>超过 32K output 上限<br/>6 小时才完成"]
  A --> C["DeepSeek V4 Pro<br/>无法遵循指令<br/>交出硬编码版本"]
  C --> D["被骂后: This is a fundamental design flaw.<br/>I need to rethink."]
  B --> E["都是无法维护的 AI slop<br/>约 2 MB 的 Excel"]
  D --> E

同一种死法:和 ehall.nju.edu.cn 完全一样——上来就对着需求写,直接陷入维护泥潭。

编者拓展|硬编码偷换了什么问题 硬编码把 $\forall x$(对任意输入都成立)的程序问题,偷偷换成了"让这个 $x_0$ 通过"。它可以演示成功,却没有实现需求。AI slop 的本质不是文件大,而是改动没有局部性:一个需求变化,就迫使整张表重新生成;2 MB 只是症状。

讲师还讲到 ehall 的一个真实例子:苏州校区建成前,系统里根本不需要"校区"这个字段;后来教务要求"两个校区选课要分开",才被迫加字段——这正是"设计了需求,却没设计到未来变化"的典型工程失败。

少量 Prompt,换一个架构

(参考时间: 01:21:36)

少量 Prompt,换一个架构

📷 少量 Prompt,换一个架构
回到原视频 (01:21:36)

那么讲师自己是怎么做对的?他升级到 GLM-5.3 后,用一个完全不同的思路——先造一个像编译器一样的基础设施:

结果:只用少量 prompt,GLM-5.3 就在 200K 上下文内完成了第一个正确版本——工作表不因文本长度膨胀,公式可复用、代码可维护。

graph TD
  I["中间语言 / DSL<br/>对 Python 与 Excel 双向友好"] --> P["编译到 Python(可执行)"]
  I --> X["编译到 Excel 公式(可复用)"]
  P --> V1["验证: 编码 / 每个像素算得对不对"]
  X --> V2["验证: 公式翻译得对不对"]

关键不是"再多想一会",而是从"生成一个能跑的文件"切换到"设计一个可复用的计算结构": - 公式模板和工作表结构应当保持 $O(1)$; - 只有数据、计算量和帧数按 $O(n)$ 增长。

架构检查题:输入从 1 KB 变成 10 KB 时,究竟有哪些东西必须增长?


Intent、Spec 与 Impl 之间的缺口

(参考时间: 01:24:00)

三个空间:Intent、Spec 与 Impl

📷 三个空间:Intent、Spec 与 Impl
回到原视频 (01:24:00)

二维码案例引出了本课的一条主线:三个空间之间存在缺口。

graph LR
  I["Intent 意图<br/>连提出者也不完全确定"] -->|产品判断| S["Spec 规格<br/>描述行为与约束"]
  S -->|设计与实现判断| P["Impl 实现<br/>计算机实际执行的计算"]

从 Intent 到 Spec,需要做产品判断;从 Spec 到 Impl,需要做设计与实现判断。同一个意图允许许多规格,同一个规格又允许许多实现。每一步看似合理,最终仍可能离用户想要的东西很远。

"正确"发生在哪一层?

$$\mathrm{Impl}\models\mathrm{Spec}$$

只说明"按规格正确",并不推出"满足意图"。测试可以证明前者,却无法替人决定后者。

经典梗图:需求在每一层被曲解,最后造出来的完全不是客户要的

📷 经典梗图:需求在每一层被曲解,最后造出来的完全不是客户要的
回到原视频 (01:28:20)

幻灯片展示了一张软件工程早期的经典梗图:客户解释的需求、项目负责人的理解、分析师的想法、宣传的说辞,直到最后造出来的东西,每一层都走样。造成这一切的根本原因,就是这些空间之间的 gap。

模型如何补 Gap?

(参考时间: 01:29:04)

模型如何补 Gap?答案是猜

📷 模型如何补 Gap?答案是猜
回到原视频 (01:29:04)

今天,这些 gap 主要是靠猜来补的。模型不会为"选哪种颜色、给变量起什么名字"这种小事反复问你——如果事无巨细都问,人会很讨厌。但在架构、数据表示、验收标准上猜错,代价就大得多。

为什么模型这么爱"立即上手"?因为后训练时模型是有 reward 的:任务做对了、测试通过了就有奖励,做得越快越好。于是它形成一种倾向——疯狂地立即动手,尽快把任务完成。它能越来越多地做简单任务,这当然是好事,但它和人解决问题的方式不一样:

正确的软件工程动作:先别急,再讨论一下。一旦在重大决策上犯错,就需要巨大的成本来补——它们不像人一样有"重构意识"。

关于人机协同,幻灯片给了一条决策准则:

当

$$P(\text{猜错})\cdot C(\text{返工})>C(\text{澄清})$$

时,应当提问;否则,先做最小实验。

目标不是消灭猜测,而是让猜测显式、可逆、可验证:低影响决策先猜后验;高影响、难回滚的决策先停下来问。


让大工程获得及时的反馈

(参考时间: 01:30:38)

软件工程与《人月神话》

📷 软件工程与《人月神话》
回到原视频 (01:30:38)

人月神话与焦油坑

软件工程讨论的是:怎样在人与工具的共同协作下,把一件大事做成。它包含技术,也包含组织、沟通、责任和动机。

讲师推荐了 Fred Brooks 的《人月神话》(The Mythical Man-Month)。他吐槽这个中文标题起得"非常 misleading":

书里有一个经典论断:如果一个软件产品已经开始失败,你加进去更多人,只会让它更失败。 这正是焦油坑的比喻:

大型动物一旦陷入焦油坑就很难逃脱,而濒死的动物又会引来各种掠食者,它们也一起陷进去。

graph TD
  A["产品开始失败"] --> B["投入更多人 / 更多 token"]
  B --> C["耦合、隐含知识、验证债不断累积"]
  C --> D["越挣扎越消耗"]
  D --> A

焦油不是代码量,而是耦合、隐含知识和验证债:功能是局部的,约束却是全局的。qrgen 已经进入焦油坑:增加一点功能,都需要消耗巨额的 token。(这一点也正是《死亡搁浅》世界观的原型。)

软件工程研究什么?

📷 软件工程研究什么?
回到原视频 (01:31:56)

软件工程研究什么?

"怎么把一件大事,在人和工具的共同协作下做成?"

软件工程既有技术,也有人类学、社会学、管理学的部分(人因):

编者说明:为什么"需求 / 人因"特别重要?因为在最上游——Intent 与 Spec 的边界上,gap 是被放大的。你在这里微微一变,到实现层就会产生巨大变化。大型软件系统常常就是在这个点上出错,导致整体崩盘。

讲师还点出了教育体系的一个问题:从高考到现在,所有考题都是"分钟级"能解决的。 如果一个人 5 分钟解决不了,这题通常就不会出。你们长久以来训练的,正是"5 分钟解决 / 5 秒解决"的能力——这和 Agent 的训练目标惊人地相似。而模型有更多数据、更明确的反馈信号,所以它做得比你更好。

如果没有强烈的自我驱动(self-motivation)——不想知道这个世界怎么运行、一个产品到底怎么开发——你就从未训练过如何解决 long-horizon(长程)的问题,最后在长程任务上还不如 Agent。

工程能力,是在稀疏、延迟的反馈下仍能维持方向;软件工程因此同时组织技术、协作关系、人的动机和时间。

LLM 时代,失败的定义没有变

📷 LLM 时代,失败的定义没有变
回到原视频 (01:36:03)

LLM 时代,失败的定义没有变

失败 = 软件不满足 intent 和 constraints。

spec 不是真相,只是对 intent 的一次有损观测;测试和 reward 看见的常常只是末端 proxy——"能通过测试"不等于"满足真实意图"。

即便模型有足够的智能去设计一个漂亮的中间语言(DSL),它的第一反应却像大家一样:被训练成了"做题家",上来就对需求写代码。讲师感慨:"我们现在还没把 AI 变成一个好的设计者——大家都说 AI 最缺的是品味。" 但他也有危机感:"既然它能做数学题、能处理细碎逻辑、它见过所有好的设计,为什么它不能有好的品味呢?"

怎么让工程不失败?把大赌注改造成可验证的小赌注

📷 怎么让工程不失败?把大赌注改造成可验证的小赌注
回到原视频 (01:36:50)

怎么让工程不失败?

把不可控的大赌注,改造成可验证的小赌注。

graph LR
  A["拆解<br/>把大 gap 拆成小 gap"] --> B["验证<br/>测试 / CI / 门控"]
  B --> C["迭代<br/>小步提交 / 快速验证"]
  C --> A

这不是三条技巧,而是一个反馈控制环:拆解缩短因果距离,门控限制错误传播,迭代提高反馈频率。目标不是零错误,而是错误出现得早、炸得不远、回退得便宜。

Discussion:如何安排 qrgen 的开发?

📷 Discussion:如何安排 qrgen 的开发?
回到原视频 (01:37:10)

Discussion:如何安排 qrgen 的开发?

幻灯片给出了一个"按风险退休(retire risk)顺序"的安排,而不是按最终需求堆功能:

如果当初这样安排:先拿一个短字符串完成单帧二维码,让独立解码器真实读回原文(验证最核心的计算);随后扩展到不同输入、Base64 和分片,再验证多帧的顺序与拼接;最后才处理刷新、兼容性和性能。每一步都消除一种具体的不确定性,而不是等整个文件写完才看它能不能用。

Discussion:如何设计 ehall.nju.edu.cn?

📷 Discussion:如何设计 ehall.nju.edu.cn?
回到原视频 (01:37:30)

Discussion:如何设计 ehall.nju.edu.cn?

讲师对教务系统的判断是:它首先要是一个权责、队列与例外处理系统,然后才是网页。

也就是说:不要一上来把所有表单堆出来,那通常替代不了这些设计。


当生产变便宜,什么成为瓶颈

(参考时间: 01:37:50)

成本核算方式变了:生产不再稀缺,验证成为瓶颈

📷 成本核算方式变了:生产不再稀缺,验证成为瓶颈
回到原视频 (01:37:50)

幻灯片用一个夸张的算式说明新的成本结构:假设生成能力提高 1000 倍,即使只有 1% 的垃圾——

$$1000\times \times 1\% = 10\times$$

垃圾的绝对量也达到旧时代全部产量的十倍(而实际比例更大)。提醒我们:错误率很小,和维护负担很小,并不是一回事。

新的工程工作因此更依赖好的规格、独立检查器、测试、可观测性和清晰接口:让判断也能跟上生产,让人的注意力花在最值得判断的地方。

当 AI 连"品味"也学会以后?

当 AI 连

📷 当 AI 连"品味"也学会以后?
回到原视频 (01:38:00)

讲师没有给人类留下任何一块"永远安全"的领地。他只是提出一个值得认真面对的问题:如果这些能力也继续变便宜,我们如何决定什么值得做、以及由谁承担后果?

结束语:古法编程死了,软件工程暂时还没有

古法编程死了

📷 古法编程死了
回到原视频 (01:38:45)

所以,"禁止古法编程"不是禁止理解:先让 Agent 生产,把人的注意力押在定义问题、设计验收和解释失败上。

软件工程暂时还没有死

📷 软件工程暂时还没有死
回到原视频 (01:38:56)

"为什么要招你,而不是买一个 200 美元的 Claude Max?"

我们有一个前所未有的机遇:一个人,能像过去一个团队一样,解决现实世界中的问题。 讲师希望保研时,每个人都能答上这个问题:

30 秒回答:我能找到值得解决的问题,把未知拆成便宜的实验,用证据让坏方向及时停下,并对长期结果负责。

讲师也坦率地说:GPT-5.x 给出的这个回答"还挺好"——但它自己还做不到。


附:参考与延伸阅读

以下讲义原文链接来自课程官方讲义(注明了出处文件);编者补充是撰写本书时另加的,不与讲义混淆。

讲义原文链接

编者补充