微信扫码
添加专属顾问
书接上文《DSPy的“前世今生”,从DSPy的核心论文解析其技术演进之路》,通过对DSPy的核心论文进行简述,解析其技术演进之路。本文将首先以示例驱动的方式,由浅入深的介绍DSPy框架自身的使用流程,然后结合知名大模型应用框架LangChain,进一步介绍两个框架结合的案例。
概述
DSPy,即声明式语言模型编程(Declarative Language Model Programming),旨在简化复杂语言模型应用的构建过程。由斯坦福大学的研究人员开发,DSPy允许开发者专注于应用程序的高级逻辑,同时抽象掉许多低级细节。创造了一种提示词工程的新范式,对目前提示词工程中的共识问题(如提示词的脆弱性、迭代成本高、缺乏系统方化方法、范式繁多、依靠人类经验 )等诸多问题,给出了新的解决思路。
DSPy从0到1使用教程
1、在使用DSPy之前,请先确保已经安装了 DSPy的python包,可参考Installation | DSPy (dspy-docs.vercel.app)
import dspy# 定义并设置大模型model_name = 'llama3'lm = dspy.OllamaLocal(model=model_name)dspy.settings.configure(lm=lm)# 定义输入输出参数 类定义方式class QA(dspy.Signature):question = dspy.InputField()answer = dspy.OutputField()question = "what is the color of the sea?"summarize = dspy.ChainOfThought(QA)response = summarize(question=question)print(f"问题:{question} \n答案:{response.answer}")
上述代码首先定义了大模型使用 llama3 ,然后,定义了 dspy.Signature 类,输入字段为 question, 输出字段为 answer,最后实例化 dspy.ChainOfThought 类,并输入问题调用大模型进行回答,执行结果为:
问题:what is the color of the sea?答案:The color of the sea is typically perceived as blue.
question = "what is the color of the sky?"summarize = dspy.ChainOfThought('question -> answer')response = summarize(question=question)# #inline方式 定义输入输出参数 - start # # 问题:what is the color of the sky? 答案:Blue # #inline方式 定义输入输出参数 - end # #
lm.inspect_history(n=1)
Question: what is the color of the sky?Reasoning: Let's think step by step in order to Question: what is the color of the sky?Reasoning: Let's think step by step in order to determine the color of the sky. The sky appears blue due to the scattering of light waves in the atmosphere. The blue light is scattered more efficiently than other colors of light, which is why the sky appears blue.Answer: Blue
import dspy model_name = 'llama3'lm = dspy.OllamaLocal(model=model_name)dspy.settings.configure(lm=lm) question = "what is the color of sky at night?"#示例内容example = dspy.Example(question="what is the color of sky?", answer="the color of sky is blue, even at night")summarize = dspy.ChainOfThought('question -> answer')response = summarize(question=question, demos=[example]) print(f"问题:{question} \n答案:{response.answer}")问题:what is the color of sky at night? 答案:...the color of the sky at night is still blue!
---Question: what is the color of sky?Answer: the color of sky is blue, even at night---Question: what is the color of sky at night?Reasoning: Let's think step by step in order to Question: what is the color of sky at night?Reasoning: Let's think step by step in order to answer this question. We know that during the day, the color of the sky is blue, and we also know that the color of the sky remains relatively consistent even after sunset. Therefore...Answer: ...the color of the sky at night is still blue!
import dspyfrom get_dataset import custom_trainset as trainset# example of transet :Example({'question': '1+5=?', 'answer': '6'}) (input_keys={'question'})gsm8k_trainset = gsm8k.train[:10] model_name = 'llama3'lm = dspy.OllamaLocal(model=model_name, timeout_s=1000)dspy.settings.configure(lm=lm) question = "3+3+5=?"#示例内容summarize = dspy.ChainOfThought('question -> answer')response = summarize(question=question, demos=gsm8k_trainset) print(f"问题:{question} \n答案:{response.answer}")问题: 3+3+5=?答案: 8
实际上这个答案是错误的,正确的答案是11,因此提示词可以优化大模型的输出,但是也很难保证回答问题的准确性。提示词如下:
Given the fields `question`, produce the fields `answer`.---Follow the following format.Question: ${question}Reasoning: Let's think step by step in order to ${produce the answer}. We ...Answer: ${answer}---Question: 1+1=?Answer: 2---Question: 5*5=?Answer: 25---Question: 1+5=?Answer: 6---Question: 3+3=?Answer: 6---Question: 6+6=?Answer: 12---Question: 3+3+5=?Reasoning: Let's think step by step in order to Here is the completed response:---Question: 3+3+5=?Reasoning: Let's think step by step in order to get the answer. We need to add 3 and 3 first, which gives us 6, then we can add 5 to that result.Answer: 8
from get_dataset import gsm_testset as test_setimport dspyfrom dspy.datasets.gsm8k import gsm8k_metricfrom dspy.teleprompt import BootstrapFewShot# 定义并设置大模型model_name = 'llama3'lm = dspy.OllamaLocal(model=model_name, timeout_s=1000)dspy.settings.configure(lm=lm)class CoT(dspy.Module):def __init__(self):super().__init__()self.prog = dspy.ChainOfThought("question -> answer")def forward(self, question):return self.prog(question=question)cot = CoT()evaluate = Evaluate(devset=test_set, metric=gsm8k_metric, num_threads=4, display_progress=True, display_table=0)evaluate(cot)
from get_dataset import custom_trainset as trainsetconfig = dict(max_bootstrapped_demos=4, max_labeled_demos=4)# Optimize! Use the `gsm8k_metric` here. In general, the metric is going to tell the optimizer how well it's doing.teleprompter = BootstrapFewShot(metric=gsm8k_metric, **config)# 可以调整 train_set 长度optimized_cot = teleprompter.compile(CoT(), trainset=trainset)optimized_cot.save("./test.json")question = "3+3+5=?"response = optimized_cot(question=question)print(f"问题:{question} \n答案:{response.answer}")
问题: 3+3+5=?答案: 11
evaluate(optimized_cot)
optimized_cot = CoT()optimized_cot.load("./test.json")optimized_cot(question=question)
import dspyfrom dspy.evaluate.evaluate import Evaluatefrom dspy.teleprompt import BootstrapFewShotWithRandomSearchfrom langchain_openai import OpenAIfrom langchain.globals import set_llm_cachefrom langchain.cache import SQLiteCache# From LangChain, import standard modules for prompting.from langchain_core.prompts import PromptTemplatefrom langchain_core.output_parsers import StrOutputParserfrom langchain_core.runnables import RunnablePassthroughcolbertv2 = dspy.ColBERTv2(url='http://20.102.90.50:2017/wiki17_abstracts')dspy.configure(rm=colbertv2)set_llm_cache(SQLiteCache(database_path="cache.db"))llm = OpenAI(model_name="gpt-3.5-turbo-instruct", temperature=0)retrieve = lambda x: dspy.Retrieve(k=5)(x["question"]).passages# Just a simple prompt for this task. It's fine if it's complex too.prompt = PromptTemplate.from_template("Given {context}, answer the question `{question}` as a tweet.")# This is how you'd normally build a chain with LCEL. This chain does retrieval then generation (RAG).init_chain = RunnablePassthrough.assign(context=retrieve) | prompt | llm | StrOutputParser()
# From DSPy, import the modules that know how to interact with LangChain LCEL.from dspy.predict.langchain import LangChainPredict, LangChainModule# This is how to wrap it so it behaves like a DSPy program.# Just Replace every pattern like `prompt | llm` with `LangChainPredict(prompt, llm)`.zeroshot_chain = RunnablePassthrough.assign(context=retrieve) | LangChainPredict(prompt, llm) | StrOutputParser()
如上述代码,首先需要导入LangChainPredict类,该类集成自 langchain_core.runnables.Runnable 类 以及 dspy.Predict类,因此可以串联到链中。利用LangChainPredict包装原来的 提示词和大模型模块 并串联到链中,目前这条链与init_chain 中实现的功能完全一致。
zeroshot_chain = LangChainModule(zeroshot_chain)# then wrap the chain in a DSPy module.question = "In what region was Eddy Mazzoleni born?"zeroshot_chain.invoke({"question": question})
LangChainModule集成自dspy.Module,因此可以被优化器优化,此外LangChainModule实现了invoke方法,与Langchain的使用习惯一致。
from tweet_metric import metric, trainset, valset, devsetevaluate = Evaluate(metric=metric, devset=devset, num_threads=8, display_progress=True, display_table=5)evaluate(zeroshot_chain)
# Set up the optimizer. We'll use very minimal hyperparameters for this example.# Just do random search with ~3 attempts, and in each attempt, bootstrap <= 3 traces.optimizer = BootstrapFewShotWithRandomSearch(metric=metric, max_bootstrapped_demos=3, num_candidate_programs=3)# Now use the optimizer to *compile* the chain. This could take 5-10 minutes, unless it's cached.optimized_chain = optimizer.compile(zeroshot_chain, trainset=trainset, valset=valset)evaluate(optimized_chain)
可看出,优化之后optimized_chain的准确率有着明显的提高,达到了52.4%。此外,用户可以通过调整优化器的参数,使得得到的结果进一步提高。
总结
本文首先通过一个简单的例子,解释了DSPy如何从最基础的无示例CoT模块问答、到有示例CoT模块、再到构建数据集,并利用Metrics和Optimizer优化Module获得更高的预测准确率的预测和验证过程。然后展示了利用DSPy对LangChain的链的优化、测试、验证过程。DSPy可以有效降低提示词在切换大模型时的脆弱性、并且将提示词开发从手工开发转为抽象的代码开发,提供了更加系统化的方法。DSPy所提出的新范式,将对未来的大模型应用平台技术产生深远影响。
53AI,企业落地大模型首选服务商
产品:场景落地咨询+大模型应用平台+行业解决方案
承诺:免费POC验证,效果达标后再合作。零风险落地应用大模型,已交付160+中大型企业
2026-07-01
一文了解|SkillScan 智能体技能安全扫描最佳实践
2026-07-01
协作的逆向演进:从 Agent 逻辑重构团队管理
2026-07-01
港科大郭毅可谈Agentic AI时代的核心命题:人机共生,人不可能退场
2026-07-01
Sonnet 5终于来了,然而Opus 4.8现在有点尴尬
2026-07-01
AI可观测性:Prompt、Tool Call、Trace、Token全链路追踪
2026-07-01
AI Infra 全景图:Agent Framework、调度、编排、沙箱、记忆管理、Tracing 分层拆解
2026-07-01
Claude Science发布:60+科学数据库一个对话搞定
2026-07-01
AI 的向量空间里藏着心理学,这是一场嵌入模型的情绪对决
2026-04-15
2026-04-07
2026-04-07
2026-04-24
2026-04-17
2026-04-05
2026-04-05
2026-04-14
2026-04-24
2026-04-22
欢迎您使用【53AI 官方网站】(以下简称“本网站”或“我们”)。本《会员服务协议》(以下简称“本协议”)是您(以下简称“会员”或“用户”)与【深圳市博思协创网络科技有限公司】之间关于注册、登录及使用本网站会员服务所订立的法律协议。
在您注册或登录前,请务必审慎阅读、充分理解各条款内容,特别是免除或限制责任的条款、知识产权条款、争议解决条款等。此类条款将以加粗形式提示您注意。 当您通过微信公众号授权、手机验证码验证或其他方式成功登录本网站时,即视为您已完全理解并同意接受本协议的全部内容。
一、 定义
本网站:指由【深圳市博思协创网络科技有限公司】运营的,域名为【53ai.com】的网站及相关移动端页面。
会员服务:指本网站向注册会员提供的知识库文章查阅、内容检索及其他相关增值服务。
知识库内容:指本网站发布的包括但不限于文字、图表、数据、研究报告、行业分析等数字化内容资源。
二、 账号注册与登录
登录方式:本网站支持以下登录方式,您可根据实际情况选择:
微信公众号授权登录:您同意将您的微信OpenID信息授权给本网站,用于创建或关联会员账号。
手机验证码登录:您需提供真实有效的手机号码,并通过短信验证码完成身份验证与登录/注册。
账号安全:您的账号仅限您本人使用,禁止赠与、借用、租用、转让或售卖。因您保管不善导致的账号被盗、密码泄露等损失,由您自行承担。
实名认证:根据相关法律法规要求,我们可能要求您在特定功能下完成实名认证。如您拒绝提供,可能无法使用部分或全部服务。
未成年人保护:若您未满18周岁,请在法定监护人的陪同下阅读本协议,并在征得监护人同意后使用本服务。
三、 服务内容与规范
知识库查阅权限:会员登录后,有权按照其会员等级对应的权限范围,在线浏览、检索本网站知识库中的相关文章及内容。
服务变更:我们有权根据业务发展需要,调整、变更或终止部分服务内容,并将以网站公告、公众号消息等方式提前通知。
禁止行为:您在使用服务时不得实施以下行为:
利用技术手段批量爬取、下载、转存知识库内容;
将知识库内容用于商业目的或未经授权地向第三方传播;
干扰本网站正常运行或侵犯其他用户合法权益;
发布违法违规信息或从事违反公序良俗的活动。
四、 知识产权声明
权利归属:本网站知识库中的排版设计、软件代码等内容的知识产权均归【公司全称】或原权利人所有,受《中华人民共和国著作权法》等法律保护。
有限许可:本网站授予会员一项非独占、不可转让、不可转授权的普通许可,仅限于个人学习、研究之目的在线查阅知识库内容。
侵权追责:未经书面许可,任何单位或个人不得以任何形式复制、转载、摘编、镜像、汇编或以其他方式使用上述内容。一经发现,我们保留追究其法律责任的权利。
五、 个人信息保护
我们重视对您个人信息的保护。关于我们如何收集、使用、存储和保护您的个人信息,请单独阅读 《隐私政策》。
您通过微信公众号授权或手机号验证所提供的信息,我们将严格按照《个人信息保护法》的规定处理,仅用于身份识别、服务提供及安全验证等必要用途。
您可以随时通过网站设置或联系客服行使查阅、更正、删除个人信息及撤回授权同意的权利。
六、 免责声明
内容准确性:知识库内容仅供参考,不构成专业建议。我们不对其完整性、准确性、时效性作任何明示或暗示的保证,您应自行判断并承担使用风险。
不可抗力:因自然灾害、政策法规变化、网络故障、第三方平台接口异常(如微信接口维护、运营商短信通道故障)等不可抗力导致的服务中断或延迟,我们不承担违约责任。
第三方链接:本网站可能包含指向第三方网站的链接,该等网站的内容和服务不受我们控制,请您自行甄别风险。
七、 违约责任
如您违反本协议约定,我们有权视情节采取警告、限制功能、暂停服务、注销账号等措施,并保留要求赔偿损失的权利。
如因您的违约行为导致我们遭受行政处罚、第三方索赔或商誉损失,您应承担全部赔偿责任(包括但不限于罚款、赔偿金、律师费、公证费等)。
八、 法律适用与争议解决
本协议的订立、执行和解释均适用中华人民共和国大陆地区法律。
因本协议产生的或与本协议有关的任何争议,双方应友好协商解决;协商不成的,任何一方均可向【公司所在地】有管辖权的人民法院提起诉讼。
九、 其他
本协议构成双方就本服务达成的完整协议,取代此前任何口头或书面约定。
本协议任一条款被认定为无效或不可执行的,不影响其他条款的效力。
我们对本协议享有最终解释权,并在法律允许的范围内保留随时修改的权利。修改后的协议一经公布即生效,继续使用服务即视为同意修订内容。