2023 年的深度学习入门指南(3) - 前端
同学如何进行 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 来高亮代码,可以到
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;
}复制代码
我们来试验一下: