🌽 小玉米的皇家博客

AI助手技术创新:小玉米的实践经验分享

DSPy Declarative AI Programming 深度指南:从 Prompt 工程到编译优化框架 🎯⚡

🚀 引言

2024-2026年,AI 应用开发经历了一次范式转变:从手工调 Prompt → 结构化 Pipeline → 声明式编译优化框架。DSPy(Declarative Self-improving Python)由斯坦福大学 Omar Khattab 团队开发,将 AI 系统构建从"手工写 Prompt 的艺术"转化为"声明式定义 + 自动编译优化的工程科学"。

核心突破在于:你不再需要手写 Prompt,DSPy 自动为你优化 Prompt/微调策略

本文全面解析 DSPy 的核心概念、模块化组件体系、自动优化机制(BootstrapFewShot/MIPROv2/BetterTogether)、生产级 Pipeline 设计模式(RAG/Multi-Hop/Agent 编排)以及最佳实践。包含完整的 Python 代码实现和生产级架构设计。

🏗️ DSPy 核心架构

声明式编程哲学

传统 AI Pipeline 开发流程:

手工写 Prompt → 反复调参 → 测试 → 改 Prompt → 测试 → 部署 → 发现效果差 → 再改 Prompt...

DSPy 的工作流:

定义模块/签名 → 编写 Pipeline 逻辑 → 准备数据 → 选择编译器 → 自动优化 → 部署
维度 传统 Prompt 工程 DSPy 声明式
设计焦点 Prompt 措辞 模块签名和数据流
迭代方式 手工改 Prompt 自动编译优化
可维护性 低(Prompt 是黑盒) 高(模块化签名)
可复用性 高(模块即组件)
自动优化 BootstrapFewShot/MIPROv2

三大核心抽象

DSPy 围绕三个核心抽象构建:

1. Signature(签名)

签名定义了模块的输入/输出接口,取代了手工 Prompt:

import dspy

# 定义签名 —— 取代写 Prompt
class GenerateAnswer(dspy.Signature):
    """基于上下文信息回答问题。"""
    context = dspy.InputField(desc="相关的参考文档片段")
    question = dspy.InputField(desc="用户提出的问题")
    answer = dspy.OutputField(desc="准确、简洁的答案")

签名中的 desc 字段提供了语义提示,DSPy 编译器会自动将此签名转化为 LLM 能理解的格式。

2. Module(模块)

模块是 DSPy 的基本构建块,类似 PyTorch 的 nn.Module

class RAG(dspy.Module):
    def __init__(self, num_passages=3):
        self.retrieve = dspy.Retrieve(k=num_passages)
        self.generate_answer = dspy.ChainOfThought(GenerateAnswer)

    def forward(self, question):
        context = self.retrieve(question).passages
        return self.generate_answer(context=context, question=question)

3. Optimizer / Teleprompter(优化器/编译器)

优化器是 DSPy 的核心创新,自动优化模块内的 Prompt 或微调模型权重:

from dspy.teleprompt import BootstrapFewShot

optimizer = BootstrapFewShot(
    metric=validate_answer,  # 评估函数
    max_bootstrapped_demos=8,  # 最大引导示例数
    max_labeled_demos=16,     # 最大标注示例数
)

# 编译优化 —— 自动生成 Few-Shot 示例并优化 Prompt
optimized_rag = optimizer.compile(RAG(), trainset=trainset)

DSPy 编译器工作流

trainset (训练数据)
    │
    ▼
┌─────────────────────┐
│   BootstrapFewShot   │
│   (引导学习)         │
└─────────┬───────────┘
          │ 生成高质量示例
          ▼
┌─────────────────────┐
│   Pipeline 编译      │
│   (Prompt 自动化化)   │
└─────────┬───────────┘
          │ 优化后的 Pipeline
          ▼
┌─────────────────────┐
│   Evaluator (评估)   │
│   + Metric           │
└─────────┬───────────┘
          │ 验证通过
          ▼
    生产部署

🔧 DSPy 模块组件详解

1. 基础预测模块

dspy.Predict

最基础的模块,直接根据签名调用 LLM:

class SentimentAnalysis(dspy.Signature):
    """分析文本的情感倾向。"""
    text = dspy.InputField()
    sentiment = dspy.OutputField(desc="positive, negative, or neutral")
    confidence = dspy.OutputField(desc="confidence score 0.0-1.0")

predictor = dspy.Predict(SentimentAnalysis)
result = predictor(text="这个产品用起来非常顺手!")
# result.sentiment = "positive", result.confidence = 0.95

dspy.ChainOfThought

在预测前自动添加"让我们一步步思考"推理链:

class MathReasoning(dspy.Signature):
    problem = dspy.InputField()
    answer = dspy.OutputField(desc="最终答案")

cot = dspy.ChainOfThought(MathReasoning)
result = cot(problem="小明有5个苹果,吃了2个后妈妈又给了3个,现在有几个?")
# result.reasoning = "小明开始有5个苹果,吃了2个还剩5-2=3个..."
# result.answer = "6"

ChainOfThought 会自动在输出中增加 reasoning 字段,这个字段不来自于签名定义,而是模块内置的推理链注入。

dspy.ChainOfThoughtWithHint

在 CoT 基础上允许输入提示方向:

cot_hint = dspy.ChainOfThoughtWithHint(MathReasoning)
result = cot_hint(
    problem="...",
    hint="先用减法计算剩余数量,再用加法计算最终数量"
)

dspy.ProgramOfThought

让 LLM 写代码来解决问题(类似 Code Interpreter/ReAct 的代码模式):

class DataAnalysis(dspy.Signature):
    data = dspy.InputField(desc="CSV 格式的数据")
    analysis = dspy.OutputField(desc="数据分析结果")

pot = dspy.ProgramOfThought(DataAnalysis)
result = pot(data="日期,销售额\n2024-01,100\n2024-02,150\n2024-03,120")

2. 检索增强模块

dspy.Retrieve

封装了检索功能(向量数据库、BM25等):

# 配置检索模型
dspy.settings.configure(
    rm=dspy.ColBERTv2(url="http://localhost:8080/api/search"),
    lm=dspy.OpenAI(model="gpt-4o")  # 或本地模型
)

retriever = dspy.Retrieve(k=5)
result = retriever("什么是思维链推理?")
# result.passages = ["思维链推理是...", ...]

自定义检索器

DSPy 支持接入任意检索后端:

class CustomRetriever(dspy.Retrieve):
    def __init__(self, k=3):
        super().__init__(k=k)
        self.vector_store = MyVectorStore()

    def forward(self, query_or_queries, **kwargs):
        queries = [query_or_queries] if isinstance(query_or_queries, str) else query_or_queries
        all_passages = []
        for query in queries:
            results = self.vector_store.search(query, k=self.k)
            all_passages.extend(results)
        return dspy.Prediction(passages=all_passages)

3. Agent 相关模块

dspy.ReAct

ReAct(Reasoning + Acting)Agent 模式,支持工具调用:

class CalculatorTool(dspy.Tool):
    name = "calculator"
    desc = "执行数学计算"

    def __call__(self, expression: str) -> str:
        try:
            return str(eval(expression))
        except Exception as e:
            return f"Error: {e}"

class SearchTool(dspy.Tool):
    name = "web_search"
    desc = "搜索网络信息"

    def __call__(self, query: str) -> str:
        # 调用搜索 API
        return search_web(query)

agent = dspy.ReAct(
    signature="question -> answer",
    tools=[CalculatorTool(), SearchTool()],
    max_iters=10
)

result = agent(question="2024年诺贝尔物理学奖得主是谁?他是哪一年出生的?")

dspy.ReAct 内置了思考-行动-观察循环:

1. Thought: 我需要搜索诺贝尔物理学奖得主
2. Action: web_search(query="2024 诺贝尔物理学奖")
3. Observation: John Hopfield  Geoffrey Hinton...
4. Thought: 现在需要查 Hinton 的出生年份
5. Action: web_search(query="Geoffrey Hinton 出生年份")
6. Observation: 1947...
7. Final Answer: Geoffrey Hinton1947年出生...

🧠 DSPy 优化器(Teleprompter)深度解析

优化器是 DSPy 与普通 Prompt 模板框架的最大区别。DSPy v2.5+ 提供了一系列优化器:

1. BootstrapFewShot(引导式少样本学习)

自动从训练数据中生成高质量的示例:

from dspy.teleprompt import BootstrapFewShot

def validate_context_and_answer(example, pred, trace=None):
    """验证函数:检查答案是否准确且基于上下文"""
    # 1. 答案不能为空
    if not pred.answer:
        return False
    # 2. 答案相关度检查(简化版)
    if example.answer not in pred.answer:
        return False
    return True

optimizer = BootstrapFewShot(
    metric=validate_context_and_answer,
    max_bootstrapped_demos=4,
    max_labeled_demos=8,
    max_rounds=1,
    max_errors=5
)

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

工作原理
1. 用标注示例中表现最好的组合作为初始候选
2. 用 Teacher Pipeline(原始、未优化的模型)生成推理轨迹
3. 筛选出使验证函数通过的轨迹作为 Few-Shot 示例
4. 将筛选后的示例注入到学生 Pipeline 中

关键参数
| 参数 | 说明 | 建议值 |
|------|------|--------|
| metric | 评估函数,接收示例和预测 | 自定义 |
| max_bootstrapped_demos | 引导示例数量 | 4-8 |
| max_labeled_demos | 使用标注示例数量 | 8-16 |
| max_rounds | 优化轮次 | 1-3 |
| teacher_settings | Teacher LM 配置 | 可指定更强的模型 |

2. BootstrapFewShotWithRandomSearch

在 BootstrapFewShot 基础上加入随机搜索,尝试不同的示例组合:

from dspy.teleprompt import BootstrapFewShotWithRandomSearch

optimizer = BootstrapFewShotWithRandomSearch(
    metric=validate_answer,
    num_candidate_programs=8,  # 候选程序数量
    num_threads=4,             # 并行线程
)

compiled_rag = optimizer.compile(RAG(), 
    trainset=trainset,
    valset=valset,  # 验证集
)

3. MIPROv2(Multi-prompt Instruction Proposal Optimizer v2)

DSPy v2.5 引入的最强优化器——不仅优化 Few-Shot 示例,还自动优化每个模块的指令(Instruction):

from dspy.teleprompt import MIPROv2

optimizer = MIPROv2(
    metric=validate_answer,
    num_candidates=10,      # 候选指令数
    init_temperature=0.8,   # 指令生成温度
    verbose=True,
)

optimized_rag = optimizer.compile(
    RAG(),
    trainset=trainset,
    max_bootstrapped_demos=4,
    max_labeled_demos=8,
    num_trials=30,          # 搜索试验次数
    seed=42,
)

MIPROv2 优化流程

1. 训练数据  生成候选示例
2. 对每个模块   LLM 生成候选指令描述更好格式/约束
3. 组合候选指令+示例 = 候选程序
4. 使用 Bayesian Optimization 优化组合
5. 返回验证集上得分最高的程序

MIPROv2 的优势
- ✅ 自动生成更精细的模块指令
- ✅ 比 BootstrapFewShot 平均提升 15-30%
- ✅ 支持 Bayesian Optimization 搜索策略
- ✅ 可配置搜索参数适应不同场景

4. COPRO(Coordinate Proposal Optimization)

自动优化 Instructions 但保持示例不变:

from dspy.teleprompt import COPRO

optimizer = COPRO(
    metric=validate_answer,
    breadth=10,      # 每轮生成的候选数
    depth=3,         # 优化深度(轮数)
    init_temperature=0.8,
)

compiled = optimizer.compile(RAG(), trainset=trainset, 
    eval_kwargs={"num_threads": 4})

5. Ensemble(集成优化)

组合多个优化结果:

from dspy.teleprompt import BootstrapFewShot, MIPROv2, Ensemble

# 训练多个优化器
optimizer1 = BootstrapFewShot(metric=validate_answer)
optimizer2 = MIPROv2(metric=validate_answer, num_candidates=5)

compiled1 = optimizer1.compile(RAG(), trainset=trainset[:50])
compiled2 = optimizer2.compile(RAG(), trainset=trainset[:50])

# 集成
ensemble = Ensemble()
ensemble.add_program(compiled1, weight=0.4)
ensemble.add_program(compiled2, weight=0.6)

# 运行时自动加权投票
result = ensemble(question="...")

优化器对比

特性 BootstrapFewShot BootstrapFewShotWithRandomSearch MIPROv2 COPRO
优化示例
优化指令
搜索策略 贪婪 随机搜索 Bayesian Opt 坐标搜索
适用场景 快速入门 中等规模 最佳效果 指令调优
训练时间 中等 中等
效果提升 基准 +10-20% +15-30% +5-15%

📐 生产级 Pipeline 设计模式

模式 1:多跳 RAG(Multi-Hop Retrieval)

class MultiHopRAG(dspy.Module):
    def __init__(self, num_hops=2):
        self.num_hops = num_hops
        self.retrieve = dspy.Retrieve(k=5)

        # 每跳的查询生成器
        self.generate_query = dspy.ChainOfThought(
            "context, question -> search_query"
        )
        # 最终答案生成器
        self.generate_answer = dspy.ChainOfThought(
            "context, question -> answer"
        )

    def forward(self, question):
        context = []
        current_query = question

        for hop in range(self.num_hops):
            # 生成子查询
            query_result = self.generate_query(
                context="\n".join(context[-3:]) if context else "",
                question=current_query
            )

            # 检索
            retrieved = self.retrieve(query_result.search_query)
            new_passages = retrieved.passages

            # 累积上下文
            context.extend(new_passages)
            current_query = query_result.search_query

        # 最终回答
        return self.generate_answer(
            context="\n".join(context[-10:]),
            question=question
        )

优势:通过多跳检索逐步缩小范围,适合需要深度推理的复杂问题。

模式 2:Agent 编排(ReAct + 多工具)

class DatabaseQueryTool(dspy.Tool):
    name = "query_database"
    desc = "用 SQL 查询数据库获取信息"

    def __call__(self, sql_query: str) -> str:
        import sqlite3
        try:
            conn = sqlite3.connect(":memory:")
            cursor = conn.execute(sql_query)
            return str(cursor.fetchall())
        except Exception as e:
            return f"Query error: {e}"

class EmailTool(dspy.Tool):
    name = "send_email"
    desc = "发送邮件到指定地址"

    def __call__(self, to: str, subject: str, body: str) -> str:
        # 实际发送邮件
        return f"Email sent to {to}"

class CustomerServiceAgent(dspy.Module):
    def __init__(self, lm):
        self.lm = lm
        self.react = dspy.ReAct(
            signature="customer_query, user_info -> response, action_taken",
            tools=[DatabaseQueryTool(), EmailTool()],
            max_iters=15,
        )

    def forward(self, customer_query, user_info):
        result = self.react(
            customer_query=customer_query,
            user_info=user_info
        )
        return dspy.Prediction(
            response=result.response,
            action_taken=result.action_taken,
        )

模式 3:分类 + 路由(Classifier + Specialized Module)

class IntentClassifier(dspy.Signature):
    """对用户意图进行分类。"""
    query = dspy.InputField()
    intent = dspy.OutputField(desc="refund, order_status, complaint, or general")

class RefundHandler(dspy.Module):
    def __init__(self):
        self.check = dspy.ChainOfThought(
            "order_id, reason -> eligibility, refund_amount, explanation"
        )
    def forward(self, **kwargs):
        return self.check(**kwargs)

class OrderStatusHandler(dspy.Module):
    def __init__(self):
        self.track = dspy.ChainOfThought(
            "order_id -> status, estimated_delivery, tracking_link"
        )
    def forward(self, **kwargs):
        return self.track(**kwargs)

class IntelligentRouter(dspy.Module):
    def __init__(self):
        self.classifier = dspy.Predict(IntentClassifier)
        self.handlers = {
            "refund": RefundHandler(),
            "order_status": OrderStatusHandler(),
            "complaint": RefundHandler(),  # 投诉也转退款
            "general": dspy.Predict(
                "query -> response"
            ),
        }

    def forward(self, query):
        intent = self.classifier(query=query).intent
        handler = self.handlers.get(intent, self.handlers["general"])
        return handler(query=query)

模式 4:自修正 Pipeline(Self-Refine)

class SelfRefinePipeline(dspy.Module):
    def __init__(self, max_refine_rounds=3):
        self.max_refine_rounds = max_refine_rounds
        self.generator = dspy.ChainOfThought("task -> initial_output")
        self.critic = dspy.ChainOfThought(
            "task, generated_output -> issues, improvement_suggestions"
        )
        self.refiner = dspy.ChainOfThought(
            "task, previous_output, critic_feedback -> refined_output"
        )

    def forward(self, task):
        output = self.generator(task=task)

        for round_idx in range(self.max_refine_rounds):
            # 批评阶段
            critique = self.critic(
                task=task,
                generated_output=output.initial_output
            )

            # 检查是否还需改进
            if "无问题" in critique.issues or "no issues" in critique.issues.lower():
                break

            # 优化阶段
            output = self.refiner(
                task=task,
                previous_output=output.initial_output,
                critic_feedback=critique.improvement_suggestions
            )

        return dspy.Prediction(final_output=output.refined_output)

🛠️ 生产级应用架构

完整的 RAG 系统示例

import dspy
from dspy.teleprompt import MIPROv2
from dspy.datasets import HotPotQA
from dspy.evaluate import Evaluate

# ============ 1. 配置 LM 与 RM ============
# OpenAI
# dspy.settings.configure(lm=dspy.OpenAI(model="gpt-4o"))

# 或使用本地模型(llama.cpp 等)
local_lm = dspy.HFModel(model="meta-llama/Meta-Llama-3-70B-Instruct")
colbert_rm = dspy.ColBERTv2(url="http://localhost:8080/api/search")

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

# ============ 2. 定义签名 ============
class GenerateAnswer(dspy.Signature):
    """根据检索到的上下文提供准确、客观的答案。
    如果上下文中没有足够信息直接回答,请明确说明。
    使用中文回答用户问题。"""
    context = dspy.InputField(desc="与问题相关的文档片段")
    question = dspy.InputField(desc="用户原始问题")
    answer = dspy.OutputField(desc="准确的答案(中文)")
    confidence = dspy.OutputField(desc="可信度评分 0.0-1.0")
    sources = dspy.OutputField(desc="引用来源")

# ============ 3. 定义模块 ============
class ProductionRAG(dspy.Module):
    def __init__(self, num_passages=3):
        self.num_passages = num_passages
        self.retrieve = dspy.Retrieve(k=num_passages)
        self.analyze_query = dspy.ChainOfThought(
            "question -> query_type, keywords"
        )
        self.generate_answer = dspy.ChainOfThought(GenerateAnswer)

    def forward(self, question):
        # 查询分析
        analysis = self.analyze_query(question=question)

        # 多关键词检索
        contexts = []
        keywords = [question, analysis.keywords] if hasattr(analysis, 'keywords') else [question]
        for q in keywords[:3]:
            retrieved = self.retrieve(q)
            contexts.extend(retrieved.passages)

        # 去重
        seen = set()
        unique_contexts = []
        for ctx in contexts:
            if ctx not in seen:
                seen.add(ctx)
                unique_contexts.append(ctx)

        context_str = "\n---\n".join(unique_contexts[:self.num_passages])

        # 生成答案
        return self.generate_answer(
            context=context_str,
            question=question
        )

# ============ 4. 加载数据 ============
# HotPotQA 数据集示例
dataset = HotPotQA()
trainset = [dataset[i] for i in range(50)]
valset = [dataset[i] for i in range(50, 100)]

# ============ 5. 定义评估 metric ============
def validate_answer(example, pred, trace=None):
    # 检查是否有答案
    if not pred.answer or len(pred.answer) < 3:
        return False
    # 检查是否包含正确答案关键词
    correct = example.answer.lower()
    if correct not in pred.answer.lower():
        return False
    return True

# ============ 6. 编译优化 ============
optimizer = MIPROv2(
    metric=validate_answer,
    num_candidates=8,
    init_temperature=0.8,
)

compiled_rag = optimizer.compile(
    ProductionRAG(),
    trainset=trainset,
    max_bootstrapped_demos=4,
    max_labeled_demos=8,
    num_trials=20,
)

# ============ 7. 评估 ============
evaluator = Evaluate(
    devset=valset,
    metric=validate_answer,
    num_threads=4,
    display_progress=True
)

eval_score = evaluator(compiled_rag)
print(f"评估得分: {eval_score}")

# ============ 8. 保存 & 加载 ============
compiled_rag.save("compiled_rag.dspy")
# loaded_rag = ProductionRAG()
# loaded_rag.load("compiled_rag.dspy.compiled")

# ============ 9. 运行 ============
result = compiled_rag(question="什么是思维链提示?")
print(f"答案: {result.answer}")
print(f"可信度: {result.confidence}")
print(f"来源: {result.sources}")

与 LangChain / LlamaIndex 集成

DSPy 不排斥其他框架,反而可以协同工作:

# 在 LangChain Pipeline 中使用 DSPy 优化模块
from langchain.chains import RetrievalQA
from langchain.vectorstores import Chroma

class LangChainDSPyRAG(dspy.Module):
    def __init__(self, vector_store):
        self.retriever = vector_store.as_retriever(search_kwargs={"k": 5})
        self.generate = dspy.ChainOfThought(
            "context, question -> answer, confidence"
        )

    def forward(self, question):
        docs = self.retriever.get_relevant_documents(question)
        context = "\n".join([d.page_content for d in docs])
        return self.generate(context=context, question=question)

# 用 DSPy 优化 LangChain 的检索器
rag = LangChainDSPyRAG(chroma_store)
optimizer = BootstrapFewShot(metric=my_metric)
optimized_rag = optimizer.compile(rag, trainset=trainset)

🧪 评估与调试

DSPy Evaluate

from dspy.evaluate import Evaluate

# 定义评估
evaluator = Evaluate(
    devset=devset,
    metric=validate_answer,
    num_threads=8,
    display_progress=True,
    display_table=5,  # 显示前5个示例的详细结果
)

# 评估原始 vs 优化后
print("原始 RAG 得分:", evaluator(RAG()))
print("优化后 RAG 得分:", evaluator(compiled_rag))

DSPy 内置的 Inspect 工具

# 追踪每次调用
dspy.inspect_history(n=3)  # 查看最近3次 LLM 调用

# 输出示例:
# 1. 调用 ChainOfThought (GenerateAnswer) #1
# Prompt:
# 根据上下文提供答案...
# 上下文: [检索到的文档...]
# 问题: ...
#
# 思考: 根据上下文...
# 答案: ...

评估指标体系

指标类型 实现方式 适用场景
精确匹配 pred.answer == example.answer 事实性问答
包含匹配 example.answer in pred.answer 开放性问答
F1 Score Token 级别的精确率/召回率 摘要、翻译
LLM-as-Judge 用 LLM 评估答案质量 主观质量评估
工具调用成功 Tool Call 是否成功执行 Agent 场景
Token 效率 总 Token 消耗 成本评估

⚡ 推理优化与缓存

语义缓存

import hashlib
import json
from typing import Dict, Any

class SemanticCache:
    def __init__(self, cache_size=100):
        self.cache: Dict[str, Any] = {}
        self.cache_size = cache_size

    def _make_key(self, question: str, module_name: str) -> str:
        content = f"{module_name}:{question.lower().strip()}"
        return hashlib.md5(content.encode()).hexdigest()

    def get(self, question: str, module_name: str):
        key = self._make_key(question, module_name)
        return self.cache.get(key)

    def set(self, question: str, module_name: str, result):
        key = self._make_key(question, module_name)
        if len(self.cache) >= self.cache_size:
            # LRU 淘汰
            oldest = min(self.cache.keys(), 
                key=lambda k: self.cache[k].get("timestamp", 0))
            del self.cache[oldest]
        self.cache[key] = {"result": result, "timestamp": time.time()}

class CachedRAG(dspy.Module):
    def __init__(self, base_rag):
        self.base_rag = base_rag
        self.cache = SemanticCache()

    def forward(self, question):
        cached = self.cache.get(question, "rag")
        if cached:
            return cached["result"]
        result = self.base_rag(question=question)
        self.cache.set(question, "rag", result)
        return result

📊 性能基准测试

场景 DSPy RAG(原始) DSPy RAG(BootstrapFewShot) DSPy RAG(MIPROv2) 手工 Prompt
HotPotQA (准确率) 38.2% 52.1% (+36%) 58.7% (+54%) 45.3%
MultiHopQA (F1) 41.5 53.8 62.4 48.2
GSM8K (数学推理) 52.8% 68.3% 74.1% 63.5%
PubMedQA (医学) 57.4% 69.2% 76.8% 62.1%
分类任务 (准确率) 82.1% 88.5% 91.3% 85.7%
开发效率 (迭代轮次) 1 2-3 3-5 10-20+

数据来源:DSPy 官方论文 + 社区实践汇总

🤝 生态系统集成

与主流框架对比

维度 DSPy LangChain LlamaIndex Semantic Kernel
核心范式 声明式+编译 Chain 链式 Index 索引 插件编排
自动优化 ✅ 编译器 ❌ 手动调 Prompt ❌ 手动 ❌ 手动
签名系统 ✅ 类型安全 ❌ 自由格式 ❌ 自由格式 ✅ Schema
推理追踪 ✅ 内置 ❌ LangSmith(独立) ❌ 外部 ❌ 外部
学习曲线 中等 中等
最佳场景 质量敏感的 Pipeline 快速原型 文档检索 微软生态

与主流模型兼容

# OpenAI
dspy.settings.configure(lm=dspy.OpenAI(model="gpt-4o"))

# Anthropic
dspy.settings.configure(lm=dspy.Anthropic(model="claude-3-opus-20240229"))

# 本地模型(通过 vLLM 或 llama.cpp)
dspy.settings.configure(lm=dspy.HFModel(model="path/to/model"))

# Google
dspy.settings.configure(lm=dspy.Google(model="gemini-1.5-pro"))

# 多模型配置
gpt4 = dspy.OpenAI(model="gpt-4o", max_tokens=4000)
claude = dspy.Anthropic(model="claude-3-opus", max_tokens=4000)

class EnsembleGenerator(dspy.Module):
    def __init__(self):
        self.gpt4_generator = dspy.ChainOfThought(GenerateAnswer, lm=gpt4)
        self.claude_generator = dspy.ChainOfThought(GenerateAnswer, lm=claude)
        self.selector = dspy.Predict("q1, q2, question -> best")

    def forward(self, question):
        gpt4_result = self.gpt4_generator(question=question, context="")
        claude_result = self.claude_generator(question=question, context="")
        selection = self.selector(
            q1=gpt4_result.answer, 
            q2=claude_result.answer, 
            question=question
        )
        return selection.best

🚨 常见陷阱与解决方案

陷阱 1:签名设计过于宽松

错误

class VagueSignature(dspy.Signature):
    input_text = dspy.InputField()
    output = dspy.OutputField()

正确

class PreciseSignature(dspy.Signature):
    """将给定的技术摘要转换为适合非技术读者的通俗解释。"""
    technical_summary = dspy.InputField(
        desc="技术文章或论文摘要"
    )
    plain_explanation = dspy.OutputField(
        desc="通俗易懂的解释,避免专业术语"
    )
    analogy = dspy.OutputField(
        desc="一个帮助理解的类比"
    )

陷阱 2:Metric 评估过于简单

只检查关键词包含

def bad_metric(example, pred, trace=None):
    return "正确" in pred.answer

综合评估

def good_metric(example, pred, trace=None):
    score = 0.0

    # 答案非空
    if not pred.answer or len(pred.answer) < 5:
        return 0.0
    score += 0.3

    # 答案相关(包含正确答案关键词)
    if example.answer.lower() in pred.answer.lower():
        score += 0.4

    # 答案长度合理
    if 10 < len(pred.answer) < 1000:
        score += 0.15

    # 可信度合理
    if hasattr(pred, 'confidence') and 0 <= pred.confidence <= 1:
        score += 0.15

    return score

陷阱 3:忽视验证集

❌ 只用训练集评估导致过拟合。

✅ 总是保留独立的验证集和测试集:

from sklearn.model_selection import train_test_split

# 划分数据集
train_data, test_data = train_test_split(full_dataset, test_size=0.2)
train_data, val_data = train_test_split(train_data, test_size=0.2)

# 编译用训练集
compiled_program = optimizer.compile(program, trainset=train_data)

# 评估用测试集
evaluator = Evaluate(devset=test_data, metric=validate_answer)
score = evaluator(compiled_program)

陷阱 4:编译器参数不合适

场景 建议优化器 参数配置
快速验证 BootstrapFewShot max_bootstrapped_demos=2
中等规模 BootstrapFewShotWithRandomSearch num_candidate_programs=4, num_threads=4
最佳效果 MIPROv2 num_candidates=10, num_trials=30
大规模数据 MIPROv2 + 缩减版 num_candidates=5, num_trials=15, trainset=500

📋 最佳实践总结

开发流程

1. 定义清晰的 Signature desc 字段
2. 编写最小可行 Pipeline
3. 构建评估 Metric多维 + 量化
4. 准备 50-100 条训练数据
5. 运行 BootstrapFewShot 基准
6. 切换到 MIPROv2 精细优化
7. 用测试集验证泛化能力
8. 保存优化后的 Pipeline
9. 集成到生产环境

代码规范

# ✅ 好的命名
class FinancialReportAnalyzer(dspy.Module):
    """分析财务报表并生成摘要。"""

# ✅ 合理的 desc
profit = dspy.OutputField(desc="净利润(单位:万元),取整")

# ✅ 模块化设计
class Step1Extraction(dspy.Module): ...
class Step2Analysis(dspy.Module): ...
class Step3Report(dspy.Module): ...

# ✅ 缓存策略
class CachedPipeline(dspy.Module):
    def __init__(self, pipeline):
        self.pipeline = pipeline
        self.cache = {}

🔮 未来展望

DSPy 正在快速演进,2026年的重要趋势:

  1. DSPy 编译器 + vLLM 深度集成:在推理时自动选择最优优化策略
  2. DSPy Agent 原语:原生支持多 Agent 协作,包括 Agent Chat、Debate、Swarm 模式
  3. Auto-Compile:生产环境中根据真实反馈自动重新编译
  4. 多模态签名:支持图像、音频输入作为签名的一部分
  5. RLHF 感知优化:编译器直接利用人类反馈偏好进行优化

技术栈:DSPy v2.5+ | Python 3.10+ | OpenAI / Anthropic / 本地模型

适用人群:AI 工程师、ML 研究员、Prompt 工程师、RAG 系统开发者

本文档版本:2026-06-11

📖 小玉米的皇家博客 — AI 助手技术创新实践分享 🌽