本页目录
Lesson 00 — 方法预热:读论文、拆源码、立基线
本课目标:建立前沿学习的三件工具——精读论文的方法、拆框架源码的方法、用基线对照实验的方法;并跑出贯穿全课程的「失忆基线」,作为之后每个机制收益的对照零点。
学完你能回答:「没有标准答案的前沿领域,你怎么学、怎么判断一个机制到底有没有用?」——答案是先有方法、再有结论。没有基线对照的「优化」都是玄学。
0. 为什么这门课开头不一样
前六门课(RAG/Agent/框架/多智能体/LLMOps/多模态文档智能)教的是已收敛的知识:RAG 怎么切块、ReAct 怎么写循环、SqliteSaver 怎么用——业界有标准答案,README 可以说「标准做法是……」。
这门课教的是未收敛的前沿:Agent 记忆怎么分层?反思到底有没有用?Code Agent 的沙箱做到什么级别才够?轨迹评估用什么指标?——业界没有标准答案,只有「几种流派 + 各自的取舍」。所以本课先立方法:怎么读论文、怎么拆源码、怎么用实验裁决。
🎯 核心认知:前沿领域的能力不是「学会别人的答案」,而是「在没有答案的地方自己找答案」。这门课的交付物不是「记住了几个机制」,而是「养成了一个会记忆、能反思、会写代码、跨会话进化的深度研究智能体,并且每一步改进都有数据支撑」。
1. 精读论文的三遍读法
前沿知识的一手来源是论文。但论文不是小说,不能从头读到尾。我用的方法是三遍读法——每一遍带着不同的目的,逐步深入。
第一遍:摘要 + 图表(5 分钟,判断值不值得读)
只看:标题 → 摘要 → 结论段 → 所有图表。目标:用 5 分钟判断这篇论文解决了什么问题、用了什么方法、结果好不好。不值得读的论文在这里就被筛掉。
第二遍:方法部分(30 分钟,搞懂怎么做)
重点读 Method/Approach 章节,搞懂:输入输出是什么 → 核心机制是什么 → 有哪些组件 → 组件之间怎么协作。这一遍不看实验细节,只追「它到底干了什么」。
第三遍:带着复现意图读(1-2 小时,能不能复现)
带着「我要复现它的核心 idea」去读:实验怎么设置的?baseline 是什么?消融实验怎么做的(去掉某组件看掉多少)?哪些是核心贡献、哪些是工程 trick?这一遍读完,你应该能写出「最小复现计划」。
带读:ReAct(Yao et al. 2022)
论文:ReAct: Synergizing Reasoning and Acting in Language Models(Yao et al. 2022, arXiv:2210.03629)
一句话说它证明了什么:让 LLM 在「推理(Thought)」和「行动(Act/调用工具)」之间交替,比纯推理(Chain-of-Thought)或纯行动(Act-only)都好——推理帮行动有方向,行动帮推理接地气。
- 第一遍(摘要+图表):问题=LLM 只推理会幻觉(没有外部事实 grounding)、只行动会乱调工具(没有规划)。方法=Thought→Action→Observation 循环。图表显示 ReAct 在 HotpotQA/ALFWorld 上比 CoT 和 Act-only 成功率都高。
- 第二遍(方法):核心是一个 prompt 模板,引导 LLM 按格式输出
Thought: ... Action: ... Observation: ...,Observation 是工具返回结果回注 prompt。就这么简单——没有训练,纯 prompt。 - 第三遍(复现意图):最小复现 = 一个 while 循环 + 一个 prompt 模板 + 一个工具执行器。你在 agent-lessons/03 已经手写过,这就是 ReAct。消融实验的关键洞察:去掉 Thought(纯 Act)成功率明显下降——推理不是装饰,是行动的导航。
带读:Reflexion(Shinn et al. 2023)
论文:Reflexion: Language Agents with Verbal Reinforcement Learning(Shinn et al. 2023, arXiv:2303.11366)
一句话说它证明了什么:把失败转成「语言化的自我反思」存进记忆,下次重试时带上这段反思,能显著提升成功率——这被称为「不用梯度的强化学习」(用语言反馈代替参数更新)。
- 第一遍:问题=ReAct 一次失败后,下一轮完全失忆,会犯同样的错。方法=失败后让 LLM 自评「为什么失败」生成反思文本,存入 episodic memory,下一轮 prompt 注入。图表显示带反思的重试成功率随轮次上升。
- 第二遍:三组件——Actor(执行任务)、Evaluator(判成功失败)、Self-Reflection(生成反思)。关键:反思必须是具体的教训("搜索词太宽泛"),不是空泛检讨("我应该更仔细")。
- 第三遍(复现意图):最小复现 = ReAct loop + 一个失败检测 + 一个反思生成 + 反思注入重试。L04 会手写。消融关键:把反思换成「随机文本」,成功率立刻回落——起作用的是反思内容,不是「多了一轮」这个动作本身。
💡 三遍读法的本质:不是读三遍同样的内容,是三遍不同的目的。第一遍筛、第二遍懂、第三遍复现。读完拿不出复现计划的,等于没读第三遍。
2. 拆源码的方法:以 LangGraph Checkpoint 为例
前沿不仅是论文,还有快速演进的框架。拆源码的能力 = 理解「别人怎么解决的」并迁移到自己系统。我们拆一个你正在用但从没看进去的东西:LangGraph 的 Checkpointer。
为什么拆 Checkpointer
我们的 research-assistant 正在用 AsyncSqliteSaver(见 persist.py)。任务书有个灵魂论断:「现有 checkpointer 只是对话状态持久化,不是记忆系统——这个区别正是 L01 的起点」。光看 API 文档理解不了这个论断,得看进去它到底存了什么。
拆解步骤
① 先看接口定义(它承诺什么)
LangGraph 的 BaseCheckpointSaver 定义了几个核心方法:
aget_tuple(config) → 取一个 thread 的最新 checkpoint
alist(config) → 列出某个 thread 的历史 checkpoint
aput(config, checkpoint) → 存一个 checkpoint
aput_writes(config, writes)→ 存中间的写入记录
关键概念是 thread_id:一次「会话/线程」的标识。checkpoint 按 thread_id 隔离。
② 看存的数据结构(它实际存了什么)
一个 checkpoint 包含:
- channel_values:图的 State 快照(你的 SystemState 序列化)
- channel_versions:每个字段的版本号
- versions_seen:每个节点看过的版本(用于去重)
③ 得出结论:对话持久化 ≠ 记忆系统
┌─────────────── Checkpointer(现状)─────────────────┐
│ 存的是:某个 thread 的【完整 State 快照】 │
│ 能做:跨轮恢复对话(thread_id 相同 → 接着上次) │
│ 不能做: │
│ 🚫 检索 —— 没法按语义"查相关历史",只能按 thread 取 │
│ 🚫 遗忘 —— 全量存,不会衰减,越堆越大 │
│ 🚫 跨 thread 共享 —— A 会话的结论 B 会话用不上 │
│ 🚫 提炼 —— 存的是原始 state,没有"经验沉淀" │
└──────────────────────────────────────────────────────┘
┌─────────────── 记忆系统(L01 要建的)────────────────┐
│ 存的是:提炼后的【经验/事实】,按语义可检索 │
│ 能做: │
│ ✅ 检索 —— 新任务前 recall 相关旧记忆 │
│ ✅ 遗忘 —— 时间衰减 + 频次保留 │
│ ✅ 跨 thread —— 不同会话共享同一记忆库 │
│ ✅ 提炼 —— 不是录像,是"学到了什么"(L02) │
└──────────────────────────────────────────────────────┘
🎯 这就是 L01 的起点:checkpoint 是「把对话状态原样存下来再原样恢复」,记忆是「把经验提炼存下来按需调回」。前者是日志,后者是大脑。research-assistant 现在只有日志,没有大脑。
拆源码的通用方法论
- 从你正在用的 API 往里钻:别从
__init__.py开始读,从你调的那个方法开始追。 - 先看数据结构,再看逻辑:
dataclass/TypedDict定义里藏着 80% 的设计意图。 - 问「它不能做什么」:API 文档告诉你能做什么,源码告诉你边界在哪。边界就是你要补的地方。
3. 流派对比:前沿领域的标准姿势
这门课每课都有「流派对比」小节——因为前沿没有标准答案,只有权衡。本课先示范一次:
问题:怎么学一个前沿新方向?
| 流派 | 做法 | 取舍 |
|---|---|---|
| ① 跟新闻 | 看 Twitter/公众号推文 | ✅ 快;🚫 浅,二手转述,常带噱头,无法复现 |
| ② 只读论文 | 精读 arXiv | ✅ 深,一手;🚫 慢,且论文常省工程细节 |
| ③ 只拆源码 | 直接读框架/仓库代码 | ✅ 接地气,能跑;🚫 缺理论背景,知其然不知其所以然 |
| ④ 三件套(本课选它) | 论文懂原理 + 源码看实现 + 基线验证收益 | ✅ 全方位;🚫 贵(每个方向投入大),但前沿就该这么投入 |
选 ④ 的理由:前沿的每个结论都是实验性的,只读不验 = 盲信。任务书反复强调「诚实标注:本机跑出的数字要附复现命令,引用的结论要标来源,没跑过的明写未实测」——这个要求的前提就是「你要能跑」。
4. 硬任务定义:贯穿全程的试金石
前沿能力(记忆/反思/长任务)只有在足够难的任务上才显出差别。玩具任务("查一下天气")测不出失忆的痛——因为一次就答完了。本课程统一用这个任务作试金石:
「持续追踪研究」任务:让 research-assistant 跨多次运行持续追踪同一个技术主题(默认:「MCP 生态的演进」,可配置)。要求: - 第 2 次运行要记得第 1 次查过什么、结论是什么(记忆) - 发现新信息与旧结论冲突时要修正并说明为什么(反思) - 需要对比数据时能写代码算(Code Agent) - 每次运行产出「增量简报」而非从零重写(长任务)
为什么玩具任务测不出前沿能力
玩具任务("查 GLM-4 的参数") 硬任务("持续追踪 MCP 生态演进")
──────────────────────────── ─────────────────────────────────
一次搜索就答完 需要跨多次运行累积
不需要记忆 不记忆 = 每次从零重做,重复劳动
没有冲突 新旧信息冲突时必须判断采信谁
不涉及计算 对比发布节奏/版本数需要算
产出一次性 产出增量,要标注"新增/修正/不变"
🎯 核心认知:评估一个机制有没有用,先要有一个「没有它就很痛」的任务。硬任务就是制造这个痛感——失忆的痛、不能反思的痛、口算出错痛、每次重来的痛。之后每个机制上线,痛感减轻多少就是它的价值。
5. 跑裸基线
现在跑一次硬任务的裸基线:用现状的 research-assistant(无记忆、无反思、无 code、无账本)连跑 2 次同一主题,看它有多失忆。
基线脚本设计
code.py 做三件事:
1. 用 mock 的假搜索结果(不烧 API、不依赖网络),模拟 research-assistant 跑「MCP 生态演进」这个主题两次
2. 把每次运行的轨迹(每步输入输出)存成 baseline_trace.jsonl
3. 打印对比报告:第 2 次有没有用到第 1 次的任何结果(剧透:没有,完全失忆)
预期结果(裸基线的病)
运行 #1:拆题 → 并行检索 → 汇总 → 写报告 → 审稿
(从零开始,查了一堆,产了一份报告)
运行 #2:拆题 → 并行检索 → 汇总 → 写报告 → 审稿
(完全从零开始,重复查了几乎一样的东西,
完全不知道 #1 查过什么、结论是什么)
对比:两次轨迹高度重复,第 2 次零增量价值。
这个 baseline_trace.jsonl 会作为全程对照——L01 加记忆后看 recall 命中、L04 加反思后看冲突修正、L08 评估时拿它算基线指标。
⚠️ 诚实标注:本课的基线用 mock 搜索结果跑(不烧真实 API),目的是演示「失忆」这个结构性问题。真实 API 跑出的报告内容会不同,但「第 2 次完全失忆」这个结论不变——因为这是架构问题(无记忆系统),不是内容问题。
6. 落地清单
本课是方法课,无代码落地改动(不改 research-assistant 任何文件)。产出:
- README.md(本文件):论文导读 + 源码拆解 + 方法论
- code.py:跑裸基线,产出 baseline_trace.jsonl
- baseline_trace.jsonl:全程对照基线(L08 评估时复用)
- exercise.md:练习
验收
# 1. 跑基线(生成轨迹文件)
cd frontier-lessons/00_method
python code.py
# 预期输出:
# - 打印两次运行的轨迹对比
# - 结论:第 2 次运行零增量、高度重复(失忆)
# - 生成 baseline_trace.jsonl
# 2. 验证轨迹文件存在且有内容
ls -la baseline_trace.jsonl
# 应看到非空文件
# 3. 验证能读出轨迹
python -c "import json; lines=open('baseline_trace.jsonl',encoding='utf-8').readlines(); print(f'{len(lines)} 条轨迹记录'); print(json.loads(lines[0])['run'])"
7. 本课在两条主线上的位置
- 评估主线:本课立了基线——L08 的轨迹评估体系建立后,要回头量化 L01–L07 每个机制的收益,对照的就是本课存的
baseline_trace.jsonl。没有基线,"加了记忆更好"就是感觉,不是数据。 - 上下文工程主线:本课拆 Checkpointer 时点明了「对话持久化 ≠ 记忆系统」——记忆的本质是「上下文的外置与按需调回」,这是整个上下文工程母题的第一块拼图(L01 正式动手)。
🎯 面试话术
「我读前沿论文用三遍法——一遍摘要图表筛、二遍方法懂、三遍带复现意图读,读完拿得出最小复现计划。拆源码我从正在用的 API 往里钻、先看数据结构、再问它不能做什么。而且我坚持先跑基线再谈改进——没有基线对照的『优化』都是玄学。比如我给研究助手加记忆前,先跑了一次失忆基线存档,之后每个机制的收益都拿它做对照。」