本节摘要:Teleprompter(遥提示器)是 DSPy 优化器的直系祖先:v2.0 之前所有"把提示词调好"的自动化策略都挂在这个名字下。本节从它的命名隐喻讲起,还原早期 Teleprompter 家族的自举思想,并解释这次更名为什么被视为范式自我确认的标志事件。理解它,就理解了 DSPy 编译器设计的原始动机。
Teleprompter 本义是"提词器"——演讲者看不到讲稿时,提词器把要点递到他眼前。早期 DSPy 用这个词命名"指导语言模型如何完成任务"的策略集合:策略不直接替模型干活,而是在幕后把示范、指令、输出解析规则适时递给模型。这个隐喻的潜台词是:主导权仍在使用者的手上,策略只是放大手艺的工具。随着自举与联合搜索策略的成熟,社区意识到事情变了——策略不再只是"递要点",而是在目标函数的引导下自主探索提示词空间,这与深度学习里的"优化器"(optimizer)角色完全同构。于是 v2.0 把 dspy.teleprompt.* 整体更名为 dspy.teleprompt 命名空间下的 Optimizer 家族,旧类名陆续废弃。改名是范式自我确认:从"给人递词"到"替人搜索",责任主体换位了。
对读者的实际意义是阅读存量资料时的翻译能力:2023 年及更早的教程、论文、issue 里出现 Teleprompter 的地方,按 Optimizer 理解即可;一些概念(teleprompter.compile 之类调用形态)在两代之间只有命名差异,机制是一脉相承的。
早期 Teleprompter 家族贡献了 DSPy 编译思想的核心机制——自举(bootstrap)。它的逻辑可以用一句话概括:让程序自己跑训练集,跑得好的中间轨迹回收为示范。展开是三步:第一步,用当前(未优化的)程序对训练集逐条推理,记录每一步的完整轨迹;第二步,用指标逐条验收,答案不对的轨迹丢弃,对的保留;第三步,把保留下来的轨迹按签名拆开,变成各个预测器的少样本示范,注回程序。此时程序再跑同样的输入,提示词里已经带上了"自己产出的高质量范例"。
这个机制的巧妙之处在于它只需要极少的人工标注:人只提供"问题加最终答案",中间步骤的示范由程序自己生成、指标自己把关。手工时代"攒示例全凭直觉"的问题,被转化成了"用指标筛选自己的输出"。当然,自举不是万灵药——如果程序的零样本能力太弱,训练集上几乎跑不出合格轨迹,自举就没有原料;如果指标把关不严,错误轨迹混进示范集,模型会把错误模式一并学走。这两个边界条件在 4.4 节讲 BootstrapFewShot 时还会量化展开。
初代家族按"自动化程度"大致分三档,先看对比表再展开:
| 档位 | 代表策略 | 数据要求 | 机制要点 | 遗留问题 |
|---|---|---|---|---|
| 标注搬运 | 早期标注示范策略 | 需较多人工标注 | 按签名格式化后直接注入 | 无生成,上限低 |
| 自举路线 | 初版自举策略 | 几十条标注起步 | 自跑轨迹、指标过滤、回收示范 | 依赖零样本能力 |
| 搜索雏形 | 早期随机搜索策略 | 外加验证集 | 多候选生成、验证集择优 | 搜索无方向,开销大 |
最朴素的一档是标注搬运:直接把人工标注的问答对按签名格式化成示范,不加任何生成,适合数据充足、任务简单的场景,成本几乎为零。中间一档是上文的自举路线:程序自跑、指标过滤、回收示范,这是 DSPy 的招牌机制,后续几乎所有优化器都以它为地基。最激进的一档在自举之外叠加了搜索:生成多个候选程序(不同的示范组合、不同的措辞),在验证集上打分,保留最优者——这一档雏形后来演化成 BootstrapFewShotWithRandomSearch 与 MIPRO 系列,是第 4 章的主角。
初代自举策略的调用形态与今天几乎一致,只是类名带着旧命名:
# 早期命名下的编译调用(示意,类名以旧版资料为准) from dspy.teleprompt import BootstrapFewShot # 旧资料常写作 teleprompt 模块下的策略类 teleprompter = BootstrapFewShot(metric=my_metric, max_bootstrapped_demos=3) compiled = teleprompter.compile(my_program, trainset=my_trainset)
值得记录的一段弯路是早期版本里出现过的梯度式提示词优化尝试(把提示词当连续向量做梯度更新的思路)。这类方案最终没有成为主线——提示词是离散文本,梯度路径与最终解码行为之间隔着采样过程,优化信号失真严重。这段弯路反向印证了 DSPy 主线选择的正确:在离散文本空间里,"生成-评估-选择"的无梯度搜索比"伪梯度"更稳。这个判断后来被 MIPRO 系列的实测结果反复确认。
Teleprompter 这段历史常被新教程一笔带过,但它是理解 DSPy 演化逻辑的关键标本:它展示了"提示词自动化"如何从辅助工具(递要点)演化为自主系统(搜索与优化),也展示了框架如何用一次更名完成范式宣言。你在第 4 章会看到,后续所有编译器的进化——更大的搜索空间、更聪明的提案模型、更精细的预算控制——都是在初代家族奠定的"自举加搜索"骨架上添砖。命名会过时,骨架不会。
补一个阅读存量资料时的实操提醒:旧命名时代的代码样例,除了类名与模块路径需要翻译,编译调用的形态(compile 传入程序与训练集)、指标的签名约定、示范的字段结构都与今天一致。真正需要警惕的是旧资料里那些"当时的最佳实践"——比如早期流行过的把大量格式规则写进签名的做法,在今天的类型注解与断言机制下已有更好的归宿。读历史资料的正确姿势因此是分层:机制层照收(大多未变),实践层校对(多数已更新)。这也是演化视角读法的又一次兑现——知道每个设计从哪来,才知道它在今天该放哪去。