LangChainで専門分野のチャットボットの精度を上げる試み【③エージェント編】

Featured image of the post

概要

専門分野のチャットボットを作るシリーズの第3回目!

前回までのおさらい

✅自社開発している専門的で複雑なソフトのチャットボットを作りたい。

✅しかし専門的すぎて精度を上げるのが難しそう。

✅独自データは「Q&A 4000個」「解説書 4000ページ」を持っている。

👉独自データは重複データをまとめるとよさそう!

👉独自データをカテゴリーごとに分けると精度が上がった!

今回やること

エージェントを使い質問プログラムを工夫することで精度の向上を試みる✅

Image in a image block

エージェントとは

エージェントとは、Google検索などの外部の機能を駆使して、良い答えを導く機能。

イメージ図

Image in a image block

💡
ここではGoogle検索ではなく、「独自データ(インデックス)」×10個を外部の機能として渡す。

AIが質問に合った独自データを使って回答してくれるのが理想😊

Image in a image block

💡
エージェントについてはこちらで解説している。

📄 初心者によるLangChain解説【イメージ画像あり】

結論ファースト

✅エージェントで精度良くカテゴリーを自動判断できなかった

✅しかし要件によっては十分実用的だと感じた!

AIに質問しても「どのカテゴリーの質問か」正しく判断できない原因

このようなシチュエーションのとき、カテゴリーを正しく判断できない❌

💡
(事前準備)
操作方法に関する複数の独自データをAIに与え、「操作について質問された場合はこのデータを使ってください」と設定する。
🙎‍♂️
(質問)
セルの書式設定のやり方を教えて!
🤖
(回答)
「セルの書式設定のやり方を教えて!」は操作方法の質問なの…?💦

✅質問とdescription(説明文)の関連性が薄い場合、自動判断が難しい

→「セルの書式設定のやり方を教えて!」と質問しても、この質問が「操作方法」についての質問だと理解できない。

description(説明文)を適切に設定すれば正しくカテゴリーを自動判断できそう

→「操作について質問された場合はこのデータを使ってください」と設定するのではなく、「セルの書式設定のやり方、〇〇のやり方、〇〇のやり方について質問された場合はこのデータを使ってください」のように具体的に設定する。

✅しかし独自データが専門的ということもあって、description(説明文)がうまくできなかった

「セルの書式設定のやり方、〇〇のやり方、〇〇のやり方について質問された場合はこのデータを使ってください」のようにすべて列挙するのは数が多すぎて非現実的。

エージェントの種類

エージェント比較結果

初めにエージェントの比較結果を示す✅

エージェント 精度 結果
案1 zero-shot-react-description 🔺 ある程度回答できるが「質問のカテゴリーを誤って判断 → 誤った回答」が多々ある。
案2 chat-zero-shot-react-description 🔺 ↑同上。
案3 chat-conversational-react-description 今回はメモリ機能は未使用で、エージェントを活かしきれず精度も微妙。
案4 openai-functions 🔺 ある程度質問のカテゴリーを正しく判断できているが、回答を間違えることが多い。

案1:zero-shot-react-description

ReActを用いて実行するアクションを決定するエージェント✅

💡
オーソドックスなエージェントと思ってもらえばOK!
公式ドキュメント

✅イメージ図
Image in a image block
コード

※実際はインデックスを10個使ったが、以下では3個だけ記載している。

※ソフトの名前は「myApp(仮称)」としている。

// .envの読み込み
require("dotenv").config();

// モデル
import { OpenAI } from "langchain/llms/openai";
import { ChatOpenAI } from "langchain/chat_models/openai";
// 埋め込み
import { OpenAIEmbeddings } from "langchain/embeddings/openai";
// ベクトル検索エンジン
import { HNSWLib } from "langchain/vectorstores/hnswlib";
// チェーン
import { VectorDBQAChain } from "langchain/chains";
// エージェント
import { initializeAgentExecutorWithOptions } from "langchain/agents";
// ツール
import { ChainTool } from "langchain/tools";

async function make_chain( indexPath: string ) {
  // 作成済みのインデックスを読み込む
  const vectorStore = await HNSWLib.load(
    indexPath,
    new OpenAIEmbeddings()
  );

  // モデル
  const model = new ChatOpenAI({
		temperature : 0,
    maxTokens : 500,
    frequencyPenalty : 0.0,
    presencePenalty : 0.0,
  });

  // チェーン
  const chain = VectorDBQAChain.fromLLM(model, vectorStore);
  
  return chain;
}

export const runLlm = async () => {
  // ツール
  const chainOpe = await make_chain( "index/ope" );
  const qaToolOpe = new ChainTool({
    name: "操作方法",
    description:
      "myApp 操作方法に関する質疑応答 - myAppというソフトの「操作」について質問する必要がある場合に便利です。",
    chain: chainOpe,
  });
  const chainPay = await make_chain( "index/pay" );
  const qaToolPay = new ChainTool({
    name: "お支払い",
    description:
      "myApp お支払いに関する質疑応答 - myAppというソフトの「お支払い」について質問する必要がある場合に便利です。",
    chain: chainPay,
  });
  const chainOther = await make_chain( "index/other" );
  const qaToolOther = new ChainTool({
    name: "その他",
    description:
      "myApp その他に関する質疑応答 - myAppというソフトの「その他」について質問する必要がある場合に便利です。",
    chain: chainOther,
  });

  const tools = [
    qaToolOpe,
    qaToolPay,
    qaToolOther,
  ];
  
  // モデル
  const model = new OpenAI({
    temperature : 0,
    maxTokens : 500,
    frequencyPenalty : 0.0,
    presencePenalty : 0.0,
  });

  // エージェント
  const executor = await initializeAgentExecutorWithOptions(tools, model, {
    agentType: "zero-shot-react-description",
    returnIntermediateSteps: true,
    verbose: true,  // ツールの選択過程を含めて出力する
  });
  
  // 質問実行
  const input1 = `テーブルにヘッダーを設定する方法を教えてください。`;
  const result1 = await executor.call({ input: input1 });

  // 結果出力
  console.log(`回答1: ${result1.output}`);
  console.log(
    `Got intermediate steps ${JSON.stringify(
      result1.intermediateSteps,
      null,
      2
    )}`
  );
};
runLlm();

✅所感
メリット⭕️ デメリット❌ 精度
「質問のカテゴリーを特定 → 正しい回答」を正しく実行し、理想の回答をしてくれることもある。 「質問のカテゴリーを誤って判断誤った回答」が多い。
例:「お支払い」の質問なのに「操作方法」のインデックスを使ってしまうなど。

回答が出るまで繰り返すのでAPI使用料金が高くなる
🔺
💡
実用的なレベルではない…💦

✅失敗時のイメージ
Image in a image block

✅考察
💡
インデックスを正しく使い分けてもらうにはdescription(説明文)の設定が大事だと感じた💦

例えば「操作方法」のインデックスのdescriptionは以下のようにしている。

"myApp 操作方法に関する質疑応答 - myAppというソフトの「操作」について質問する必要がある場合に便利です。"

→複雑な質問をされると、この説明だけでは「操作」についての質問か判断できない。

💡
しかし専門用語が多く、カテゴリー分けが複雑なので適切なdescription(説明文)を設定するのが難しい💦

案2:chat-zero-shot-react-description

案1「zero-shot-react-description」とほぼ同じエージェント✅

💡
LLMモデルではなく、チャットモデルで使う点が異なる!
公式ドキュメント

✅イメージ図
Image in a image block
コード

※実際はインデックスを10個使ったが、以下では3個だけ記載している。

※ソフトの名前は「myApp(仮称)」としている。

// .envの読み込み
require("dotenv").config();

// モデル
import { ChatOpenAI } from "langchain/chat_models/openai";
// 埋め込み
import { OpenAIEmbeddings } from "langchain/embeddings/openai";
// ベクトル検索エンジン
import { HNSWLib } from "langchain/vectorstores/hnswlib";
// チェーン
import { VectorDBQAChain } from "langchain/chains";
// エージェント
import { initializeAgentExecutorWithOptions } from "langchain/agents";
// ツール
import { ChainTool } from "langchain/tools";

async function make_chain( indexPath: string ) {
  // 作成済みのインデックスを読み込む
  const vectorStore = await HNSWLib.load(
    indexPath,
    new OpenAIEmbeddings()
  );

  // モデル
  const model = new ChatOpenAI({
		temperature : 0,
    maxTokens : 500,
    frequencyPenalty : 0.0,
    presencePenalty : 0.0,
  });

  // チェーン
  const chain = VectorDBQAChain.fromLLM(model, vectorStore);
  
  return chain;
}

export const runLlm = async () => {
  // ツール
  const chainOpe = await make_chain( "index/ope" );
  const qaToolOpe = new ChainTool({
    name: "操作方法",
    description:
      "myApp 操作方法に関する質疑応答 - myAppというソフトの「操作」について質問する必要がある場合に便利です。",
    chain: chainOpe,
  });
  const chainPay = await make_chain( "index/pay" );
  const qaToolPay = new ChainTool({
    name: "お支払い",
    description:
      "myApp お支払いに関する質疑応答 - myAppというソフトの「お支払い」について質問する必要がある場合に便利です。",
    chain: chainPay,
  });
  const chainOther = await make_chain( "index/other" );
  const qaToolOther = new ChainTool({
    name: "その他",
    description:
      "myApp その他に関する質疑応答 - myAppというソフトの「その他」について質問する必要がある場合に便利です。",
    chain: chainOther,
  });

  const tools = [
    qaToolOpe,
    qaToolPay,
    qaToolOther,
  ];
  
  // モデル
  const model = new ChatOpenAI({
		temperature : 0,
    maxTokens : 500,
    frequencyPenalty : 0.0,
    presencePenalty : 0.0,
  });

  // エージェント
  const executor = await initializeAgentExecutorWithOptions(tools, model, {
    agentType: "chat-zero-shot-react-description",
    returnIntermediateSteps: true,
    verbose: true,  // ツールの選択過程を含めて出力する
  });
  
  // 質問実行
  const input1 = `テーブルにヘッダーを設定する方法を教えてください。`;
  const result1 = await executor.call({ input: input1 });

  // 結果出力
  console.log(`回答1: ${result1.output}`);
  console.log(
    `Got intermediate steps ${JSON.stringify(
      result1.intermediateSteps,
      null,
      2
    )}`
  );
};
runLlm();

✅所感

案1「zero-shot-react-description」と同じような結果だった。

メリット⭕️ デメリット❌ 精度
「質問のカテゴリーを特定 → 正しい回答」を正しく実行し、理想の回答をしてくれることもある。 「質問のカテゴリーを誤って判断誤った回答」が多い。
例:「お支払い」の質問なのに「操作方法」のインデックスを使ってしまうなど。

回答が出るまで繰り返すのでAPI使用料金が高くなる
🔺
💡
実用的なレベルではない…💦

✅考察
💡
案1「zero-shot-react-description」とほぼ同じなので、精度の向上は見られなかった💦

案3:chat-conversational-react-description

ユーザーと会話することに適したエージェント✅

💡
メモリ機能を使って会話の内容を記憶できる!
公式ドキュメント

✅イメージ図
Image in a image block
コード

※実際はインデックスを10個使ったが、以下では3個だけ記載している。

※ソフトの名前は「myApp(仮称)」としている。

// .envの読み込み
require("dotenv").config();

// モデル
import { ChatOpenAI } from "langchain/chat_models/openai";
// 埋め込み
import { OpenAIEmbeddings } from "langchain/embeddings/openai";
// ベクトル検索エンジン
import { HNSWLib } from "langchain/vectorstores/hnswlib";
// チェーン
import { VectorDBQAChain } from "langchain/chains";
// エージェント
import { initializeAgentExecutorWithOptions } from "langchain/agents";
// ツール
import { ChainTool } from "langchain/tools";

async function make_chain( indexPath: string ) {
  // 作成済みのインデックスを読み込む
  const vectorStore = await HNSWLib.load(
    indexPath,
    new OpenAIEmbeddings()
  );

  // モデル
  const model = new ChatOpenAI({
		temperature : 0,
    maxTokens : 500,
    frequencyPenalty : 0.0,
    presencePenalty : 0.0,
  });

  // チェーン
  const chain = VectorDBQAChain.fromLLM(model, vectorStore);
  
  return chain;
}

export const runLlm = async () => {
  // ツール
  const chainOpe = await make_chain( "index/ope" );
  const qaToolOpe = new ChainTool({
    name: "操作方法",
    description:
      "myApp 操作方法に関する質疑応答 - myAppというソフトの「操作」について質問する必要がある場合に便利です。",
    chain: chainOpe,
  });
  const chainPay = await make_chain( "index/pay" );
  const qaToolPay = new ChainTool({
    name: "お支払い",
    description:
      "myApp お支払いに関する質疑応答 - myAppというソフトの「お支払い」について質問する必要がある場合に便利です。",
    chain: chainPay,
  });
  const chainOther = await make_chain( "index/other" );
  const qaToolOther = new ChainTool({
    name: "その他",
    description:
      "myApp その他に関する質疑応答 - myAppというソフトの「その他」について質問する必要がある場合に便利です。",
    chain: chainOther,
  });

  const tools = [
    qaToolOpe,
    qaToolPay,
    qaToolOther,
  ];
  
  // モデル
  const model = new ChatOpenAI({
		temperature : 0,
    maxTokens : 500,
    frequencyPenalty : 0.0,
    presencePenalty : 0.0,
  });

  // エージェント
  const executor = await initializeAgentExecutorWithOptions(tools, model, {
    agentType: "chat-conversational-react-description",
    verbose: true,  // ツールの選択過程を含めて出力する
  });
  
  // 質問実行
  const input1 = `テーブルにヘッダーを設定する方法を教えてください。`;
  const result1 = await executor.call({ input: input1 });

  // 結果出力
  console.log(`回答1: ${result1.output}`);
  console.log(
    `Got intermediate steps ${JSON.stringify(
      result1.intermediateSteps,
      null,
      2
    )}`
  );
};
runLlm();

✅所感
メリット⭕️ デメリット❌ 精度
会話型のプログラムが作りやすい。 「質問のカテゴリーを誤って判断誤った回答」が多い。
例:「お支払い」の質問なのに「操作方法」のインデックスを使ってしまうなど。
💡
カテゴリー判断の誤りは改善されず精度は悪い😫

✅考察
💡
今回は会話機能を使っていないので、このエージェントを活かせていない💦
💡
問題解決するような変更はしていないので精度がよくならないのも当然…?💦

案4:openai-functions

OpenAIのFunction Callingを使うエージェント✅

💡
Function Callingについてはこちらで解説している。

📄 OpenAIの新機能Function Callingを誰でも分かるようイメージを解説

公式ドキュメント

✅イメージ図

※案2「chat-zero-shot-react-description」と似ている

Image in a image block
コード

※実際はインデックスを10個使ったが、以下では3個だけ記載している。

※ソフトの名前は「myApp(仮称)」としている。

// .envの読み込み
require("dotenv").config();

// モデル
import { ChatOpenAI } from "langchain/chat_models/openai";
// 埋め込み
import { OpenAIEmbeddings } from "langchain/embeddings/openai";
// ベクトル検索エンジン
import { HNSWLib } from "langchain/vectorstores/hnswlib";
// チェーン
import { VectorDBQAChain } from "langchain/chains";
// エージェント
import { initializeAgentExecutorWithOptions } from "langchain/agents";
// ツール
import { ChainTool } from "langchain/tools";

async function make_chain( indexPath: string ) {
  // 作成済みのインデックスを読み込む
  const vectorStore = await HNSWLib.load(
    indexPath,
    new OpenAIEmbeddings()
  );

  // モデル
  const model = new ChatOpenAI({
		modelName : "gpt-3.5-turbo-0613",
		temperature : 0,
    maxTokens : 500,
    frequencyPenalty : 0.0,
    presencePenalty : 0.0,
  });

  // チェーン
  const chain = VectorDBQAChain.fromLLM(model, vectorStore);
  
  return chain;
}

export const runLlm = async () => {
  // ツール
  const chainOpe = await make_chain( "index/ope" );
  const qaToolOpe = new ChainTool({
    name: "操作方法",
    description:
      "myApp 操作方法に関する質疑応答 - myAppというソフトの「操作」について質問する必要がある場合に便利です。",
    chain: chainOpe,
  });
  const chainPay = await make_chain( "index/pay" );
  const qaToolPay = new ChainTool({
    name: "お支払い",
    description:
      "myApp お支払いに関する質疑応答 - myAppというソフトの「お支払い」について質問する必要がある場合に便利です。",
    chain: chainPay,
  });
  const chainOther = await make_chain( "index/other" );
  const qaToolOther = new ChainTool({
    name: "その他",
    description:
      "myApp その他に関する質疑応答 - myAppというソフトの「その他」について質問する必要がある場合に便利です。",
    chain: chainOther,
  });

  const tools = [
    qaToolOpe,
    qaToolPay,
    qaToolOther,
  ];
  
  // モデル
  const model = new ChatOpenAI({
		modelName : "gpt-3.5-turbo-0613",
		temperature : 0,
    maxTokens : 500,
    frequencyPenalty : 0.0,
    presencePenalty : 0.0,
  });

  // エージェント
  const executor = await initializeAgentExecutorWithOptions(tools, model, {
    agentType: "openai-functions",
    returnIntermediateSteps: true,
    verbose: true,  // ツールの選択過程を含めて出力する
  });
  
  // 質問実行
  const input1 = `テーブルにヘッダーを設定する方法を教えてください。`;
  const result1 = await executor.call({ input: input1 });

  // 結果出力
  console.log(`回答1: ${result1.output}`);
  console.log(
    `Got intermediate steps ${JSON.stringify(
      result1.intermediateSteps,
      null,
      2
    )}`
  );
};
runLlm();

✅所感
メリット⭕️ デメリット❌ 精度
案2「chat-zero-shot-react-description」に比べて、「質問のカテゴリー分類」がやや正確に感じた。 間違いも多々あり、精度はそこまで高くない。
💡
案2「chat-zero-shot-react-description」と似た結果を想像していた💭

「質問のカテゴリー分類」はこちらの方が正確に感じた!
→「質問の回答」は微妙…

💡
総評すると案2「chat-zero-shot-react-description」と精度は同じくらいで実用的なレベルではない…💦

✅考察
💡
要件によって、「chat-zero-shot-react-description」「openai-functions」はどちらの精度が良いか変わるかもしれない💦

description(説明文)を調整

課題

descriptionとは「ツールの説明文」のこと。

エージェントはdescriptionを参考に「どのツールを使うか」決定している。

Image in a image block

理想の動作

例えば「操作」について質問した場合、AIが「これは操作の質問だ!」と判断して操作のツールを使って回答してほしい!

現状の動作

前述のエージェントの比較では「これは操作の質問だ!」の判断を間違えることが多かった。

この原因はdescription(説明文)が悪いせいだと考えた💭

💡
どのツールを使えばいいかAIが分かるようにdescription(説明文)を書いてあげる必要がある。

description比較結果

初めにdescription(説明文)の比較結果を示す✅

description 精度 結果
案1 タイトル + 抽象的な説明 説明が抽象的すぎて正しく判断できない。
案2 タイトル+具体的な説明 🔺 多少は正しく判断できるようになった。

案1:タイトル抽象的な説明
✅descriptionの例
💡
myApp 操作方法に関する質疑応答 - myAppというソフトの「操作」について質問する必要がある場合に便利です。

※ソフトの名前は「myApp(仮称)」としている。

✅所感
メリット⭕️ デメリット❌ 精度
シンプルな質問なら、どのカテゴリーの質問か正しく判断してくれる。 「セルの書式設定」についての質問など一見「操作」についての質問か分からない質問は、どのカテゴリーの質問か判断できない。
💡
間違いが多くて使い物にならない…💦

✅考察
💡
description(説明文)が抽象的すぎてどんな質問が「操作」の質問かAIが理解できなかった💦
💡
より具体的なdescription(説明文)が必要そう!

案2:タイトル具体的な説明
✅descriptionの例
💡
myApp 操作方法に関する質疑応答 - myAppというソフトの「セルの入力」「セルの書式設定」「テーブルの作り方」「データの集計」「グラフの作成」について質問する必要がある場合に便利です。

※ソフトの名前は「myApp(仮称)」としている。

✅所感
メリット⭕️ デメリット❌ 精度
「セルの書式設定」などの明記した言葉について質問されると、どのカテゴリーの質問か正しく判断できることが多い。 descriptionに具体的な操作をすべて書く必要がある。 🔺
💡
完璧ではないが少し実用的になった😊

✅考察
💡
しっかりと具体的に説明をしてあげるとAIも理解しやすそう💭
💡
しかしプログラムが大規模なため、具体的な操作をすべて書ききれない💦

エージェントのまとめ

エージェントでは理想的な回答は得られなかった😫

一番精度がよかったエージェント

エージェントの中で一番精度が良いと感じたのは以下の組み合わせ⭐️

エージェントの種類 案2:chat-zero-shot-react-description
description 案2:タイトル+具体的な説明
コード

※実際はインデックスを10個使ったが、以下では3個だけ記載している。

※ソフトの名前は「myApp(仮称)」としている。

// .envの読み込み
require("dotenv").config();

// モデル
import { ChatOpenAI } from "langchain/chat_models/openai";
// 埋め込み
import { OpenAIEmbeddings } from "langchain/embeddings/openai";
// ベクトル検索エンジン
import { HNSWLib } from "langchain/vectorstores/hnswlib";
// チェーン
import { VectorDBQAChain } from "langchain/chains";
// エージェント
import { initializeAgentExecutorWithOptions } from "langchain/agents";
// ツール
import { ChainTool } from "langchain/tools";

async function make_chain( indexPath: string ) {
  // 作成済みのインデックスを読み込む
  const vectorStore = await HNSWLib.load(
    indexPath,
    new OpenAIEmbeddings()
  );

  // モデル
  const model = new ChatOpenAI({
		temperature : 0,
    maxTokens : 500,
    frequencyPenalty : 0.0,
    presencePenalty : 0.0,
  });

  // チェーン
  const chain = VectorDBQAChain.fromLLM(model, vectorStore);
  
  return chain;
}

export const runLlm = async () => {
  // ツール
  const chainOpe = await make_chain( "index/ope" );
  const qaToolOpe = new ChainTool({
    name: "操作方法",
    description:
      "myApp 操作方法に関する質疑応答 - myAppというソフトの「セルの入力」「セルの書式設定」「テーブルの作り方」「データの集計」「グラフの作成」について質問する必要がある場合に便利です。",
    chain: chainOpe,
  });
  const chainPay = await make_chain( "index/pay" );
  const qaToolPay = new ChainTool({
    name: "お支払い",
    description:
      "myApp お支払いに関する質疑応答 - myAppというソフトの「お支払い」「クレジットカードの登録」「サブスクリプション」について質問する必要がある場合に便利です。",
    chain: chainPay,
  });
  const chainOther = await make_chain( "index/other" );
  const qaToolOther = new ChainTool({
    name: "その他",
    description:
      "myApp その他に関する質疑応答 - myAppというソフトの「ファイルの拡張子」「自動バックアップ」「詳細設定」について質問する必要がある場合に便利です。",
    chain: chainOther,
  });

  const tools = [
    qaToolOpe,
    qaToolPay,
    qaToolOther,
  ];
  
  // モデル
  const model = new ChatOpenAI({
		temperature : 0,
    maxTokens : 500,
    frequencyPenalty : 0.0,
    presencePenalty : 0.0,
  });

  // エージェント
  const executor = await initializeAgentExecutorWithOptions(tools, model, {
    agentType: "chat-zero-shot-react-description",
    returnIntermediateSteps: true,
    verbose: true,  // ツールの選択過程を含めて出力する
  });
  
  // 質問実行
  const input1 = `テーブルにヘッダーを設定する方法を教えてください。`;
  const result1 = await executor.call({ input: input1 });

  // 結果出力
  console.log(`回答1: ${result1.output}`);
  console.log(
    `Got intermediate steps ${JSON.stringify(
      result1.intermediateSteps,
      null,
      2
    )}`
  );
};
runLlm();

しかしそれでもAIに「どのデータを使えばいいか?」を判断してもらうのが難しく、思うような精度にはならなかった💦

Image in a image block

考察

思うような精度が出ない理由を2つのポイントに分けて考察してみた。

Image in a image block

ツール(独自データ)の選択
  • 独自データに専門的な言葉が多いせいで、AIが質問のカテゴリーを正しく判断できない💦
  • この問題はツールのdescription(説明文)を詳細に書けば解決できそう!しかし取り扱っているソフトが多機能かつ大規模なためdescriptionを書ききれない💦
💡
descriptionの書き方はもっと工夫ができるかも…?

ツール(独自データ)を使って回答
  • 前述のツールの選択が正しくできていないと、この部分の精度を上げても意味がない💦
  • 今回この部分の改良はしていない。次回以降試す予定!
    • 他のモデルの使用(GPT-4)
    • モデルのパラメータの調整
    • プロンプトの調整
💡
回答する以前に、まず正しい独自データを選ぶ必要がある!

エージェントの課題
  • ツールの選択(=カテゴリーの自動選択)の精度を上げるのが難しい。
  • 回答が出るまで何度も質問を繰り返すため、トークンの消費が激しくAPI利用料金が高くなる。

今回の要件では難しいと感じる部分が多かった💦

エージェントの採用は見送ろうと思う…😫

💡
ただし要件によってはエージェントで高精度なものを作れる場合もありそう!

次回

今回はここまで!

試した中では「chat-zero-shot-react-description」を使い、具体的なdescriptionを書くのが一番よさそうだった!

💡
しかし課題も多く理想の精度にはならなかった💦

次回はチェーンを使った質問プログラムでもっと精度を上げる〜🙌