初心者によるTypeScript版LangChain【②テンプレート編】

Featured image of the post

概要

TypeScript版のLangChainを用いて、プロンプトのテンプレートを作る方法を解説する😊

💡
初心者でも手順通りにコピペしていくだけで動くものが作れる!

今回作るもの
  • 「あなたは○○です。△△をお題に一発ギャグを考えて。」のような虫食いのプロンプトを作る!
    • 利用者はChatGPTみたいな文章入力は不要!
    • 利用者は○○△△の2単語だけ入力すればOK!

LangChainのバージョン

✅安定版のv.0.1.25時点のコードで解説する。

📝
更新履歴
  • 2023/05/13作成:v0.0.121のコードを記載。
  • 2024/03/08更新:v.0.1.25(安定版)のコードを追記。

LangChainとは

LLM(大規模言語モデル)を強化できるライブラリ✅

📎
こちらで詳しく解説している

  • v.0.1.25(安定版)の記事

LangChainのテンプレート機能とは

テンプレート機能を使うと…
  • 似たような質問を効率的に作ることができる。
  • ユーザーは質問の一部だけ入力すればOK

テンプレートのイメージ

「〇〇の名産地を教えて」というテンプレートを作った場合。

使用する技術

💡
詳細を知らなくても、とりあえずコピペで動くので一旦スルーしてOK!

環境構築

今回のコードを動かすには事前に「パッケージのインストール」「APIキーの設定」が必要⚠️

こちらの記事のとおりやれば2~3分でできるので、先に設定しておく😊

サンプルを実行してみる(LLMのテンプレート機能)

LLMのモデル(一般的な大規模言語モデル)でテンプレート機能を使う簡単な例を解説する。

サンプルプログラムを作成する

プロジェクトフォルダの直下に以下のファイルを作成する✅

Image in a image block

sample.ts

require("dotenv").config();
import { PromptTemplate } from "@langchain/core/prompts";
import { OpenAI } from "@langchain/openai";

// サンプル用の関数
export const runTemplete = async () => {
    // ①プロンプトのテンプレート
    const template = "{input}をお題に一発ギャグを考えて";
		const prompt = PromptTemplate.fromTemplate( template );
		
    // ③質問文章を作成(卵をお題に一発ギャグを考えて)
    const text = await prompt.format({ input: "卵" });
    console.log(text);

    // ③LLMのインスタンスを生成
    const model = new OpenAI();

    // ④質問する(卵をお題に一発ギャグを考えて)
    const res = await model.invoke(text);
    console.log(res);
};

runTemplete();
【旧】Ver.0.0.121時点のコード
require("dotenv").config();
import { PromptTemplate } from "langchain/prompts";
import { OpenAI } from "langchain/llms";
import { LLMChain } from "langchain/chains";

// サンプル用の関数
export const runTemplete = async () => {
    // ✅プロンプトのテンプレート
    const template = "{input}をお題に一発ギャグを考えて";
    const prompt = new PromptTemplate({
        template: template,
        inputVariables: ["input"],
    });

		// ✅質問文章を表示する
    const text = await prompt.format({ input: "卵" });
    console.log(text);

		// ✅質問の準備
    const model = new OpenAI();
    const chain = new LLMChain({ llm: model, prompt: prompt });

    // ✅質問する(卵をお題に一発ギャグを考えて)
    const res = await chain.call({ input: "卵" });
    console.log(res);
};
  
runTemplete();

【解説】①プロンプトのテンプレート
// ①プロンプトのテンプレート
const template = "{input}をお題に一発ギャグを考えて";
const prompt = PromptTemplate.fromTemplate( template );

  • new PromptTemplate(...)テンプレートが作れる。
💡
ここでは「◯◯をお題に一発ギャグを考えて」というテンプレートを作っている。
※変数名はinput以外でもOK。

【解説】②質問文章を作成(卵をお題に一発ギャグを考えて)
// ③質問文章を作成(卵をお題に一発ギャグを考えて)
const text = await prompt.format({ input: "卵" });
console.log(text);

  • prompt.format(...)テンプレートから質問文章を生成できる。
  • テンプレートに当てはめる文字を引数に指定する。{ input: "卵" }
💡
ここでは「卵をお題に一発ギャグを考えて」が作成される。

今回は「卵」で固定だが、ここをユーザー入力値にすると便利✨

【解説】③LLMのインスタンスを生成
// ③LLMのインスタンスを生成
const model = new OpenAI();

  • 自分が使いたいLLM(大規模言語モデル)のインスタンスを生成する。
💡
ここではOpenAIを使う。

【解説】④質問する(卵をお題に一発ギャグを考えて)
// ④質問する(卵をお題に一発ギャグを考えて)
const res = await model.invoke(text);
console.log(res);

  • await model.invoke(text)質問を実行できる。
💡
ここでは「卵をお題に一発ギャグを考えて」という質問を実行する。

ビルド

TypeScriptをビルドしてJavaScriptファイルを生成する。

以下のコマンドを実行する✅

tsc

Image in a image block

サンプルプログラムを実行する

HTMLからJSを呼び出しても、JSを単体で実行してもどちらでもOK。

今回はJSを単体で動かして動作を確認する。

以下のコマンドを実行する✅

node sample.js

何か返答が表示されればOK!

Image in a image block

サンプルを実行してみる(チャットモデルのテンプレート機能)

チャットモデル(チャットに特化した大規模言語モデル)でテンプレート機能を使う簡単な例を解説する。

サンプルプログラムを作成する

プロジェクトフォルダの直下に以下のファイルを作成する✅

Image in a image block

sample.ts

require("dotenv").config();
import { ChatPromptTemplate } from "@langchain/core/prompts";
import { ChatOpenAI } from "@langchain/openai";

// サンプル用の関数
export const runTemplete = async () => {
    // ①プロンプトのテンプレート
    const chatPrompt = ChatPromptTemplate.fromMessages([
        ["system","あなたは{role}です。",],
        ["human", "{input}をお題に一発ギャグを考えて。"],
    ]);

    // ②文章を作成(あなたは面白い芸人です。卵をお題に一発ギャグを考えて。)
    const text = await chatPrompt.format({ role: "面白い芸人", input: "卵", });
    console.log({ text });

    // ③チャットモデルのインスタンスを生成
    const chat = new ChatOpenAI({ temperature: 0 });

    // ④質問用の文章を作成(あなたは面白い芸人です。卵をお題に一発ギャグを考えて。)
    const formattedChatPrompt  = await chatPrompt.formatMessages({ role: "面白い芸人", input: "卵", });
    console.log({ formattedChatPrompt  });

    // ⑤質問する(あなたは面白い芸人です。卵をお題に一発ギャグを考えて。)
    const res = await chat.invoke( formattedChatPrompt  );  
    console.log(res);
};

runTemplete();
💡
基本の流れはLLMモデルと同じ。

【解説】①プロンプトのテンプレート
// ①プロンプトのテンプレート
const chatPrompt = ChatPromptTemplate.fromMessages([
    ["system","あなたは{role}です。",],
    ["human", "{input}をお題に一発ギャグを考えて。"],
]);

  • ChatPromptTemplate.fromPromptMessages(...)でテンプレートが作れる。
  • 引数に"system"(役割)と"human"(質問)のテンプレートを指定する。
💡
ここでは以下のテンプレートを作っている。

役割「あなたは〇〇です。」

質問「△△をお題に一発ギャグを考えて。」

【解説】②文章を作成(あなたは面白い芸人です。卵をお題に一発ギャグを考えて。)
// ③チャットモデルのインスタンスを生成
const chat = new ChatOpenAI({ temperature: 0 });

  • chatPrompt.format(...)でテンプレートから文章を生成できる。
  • テンプレートに当てはめる文字を引数に指定する。{ role: "面白い芸人", input: "卵", }
  • 今回のプログラムではこの処理は削除してOK。文章を生成できることを確かめるためにこのコードを実行した。
💡
ここでは以下の文章が生成される。

'System: あなたは面白い芸人です。\nHuman: 卵をお題に一発ギャグを考えて。’

【解説】③チャットモデルのインスタンスを生成
// ③チャットモデルのインスタンスを生成
const chat = new ChatOpenAI({ temperature: 0 });

  • 自分が使いたいチャットモデルのインスタンスを生成する。
💡
ここではChatOpenAIを使う。

【解説】④質問用の文章を作成(あなたは面白い芸人です。卵をお題に一発ギャグを考えて。)
// ④質問用の文章を作成(あなたは面白い芸人です。卵をお題に一発ギャグを考えて。)
const formattedChatPrompt  = await chatPrompt.formatMessages({ role: "面白い芸人", input: "卵", });
console.log({ formattedChatPrompt  });

  • formatPromptValue()toChatMessages()質問で使う配列を生成する。
💡
ここでは以下の質問が生成される。

役割「あなたは面白い芸人です。」

質問「卵をお題に一発ギャグを考えて」

※今回は「面白い芸人」「卵」で固定だが、ここをユーザー入力値にすると便利✨

【補足】formatPromptValue()toChatMessages()の戻り値
const formattedChatPrompt  = await chatPrompt.formatMessages({ role: "面白い芸人", input: "卵", });
// 戻り値の内容
// 型:BaseMessage[]
//[
//  SystemMessage {
//    lc_serializable: true,
//    lc_kwargs: { content: 'あなたは面白い芸人です。', additional_kwargs: {} },
//    lc_namespace: [ 'langchain_core', 'messages' ],
//    content: 'あなたは面白い芸人です。',
//    name: undefined,
//    additional_kwargs: {}
//  },
//  HumanMessage {
//    lc_serializable: true,
//    lc_kwargs: { content: '卵をお題に一発ギャグを考えて。', additional_kwargs: {} },
//    lc_namespace: [ 'langchain_core', 'messages' ],
//    content: '卵をお題に一発ギャグを考えて。',
//    name: undefined,
//    additional_kwargs: {}
//  }
//]

【解説】④質問する(あなたは面白い芸人です。卵をお題に一発ギャグを考えて。)
// ⑤質問する(あなたは面白い芸人です。卵をお題に一発ギャグを考えて。)
const res = await chat.invoke( formattedChatPrompt  );  
console.log(res);

  • chat.call(...)質問を実行できる。
  • テンプレートに当てはめる文字を引数に指定する。
💡
ここでは以下の質問を実行する。

役割「あなたは面白い芸人です。」

質問「卵をお題に一発ギャグを考えて」

ビルド

TypeScriptをビルドしてJavaScriptファイルを生成する。

以下のコマンドを実行する✅

tsc

Image in a image block

サンプルプログラムを実行する

HTMLからJSを呼び出しても、JSを単体で実行してもどちらでもOK。

今回はJSを単体で動かして動作を確認する。

以下のコマンドを実行する✅

node sample.js

何か返答が表示されればOK!

Image in a image block

次の記事

📎
次回は独自データを使って回答してもらう方法を解説する!

📄 初心者によるTypeScript版LangChain【③独自データ編】

参考サイト

公式ドキュメント(テンプレート)