第一讲 · 讲义
DeltaMed Solutions, Inc. — Empowering Excellence & Enabling Quality
内部培训 · 第一讲讲义

它是什么

这一讲要回答的不是「AI 能干什么」,而是「它到底在干什么」。先补上术语底座——命令行、Python、库与框架、API——再拆开模型的机制、边界和沟通方式。讲完这一讲,后面两讲提到的每一个词,在座的人都应该知道它指什么。

板块
4 个 · 含技术底座
时长
约 165 分钟
前置要求
无 · 不假设编程经验
演示
13 个可交互 demo

页内演示的三种标签

真实运行这段逻辑真的在你的浏览器里跑:正则匹配、JSON.parse、文本切块、概率归一化。你改输入,结果就跟着变,没有预先写好的答案。
模拟沙盘行为是照真实工具复刻的,但输出是我事先写好的。终端、代码执行过程属于这一类——机制可靠,但它不是一台真的机器。
示意数值数字是为了讲清道理编的,不是实测值。概率分布、注意力衰减曲线属于这一类。看这类演示时,请把它当示意图,不要当基准测试。

所有演示都能用键盘操作。整页可直接打印,打印时按钮会自动隐藏。

开场

先把预期校准

5 min

这门课不教「怎么让 AI 写周报」。三讲的目标是让一间会议室里的人用同一套词说话:当有人说「这个上下文塞不进去」「这一步要不要人在环」「这个 Agent 会不会绕圈」,所有人指的是同一件事。第一讲负责铺词。

Q1–3先自答

先回答三个问题

先记下你自己的答案,第三讲结束时回来对一遍

  1. 你用过 AI 工具吗?用来干什么、有没有哪次结果让你不敢用了。
  2. 你打开过命令行吗?不是问会不会用,是问见过没见过那个黑框。
  3. 你觉得它错的时候,是「不会」还是「胡说」?先记下你的直觉,板块 1.4 会给出答案。
板块 0 · 前置

技术底座

32 min

这个板块不是为了让谁学会编程,是为了拆掉五个会一直挡路的词:命令行、Python、库与框架、API、Git。后面两讲每一次提到「终端型 Agent」「装个库」「调 API」「它自己开了个 PR」,都要用到这五个词。不讲这一块,第三讲会有一半人在猜。

0.18 min

命令行:同一台电脑的另一个门

不是黑客的东西,是没有图形界面时的正常操作方式

图形界面和命令行不是「简单版」和「高级版」,是同一台电脑的两个门。双击文件夹图标和敲 cd study-DM001 干的是同一件事:把「我现在在哪个目录」这个状态改掉。差别只有一个——图形界面用,命令行用

为什么非要有个用「说」的门?因为说出来的话可以被记下来、重放、串起来、让别人检查。指的动作不行。你没法把「鼠标移到这儿、双击、再拖到那儿」存成文件明年再跑一遍,但你能把三十行命令存成一个脚本。这就是自动化的全部秘密,也是为什么所有能自己干活的工具最后都长出一个命令行。

同一个任务:把 ae.csv 里 3 级以上的不良事件挑出来存成新文件 图形界面 打开表格 点筛选 选条件 另存为 下个月再来一遍? 重新点四次 命令行 python filter_ae.py raw/ae.csv --sev 3 -o out/ae3.csv 存成文件 明年原样重放 同一行字 → 可审计 · 可版本控制 · 可交给 Agent 执行
命令行的价值不在快,在于它是文字。文字能存档、能被复核、能写进 SOP,也能被一个 Agent 读懂并执行——第三讲的「终端型 Coding Agent」就是坐在这个门后面工作的。
Demo A摸一次命令行模拟沙盘

下面是一个假的、跑在这个网页里的终端,装了一个假的项目目录。点按钮或者直接在里面打字,回车执行。删不坏任何东西——这里没有真的文件。先照顺序点一遍上面那排按钮。

照着点
bash — analyst@deltamed
analyst@deltamed:~$

支持 pwd ls ls -l cd cat head wc -l python pip install help clear。↑ ↓ 可以翻历史命令。

analyst当前用户。权限跟着这个身份走。
@deltamed机器名。远程连到服务器时,这里会变,是你判断「我在哪台机器上」的唯一提示。
:~/study-DM001当前目录~ 是你的主目录。所有相对路径都从这里算。
$「说完了,该你了」。$ 是普通用户,# 是 root——看到 # 就该谨慎。
要带走的三件事 一、命令有形状。命令 选项 参数——wc 是命令,-l 是选项(改行为),raw/ae.csv 是参数(作用对象)。看不懂一条命令时,先按这三段切开。
二、「当前目录」是个状态。同一条 ls 在不同目录给不同结果。所有「怎么在我这儿跑不出来」的问题,一半是这个状态不一样。
三、报错是信息,不是斥责。点一下 lss——command not found 的意思很具体:这个词我不认识。它已经把问题精确指到了哪一个字上。命令行的报错几乎都是这种风格,读懂它比记住命令重要。
和我们的关系

第三讲会讲「终端型 Coding Agent」。它的能力边界就是这个黑框的能力边界:你在命令行能做的,它能做;你做不了的,它也做不了;而你能在这里删掉的东西,它同样能删掉。这句话是后面讨论「人在环」和「设卡」时的物理基础。

0.29 min

Python:一门和 SAS 分工不同的语言

不学语法,只建立「一个脚本是怎么跑起来的」这个直觉

先把关系摆正:Python 不是「更好的 SAS」,它是一门通用语言。SAS 是为「表格数据 + 统计过程」这一件事造的,所以它在这件事上顺手得不像话——proc freq 一行就出频数表。Python 什么都能干,代价是什么都得自己拼,或者装个库来拼。

三个必须记住的机制差别:

  • SAS 的数据步自带循环,Python 的循环要写出来。data / set / run 这三行背后有一个「逐行读、逐行处理」的引擎,你只写规则。Python 里那个 for 得自己敲——这是初看 Python 代码觉得啰嗦的主要原因。
  • SAS 的能力在内置的 PROC 里,Python 的能力在第三方库里。SAS 装好就有几百个过程;Python 装好只有一个很小的内核,pandasnumpy 全是外面的人写的、要自己装。这是两个世界最大的心智落差,0.3 专门讲。
  • 缩进是语法。SAS 里空格随便打,Python 里缩进决定了「哪几行属于这个 if」。缩进错了就是逻辑错,而且经常不报错。

还有个更基础的问题:一个脚本到底怎么「跑起来」?check_ae.py 只是个文本文件,本身什么都不会发生。是你在命令行敲 python check_ae.py,启动了叫 Python 解释器的那个程序,让它从上到下,一行一行读这个文件并照做。SAS 里对应的是提交代码给 SAS 引擎、然后看 log——一样的道理。

Demo B一行一行看它怎么跑模拟沙盘

这是一个真能用的脚本:从 raw/ae.csv 里挑出 3 级及以上的不良事件,按受试者计数。点「下一步」,左边看它现在停在哪行,右边看变量的值怎么变。这是理解「程序」这个词最快的路径——它就是一个不断改写变量的过程。

第 0 / 24 步
check_ae.py等待开始
变量此刻的值
终端输出 stdout
点「下一步」开始。看右边——每一步真正变的东西都会高亮。
这个演示要说明的事 程序没有魔法,只有顺序和状态。它从第一行走到最后一行,一路改一堆变量的值,偶然往屏幕上写点东西。你看不懂一段代码的时候,就按这个演示的方式一行一行走——这是唯一可靠的办法,专业程序员调试时干的也是这件事(那个工具叫调试器 debugger)。
顺手记住第 6 行那个坑:int(row["AESEV"])。CSV 文件里没有类型,读进来的 "3"文字不是数字,不转换就比不出大小。SAS 的 proc import 会替你猜类型(有时猜错),Python 里这一步要你自己表态。
Demo C同一个任务,三种写法模拟沙盘

任务完全一样:读 ae.csv,筛 AESEV >= 3,按受试者出频数。切换标签,对着看。重点不是哪个好,是各自把哪部分工作交给了谁

代码

proc import datafile="raw/ae.csv"
  out=ae dbms=csv replace;
run;

data ae3;
  set ae;
  if AESEV >= 3;
run;

proc freq data=ae3;
  tables USUBJID / nocum nopercent;
run;

谁在替你干活

  • 循环:不用写。set 背后就是逐行读。
  • 类型proc import 替你猜。方便,也是最常见的隐患来源。
  • 统计proc freq 内置,带完整的输出表和 ODS。
  • 日志:log 是一等产物,自动记录每步读了多少行。
  • 代价:出了 SAS 生态就什么都没有——没法调 HTTP 接口,没法接大模型。
0.37 min

库、框架、环境:为什么「在我这儿能跑」

时间紧时可以自学;但第三讲讲 Coding Agent 之前必须补上

一句话分清库和框架:库是你调它,框架是它调你。

  • 库(library):一堆现成的函数,你想用哪个就调哪个,主动权在你手上。pandas 读表、requests 发网络请求。约等于 SAS 里一套别人写好的宏。
  • 框架(framework):它把整个流程的骨架定好了,留出一些位置让你填。程序的运行由框架发起,你的代码只是被它在合适的时候叫起来。第二讲会提到的 LLM 应用框架就是这类东西。它省掉的是搭骨架的功夫,换来的是必须按它的规矩写。
用「库」:控制流从你出发 你的代码 决定顺序 read_csv() pandas 你随时可以不调它, 换成别的库或自己写。 用「框架」:控制流从它出发 框架 决定顺序 叫你 你的代码 想换框架,等于重写 ——这就是「锁定」。
箭头方向就是全部区别。这个方向决定了替换成本:换库容易,换框架难。选型时值得为此多想一会儿——第三讲评估工具时会用到这个判断。

接下来是最实际的一件事:库要装。装库的工具叫 pip,敲 pip install pandas,它去一个叫 PyPI 的公共仓库把包下载下来。这里埋着两个我们躲不开的问题。

Demo D「在我机器上能跑」的真正原因模拟沙盘

两个项目:DM001 号研究的老脚本需要 pandas 1.5DM002 号研究的新脚本需要 pandas 2.2。先在「全局环境」模式下,按顺序装两个版本、再分别跑一下,看会发生什么。然后切到「虚拟环境」模式重来一遍。

模式
操作
bash — 全局环境

全局环境 一台机器一份库

python3
 └─ site-packages/
     └─ (空)

装第二个版本时,第一个被覆盖掉了,而且没有任何警告。老脚本从此坏掉,坏的时间点和你改动的地方毫无关系——这是最难查的一类故障。

虚拟环境 一个项目一份库

study-DM001/.venv/  → (空)
study-DM002/.venv/  → (空)

每个项目自带一份独立的库目录,互不影响。python -m venv .venv 一行创建。这是行业默认做法,不是高级技巧。

对受监管环境的意义 依赖就是供应链。一个 Python 脚本的行为不只取决于你写的那几十行,还取决于它调用的那几十个库的具体版本。所以在我们这行,光存代码是不够的——必须把依赖清单和版本号一起冻结、一起归档(那份清单通常就叫 requirements.txt,每行写死一个版本,比如 pandas==1.5.3)。
做不到这一点,「三年后能不能重现这次分析」就是一个没有答案的问题。SAS 世界里这个问题被 SAS 版本号一并解决了,Python 世界里要你自己负责。第三讲讨论验证与留痕时,这是绕不过去的一条。
0.46 min

API 与 JSON:机器之间怎么说话

这一节是板块 0 里最该讲的——后面两讲全靠它

API 是一台机器留给另一台机器用的表单。它规定了三件事:往哪个地址发、表单上有哪些格子、填对了会回你什么。人用网页,机器用 API,背后往往是同一套系统。

那张表单用 JSON 这种格式写。JSON 只有两种结构,看一眼就够:{} 是「键值对」(像一行观测,字段名 → 值),[] 是「列表」(像一叠行)。整个 AI 应用领域的数据都长这个样子,包括第二讲的工具调用、第三讲的 Agent 消息记录。板块 3.3 还会讲怎么让模型直接吐 JSON。

对应到我们熟悉的东西

一份 define.xml 描述了数据集里有哪些变量、什么类型、取值范围——API 文档干的是同一件事,只是描述对象从数据集变成了接口。而 JSON 相当于 XML 的一个更省事的表亲。

Demo E解剖一次真实的模型调用模拟沙盘

下面是调用 Claude 时真正在网络上传输的东西——左边是发出去的,右边是回来的。点任何一个带下划线的字段,下面会解释它是什么、为什么在这儿。这一屏是第二讲和第三讲的地基:所谓「接了大模型」,指的就是有程序在替你反复发这个请求。

→ 请求 REQUEST

: sk-ant-••••••••••••
: 2023-06-01
content-type: application/json

{
  "": "claude-opus-5",
  "": 2048,
  "": "你是临床数据审阅助手。只依据提供的数据回答,无法确定时明确说无法确定。",
  "": [
    {
      "": "user",
      "": "以下是 3 条 AE 记录……01-001-0042 有几条 3 级事件?"
    }
  ],
  "": { "effort": "medium" },
  "": { "type": "adaptive" }
}
← 响应 RESPONSE
{
  "id": "msg_01Ab2Cd3Ef4Gh5",
  "type": "message",
  "role": "assistant",
  "model": "claude-opus-5",
  "": [
    {
      "type": "text",
      "text": "01-001-0042 有 2 条 3 级事件:\n中性粒细胞减少(2026-03-14)、\n发热(2026-03-21)。"
    }
  ],
  "": "end_turn",
  "": {
    "input_tokens": 1284,
    "output_tokens": 96,
    "cache_read_input_tokens": 0
  }
}
点上面任意一个下划线字段

先看整体形状:一次调用是无状态的。这个请求里没有「上一句话」,模型也不记得你刚问过什么。所谓「多轮对话」,是客户端每次都把之前所有轮次重新装进 messages 数组再发一遍。这一条解释了后面很多现象——为什么对话越长越贵、越长越慢,也为什么它会「忘」。

三个必须带走的结论 一、调用是无状态的,记忆是客户端伪造的。每一轮都把全部历史重发一次。这是板块 3 全部内容的物理前提。
二、usage 就是账单。input_tokens + output_tokens 决定这一次花多少钱。第三讲算成本时,算的就是这两个数字。
三、x-api-key 是钥匙,数据是从我们这边流出去的。请求体里那段 content 会离开公司网络。这是整个系列里最需要记住的一条边界——它是第三讲「数据边界」整节的起点,也是为什么受试者可识别信息不能进这个格子。
0.54 min

Git:为什么 Agent 都围着它转

时间紧时可以自学;只需要建立一个概念

Git 是版本控制工具。对这门课来说,只需要理解它提供的一样东西:一个可以随时回到的已知良好状态。

  • commit(提交):给当前所有文件拍一张快照,附一句说明。快照永远在,随时能回去。
  • branch(分支):从主线拉一条岔路做实验,做坏了整条丢掉,主线一点没动。
  • diff(差异):两个快照之间逐行的变化。这是审阅的单位。
  • PR(合并请求):「我改完了,请复核后并回主线」——一个带评论和批准的正式流程。

这四个词解释了第三讲的一个观察:所有严肃的 Coding Agent 都要求项目在 Git 里。原因很直白——它要改一堆文件,而你需要在它改坏的时候一键回退,还需要逐行看它到底改了什么。Git 是把「让 AI 改代码」从赌博变成可控操作的那件东西。

scripts/check_ae.pyAgent 提交 · +3 −1
@@ -4,7 +4,9 @@
 counts = {}
 with open("raw/ae.csv") as f:
     for row in csv.DictReader(f):
-        if int(row["AESEV"]) >= 3:
+        sev = row["AESEV"].strip()
+        if not sev.isdigit():
+            continue
+        if int(sev) >= 3:
             sid = row["USUBJID"]

上面是一个 Agent 真实会产出的那种改动:它发现 AESEV 有空值时原来的 int() 会崩,于是加了防护。这就是你要审的东西——四行,一眼能看完,判断得出对不对。

这里已经能看出第三讲的核心矛盾

上面这个改动技术上对,业务上未必对。空的 AESEVcontinue 悄悄跳过了——脚本不崩了,但那条记录从统计里消失了,而且没有任何提示。在我们这行,「静默丢数据」比「程序报错」严重得多。

这就是为什么「它跑通了」永远不等于「它做对了」。四行改动尚且如此,四百行改动会怎样,值得在这里停下来想三秒钟。

板块 1

大模型的运作机制

40 min

这个板块要同时拆掉两样东西:神秘感,和不切实际的期待。讲完之后,「它为什么会一本正经地编」「为什么对话长了就变笨」「为什么算数会错」这几个问题,应该都变成能推导出来的结论,而不是需要背的现象。

1.114 min

它只做一件事:猜下一个 token

全课程最重要的一节。后面所有结论都从这一句推出来

大模型的全部工作是:读入一段文字,输出「下一个 token 该是什么」的一张概率表。就这样。没有理解、没有意图、没有查询数据库。它反复做这一件事,一次一个 token,把自己刚吐出来的接回输入,再猜下一个。

先解决那个词:token 不是「字」也不是「词」,是模型的最小切分单位。它是拿海量文本统计出来的——常见的片段占一个位置,不常见的被拆开。模型眼里的世界就是一串 token 编号,它从来没见过「字母」这个东西。这一条比听起来重要,先摸一下。

Demo 1模型眼里的文字长什么样真实运行

在框里打任何字,下面实时切成 token。先按顺序点前两个预设——同一句话的中文和英文版,比一下 token 数。

预设
token 数0
字符数0
字符 / token0
发 1000 次的输入费$0

这是一个近似分词器:它复刻了真实分词器的三个规律(中文约一字一 token、英文约四字符一 token、数字和标识符被切碎),但具体边界和真实的 tokenizer 不完全一致。要精确数,用官方的 count_tokens 接口。

从这四个预设里能直接读出的结论 一、中文更贵。同样一句话,中文字符数只有英文的三分之一,但 token 数基本持平甚至更多——按 token 计费时,中文单位信息的成本明显高于英文。写系统提示词时这笔账是真的。
二、USUBJID 在模型眼里不是一个整体,是两三个碎片。所以它偶尔会把变量名拼错成一个「看起来很像」的东西——因为在它的世界里,这些碎片本来就是可以重新组合的。
三、这就是它算数不可靠的物理原因。看第四个预设:1234567890 被切成了几段。模型看不到「这是一个整数」,它看到的是几个碎片的排列。让它算数,等于让人只凭「这几个字块常一起出现」来做加法。算数要交给工具——这是第二讲工具调用的第一个理由。

知道了输入是什么,再看那个循环。这是全课程最该记住的一张图:

全部文本 系统提示 + 对话 + 已生成 的每一个 token 一次前向计算 读进去的每个 token 都参与这一次计算 一张概率表 词表里每一个 token 各占多少概率 采样 抽一个出来 把抽到的 token 追加到文本末尾 这个循环解释了三件事: ① 输出是一个 token 一个 token 出来的 → 所以有「打字机效果」,也所以输出越长越慢、越贵。 ② 每生成一个 token,前面所有 token 都要重算一遍 → 所以上下文越长,每个字都更慢更贵。 ③ 一旦抽错一个 token,它会被当成既定事实接着往下写 → 错误会被自己顺下去,而不是被纠正。
第 ③ 条是「幻觉」的机制起点。模型没有「回头看看刚才那句对不对」这一步——已经写出来的东西对它而言就是上下文,是前提。1.4 会回到这里。
Demo 2亲手采样:一次一个 token示意数值

开头已经给定。每点一次「生成下一个」,就走一遍上面那张图的一整圈。先用默认温度点到句子结束,然后把温度拉到 0 重来一遍,再拉到 1.6 重来一遍——注意句子怎么变。也可以直接点概率条自己选一个 token。

温度 temperature
1.00

读懂这个演示 温度不改变模型的知识,只改变它敢不敢选第二名。温度 0 时永远取概率最高的那个(贪心解码),所以同一个问题总得到同一句话,但也永远走不出那条最平庸的路。温度高时低概率的选项被放大,句子更有变化,也更容易拐进胡说。数学上就是把每个概率取 1/T 次幂再归一化——这个演示里算的就是这个式子,你拉滑块时那些百分比是真的在重算。
「同一个问题两次答案不一样」在这里就有了完整解释,它不是 bug,是采样。
一条要留意的现状:在当前这一代 Claude 模型(Opus 5、Sonnet 5 等)上,API 已经不再接受 temperature 参数了——传了会直接报错。控制深浅的旋钮换成了 output_config.effortlowmax)。温度作为原理依然要理解(所有采样式生成都是这么工作的),但作为参数已经不是你该去调的东西了。这类「原理长期有效、参数半年就变」的落差,在这个领域里是常态——记原理,别记参数。
最容易出现的误解

「它是不是在数据库里查了一下?」没有。整个过程里没有任何查询——只有一次矩阵计算和一次抽样。它「知道」的东西全部压在参数里,是训练时把统计规律固化下来的结果,没有一条可以指着说「这条知识存在这里」

这也就是为什么你没法让它「改掉」某一条错误知识,只能在提问时把正确信息给它(板块 2、3 的全部内容),或者让它去外部查(第二讲的 RAG 和工具调用)。

1.29 min

从「补全机器」到「助手」:三段式训练

这一节解释为什么它会「听话」——以及听话是被训出来的,不是天生的

上一节那个循环只会补全文本。一个只会补全的模型,你问它问题,它不会回答,它会接着往下编更多问题。它变成一个「助手」,靠的是训练完之后的两道加工。

第一段预训练

拿海量文本反复做「猜下一个 token」。语言、常识、代码、逻辑的雏形都在这一步长出来,绝大部分能力来自这里

数据:几万亿 token 的公开文本
目标:把下一个 token 猜得更准
产物:一个博学但不听话的补全器
第二段指令微调 SFT

喂进大量「人问 → 好答案」的示范对,让它学会「被问了就该回答」这个格式。学的是行为模式,不是新知识。

数据:几万到几十万条人写的示范
目标:模仿示范的回答方式
产物:会答题了,但生硬、不知进退
第三段对齐 RLHF / RLAIF

让人(或另一个模型)对多个候选答案排序,再用这些偏好去调它。有用、诚实、无害这些性质是在这一步塑造的。

数据:大量「A 比 B 好」的偏好比较
目标:产出人更满意的回答
产物:会分点、会追问、会说「我不确定」
Demo 3同一个问题,三个阶段的三种反应示意数值

问题固定:「临床试验里的盲态是什么意思?」切换标签,看同一个模型在三个训练阶段会输出什么。第一个标签是重点——多数人从没见过纯预训练模型的反应,而那才是「猜下一个 token」的裸机行为。

纯预训练模型 · 它在补全一份文档
这个演示要打掉的两个错觉 一、「它想帮我」是个错觉。「有问必答、答完还问你要不要展开」是第三段训出来的行为习惯,不是它有服务意识。理解这一点,你就不会指望它在该拒绝的时候拒绝——除非那种情形也被训过。
二、「它变得更聪明了」也是个错觉。后两段几乎不增加知识,只改变表达方式和取舍偏好。所以指望「换一个更听话的模型」来解决「它不知道我们公司的 SOP」,方向就是错的——那要靠板块 2、3 把信息喂进去,或者靠第二讲的检索。
1.310 min

三个硬约束:token、上下文窗口、知识截止

这三条不是缺点,是物理边界。绕不过去,只能规划

  1. token 是计价单位,进出都算。输入的每个 token 和输出的每个 token 分别计费,输出通常贵好几倍。以 Claude Opus 5 为例:输入 $5 / 百万 token,输出 $25 / 百万 token。关键是 0.4 讲过的那件事——每一轮都把全部历史重发一遍,所以一段长对话的成本不是线性增长,是越聊越快地涨。
  2. 上下文窗口是一次能塞进去的 token 总量上限。Claude Opus 5 是 100 万 token,Haiku 4.5 是 20 万。但这个数字是「输入 + 输出」共享的,而且要给系统提示词、工具定义、对话历史都留位置。你真正能用来放文档的,远少于标称值。
  3. 知识截止日期是一条硬线。训练数据截止之后发生的事,它一概不知道——而且不知道自己不知道。任何涉及「最新版指南」「今年的法规」「上个月的会议决定」的问题,答案只能由你提供,不能问它。
Demo 4上下文预算:把窗口花在哪真实运行

下面所有数字都是真算的。先选一个模型,然后拖「附件文档」和「对话轮数」,看那条预算条什么时候撑爆。重点看右下角两个数字:这一轮花多少,和聊到现在累计花多少。

模型
附件文档
60 页
对话轮数
第 8 轮
已占用 / 窗口
还剩
这一轮费用
累计到本轮
四个非直觉的点 一、撑爆的时候 API 是报错,不是悄悄截断。那些「自动帮你截掉最早几轮」的行为是客户端软件做的,不是模型做的。所以同一段对话在不同工具里表现不同——有的报错,有的悄悄把开头丢了然后开始答非所问。
二、工具定义是白交的房租。挂上去的每个工具,它的名字、说明、参数结构每一轮都要完整重发一遍,哪怕这轮根本没用到。把开关关掉看那一段有多宽——这是第二讲「不要什么工具都挂上」的量化依据。
三、输出必须预留。那段绿色不是浪费,是给答案留的位置。留少了,它会在句子中间被硬切断(stop_reason 变成 max_tokens)。
四、累计费用是超线性的。把轮数从 8 拖到 60,看「这一轮」和「累计」的涨法完全不同——因为历史每轮重发。「长对话」在成本上是个陷阱,开新会话往往更省。
对我们最实际的一条

「窗口有 100 万 token,那我把整个研究的文档全塞进去不就行了?」——技术上塞得进,但会同时踩两个坑:一是每一轮都按这个量重新计费,成本会失控;二是塞得越满,找得越不准(板块 3.4 会用一张图说明这件事)。塞满不等于用好。该带的是相关的那几页,不是全部。

1.47 min

幻觉:自信和正确是两件不相干的事

回到开场第 3 题——答案是「都不是」

开场问过:它错的时候是「不会」还是「胡说」?正确答案是:这个区分在机制上不存在。它每一步都在做同一件事——从概率表里抽一个 token。表很尖的时候抽出来是对的,表很平的时候抽出来是编的,而这两种情况生成的句子在语气上完全一样

关键在于:那张概率表里没有「我不知道」这个选项占据高位。模型必须输出某个 token,它不能输出「空」。所以在它没有相关知识时,概率会摊薄到一堆格式正确、看起来合理的候选上——然后其中一个被抽中,被当作既定事实接着往下写。

Demo 5两张概率表,两种完全不同的处境示意数值

同一个模型,两个问题。切换看两张概率表的形状差别,然后看最下面那行「它实际会输出什么」。这个演示的全部意义在于:形状差别巨大,输出的语气毫无差别。

提问
最高概率
分布集中度
这个答案可信吗
为什么这件事这么难防 那个分布的形状,你在输出里看不到。模型不会说「我这次只有 14% 的把握」——它把最高的那个抽出来,然后用和情况 A 一模一样的流畅中文写出来。「语气有多确定」和「内容有多可靠」之间没有任何关系,这是它和人最不一样的地方,也是最危险的地方。
在我们这行还要加一层:它编出来的东西格式往往是对的。编一个变量名会符合 SDTM 命名习惯,编一个文献引用会有卷号页码,编一个法规条款号会长得像真的。格式正确恰恰是它最擅长的部分——所以「看起来很规范」在这里完全不能作为可信的证据。

能真正降低幻觉的四件事

没用大家常做但不管用的

  • 在提示词里写「不要编造」「请确保准确」——它本来就不觉得自己在编。
  • 追问「你确定吗?」——它通常会顺着你改口,这是对齐训出来的迎合,不是复核。
  • 让它自己打个置信分——那个分数同样是猜出来的 token。
  • 换更强的模型——能减少,但改变不了机制。

有用动机制的四件事

  • 把材料给它,别问它记不记得。答案在上下文里时,分布会变尖。这是板块 2、3 的全部主题。
  • 给它退路。明确写「材料里没有就回答『材料中未提及』」——把「不知道」变成一个合法且高概率的输出。这一条最便宜、最有效。
  • 要求逐条给出处。「每个结论后面注明来自第几页」——没法编出处的结论它就不容易写出来。
  • 让它去查,别让它回忆。接上真实数据源或工具(第二讲)。
一句可以直接写进规范的话

凡是「它应该知道」的问题,都改成「这里是材料,请只依据材料回答,材料里没有就说没有」。这一句改写,能消掉我们日常用法里的大部分幻觉风险,而且不需要任何工具、任何开发、任何预算。

板块 2

提示词与沟通

40 min

全课程投入产出比最高的一个板块:不需要开发、不需要预算、今天下午就能用上。核心只有一句话——提示词的工作不是「说得客气」,是把模型必须替你猜的东西一个个关掉。

2.114 min

提示词到底在做什么:关掉歧义

先讲原理,五要素只是原理的一个清单

回到 1.1:模型在算「下一个 token 的概率分布」。你的提示词是这张分布的唯一条件。提示词模糊,意味着有一大片彼此矛盾但都合理的续写共享概率——它抽中哪个都是偶然。提示词精确,意味着概率集中到你想要的那一片上。

所以「写好提示词」不是修辞问题,是信息问题:你每补一句话,就从模型的猜测清单上划掉一项。下面这个演示把这件事直接摊开。

Demo 6五个开关,九个歧义真实运行

原始请求就一句话:「帮我看一下这批 AE 数据有没有问题」。右边列着模型此刻必须替你猜的九件事。逐个打开左边的开关,看被划掉几条、提示词长成什么样。

五要素
你实际发出去的提示词
它还得替你猜的事 · 9 / 9
    这个演示的真正结论 「提示词写长一点」是错的说法,「把猜的地方堵上」才是对的说法。五个开关全开之后剩下的那一条,无论你怎么写都堵不上——因为它需要的是数据本身,不是措辞。那条就是板块 3 的入口:再好的提示词也补不上缺失的上下文。
    反过来说:如果你写了一大段客气话却没关掉任何一条,那段话除了多花 token 之外没有任何作用。「请你务必帮我认真仔细地检查一下」这种句子,关掉的歧义数是零。

    五要素:一张不用记的检查表

    要素它关掉的是写不写都行?
    角色「这话说给谁听、用什么专业深度」短任务可省。但跨专业沟通时必写——写给统计师看和写给项目经理看是两份东西。
    任务「到底要我干什么、干到什么程度」必写。而且要写成动词:「列出」「比对」「改写成」,不要写「看一下」「处理一下」。
    上下文「相关事实是什么」必写,而且是决定上限的那一项。板块 3 整节讲它。
    输出格式「长什么样、多长、什么语言」结果要进下游程序时必写,而且要写成可机读的(板块 3.3)。
    约束「不许做什么、遇到边界怎么办」最容易漏、也最值钱的一项。「材料里没有就说没有」属于这一项。
    2.29 min

    示例驱动:给两个例子胜过写五段说明

    最省力的一招,原因也在 1.1 那张概率表里

    为什么例子比说明有效?因为说明要模型先理解再翻译成行为,例子直接就是行为。你给它两条「输入 → 输出」的实例,它要做的只是把这个模式延续下去——而延续模式恰好是它唯一擅长的事。

    更准确的说法是:例子在收窄可能性,不是在增加信息。下面这个演示把这个过程画出来。

    Demo 7例子在做的事:把可能性掐掉示意数值

    任务:「把研究者手写的不良事件描述整理成标准条目」。下面六种输出全都符合这句指令——这就是问题所在。拖动示例数量,看哪些形态被掐掉。

    给几个示例
    0 个
    你发出去的提示词
    它可能给你的形态 · 6 种都可能
    实操要点 一、两个例子是性价比拐点。一个例子只钉住「大概长这样」,两个例子才钉住「变的是哪部分、不变的是哪部分」。三个以上收益迅速衰减,除非你在处理边界情况。
    二、把边界情况放进例子里,比用文字描述它有效得多。与其写「如果日期缺失请留空」,不如直接给一条日期缺失的示例,输出里那一格就是空的。这一条对我们特别有用——临床数据里缺失值、部分日期、单位不统一才是常态。
    三、例子里的错误会被忠实地学走。你的示例里格式打错一个字符,它会一路照错下去。示例是要审的东西,不是随手写的。
    2.37 min

    让它「多想一会儿」:什么时候值这个钱

    这一节的参数细节半年就会变,判断标准不会变

    所谓推理模型(或者「思考模式」),做的事很朴素:在给出答案之前,先生成一段推导过程。那段推导也是 token,一样计费、一样占窗口,只是通常不展示给你看。

    为什么这会有效?回到 1.1 的第 ③ 条——模型没有回头修正的机制,已经写出来的就是前提。所以如果它一上来就要报答案,那个答案是「一步蒙出来的」。让它先把中间步骤写出来,每一步都成为下一步的上下文,等于给了它一张草稿纸。

    一个判断标准,比任何参数表都好用

    这道题你自己做,需不需要打草稿?

    需要打草稿的(多步推导、要回溯、有明确对错)→ 开深一点,值。
    不需要打草稿的(查找、抽取、改写、翻译、格式转换、分类)→ 开了纯浪费钱和时间,而且有时更差:它会给一个简单任务硬编出一套推理,然后被自己那套推理带偏。

    我们的日常任务要不要让它多想为什么
    从 CRF 里抽字段填映射表不要是查找和搬运,没有推理链。多想只会增加编造的机会。
    把一段 SAS 改写成等价 Python要逐句对照语义、处理缺失值差异,是多步推导。
    润色一段病历叙述不要改写任务。想多了会自己加内容——在我们这行这叫编造。
    核对派生变量的逻辑是否自相矛盾典型的约束满足问题,需要来回验算。
    按规范判断一批记录合不合规规则多、有例外、要逐条比对。
    把一份清单翻译成英文不要逐项映射,没有需要权衡的地方。
    现状速记 · 这一段会过时

    过去几年这件事的做法一直在变,现在(2026 年 9 月)在 Claude 这一代上是这样:思考默认是开着的、自适应的thinking: {type: "adaptive"}),你不再指定「思考多少 token」,而是用一个叫 effort 的档位控制深浅——low / medium / high / xhigh / max。同时,1.1 提过的 temperature 在这一代上已经被移除了。

    这些参数名不必记,只需要记住一件事:「深浅」现在是一个可调的旋钮,调它要花钱,所以该按任务性质选,不是一律开到最大。具体参数叫什么、有几档,要动手时去看当时的官方文档。

    2.410 min

    四种失效:每一种都有固定改法

    四组前后对照,可以直接照着改自己的提示词

    失效一 · 任务笼统:动词没说清

    它必须猜你要什么动作

    帮我处理一下这个 AE 数据集。
    • 「处理」可以是清洗、汇总、检查、转换、画图——它挑一个,而且大概率不是你想的那个。

    动词 + 判据 + 产物

    逐条检查下面的 AE 记录,找出
    「结束日期早于开始日期」和
    「严重程度为 3 级以上但结局为
    已恢复且未采取任何措施」这两类
    矛盾,列出涉及的 USUBJID 和
    AESEQ。不要给处理建议。
    • 动作是「找出并列出」,判据写死了,还明确说了不要什么。

    失效二 · 上下文缺失:问了它不可能知道的事

    它只能编

    我们这个研究的主要终点该怎么
    定义比较合适?
    • 它不知道「我们这个研究」是什么。它会给一个格式完美、内容虚构的答案——这正是 1.4 情况 B。

    材料先给,再问

    以下是方案第 4 节的原文:
    【粘贴原文】
    
    依据以上原文,说明主要终点的
    定义和评估时点。原文未写明的
    部分,回答「方案中未写明」,
    不要推测。
    • 材料在上下文里,分布就变尖了;还给了「不知道」这条退路。

    失效三 · 一次问太多:五个任务挤一句

    它会挑轻的做

    把这份数据检查一遍,总结主要
    发现,写成给申办方的邮件,
    再列出后续要做的事,顺便看看
    有没有需要报告的 SAE。
    • 五个任务权重不同,它会均匀分配注意力——结果每一项都做了一点,没有一项做完。最要紧的 SAE 排在最后,最容易被草草带过。

    拆开,串起来

    第一步(只做这一步):逐条检查
    下面记录,输出问题清单,每条
    注明 USUBJID 和问题类型。
    
    ——确认清单无误后,再发第二条
    提示词让它写邮件。
    • 一次一件,每件都能验收。这个「拆开 + 串起来」的形状,就是第二讲要讲的「工作流」。

    失效四 · 隐含前提没说:你以为是常识的东西

    它按通用常识做,不是按你们的规矩

    把这些日期统一一下格式。
    • 「统一」成什么?它会选一个流行格式。而部分日期(只有年月)怎么处理,它会自己发明一套规则——发明得很合理,但不是我们的规则。

    把「大家都知道」写出来

    把下列日期改写成 ISO 8601
    (YYYY-MM-DD)。规则:
    · 只有年月的写成 YYYY-MM,
      不要补日
    · 完全缺失的留空,不要写 NA
    · 任何无法确定的,原样保留并
      在末尾加 (?) 标记
    • 这三条对我们是常识,对它是必须说出来的信息。边界情况是隐含前提最集中的地方。
    动手练一次 · 5 分钟

    拿出你这周真的问过 AI 的一句话,套用五问改写一遍,念给旁边的人听。不要求写得好,只要求指出原来那句里哪几件事是让模型猜的。改自己的活,比看别人的例子有用得多。

    板块 3

    上下文

    35 min

    板块 2 讲的是怎么问,这个板块讲的是给它看什么。一句话概括全部内容:上下文是产出质量的上限,不是配料。提示词再好,也补不上没给它的事实。

    3.17 min

    上下文是上限

    这一节只有一个观念,但它决定后面所有做法

    「上下文」指的是这一次调用时,模型能看到的全部文字:系统提示词、工具定义、之前每一轮对话、你粘进去的文档、工具返回的结果——0.4 那个请求体里的全部内容。

    它是上限,因为回到 1.1:模型的输出是以上下文为条件的概率分布。不在上下文里的事实,不会以任何方式影响这个分布(除了它训练时碰巧记住的那部分,而那部分你既不能查也不能改)。所以:

    • 没给的事实,它只能编。不是它不努力,是那个信息根本不在算式里。
    • 给错的事实,它会当真。它没有「这条看着不对」的核验步骤,除了你明确让它核。
    • 给多了,它会分心。3.4 会说明为什么——这一条最反直觉。
    一句可以贴在墙上的话

    问「怎么让 AI 答得更准」之前,先问「我给它看的东西够不够它答对」。十次里有七次,问题在后半句。

    3.211 min

    长文档和表格是怎么进去的,以及损耗在哪

    对我们最实际的一节——我们的材料几乎全是表格和长文档

    模型的输入只有一种形状:一串 token。所以任何东西进去之前都要先拉平成文本。这个拉平过程是我们大部分「它读错了表」问题的真正来源。

    • 表格失去二维结构。一张表拉平成文本后,「这个 3 属于 AESEV 这一列」这件事,只能靠列的先后顺序和表头的位置推断。行一多、列一宽,对齐关系就开始飘。
    • PDF 的排版会打乱顺序。双栏、页眉页脚、跨页表格,抽出来的文本顺序常常和你看到的不一样。扫描版 PDF 更糟——那是图片,要先 OCR,而 OCR 会把 0 认成 O、把 1 认成 l
    • Excel 的合并单元格会变成空值。拉平后合并区域只有第一格有值,剩下的是空——而空值在它眼里就是「没有」。
    • 长文档要切块。超过窗口就得切,而切在哪里,决定了信息还能不能被找到。
    Demo 8一刀切在错误的位置真实运行

    下面是一张 AE 表,要被切成小块送进模型(或存进检索库)。拖动块大小,看切口落在哪。然后看最下面那条判定——同一个问题,在不同切法下能不能答对。切块和判定都是这个页面真算的,不是写死的。

    每块大小
    40 token
    三个开关对应三条实操规则 一、结构化数据永远按行切,绝不按字数切。把「只在换行处切」打开,切断行的问题立刻消失。按字数切是通用文本的默认做法,用在表格上就是错的
    二、每块都要重复表头。关掉那个开关看第二块——里面有一堆数字,但没有任何东西说明第三列是严重程度。模型看到的就是这么一块没头没尾的东西,它只能猜列的含义,而它猜得相当自信。
    三、块之间留一点重叠。成本是重复几十个 token,收益是跨块的句子和上下文关系不会被完全切断。
    这三条是第二讲 RAG 的地基。做 RAG 时「该召回的没召回」,一大半原因不在检索算法,而在这一步就把信息切碎了。
    给我们的建议顺序

    要让它读一份材料,优先级是:① 纯文本 / CSV > ② Markdown 表格 > ③ 原生 PDF > ④ Excel > ⑤ 扫描版 PDF / 截图。能自己控制格式的时候,导成 CSV 或纯文本再给它,准确率的提升往往比换模型大得多,而且不花钱。

    3.39 min

    结构化输出:让它给 JSON,而不是给散文

    这一节决定了「能不能接进现有流程」

    只要结果的下一站是程序而不是人,就必须要求结构化输出。理由不是好看,是散文的形状不稳定:同一个意思它能有十种写法,而每一种都要下游写一套解析——这活干不完。下面这个演示直接跑给你看。

    Demo 9让程序去读它的回答真实运行

    下面四段散文说的是同一件事,只是措辞不同。右边那个提取程序(真的正则,就在这个页面里跑)逐个去读。点着看每一段坏在哪——特别是第四段。

    散文回答
    模型的回答(散文)
    提取程序拿到了什么

    换成要求 JSON

    JSON 回答
    模型的回答(JSON)
    JSON.parse() 的结果
    四条结论 一、散文每次都能读懂,但每次读不到同一个位置。四种写法,正则各坏在不同地方。为散文写解析器是个无底洞。
    二、写法四是最可怕的一种失败。它不是没提到,是提错了——「不相关」被读成「相关」,而程序一点异常都不报。缺失能被发现,静默的错值不能。在我们这行,这类错误会一路走进交付物。
    三、JSON 也会失败,但失败方式是「一眼可见」的。解析失败就是抛异常,程序当场停住。会响的故障远好过不会响的故障。
    四、正确做法不是靠提示词求它。API 层面可以直接约束输出必须符合某个结构(Claude 上是 output_config.format,或者把它做成一个工具的参数)。能在 API 层约束的东西,就不要在提示词里恳求。
    今天就能用的一句模板

    不写程序的人也用得上:「输出一个表格,四列:USUBJID、问题类型、涉及记录、依据。不要任何表格以外的文字。」——最后那半句是关键。它能把「好的,我帮您看了一下……」那段寒暄掐掉,让结果可以直接粘进 Excel。

    3.48 min

    上下文污染:为什么对话越长越笨

    这一节收掉第一讲,也直接接上第二讲

    直觉会说:给的信息越多,它答得越好。实际不是。塞到一定程度之后,质量会掉。原因有五个,前两个是模型本身的,后三个是我们自己造成的。

    1. 信噪比下降。相关的那两句话,从占上下文的 50% 变成占 0.5%。它没有「先检索再回答」这一步——所有 token 都平等地参与那一次计算,噪声也一样参与。
    2. 中段位置劣势。放在开头和结尾的信息更容易被用上,埋在中间的最容易被忽略——即使它完全在窗口之内。这是公开研究反复观察到的现象,业内叫 lost in the middle
    3. 失效的旧指令还在里面。你第 3 轮说「用中文」,第 20 轮说「改成英文」——两条都在上下文里,它得自己判断哪条算数,有时判断错。
    4. 它自己的错误成了前提。第 5 轮它编了一个变量名,这句话现在是上下文的一部分。后面每一轮它都会把那个编造当成已经确认的事实。这是 1.1 第 ③ 条在多轮尺度上的放大版。
    5. 工具返回的原始结果堆积。Agent 场景里最严重:每次调用都往上下文里倒一大段原始输出,几轮之后真正的任务描述被埋在几万 token 底下。第二讲、第三讲会反复回到这个问题。
    示意 · 关键信息所在位置 → 被正确用上的相对可能性 上下文开头 中段 上下文结尾 开头:记得住 中段:最容易被漏掉 结尾:记得最牢 曲线是趋势示意,不是实测数据;不同模型、不同长度下幅度差别很大,但这个 U 形反复被观察到。
    直接的实操含义:把最关键的约束放在最后。先给材料,最后一句才写「现在,依据以上材料,只回答……」。「关键的话放最后」是这张图唯一需要记住的操作性结论。

    四个立刻能用的办法

    这四件事有效

    • 该开新会话就开新会话。换任务了就别接着聊。把上一轮的结论复制成一段干净的文字,作为新会话的开头——这一招几乎解决所有「它突然变笨了」
    • 只带相关的那几页。不是整本方案,是第 4 节。
    • 关键约束放最后一句。照上图。
    • 它答错时不要在原会话里纠正十轮,改提示词重开一次。错误答案留在上下文里会持续起作用。

    这四件事在帮倒忙

    • 别一次把全部材料倒进去「让它自己找」。
    • 别在一个会话里跨任务连着聊一整天。
    • 别指望「窗口更大」能解决这个问题——窗口变大只是能装更多,不代表能在更多里找得同样准。
    • 别反复追问「你确定吗」。它大概率改口,而且改的方向是让你满意,不是让答案更对。
    这就是第二讲的入口

    顺着这一节往下想一步:如果「不能全塞进去」,又「必须让它用上那些材料」,那就得有个东西在每次提问时替你挑出该带的那几页——那个东西叫 RAG,是第二讲第一节。
    再往下:如果它需要的不是文档而是算一下、查一下、改一下,那就得让它能调用外部程序——那是工具调用与 MCP,第二讲第二节。第一讲讲完的是边界,第二讲讲的全是怎么绕过这些边界。

    收束

    三句话和一份作业

    5 min
    回顾3 min

    如果只带走三句话

    1. 它只会猜下一个 token。算数不准、会编造、错了会顺着错下去——全部从这一句推得出来,不用另外记。
    2. 上下文是上限。提示词决定它怎么答,上下文决定它能不能答对。十次答不好,七次是材料没给够。
    3. 自信和正确不相干。它语气最肯定的时候,恰恰可能是它最没根据的时候。「看起来很专业」在我们这行不构成任何证据。
    回到开场那三个问题

    把你开场时记下的答案对一遍。第 2 题(有没有打开过命令行)现在应该是「有」了。第 3 题的正确答案是「这个区分不存在」——它没有「不会」和「胡说」两种模式,只有一种模式。

    作业2 min

    到第二讲之间做三件事

    1. 改写一句你自己的提示词,记录前后差别。用板块 2 的五问改一句你这周真的问过的话,把两次的回答都留着,第二讲开场分享。这是唯一必做的一项。
    2. 找一次它编造的记录。故意问它一件它不可能知道的事(我们某个内部编号、某份内部 SOP 的条款),把它编出来的东西截图。亲眼见过一次,比听十遍「它会幻觉」有用。
    3. 打开一次命令行,敲三条命令。Mac 上是「终端」,Windows 上是 PowerShell。pwdls(Windows 上是 dir)、cd 各一次。目标只是让那个黑框从「陌生」变成「见过」——第三讲讲终端型 Agent 时会用到这个熟悉感。
    第二讲预告

    第一讲讲的全是边界:它只会猜下一个 token、窗口有限、不知道截止日期之后的事、算不好数。第二讲讲的全是怎么绕过这些边界——用检索绕过知识边界(RAG),用工具绕过能力边界(Function Calling 与 MCP),用自主循环绕过单次调用的边界(Agent)。本讲的每一个约束,在第二讲都有一个对应的破解办法。

    附录 · 供发放与自学

    术语表与预设问答

    术语表按本讲出现顺序排列,可以单独打印。预设问答是这类培训里最常被问到的九个问题,答案一并写在这里,便于会后查阅。

    术语表

    命令行 / 终端 / shell
    只接受文字指令的操作界面。价值在于指令是文字——可存档、可重放、可审计、可交给程序执行。
    路径 / 当前目录
    文件在目录树里的位置。~ 是主目录,. 是当前目录,.. 是上一层。「当前目录」是个会变的状态。
    脚本 / 解释器
    脚本是一个文本文件;解释器(如 python)是那个从上到下读它并照做的程序。
    库 library
    别人写好的一批函数,你主动调用。约等于一套现成的 SAS 宏。
    框架 framework
    它定好流程骨架,在合适的时候调用你的代码。控制方向和库相反,所以替换成本高。
    包管理 / pip / PyPI
    pip install X 从公共仓库 PyPI 下载安装库。这条依赖链是需要被冻结和归档的供应链。
    虚拟环境 venv
    给单个项目独立的一份库目录,避免不同项目的版本互相覆盖。行业默认做法。
    requirements.txt
    依赖清单,每行一个库和写死的版本号。受监管环境里必须和代码一起归档。
    API
    一台机器留给另一台机器用的接口。规定了发到哪、填什么、回什么。
    JSON
    机器之间传数据的文本格式。只有 {}(键值对)和 [](列表)两种结构。
    无状态
    每次 API 调用互相独立。「多轮对话」是客户端每轮把全部历史重发一遍伪造出来的。
    Git / commit / diff / PR
    版本控制。提供「可回到的已知良好状态」和「逐行看改了什么」,是让 Agent 改代码可控的前提。
    token
    模型的最小切分单位,也是计费单位。中文约一字一个,英文约四字符一个,数字和标识符会被切碎。
    自回归 / 下一个词预测
    读全部文本 → 输出下一个 token 的概率表 → 抽一个 → 追加 → 重复。模型做的就只有这件事。
    采样 / 温度
    从概率表里抽签的规则。温度低偏保守,高偏发散。当前 Claude 一代已移除 temperature 参数,改用 effort 档位。
    上下文窗口
    一次调用能容纳的 token 总量上限,输入和输出共享。Opus 5 为 100 万,Haiku 4.5 为 20 万。
    知识截止日期
    训练数据的时间边界。之后的事它不知道,而且不知道自己不知道
    预训练 / SFT / 对齐
    三段式训练。能力基本来自第一段,「听话」和「会说不确定」来自后两段。
    幻觉
    概率表摊平时抽出的、格式正确但内容无据的输出。它和正确输出在语气上没有区别。
    提示词 prompt
    你发给模型的全部指令文字。作用是把模型必须替你猜的事一件件关掉。
    Few-shot / 示例驱动
    在提示词里给几组「输入 → 输出」实例。作用是收窄可能的输出形态,尤其能钉住边界情况的处理方式。
    结构化输出
    强制模型按给定结构(如 JSON)输出,让下游程序能稳定解析。可在 API 层约束,不必靠提示词恳求。
    切块 chunking
    把长文档切成小段。表格必须按行切、每块重复表头、块间留重叠。
    上下文污染
    上下文变长后质量下降:信噪比下降、中段被忽略、旧指令冲突、自己的错误成了前提、工具输出堆积。
    Lost in the middle
    关键信息埋在上下文中段时最容易被忽略。实操结论:关键约束放最后一句。
    effort / 思考深浅
    控制模型答前推导多少的档位。判断标准:这题你自己做需不需要打草稿。

    预设问答

    它是不是会偷偷学我们的数据,然后告诉别人?

    要分两件事说。一、你发出去的内容确实离开了公司网络,这一点没有含糊空间,所以受试者可识别信息和未盲态数据不能进去。二、「会不会被用于训练」取决于你用的是哪种账户和合同——企业/API 通道通常默认不用于训练,个人版免费产品经常会。这不是技术问题,是合同问题,要看我们和供应商签的是什么,不能靠猜。第三讲会专门处理这一节。

    那我把姓名删掉再发,是不是就安全了?

    不够。去标识不等于不可识别——罕见适应症 + 出生年月 + 中心编号 + 访视日期,组合起来往往就能定位到人。判断依据应当是我们现有的数据分级规范,不是「我觉得看不出来是谁」。这一条建议直接沿用公司现行的数据处理 SOP,不要在这门课里另立标准。

    既然它会编,那还能用来干什么?

    用在「产出容易被验证」的地方。写检查脚本——跑一下就知道对不对;读懂一份没人熟悉的旧程序——它给的解释你可以对着代码核;把材料给它做抽取和改写——原文在手边,一比就知道。反过来,「产出难以验证」的地方就是它最危险的地方,比如让它凭记忆说某条法规怎么规定。判断标准不是任务难不难,是错了你能不能发现

    为什么同一个问题问两次答案不一样?这不是不可靠吗?

    这是 Demo 2 里的采样——它每步是从概率表里抽签,不是查表。「不确定性」是这类模型的固有属性,不是缺陷或 bug。所以任何需要可重复的场景,都不能依赖「再问一次应该也一样」,必须把输出固化下来(存成文件、纳入版本控制),并且对结果做验证。第三讲讲验证和留痕时会回到这里。

    我们要不要自己训练一个模型?

    几乎肯定不要。板块 1.2 那张三段式图就是答案——能力主要来自预训练,而那一步的成本以千万美元计。真正的需求「让它懂我们的规范和数据」,属于后两段甚至更外层的问题,应该用上下文、检索、工具来解决(板块 2、3 和第二讲的全部内容),成本差好几个数量级,而且改起来是当天生效的。

    我不写代码,板块 0 那些东西对我有什么用?

    用处在于你要参与判断。第三讲会讨论「这个工具能不能进我们的流程」「哪一步必须有人确认」「数据边界划在哪」——这些讨论里会不断出现命令行、依赖、API、Git 这些词。不需要会用,需要知道它们指什么、边界在哪。不然那场讨论里你只能听,没法投票。

    Python 会取代 SAS 吗?我们要不要都去学 Python?

    这门课不回答这个问题,而且要小心别让它变成本课的隐含结论。板块 0.2 讲 Python 只有一个目的:这个领域的工具和示例几乎都是 Python 写的,看得懂才能参与判断。至于我们的交付流程用什么语言,是另一场需要考虑监管、验证、团队能力和历史资产的讨论,和这门课无关。

    上下文窗口有 100 万 token,是不是就没有限制了?

    窗口大只解决「装得进」,不解决「找得准」——板块 3.4 那张 U 形图讲的就是这件事。而且每一轮都按实际装进去的量重新计费,塞满 100 万 token 聊二十轮,账单会很有说服力。正确做法是带相关的那几页,不是全带。

    这份讲义里的数字和参数,多久会过时?

    分三层。原理层(下一个词预测、上下文是上限、幻觉机制、切块规则)——很稳定,可以按年算。实践层(提示词五要素、示例驱动、结构化输出)——也很稳定。参数与价格层(模型名、窗口大小、单价、temperature 还在不在)——三到六个月就会变一轮。所以本页凡是具体数字都注明了「2026 年 9 月」——请把它们当快照,不要当结论。

    本讲演示索引

    编号演示在哪一节标签
    Demo A摸一次命令行0.1模拟沙盘
    Demo BPython 执行追踪0.2模拟沙盘
    Demo CSAS / Python 对照0.2模拟沙盘
    Demo D依赖与虚拟环境0.3模拟沙盘
    Demo E解剖一次模型调用0.4模拟沙盘
    Demo 1分词器1.1真实运行
    Demo 2亲手采样 + 温度1.1示意数值
    Demo 3三个训练阶段1.2示意数值
    Demo 4上下文预算1.3真实运行
    Demo 5两张概率表1.4示意数值
    Demo 6五个开关九个歧义2.1真实运行
    Demo 7示例收窄可能性2.2示意数值
    Demo 8表格被切在错的位置3.2真实运行
    Demo 9让程序去读回答3.3真实运行