跳到主要内容

《动手学大模型应用开发》拆解大纲(定稿:已按审读意见改过)

这一份是动笔前的节级大纲,一节一行,每行「进来时以为 → 出去时知道」。 两头是同一件事的节已经删掉或合并。定稿后正文的节序与这里一致。

原书是 Datawhale 的开源教程 llm-universe,16.7 万字。转码后没有章节锚, 只有十个页桶(text/01-p1-20.txttext/10-p181-188.txt), 所以本组拆解的出处只能指到页桶 + 段号 + 搜索短语。

一、审读意见落到了哪里(逐条)

审读人分三批提了要求。第一批必须动笔前改完,否则越写越歪。

第一批:动笔前必改(四处)

审读提的问题改在哪
07 的整章主走查是三处拼起来的,书里没发生过采用审读给的方案 ①:老实用原书 4.2 的真实结果——「什么是南瓜书?」→「抱歉,我不知道南瓜书是什么。谢谢你的提问!」。链是通的、答案是空的;「为什么答不上」交给 06 §2 的只放 20 块
02 的走查把两次调用拼成一次走查换成英文那一次(messages 两条 → Hello! How can I assist you today?,19 / 9 / 28 个词元),费用也算在这一次上;中文「你好」那次留给 §5 讲封装
总纲 §2 说第三部分正文也空着改成:只有第二部分空着;第三部分两篇已完稿,由不同作者写、体例与第一部分明显不同。书首那句「第二、三部分正在创作中」标成书自己的过期说法
总纲 §4 的最短路径漏了建库那一章最短路径改成五章:0204050607;03(提示词写法)、08(记忆)、09(上线)、1013 归到「造完之后」

第二批:结构性的(改的是节与章的切分)

审读提的问题改在哪
「140 次」那笔账在两章各讲一遍只留在 11 §2(那里才有七个维度作支撑)。10 §9 改成只交一件 11 交不了的事:手工回归的次数随坏例子数成平方增长,并钉死「原来答对的不许被改坏」;10 §1 的出口收窄成「先一到三个例子调通」,不提自动化
「换个向量模型就全对不上」讲了两遍只留在 04 §4。原大纲 06 §2 整节撤掉,「落盘 / 重开」两行并进 06 §1 末尾;腾出的位子给 06 §2「为什么只放 20 块」(720 次调用、耗时、QPS 限制)
03 四处另起走查、且现象悬了三节重排成一条连续链:§1 现象(它对算错的题点头)→ §2 为什么会点头(先讲原则二)→ §3 两种给时间的写法(走查收口)→ §4 才进原则一。原则一的四个技巧压成一处另起(分隔符那一组)+ 一张表;幻觉那处是第二处另起。全章正好用满配额
08 是两个半章拼的,§3 → §4 断级拆成两章:08 记忆(一条两轮对话的走查)、09 上线(一条从 streamlit run 到浏览器的走查)。书里那句抄错的结论留在 08 §6,不再跨到上线那半
01 的走查只有起点和终点补出中间态:同一句「什么是南瓜书?」在 §1 拿到编造答案 → §3 看它被塞进模板后变成什么样 → §6 在八步图上标出它此刻在第几格
13(原 11)一章两个项目,走查只覆盖后一半拆成两章:12 个人知识库助手(走查:一个仓库的 README 走完五步)、13 天机(走查:「如何给长辈敬酒?」四条路)

第三批:逐句订正

审读提的问题改在哪
把自定义 Embedding 的三个方法安到了自定义 LLM 头上07 §2 只讲自定义 LLM(继承 LLM、实现 _call_llm_type);三个方法(_embed / embed_query / embed_documents)挪回 06 §3
跑分表说成「两列印反」改成只有 text-embedding-3-large 那一行的两个分数对调了,同表另外两行和官方公告一致。维度那处单独交代它出自第一章的另一张表
总纲说「算相似度的代码把参数用反了」改成「用 BLEU 自动评分的那段代码把参考答案传错了类型,两个分数都掉到 1e-231」,和 11 §4 一字对齐
第二部分目录列错(多了「重排」、漏了五项)照目录原样列进 11 §9(合并同级但不添不漏);「重排」另起一句说明它出自检索评估那一节的顺带一提
13 走查里两个数没出处删掉「几千条」,改用书的原话「在积累大量数据的情况下」;k_num=5 写明是同项目另一处查询用的取回数;「不需要显卡」标成我们的推断,并照实写「书那张表这一格是空的」
05 两处许诺兑不了①「切坏的块」只许诺给 11;②「标出处靠元数据」改成「07 把用到的原文块连同来源路径和页码一起还给你」。两处都进兑现表
11 走查首句许了「同一个输入贯穿全章」照实写:主走查用「应该如何使用南瓜书?」串 §2 与 §5;§3 客观题、§4 BLEU 明确标成另起的两处,并说明为什么必须换题
06 走查说取回「第 03 章讲少样本的那个文言文例子」照实写成「讲少样本的那一块(库里那份教程用的是祖孙对话 / 韧性的例子,和 03 正文那组文言文问答是同一技巧的两个版本)」
04 §5 用了「混合搜索」这个名字却把解释推给后面04 §5 改成大白话「把按词找和按意思找两路合起来用」,不出名字;名字留给 06 §6 挂牌
03 §5 把两种写法说成「书归到思维链名下」改成:书把它们放在「给模型时间去思考」名下;思维链是书在别处(第一章讲涌现、第五章讲自我反思)用的名字,并标明是我们把它们对上的
01 §3 引入「上下文学习」之后全书没再用01 §4 只说「你在提问里摆两个例子,它就会做一件没专门训练过的事」,不出名字;名字挪到 03 §5 讲少样本时挂牌,在那里它挣到了位子
模型谱系那一大段既没覆盖也没声明不覆盖01 §5 新增一节「这门课不教什么」把它整体收编成一句话 + 一张表;总纲 §5 同时明写「不覆盖:模型谱系与架构改进细节、RAG 的四阶段术语划分」
幻觉在三处讲成同一件事01 §1 = 它为什么不会说不知道(续写机制);03 §6 = 边界的方向(提示词管怎么问、管不了肚子里没有);10 §6 = 拼碎片式的幻觉和整段瞎编在检出难度上的差别
11 §7 声明了「召回率」却没得教从该节的新词里删掉,正文只留准确率那一个口径,并照实写「书把这一半推给了搜索领域的经典指标,没有展开」

三类来源的标法(审读特别提醒的一条口径)

书没写、而我们算出来或推出来的量,一律当场标。全书只有四处:

在哪是什么标成
06 §2建全库要调 720 次接口、要跑好几分钟我们的推算(书只给了「为了速度,只选择前 20 个」和 QPS 提示)
04 §5向量库「预先建好一张跳表」我们的通用知识(书只说「使用高效的索引和查询算法」)
04 §6官方公告的四个分数② 类外部来源,带查阅日期
13 §6知识库那条路不需要显卡我们的推断 + 照实写「书那一格是空的」

二、新词配额账(定稿后按实测重填)

口径按标准:只数 book-jargon 词表里的承重词,同一概念的不同叫法算一张脸, 按第一次出现的位置归章。章不设上限,一节上限 5 个、一段上限 1 个。

下面这张表是正文写完之后用 node scripts/book-jargon.mjs <bookId> --list 实测出来的, 不是动笔前的估计:

位置第一次出现的承重词个数
总纲大语言模型 / LLM / 模型、检索增强 / RAG / 检索、提示词、召回率、微调、幻觉、训练11(按概念算 7)
01机器学习、基座模型、提示工程、API、GPU、GPT、参数、涌现、算法9
02token / 词元、系统提示词、top-p、温度、接口6(按概念算 4)
03上下文学习、结构化输出、提示注入、JSON、思维链、上下文、少样本、分隔符8
04向量数据库、关键词搜索、基准测试、词向量、字符串、嵌入、向量、维度、余弦、索引、语义11
05上下文窗口、元数据2
06向量检索、混合搜索、提示3
07提示词模板、弃用2
08强化学习、记忆、轮3
09变量1
10智能体、迭代、解析3
11对齐、量化、分块、重排、优化5
12环境变量、开源2
13多智能体、LoRA、标注3

机检结果:段级超额 0 处、节级超额 0 处、首现无解释 0 处。 最重的两章是 04(11 个)和总纲(11 个,按概念 7 个), 但它们各自分在 6–8 个小节里,没有任何一节超过 5 个概念

压回去用的都是标准允许的两条路(拆章、把外围概念整节移出),一处都没有靠砍解释来压:

原本会更多压回去的办法
总纲20+兑现表整张用大白话重写(左栏写「许诺的意思」而不是逐字原文),否则那一张表会一次性把十几个还没解释的名字倒给读者;主线里「参数 / 变量 / 温度 / 记忆 / 余弦 / 元数据」等一律换成大白话
0111「上下文学习」整个挪到 03 §5(它在那里才被用到);模型谱系那一批名字根本不引入,§5 用一句「这门课一次都用不上」整体退回表格
0310「零样本」不要了(全章用不到);「Completion」不当第二张脸,统一叫「回答」
0413「点积 / 欧几里得距离」不要了,只留余弦一个量法;「最大边际相关性」的名字挪到 06 §5
0811(记忆 + 上线)拆章:记忆 08、上线 09
1312(两个项目)拆章:知识库助手 12、天机 13

三、每章的主走查(一章一条,另起最多两处)

主走查(一个具体输入,从头走到尾)另起
01「什么是南瓜书?」——§1 拿到编造答案 → §3 被塞进模板 → §6 在八步图上定位0
02两条英文消息 → Hello! How can I assist you today?,19 / 9 / 28 词元,0.000023 美元1(温度 0 与 0.95 的两份论文选题)
03太阳能发电站那道算错的题:模型点头 → 加一句「先自己解一遍」→ 它算出 360x2(分隔符那一组、三篇不存在的论文)
04同一句话送给三家:1536 / 384 / 1024 个数,12 个词元1(跑分表)
05南瓜书 PDF:196 页 → 清洗一页 → 720 块 / 308931 字符 / 平均 429 字0
0620 块进库 → 问一句 → 取回 3 块 → 换 MMR 再取一次,第 2、3 块换了1(自定义向量接口)
07「什么是南瓜书?」走完整条链 → 「抱歉,我不知道南瓜书是什么。谢谢你的提问!」1(不接知识库时它编的那段南瓜种植书)
08两轮对话:「我可以学习到关于提示工程的知识吗?」→「为什么这门课需要教这方面的知识?」0
09streamlit run streamlit_app.py 到浏览器里出现输入框,再加 st.session_state0
10四版提示词 v1 → v4,每版一个具体问题、一份具体回答2(拼碎片式幻觉那次、指令解析那次)
11「应该如何使用南瓜书?」串起人工七维(1/0.8/1/0.8/0.7/0.6/0.5)与裁判模型(1/0.9/0.9/0.9/0.9/0.9/0.8)2(客观题、BLEU)
12datawhalechina 某个仓库的 README → 删网址与审核词 → 200 字摘要 → 只有摘要进库 → 提问命中0
13「如何给长辈敬酒?」四条路各怎么答1(哄哄模拟器)

总纲 index.md

七节:30 秒导读 → 这是谁在什么时候写的 → 全书一条主线 → 章节地图(含最短路径)→ 覆盖什么 / 不覆盖什么 → 我们的判断 → 许诺兑现表。


01 这门课要造的到底是什么

进来时以为 → 出去时知道
1以为它答不上来会说「不知道」→ 知道它只是在续写,所以答不上来时会编一段像样的(走查起点:南瓜种植的书)
2以为治它只有「再训练一遍」一条路 → 知道还有一条便宜得多的:把资料塞进问题里,并知道两条路各自的代价
3以为「塞进问题里」是句比喻 → 看到那段话真正的样子:一个通用模型 + 一段留了两个空的模板(走查中段)
4以为这条路一直存在 → 知道它是模型大到某个规模之后才成立的,以及「基座模型」这个说法为什么是个转折
5以为要先学懂模型内部才能动手 → 知道这门课整章讲的模型谱系与内部改进,后面一次都用不上,以及为什么
6以为「做一个 AI 应用」是一件事 → 能把它拆成八步,并指出这句提问此刻停在第几格(走查终点)
7以为这本书是一本完整的书 → 知道它分三部分、第二部分至今只有目录,以及书里的清单停在什么时候

02 调一次模型:请求、回答、账单

进来时以为 → 出去时知道
1以为调模型要先装环境、配显卡 → 知道它就是一次网络请求,三行代码(走查第 1 步)
2以为发过去的是一句话 → 知道发过去的是一个列表,里面的每条都有身份,身份不同待遇不同(走查第 2 步)
3以为回来的是一段文字 → 知道回来的是一个对象,里面除了正文还有一张账单,并能自己把这次调用的钱算出来(走查第 3 步)
4以为模型的输出是固定的 → 知道有一个旋钮管它保守还是发散,并见到同一个问题在两个刻度下的两份回答(另起)
5以为每次调用都要写这么多 → 知道可以把细节包成一个函数,以及包掉之后丢了什么
6以为换一家模型就是改个模型名 → 知道有三处会绊倒你,并知道各是什么
7以为照书填参数就能跑 → 知道书里的价目和额度已经过期,以及密钥该放哪儿

03 把话说对:两条原则和它们治不了的一样

进来时以为 → 出去时知道
1以为它会检查算式 → 看到它对一道算错的题说「正确」(走查起点)
2以为它是算错了 → 知道它根本没算,它在顺着学生那份解法往下续写
3以为让它算得先教它数学 → 知道只要在提问里给它一个「先自己解一遍」的位置,它就抓出来了(走查终点:360x)
4以为把需求写短一点它更容易懂 → 知道另一条原则是把话说清楚,并见到不加一道墙时用户能怎么把你的指令顶掉(另起一)
5以为「说清楚」只有一种做法 → 拿到三个具体技巧(要格式、要它先验条件、给它两个例子),并知道最后那个的名字出门会撞见
6以为提示词写好了它就不编了 → 知道提示词管的是怎么问,管不了它肚子里没有(另起二:三篇不存在的论文)
7以为书里这一章可以照抄 → 知道有两处口径要当心:一个名字写错了,一处归类是我们对上的、不是书说的

04 把一句话变成一串数

进来时以为 → 出去时知道
1以为搜资料就是按关键词找 → 知道按关键词找会漏掉说法不同、意思相同的那些
2以为「变成数」是个比喻 → 看到一句话真的变成了 1536 个小数(走查第 1 步)
3以为这串数是随便编的 → 知道它被安排成「意思近的挨得近」,并知道拿什么量「挨得近」
4以为向量模型可以随便换 → 看到同一句话在三家分别是 1536 / 384 / 1024 个数,并知道建库和提问必须用同一个(走查第 2、3 步)
5以为这些数用普通数据库存就行 → 知道有一类专门存它的库,以及它凭什么比一条条比对快
6以为跑分高的就该选 → 知道该看的是两个不同的分,并发现书里那张表有一行印反了(另起)
7以为四家都能用 → 知道其中一家当时还没开放,以及书里那份维度数据出自另一张表

05 从一份文件到一堆块

进来时以为 → 出去时知道
1以为读 PDF 就是读出一大段文字 → 知道读出来的是一页一个对象,一共 196 个(走查第 1 步)
2以为一个对象里只有正文 → 知道还别着一张卡片,上面记着它从哪来、第几页
3以为提取出来的文字直接能用 → 见到它有多脏,以及三步各删掉了什么(走查第 2 步)
4以为整份资料一起丢给模型最省事 → 知道两个必须切碎的理由,一个是装不下,一个是检索以块为单位
5以为切就是按长度剪断 → 知道要给两个数,并知道那个重叠是干什么用的(走查第 3 步)
6不知道切完是什么规模 → 拿到三个数:720 块、308931 个字符、平均 429 字(走查终点)
7以为切法是个细节 → 知道书自己说它决定检索系统的下限,并知道书里两处切分参数是打架的

06 建库、落盘、取回来

进来时以为 → 出去时知道
1以为建库要先设计表结构 → 知道一行代码就建好了,并知道它必须落盘、下次按路径打开(走查第 1 步)
2以为书为了省事才只放 20 块 → 知道全库要调 720 次接口,以及这笔钱和时间大概是多少
3以为框架内置了所有向量模型 → 知道没内置的那家要自己接,补三个方法(另起)
4以为取回来靠的是关键词匹配 → 看到它按余弦距离排序、取回前 3 块,并看清这 3 块分别是什么(走查第 2 步)
5以为取最像的几块就够了 → 知道最像的几块往往互相重复,以及第二种取法怎么换掉其中两块(走查第 3 步)
6以为按意思找就能取代按词找 → 知道两路合起来用是有名字的一种做法,并知道那个名字
7以为「取回来的最像」等于「取回来的是答案」→ 知道向量模型学的是配对不是因果,以及这个坑长什么样
8以为库建好了就能问事了 → 知道这个 20 块的库答不出南瓜书,并知道这笔账留给下一章还

07 串成一条链:检索问答

进来时以为 → 出去时知道
1以为取回块之后还要自己拼字符串 → 知道框架把「取块 + 填模板 + 问模型」包成了一条链,由三样东西组成
2以为框架支持所有模型 → 知道没支持的那家要自己接,继承一个基类、实现两样东西
3以为提示词模板就是一段固定的话 → 看到它留着两个空,并知道谁来填
4以为建链要写一堆胶水 → 知道四个参数就够,并知道每个参数管什么(走查第 1 步)
5以为链跑通了答案就对了 → 看到它答「抱歉,我不知道南瓜书是什么」,并知道错不在链(走查终点)
6以为「不知道」是个失败 → 对照不接知识库那次它编的南瓜种植书,知道两种错哪一种更值钱(另起)
7以为答案里的出处要自己想办法 → 知道有一个参数能把用到的原文块连同来源路径和页码一起还给你
8以为书里的写法照抄就行 → 知道书这一章跑出来满屏弃用警告,以及那条竖线写法是什么

08 让它记得上一句

进来时以为 → 出去时知道
1以为对话是连续的 → 知道每一次调用都是从零开始,它不记得你上一句(走查起点)
2以为「不记得」是个 bug → 知道它是第 02 章那个列表的直接后果:没写进列表的东西根本不存在
3以为要让它记住得改模型 → 知道办法朴素得出奇:把之前说过的原样再发一遍,框架有个现成的盒子
4以为把历史塞回去就完事了 → 知道还差一步:代词指不到,得先把历史和新问题合成一个完整查询再去检索(走查第 2 轮)
5以为历史可以无限攒 → 知道它按字收钱、还会被截断,并拿到四种攒法
6以为书里的结论可以照抄 → 知道书在这一节抄错了一句,并知道错在哪

09 让别人也能打开它

进来时以为 → 出去时知道
1以为做界面要先学网页那三样 → 知道有一种库让你只写 Python,并知道它的代价
2以为要写事件绑定 → 看到一个输入框、一个按钮、一次回答是怎么用五行写出来的(走查第 1 步)
3以为变量会一直在那儿 → 知道每次交互它把整个脚本从头跑一遍,所以对话历史会消失
4以为得自己搭个数据库存历史 → 知道有一个专门活下来的盒子,并看到加上它之后的效果(走查第 2 步)
5以为前面几章的代码要重写一遍 → 知道它们被包成三个函数,页面上给三挡单选
6以为上线要买服务器 → 知道推两个文件就够,并知道是哪两个
7以为这就算做完了 → 拿到书自己列的四个优化方向,以及一个书没说的隐患

10 一个坏例子,改一次提示词

进来时以为 → 出去时知道
1以为要先攒一批测试用例 → 知道先拿一到三个例子把提示词调通,收坏例子是之后的事
2以为回答对了就算过 → 看到 v1 的回答对但太简略,并看到加一句话之后 v2 变成什么样(走查第 1、2 步)
3以为「越详细越好」→ 看到详细带来的新毛病:没有重点;v3 加一句「有几点就分点标号」(走查第 3 步)
4以为回答里说了什么就是知识库里有什么 → 知道可以要求它附上来源原文,并知道这么做的代价(走查第 4 步)
5以为接了知识库它就不编了 → 见到一种更难发现的编法:拿库里的碎片拼出一段没人说过的话(另起一)
6以为这种幻觉只能靠人眼抓 → 知道可以把提示词拆成两步,第二步让它自己回头查一遍
7以为用户提的格式要求它会照做 → 知道要求被模板吃掉了,并知道前面加一层解析怎么救(另起二)
8以为改提示词是纯赚的 → 知道每改一版都要把之前对的重跑一遍,而这个次数长得很快

11 五种打分办法

进来时以为 → 出去时知道
1以为坏例子改完就完了 → 知道坏例子会攒成一个验证集,到某个体量就必须有一个数来代表整体
2以为打分就是「好 / 不好」→ 知道要量化、要多维,并见到七个维度在同一个回答上的七个分(走查第 1 步)
3以为主观题没法自动判 → 知道可以把它改造成选择题,并知道打分策略里那个 -1 分是为什么加的(另起一)
4以为算相似度更客观 → 看到两个答案的分都是 1e-231,并知道那段代码错在哪(另起二)
5以为自动评分只能这两条路 → 知道还能让另一个更强的模型来当裁判,并看到它给的七个分(走查第 2 步)
6以为要在几种办法里挑一种 → 知道该按维度分派,并拿到书给的那张分派表
7以为评估只评回答 → 知道还得单独评检索那一半,并能写出那个准确率的口径
8以为检索不准只有一个原因 → 拿到四类归因和各自的治法,并知道其中一类正是第 05 章埋的账
9以为书把这一块讲完了 → 知道它把另一半推给了搜索领域,并知道书许诺的第二部分到底列了哪些东西

12 项目一:个人知识库助手

进来时以为 → 出去时知道
1以为这只是把前面几章拼起来 → 拿到它的五层分工图,并知道每一层管什么
2以为知识库的资料是人手工整理的 → 知道它是爬来的:一个组织下所有仓库的说明文件(走查第 1 步)
3以为爬下来就能进库 → 知道要先删两样东西,再让模型把每份压成 200 字以内(走查第 2、3 步)
4以为进库和第 06 章一样 → 知道这里换了参数、换了向量模型,并知道换成本地模型意味着什么(走查第 4 步)
5以为问答链就是第 07 章那一条 → 知道项目把它写成了两个类,并知道多出来的那几个开关是什么(走查第 5 步)
6以为跑起来要部署 → 知道它给了两种服务方式,以及各自的一条命令
7以为项目代码就是书里的定稿 → 知道它的版本号、未来规划,以及它和第 05 章那组切分参数不一致

13 项目二:天机

进来时以为 → 出去时知道
1以为大模型只能答知识问题 → 知道有人拿它做人情世故,并知道这类问题为什么没有标准答案
2以为做这件事得训练一个模型 → 知道最省的一条路只用一段写好的话,并知道那段话有四个部件(走查第 1 步)
3以为角色扮演只能一问一答 → 见到同一条路做成游戏之后长什么样:一个从 20 涨到 60 的数(另起)
4以为知识库那条路和第 06 章一样 → 知道它换了本地向量模型、块大到 3000 字,并知道为什么(走查第 2 步)
5以为剩下两条路是更高级的同一件事 → 知道它们一个改的是流程、一个改的是模型本身(走查第 3、4 步)
6以为四条路可以随便挑 → 拿到成本对照,并知道哪一格是书自己空着的
7以为这一章的数都来自书 → 知道有三个数是别处的、是推断的、或者书根本没给