DSPy 优化器 #

什么是优化器? #

优化器(Optimizer)是 DSPy 的核心创新之一,它可以自动优化模块的性能。通过提供训练数据,优化器可以自动生成最优的提示词、Few-shot 示例,甚至微调模型。

text
┌─────────────────────────────────────────────────────────────┐
│                    优化器的作用                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  传统方式:                                                  │
│  手写提示词 -> 测试 -> 调整 -> 再测试 -> ...                 │
│                                                             │
│  DSPy 优化器:                                               │
│  提供训练数据 -> 选择优化器 -> 自动编译 -> 最优模块          │
│                                                             │
│  优化器可以:                                                │
│  1. 自动生成 Few-shot 示例                                  │
│  2. 优化指令措辞                                            │
│  3. 选择最佳推理路径                                        │
│  4. 适应不同模型                                            │
│                                                             │
└─────────────────────────────────────────────────────────────┘

优化器概览 #

text
┌─────────────────────────────────────────────────────────────┐
│                    DSPy 优化器类型                           │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ BootstrapFewShot                                     │   │
│  │ 通过引导生成 Few-shot 示例                           │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ MIPRO                                                │   │
│  │ 多指令提示优化,优化指令和示例                        │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ BootstrapFinetune                                    │   │
│  │ 引导微调,生成训练数据微调模型                        │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ KNN                                                   │   │
│  │ K近邻示例选择,动态选择相似示例                       │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ Ensemble                                              │   │
│  │ 集成多个优化后的模块                                  │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
└─────────────────────────────────────────────────────────────┘

准备工作 #

创建训练数据 #

python
from dspy import Example

trainset = [
    Example(
        question="Python 的创始人是谁?",
        answer="Python 的创始人是 Guido van Rossum"
    ).with_inputs("question"),
    Example(
        question="JavaScript 的创始人是谁?",
        answer="JavaScript 的创始人是 Brendan Eich"
    ).with_inputs("question"),
    Example(
        question="Linux 的创始人是谁?",
        answer="Linux 的创始人是 Linus Torvalds"
    ).with_inputs("question"),
]

定义评估指标 #

python
def validate_answer(example, pred, trace=None):
    return example.answer.lower() == pred.answer.lower()

def semantic_match(example, pred, trace=None):
    from difflib import SequenceMatcher
    return SequenceMatcher(None, example.answer.lower(), pred.answer.lower()).ratio()

BootstrapFewShot #

BootstrapFewShot 是最常用的优化器,通过引导生成 Few-shot 示例。

基本用法 #

python
import dspy
from dspy.teleprompt import BootstrapFewShot

lm = dspy.LM('openai/gpt-4o-mini')
dspy.configure(lm=lm)

class QA(dspy.Signature):
    """回答问题"""
    question = dspy.InputField()
    answer = dspy.OutputField()

class SimpleQA(dspy.Module):
    def __init__(self):
        super().__init__()
        self.predict = dspy.Predict(QA)
    
    def forward(self, question):
        return self.predict(question=question)

optimizer = BootstrapFewShot(
    metric=validate_answer,
    max_bootstrapped_demos=4,
    max_labeled_demos=16
)

optimized_qa = optimizer.compile(SimpleQA(), trainset=trainset)

参数详解 #

python
optimizer = BootstrapFewShot(
    metric=validate_answer,
    max_bootstrapped_demos=4,
    max_labeled_demos=16,
    max_rounds=1,
    max_errors=10
)
text
┌─────────────────────────────────────────────────────────────┐
│                    BootstrapFewShot 参数                     │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  metric: 评估指标函数                                        │
│  - 用于判断输出是否正确                                     │
│  - 返回 True/False 或分数                                   │
│                                                             │
│  max_bootstrapped_demos: 最大引导示例数                     │
│  - 通过引导生成的示例数量                                   │
│  - 默认 4                                                   │
│                                                             │
│  max_labeled_demos: 最大标注示例数                          │
│  - 直接使用的训练集示例数量                                 │
│  - 默认 16                                                  │
│                                                             │
│  max_rounds: 最大优化轮数                                   │
│  - 优化迭代次数                                             │
│  - 默认 1                                                   │
│                                                             │
│  max_errors: 最大错误数                                     │
│  - 引导过程中允许的最大错误数                               │
│  - 默认 10                                                  │
│                                                             │
└─────────────────────────────────────────────────────────────┘

工作原理 #

text
┌─────────────────────────────────────────────────────────────┐
│                    BootstrapFewShot 工作流程                 │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  1. 初始化                                                  │
│     - 加载训练数据                                          │
│     - 准备模块                                              │
│                                                             │
│  2. 引导生成                                                │
│     - 对每个训练样本执行模块                                │
│     - 如果输出正确,保存为示例                              │
│     - 重复直到达到最大示例数                                │
│                                                             │
│  3. 编译模块                                                │
│     - 将生成的示例添加到模块                                │
│     - 作为 Few-shot 示例使用                                │
│                                                             │
│  4. 返回优化后的模块                                        │
│                                                             │
└─────────────────────────────────────────────────────────────┘

完整示例 #

python
import dspy
from dspy import Example
from dspy.teleprompt import BootstrapFewShot

lm = dspy.LM('openai/gpt-4o-mini')
dspy.configure(lm=lm)

class QA(dspy.Signature):
    """回答编程语言相关问题"""
    question = dspy.InputField()
    answer = dspy.OutputField()

class ProgrammingQA(dspy.Module):
    def __init__(self):
        super().__init__()
        self.predict = dspy.Predict(QA)
    
    def forward(self, question):
        return self.predict(question=question)

trainset = [
    Example(question="Python 是什么类型的语言?", answer="Python 是解释型、面向对象的编程语言").with_inputs("question"),
    Example(question="Java 的主要特点是什么?", answer="Java 是面向对象、跨平台、强类型的编程语言").with_inputs("question"),
    Example(question="JavaScript 用于什么?", answer="JavaScript 主要用于 Web 前端开发").with_inputs("question"),
    Example(question="Go 语言的特点?", answer="Go 是静态类型、编译型、并发支持强的语言").with_inputs("question"),
]

def validate_answer(example, pred, trace=None):
    return example.answer.lower() in pred.answer.lower()

optimizer = BootstrapFewShot(
    metric=validate_answer,
    max_bootstrapped_demos=3
)

optimized_qa = optimizer.compile(ProgrammingQA(), trainset=trainset)

result = optimized_qa(question="Rust 语言有什么特点?")
print(result.answer)

MIPRO #

MIPRO(Multi-Instruction Prompt Optimization)是一个更强大的优化器,可以同时优化指令和示例。

基本用法 #

python
import dspy
from dspy.teleprompt import MIPRO

lm = dspy.LM('openai/gpt-4o-mini')
dspy.configure(lm=lm)

optimizer = MIPRO(
    metric=validate_answer,
    num_threads=4,
    max_bootstrapped_demos=4,
    max_labeled_demos=16
)

optimized_module = optimizer.compile(
    my_module,
    trainset=trainset,
    valset=valset
)

参数详解 #

python
optimizer = MIPRO(
    metric=validate_answer,
    num_threads=4,
    max_bootstrapped_demos=4,
    max_labeled_demos=16,
    max_rounds=3,
    num_candidates=10,
    teacher_settings={}
)
text
┌─────────────────────────────────────────────────────────────┐
│                    MIPRO 参数                                │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  metric: 评估指标                                            │
│  num_threads: 并行线程数                                     │
│  max_bootstrapped_demos: 最大引导示例数                     │
│  max_labeled_demos: 最大标注示例数                          │
│  max_rounds: 最大优化轮数                                   │
│  num_candidates: 候选指令数量                               │
│  teacher_settings: 教师模型设置                             │
│                                                             │
│  MIPRO 特点:                                               │
│  - 优化指令措辞                                             │
│  - 优化示例选择                                             │
│  - 支持多轮优化                                             │
│  - 支持并行处理                                             │
│                                                             │
└─────────────────────────────────────────────────────────────┘

工作原理 #

text
┌─────────────────────────────────────────────────────────────┐
│                    MIPRO 工作流程                            │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  阶段 1: 引导                                               │
│  - 使用教师模型生成示例                                     │
│  - 收集成功的示例                                           │
│                                                             │
│  阶段 2: 指令生成                                           │
│  - 分析任务特点                                             │
│  - 生成多个候选指令                                         │
│                                                             │
│  阶段 3: 评估选择                                           │
│  - 在验证集上评估每个候选                                   │
│  - 选择最佳指令和示例组合                                   │
│                                                             │
│  阶段 4: 迭代优化                                           │
│  - 重复优化过程                                             │
│  - 直到达到最大轮数或收敛                                   │
│                                                             │
└─────────────────────────────────────────────────────────────┘

BootstrapFinetune #

BootstrapFinetune 生成训练数据来微调模型。

基本用法 #

python
import dspy
from dspy.teleprompt import BootstrapFinetune

lm = dspy.LM('openai/gpt-4o-mini')
dspy.configure(lm=lm)

optimizer = BootstrapFinetune(
    metric=validate_answer,
    max_bootstrapped_demos=100
)

optimized_module = optimizer.compile(
    my_module,
    trainset=trainset,
    target_model="gpt-3.5-turbo"
)

适用场景 #

text
┌─────────────────────────────────────────────────────────────┐
│                    BootstrapFinetune 适用场景                │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  适合:                                                     │
│  ✅ 有大量训练数据                                          │
│  ✅ 需要降低推理成本                                        │
│  ✅ 需要特定领域优化                                        │
│  ✅ 需要更快的响应速度                                      │
│                                                             │
│  不适合:                                                   │
│  ❌ 训练数据很少                                            │
│  ❌ 任务变化频繁                                            │
│  ❌ 没有微调资源                                            │
│                                                             │
└─────────────────────────────────────────────────────────────┘

KNN 优化器 #

KNN 优化器动态选择与当前输入最相似的示例。

基本用法 #

python
import dspy
from dspy.teleprompt import KNN

optimizer = KNN(
    k=3,
    trainset=trainset
)

optimized_module = optimizer.compile(my_module)

工作原理 #

text
┌─────────────────────────────────────────────────────────────┐
│                    KNN 优化器工作原理                        │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  1. 向量化:将所有训练样本转换为向量                        │
│                                                             │
│  2. 查询:对于新输入,计算与所有样本的相似度                │
│                                                             │
│  3. 选择:选择最相似的 k 个样本作为示例                     │
│                                                             │
│  4. 生成:使用选中的示例生成输出                            │
│                                                             │
│  优势:                                                     │
│  - 动态选择最相关的示例                                     │
│  - 适应不同类型的输入                                       │
│  - 不需要重新编译                                           │
│                                                             │
└─────────────────────────────────────────────────────────────┘

Ensemble 优化器 #

Ensemble 优化器组合多个优化后的模块。

基本用法 #

python
import dspy
from dspy.teleprompt import BootstrapFewShot, Ensemble

optimizer1 = BootstrapFewShot(metric=metric1, max_bootstrapped_demos=4)
optimizer2 = BootstrapFewShot(metric=metric2, max_bootstrapped_demos=4)

module1 = optimizer1.compile(MyModule(), trainset=trainset)
module2 = optimizer2.compile(MyModule(), trainset=trainset)

ensemble = Ensemble([module1, module2])
result = ensemble(question="测试问题")

优化器选择指南 #

text
┌─────────────────────────────────────────────────────────────┐
│                    优化器选择指南                            │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  BootstrapFewShot:                                         │
│  - 通用场景首选                                             │
│  - 中等规模训练数据                                         │
│  - 需要快速优化                                             │
│                                                             │
│  MIPRO:                                                    │
│  - 需要优化指令措辞                                         │
│  - 有充足的计算资源                                         │
│  - 追求最佳性能                                             │
│                                                             │
│  BootstrapFinetune:                                        │
│  - 大量训练数据                                             │
│  - 需要降低成本                                             │
│  - 特定领域优化                                             │
│                                                             │
│  KNN:                                                      │
│  - 多样化的输入类型                                         │
│  - 需要动态示例选择                                         │
│  - 训练数据分布均匀                                         │
│                                                             │
│  Ensemble:                                                 │
│  - 需要最稳定的结果                                         │
│  - 有多个优化版本                                           │
│  - 可以接受更高延迟                                         │
│                                                             │
└─────────────────────────────────────────────────────────────┘

评估优化效果 #

使用 Evaluate #

python
from dspy.evaluate import Evaluate

evaluator = Evaluate(
    devset=testset,
    metric=validate_answer,
    num_threads=4,
    display_progress=True,
    display_table=5
)

score_before = evaluator(original_module)
score_after = evaluator(optimized_module)

print(f"优化前: {score_before}")
print(f"优化后: {score_after}")

对比分析 #

python
def compare_modules(original, optimized, testset):
    results = []
    for example in testset:
        orig_result = original(question=example.question)
        opt_result = optimized(question=example.question)
        
        results.append({
            'question': example.question,
            'expected': example.answer,
            'original': orig_result.answer,
            'optimized': opt_result.answer
        })
    
    return results

保存和加载优化后的模块 #

保存 #

python
optimized_module.save("optimized_qa.json")

加载 #

python
loaded_module = MyModule()
loaded_module.load("optimized_qa.json")

自定义优化器 #

基本结构 #

python
from dspy.teleprompt import Teleprompter

class MyOptimizer(Teleprompter):
    def __init__(self, metric, **kwargs):
        self.metric = metric
        self.kwargs = kwargs
    
    def compile(self, student, *, teacher=None, trainset):
        optimized = student.deepcopy()
        
        for example in trainset:
            result = optimized(**example.inputs())
            if self.metric(example, result):
                pass
        
        return optimized

完整示例 #

python
from dspy.teleprompt import Teleprompter
import random

class RandomFewShot(Teleprompter):
    def __init__(self, metric, k=3):
        self.metric = metric
        self.k = k
    
    def compile(self, module, trainset):
        successful_examples = []
        
        for example in trainset:
            result = module(**example.inputs())
            if self.metric(example, result):
                successful_examples.append(example)
        
        demos = random.sample(
            successful_examples,
            min(self.k, len(successful_examples))
        )
        
        module.demos = demos
        return module

最佳实践 #

1. 数据质量 #

python
trainset = [
    Example(
        question="高质量的问题",
        answer="准确、详细的答案"
    ).with_inputs("question")
    for _ in range(100)
]

2. 指标设计 #

python
def good_metric(example, pred, trace=None):
    if trace:
        return detailed_check(example, pred)
    return quick_check(example, pred)

3. 渐进优化 #

python
optimizer1 = BootstrapFewShot(metric=metric, max_bootstrapped_demos=2)
module = optimizer1.compile(module, trainset=trainset)

optimizer2 = MIPRO(metric=metric, max_rounds=2)
module = optimizer2.compile(module, trainset=trainset, valset=valset)

下一步 #

现在你已经掌握了优化器的使用方法,接下来学习 检索器,了解如何构建 RAG 应用!

最后更新:2026-03-30