定义签名与模块
签名语法、ChainOfThought、ReAct 以及自定义 DSPy 模块。
定义签名与模块 是 CoddyKit 上的免费 AI Prompt Engineering 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 AI Prompt Engineering 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 AI Prompt Engineering 课程共包含 4 节课。
signature 是类型化契约
DSPy 的 signature 是一个 Python 类,用于声明推理步骤的输入和输出。您可以将它理解为 LLM 调用的类型化函数契约。
文档字符串会成为任务描述。字段注解会告诉 DSPy 要生成什么。您无需编写实际的提示词文本,DSPy 会根据这份声明推导出提示词。
定义基本 signature
最小的 signature 继承 dspy.Signature,并将字段标注为 InputField 或 OutputField。类的文档字符串提供任务指令。
import dspy
class QASignature(dspy.Signature):
"""Answer the question based on the given context."""
context: str = dspy.InputField(desc='Relevant background text')
question: str = dspy.InputField(desc='The question to answer')
answer: str = dspy.OutputField(desc='A concise answer')
# Inspect what DSPy sees
print(QASignature.instructions) # The docstring
print(list(QASignature.input_fields.keys())) # ['context', 'question']
print(list(QASignature.output_fields.keys())) # ['answer']多个输出字段
signature 可以包含多个输出字段。DSPy 会提示模型在一次调用中生成所有输出。这对于提取结构化信息很有用。
import dspy
class EntityExtraction(dspy.Signature):
"""Extract named entities from the text."""
text: str = dspy.InputField()
people: list[str] = dspy.OutputField(desc='List of person names mentioned')
organizations: list[str] = dspy.OutputField(desc='List of organization names')
locations: list[str] = dspy.OutputField(desc='List of place names')
extractor = dspy.Predict(EntityExtraction)
result = extractor(text='Elon Musk founded SpaceX in Hawthorne, California.')
print(result.people, result.organizations, result.locations)Predict 模块
dspy.Predict 是最简单的模块。它接收一个 signature,直接要求 LM 生成输出。它不会添加推理框架,只会生成与 signature 匹配的结构化提示词。
当任务很直接且不需要明确的推理步骤时,请使用 Predict。
import dspy
class Classify(dspy.Signature):
"""Classify the sentiment of the review."""
review: str = dspy.InputField()
sentiment: str = dspy.OutputField(desc='positive, negative, or neutral')
# Predict wraps the signature with a direct prompt
classifier = dspy.Predict(Classify)
result = classifier(review='The food was amazing and the service was excellent!')
print(result.sentiment) # positiveChainOfThought 模块
dspy.ChainOfThought 会为 signature 添加一个中间的 reasoning 字段。模型会先写出推理过程,然后生成最终答案。
对于多步骤问题,这种方式可以稳定提升准确率,而且您无需编写任何思维链提示词指令。
import dspy
class MathSolver(dspy.Signature):
"""Solve the math problem."""
problem: str = dspy.InputField()
answer: str = dspy.OutputField(desc='The numerical answer')
# ChainOfThought adds a 'reasoning' step automatically
solver = dspy.ChainOfThought(MathSolver)
result = solver(problem='If a train travels 60 mph for 2.5 hours, how far does it go?')
print(result.reasoning) # Step-by-step reasoning
print(result.answer) # 150 milesReAct 模块
dspy.ReAct 实现了推理 + 行动循环。模型会在推理步骤和工具调用之间交替进行,因此非常适合需要搜索、计算或获取数据的代理。
您只需提供工具列表(带有文档字符串的 Python 函数),DSPy 会自动处理它们之间的交替过程。
import dspy
def search_web(query: str) -> str:
"""Search the web and return relevant results."""
# In production, call a real search API
return f'Search results for: {query}'
def calculate(expression: str) -> str:
"""Evaluate a mathematical expression."""
return str(eval(expression))
class ResearchQA(dspy.Signature):
"""Answer the question using web search and calculation as needed."""
question: str = dspy.InputField()
answer: str = dspy.OutputField()
agent = dspy.ReAct(ResearchQA, tools=[search_web, calculate])
result = agent(question='What is 15% of 847?')
print(result.answer)将模块组合成程序
将模块组合成多步骤程序,才能发挥真正的威力。继承 dspy.Module,在 __init__ 中定义子模块,并实现 forward() 将它们串联起来。
import dspy
class RetrieveAndAnswer(dspy.Module):
def __init__(self):
super().__init__()
self.retrieve = dspy.Retrieve(k=3) # Retrieves top-3 passages
self.generate = dspy.ChainOfThought('context, question -> answer')
def forward(self, question):
passages = self.retrieve(question).passages
context = '\n'.join(passages)
return self.generate(context=context, question=question)
# This is a complete RAG pipeline in ~10 lines
rag = RetrieveAndAnswer()
result = rag(question='What are the main causes of climate change?')
print(result.answer)内联 signature 简写
对于简单情况,DSPy 接受内联字符串 signature:'input1, input2 -> output1, output2'。无需定义完整的类,就可以快速制作原型,非常方便。
import dspy
# Full class signature
class Translate(dspy.Signature):
"""Translate text to French."""
text: str = dspy.InputField()
translation: str = dspy.OutputField()
# Equivalent inline shorthand
translator_v1 = dspy.Predict(Translate)
translator_v2 = dspy.Predict('text -> translation') # Less metadata
# Both work the same way
result = translator_v1(text='Hello world')
print(result.translation)字段描述很重要
InputField 和 OutputField 中的 desc 参数会被包含在生成的提示词中。优秀的描述可以精确地引导模型。
您可以将 desc 理解为字段级文档,它会与字段名称一起出现在提示词中。
import dspy
class Summarize(dspy.Signature):
"""Summarize the article for a busy executive."""
article: str = dspy.InputField(
desc='The full article text to summarize'
)
summary: str = dspy.OutputField(
desc='3-5 bullet points highlighting key decisions and numbers'
)
confidence: float = dspy.OutputField(
desc='Your confidence in the summary accuracy from 0.0 to 1.0'
)
summarizer = dspy.Predict(Summarize)
# DSPy constructs a prompt using all the desc values automatically保存和加载程序
优化完成后,您可以保存编译后的程序,这样就不必每次都重新运行优化。DSPy 会将优化后的状态序列化为 JSON 文件。
import dspy
class QA(dspy.Signature):
"""Answer questions accurately."""
question: str = dspy.InputField()
answer: str = dspy.OutputField()
program = dspy.ChainOfThought(QA)
# After optimization, save the compiled state
program.save('optimized_qa.json')
# Load it later without re-running optimization
loaded_program = dspy.ChainOfThought(QA)
loaded_program.load('optimized_qa.json')
result = loaded_program(question='What is the speed of light?')
print(result.answer)用于输出约束的断言
DSPy 的断言让您可以声明输出约束。如果模型违反约束,DSPy 会自动结合纠正性反馈重试,无需手动编写重试逻辑。
import dspy
class ShortAnswer(dspy.Signature):
"""Answer in at most 10 words."""
question: str = dspy.InputField()
answer: str = dspy.OutputField()
class ConstrainedQA(dspy.Module):
def __init__(self):
super().__init__()
self.predict = dspy.Predict(ShortAnswer)
def forward(self, question):
result = self.predict(question=question)
# Assert: answer must be at most 10 words
dspy.Assert(
len(result.answer.split()) <= 10,
'The answer must be 10 words or fewer.'
)
return result知识检查:ChainOfThought
使用相同的 signature 时,dspy.ChainOfThought 相比 dspy.Predict 增加了什么?
回顾:signature 和模块
DSPy 的 signature 是描述 LLM 步骤应执行什么操作的类型化类声明,包括输入、输出和文档字符串指令。Predict、ChainOfThought 和 ReAct 等模块围绕 signature 实现不同的推理策略。您可以在 dspy.Module 子类中组合多个模块,构建多步骤流水线。字段的 desc 值会在自动生成的提示词中引导模型,而断言则通过自动重试来强制执行输出约束。
常见问题解答
「定义签名与模块」课时是免费的吗?
是的 — 「定义签名与模块」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 AI Prompt Engineering 课程的其余内容,请升级到 CoddyKit PRO。 AI Prompt Engineering 课程共包含 4 节课。
「定义签名与模块」这节课中我会学到什么?
签名语法、ChainOfThought、ReAct 以及自定义 DSPy 模块。 你通过在浏览器中直接运行的动手代码来练习 AI Prompt Engineering,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 AI Prompt Engineering 需要有经验吗?
无需任何先前经验。CoddyKit 上的 AI Prompt Engineering 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。
「定义签名与模块」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 AI Prompt Engineering 课中编写并运行代码吗?
能。每节 AI Prompt Engineering 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- DSPy 框架简介
- 定义签名与模块
- 编译与优化提示词
- 评估 DSPy 流程