热门搜索:和平精英 原神 街篮2 

您的位置:首页 > > 教程攻略 > ai资讯 >告别提示工程,未来属于DSPy(下)

告别提示工程,未来属于DSPy(下)

来源:互联网 更新时间:2026-08-26 13:51

介绍DSPy框架的核心概念、编程模型、编译器功能,并通过一个简单示例展示其应用方式。话不多说,直接进入正题。

告别提示工程,未来属于DSPy(下)

2.3 提词器:自动化提示优化DSPy程序

提词器在DSPy里扮演着优化器的角色——它利用特定的性能指标来优化DSPy程序模块的提示,并与编译器协同工作,从而提升程序执行的效率和效果。简单说,就是让提示自动变得更好。

举个简单的例子,BootstrapFewShot是入门级提词器:

from dspy.teleprompt import BootstrapFewShot

teleprompter = BootstrapFewShot(metric=dspy.evaluate.answer_exact_match)

目前DSPy支持五种提词器,各有侧重:

  • dspy.LabeledFewShot:定义预测器使用k个样本的数量。
  • dspy.BootstrapFewShot:引导式启动,像搭积木一样逐步构建。
  • dspy.BootstrapFewShotWithRandomSearch:在BootstrapFewShot基础上加入随机搜索,探索更多可能。
  • dspy.BootstrapFinetune:专门用于编译过程中的微调,适合需要精细调优的场景。
  • dspy.Ensemble:把多个程序集成起来,统一不同输出为单一结果,类似于投票机制。

不同提词器在优化成本与质量之间各有取舍,选对工具往往事半功倍。

3 DSPy编译器

DSPy编译器会在内部跟踪你的程序,然后使用提词器(优化器)进行优化,从而提升程序性能。这一优化过程会根据你选用的语言模型规模和特性来动态调整:

  • 对于大型语言模型(LLMs),编译器会构建少量但高质量的示例提示。
  • 对于规模较小的语言模型,则会自动进行微调训练。

换句话说,编译器能智能地将程序模块与优质的提示、微调、推理和增强策略相匹配。后台它会模拟程序在不同输入下的各种运行版本,通过引导式学习不断自我完善,最终适应你的特定任务。这个过程,跟训练神经网络其实有几分神似。

前面创建的ChainOfThought模块虽然给语言模型提供了一个不错的起点,但往往并非最佳提示。正如以下图像所示,DSPy编译器可以优化初始提示,省去手动调整提示的繁琐步骤——这才是它真正的价值所在。

编译器需要以下输入:

  • 程序
  • 提词器(包括定义的验证指标)
  • 一些训练样本
from dspy.teleprompt import BootstrapFewShot

# 带有问题和答案对的小型训练集
trainset = [dspy.Example(question="What were the two main things the author worked on before college?", 
                         answer="Writing and programming").with_inputs('question'),
            dspy.Example(question="What kind of writing did the author do before college?", 
                         answer="Short stories").with_inputs('question'),
            ...
            ]

# 提词器将引导缺失的标签:推理链和检索上下文
teleprompter = BootstrapFewShot(metric=dspy.evaluate.answer_exact_match)

compiled_rag = teleprompter.compile(RAG(), trainset=trainset)

4 DSPy实践:构建简单的RAG流程

现在核心概念已经掌握,接下来动手构建第一个DSPy流程。检索增强生成(RAG)在生成式AI领域非常流行,用它作为起点再合适不过。

开始之前先安装DSPy:

pip install dspy-ai

步骤1:初始化设置

先配置好语言模型(LM)和检索模型(RM)。

  • 语言模型(LM)

    :采用OpenAI的gpt-3.5-turbo,需要准备好API密钥。

  • 检索模型(RM)

    :使用Wea viate——一个开源向量数据库。我们用一些示例数据来初始化它。

数据来自LlamaIndex GitHub仓库(MIT许可)。当然,完全可以用自己的数据代替。

!mkdir -p 'data'
!wget 'https://raw.githubusercontent.com/run-llama/llama_index/main/docs/examples/data/paul_graham/paul_graham_essay.txt' -O 'data/paul_graham_essay.txt'

接下来将文档拆分成单独句子导入数据库。使用Wea viate嵌入式版本,免费且无需注册API密钥。

注意:导入时每个数据项必须包含名为"content"的属性,这是Wea viate检索的关键。

import wea viate
from wea viate.embedded import EmbeddedOptions
import re

# 以嵌入模式连接到 Wea viate 客户端
client = wea viate.Client(embedded_options=EmbeddedOptions(),
                             additional_headers={
                                "X-OpenAI-Api-Key": "sk-",
                             }
                         )

# 创建 Wea viate 模式
schema = {
   "classes": [
       {
           "class": "MyExampleIndex",
           "vectorizer": "text2vec-openai",
            "moduleConfig": {"text2vec-openai": {}},
           "properties": [{"name": "content", "dataType": ["text"]}]
       }      
   ]
}
    
client.schema.create(schema)

# 将文档分割为单个句子
chunks = []
with open("./data/paul_graham_essay.txt", 'r', encoding='utf-8') as file:
    text = file.read()
    sentences = re.split(r'(?

现在配置全局LM和RM:

import dspy
import openai
from dspy.retrieve.wea viate_rm import Wea viateRM

openai.api_key = "sk-"

lm = dspy.OpenAI(model="gpt-3.5-turbo")

rm = Wea viateRM("MyExampleIndex", 
                wea viate_client = client)

dspy.settings.configure(lm = lm, 
                        rm = rm)

步骤2:数据准备

接下来收集训练示例,这里手工注释了少量问答对:

trainset = [dspy.Example(question="What were the two main things the author worked on before college?", 
                          answer="Writing and programming").with_inputs('question'),
            dspy.Example(question="What kind of writing did the author do before college?", 
                          answer="Short stories").with_inputs('question'),
            dspy.Example(question="What was the first computer language the author learned?", 
                          answer="Fortran").with_inputs('question'),
            dspy.Example(question="What kind of computer did the author's father buy?", 
                          answer="TRS-80").with_inputs('question'),
            dspy.Example(question="What was the author's original plan for college?", 
                          answer="Study philosophy").with_inputs('question'),]

步骤3:构建DSPy程序

先定义签名GenerateAnswer,描述从问题到答案的转换:

class GenerateAnswer(dspy.Signature):
    """Answer questions with short factoid answers."""

    context = dspy.InputField(desc="may contain relevant facts")
    question = dspy.InputField()
    answer = dspy.OutputField(desc="often between 1 and 5 words")

然后编写自定义RAG类,继承自dspy.Module。在__init__()中声明模块,在forward()中描述信息流:

class RAG(dspy.Module):
    def __init__(self, num_passages=3):
        super().__init__()
        self.retrieve = dspy.Retrieve(k=num_passages)
        self.generate_answer = dspy.ChainOfThought(GenerateAnswer)
    
    def forward(self, question):
        context = self.retrieve(question).passages
        prediction = self.generate_answer(context=context, question=question)
        return dspy.Prediction(context=context, answer=prediction.answer)

步骤4:编译与优化

最后定义提词器并编译程序,这会更新ChainOfThought模块中使用的提示:

from dspy.teleprompt import BootstrapFewShot

teleprompter = BootstrapFewShot(metric=dspy.evaluate.answer_exact_match)

compiled_rag = teleprompter.compile(RAG(), trainset=trainset)

调用RAG流程:

pred = compiled_rag(question = "What programming language did the author learn in college?")

可以评估结果,并迭代优化,直到对性能满意为止。整个流程下来,提示工程那些繁琐的手工活,就交给DSPy去自动完成吧。

关于宇宙的好的网名有哪些
关于宇宙的好的网名有哪些

类型:角色扮演

大小:1

语言:简体中文

平台:互联网

游戏下载

热门手游

手机号码测吉凶
本站所有软件,都由网友上传,如有侵犯你的版权,请发邮件haolingcc@hotmail.com 联系删除。 版权所有 Copyright@2012-2013 haoling.cc