【AI大模型应用开发】【LangChain系列】9. 实用技巧:大模型的流式输出在 OpenAI 和 LangChain 中的使用

  • 大家好,我是同学小张,日常分享AI知识和实战案例
  • 欢迎 点赞 + 关注 👏,持续学习持续干货输出
  • +v: jasper_8017 一起交流💬,一起进步💪。
  • 微信公众号也可搜【同学小张】 🙏

本站文章一览:

在这里插入图片描述


当大模型的返回文字非常多时,返回完整的结果会耗费比较长的时间。如果等待大模型形成完整的答案再展示给用户,明显会给用户不好的体验。所以,现在市面上大多数的AI应用,在给用户结果时,都是以流式输出的方式展示给用户的。所谓的流式输出,就是类似打字机式的方式,一个字或一个词的输出,给用户一种答案逐渐出现的动画效果。

今天我们来学习下如何流式输出大模型的返回结果。本文将涵盖 LangChain 的流式输出方式和 OpenAI 原生的流式输出方式。

文章目录

  • 0. LangChain的流式输出 Streaming
    • 0.1 实现流式输出
  • 1. OpenAI 原生的流式输出
    • 1.1 启动 OpenAI 的流式输出
    • 1.2 流式输出结果组装
    • 1.3 完整的流式输出测试程序

0. LangChain的流式输出 Streaming

0.1 实现流式输出

我们在 【AI大模型应用开发】【LangChain系列】实战案例4:再战RAG问答,提取在线网页数据,并返回生成答案的来源 代码的基础上,增加流式输出。

原代码:

import bs4
from langchain import hub
from langchain_community.document_loaders import WebBaseLoader
from langchain_community.vectorstores import Chroma
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from langchain_text_splitters import RecursiveCharacterTextSplitter# Load, chunk and index the contents of the blog.
loader = WebBaseLoader(web_paths=("https://lilianweng.github.io/posts/2023-06-23-agent/",),bs_kwargs=dict(parse_only=bs4.SoupStrainer(class_=("post-content", "post-title", "post-header"))),
)
docs = loader.load()text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
splits = text_splitter.split_documents(docs)
vectorstore = Chroma.from_documents(documents=splits, embedding=OpenAIEmbeddings())# Retrieve and generate using the relevant snippets of the blog.
retriever = vectorstore.as_retriever()
prompt = hub.pull("rlm/rag-prompt")
llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0)def format_docs(docs):return "\n\n".join(doc.page_content for doc in docs)from langchain_core.runnables import RunnableParallelrag_chain_from_docs = (RunnablePassthrough.assign(context=(lambda x: format_docs(x["context"])))| prompt| llm| StrOutputParser()
)rag_chain_with_source = RunnableParallel({"context": retriever, "question": RunnablePassthrough()}
).assign(answer=rag_chain_from_docs)result = rag_chain_with_source.invoke("What is Task Decomposition")
print(result)

修改为流式输出:

# result = rag_chain_with_source.invoke("What is Task Decomposition")
# print(result)
for chunk in rag_chain_with_source.stream("What is Task Decomposition"):print(chunk)

修改方式很简单,LangChain的Chain中已经帮我们封装好了 stream 接口,调用该接口获取的结果即为流式输出的结果。其输出的结果如下(每次输出一个词,词前面加一个Key,用来标识这是答案的哪一部分):

在这里插入图片描述
我们可以利用Key来组装答案:

output = {}
curr_key = None
for chunk in rag_chain_with_source.stream("What is Task Decomposition"):for key in chunk:if key not in output:output[key] = chunk[key]else:output[key] += chunk[key]if key != curr_key:print(f"\n\n{key}: {chunk[key]}", end="", flush=True)else:print(chunk[key], end="", flush=True)curr_key = key

这样我们看到的答案的打印过程就是一个词一个词的出现了。最后展示完跟非流式输出一样。

在这里插入图片描述

1. OpenAI 原生的流式输出

1.1 启动 OpenAI 的流式输出

只需要在OpenAI接口调用时,将stream参数置为True,就启用了流式输出。

response = client.chat.completions.create(model = model,messages = messages,temperature = temperature,stream=True,    # 启动流式输出
)

1.2 流式输出结果组装

结果的组装过程如下,流式输出的结果在 msg.choices[0].delta 中存着:

text = ""
print("====Streaming====")
# 需要把 stream 里的 token 拼起来,才能得到完整的 call
for msg in response:delta = msg.choices[0].deltaif delta.content:text_delta = delta.contentprint(text_delta)text = text + text_delta
print("====done!====")
if text:print(text)

1.3 完整的流式输出测试程序

from openai import OpenAI
# 加载 .env 到环境变量
from dotenv import load_dotenv, find_dotenv
_ = load_dotenv(find_dotenv())client = OpenAI()###### 这里封装成函数 #######
def get_openai_chat_completion(messages, temperature, model = "gpt-3.5-turbo-1106"):response = client.chat.completions.create(model = model,messages = messages,temperature = temperature,stream=True,    # 启动流式输出)return responseSYSTEM_PROMPT = """
你是一名资深教师,你叫“同学小张”,用户会给你一个提示,你根据用户给的提示,来为用户设计关于此课程的学习大纲。
你必须遵循以下原则:
1. 你有足够的时间思考,确保在得出答案之前,你已经足够理解用户需求中的所有关键概念,并给出关键概念的解释。
2. 输出格式请使用Markdown格式, 并保证输出内容清晰易懂。
3. 至少输出10章的内容, 每章至少有5个小节不要回答任何与课程内容无关的问题。
"""if __name__ == "__main__":user_input = "大模型应用开发"messages = [{"role": "system","content": SYSTEM_PROMPT,},{"role": "user","content": user_input,}   ]response = get_openai_chat_completion(messages, 0.5)text = ""print("====Streaming====")# 需要把 stream 里的 token 拼起来,才能得到完整的 callfor msg in response:delta = msg.choices[0].deltaif delta.content:text_delta = delta.contentprint(text_delta)text = text + text_deltaprint("====done!====")if text:print(text)

流式输出过程如下:

在这里插入图片描述
组装后结果如下:

在这里插入图片描述

如果觉得本文对你有帮助,麻烦点个赞和关注呗 ~~~


  • 大家好,我是 同学小张,日常分享AI知识和实战案例
  • 欢迎 点赞 + 关注 👏,持续学习持续干货输出
  • +v: jasper_8017 一起交流💬,一起进步💪。
  • 微信公众号也可搜同学小张 🙏

本站文章一览:

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/743292.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【RHCSA问答题】第十五章 访问Linux文件系统(上)

系列文章目录 第一章 红帽企业Linux入门 第二章 访问命令行 第三章 从命令行管理文件(上) 第三章 从命令行管理文件(下) 第五章 创建、查看和编辑文本文件(上) 第五章 创建、查看和编辑文本文件&#xff0…

Python使用openpyxl库或pandas库创建.xlsx格式的Excel文件,并向文件不同的sheet按行或按列写入内容

import openpyxl# 创建-一个Workbook对象 wb openpyxl.Workbook()# 创建多个工作表 sheet1 wb.active sheet1.title "s1"sheet2 wb.create_sheet("s2")# 在不同的工作表中写入数据 sheet1["A1"] Data for Sheet1 sheet1["A2"] D…

软考架构师-案例题分享(带答案)

目录 1.质量属性+架构风格2.UML建模3.数据流图4.大数据架构5.鸿蒙架构5.SOA和企业应用集成7.微服务和 SOA8. 架构评估9.数据库设计1.质量属性+架构风格 某软件公司为电子商城开发一套应用程序集成开发环境,以提高开发电子商城应用程序的质量和效率。在项目之初,公司的系统分…

「jQuery系列」jQuery 校验表单(Validate)

文章目录 一、校验表单(Validate)1. 基本用法2. 验证规则3. 国际化4. 插件扩展 二、Validate常用方法1. 基本验证2. 自定义验证规则3. 远程验证(通过 AJAX)4. 提交处理(submitHandler)5. 忽略某些元素的验证…

Edge浏览器可以多开的几种方法

新建用户数据目录: 首先,安装一个Edge浏览器或者谷歌浏览器。在电脑的D盘(或其他盘)新建一个文件夹,例如命名为“Edge”。在“Edge”文件夹下再新建两个子文件夹,分别命名为“Edge2”和“Edge3”&#xff0…

【2024年5月备考新增】《软考真题分章练习(答案解析) - 4 项目范围管理(高项)》

点击跳转无答案版 1、() includes the processes required to ensure that the project includes all the work required , and only the work required , to complete the project successfully . Managing the project scope is primarily concerned with defining and con…

数学问题难解?新研究提出MathScale方法,让AI更懂数学推理

引言:数学问题解决中的语言模型挑战 数学问题解决是一个复杂的认知过程,它要求参与者不仅要掌握数学知识,还要能够进行多步骤的逻辑推理。近年来,大语言模型(LLMs)在解决问题方面展现出了显著的能力&#…

18. 查看帖子详情

文章目录 一、建立路由二、开发GetPostDetailHandler三、编写logic四、编写dao层五、编译测试运行 一、建立路由 router/route.go v1.GET("/post/:id", controller.GetPostDetailHandler)二、开发GetPostDetailHandler controller/post.go func GetPostDetailHand…

java中集合类的使用场景和区别

无极低码 :https://wheart.cn Java Collection Interface 使用场景:Collection是所有单值集合类型的根接口,包括List、Set等。它提供了一组通用方法来添加、删除、检查元素存在性、获取集合大小等。区别:它是抽象概念,不关心元素是否有序或唯一。Java List Interface 使用…

java数据结构与算法刷题-----LeetCode90. 子集 II

java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完):https://blog.csdn.net/grd_java/article/details/123063846 文章目录 解题思路:时间复杂度O( n 2 ∗ n n^2*n n2∗n),空间复杂度O(n) 7…

C#中的小数

一、关于类型 在C#中,可以用以下数据类型来存放小数: float: 单精度浮点数(是32位单精度浮点数类型) 优点:占用空间小,适合存储大量小数值;性能较好。缺点:精度有限,可能…

JAVA初阶数据结构栈(工程文件后续会上传)(+专栏数据结构练习是完整版)

1.栈的概念讲解(Stack)) 定义:栈是一种先进后出的数据结构 要想拿到12就要把它头上的所有东西给移出去 2.栈的实现(代码) 2.1栈的方法逻辑的讲解 (1)新建一个测试类Frank (2)进…

机器学习模型—决策树

机器学习模型—决策树 决策树是最强大和最流行的算法之一。Python 决策树算法属于监督学习算法的范畴。它适用于连续输出变量和分类输出变量也就是可以处理分类和回归任务。在本文中,我们将在 UCI 上提供平衡秤体重和距离数据库上用 Python 算法实现决策树。 决策树算法,是…

【MySQL探索之旅】MySQL数据表的增删查改(初阶)

📚博客主页:爱敲代码的小杨. ✨专栏:《Java SE语法》 | 《数据结构与算法》 | 《C生万物》 |《MySQL探索之旅》 ❤️感谢大家点赞👍🏻收藏⭐评论✍🏻,您的三连就是我持续更新的动力❤️ &…

【Java设计模式】十九、中介者模式

文章目录 1、中介者模式2、案例3、总结 1、中介者模式 如图: 同事类之间关联较多时,整体出现网状结构,耦合度极高。一个对象一变动,好多对象都得改。若变为右边的星形结构,则一个类的变动,只影响自身与中介…

二叉树算法

递归序 每个节点都能回到3次! 相当于2执行完然后返回了代码会往下走,来到3节点 小总结: 也就是4节点先来到自己一次,不会执行if,先调用自己左边的那个函数,但是是null,直接返回。 这个函数执行完了,就会回到自己,调用自己右边的那个函数,结果又是空,又返回,回到…

在springboot中Redis数据与MySQL数据的一致性方案思考和案例

文章目录 前言一、双写一致性模式(同步)Redis->MySQLMySQL->Redis 二、数据监听模式(异步)Redis->MySQLMySQL -> Redis 总结 前言 Redis和MySQL之间保持数据一致性是个复杂的问题,搜索资料发现大部分也只…

鸿蒙API9+axios封装一个通用工具类

使用方式: 打开Harmony第三方工具仓,找到axios,如图: 第三方工具仓网址:https://ohpm.openharmony.cn/#/cn/home 在你的项目执行命令:ohpm install ohos/axios 前提是你已经装好了ohpm ,如果没…

【MySQL 系列】MySQL 函数篇

MySQL 提供了广泛的函数,用于处理各种数据类型,包括数值、字符串、日期和时间等。这些函数可以帮助你进行复杂的数据操作,改善数据查询的效率和灵活性。 文章目录 1、MySQL 函数介绍1.1、MySQL 函数简介2.1、MySQL 函数分类 2、MySQL 数学函数…

最适合Oracle数据库的Linux操作系统?

先声明:以下观点仅供参考。我只引用网上的一些观点,包括官网等。 Oracle数据库认证的Linux操作系统 最近老被问到Oracle Linux免费吗?因为用户需要安装Oracle数据库,面临选择操作系统的问题。 首先,Oracle数据库 19…