DSPy,让提示语工程师失业!

1,445 阅读5分钟

大模型技术还在快速发展,不得不让人感到惊叹。

前文提到提示语:《# 从 Prompt 到 RAG,从 RAG 到 DSPy》,这体现出当下的大模型提示语仍然脆弱,就像沙子构筑的城堡,很容易被用户瓦解,让用户崩溃。

本篇进一步来看看 DSPy,这个有可能改善这一困局的兵器~

DSPy:为提示语带来新的可能

你是否在使用大模型的时候遇到以下过这些烦恼?

  • 花了几个小时调整提示词,结果性能提升却微乎其微
  • 换了个模型,原本完美的提示词突然不管用了
  • 每个新任务都得重新设计提示链,感觉自己在重复造轮子

上述情况,DSPy 可能可以帮助你解决!

DSPy —— 编程,而非提示

DSPy 展开是 Declarative Self-improving Language Programs in Python,是斯坦福 NLP 研究人员推出的下一代开发框架。它的口号简单明了: “编程,而非提示”

试想一下,如果你能像写普通 Python 代码那样开发大模型应用,再也不用为设计完美提示而头疼,这就是 DSPy 的目的或者说是它的初衷。它的核心特点包括:

  • 模块化设计:将任务流程和提示分开,让代码更灵活、维护更方便

  • 智能优化器:自动调整LLM调用的提示,省下大量精力和时间

  • 一次编写,随处运行:DSPy会自动适应更换模型

“DSPy就像是大模型开发的瑞士军刀”

核心功能详解

如果模型开发是建造一座摩天大楼,传统方法就像是手工雕刻每一块砖。DSPy,则提供整个建筑工具包和预制模块。

image.png

1. Signatures:定义任务结构

在开发中,清晰地定义任务是关键。Signatures 为此而生,用一行代码就描述一个复杂的AI任务。例如,创建一个情感分析器:

python

classify = dspy.Predict('sentence -> sentiment')
result = classify(sentence="你太棒了!").sentiment
print(result)  # 输出: 'Positive'

这么简单! 对于更复杂的任务,也可以类似如下定义:

python

class QuestionAnswer(dspy.Signature):
 """根据给定的上下文回答问题。"""
 
 context = dspy.InputField()
 question = dspy.InputField()
 answer = dspy.OutputField()

这种方式不仅清楚地定义输入和输出,还为模型提供任务的上下文。如果为一个客服机器人设计问答系统,通过它可以轻松考虑背景知识,提高答案的准确性。

在设计Signature时,试着从函数式编程角度来思考。它知道什么(输入)?它给出什么(输出)?通过这样的思维方式能帮助你设计出更高效系统。

2. Modules:构建行为

如果 Signatures 是 AI 任务的蓝图,那 Modules 就是实现这些蓝图的积木。

Modules 封装常见的推理模式,让开发者可以像玩乐高一样组合出复杂的行为。例如,让 AI 像人一样思考?DSPy 是这样做的:

python

question = "为什么天空是蓝色的?"
thinker = dspy.ChainOfThought('question -> answer', n=3)
response = thinker(question=question)
print(response.answer)

这个例子使用思维链(Chain of Thought)模式,让AI给出答案同时展示推理过程。

image.png

这只是 DSPy 强大功能的冰山一角。DSPy还提供了丰富的内置Modules,如:

  • dspy.ReAct:结合推理和行动,适合需要与外部环境交互的任务。
  • dspy.MultiChainComparison:生成多个答案并比较,选出最佳结果。

你还可以创建自己的模块:

python

class FactCheckingQA(dspy.Module):
    def __init__(self):
        super().__init__()
        self.retrieve = dspy.Retrieve(k=3)
        self.generate = dspy.ChainOfThought("context, question -> answer, explanation")
        self.validate = dspy.Predict("context, question, answer, explanation -> is_valid, confidence")

    def forward(self, question):
        context = self.retrieve(question)
        answer, explanation = self.generate(context=context, question=question)
        is_valid, confidence = self.validate(context=context, question=question, answer=answer, explanation=explanation)
        return answer, is_valid, confidence

fact_checker = FactCheckingQA()

上述,通过组合多个Modules,构建一个完整的事实核查系统。它会先检索相关信息,然后生成答案和解释,最后验证结果的有效性。

模块化设计让代码更易读、更易维护,同时也更方便重用。

3. Optimizers:自动优化AI提示

有了蓝图 Signatures 和积木 Modules,接下来就是Optimizers 上场了,它能确保高效运作。DSPy 的 Optimizer 就相当于给 AI 配了一个私人教练,帮助优化提示,提高系统性能。

开发者不再需要手动调整提示,让 Optimizer 完成这项工作:

python

from dspy.teleprompt import BootstrapFewShotWithRandomSearch
optimizer = BootstrapFewShotWithRandomSearch(metric=your_metric)
super_qa = optimizer.compile(your_qa_module, trainset=your_data)

通过这段代码,Optimizer 会:根据任务自动生成高质量的示例、尝试不同的提示组合,找到最佳方案、根据定义的指标评估每个方案的效果、随着数据增加,自动调整和优化。

选择合适的 Optimizer 也是一门艺术。DSPy 提供多种 Optimizer,每个适用于不同的场景:

  • LabeledFewShot:适用于少量高质量标注数据的情况。
  • BootstrapFewShot:适合数据非常少(如10个样本)的情况。
  • MIPRO:适用于大型数据集(300+样本),可以优化多个指令提示。

刚开始时,可以先使用BootstrapFewShotWithRandomSearch作为通用选择,等对任务和数据有更深入的理解后,再考虑切换到更专业的 Optimizer。

DSPy:不仅是一个框架,更是一种思维方式

DSPy 不再是被提示词牵着走,而是一个真正的应用架构师。这是一种思路: 聚焦设计整体系统架构,而不是纠结单一提示;轻松应对模型和数据的变化,确保系统稳定运行;借助自动化优化,不断提升系统性能。

DSPy 是不是意味着“提示工程师”这个职位将会消失? —— 我认为,应该是的。