DSPy:AI的自动化提示工程框架

世界上有一种编程方式,你只需要告诉AI"我要什么",而不是"怎么说"。

📅 2026-04-19 🏷️ Agent开发 / Prompt Engineering / 自动化 ⏱️ 阅读约 8 分钟

凌晨2点47分,我对着屏幕上的第43版Prompt发呆。

"请帮我写一封邮件。注意:语气要专业但不过于正式,提到上次会面的要点,但不要显得太急迫……"

我觉得自己不是在写代码,而是在跟一个极其敏感的室友谈判——每个字、每个标点符号,他都能给你解读出三种意思。

然后我发现了DSPy。那一刻就像你发现了全自动洗碗机——而你之前一直在用手洗了三年的碗。

🤔 DSPy 到底是什么?

一句话版:DSPy 是斯坦福大学开发的框架,让你的AI程序自动优化Prompt,而不是让你手工一个个试。

比喻版:想象你开了一家餐厅。

  • 传统的Prompt Engineering = 你每天亲自去厨房试菜,盐放多了加水,水多了加面,面多了……你懂。
  • DSPy = 你雇了一个主厨(优化器),你只要告诉他"我想做一道不辣的川菜",他自己调配方、试味道、迭代,最后端给你成品。

DSPy 的核心理念是:把Prompt当成可编程的模块,把Prompt优化交给算法。

它由斯坦福NLP实验室开发(对,就是那个Stanford),全称 Demonstrate-Search-Predict。名字很长,但思想很简洁:

"与其纠结于Prompt的措辞,不如告诉框架你的任务目标,让它自己找出最优的Prompt。"

🏗️ DSPy 的三大核心概念

1. Signature(签名)—— 你要AI做什么

Signature 就像是你和AI签的"劳动合同"。你只需要声明输入和输出:

# 我要一个问答系统 qa = dspy.Signature("question -> answer") # 我要一个情感分析器 sentiment = dspy.Signature("sentence -> sentiment_label") # 我要一个邮件生成器 email = dspy.Signature("context, tone -> email_body")

看到了吗?你不需要写任何Prompt文本。就像你在点外卖——你只需要说"红烧肉,微辣,多放葱",不需要告诉厨师红烧肉怎么炒。

2. Module(模块)—— 怎么组织你的AI

Module 是 DSPy 的乐高积木。你可以把简单的模块拼成复杂的流程:

# 最简单的模块 predict = dspy.Predict(dspy.Signature("question -> answer")) # Chain-of-Thought 版(让AI先思考再回答) cot = dspy.ChainOfThought(dspy.Signature("question -> reasoning, answer")) # 多模块串联 class QASystem(dspy.Module): def __init__(self): self.retrieve = dspy.Retrieve(k=3) self.generate = dspy.ChainOfThought("context, question -> answer") def forward(self, question): context = self.retrieve(question).passages return self.generate(context=context, question=question)

妙趣比喻:Module就像你要组装的宜家家具。

  • Predict = 一块板子
  • ChainOfThought = 一块带螺丝孔的板子(多了思考环节)
  • ReAct = 一个抽屉组件(能思考+行动)
  • 你自己定义的 Module = 把所有零件拼成书柜

重点是:你可以专注于"书柜长什么样",而不是"螺丝怎么拧"。

3. Optimizer(优化器)—— 自动调参神器

这是DSPy的灵魂。Optimizer 会自动搜索最佳的Prompt和few-shot示例:

from dspy.teleprompt import BootstrapFewShot # 定义评估函数 def validate_answer(example, pred, trace=None): return pred.answer.lower() == example.answer.lower() # 自动优化! teleprompter = BootstrapFewShot(metric=validate_answer, max_bootstrapped_demos=4) optimized_qa = teleprompter.compile(qa, trainset=train_examples)

凌晨2点47分的我:对着第43版Prompt发呆,想着"是不是应该把'Please'换成'You must'……"

凌晨3点12分的我(用了DSPy后): optimizer已经试了100多种Prompt变体,找到了准确率最高的版本。

差距,就是这么残酷。

⚙️ DSPy 优化器家族

优化器 原理 适合场景
BootstrapFewShot 用模型自己生成few-shot示例 有少量训练数据,追求快速上线
MIPROv2 指令+示例联合搜索优化 中大规模数据集,效果最好
BootstrapFewShotWithRandomSearch 随机搜索+Bootstrap 比纯Bootstrap更稳定
COPRO 协同提示优化 多步骤Pipeline优化

🔄 DSPy vs 传统Prompt Engineering

对比维度 传统Prompt Engineering DSPy
编写方式 手动写Prompt文本 声明输入输出即可
调优方式 人肉试错、凭感觉 算法自动搜索
可复现性 "昨天好使今天不行" 保存优化结果,随时复现
换模型成本 全部重写 换个模型重新编译就行
规模化 一个一个Prompt调 批量优化多个模块
维护成本 模型更新 = 你的噩梦 重跑优化器 = 完事

💡 关键洞察:传统Prompt Engineering最大的问题是——你的Prompt是和特定模型绑定的。GPT-4调好的Prompt,换成Claude可能就崩了。DSPy的Prompt是自动生成的,换模型只需要重新编译,相当于给你的程序装了个"万能适配器"。

🛠️ OpenClaw 实战:用 DSPy 思想优化你的 Agent

你可能问了:"妙趣,DSPy是Python框架,跟我的OpenClaw有什么关系?"

好问题。DSPy的核心思想——声明式编程+自动优化——完全可以应用到OpenClaw的Agent开发中。

实战1:用声明式方式定义 OpenClaw Skill

与其在Skill里硬编码Prompt,不如采用DSPy的"签名"思路:

<skill name="qna"> <description>回答用户问题</description> <instruction> 你是一个专业的问答助手。 请根据上下文回答用户的问题。 如果不知道答案,请诚实地说不知道。 回答要简洁、准确、有条理。 ……(还有50行Prompt) </instruction> </skill> <skill name="qna-v2"> <description>回答用户问题</description> <signature> 输入:user_question, context 输出:reasoning(思考过程), answer(最终答案), confidence(置信度) </signature> <instruction> 基于给定的上下文,先进行推理,再给出答案。 使用Chain-of-Thought策略。 </instruction> </skill>

实战2:在 OpenClaw 中实现"自动优化"循环

# 用OpenClaw的cron定时执行"Skill效果评估+优化建议" # # 思路:每天凌晨自动评估昨天的Skill表现, # 生成优化建议,更新Skill配置 # # 具体步骤: # 1. 收集昨天Agent的执行日志 # 2. 评估每条Skill调用是否达标 # 3. 对不达标的Skill,分析失败模式 # 4. 生成新的Prompt变体建议 # 5. 自动更新SKILL.md文件 # # 这不就是DSPy Optimizer的手动版吗?😄

⚠️ 注意:DSPy目前是Python生态的框架,不能直接在OpenClaw中运行。但它的设计思想完全值得借鉴。特别是:

  • 把Prompt当成可测试、可迭代的代码
  • 定义清晰的输入输出签名
  • 用数据驱动Prompt优化(而不是靠感觉)
  • 模块化组合,而不是写一坨巨型Prompt

🎯 DSPy 的适用场景

✅ 适合用 DSPy 的场景

❌ 不太适合的场景

📝 DSPy 快速上手指南

# 1. 安装 pip install dspy-ai # 2. 配置LLM import dspy lm = dspy.LM('openai/gpt-4') dspy.configure(lm=lm) # 3. 定义任务 class QASignature(dspy.Signature): """根据上下文回答问题""" context: str = dspy.InputField(desc="参考上下文") question: str = dspy.InputField(desc="用户问题") answer: str = dspy.OutputField(desc="答案") # 4. 构建模块 class RAGModule(dspy.Module): def __init__(self): super().__init__() self.retrieve = dspy.Retrieve(k=3) self.generate = dspy.ChainOfThought(QASignature) def forward(self, question): context = self.retrieve(question).passages return self.generate(context=context, question=question) # 5. 编译优化 from dspy.teleprompt import BootstrapFewShot def metric(example, pred): # 你的评估逻辑 return 1.0 if answer_correct else 0.0 optimizer = BootstrapFewShot(metric=metric, max_labeled_demos=4) compiled = optimizer.compile(RAGModule(), trainset=training_data) # 6. 使用 result = compiled(question="什么是DSPy?") print(result.answer)

🌍 DSPy 生态圈

💭 妙趣感悟

凌晨3点15分,我关掉了那个写着"Prompt_v43_final_真的最终版_不再改了.py"的文件。

DSPy教会我一件事:在这个AI时代,最高效的Prompt Engineering,就是让别人帮你做Prompt Engineering。

这听起来像个悖论,但其实不然。

就像你不会去手动调优一个编译器的中间代码——你写高级语言,编译器帮你优化到机器码。

DSPy就是Prompt工程的"编译器"。

你的注意力应该放在"我想让AI做什么",而不是"我该怎么说才能让AI做对"。

世界上有一种编程方式,叫做"声明式"。你告诉系统目标,系统自己找路。DSPy把这个理念,带进了AI开发的世界。

至于那个43版Prompt……它教会我最重要的一课:

有时候,最聪明的优化,就是别自己优化。

🔗 延伸阅读