DSPy 用 Signature 描述输入输出契约,再由 Module 承载推理策略,将提示词从脆弱的长字符串改造成结构化、可替换的程序接口。该抽象能降低更换模型时的隐性行为漂移,并提升 LLM 应用的可维护性。
你调用 car.start() 时,并不关心底层运行的是 V8 发动机还是电动机。这就是抽象:稳定的接口,可替换的实现。
Prompt engineering 通常跳过了这一层。大多数 prompt 都是一长串字符串,同时承担方法签名、方法体和配置文件的职责。更换模型后,昨天还能正常工作的字符串,今天可能悄无声息地失效。没有报错,没有警告,只是答案出现了一点不易察觉的偏差。
斯坦福推出的框架 DSPy,将 OOP 风格的结构应用到了这个问题上。下面来看看它是如何工作的。

在 DSPy 中,你不需要编写 prompt,而是编写一个 Signature:一份完全不包含具体措辞的输入/输出契约。
class GenerateAnswer(dspy.Signature):
"""Answer questions based on the given context."""
context = dspy.InputField()
question = dspy.InputField()
answer = dspy.OutputField()
这就是接口:给定上下文和一个问题,生成答案。它读起来就像方法签名:answer(context, question) -> answer。
然后,你可以为它挂载一种满足该契约的策略:
class RAG(dspy.Module):
def __init__(self):
self.generate = dspy.ChainOfThought(GenerateAnswer)
def forward(self, context, question):
return self.generate(context=context, question=question)
ChainOfThought 会在回答前进行推理。将它替换为 Predict,你就能得到直接答案,不显示推理过程,但 Signature 保持不变。调用方完全察觉不到变化。这与在同一个 Repository 接口背后,将 PostgresRepository 替换成 MySQLRepository 是同一种做法。
DSPy 正是在这里配得上“编译器”这个比喻。你向它提供带标签的示例和一个 metric(答案是否符合预期?),它就会搜索不同的 prompt 措辞和 few-shot 示例组合,为每种方案评分,并保留表现最好的版本。最终的 prompt 不需要你手写,而是由 DSPy 编译生成。
假设你针对 GPT-4 调优了一个 prompt,而且效果很好。当你切换到 Claude 时,这套调优过的措辞往往表现得更差,因为不同模型对不同表达方式的响应并不相同。通常,你需要从头开始手动重新调优。而使用 DSPy,Signature 始终保持不变。你只需针对新模型重新编译,optimizer 就会重新构建一套适合该模型的 prompt。更换模型后,契约仍然有效,只有实现会被重新构建。

假设你的 Signature 是 summarize(document) -> summary,metric 会检查摘要是否提到了源文档中的每一个命名实体。
使用二十份带标签的文档运行 optimizer。它可能首先尝试一条 zero-shot 指令并进行评分;接着尝试加入两个 few-shot 示例,再次评分;然后尝试一个 chain-of-thought 变体,在生成摘要前先列出实体。无论哪个版本在实体覆盖率上的得分最高,它都会成为最终编译生成的 prompt。你从未改动具体措辞,真正调整的是 metric 和示例。
下个月,将底层模型从 GPT-4 切换到 Claude 时,你只需针对相同的二十个示例和相同的 metric,重新运行同一个编译步骤。Signature summarize(document) -> summary 始终不变,变化的只有底层的实现方案。
如果你使用过 Spring Boot 或任何强类型后端,那么看到这种对应关系时,应该会觉得非常熟悉。Signature 就是方法接口,Module 是它的一种实现。optimizer 则取代了过去通过反复试错进行 prompt engineering 的人,让这个过程变得自动化且可度量。
可以先从一个你已经在手动处理的任务入手,为它定义一个 Signature,比如基于文档回答问题、分类或信息提取。在完全不添加任何 prompt 文本的情况下,写出输入字段和输出字段。先挂载 dspy.Predict,再换成 dspy.ChainOfThought,比较两者的效果。然后添加十个带标签的示例和一个简单的 metric,运行 BootstrapFewShot,看看它会生成什么。这是观察接口与实现分离如何落地的最快方式,而不是只停留在纸面概念上。
DSPy 确实需要训练集和用于编译的 metric,因此,与完全开放式的生成任务相比,它更适合答案可以检查的任务。开始使用前值得了解这一点,但这并不是避开它的理由。
Prasad MK 长期撰写有关分布式系统、API 治理以及现代 AI 工具底层架构的文章。
如需采取进一步措施,你可以考虑屏蔽此人和/或举报滥用行为。