您的当前位置:首页>全部文章>文章详情

编写 ChatGPT 桌面版,改进版支持上下文对话

发表于:2023-06-25 11:30:41浏览:1646次TAG:

调用 ChatGPT 官方 API 接口的好处是没有登录地区限制,编写桌面版的好处是可以单用户独享,免费额度足够用了,不至于消耗太快。

网页版 ChatGPT 的上下文对话很棒,其实我们自己编写的桌面版也可以实现这个功能。今天小改了一下前几天发的源代码,支持上下文对话以后的效果:

图片alt
以下是完整源代码(使用 aardio 编写,复制粘贴到 aardio 编辑器直接点运行就可以了 )。

import win.ui;
/*DSG{{*/
var winform = win.form(text="ChatGPT 桌面智能助理";right=661;bottom=721)
/*}}*/

import web.view;
var wb = web.view(winform);

import web.rest.jsonClient;
var http = web.rest.jsonClient(); 

//参数请改成您的 API key(或者获取 API key 的网址也可以)。
http.setAuthToken("http://api.aardio.com/demo/openai/token2");
var ai = http.api("https://api.openai.com/v1/");

var conversation = {};
var chatGptName = "桌面智能助理";
var chatGptInfo = "是一个快乐的程序员,精通多种编程语言";

wb.external = {
    ask = function(q){
        table.push(conversation,"用户:"+q);

        var prompt;
        do{
            prompt =  "提示:你叫"
            + chatGptName + ","
            + chatGptInfo + "。<|endoftext|>"  
            + "当前时间:" + tostring(time()) + "。<|endoftext|>"  
            + string.join(conversation,"<|endoftext|>") 
            + "<|endoftext|>"
            + chatGptName + ":";

            if(#prompt < 2000) break; 

            table.shift(conversation);
        }while(true);    

        var ret,err = ai.completions({
            "prompt": prompt,//发送提示
            "model": "text-davinci-003",//GPT 3.5 模型
            "temperature": 0.8,//热度,0~1 之间。
            "max_tokens": 2048,//最大允许的字符数量 
            "stop": {"<|endoftext|>"}  
        })

        if(ret){
            var a = ret.choices[1].text; 
            table.push(conversation,chatGptName+":"+a);
            return a;
        }
        else {
            if(err[1]=='{'#){
                var errObject = web.json.tryParse(err)[["error"]];
                if(errObject[["code"]]="invalid_api_key"){
                    return "您的 API key 已经失效了!"; 
                } 

                if(errObject[["message"]]) return errObject[["message"]];
            }

            return err;
        }
    };    
} 

wb.html = /**
<!DOCTYPE html><html>
<head>
    <meta charset="utf-8" />
    <title>ChatGPT 桌面智能助理</title> 
    <script src="https://lib.baomitu.com/react/18.2.0/umd/react.production.min.js"></script>
    <script src="https://lib.baomitu.com/react-dom/18.2.0/umd/react-dom.production.min.js"></script> 
    <script src="https://lib.baomitu.com/chatui-core/2.4.2/index.min.js"></script> 
    <link rel="stylesheet" href="https://lib.baomitu.com/chatui-core/2.4.2/index.min.css"> 
    <script src="https://lib.baomitu.com/babel-standalone/7.20.14/babel.min.js"></script> 
    <style type="text/css">html,body,#app{height:100%}</style>
</head>
<body>  

<script type="text/babel"> 
    const { useState,useEffect,useCallback,useRef } =  React;  
    const { default: Chat, Bubble, useMessages } = ChatUI;  

    const App = () => {
        const { messages, appendMsg, setTyping } = useMessages([{
            type: 'text',
            content: { text: '主人好,我是桌面智能助理,您的贴心小助手~' },
            user: { avatar: 'https://gw.alicdn.com/tfs/TB1DYHLwMHqK1RjSZFEXXcGMXXa-56-62.svg' },
        }]);

        function handleSend(type, val) {
            if (type === 'text' && val.trim()) {
                appendMsg({
                    type: 'text',
                    content: { text: val },
                    position: 'right',
                });

                setTyping(true);

                aardio.ask(val).then( text=>{
                    appendMsg({
                        type: 'text',
                        content: { text: text },
                    });    
                }) 
            }
        }

        function renderMessageContent(msg) {
            const { content } = msg;
            return <Bubble content={content.text} />;
        }

        return (
            <Chat
                navbar={{ title: '' }}
                messages={messages}
                renderMessageContent={renderMessageContent}
                onSend={handleSend}
            />
        );
    };

    const root = ReactDOM.createRoot(document.getElementById('app'));
    root.render(<App />);

</script>
<div id="app"></div>
**/

winform.show();
win.loopMessage();
0.094105s