0Pricing
AI Prompt Engineering · 课时

编译与优化提示词

实际使用 BootstrapFewShot、MIPRO 及其他 DSPy 优化器。

编译与优化提示词 是 CoddyKit 上的免费 AI Prompt Engineering 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 AI Prompt Engineering 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 AI Prompt Engineering 课程共包含 4 节课。

DSPy 中的优化意味着什么

DSPy 的优化(称为编译)会根据训练集和指标,为您的程序找出最佳提示词配置。优化器会在可能的少样本示例、指令和推理示例中进行搜索。

您只需运行一次编译,保存结果,然后部署优化后的程序。推理时只需进行快速的 LLM 调用,不再产生优化开销。

定义指标函数

每个 DSPy 优化器都需要一个指标函数,用于根据预期输出为预测结果评分。它返回一个数值(或布尔值),数值越高越好。

指标是优化器用来判断某个提示词配置是否良好的信号。

# Metric: exact match on answer field
def exact_match_metric(example, prediction, trace=None):
    """
    example: a training example with .answer
    prediction: the module's output with .answer
    Returns 1.0 if correct, 0.0 otherwise
    """
    expected = example.answer.strip().lower()
    predicted = prediction.answer.strip().lower()
    return float(expected == predicted)

# Metric: F1 score for token overlap (common in QA)
def token_f1_metric(example, prediction, trace=None):
    gold_tokens = set(example.answer.lower().split())
    pred_tokens = set(prediction.answer.lower().split())
    if not pred_tokens:
        return 0.0
    precision = len(gold_tokens & pred_tokens) / len(pred_tokens)
    recall = len(gold_tokens & pred_tokens) / len(gold_tokens)
    if precision + recall == 0:
        return 0.0
    return 2 * precision * recall / (precision + recall)

准备训练集

DSPy 需要由 dspy.Example 对象组成的训练集。每个示例都会指定输入和预期输出。对于 BootstrapFewShot,通常 20–50 个示例就足够了。

import dspy

# Build training examples
trainset = [
    dspy.Example(
        question='What is the capital of Germany?',
        answer='Berlin'
    ).with_inputs('question'),

    dspy.Example(
        question='Who wrote Romeo and Juliet?',
        answer='William Shakespeare'
    ).with_inputs('question'),

    dspy.Example(
        question='What year did World War II end?',
        answer='1945'
    ).with_inputs('question'),
    # ... add more examples
]

print(f'Training set size: {len(trainset)} examples')
print(trainset[0].question, '->', trainset[0].answer)

BootstrapFewShot 优化器

BootstrapFewShot 是最常用的 DSPy 优化器。它会在训练集上运行您的程序,收集成功的轨迹(指标判定通过的输入-输出对),并将这些轨迹用作编译后提示词中的少样本示例。

import dspy
from dspy.teleprompt import BootstrapFewShot

# Define your program
class QA(dspy.Signature):
    """Answer factual questions."""
    question: str = dspy.InputField()
    answer: str = dspy.OutputField()

program = dspy.ChainOfThought(QA)

# Set up the optimizer
optimizer = BootstrapFewShot(
    metric=exact_match_metric,
    max_bootstrapped_demos=4,   # Up to 4 few-shot examples per predictor
    max_labeled_demos=4,        # Use labeled examples directly if available
)

# Compile!
compiled_program = optimizer.compile(program, trainset=trainset)
print('Compilation complete')

MIPRO 优化器

MIPRO(多提示词指令提议与优化)是一种更强大的优化器。它不仅会选择少样本示例,还会搜索要包含在提示词中的更佳指令文本。

MIPRO 在编译期间需要进行更多 LLM 调用,但通常能实现显著更高的准确率。

import dspy
from dspy.teleprompt import MIPROv2

class QA(dspy.Signature):
    """Answer factual questions."""
    question: str = dspy.InputField()
    answer: str = dspy.OutputField()

program = dspy.ChainOfThought(QA)

# MIPRO: optimizes both instructions AND few-shot examples
optimizer = MIPROv2(
    metric=exact_match_metric,
    auto='medium',      # 'light' / 'medium' / 'heavy' for optimization budget
    num_threads=4,      # Parallel evaluation threads
)

compiled_program = optimizer.compile(
    program,
    trainset=trainset,
    num_trials=20,       # Number of candidate prompts to evaluate
)
print('MIPRO compilation complete')

编译后的提示词是什么样的

编译后,DSPy 会将优化后的少样本示例嵌入提示词。您可以检查编译后程序的预测器来查看这些内容。

import dspy

# After compiling, inspect the optimized state
compiled_program = dspy.ChainOfThought('question -> answer')
# (Assume this was returned by optimizer.compile(...))

# Inspect the demos that were found
for demo in compiled_program.demos:
    print('Input:', demo.question)
    print('Reasoning:', demo.get('reasoning', 'N/A'))
    print('Answer:', demo.answer)
    print('---')

# Save the compiled state
compiled_program.save('compiled_qa_program.json')
print('Saved compiled program')

teleprompter.compile() 接口

所有 DSPy 优化器都共享相同的 compile() 接口。这种一致性意味着您可以更换优化器,而无需修改程序代码。

from dspy.teleprompt import BootstrapFewShot, MIPROv2, COPRO

# All optimizers use the same interface:
# compiled = optimizer.compile(program, trainset=trainset)

# BootstrapFewShot: fast, uses successful traces as demos
opt1 = BootstrapFewShot(metric=exact_match_metric)

# MIPRO: slower, optimizes instructions too
opt2 = MIPROv2(metric=exact_match_metric, auto='light')

# COPRO: coordinate descent over instruction proposals
opt3 = COPRO(metric=exact_match_metric, depth=3)

# Swap between them with one line change:
compiled = opt1.compile(program, trainset=trainset)
# or: compiled = opt2.compile(program, trainset=trainset)

BootstrapFewShotWithRandomSearch

BootstrapFewShotWithRandomSearch 会生成多个候选示例集,并在验证集上选择表现最佳的示例集,从而扩展 BootstrapFewShot 的功能。

这是一个很好的折中方案,兼具 BootstrapFewShot 的简单性和 MIPRO 的强大能力。

from dspy.teleprompt import BootstrapFewShotWithRandomSearch

# Split data into train and validation
trainset = examples[:40]
devset = examples[40:60]

optimizer = BootstrapFewShotWithRandomSearch(
    metric=exact_match_metric,
    max_bootstrapped_demos=4,
    num_candidate_programs=8,  # Try 8 different demo sets
    num_threads=4,
)

compiled_program = optimizer.compile(
    program,
    trainset=trainset,
    valset=devset,  # Picks the best program based on validation
)
print('Best program selected from 8 candidates')

编译成本注意事项

编译会进行额外的 LLM 调用,以生成和评估候选提示词。请相应地安排预算:

  • BootstrapFewShot:LLM 调用次数约为训练集大小的 1–2 倍
  • RandomSearch(8 个候选项):约为 8–10 倍
  • MIPRO 中等规模:约为 30–50 倍

请离线运行编译,保存结果,然后部署已保存的程序。生产环境中的推理成本不会改变。

验证编译后的程序

编译后,请始终在留出的测试集上进行评估,以确认优化后的程序确实能够泛化。不要只检查训练集上的表现。

import dspy

# Evaluate on test set
evaluate = dspy.Evaluate(
    devset=testset,
    metric=exact_match_metric,
    num_threads=4,
    display_progress=True,
)

# Compare uncompiled vs compiled
uncompiled_score = evaluate(uncompiled_program)
compiled_score = evaluate(compiled_program)

print(f'Uncompiled accuracy: {uncompiled_score:.1%}')
print(f'Compiled accuracy:   {compiled_score:.1%}')
print(f'Improvement: +{compiled_score - uncompiled_score:.1%}')

整合起来

完整的 DSPy 优化流程是:定义 signature → 构建模块 → 准备训练数据 → 选择优化器 → 编译 → 评估 → 保存。这是从构想到可用于生产环境的优化提示词流水线的完整周期。

import dspy
from dspy.teleprompt import BootstrapFewShot

# 1. Configure LM
dspy.configure(lm=dspy.LM('openai/gpt-4o-mini', api_key='sk-...'))

# 2. Define signature and module
class QA(dspy.Signature):
    """Answer questions accurately."""
    question: str = dspy.InputField()
    answer: str = dspy.OutputField()

program = dspy.ChainOfThought(QA)

# 3. Compile
optimizer = BootstrapFewShot(metric=exact_match_metric)
compiled = optimizer.compile(program, trainset=trainset)

# 4. Save
compiled.save('production_qa.json')
print('Production program ready')

知识检查:BootstrapFewShot

BootstrapFewShot 会使用训练集中的什么内容来改进编译后的提示词?

回顾:编译与优化

DSPy 优化使用指标函数和训练集搜索最佳提示词配置。BootstrapFewShot 从成功的轨迹中找出优质的少样本示例。MIPROv2 还会进一步搜索更佳的指令文本。所有优化器都共享 compile(program, trainset=...) 接口。编译是一次性的离线成本,请使用 program.save() 保存结果,然后部署优化后的程序,以便在推理时无需额外的优化开销。

常见问题解答

「编译与优化提示词」课时是免费的吗?

是的 — 「编译与优化提示词」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 AI Prompt Engineering 课程的其余内容,请升级到 CoddyKit PRO。 AI Prompt Engineering 课程共包含 4 节课。

「编译与优化提示词」这节课中我会学到什么?

实际使用 BootstrapFewShot、MIPRO 及其他 DSPy 优化器。 你通过在浏览器中直接运行的动手代码来练习 AI Prompt Engineering,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 AI Prompt Engineering 需要有经验吗?

无需任何先前经验。CoddyKit 上的 AI Prompt Engineering 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。

「编译与优化提示词」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 AI Prompt Engineering 课中编写并运行代码吗?

能。每节 AI Prompt Engineering 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. DSPy 框架简介
  2. 定义签名与模块
  3. 编译与优化提示词
  4. 评估 DSPy 流程
← 返回 AI Prompt Engineering