LCEL是专门为方便开发LLM应用而设计的编程语言,它提供了一系列直观、好用的功能和语法。
本篇我们来学习提升LLM应用体验的一个功能——stream流式输出。
1. LCEL流式输出接口-stream
(1)为什么要用流式输出
在使用LLM应用时,用户总是期望立即得到答案,不管他的问题有多么复杂,或者让LLM生成的文本有多么长。
“流式输出“这时就派上用场了,它能够使LLM在生成文本时逐步提供结果,而不是等到整个文本生成完成后再一次性返回给用户。
流式输出的方式有以下几个优点:
- 实时性:不用等待整个文本生成完毕再返回结果,减少响应时间,用户获得实时响应体验。
- 交互性:生成结果逐步提供,可匹配用户阅读速度,增强交互感。
- 节省资源和带宽:逐步返回生成的结果可以减少对网络带宽的需求。
- 支持长文本生成:生成长文本时无需担心超出内存限制。
总之,流式输出可以让用户得到更好的体验,让用户觉得你的LLM程序”性能“很棒。
(2)流式输出接口的使用
LangChain在Runnable协议中定义了流式输出方法stream,以及它的异步方法astream。
LangChain的很多组件都是遵循Runnable的对象,可以直接调用stream/astream方法。以之前专栏多次构建过的链chain为例:
chain.stream()
chain.astream()
2.快速上手
以让LLM生成一首诗为例,对比下直接输出、流式输出的差异效果。
任务链的构建不再赘述,如下代码,我们构建了名为chain
的链,它的功能是根据输入的主题生成一首诗。
(1)使用invoke方法直接调用
- 调用语法:chain.invoke(“犀牛”)
- 执行效果:任务启动后,没有立即得到响应;大概6秒后,生成结果一次性闪现。
(2)使用stream方法流式输出
- 调用语法:chain.stream(“犀牛”)
- 注意:由于stream()是迭代输出,因此用for语句来循环遍历输出结果。
- 执行效果:任务启动后,立即得到响应,以一定的字频逐行输出结果。
- 如果想用异步方式astream,则调用语法如下:
(3) 对比总结 Invoke vs Stream
对于一个交互式的LLM应用程序,stream流式输出的响应实时性和交互体验都更好。
在 Python 中,没有名为"stream” 的内置方法,但是有类似于流式操作的机制,比如生成器(yield)、迭代器(iterator)。所以,如果没有LCEL提供的stream方法,而是要我们自己来实现的话,将是一件费脑筋的事。
如下是不使用LCEL实现流式输出的示例代码,可以跟上面简单的一行方法调用对比下:
LangChain的大牛们用python实现了与Java “Stream API"类似的流式处理方法,极大的方便了开发人员。
某种意义上来说,LangChain不仅仅是定义了一套Runnable协议,也是对Python语法的重构,构建了自己的语法——LCEL。
3.小结
本文解读了LangChain LCEL语法中提升性能的一种方法——stream流式输出。关键要点如下:
流式输出接口
- “流式输出"使LLM在生成文本时逐步提供结果,提升LLM应用程序的性能,让用户得到更好的体验。
- LangChain的Runnable对象可以直接调用stream/astream方法。
实例演示
- 对比invoke直接输出和stream流式输出的效果差异。
参考文档:翻译的LangChain官方文档
- 翻译链接:https://jherculesqz.gitbook.io/langchain-guan-fang-wen-dang