How can I change from OpenAI to ChatOpenAI in langchain and Flask?

news2024/11/15 20:02:20

题意:“在 LangChain 和 Flask 中,如何将 OpenAI 更改为 ChatOpenAI?”

问题背景:

This is an implementation based on langchain and flask and refers to an implementation to be able to stream responses from the OpenAI server in langchain to a page with javascript that can show the streamed response.

“这是一个基于 LangChain 和 Flask 的实现,用于将 OpenAI 服务器的响应流式传输到一个带有 JavaScript 的页面,该页面可以显示流式响应。”

I tried all ways to modify the code below to replace the langchain library from openai to chatopenai without success, i upload below both implementations (the one with openai working) and the one chatopenai with error. thank you to all the community and those who can help me to understand the problem, it would be very helpful if you could also show me how to solve it since I have been trying for days and the error it shows has really no significance.

“我尝试了所有方法修改下面的代码,将 LangChain 库从 OpenAI 替换为 ChatOpenAI,但没有成功。下面上传了两个实现(一个是使用 OpenAI 正常工作的版本,另一个是带有错误的 ChatOpenAI 版本)。感谢所有社区成员以及能够帮助我理解问题的人。如果你们能告诉我如何解决这个问题,那将非常有帮助,因为我已经尝试了好几天,而显示的错误并没有什么实际意义。”

Code version with library that works but reports as deprecated:

“这是使用库的代码版本,它可以正常工作但报告为已弃用:”

from flask import Flask, Response
import threading
import queue

from langchain.llms import OpenAI
from langchain.callbacks.base import BaseCallbackManager
from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler

app = Flask(__name__)

@app.route('/')
def index():
    return Response('''<!DOCTYPE html>
<html>
<head><title>Flask Streaming Langchain Example</title></head>
<body>
    <div id="output"></div>
    <script>
const outputEl = document.getElementById('output');

(async function() {
    try {
        const controller = new AbortController();
        const signal = controller.signal;
        const timeout = 120000; // Imposta il timeout su 120 secondi

        setTimeout(() => controller.abort(), timeout);

        const response = await fetch('/chain', {method: 'POST', signal});
        const reader = response.body.getReader();
        const decoder = new TextDecoder();
        let buffer = '';

        while (true) {
            const { done, value } = await reader.read();
            if (done) { break; }

            const text = decoder.decode(value, {stream: true});
            outputEl.innerHTML += text;
        }
    } catch (err) {
        console.error(err);
    }
})();

    </script>
</body>
</html>''', mimetype='text/html')


class ThreadedGenerator:
    def __init__(self):
        self.queue = queue.Queue()

    def __iter__(self):
        return self

    def __next__(self):
        item = self.queue.get()
        if item is StopIteration: raise item
        return item

    def send(self, data):
        self.queue.put(data)

    def close(self):
        self.queue.put(StopIteration)

class ChainStreamHandler(StreamingStdOutCallbackHandler):
    def __init__(self, gen):
        super().__init__()
        self.gen = gen

    def on_llm_new_token(self, token: str, **kwargs):
        self.gen.send(token)

def llm_thread(g, prompt):
    try:
        llm = OpenAI(
            model_name="gpt-4",
            verbose=True,
            streaming=True,

            callback_manager=BaseCallbackManager([ChainStreamHandler(g)]),
            temperature=0.7,
        )
        llm(prompt)
    finally:
        g.close()


def chain(prompt):
    g = ThreadedGenerator()
    threading.Thread(target=llm_thread, args=(g, prompt)).start()
    return g


@app.route('/chain', methods=['POST'])
def _chain():
    return Response(chain("Create a poem about the meaning of life \n\n"), mimetype='text/plain')

if __name__ == '__main__':
    app.run(threaded=True, debug=True)

Version with error (OpenAI replaced with ChatOpenAI)“

这是带有错误的版本(将 OpenAI 替换为 ChatOpenAI):”

import threading
import queue

from langchain.chat_models import ChatOpenAI
from langchain.callbacks.base import BaseCallbackManager
from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler

app = Flask(__name__)

@app.route('/')
def index():
    return Response('''<!DOCTYPE html>
<html>
<head><title>Flask Streaming Langchain Example</title></head>
<body>
    <div id="output"></div>
    <script>
const outputEl = document.getElementById('output');

(async function() {
    try {
        const controller = new AbortController();
        const signal = controller.signal;
        const timeout = 120000; // Imposta il timeout su 120 secondi

        setTimeout(() => controller.abort(), timeout);

        const response = await fetch('/chain', {method: 'POST', signal});
        const reader = response.body.getReader();
        const decoder = new TextDecoder();
        let buffer = '';

        while (true) {
            const { done, value } = await reader.read();
            if (done) { break; }

            const text = decoder.decode(value, {stream: true});
            outputEl.innerHTML += text;
        }
    } catch (err) {
        console.error(err);
    }
})();

    </script>
</body>
</html>''', mimetype='text/html')


class ThreadedGenerator:
    def __init__(self):
        self.queue = queue.Queue()

    def __iter__(self):
        return self

    def __next__(self):
        item = self.queue.get()
        if item is StopIteration: raise item
        return item

    def send(self, data):
        self.queue.put(data)

    def close(self):
        self.queue.put(StopIteration)

class ChainStreamHandler(StreamingStdOutCallbackHandler):
    def __init__(self, gen):
        super().__init__()
        self.gen = gen

    def on_llm_new_token(self, token: str, **kwargs):
        self.gen.send(token)

    def on_chat_model_start(self, token: str):
        print("started")

def llm_thread(g, prompt):
    try:
        llm = ChatOpenAI(
            model_name="gpt-4",
            verbose=True,
            streaming=True,

            callback_manager=BaseCallbackManager([ChainStreamHandler(g)]),
            temperature=0.7,
        )
        llm(prompt)
    finally:
        g.close()


def chain(prompt):
    g = ThreadedGenerator()
    threading.Thread(target=llm_thread, args=(g, prompt)).start()
    return g


@app.route('/chain', methods=['POST'])
def _chain():
    return Response(chain("parlami dei 5 modi di dire in inglese che gli italiani conoscono meno \n\n"), mimetype='text/plain')

if __name__ == '__main__':
    app.run(threaded=True, debug=True)

Error showing the console at startup and at the time I enter the web page:

“启动时和进入网页时控制台显示的错误:”

Error in ChainStreamHandler.on_chat_model_start callback: ChainStreamHandler.on_chat_model_start() got an unexpected keyword argument 'run_id'
Exception in thread Thread-4 (llm_thread):
127.0.0.1 - - [09/Sep/2023 18:09:29] "POST /chain HTTP/1.1" 200 -
Traceback (most recent call last):
  File "C:\Users\user22\Desktop\Work\TESTPROJ\env\Lib\site-packages\langchain\callbacks\manager.py", line 300, in _handle_event
    getattr(handler, event_name)(*args, **kwargs)
  File "C:\Users\user22\Desktop\Work\TESTPROJ\env\Lib\site-packages\langchain\callbacks\base.py", line 168, in on_chat_model_start
    raise NotImplementedError(
NotImplementedError: StdOutCallbackHandler does not implement `on_chat_model_start`

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\user22\AppData\Local\Programs\Python\Python311\Lib\threading.py", line 1038, in _bootstrap_inner    
    self.run()
  File "C:\Users\user22\AppData\Local\Programs\Python\Python311\Lib\threading.py", line 975, in run
    self._target(*self._args, **self._kwargs)
  File "c:\Users\user22\Desktop\Work\TESTPROJ\streamresp.py", line 90, in llm_thread
    llm(prompt)
  File "C:\Users\user22\Desktop\Work\TESTPROJ\env\Lib\site-packages\langchain\chat_models\base.py", line 552, in __call__
    generation = self.generate(
                 ^^^^^^^^^^^^^^
  File "C:\Users\user22\Desktop\Work\TESTPROJ\env\Lib\site-packages\langchain\chat_models\base.py", line 293, in generate
    run_managers = callback_manager.on_chat_model_start(
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\user22\Desktop\Work\TESTPROJ\env\Lib\site-packages\langchain\callbacks\manager.py", line 1112, in on_chat_model_start
    _handle_event(
  File "C:\Users\user22\Desktop\Work\TESTPROJ\env\Lib\site-packages\langchain\callbacks\manager.py", line 304, in _handle_event
    message_strings = [get_buffer_string(m) for m in args[1]]
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\user22\Desktop\Work\TESTPROJ\env\Lib\site-packages\langchain\callbacks\manager.py", line 304, in <listcomp>
    message_strings = [get_buffer_string(m) for m in args[1]]
                       ^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\user22\Desktop\Work\TESTPROJ\env\Lib\site-packages\langchain\schema\messages.py", line 52, in get_buffer_string
    raise ValueError(f"Got unsupported message type: {m}")
ValueError: Got unsupported message type: p

thank you very much for the support!

“非常感谢您的支持!”

问题解决:

Thanks to python273 user on github I've resolved:

“感谢 GitHub 上的用户 python273,我已经解决了这个问题。”

import os
os.environ["OPENAI_API_KEY"] = ""

from flask import Flask, Response, request
import threading
import queue

from langchain.chat_models import ChatOpenAI
from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler
from langchain.schema import AIMessage, HumanMessage, SystemMessage

app = Flask(__name__)

@app.route('/')
def index():
    # just for the example, html is included directly, move to .html file
    return Response('''
<!DOCTYPE html>
<html>
<head><title>Flask Streaming Langchain Example</title></head>
<body>
    <form id="form">
        <input name="prompt" value="write a short koan story about seeing beyond"/>
        <input type="submit"/>
    </form>
    <div id="output"></div>
    <script>
        const formEl = document.getElementById('form');
        const outputEl = document.getElementById('output');

        let aborter = new AbortController();
        async function run() {
            aborter.abort();  // cancel previous request
            outputEl.innerText = '';
            aborter = new AbortController();
            const prompt = new FormData(formEl).get('prompt');
            try {
                const response = await fetch(
                    '/chain', {
                        signal: aborter.signal,
                        method: 'POST',
                        headers: {'Content-Type': 'application/json'},
                        body: JSON.stringify({
                            prompt
                        }),
                    }
                );
                const reader = response.body.getReader();
                const decoder = new TextDecoder();
                while (true) {
                    const { done, value } = await reader.read();
                    if (done) { break; }
                    const decoded = decoder.decode(value, {stream: true});
                    outputEl.innerText += decoded;
                }
            } catch (err) {
                console.error(err);
            }
        }
        run();  // run on initial prompt
        formEl.addEventListener('submit', function(event) {
            event.preventDefault();
            run();
        });
    </script>
</body>
</html>
''', mimetype='text/html')

class ThreadedGenerator:
    def __init__(self):
        self.queue = queue.Queue()

    def __iter__(self):
        return self

    def __next__(self):
        item = self.queue.get()
        if item is StopIteration: raise item
        return item

    def send(self, data):
        self.queue.put(data)

    def close(self):
        self.queue.put(StopIteration)

class ChainStreamHandler(StreamingStdOutCallbackHandler):
    def __init__(self, gen):
        super().__init__()
        self.gen = gen

    def on_llm_new_token(self, token: str, **kwargs):
        self.gen.send(token)

def llm_thread(g, prompt):
    try:
        chat = ChatOpenAI(
            verbose=True,
            streaming=True,
            callbacks=[ChainStreamHandler(g)],
            temperature=0.7,
        )
        chat([HumanMessage(content=prompt)])
    finally:
        g.close()


def chain(prompt):
    g = ThreadedGenerator()
    threading.Thread(target=llm_thread, args=(g, prompt)).start()
    return g


@app.route('/chain', methods=['POST'])
def _chain():
    return Response(chain(request.json['prompt']), mimetype='text/plain')

if __name__ == '__main__':
    app.run(threaded=True, debug=True)

Link to the original reply: https://gist.github.com/python273/563177b3ad5b9f74c0f8f3299ec13850

“原始回复的链接: https://gist.github.com/python273/563177b3ad5b9f74c0f8f3299ec13850”

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

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

相关文章

力扣763-划分字母区间(Java详细题解)

题目链接&#xff1a;763. 划分字母区间 - 力扣&#xff08;LeetCode&#xff09; 前情提要&#xff1a; 因为本人最近都来刷贪心类的题目所以该题就默认用贪心方法来做。 贪心方法&#xff1a;局部最优推出全局最优。 如果一个题你觉得可以用局部最优推出全局最优&#xf…

云服务器系统盘存储空间不够用怎么办?解决方法:扩容或挂载数据盘

云服务器系统盘满了不够用怎么办&#xff1f;服务器百科&#xff1a;可以系统盘扩容&#xff0c;也可以通过挂载数据盘来增大存储空间。 1、系统盘扩容教程&#xff1a;使用云服务器系统盘空间不足时&#xff0c;可以在ECS控制台上扩容云盘的容量以增加存储空间。阿里云支持云…

MCU3.电平等一些名词

1.电平的简单定义 计算机由各种硬件组成&#xff0c;只认识0和1&#xff0c;可以通过改变电压来向计算机输入数据&#xff08;0和1&#xff09; 例如&#xff1a;最大电压为3.3V 电压范围是0~3.3V&#xff0c;可以定义0~1V较低的电压表示0&#xff0c;定义2~3.3V较高的电压表…

领域驱动设计——大型结构(Large-Scale Structure)的综合运用

在一个大的、复杂的系统中&#xff0c;可能需要在一个设计中综合运用几种策略。那么&#xff0c;大型结构如何与CONTEXT MAP共存?应该把构造块放到哪里?第一步先做什么?第二步和第三步呢?如何设计你的战略? 把大型结构与BOUNDED CONTEXT结合起来使用 战略设计的3个基本原…

SpringBoot中@Value获取值和@ConfigurationProperties获取值用法及比较

SpringBoot中Value获取值和ConfigurationProperties获取值用法及比较 更新时间&#xff1a;2024年08月08日 09:41:48 作者&#xff1a;岳轩子 在Spring Boot中,Value注解是一个非常有用的特性,它允许我们将外部的配置注入到我们的Bean中,ConfigurationProperties用于将配置文件…

理解调试和组织 CSS——WEB开发系列26

CSS&#xff08;层叠样式表&#xff09;不仅是为网页提供样式的关键工具&#xff0c;也是调试和优化网页表现的重要部分。无论是调整网页布局&#xff0c;还是确保样式的一致性&#xff0c;掌握调试和组织 CSS 的技巧都是至关重要的。 一、使用浏览器开发者工具 浏览器开发者工…

【国外比较权威的免费的卫星数据网站——Sentinel Open Access Hub】

Sentinel Open Access Hub 网址&#xff1a;https://scihub.copernicus.eu/dhus/#/home简介&#xff1a;哨兵系列卫星科研数据中心&#xff08;Sentinel Open Access Hub&#xff09;是欧洲航天局&#xff08;ESA&#xff09;提供卫星数据的官方网站。该网站提供哨兵系列卫星的…

八、2 DMA数据转运 DMA函数介绍

把数组定义在Flash中&#xff0c;可以节省SRAM的空间 去掉const不会影响程序运行&#xff0c;但会占用SRAM的空间 1、步骤 &#xff08;1&#xff09;RCC开启DMAD的时钟 &#xff08;2&#xff09;调用DMA_Init&#xff0c;初始化参数 &#xff08;3&#xff09;调用DMA_Cmd…

Java的动态代理(实际案例秒懂!)

在看动态代理解决两个案例之前&#xff0c;请先看链接VCR 《java代理》2分钟动画_哔哩哔哩_bilibili 一.动态代理-精致小案例 需求分析 传统方法 就是定义一个接口&#xff0c;然后实现类去实现规定的run方法 缺点&#xff1a;代码很冗余&#xff0c;有一些运行前和运行后…

C++ | Leetcode C++题解之第385题迷你语法分析器

题目&#xff1a; 题解&#xff1a; class Solution { public:int index 0;NestedInteger deserialize(string s) {if (s[index] [) {index;NestedInteger ni;while (s[index] ! ]) {ni.add(deserialize(s));if (s[index] ,) {index;}}index;return ni;} else {bool negati…

超实用!如何用搜索引擎提升你的工作效率

平常用的Google浏览器比较多&#xff0c;所以分享下Google Chrome一些能提高工作效率的配置和操作以及如何巧妙利用Google搜索技巧快速找我们想要的数据 1. 浏览器设置 1. 搜索引擎快速切换 使用效果&#xff1a; 2. 历史记录快速打开 效果展示&#xff1a; 3. 隐藏显示书…

线性约束最小方差准则(LCMV)波束形成算法及MATLAB深入仿真分析

阵列信号处理——线性约束最小方差准则(LCMV)波束形成算法及MATLAB深入仿真分析 目录 前言 一、LCMV算法 二、仿真参数设置 三、抗干扰权值计算仿真 四、不同干扰方位下抗干扰性能仿真 五、不同信噪比和干噪比下抗干扰性能仿真 总结 前言 在信号处理模块中&#xff0c;通…

Vue——认识day06_class与style绑定

在Vue中&#xff0c;可以使用v-bind指令来将CSS样式动态地绑定到HTML元素上。有两种方式可以实现CSS与style的绑定&#xff1a; 对象语法&#xff1a;可以将一个包含CSS属性和值的对象传递给v-bind&#xff0c;将对象的属性与HTML元素的style属性进行绑定。例如&#xff1a; …

使用 Docker 搭建企业级私有仓库HARBOR

目录 1 HARBOR 的获取 1.1 下载软件包地址 1.2 HARBOR 的介绍 2 部署harbor 2.1 仓库端操作 2.1.1 修改harbor配置文件 2.1.2 生成服务端的证书与秘钥 2.1.3 管理HARBOR 2.1.4 查看是否运行 2.2 客户端操作 2.2.1 证书拷贝给客户端 2.2.2 环境配置 2.2.3 批量读取本地镜像 2.2…

Transformer面试真题详解——覆盖99%的Transformer面试问题(建议收藏)

文章目录 1. 请简述一下Transformer的基本结构和原理2. Transformer为什么使用多头注意力机制3. Transformer计算attention为什么选择点乘而不是加法&#xff1f;两个计算复杂度和效果上有什么区别&#xff1f;4. 为什么在softmax之后要对attention进行scaled&#xff08;为什么…

dubbo之时间轮算法分析

文章目录 前言一、参数说明二、具体实现1、HashedWheelTimer2、createWheel3、newTimeout4、start5、run6、waitForNextTick7、transferTimeoutsToBuckets8、expireTimeouts 总结 前言 时间轮&#xff08;TimingWheel&#xff09;是一种高效利用线程资源进行批量化调度的算法&…

ffmpeg音频编码

音视频播放的流程 根据我之前的文章 我们已经从解复用&#xff0c;解码得到原始数据&#xff0c;现在我们逆向&#xff0c;将frame转化packet。也就是原始数据转化为压缩后的数据文件。 介绍 PCM样本格式 PCM(Pulse Code Modulation&#xff0c;脉冲编码调制)⾳频数据是未经…

离散数学------关系理论

一、序偶和笛卡尔积 序偶 两个序偶如果相等&#xff0c;那么他们相对应的第一第二元素分别相等 笛卡尔积 笛卡尔积是集合之间的一种运算&#xff0c;运算的结果是个序偶&#xff0c;第一元素来自前面的集合&#xff0c;第二元素来自后面的集合。 两集合进行笛卡尔积运算后集合…

UE5学习笔记20-给游戏添加声音

一、准备音频资源 1.Jump文件夹中有跳跃的音频资源wav文件夹中是SoundCue的音波资源 2.音乐衰减文件&#xff0c;右键->音频->音效衰减 二、 在对应的动画资源处将音频添加 1.找到对应的动画帧 2.在对应的行右键添加通知->播放音效 3、选中添加的音效选择对应的音频资…

拦截通信助理,拦截小秘书技术

有人叫做空号识别&#xff0c;有人称为彩铃识别&#xff0c;磐石云通过嵌入软交换进行实时识别前期媒体 案例&#xff1a; 王总公司有20坐席的员工回访用户服务满意度业务&#xff0c;由于用户开通了语音秘书和通信助理&#xff0c;漏话提醒等等&#xff0c;坐席拨打时对方由…