✏️

ChatGPTの質問・回答システムをシンプルにつくる

2023/05/29に公開

ChatGPTで質問・回答を行うには?

オリジナルの文脈(会社や製品の情報)を元に、
ChatGPTで質問・回答を行いたい場合、

たとえば、

「製品Aは機能が多い」
「製品Bは価格が安い」

という情報源をもとに、

「価格が安い製品を教えて」

という質問に回答してもらう場合、
以下のプロンプトで実現できます。

Speak in Japanese.
Answer the question only based on the multiple contexts below.
If the question cannot be answered using the information provided answer with "ごめんなさい!私にはわかりません。".

Context:
製品Aは機能が多い
====
製品Bは価格が安い

Question:
価格が安い製品を教えて

Answer:

※プロンプトはLangChainを参考

文脈が多い場合

ChatGPTでは文字数制限があるため、
文脈の文字数が多い場合、
すべて記載することができません。

質問に最適な文脈を取得してくる必要があります。

そのときに使えるのがEmbeddingです。
Embeddingはテキストをベクトルであらわすための技術で、
文書と文書の近しさを計算することができるため、
以下のフローで最適な文脈を取得することができます。

文脈のEmbeddingを生成

質問のEmbeddingを生成

質問と文脈のEmbeddingを計算し最適な文脈を取得

Embedding

EmbeddingはOpenAIのAPIで取得できます。
次元数は1536になります。

https://platform.openai.com/docs/guides/embeddings

export const embed = async ({
  apiKey,
  text,
}: {
  apiKey: string;
  text: string;
}) => {
  const data = await axios.post(
    "https://api.openai.com/v1/embeddings",
    {
      model: "text-embedding-ada-002",
      input: text,
    },
    {
      headers: {
        "Content-Type": "application/json",
        Authorization: `Bearer ${apiKey}`,
      },
    }
  );

  return data.data.data[0].embedding as number[]; // eslint-disable-line @typescript-eslint/no-unsafe-member-access
};

近しさの計算

近しさとはベクトルとベクトルの角度が低いことを意味しており、
これを取得するために内積(コサイン類似度)をとります。

スコアが1に近ければ近いほど、
近しい文書であるといえます。

TypeScriptではmathjsdotを利用することが出来ます。

dot(qEmbedding, sEmbedding)

Discussion