斯坦福 CS329A 这学期的主题是 Self-Improving AI Agents也就是自我改进的 AI 智能体。它不是一门教你“怎么调 Prompt、怎么接工具链”的应用课而是把最底层的问题摆在桌面上一个 Agent 在犯错之后如何通过推理、搜索和强化学习让自己下一次做得更好。这门课最值得关注的地方是它把三大块技术串成了同一条训练链路推理Reasoning负责让模型“想得更深”搜索Search和规划Planning负责在更大的解空间里找更优答案强化学习RL负责把“答对/做对”变成可持续的优化信号。也就是说你会在同一门课里看到 AlphaGo 式的搜索思想、ChatGPT 式的偏好对齐、以及 Kendrick 所谓“test-time compute”式的推理时扩展如何被统一进一个 Agent 框架。这篇文章会把 CS329A 的知识体系拆开看并给出一条可以自己在本地机器上落地的学习路线。你不需要先上完课才能动手从最基本的“多次采样 验证”开始可以一路做到 DPO 微调和规则奖励强化学习的小闭环。读完你应该能回答这几个问题Agent 的自我改进到底改的是什么、需要什么环境、先做哪个实验最划算、最容易在哪个环节翻车。如果你已经在做 Agent 应用开发但总觉得停留在“调用 API、拼接工具”的层面这篇建议直接收藏。1. 课程核心模块速览先给一张课程层面的速览表方便快速判断这门课是否需要投入精力。维度说明课程定位斯坦福大学开设的 AI 专题课程聚焦自我改进 AI 智能体核心技术线推理Reasoning、搜索与规划Search Planning、强化学习RL学习形式公开讲义与视频、编程作业、项目实践具体以课程官方发布为准前置要求Python、PyTorch 基础熟悉 Transformer 结构和基本微调流程运行环境有 NVIDIA GPU 最理想没有本地 GPU 可用 Colab / Kaggle 等云环境替代核心产出理解 Agent “生成-评估-优化” 的完整链路掌握可迁移的训练实验方法再看一张概念速览表。这些概念会反复出现在课程材料和作业里提前建立印象会让后续学习顺很多。核心概念一句话解释在课程链路里的位置CoT思维链让模型在给出答案前先输出推理过程推理模块的起点verifier / reward model给模型输出打分的模块是搜索和 RL 的“裁判”贯穿推理、搜索、强化学习self-correction让模型检查自己的答案并修正推理模块的关键能力best-of-n / beam search在生成阶段保留多个候选再筛选搜索模块的代表方法MCTS蒙特卡洛树搜索通过模拟和回传选择最优动作路径规划与决策模块DPO / GRPO不需要单独训练奖励模型的偏好优化方法强化学习模块的轻量入口tool use / 环境反馈Agent 调用外部工具或执行代码获得真实反馈应用与部署层从课程结构看这门课不是在讲单点技巧而是反复围绕一个循环模型先产生输出再通过某种信号判断好坏最后把这些判断转成下一次改进的依据。下面几个章节会按照这条主线展开。2. 这门课适合谁不适合谁先说适合的人群。第一类是正在做 Agent 应用开发的工程师。很多人已经能熟练使用 LangChain、AutoGPT 这类框架但对模型为什么失败、如何把失败变成训练信号缺乏系统理解。CS329A 正好补上这一层你会学到如何定义验证信号、如何构造偏好数据、如何用搜索和强化学习提升模型的稳定性。第二类是想从 Prompting 转向模型训练的开发者。如果你已经会调用模型 API但还没碰过微调、偏好优化和强化学习这门课是一个完整的升级路径。它不会只让你“跑通一个 DPO 脚本”而是让你理解 DPO 在整个自我改进闭环中的位置。第三类是算法方向的学生和研究员。课程会涉及大量文献和实验设计对梳理“推理增强”“测试时搜索”“偏好优化”这几条研究线非常有帮助。不太适合的情况也很明确。如果你只是想快速上线一个 Agent 产品这门课偏原理和实验不是框架使用手册短期 ROI 不高。如果你是零基础连 Python 和机器学习基础都比较薄弱建议先补完基础再回来。另外如果完全没有 GPU 而且也不愿意用云端环境动手环节会非常受限光看讲义很难建立体感。关于使用边界有几件事必须提前说明。课程讲义、视频和作业材料版权归课程方所有请通过官方渠道获取不要二次分发。实验阶段如果用公开数据集或 API 生成合成数据要检查数据授权和厂商使用政策。本地方案可以处理私有数据但一旦把数据发给云端 API就默认接受该平台的数据使用条款。最后在认知边界上也要冷静自我改进不是“模型自己突然变强”而是“在明确反馈信号下不断优化”。如果信号设计有漏洞模型会找到你没想到的捷径也就是后面会说到的 reward hacking。3. 环境准备与前置条件3.1 前置知识清单建议在上手前确认自己具备以下基础不需要全部精通但至少要熟悉Python 工程能力会写脚本、处理 JSON、做简单的多线程和异常处理。机器学习基础理解损失函数、梯度下降、过拟合这些概念。LLM 基础了解 Transformer 结构、pre-training 和 fine-tuning 的区别知道 RLHF 的大致流程。数学基础主要是概率论和线性代数计算量不会很大但概念要能看懂。如果这些还不熟先不要急着刷课程把 Python 和 Prompt 基础打牢会更高效。3.2 硬件与系统要求从课程实验的常见需求看推理实验用普通 NVIDIA GPU 就能起步。进入微调和强化学习阶段后显存会更吃紧更稳妥的起点是 8GB 以上显存实际以你本机情况为准。没有本地 GPU 的话Colab 的免费 T4、Kaggle 的 GPU 环境都是可行的替代方案。操作系统方面Windows 建议用 WSL2 跑 Linux 环境macOS 可以跑推理和小规模训练但真正做 RL 实验还是会受限于显卡。模型大小和显存的关系建议遵循一个原则消费级显卡优先从 7B 以下模型开始用 LoRA / QLoRA 做微调实验。3.3 软件环境搭建下面给一套通用实验环境。这不是课程指定的环境而是覆盖了推理、微调、RL 和 API 调用所需的最小工具链。conda create -n cs329a python3.10 -y conda activate cs329a pip install torch transformers datasets accelerate peft trl pip install vllm openai pandas装完以后可以用下面两条命令确认 GPU 和磁盘状态。nvidia-smi # 查看显卡型号和当前显存占用 df -h # 查看剩余磁盘空间微调和模型下载都需要空间另外准备一个模型目录和一个日志目录后续实验的数据、模型权重、日志分开存放避免根目录堆成一团。4. 把课程主线拆成四个可执行阶段CS329A 的知识体系可以粗略拆成四个阶段。每个阶段都对应一个可以独立完成的实验建议按顺序走。4.1 阶段一理解推理先学会观察模型“在想什么”自我改进的第一步不是调参而是观察模型在什么情况下会答错、为什么答错。思维链CoT是最直接的观察窗口让模型先输出推理过程再给出最终答案。一旦推理过程可读你就能区分“算错了”和“推理路径本身就是错的”。更进一步self-consistency 的思路是同一道题多次采样然后做多数投票self-correction 则是在模型给出答案后再让模型自己检查一遍。这些方法不需要训练新的模型只靠采样和验证就能提升效果是理解自我改进最直观的入口。下面是一个通用示例脚本目的是观察候选答案的多样性from transformers import pipeline # 通用示例用一个小模型生成多个候选答案 gen pipeline(text-generation, modelQwen/Qwen2.5-7B-Instruct, device0) def sample_with_cot(prompt: str, n: int 4) - list[str]: outputs [] for _ in range(n): res gen( prompt \n请先写出推理过程再给出最终答案。, max_new_tokens512 )[0][generated_text] outputs.append(res) return outputs prompt 小明有12个苹果吃掉3个后又买来5个现在有几个 candidates sample_with_cot(prompt, n4) for i, c in enumerate(candidates): print(f候选{i 1}:\n{c}\n---)这个实验的目的不是刷分而是让你直观感受“采样温度”“候选数量”“提示词约束”对输出分布的影响。能把这一步做好后面构造训练数据会顺手很多。4.2 阶段二搜索与规划把采样本身变成算法当“让模型生成一个答案”变成“让模型生成很多答案再选一个最好的”搜索就进来了。这一阶段需要掌握的几种方法可以放在一起对比方法核心思想并行友好度典型场景best-of-n生成 n 条候选用验证器选最优高一次生成多条答案再打分beam search解码时逐步保留 top-k 路径中受限解码、翻译、结构化生成MCTS用模拟和回传选择最优动作路径中代码生成、游戏、规划类任务self-consistency多次采样 多数投票高数学推理、事实类问答重点理解 best-of-n因为它是最容易落地的搜索改进手段。它的核心逻辑是不改变模型权重只通过“多次采样 验证器筛选”就能显著提升正确率。这在课程里通常被当作一个基础实验也是后面构造偏好数据集的原料。这一阶段要注意成本和延迟。搜索空间变大验证器每跑一次都是在花钱花时间。控制候选数量、限制采样长度、对验证结果做缓存都是必要的工程手段。4.3 阶段三从数据到偏好优化把“对错”变成训练信号搜索能在推理阶段提升效果但模型本身没有变强。要让模型后续直接生成更好的答案需要把搜索得到的高质量结果变成训练数据。这一步的完整路径是收集轨迹数据 - 筛选出高质量样本 - 做 SFT监督微调让模型模仿好行为。在此基础上再引入偏好优化。DPO 的核心是用偏好对chosen / rejected直接优化策略不必单独训练奖励模型GRPO 则在 RL 过程中用组内相对奖励来减少方差是 DeepSeek-R1 这类公开模型采用的轻量化方案。DPO 和 GRPO 对实验者更友好也是当前开源社区最常用的两个工具。DPO 训练用 HuggingFace TRL 库可以写得很短from trl import DPOTrainer from transformers import AutoModelForCausalLM, AutoTokenizer model AutoModelForCausalLM.from_pretrained(Qwen/Qwen2.5-7B-Instruct) tokenizer AutoTokenizer.from_pretrained(Qwen/Qwen2.5-7B-Instruct) trainer DPOTrainer( modelmodel, tokenizertokenizer, train_datasetpreference_dataset, # 需要自己构造 beta0.1, max_length1024, ) trainer.train()这里preference_dataset是关键它需要由你自行构造常见格式是prompt、chosen、rejected三个字段。整个流程中最花时间的往往不是训练本身而是构造干净、可靠的偏好对。4.4 阶段四强化学习闭环让 Agent 在交互中获得反馈并更新最后一个阶段是把前面所有内容串成一个闭环Agent 在环境中采取动作、获得奖励、更新策略、再行动如此循环。经典 RLHF 流程是“SFT - 奖励模型 - RL 策略优化”。奖励模型给任意输出打一个分数策略模型在这个分数的引导下持续更新。但这个流程成本高、实现复杂。看现在业界的轻量实践用规则奖励做强化学习是更现实的做法比如数学题答案和标准结果一致就给正奖励格式不满足就给负奖励。DeepSeek-R1 公开披露的思路里就是用格式奖励加答案正确性奖励来驱动推理能力的提升。一个最小强化学习交互循环可以抽象成下面这样for step in range(num_steps): action policy.generate(state) # 策略模型采样动作 reward env.compute_reward(action) # 规则或模型打分 memory.append((state, action, reward)) policy.update(memory) # 用 DPO / GRPO 等方式更新策略这个阶段的重点不是写复杂的算法而是理解三个组件的关系策略模型负责生成、环境负责反馈、更新算法负责把反馈转成参数变化。任何一个环节有偏差结果都会变得诡异最典型的就是 reward hacking——模型找到一种“奖励很高但实际很蠢”的输出直接把你辛苦设计的训练流程带偏。5. 实战搭一个最小的自我改进循环理论讲完下面给一个可以直接在本地跑起来的最小闭环。整个流程用“生成 - 验证 - 筛选 - 微调 - 迭代”五个步骤串联先小规模跑通再考虑放大。5.1 实验设计选一个带标准答案的任务数学推理是最合适的因为验证信号可以写成规则而不是再请一个模型打分。这里用 GSM8K 数据集的部分样本作为示例目的是演示流程你可以换成任何带标准答案的私有数据集。具体步骤准备带标准答案的测试问题。用基础模型对每个问题采样 8 个候选答案。用规则验证候选答案是否正确。构造偏好对正确候选作为 chosen错误候选作为 rejected。用 DPO 微调原模型。在固定评估集上重测效果。把微调后的模型当成新的基础模型继续迭代。5.2 候选生成与验证下面的代码用 vLLM 做批量生成用规则抽取最终答案并对比标准答案import random from datasets import load_dataset from vllm import LLM, SamplingParams # 示例数据GSM8K 前300条 dataset load_dataset(openai/gsm8k, main, splittrain[:300]) model LLM(modelQwen/Qwen2.5-7B-Instruct, tensor_parallel_size1) sampling SamplingParams(temperature0.8, max_tokens1024) def get_answer(text: str) - str: # 只取最后一行作为最终答案具体抽法按任务调整 return text.strip().splitlines()[-1] def verify(pred: str, gold: str) - bool: return pred.replace(,, ).strip() gold.replace(,, ).strip() chosen, rejected, prompts [], [], [] for item in dataset.select(range(64)): prompt item[question] outputs model.generate([prompt] * 8, sampling) cands [o.outputs[0].text for o in outputs] ok [c for c in cands if verify(get_answer(c), item[answer])] bad [c for c in cands if not verify(get_answer(c), item[answer])] if ok and bad: prompts.append(prompt) chosen.append(ok[0]) rejected.append(bad[0])这里有几个容易踩的坑。第一GSM8K 的答案里有逗号直接对比会误判所以先去掉逗号再比。第二模型输出可能包含大量解释文字抽取最终答案的策略要提前看几批结果确认稳定。第三候选全对或者全错的样本要丢掉无法构成偏好对。5.3 构造偏好数据集并微调把上一阶段得到的chosen和rejected组成 DPO 数据集from datasets import Dataset dpo_data Dataset.from_dict({ prompt: prompts, chosen: chosen, rejected: rejected, }) dpo_data.save_to_disk(./data/dpo_example)然后跑 DPO 训练。先用默认参数跑一轮预览确认数据格式没问题再正式调参。LoRA 可以有效降低显存占用配置如下from peft import LoraConfig from trl import DPOTrainer from transformers import AutoModelForCausalLM, AutoTokenizer model AutoModelForCausalLM.from_pretrained(Qwen/Qwen2.5-7B-Instruct) tokenizer AutoTokenizer.from_pretrained(Qwen/Qwen2.5-7B-Instruct) lora_config LoraConfig( r16, lora_alpha32, target_modules[q_proj, k_proj, v_proj, o_proj], lora_dropout0.05, ) trainer DPOTrainer( modelmodel, ref_modelNone, tokenizertokenizer, train_datasetdpo_data, argstraining_args, peft_configlora_config, beta0.1, ) trainer.train() trainer.save_model(./models/dpo_experiment_v1)5.4 评估与迭代微调完不要只看 loss要回到固定的评估集上重新测。评估集不能和构造偏好对的数据重合否则测出来的是记忆不是泛化。可以记录以下几个指标正确答案比例提升多少。生成长度是否异常变短或变长。是否出现模型通过“偷懒格式”获得奖励的情况例如只输出答案不输出推理过程。一轮实验跑完把效果合格的模型作为下一轮的基础模型。这样就是一个完整的自我改进循环搜索或采样生成数据 - 验证 - 偏好优化 - 评估 - 再采样。课程里讨论的“自我改进”本质上就是这条链路的不断迭代。这里有两点得说清楚。第一用公开数据集做实验没问题但如果是商业项目数据授权是第一关。第二实验中可能不止精度提升也可以观察输出分布变化比如模型是否更爱输出结构化推理。最终判断标准应该来自你的实际业务场景而不是单一测试集。6. 把自我改进循环工程化推理引擎、接口与批量任务课程实验可以只跑脚本但真实项目最终要落到“服务化”和“批量任务”上。自我改进循环里有两个高频工程环节批量采样候选、批量验证结果。6.1 用 vLLM 启动本地推理服务本地批量生成场景下vLLM 是性价比较高的选择。支持 OpenAI 兼容接口也支持连续批处理可以对并发采样做更好的资源利用。vllm serve Qwen/Qwen2.5-7B-Instruct --port 8000启动后可以用 OpenAI SDK 直接访问本地接口from openai import OpenAI client OpenAI(base_urlhttp://127.0.0.1:8000/v1, api_keyEMPTY) resp client.chat.completions.create( modelQwen/Qwen2.5-7B-Instruct, messages[{role: user, content: 11?}], n4, ) for choice in resp.choices: print(choice.message.content)接口能跑通后就可以把验证、筛选、构造偏好数据这些逻辑接到这个接口上形成稳定的数据生产管线。6.2 批量任务队列与失败重试批量采样的关键不是“循环里调接口”而是“并发控制 失败重试 结果落盘”。一个稳定做法是把任务先写进队列再并发消费失败重试指数退避。import time from concurrent.futures import ThreadPoolExecutor def run_inference(task: dict) - dict: # 调用本地或远程接口返回生成结果 response client.chat.completions.create( modelQwen/Qwen2.5-7B-Instruct, messages[{role: user, content: task[prompt]}], n4, ) return {id: task[id], outputs: [c.message.content for c in response.choices]} def process_with_retry(task: dict, retries: int 3) - dict | None: for attempt in range(retries): try: return run_inference(task) except Exception as e: print(ftask {task[id]} failed: {e}, retry {attempt 1}) time.sleep(2 ** attempt) return None with ThreadPoolExecutor(max_workers8) as pool: results list(pool.map(process_with_retry, task_list))工程上还有一些细节值得注意每条结果要带 task id方便失败后定位输出结果要按批次落盘避免中途断掉丢失全部进度验证器在并发场景下要保证可重入、无状态。7. 资源占用与性能观察自我改进实验的资源消耗差异很大推理阶段和训练阶段要分开看。推理阶段主要观察 GPU 显存、吞吐和延迟。用 vLLM 做推理时max_model_len、并发数、采样温度都会影响资源占用。候选数量和 batch size 越大显存压力越大但吞吐不一定线性变化需要实测才能找到当前硬件条件下收益最高的并发数。观察命令可以一直挂着watch -n 1 nvidia-smi训练阶段普通消费级显卡建议从 7B 以下模型开始配合 LoRA 或 QLoRA 控制显存。如果需要进一步压缩可以打开 gradient checkpointing、降低 batch size、使用 4bit 量化加载基础模型。需要注意“能跑起来”和“稳定训练”是两回事量化会带来一定的精度损失需要实验验证。降低资源占用的通用手段按优先级排先用更小的模型验证流程再逐步放大训练阶段优先 LoRA而不是全参数微调推理阶段优先并发控制和缓存而不是堆更多显卡。8. 常见问题与排查方法自我改进实验链路长问题往往不在单点而在多个环节的叠加。下面是按现象整理的排查表。问题现象可能原因排查方式解决思路GPU 显存不足模型过大、batch 过大、并发过高用 nvidia-smi 看实际占用降低 batch、开梯度检查点、用 4bit 量化、换更小模型微调后效果反而变差偏好对噪声大、过拟合、评估集太小对比训练前后固定评估集清洗数据、加评估集、早停、降低学习率候选答案全是错的基础模型能力不足、提示词不够明确人工抽样看输出换更强模型、增加采样轮数、优化提示词API 调用频繁报错触发限流、服务不稳定查看状态码和错误日志指数退避重试、控制并发、本地缓存推理速度很慢模型太大、并发排队、未用批量推理看延迟和吞吐指标上 vLLM、减小 max_model_len、限制并发训练不收敛学习率过高、偏好对冲突观察 loss 和 reward 曲线降低学习率、清洗偏好对、换 DPO 参数 beta出现 reward hacking奖励规则有漏洞检查高奖励样本的内容增加格式约束、使用更强验证器、人工复核端口被占用本地 vLLM 或其他服务占了 8000netstat / lsof 查端口换端口启动课程资料访问受限网络或平台访问问题确认官方发布渠道以官方渠道为准不要使用来路不明的二次分发最容易翻车的三个点偏好数据质量不过关导致 DPO 越训越差、评估集和训练数据重叠导致“假提升”、奖励规则有漏洞导致模型学会刷分。这三个问题都可以通过在流程里加入人工抽检和固定评估集来缓解。9. 最佳实践与使用建议把 CS329A 的路线落地到实际项目有几点工程建议值得固化下来。第一先跑最小闭环再优化配方。第一次做自我改进实验不要一上来就堆大模型、大数据。用 64 条样本、8 个候选、跑一轮 DPO先把整条链路打通再逐步扩大数据规模。第二始终保留一套固定评估集。评估集不参与训练不参与偏好对构造。每次实验都跑同一套评估才能对比不同配置的真实差异。第三模型、数据、日志分目录管理。建议按data/、models/、logs/、scripts/分目录存放每个实验结果带上时间戳和配置说明。RL 实验的状态非常容易混乱没有日志就无法复盘。第四批量任务要具备断点续跑能力。候选生成、验证、偏好构造都可能有偶发失败。任务落盘、带上 task id、失败重试这些基础功夫比模型算法更能决定实验效率。第五数据与合规检查要前置。使用任何公开数据集、API 生成数据、他人版权内容做训练都要先确认授权范围。涉及人脸、声音、私密信息的数据不经过脱敏和授权确认不能进入实验流程。接口服务如果开放到局域网或公网务必加访问控制防止被滥用。第六对“自我改进”的边界保持清醒。强化学习能提升的能力上限受限于验证信号的质量。如果验证器本身判不准模型只会朝着错误方向越走越远。投入资源之前先确认你的奖励信号可靠。10. 总结与下一步CS329A 最值得尝试的点是它把推理、搜索、强化学习统一进了一个循环生成 - 评估 - 优化。这和单纯刷榜或者套框架是完全不同的思路学到的是可迁移的Agent训练方法论。接触这门课最先应该验证的是 4.1 节的候选多样性实验。它成本最低也最直观你会亲眼看到同一个模型、同一个问题在不同采样条件下输出有多不稳定。理解了这一点自然就会明白为什么需要搜索、需要训练信号。最容易踩的坑是 reward hacking 和评估集污染这两点几乎是所有自我改进实验的共性风险。如果刚开始跑 DPO 发现效果不升反降先检查偏好对质量再怀疑训练参数。下一步的扩展方向可以分几步走先把课程里的推理和搜索模块吃透接着在数学或代码任务上复现一轮 DPO 实验然后尝试 GRPO 或规则奖励做强化学习最后把实验闭环接到真实业务环境里做灰度验证。如果对多智能体协作感兴趣还可以在这个基础上继续关注“多个自改进 Agent 如何通过外部信号互相校准”的方向但前提是先把单 Agent 的自改进链路走通。