效果展示
与AI扮演的乔布斯谈天:
与AI扮演的特朗普谈天:
整体设计
首先咱们希望做一个与AI扮演的名人谈天的运用,运用的核心运用GPT。能够挑选让AI扮演哪位名人。
获取上下文
既然是谈天,咱们就需求对上下文有了解,这样聊的才会顺利。怎么才能让AI了解上下文,这儿运用的计划是每次将谈天的上下文全部作为prompt传递给gpt模型。
怎么让AI进入扮演状况
GPT是十分强大的,咱们只需求在prompt最初的时分告诉它:pretend you are xxx.即可
整体流程
back-end(后端)
咱们这儿运用express建立后端服务
npm i express
npm i cors // 解决前端同源战略
npm i body-parser // 解析http req的格局
const express = require('express');
const cors = require('cors')
const bodyParser = require('body-parser')
const app = express();
app.use(cors())
app.use(bodyParser.json())
app.post('/chat_ai', async (req, res) => {
const prompt = req.body.prompt;
const openAiRes = await requestOpenAi(prompt);
const data = { chat_res: openAiRes };
res.send(data);
});
app.listen(8111, () => {
console.log('Server is running at http://localhost:8111')
})
然后咱们使openAI官方供给的npm包来调用GPT。
npm i openai
async function requestOpenAi(prompt) {
const OpenAi = require("openai")
const { Configuration, OpenAIApi } = OpenAi
const configuration = new Configuration({
organization: "xx",
apiKey: "xx",
});
const openai = new OpenAIApi(configuration);
const response = await openai.createCompletion({
model: "text-davinci-003",
prompt: prompt,
temperature: 0.9,
max_tokens: 500,
top_p: 1,
frequency_penalty: 0.0,
presence_penalty: 0.6,
});
const resText = response.data.choices[0].text;
return resText;
}
其中oranization与apiKey 别离能够下面2个地方找到:
- beta.openai.com/account/org…
- beta.openai.com/account/api…
front-end (前端)
运用react + bootstrap建立前端
npx create-react-app ai-frontend
npm i sass
npm i bootstrap
自界说网络恳求办法,后边网络相关的通用逻辑能够在这儿处理
export function customFetch(input: string, init?: RequestInit): Promise<Response> {
input = "http://localhost:8111" + input;
const url = input;
const headers_value = { ...(init?.headers), "Content-Type": "application/json" };
init = { ...init, headers: headers_value }
return fetch(url, init);
}
接下来便是咱们的首要业务逻辑
如最开端的效果图所示,咱们一共有2个输入性元素,1个输出性元素,2个输入性元素别离用来挑选AI扮演的名人和输入谈天内容,1个输出性元素是1个列表即展示咱们的对话列表。
function App() {
function listItem(data, index) {
console.log("listItem index:" + index + " data: " + data);
const isMe = data.startsWith("Me: ");
return <li className={['list-group-item', 'chat_item', isMe ? "me" : null].join(' ')} key={index}>{data}</li>
}
function listRole(data, index) {
console.log("listRole index:" + index + " data: " + data);
return <option value = {data} > {data}</option>
}
return (
<div className='root'>
<div className="App">
<ul className='list-group chat_list'>
{chatList.map((data, index) => listItem(data, index))}
</ul>
<div className='row chat_input'>
<select class="form-select select_role" aria-label="role selector" onChange={onRoleSelect} >
<option selected>select role</option>
{roleList.map((data, index) => listRole(data, index))}
</select>
<input type="text" className="form-control col" id="chat_input" placeholder="please input" value={inputValue} onChange={handleChange} />
<button className="btn btn-primary col-md-auto send_btn" onClick={sendClick}>send</button>
</div>
</div>
</div>
);
}
然后咱们针对这2个输入的元素和1个输出的元素别离界说状况,并将其关联到ui组件上:
const [chatList, setChatList] = useReducer((olddata, newdata) => {
if (newdata === "clear") {
return [];
}
return olddata.concat(newdata)
}, [])
const [inputValue, setInputValue] = useState("");
const [role, setRole] = useState("");
function onRoleSelect(event) {
console.log("select value is" + event.target.value);
if ("select role" === event.target.value) {
setRole("")
}
setRole(event.target.value)
setChatList("clear")
}
const handleChange = (event) => {
console.log("input value is" + event.target.value);
setInputValue(event.target.value);
}
一起界说一组可扮演名人的选项
let roleList = ["AI", "Steve Jobs", "Donald John Trump", "Ma Yun", "Ray Dalio"];
咱们需求在对话前面加上谁说的这句话,所以咱们供给统一前缀
function genChatName(role) {
return role + ": "
}
接下来处理点击事情,首先会校验是否现已挑选和让AI扮演哪位名人,接下来将输入内容格局化为”Me: xxx”的形式,展示在谈天列表中并恳求后端。恳求后端前,需求生成prompt,如最初所说,完成上下文的方式是将所有谈天内容都组合作为prompt传给GPT。所以咱们需求经过chatList生成对应的prompt。恳求完成后,将结果放入chatList中展示即可。
function sendClick() {
if (role === "") {
alert("please select a role to chat with you")
return
}
const fullInput = genChatName("Me") + inputValue;
let newList = chatList.concat(fullInput);
setChatList(fullInput)
submit(genPrompt(newList));
}
function submit(text) {
const api = "/chat_ai";
const body = { prompt: text, role: genChatName(role)}
customFetch(api, {body: JSON.stringify(body), method: "POST"}).then(async (res) => {
const data = await res.json();
setChatList(genChatName(role) + data.chat_res)
}).catch((e) => {
console.error(e);
})
}
function genPrompt(chatList) {
let prompt = genTopic(role);
chatList.forEach(e => {
prompt=prompt + e + "\n";
});
prompt = prompt + genChatName(role);
return prompt;
}
最终
openAI推出chatGPT以来让咱们见识了通用言语模型的威力,越来越多的idea在GPT这个模型的基础上爆发,也有越来越多的运用融入了GPT能力。期待下一代GPT模型的到来,给更多的运用层开发者带来创新的机会。