2023年的深度学习入门指南(10) = 前端同学如何进行chatgpt开发

news2024/11/28 20:56:19

2023年的深度学习入门指南(10) = 前端同学如何进行chatgpt开发

在第二篇,我们使用openai的python库封装,搞得它有点像之前学习的PyTorch一样的库。这一节我们专门给它正下名,前端就是字面意义上的前端。

给gpt4写前端

下面我们写一个最土的使用gpt4 API的页面,就一个输入框加一个回显的区域。

我们先写HTML页面:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>gpt4聊天机器人</title>
    <link rel="stylesheet" href="styles.css">
    <link rel="stylesheet"
          href="default.min.css">
    <script src="highlight.min.js"></script>
</head>
<body>
<div class="container">
    <h1>gpt4聊天机器人</h1>
    <form id="inputForm">
        <label for="userInput">请输入聊天内容:</label>
        <input type="text" id="userInput" name="userInput">
        <button type="submit">提交</button>
    </form>
    <div id="response">
        <h2>来自gpt4的回复:</h2>
        <div id="responseText"></div>
    </div>
</div>
<script src="script.js"></script>
</body>
</html>

我对代码的显示格式比较看重,所以增加了highlight.js来高亮代码,可以到https://highlightjs.org/download/ 这里去下载最新版本放到本地。
其它的就是一个form加上一个div。

然后是javascript,首先是响应submit事件的处理:

document.getElementById("inputForm").addEventListener("submit", async (event) => {
    event.preventDefault();
    const userInput = document.getElementById("userInput").value;

    if (userInput) {
        const responseText = document.getElementById("responseText");
        responseText.innerHTML = "gpt4正在思考中...";
        const apiResponse = await callOpenAI(userInput);
    }
});

接着是调用OpenAI API的部分了,因为我们没有后端,所以key暂时先明文写到网页里。

async function callOpenAI(userInput) {
    const apiKey = "你的openai api key";
    const apiURL = "https://api.openai.com/v1/chat/completions";

    const requestOptions = {
        method: "POST",
        headers: {
            "Content-Type": "application/json",
            "Authorization": `Bearer ${apiKey}`
        },
        body: JSON.stringify({
            model: "gpt-4",
            messages: [
                {role: "system", content: "You are a skilled software engineer."},
                {role: "user", content: userInput}
            ],
            max_tokens: 4096,
            n: 1,
            stop: null,
            temperature: 1
        })
    };

    try {
        const response = await fetch(apiURL, requestOptions);
        const data = await response.json();
        const responseTextElement = document.getElementById("responseText");
        responseTextElement.innerHTML = parseAndHighlightCode(data.choices[0].message.content);
        // Apply highlight to all <code> elements
        const codeBlocks = responseTextElement.getElementsByTagName("code");
        for (const codeBlock of codeBlocks) {
            hljs.highlightBlock(codeBlock);
        }
    } catch (error) {
        console.error("Error:", error);
        responseText.innerHTML = "An error occurred while fetching the response.";
    }
}

大家注意这部分参数:

            model: "gpt-4",
            messages: [
                {role: "system", content: "You are a skilled software engineer."},
                {role: "user", content: userInput}
            ],

模型根据需要来选择,一般选择chatgpt,也就是’gpt-3.5-turbo’.
另外还有角色的部分,根据场景的不同,可以给system角色以更多的提示。

最后是解析代码并高亮的部分:

function parseAndHighlightCode(text) {
    text = String(text); // Ensure 'text' is a string
    const regex = /```(\w+)?\s*([\s\S]*?)```/g;
    return text.replace(regex, (match, language, code) => {
        const langClass = language ? ` class="${language}"` : '';
        return `<pre><code${langClass}>${code.trim()}</code></pre>`;
    });
}

该函数的作用是在输入的文本中搜索用三个反引号包裹的代码块,并将其包裹在 HTML 的 <pre><code> 标签中,如果代码块开头的反引号中指定了编程语言,还会在 <code> 标签中添加一个 class 属性。

这个函数首先将 text 参数转换为字符串类型,确保它是一个字符串。然后,它使用 RegExp 构造函数创建一个正则表达式对象,这个正则表达式对象可以匹配以三个反引号开始和结束的代码块,并且可以在反引号内指定编程语言。

样式都是chatgpt给生成的,我只是改了下支持换行显示:

body {
    font-family: Arial, sans-serif;
    background-color: #f0f0f0;
    margin: 0;
    padding: 0;
}

.container {
    max-width: 800px;
    margin: 0 auto;
    padding: 2rem;
    background-color: #ffffff;
    box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1);
}

form {
    display: flex;
    flex-direction: column;
}

input {
    margin-bottom: 1rem;
    padding: 0.5rem;
    font-size: 1rem;
}

button {
    background-color: #0077cc;
    color: #ffffff;
    padding: 0.5rem;
    font-size: 1rem;
    border: none;
    cursor: pointer;
    margin-bottom: 2rem;
}

button:hover {
    background-color: #0055a5;
}
#responseText {
    white-space: pre-wrap;
}

修改输入框高度

只支持一行看起来不太好,那干脆我们多支持几行:

<div class="container">
    <h1>gpt4聊天机器人</h1>
    <form id="inputForm">
        <label for="userInput">请输入聊天内容:</label>
        <!--input type="text" id="userInput" name="userInput"-->
        <textarea id="userInput" rows="10" cols="50" placeholder="请输入内容"></textarea>
        <button type="submit">提交</button>
    </form>
    <div id="response">
        <h2>来自gpt4的回复:</h2>
        <div id="responseText"></div>
    </div>
</div>

这样输入大段文本的时候能更舒服一点。

我们还可以将其改成文本区域自动适应的。

我们可以给textarea增加一个oninput事件处理函数:

<textarea id="userInput" rows="1" cols="80" placeholder="请输入内容" oninput="autoResize(this)"></textarea>

实现起来也很简单,将高度改成auto:

function autoResize(textarea) {
    textarea.style.height = 'auto'; // Reset the height to 'auto'
    textarea.style.height = textarea.scrollHeight + 'px'; // Set the new height based on scrollHeight
}

为了能够让页面加载时也根据内容调整,我们给DOMContentLoaded事件上注册一个函数:

document.addEventListener('DOMContentLoaded', () => {
    const userInput = document.getElementById('userInput');
    autoResize(userInput);
});

让chatgpt成为有身份的人

我们知道,在chatgpt的使用中,告诉chatgpt具体的情境会大大提升准确率。
于是我们给角色增加一个输入框吧:

<div class="container">
    <h1>gpt4聊天机器人</h1>
    <form id="inputForm">
        <label for="userInput">请输入聊天内容:</label>
        <!--input type="text" id="userInput" name="userInput"-->
        <textarea id="userInput" rows="1" cols="80" placeholder="请输入内容" oninput="autoResize(this)"></textarea>
        <button type="submit">提交</button>
    </form>
    <div id="system-input">
        <h2>你希望gpt4扮演一个什么样的角色</h2>
        <input id="systemInput" type="text" placeholder="你是一个友好的聊天机器人"/>
    </div>
    <div id="response">
        <h2>来自gpt4的回复:</h2>
        <div id="responseText"></div>
    </div>
</div>

然后将用户输入发给openai:

    const systemInput = document.getElementById("systemInput").value;

    const requestOptions = {
        method: "POST",
        headers: {
            "Content-Type": "application/json",
            "Authorization": `Bearer ${apiKey}`
        },
        body: JSON.stringify({
            model: "gpt-4",
            messages: [
                {role: "system", content: systemInput},
                {role: "user", content: userInput}
            ],
            max_tokens: 4096,
            n: 1,
            stop: null,
            temperature: 1
        })
    };

样式有点难看啊,我们写个样式吧:

#system-input {
    display: flex;
    flex-direction: column;
    align-items: center;
    margin-bottom: 20px;
}

#system-input h2 {
    margin-bottom: 10px;
}

#systemInput {
    font-size: 16px;
    padding: 8px 12px;
    width: 100%;
    max-width: 500px;
    border: 1px solid #ccc;
    border-radius: 4px;
    box-sizing: border-box;
    outline: none;
    transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
}

#systemInput:focus {
    border-color: #66afe9;
    box-shadow: 0 0 4px rgba(102, 175, 233, 0.6);
}

chatgpt回复部分也稍微调下样式:

#response {
    display: flex;
    flex-direction: column;
    align-items: center;
    margin-bottom: 20px;
}

#response h2 {
    margin-bottom: 10px;
}

#responseText {
    font-size: 16px;
    padding: 15px;
    width: 100%;
    max-width: 600px;
    border: 1px solid #ccc;
    border-radius: 4px;
    background-color: #f8f9fa;
    box-sizing: border-box;
    white-space: pre-wrap; /* Ensures line breaks are maintained */
    word-wrap: break-word; /* Allows long words to wrap onto the next line */
}

总之调整下样式吧。

样子写下来大致是:

body {
    font-family: 'Noto Sans SC', sans-serif;
    font-size: 16px;
    line-height: 1.6;
    color: #333;
}

.container {
    max-width: 800px;
    margin: 0 auto;
    padding: 2rem;
    background-color: #ffffff;
    box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1);
}

h1 {
    font-size: 2.5em;
    font-weight: bold;
    text-align: center;
    margin: 20px 0;
    color: #333;
}

h2 {
    margin-bottom: 10px;
    font-weight: bold;
    text-align: center;
}

form {
    display: flex;
    flex-direction: column;
    align-items: center;
    margin-bottom: 20px;
    
}

label {
    display: inline-block;
    font-size: 1.2em;
    font-weight: bold;
    color: #333;
    margin-bottom: 10px;
}

#userInput {
    font-size: 16px;
    padding: 8px 12px;
    width: 100%;
    max-width: 500px;
    border: 1px solid #ccc;
    border-radius: 4px;
    box-sizing: border-box;
    outline: none;
    transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
    margin-bottom: 20px;
}

#userInput:focus {
    border-color: #66afe9;
    box-shadow: 0 0 4px rgba(102, 175, 233, 0.6);
}

button {
    font-size: 1em;
    font-weight: bold;
    color: #fff;
    background-color: #007bff;
    border: none;
    border-radius: 4px;
    padding: 7px 20px;
    cursor: pointer;
    transition: background-color 0.2s ease-in-out;
    margin-bottom: 20px;
}

button:hover {
    background-color: #0056b3;
}


#response {
    display: flex;
    flex-direction: column;
    align-items: center;
    margin-bottom: 20px;
}

#responseText {
    font-size: 16px;
    padding: 15px;
    width: 100%;
    max-width: 600px;
    border: 1px solid #ccc;
    border-radius: 4px;
    background-color: #f8f9fa;
    box-sizing: border-box;
    white-space: pre-wrap; /* Ensures line breaks are maintained */
    word-wrap: break-word; /* Allows long words to wrap onto the next line */
}

#systemInput {
    font-size: 16px;
    padding: 8px 12px;
    width: 100%;
    max-width: 500px;
    border: 1px solid #ccc;
    border-radius: 4px;
    box-sizing: border-box;
    outline: none;
    transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
    margin-bottom: 20px;
}

#systemInput:focus {
    border-color: #66afe9;
    box-shadow: 0 0 4px rgba(102, 175, 233, 0.6);
}

增加模型选择功能

我们再增加一个选择使用gpt4还是chatgpt的功能吧,先加元素:

<div class="container">
    <h1>gpt4聊天机器人</h1>
    <form id="inputForm">
        <label for="userInput">请输入聊天内容</label>
        <textarea id="userInput" rows="1" cols="80" placeholder="请输入内容" oninput="autoResize(this)"></textarea>
        <label for="systemInput">你希望gpt4扮演一个什么样的角色</label>
        <input id="systemInput" type="text" placeholder="你是一个友好的聊天机器人"/>
        <div id="model-selection">
            <label for="modelSelect">选择模型类型</label>
            <select id="modelSelect">
                <option value="gpt-4">GPT-4</option>
                <option value="gpt-3.5-turbo">GPT-3.5 Turbo</option>
            </select>
        </div>
        <button type="submit">提交</button>
    </form>
    <div id="response">
        <h2>来自gpt4的回复:</h2>
        <div id="responseText"></div>
    </div>
</div>

再加代码:

    const systemInput = document.getElementById("systemInput").value;
    const model = document.getElementById("modelSelect").value;

    const requestOptions = {
        method: "POST",
        headers: {
            "Content-Type": "application/json",
            "Authorization": `Bearer ${apiKey}`
        },
        body: JSON.stringify({
            model: model,
            messages: [
                {role: "system", content: systemInput},
                {role: "user", content: userInput}
            ],
            max_tokens: 4096,
            n: 1,
            stop: null,
            temperature: 1
        })
    };

最后加上样式:

#model-selection {
    display: flex;
    flex-direction: column;
    align-items: center;
    margin-bottom: 20px;
}

#modelSelect {
    font-size: 1em;
    padding: 8px;
    border: 1px solid #ccc;
    border-radius: 4px;
    outline: none;
    cursor: pointer;
}

看看效果:
在这里插入图片描述

小结

从上面一步一步的例子,我们可以看到,前端对于用户更好地使用大模型有着不可替代的重要作用。
上面的功能我们还可以不断增加下去,比如我们可以增加例子,保存记录,反馈错误等等。

虽然没有写一行python代码,也没有微调模型(当然是可以做的),但是这里面是有对于AI的深刻理解的。

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

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

相关文章

“BIM+智慧工地”精准“数字化”变身智慧工程“管家”

用手机对着满载钢筋的卡车拍照&#xff0c;手指选定一下钢筋范围&#xff0c;几秒后&#xff0c;屏幕就能迅速识别车上有多少根钢筋——这是建筑产业数字化管理智慧工程的应用领域之一。 投资1.78亿元建设的贵州民航产教融合实训基地是集实践教学、社会培训、企业生产保障和科研…

学历与就业:我对“孔乙已长衫”现象的思考

一、你认为社会对于学历和职业之间的关系认知是怎样的&#xff1f; 在当前的社会中&#xff0c;学历往往被看作是一个人能否获得好工作的重要标准。许多用人单位更愿意录取拥有更高学历的求职者&#xff0c;因为他们通常具备更广阔的知识视野和更强的理论基础。然而&#xff0…

Presto之Left Join和Right Join的实现

一. 前言 我们知道&#xff0c;在Presto中&#xff0c;与inner join相比&#xff0c;left join会保留probe表&#xff08;左表&#xff09;的所有值&#xff0c;right join会保留build表&#xff08;右表&#xff09;的所有值。inner join的是实现在文章Presto之Hash Join 数据…

攻击者可以使用HTML和CSS隐藏“外部发件人”电子邮件警告

导语&#xff1a;研究人员近日证实&#xff0c;Microsoft Outlook等客户端向电子邮件收件人显示的“外部发件人”警告可能被发件人隐藏。 研究人员近日证实&#xff0c;Microsoft Outlook等客户端向电子邮件收件人显示的“外部发件人”警告可能被发件人隐藏。 事实证明&#x…

【数据结构】一篇带你彻底玩转 链表

文章目录 链表的概念及结构链表的分类链表接口的实现链表打印链表申请节点链表尾插链表头插链表尾删链表头删链表查找链表在指定位置之后插入数据链表删除指定位置之后的数据链表在指定位置之前插入数据链表删除指定位置之前的数据链表删除指定位置的数据链表的销毁 链表的概念…

总结835

学习目标&#xff1a; 4月&#xff08;复习完高数18讲内容&#xff0c;背诵21篇短文&#xff0c;熟词僻义300词基础词&#xff09; 学习内容&#xff1a; 暴力英语&#xff1a;熟练背诵《大独裁者》&#xff0c;最后默写。抄写今后要背诵的两篇文章。 高等数学&#xff1a;做…

机器视觉各开发语言对比以及选择

机器视觉主流开发语言主要有, 一.C#,占有率极高 市面主要以Halcon,visionpro,visionmaster,opencvsharp为主。 开发人员利用 C# 能够生成在 .NET 中运行的多种安全可靠的应用程序。 二.C++,Qt 市面主要以Halcon,visionpro,visionmaster,opencv为z主。 C++ 即已成为世界上…

Arduino学习笔记5

一.直流电机控制实验 1.源代码 int dianJiPin9;//定义数字9接口接电机驱动IN1的控制口void setup() {pinMode(dianJiPin,OUTPUT);//定义电机驱动IN1的控制口为输出接口 } void loop() {digitalWrite(dianJiPin,LOW);//关闭电机delay(1000);//延时digitalWrite(dianJiPin,HIGH…

基于protobuf构建grpc服务

一、protobuf介绍 protobuf是谷歌开源的一种数据格式&#xff0c;适合高性能&#xff0c;对响应速度有要求的数据传输场景。因为profobuf是二进制数据格式&#xff0c;需要编码和解码。数据本身不具有可读性。因此只能反序列化之后得到真正可读的数据。 优势&#xff1a; 序列…

【Unity-UGUI控件全面解析】| Text文本组件详解

🎬【Unity-UGUI控件全面解析】| Text文本组件详解一、组件介绍二、组件属性面板三、代码操作组件四、组件常用方法示例4.1 改变Text文本颜色4.2 文本换行问题4.3 空格自动换行问题4.4 逐字显示效果五、组件相关扩展使用5.1 文本描边组件(Outline)5.2 阴影组件(Shadow)5.3…

操作系统——操作系统逻辑结构

0.关注博主有更多知识 操作系统入门知识合集 目录 2.1操作系统的逻辑结构 思考题&#xff1a; 2.2CPU的态 思考题&#xff1a; 2.3中断机制 2.1操作系统的逻辑结构 操作系统的结构指的是操作系统的设计和实现思路&#xff0c;按照什么样的结构设计、实现。 操作系统的…

[java]云HIS:检验字典维护

术语解释&#xff1a; 1、最小剂量&#xff1a;并非指医生开处方时的最小剂量值&#xff0c;而是为了对应计量单位和剂量单位之间数量关系而设置的。 2、包装规格&#xff1a;是计价单位和计量单位之间换算的关系值&#xff0c;1个计价单位计价规格个计量单位。 药品单位之间的…

【三十天精通Vue 3】第二十一天 Vue 3的安全性详解

✅创作者&#xff1a;陈书予 &#x1f389;个人主页&#xff1a;陈书予的个人主页 &#x1f341;陈书予的个人社区&#xff0c;欢迎你的加入: 陈书予的社区 &#x1f31f;专栏地址: 三十天精通 Vue 3 文章目录 引言一、Vue 3 中的安全问题1.1 前端安全问题概述1.2 Vue 3 中的安…

浅谈Golang等多种语言转数组成字符串

目录 Python 一维列表转字符串 二维列表转字符串 多维列表转字符串 Golang 一维数组的遍历打印 二维数组的遍历打印 Java 一维容器的直接打印 二维容器的直接打印 普通数组的转化 C 一维容器的遍历 1. to_string() 2. stringstream 二维容器的遍历 简要小结 …

【Python--高级教程】

高级教程 1.正则表达式re.compile()re.match()函数re.search()函数re.search()函数与re.match()函数的区别group(num) 或 groups()检索和替换re.sub()替换函数中的re.sub可以是一个函数findAll()方法re.finditer()方法re.split()regex修饰符正则表达式模式 2.CGI编程什么是CGI网…

Top-K问题

Top-K简介 &#x1f604;Top-k算法常用于对诸如前几名&#xff0c;前几个最大值&#xff0c;前几个最小值这样的问题的求解&#xff0c;并且在数据量较大时力求在最短的时间内求出问题的解。例如&#xff1a; 世界500强公司&#xff0c;世界上年龄最大的几个人&#xff0c;某知…

3.7 Linux shell脚本编程(分支语句、循环语句)

目录 分支语句&#xff08;对标C语言中的if&#xff09; 多路分支语句&#xff08;对标C语言中的swich case&#xff09; 分支语句&#xff08;对标C语言中的if&#xff09; 语法结构: if 表达式 then 命令表 fi 如果表达式为真, 则执行命令表中的命令; 否则退出if语句,…

数据湖Data Lakehouse支持行级更改的策略:COW、MOR、Delete+Insert

COW:写时复制,MOR:读时合并,Delete+Insert:保证同一个主键下仅存在一条记录,将更新操作转换为Delete操作和Insert操作 COW和MOR的对比如下图,而Delete+Insert在StarRocks主键模型中用到。 目前COW、MOR在三大开源数据湖项目的使用情况,如下图。 写入时复制【Copy-On…

浙大的SAMTrack,自动分割和跟踪视频中的任何内容

Meta发布的SAM之后&#xff0c;Meta的Segment Anything模型(可以分割任何对象)体验过感觉很棒&#xff0c;既然能够在图片上面使用&#xff0c;那肯定能够在视频中应用&#xff0c;毕竟视频就是一帧一帧的图片的组合。 果不其然浙江大学就发布了这个SAMTrack&#xff0c;就是在…

编译预处理以及相关面试

编译预处理 1、宏定义1.1、 无参宏定义1.2、使用宏定义的优点1.3、宏定义注意点1.4、带参数的宏(重点)1.5、条件编译1.6、宏定义的一些巧妙用法(有用)1.7、结构体占用字节数的计算原则&#xff08;考题经常考&#xff0c;要会画图&#xff09;1.8、#在宏定义中的作用&#xff0…