当我们向 OpenAI 提出需要特定上下文的问题时,例如:
Who is my father?
OpenAI 可能会产生幻觉,或者回答说它不知道。
为了帮助 OpenAI 回答特定问题,您可以在提示本身中提供额外的上下文信息。
My father lives in Barcelona and is 50 year's old.
如果我们再次向 OpenAI 提出同样的问题,OpenAI 将会结合所提供的包含上下文信息的提示进行回答。
嵌入向量
OpenAI 提供了一种称为文本嵌入的功能,用于衡量文本字符串之间的相关性。对于每个文本块、章节或主题,我们都可以将该信息发送到 OpenAI 的嵌入服务,以获取其嵌入数据(即浮点数的向量列表)。请求示例:
TsgcHTTP_API_OpenAI._CreateEmbeddings('text-embedding-ada-002', 'My father lives in Barcelona and is 50 year's old.');
OpenAI 的响应大致如下:
{
"data": [
{
"embedding": [
-0.006929283495992422,
-0.005336422007530928,
...
-4.547132266452536e-05,
-0.024047505110502243
],
"index": 0,
"object": "embedding"
}
],
}
一旦我们收集了代表我们希望聊天机器人理解的不同信息片段的特殊数据,就需要将其保存到安全的地方(例如向量数据库)。请记住,这一步骤只需执行一次。我们只在第一次获取信息的特殊数据,仅在信息发生变化时才进行更新。
最后,当我们想向聊天机器人提问时,首先将查询转换为向量,然后在之前创建的数据库中搜索哪个向量与我们的查询最相似,一旦找到,就将最相似向量的提示作为嵌入内容添加到问题中。
简单示例
让我们创建一个使用嵌入向量和 sgcWebSockets 库的简单示例。首先我们将描述家庭成员,并为每位成员计算向量。
oOpenAI := TsgcHTTP_API_OpenAI.Create(nil);
oOpenAI.OpenAIOptions.ApiKey := '<your api key>';
oOpenAI._CreateEmbeddings('text-embedding-ada-002', 'My father lives in Barcelona and is 50 year''s old.');
oOpenAI._CreateEmbeddings('text-embedding-ada-002', 'My mather lives in Berlin and is 47 year''s old.');
oOpenAI._CreateEmbeddings('text-embedding-ada-002', 'My sister lives in Seoul and is 28 year''s old.');
上述结果可以存储到一张表中,其中每行是一个包含提示和向量数据的嵌入条目。
| 提示 | 向量 |
| My father lives in Barcelona and is 50 year's old. | [0.000742552,-0.0049907574...] |
| My mather lives in Berlin and is 47 year's old. | [-0.027452856,-0.0023051118...] |
| My sister lives in Seoul and is 28 year's old. | [-0.007873567,-0.014787777...] |
现在我们已经存储了向量,接下来将我们发送给 ChatGPT 的问题也转换为向量:
oOpenAI := TsgcHTTP_API_OpenAI.Create(nil);
oOpenAI.OpenAIOptions.ApiKey := '<your api key>';
vVectorQuery := oOpenAI._CreateEmbeddings('text-embedding-ada-002', ''Who is my father?'');
然后我们将在数据库中搜索该向量,以找出哪个向量与问题最相似。以下是伪代码示例:
// search the most similar vector using Cosine Similarity
vMostSimilarVector := 0;
Database.First;
While not Database.EOF do
begin
vCosineSimilarity := VectorCosineSimilarity(vVectorQuery, Database.FieldByName('Vector'));
if vConsineSimilarity > vMostSimilarVector then
begin
vMostSimilarVector := vCosineSimilarity;
vContext := Database.FieldByName('Prompt');
end;
Database.Next;
end;
最后,我们将找到的嵌入内容作为上下文信息添加到问题中,再向 ChatGPT 提问:
vQuestion := 'Who is my father?';
ChatBot := TsgcAIOpenAIChatBot.Create(nil);
ChatBot.OpenAIOptions.ApiKey := '<your api key>';
ShowMessage(ChatBot.ChatAsUser('Answer the question based on the context below.\n\nContext:\n' + vContext + '\nQuestion:' + vQuestion + '\nAnswer:'));
