DSPy 模块详解 #
什么是模块? #
模块(Module)是 DSPy 中实现具体功能的组件。每个模块封装了一个特定的处理逻辑,接收输入、调用 LLM、返回输出。模块是 DSPy 程序的构建块。
text
┌─────────────────────────────────────────────────────────────┐
│ 模块的作用 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 1. 封装逻辑:将 LLM 调用封装为可复用的组件 │
│ 2. 绑定签名:将签名与具体的处理方式结合 │
│ 3. 组合构建:多个模块可以组合成复杂程序 │
│ 4. 自动优化:模块可以被优化器自动改进 │
│ │
└─────────────────────────────────────────────────────────────┘
内置模块概览 #
text
┌─────────────────────────────────────────────────────────────┐
│ DSPy 内置模块 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ dspy.Predict │ │
│ │ 最基础的预测模块,直接根据签名生成输出 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ dspy.ChainOfThought │ │
│ │ 思维链模块,先推理再输出 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ dspy.ReAct │ │
│ │ 推理-行动模块,支持工具调用 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ dspy.ProgramOfThoughts │ │
│ │ 程序化思维模块,生成代码解决问题 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ dspy.Retrieve │ │
│ │ 检索模块,从知识库获取相关内容 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ dspy.MultiChainComparison │ │
│ │ 多链比较模块,比较多个推理路径 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
Predict 模块 #
Predict 是最基础的模块,直接根据签名生成输出。
基本用法 #
python
import dspy
lm = dspy.LM('openai/gpt-4o-mini')
dspy.configure(lm=lm)
class QA(dspy.Signature):
"""回答问题"""
question = dspy.InputField()
answer = dspy.OutputField()
qa = dspy.Predict(QA)
result = qa(question="Python 的创始人是谁?")
print(result.answer)
多输入 #
python
class ContextQA(dspy.Signature):
"""根据上下文回答问题"""
context = dspy.InputField()
question = dspy.InputField()
answer = dspy.OutputField()
qa = dspy.Predict(ContextQA)
result = qa(
context="Python 由 Guido van Rossum 于 1991 年创建。",
question="Python 何时创建?"
)
print(result.answer)
多输出 #
python
class Analysis(dspy.Signature):
"""分析文本"""
text = dspy.InputField()
summary = dspy.OutputField()
sentiment = dspy.OutputField()
keywords = dspy.OutputField()
analyzer = dspy.Predict(Analysis)
result = analyzer(text="今天天气真好,阳光明媚!")
print(result.summary)
print(result.sentiment)
print(result.keywords)
内联签名 #
python
qa = dspy.Predict("question -> answer")
result = qa(question="测试问题")
translate = dspy.Predict("text, source_lang, target_lang -> translation")
result = translate(text="Hello", source_lang="English", target_lang="Chinese")
ChainOfThought 模块 #
ChainOfThought 模块在输出前会先进行推理,适合需要复杂思考的任务。
基本用法 #
python
import dspy
class MathProblem(dspy.Signature):
"""解决数学问题"""
problem = dspy.InputField()
answer = dspy.OutputField()
solver = dspy.ChainOfThought(MathProblem)
result = solver(problem="如果 x + 5 = 12,那么 x 是多少?")
print(result.rationale)
print(result.answer)
推理过程 #
text
┌─────────────────────────────────────────────────────────────┐
│ ChainOfThought 工作流程 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 输入:problem = "如果 x + 5 = 12,那么 x 是多少?" │
│ │
│ ChainOfThought 处理: │
│ 1. 分析问题:这是一个简单的一元一次方程 │
│ 2. 移项:x = 12 - 5 │
│ 3. 计算:x = 7 │
│ 4. 验证:7 + 5 = 12 ✓ │
│ │
│ 输出: │
│ rationale: "首先,我需要解这个方程..." │
│ answer: "x = 7" │
│ │
└─────────────────────────────────────────────────────────────┘
适用场景 #
python
class ReasoningTask(dspy.Signature):
"""需要推理的任务"""
question = dspy.InputField()
answer = dspy.OutputField()
reasoner = dspy.ChainOfThought(ReasoningTask)
result = reasoner(question="为什么天空是蓝色的?")
result = reasoner(question="请解释相对论的基本原理")
result = reasoner(question="分析这段代码的时间复杂度")
与 Predict 对比 #
python
import dspy
class Task(dspy.Signature):
"""任务"""
input = dspy.InputField()
output = dspy.OutputField()
predict = dspy.Predict(Task)
cot = dspy.ChainOfThought(Task)
input_text = "解释量子纠缠现象"
result1 = predict(input=input_text)
result2 = cot(input=input_text)
print("Predict 输出:", result1.output)
print("CoT 推理:", result2.rationale)
print("CoT 输出:", result2.output)
ReAct 模块 #
ReAct(Reasoning and Acting)模块支持工具调用,可以执行外部操作。
基本用法 #
python
import dspy
class SearchQA(dspy.Signature):
"""搜索并回答问题"""
question = dspy.InputField()
answer = dspy.OutputField()
def search(query):
return f"搜索结果: {query}"
react = dspy.ReAct(SearchQA, tools=[search])
result = react(question="Python 的最新版本是什么?")
print(result.answer)
多工具支持 #
python
import dspy
class ToolQA(dspy.Signature):
"""使用工具回答问题"""
question = dspy.InputField()
answer = dspy.OutputField()
def calculator(expression):
return str(eval(expression))
def search(query):
return f"搜索: {query}"
def weather(city):
return f"{city} 天气: 晴,25°C"
react = dspy.ReAct(ToolQA, tools=[calculator, search, weather])
result = react(question="北京今天天气怎么样?")
ReAct 工作流程 #
text
┌─────────────────────────────────────────────────────────────┐
│ ReAct 工作流程 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 问题:"北京今天天气怎么样?" │
│ │
│ 步骤 1: 思考 │
│ "我需要查询北京的天气信息" │
│ │
│ 步骤 2: 行动 │
│ 调用 weather("北京") │
│ │
│ 步骤 3: 观察 │
│ "北京 天气: 晴,25°C" │
│ │
│ 步骤 4: 回答 │
│ "北京今天天气晴朗,气温 25°C" │
│ │
└─────────────────────────────────────────────────────────────┘
ProgramOfThoughts 模块 #
ProgramOfThoughts 模块生成代码来解决问题,适合需要精确计算的任务。
基本用法 #
python
import dspy
class MathCalculation(dspy.Signature):
"""数学计算"""
problem = dspy.InputField()
answer = dspy.OutputField()
solver = dspy.ProgramOfThoughts(MathCalculation)
result = solver(problem="计算 1 到 100 的和")
print(result.answer)
工作原理 #
text
┌─────────────────────────────────────────────────────────────┐
│ ProgramOfThoughts 工作流程 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 问题:"计算 1 到 100 的和" │
│ │
│ 生成的代码: │
│ total = 0 │
│ for i in range(1, 101): │
│ total += i │
│ print(total) │
│ │
│ 执行结果:5050 │
│ │
│ 输出:answer = "5050" │
│ │
└─────────────────────────────────────────────────────────────┘
适用场景 #
python
class DataAnalysis(dspy.Signature):
"""数据分析"""
data_description = dspy.InputField()
analysis_result = dspy.OutputField()
analyzer = dspy.ProgramOfThoughts(DataAnalysis)
result = analyzer(data_description="计算列表 [1,2,3,4,5] 的平均值和标准差")
Retrieve 模块 #
Retrieve 模块用于从知识库检索相关内容。
基本用法 #
python
import dspy
rm = dspy.ColBERTv2(url='http://localhost:8893/api/search')
dspy.configure(rm=rm)
retrieve = dspy.Retrieve(k=3)
results = retrieve("什么是机器学习?")
print(results.passages)
在自定义模块中使用 #
python
import dspy
class GenerateAnswer(dspy.Signature):
"""根据上下文回答问题"""
context = dspy.InputField()
question = dspy.InputField()
answer = dspy.OutputField()
class RAG(dspy.Module):
def __init__(self, k=3):
super().__init__()
self.retrieve = dspy.Retrieve(k=k)
self.generate = dspy.ChainOfThought(GenerateAnswer)
def forward(self, question):
context = self.retrieve(question).passages
return self.generate(context=context, question=question)
自定义模块 #
基本结构 #
python
import dspy
class MyModule(dspy.Module):
def __init__(self):
super().__init__()
self.predict = dspy.Predict(MySignature)
def forward(self, **kwargs):
return self.predict(**kwargs)
多步骤模块 #
python
import dspy
class Step1(dspy.Signature):
"""第一步:分析"""
input = dspy.InputField()
analysis = dspy.OutputField()
class Step2(dspy.Signature):
"""第二步:处理"""
analysis = dspy.InputField()
result = dspy.OutputField()
class Step3(dspy.Signature):
"""第三步:输出"""
result = dspy.InputField()
output = dspy.OutputField()
class Pipeline(dspy.Module):
def __init__(self):
super().__init__()
self.analyze = dspy.Predict(Step1)
self.process = dspy.ChainOfThought(Step2)
self.output = dspy.Predict(Step3)
def forward(self, input_data):
analysis = self.analyze(input=input_data).analysis
result = self.process(analysis=analysis).result
output = self.output(result=result).output
return dspy.Prediction(output=output)
条件分支模块 #
python
import dspy
class SimpleQA(dspy.Signature):
"""简单问答"""
question = dspy.InputField()
answer = dspy.OutputField()
class ComplexQA(dspy.Signature):
"""复杂问答"""
question = dspy.InputField()
reasoning = dspy.OutputField()
answer = dspy.OutputField()
class ClassifyQuestion(dspy.Signature):
"""分类问题"""
question = dspy.InputField()
complexity = dspy.OutputField(desc="simple 或 complex")
class AdaptiveQA(dspy.Module):
def __init__(self):
super().__init__()
self.classifier = dspy.Predict(ClassifyQuestion)
self.simple_qa = dspy.Predict(SimpleQA)
self.complex_qa = dspy.ChainOfThought(ComplexQA)
def forward(self, question):
complexity = self.classifier(question=question).complexity
if complexity == "simple":
return self.simple_qa(question=question)
else:
return self.complex_qa(question=question)
循环处理模块 #
python
import dspy
class ProcessItem(dspy.Signature):
"""处理单个项目"""
item = dspy.InputField()
result = dspy.OutputField()
class BatchProcessor(dspy.Module):
def __init__(self):
super().__init__()
self.process = dspy.Predict(ProcessItem)
def forward(self, items):
results = []
for item in items:
result = self.process(item=item)
results.append(result.result)
return dspy.Prediction(results=results)
模块组合 #
串行组合 #
python
import dspy
class Extract(dspy.Signature):
"""提取信息"""
text = dspy.InputField()
entities = dspy.OutputField()
class Transform(dspy.Signature):
"""转换格式"""
entities = dspy.InputField()
formatted = dspy.OutputField()
class Load(dspy.Signature):
"""加载数据"""
formatted = dspy.InputField()
status = dspy.OutputField()
class ETL(dspy.Module):
def __init__(self):
super().__init__()
self.extract = dspy.Predict(Extract)
self.transform = dspy.ChainOfThought(Transform)
self.load = dspy.Predict(Load)
def forward(self, text):
entities = self.extract(text=text).entities
formatted = self.transform(entities=entities).formatted
status = self.load(formatted=formatted).status
return dspy.Prediction(status=status)
并行组合 #
python
import dspy
class AnalyzeSentiment(dspy.Signature):
"""情感分析"""
text = dspy.InputField()
sentiment = dspy.OutputField()
class ExtractKeywords(dspy.Signature):
"""关键词提取"""
text = dspy.InputField()
keywords = dspy.OutputField()
class SummarizeText(dspy.Signature):
"""文本摘要"""
text = dspy.InputField()
summary = dspy.OutputField()
class TextAnalyzer(dspy.Module):
def __init__(self):
super().__init__()
self.sentiment = dspy.Predict(AnalyzeSentiment)
self.keywords = dspy.Predict(ExtractKeywords)
self.summary = dspy.ChainOfThought(SummarizeText)
def forward(self, text):
sentiment = self.sentiment(text=text).sentiment
keywords = self.keywords(text=text).keywords
summary = self.summary(text=text).summary
return dspy.Prediction(
sentiment=sentiment,
keywords=keywords,
summary=summary
)
嵌套组合 #
python
import dspy
class SubModuleA(dspy.Module):
def __init__(self):
super().__init__()
self.step = dspy.Predict("input -> output")
def forward(self, input_data):
return self.step(input=input_data)
class SubModuleB(dspy.Module):
def __init__(self):
super().__init__()
self.step = dspy.ChainOfThought("input -> output")
def forward(self, input_data):
return self.step(input=input_data)
class MainModule(dspy.Module):
def __init__(self):
super().__init__()
self.module_a = SubModuleA()
self.module_b = SubModuleB()
def forward(self, input_data):
result_a = self.module_a(input_data)
result_b = self.module_b(result_a.output)
return result_b
模块状态管理 #
保存和加载 #
python
import dspy
class MyModule(dspy.Module):
def __init__(self):
super().__init__()
self.predict = dspy.Predict("input -> output")
module = MyModule()
module.save("my_module.json")
loaded_module = MyModule()
loaded_module.load("my_module.json")
克隆模块 #
python
import copy
original = dspy.Predict("input -> output")
cloned = copy.deepcopy(original)
模块调试 #
查看模块结构 #
python
import dspy
class MyModule(dspy.Module):
def __init__(self):
super().__init__()
self.step1 = dspy.Predict("input -> intermediate")
self.step2 = dspy.ChainOfThought("intermediate -> output")
module = MyModule()
print(module.named_modules())
print(module.named_predictors())
追踪执行 #
python
import dspy
dspy.settings.configure(trace=True)
module = dspy.Predict("question -> answer")
result = module(question="测试")
dspy.inspect_trace()
下一步 #
现在你已经掌握了模块的各种用法,接下来学习 优化器,了解如何自动优化模块性能!
最后更新:2026-03-30