理念

  1. 把 prompt 当做可以通过学习,自动调参的神经网络参数
  2. prompt 在学习过程中,自动优化,而不是手动修改调整 prompt

关键概念

Modules: Structured and Declarative Natural-language modules

类似 pytorch 神经网络构建中的 Module

Module 例子:

数学例子

1
2
math = dspy.ChainOfThought("question -> answer: float") 
math(question="Two dice are tossed. What is the probability that the sum equals two?")

分类例子

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
from typing import Literal

class Classify(dspy.Signature):
    """Classify sentiment of a given sentence."""  # 解释 Signature 作用
    # 输出
    sentence: str = dspy.InputField() 

    # 输出
    sentiment: Literal["positive", "negative", "neutral"] = dspy.OutputField()
    confidence: float = dspy.OutputField()

classify = dspy.Predict(Classify)
classify(sentence="This book was super fun to read, though not the last chapter.")

多阶段例子 Multi-Stage PipeLines

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class Outline(dspy.Signature):
    """Outline a thorough overview of a topic."""

    topic: str = dspy.InputField()
    title: str = dspy.OutputField()
    sections: list[str] = dspy.OutputField()
    section_subheadings: dict[str, list[str]] = dspy.OutputField(desc="mapping from section headings to subheadings")

class DraftSection(dspy.Signature):
    """Draft a top-level section of an article."""

    topic: str = dspy.InputField()
    section_heading: str = dspy.InputField()
    section_subheadings: list[str] = dspy.InputField()
    content: str = dspy.OutputField(desc="markdown-formatted section")

class DraftArticle(dspy.Module):
    def __init__(self):
        self.build_outline = dspy.ChainOfThought(Outline)
        self.draft_section = dspy.ChainOfThought(DraftSection)

    def forward(self, topic):
        outline = self.build_outline(topic=topic)
        sections = []
        for heading, subheadings in outline.section_subheadings.items():
            section, subheadings = f"## {heading}", [f"### {subheading}" for subheading in subheadings]
            section = self.draft_section(topic=outline.title, section_heading=section, section_subheadings=subheadings)
            sections.append(section.content)
        return dspy.Prediction(title=outline.title, sections=sections)

draft_article = DraftArticle()
article = draft_article(topic="World Cup 2002")

Optimizers 优化器(优化方法)

参考:

合成 few shot 样本的优化

  • dspy.BootstrapRS 即 BootstrapFewShotWithRandomSearch

    • Bootstrap Few-Shot with Random Search

流程:

  1. 基线构建:

    • zero shot
    • 纯标签
    • 标准 BootstrapFewShot

prompt 指令优化

  • dspy.GEPA
  • dspy.MIPROv2

构建数据集优化

  • dspy.BootstrapFinetune

例子

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
import dspy
from dspy.datasets import HotPotQA

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

def search_wikipedia(query: str) -> list[str]:
    results = dspy.ColBERTv2(url="http://20.102.90.50:2017/wiki17_abstracts")(query, k=3)
    return [x["text"] for x in results]

trainset = [x.with_inputs('question') for x in HotPotQA(train_seed=2024, train_size=500).train]
react = dspy.ReAct("question -> answer", tools=[search_wikipedia])

tp = dspy.MIPROv2(metric=dspy.evaluate.answer_exact_match, auto="light", num_threads=24)
optimized_react = tp.compile(react, trainset=trainset)