介绍
让我们使用 DSPy 构建一个逻辑推理器。
推理器的原理很简单。给定一段文本,它首先提取事实,并将它们归类为前提和结论。
- 前提是论点声称将支持其结论的陈述或事实。它们是认为结论为真的理由。
- 结论是前提应该支持或证明的陈述。这是演讲者或作者试图让你基于所提供的前提相信的内容。
正确识别前提和结论至关重要。这涉及到理解论点的结构,这些结构可能是明确的或隐含的。逻辑、批判性思维或论证理论的训练可以提高这项技能。
在识别了前提和结论之后,推理者必须检查所做论点的有效性和合理性。
- 有效性涉及的是论点的逻辑结构是否是这样的:如果前提是真的,那么结论也必然是真的。这是对论点形式的检验。
- 健全性是关于前提本身的真理。如果一个论证既有效,其前提又为真,则该论证是健全的。
代码实现
第一步,显然,是配置我们将要使用的语言模型。由于我们将进行逻辑推理,使用 GPT-4 是明智的。它比 GPT-3.5-turbo 具有更好的“推理”能力。
import dspy
import os
from dotenv import load_dotenv
load_dotenv()
llm = dspy.OpenAI(
model='gpt-4',
api_key=os.environ['OPENAI_API_KEY'],
max_tokens=100
)
dspy.settings.configure(lm=llm)
第二步是定义 check_logic 签名,这将帮助我们验证从输入文本中提取的结论与提取的前提是否一致。
class check_logic(dspy.Signature):
"""给定一个论点的前提和结论,检查结论是否合乎逻辑。"""
# 创建一个输入字段,用于输入论点的前提
premises = dspy.InputField(desc="论点的前提")
# 创建一个输入字段,用于输入论点的结论
conclusions = dspy.InputField(desc="论点的结论")
# 创建一个输出字段,用于指示给定前提下结论是否合乎逻辑
logical = dspy.OutputField(desc="给定前提,结论是否合乎逻辑")
最后,我们定义了 logical_reasoner 模块,并在示例上对其进行了测试。如前所述,logical_reasoner 首先提取前提和结论。然后,它检查结论是否与前提一致。
# 定义一个名为 logical_reasoner 的类,它继承自 dspy.Module 类。
class logical_reasoner(dspy.Module):
# 类的构造函数(初始化方法)。
def __init__(self):
# 调用父类 dspy.Module 的构造函数。
super().__init__()
# 初始化一个用于文本到前提、结论预测的 Predict 对象。
self.logical_reasoner = dspy.Predict("text -> premises, conclusions")
# 初始化一个用于检查逻辑的 ChainOfThought 对象。
self.checker = dspy.ChainOfThought(check_logic)
# 定义 forward 方法,它是逻辑推理器的主要执行方法。
def forward(self, text):
# 使用 logical_reasoner 对象对输入文本进行预测,得到前提和结论。
prediction = self.logical_reasoner(text=text)
# 使用 checker 对象检查预测得到的前提和结论是否逻辑一致。
result = self.checker(premises=prediction.premises, conclusions=prediction.conclusions)
# 返回检查结果。
return result
# 定义一个输入文本,这是一个逻辑推理的示例。
text = "如果正在下雨,那么草是湿的。草是湿的。因此,并没有下雨。"
# 实例化 logical_reasoner 类。
lr = logical_reasoner()
# 使用逻辑推理器实例对输入文本进行推理,并打印结果。
print(lr(text=text))
结果,我们的 logical_reasoner 正确地检测到了文本中的逻辑问题。
Prediction(
rationale='推导出逻辑性。我们从第一个前提知道,如果下雨,那么草就会湿。然而,第二个前提仅仅告诉我们草是湿的。它并没有告诉我们草为何会湿。草湿可能有其他原因,比如有人浇了水或者早晨的露水。因此,我们不能仅仅因为草是湿的就得出没有下雨的结论。',
# 逻辑性判断部分明确指出,根据给出的前提,得出的结论在逻辑上是不成立的。
logical='根据前提,结论不合逻辑。'
)
第二代码实现
在第一次代码实现中,我们没有检查每个前提是否在一开始就是合理的。错误的前提仍然可以逻辑上导致一个结论。但是,由于前提是错误的,所以这个结论也将是错误的。
import dspy
import os
from dotenv import load_dotenv
# 加载环境变量。
load_dotenv()
# 初始化一个与 OpenAI API 交互的 dspy.OpenAI 对象。
llm = dspy.OpenAI(
模型='gpt-4', # 使用 OpenAI 的 gpt-4 模型。
api_key=os.environ['OPENAI_API_KEY'], # 从环境变量中获取 API 密钥。
最大令牌数=100 # 设置生成的最大令牌数。
)
# 配置 dspy 的设置,将 llm 设置为语言模型。
dspy.settings.configure(lm=llm)
# 定义 check_logic 类,它是一个用于检查结论逻辑性的 dspy.Signature。
class check_logic(dspy.Signature):
"""
给定论点的前提和结论,检查结论是否逻辑上合理。
"""
premises = dspy.InputField(desc="论点的前提")
conclusions = dspy.InputField(desc="论点的结论")
sound = dspy.InputField(desc="前提是否合理")
logical = dspy.OutputField(desc="给定前提,结论是否逻辑上合理")
# 定义 check_premises 类,它是一个用于检查前提是否合理的 dspy.Signature。
class check_premises(dspy.Signature):
"""
给定论点的前提,检查前提是否合理。
"""
premises = dspy.InputField(desc="论点的前提")
sound = dspy.OutputField(desc="前提是否合理")
# 定义 logical_reasoner 类,它是一个用于逻辑推理的 dspy.Module。
class logical_reasoner(dspy.Module):
def __init__(self):
super().__init__()
self.logical_reasoner = dspy.Predict("text -> premises, conclusions")
self.check_prems = dspy.Predict(check_premises)
self.checker = dspy.ChainOfThought(check_logic)
def forward(self,text):
prediction = self.logical_reasoner(text=text)
sound = self.check_prems(premises=prediction.premises)
result = self.checker(premises=prediction.premises, conclusions=prediction.conclusions, sound=sound.sound)
return result
text="If it is raining, then the grass is wet. The grass is wet. Therefore, it is raining."
lr = logical_reasoner()
print(lr(text=text))
这是检查前提合理性的代码。如果你理解了我们之前所做的,它应该是不言自明的。