前言
前些日子刚从马来西亚度假回来,受限于英语口语和听力水平,游玩的时候总能遇到奇奇怪怪的问题,回国后痛下决心,要让自己全方位沉浸在外语学习中。
模式非常简单,受限网络延迟,选择本地启用一个 TTS 模型作为语音输出,同时借用 GPT 进行场景模拟对话,期间还穿插了如何自定义一个 Bot,本文内含了大量的编码内容,也是项目思路的一个分享,文章仅供参考。
前端
由于是给自己使用,不存在说用户体验这回事,当然是能多简单就多简单,我们设计一个实时的聊天框和语音输入框即可,提交和回显方面,使用原生 H5 的 XMLHttpRequest 即可。这里受限篇幅会只保留关键代码。
...
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.9.3/css/bulma.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css"
crossorigin="anonymous"></script>
</head>
<body>
<section class="hero is-primary">
<div class="hero-body">
<div class="container">
<h1 class="title">
AIPOICE
</h1>
</div>
</div>
</section>
<section class="section">
<div class="container">
<div class="columns">
<div class="column is-two-thirds">
<div class="box" style="border-color: #3273dc;">
<div class="content">
<p><strong>Bot:</strong> Hi there! How can I help you?</p>
</div>
</div>
</div>
<div class="column">
<div class="field has-addons">
<div class="control is-expanded">
<input class="input" type="text" placeholder="Type your message" id="inputText">
</div>
<div class="control">
<button class="button is-danger" onclick="clearInput()">
<span class="icon">
<svg t="1691502059165" class="icon" viewBox="0 0 1024 1024" version="1.1"
xmlns="http://www.w3.org/2000/svg" p-id="4874" width="24" height="24"><path
d="M886.401 395.097h-251.7V80.614c0-22.091-19.899-40-44.447-40H439.148c-24.547 0-44.447 17.909-44.447 40v314.483h-251.7c-22.315 0-40.404 17.909-40.404 40v506.471c0 22.091 18.09 40 40.404 40h743.4c22.315 0 40.404-17.909 40.404-40V435.097c0.001-22.092-18.089-40-40.404-40z m-10.72 536.47h-127.98V831c0-17.673-12.088-32-27-32s-27 14.327-27 32v100.567h-152V792c0-14.912-12.088-27-27-27s-27 12.088-27 27v139.567h-152V831c0-17.673-12.088-32-27-32s-27 14.327-27 32v100.567H152.597V688.332h723.084v243.235z m0-293.235H152.597V445.097H444.479V90.614h137.819v354.483H875.68v193.235z"
fill="#ffffff" p-id="4875"></path></svg></span>
</button>
</div>
</div>
<div class="field">
<div class="control">
<button class="button is-success is-fullwidth" onclick="sendRequest()">
<span class="icon">
<i class="fas fa-paper-plane"></i>
</span>
<span>Send</span>
</button>
</div>
</div>
</div>
</div>
</div>
</section>
<script>
function clearInput() {
document.getElementById("inputText").value = "";
}
function sendRequest() {
var inputText = document.getElementById("inputText").value;
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://127.0.0.1:8080/api/chat", true);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.onreadystatechange = function () {
if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
var resp = JSON.parse(xhr.responseText);
var userMessage = document.createElement("p");
userMessage.innerHTML = "<strong>You:</strong> " + inputText;
var botMessage = document.createElement("p");
botMessage.innerHTML = "<strong>Bot:</strong> " + resp.text;
document.querySelector(".content").appendChild(userMessage);
document.querySelector(".content").appendChild(botMessage);
document.getElementById("inputText").value = ""; // 清空输入框
}
};
xhr.send(JSON.stringify({text: inputText}));
}
</script>
...
这样一个简易的对话前端页面就出来了,发送内容全都取决于后端