提示词工程(3): 别手写提示词了, DSPy时代, Prompt需要编译

by JeariCk 2 min read
提示词工程(3)

2026年还在手搓prompt的人,就像2022年还在手写SQL join的——能干活,但卷不过用框架的。

不是说手写prompt不对,而是当你的项目从”给ChatGPT问个问题”扩展到”要管20个prompt在不同模型上跑、还要保证输出质量不波动”的时候,纯手工操作已经撑不住了。

这时候DSPy来了。它不是又一个prompt模版工具。它是把提示词工程变成了编译问题。

提示词工程(3)
提示词工程(3)

提示词工程的进化

先画个时间线,帮你理解DSPy出现在哪个位置。

纯手工时代(2022-2024)

打开ChatGPT,打一句话,看结果。不行就改措辞,再试。反复试到满意为止。

当时这已经叫”工程”了。本质就是直觉加试错。

框架结构化时代(2024-2025)

COSTAR、RTF、CRISPE、RACE这些框架冒出来。它们告诉你:prompt应该按角色、任务、格式、约束这些维度来组织。

比纯手工强,至少有了骨架。但本质还是手动写,靠个人经验。

程序化优化时代(2025-2026)

DSPy就是这个时代的代表。核心变化:你不用写prompt了,你写的是程序逻辑,prompt由编译器自动生成并优化

如果说第一代是石器时代,第二代是青铜时代,第三代就是工业革命——从手工艺到流水线的跨越。


DSPy是什么

DSPy(Declarative Self-improving Python)是斯坦福NLP组搞的一个框架,核心思想简单粗暴:

你把”要干什么”定义好,DSPy帮你找到”怎么写prompt最有效”。

传统的prompt工作流是这样:

```

我要一个分类器 -> 我写prompt -> 测一下 -> 发现不准 -> 我改prompt -> 再测 ...

```

全程依赖你对模型的直觉。模型变了,prompt得重写。

DSPy的工作流是这样:

```

我要一个分类器 -> 定义输入输出签名 -> 给几个标注好的例子 -> 运行编译器 -> DSPy自动找到最优prompt

```

你的工作从”写prompt”变成了”定义任务边界”。模型换了?重新编译一次就行。

这个思路等于把提示词工程从写文案变成了写配置


四个核心概念

DSPy的体系不算复杂,四个东西搞懂就能上手。

Signatures(签名)

签名就是定义”输入是什么、输出是什么”。比Python的类型注解简单,但思路一样。

```python

# 定义:输入是一个问题和上下文,输出是一个答案

class AnswerQuestion(dspy.Signature):

    """回答问题,基于给定的上下文"""

    context = dspy.InputField(desc="相关信息来源")

    question = dspy.InputField(desc="用户提出的问题")

    answer = dspy.OutputField(desc="简洁准确的回答")

```

你不需要写”请基于以下上下文回答问题,回答要简洁准确,不要多余信息”。DSPy会根据这些签名描述,自己去生成并优化那段prompt。

Modules(模块)

模块是可组合的prompt组件。DSPy内置了几种:

– `dspy.Predict`:最简单的预测模块

– `dspy.ChainOfThought`:带思维链的预测

– `dspy.ReAct`:推理+行动的循环(Agent的基础)

– `dspy.ProgramOfThought`:用代码来推理

你组合它们就像搭积木:

```python

class QAProgram(dspy.Module):

    def __init__(self):

        self.qa = dspy.ChainOfThought(AnswerQuestion)

    def forward(self, context, question):

        return self.qa(context=context, question=question)

```

Metrics(指标)

怎么判断输出好不好?你得定义指标。DSPy不挑——可以用LLM来打分,可以用精确匹配,也可以用自定义函数。

```python

def qa_metric(gold, pred, trace=None):

    # gold是标准答案,pred是模型输出

    # 返回0到1之间的分数

    return dspy.evaluate.answer_exact_match(gold, pred)

```

Optimizers(优化器/编译器)

这是DSPy最值钱的部分。你定义好签名、模块和指标,优化器负责搜索最优的prompt策略。DSPy提供了多个优化器:

LabeledFewShot:从标注数据里挑few-shot示例

BootstrapFewShot:让模型自己生成few-shot示例,再挑最好的

BootstrapFewShotWithRandomSearch:多跑几次BootstrapFewShot,选最优

MIPROv2:同时优化指令文本和few-shot示例

GEPA:让大模型自己反思,分析什么prompt策略有效、什么无效,然后针对性改进

COPRO:基于坐标下降的指令优化

编译就像这样:

```python

from dspy.teleprompt import MIPROv2

teleprompter = MIPROv2(

    metric=qa_metric,

    num_candidates=10,  # 每轮生成10个候选

    init_temperature=1.0

)

optimized_program = teleprompter.compile(

    QAProgram(),

    trainset=training_examples,  # 你的标注数据

    num_trials=30,               # 编译30轮

    max_bootstrapped_demos=4,    # 最多4个动态示例

    max_labeled_demos=4          # 最多4个静态示例

)

```

跑完之后,`optimized_program` 在相同的签名下面,已经用最优的prompt配置替换了默认行为。


一个你看得懂的例子:分类任务

为了让你直观理解DSPy到底省了什么,来看个分类任务。

传统手写prompt:

```text

你是一个文本分类助手。你的任务是将给定的用户反馈分类到以下类别之一:

[bug, feature_request, question, other]

请严格只输出一个英文单词作为分类结果,不要额外说明。

用户反馈:[具体内容]

分类:

```

换个模型或者换个任务,你得重新试。更气人的是,有时候只是改了个标点符号,输出质量就不一样了。毫无工程可言。

DSPy版本:

```python

class FeedbackClassifier(dspy.Signature):

    """将用户反馈分类"""

    feedback = dspy.InputField(desc="用户反馈文本")

    category = dspy.OutputField(desc="分类结果: bug/feature_request/question/other")

classifier = dspy.ChainOfThought(FeedbackClassifier)

# 编译

optimized = teleprompter.compile(classifier, trainset=train_data)

# 使用

result = optimized(feedback="App crashes when I click submit")

print(result.category)

```

不用写prompt。不用试措辞。定义清楚就行。


不能忽视DSPy

跨模型迁移

这是DSPy最实用的能力。你今天用GPT-4o跑得很好的系统,明天换成Claude Sonnet,传统做法是全线重写一遍prompt。

DSPy做的事情是:重新编译一次。签名和数据不动,优化器自动为新模型找到最优prompt策略。

自动适应模型更新

模型提供商每个月都在更新。昨天能跑的prompt,今天可能就废了——不是prompt变了,是模型的内部行为漂移了。

DSPy的优化器可以定期重跑,自动适应模型漂移。这相当于给你的AI系统加了一层自适应巡航。

减少手工作业

一个中等复杂度的AI功能,手写prompt大概要试20-30个版本才能稳定。用DSPy,你主要花时间在定义好签名、准备标注数据、选好指标。剩下的编译器帮你搜。

可复现和可测试

手写prompt最大的痛是测不了,因为”好prompt”的标准是主观的。DSPy强迫你用代码定义指标,这就等于给prompt上了测试套件。


什么场景适合DSPy

说人话:不是所有场景都需要DSPy。

适合上DSPy的场景:

– 多步推理的任务(问答、代码生成、文档分析)

– 需要稳定输出格式的生产系统

– 要在多个模型上跑的同一条pipeline

– prompt数量超过5个,手动维护快疯了

不需要DSPy的场景:

– 就一个ChatGPT聊聊天,不需要自动化

– 一次性任务,用完即弃

– 你只是想让Claude帮你改个文案


DSPy不是银弹

DSPy不是万能药,有几个问题你得知道:

需要标注数据:优化器需要一些标注好的输入输出对。没有数据,编译器没法编。

编译有成本:MIPROv2跑30轮大概要花几美元到几十美元的API费用。但对比手动调prompt花的时间,这点成本可以忽略。

不适合简单任务:一个”请将文本翻译成英文”这种简单任务,DSPy不会比手写prompt好多少。

学习曲线:不写prompt写Python类,对非程序员有门槛。


和其他框架的对比

特点手写PromptLangChainDSPy
写什么 自然语言 链式调用 程序签名
优化方式 手动试 手动试 自动搜索
跨模型迁移 重写 微调 重编译
可测试 困难 一般 天生的
学习成本 中高

另一个经常被拿出来和DSPy比较的是TextGrad,它用梯度下降的思路来做prompt优化,类似反向传播。但DSPy的生态更成熟,文档和社区支持也更好。


如果你要开始

入门DSPy不需要很长时间:

1. `pip install dspy`(注意不是pypi上的`dsp`,那个早就废弃了)

2. 看官方文档 `dspy.ai`

3. 从最简单的签名定义开始试

4. 加一个你手头的分类或提取任务做实验

5. 感受一下”不用写prompt”的快乐

2026年的AI开发,拼的不再是谁的prompt写得更花哨。从”写文案”到”写程序”,这个转变决定了你是用AI的,还是被AI用的。

如果你还没试过DSPy,现在可以把它加进你的技能树了。


📖 推荐阅读

看看这些文章,你可能会感兴趣:

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注