一、开发准备
前端:HTML+CSS+JS、vue3(框架)
后端:node.js、express(框架)
数据库:postgreSQL、pgvector(插件)
二、实现原理
知识库的实现大体分为两个部分,数据的训练和对gpt的提问。
1、数据训练
首先通过 openai 的开发能力 “Embedding”(嵌入),对需要训练的数据进行向量化。
示例请求:
curl https://api.openai.com/v1/embeddings \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-d '{
"input": "Your text string goes here",
"model": "text-embedding-ada-002"
}'
示例响应:
{
"data": [
{
"embedding": [
-0.006929283495992422,
-0.005336422007530928,
...
-4.547132266452536e-05,
-0.024047505110502243
],
"index": 0,
"object": "embedding"
}
],
"model": "text-embedding-ada-002",
"object": "list",
"usage": {
"prompt_tokens": 5,
"total_tokens": 5
}
}
这是 openai 官网的一个例子,其中 响应数据中的 “embedding” 为向量化后的数据,然后我们就可以把 这个向量数据 保存到数据库中(注:数据库必须安装 pgvector )。
在实际应用中,如果我们要训练一个问答对的知识库,我们可能会把表设计成这样
然后我们,问题内容进行向量化处理,再把 向量数据、问题内容、回答内容 存储至数据库中。这样我们就完成了一个问答对的训练了。
2、提问
提问部分我们还是需要用到 openai 的 “Embedding” 这个开放能力。
首先,我们需要把 提问的内容 进行向量化处理(跟训练数据时的步骤一样),我们就能拿到向量化后的 提问的提问内容。
然后我们需要把这个 向量数据 利用 pgvector 这个插件在数据库中进行比对和搜索。具体命令可以查看 pgvector 的文档。通过搜索我们可以获取到一个或多条的相似的数据。
最后我们再把 搜索到的数据 喂给gpt ,再给 chatGPT 输入限定词,例如:使用以上数据进行回答,如果不知道,就回答“不知道”。(这个只是大概表述,可以再具体一点,并且翻译成英文效果更好)。chatGPT就会通过投喂的数据进行回答了。
以上为知识库的简单实现原理。
三、具体实现
这是我用 express 实现的方法,可以根据上述实现原理进行一个参考。
训练问答对
exports.trainData = async (req, res, next) => {
try {
const response = await openai().embeddings.create({
input: req.body.question, model: 'text-embedding-ada-002'
})
await saveData(req.body.answer, req.body.question, response.data[0].embedding)
res.send({ data: '训练成功!' })
} catch (error) {
res.send(error.message)
}
}
提问
exports.askQuestion = async (req, res, next) => {
try {
const question = req.body.question
const response = await openai().embeddings.create({
input: question, model: 'text-embedding-ada-002'
})
//查询向量数据库
const queryRes = await queryData(response.data[0].embedding)
//查询结果
const returnData = queryRes.rows.map((item) => {
return { question: item.question, answer: item.answer }
}).map(item => {
return JSON.stringify(item)
}).join(',')
console.log(returnData);
// 将结果喂给gpt
const chatCompletion = await openai().chat.completions.create({
messages: [{ role: 'system', content: `""" ${returnData} """` },
{ role: 'system', content: 'Use the provided content delimited by triple quotes to answer questions.Your task is to answer.he question using only the provided content. If the content does not contain the information needed.to answer this question then simply write: "抱歉,您问的问题没有在知识库中体现".' },
{ role: 'user', content: `${question}` }],
model: 'gpt-3.5-turbo',
});
res.send({ data: chatCompletion.choices[0].message.content })
} catch (error) {
console.log(error);
res.send({ data: error.message })
}
}