Cloudflare Workers上でLangChainを動かし指定したWebサイトについて質問できるか試してみた

2023.05.22

どうも!オペレーション部の西村祐二です。

Cloudflareから下記ブログが公開され、Cloudflare WorkersでLangChainが動くことを知りました。

Using LangChainJS and Cloudflare Workers together

このブログはLangChain、Cloudflare Workersを使ったチュートリアルであり、読み込むWebページとしてブルックリンのwikipediaが利用されていました。

そこで、今回、このブログを参考に弊社クラスメソッドのカルチャーのページを読み込んで、このWebページについて質問できるか試してみました

今回は英語のページを利用します。なぜか日本語のページだとあまり回答精度がよくなかったためです。

Classmethod Leadership Principles (CLP)

成果物

デプロイ時に払い出されるWorkersのURLのクエリパラメータに question=質問内容 とすることで質問できるようにします。

  • ?question=CLPとは?

きちんと、Webページの内容を読み取ってCLPはClassmethod Leadership Principlesの略であることを回答してくれています。

  • ?question=CLPの要素を教えて

直訳ですが、「リーダーシップ、パートナーシップ、多様性、プロフェッショナリズム、感謝の気持ち、視点、フィードバック、アウトプット、スタート・スモール、そして楽しみ」と回答してくれています。

  • ?question=明日の天気は?

Webページに記載のない関係ないことを質問すると、わからないと回答が返ってきました。

やってみる

Cloudflareのブログに記載の内容とほとんど同様ですが、試していきます

環境

  • Node.js: 18.15.0

  • langchain: 0.0.78

  • wrangler: 3.0.0

前提条件

  • OpenAI APIキーは事前に払い出しておきます

  • Cloudflareが利用できる状態にしておきます

プロジェクトを作成

wranglerを使って雛形を作成します。

対話形式の入力は下記のようにしてます。

  • 名前は「test-langchain」
  • タイプは"Hello World" script
  • TypeScriptは No
  • デプロイは No
$ npx wrangler init test-langchain

 ⛅️ wrangler 3.0.0
------------------
Using npm as package manager.
▲ [WARNING] The `init` command is no longer supported. Please use `npm create cloudflare@2` instead.

  The `init` command will be removed in a future version.


Running `npm create cloudflare@2`...
Need to install the following packages:
  create-cloudflare@2.0.7
Ok to proceed? (y) y

using create-cloudflare version 2.0.7

╭ Create an application with Cloudflare Step 1 of 3
│
├ Where do you want to create your application?
│ dir test-langchain
│
├ What type of application do you want to create?
│ type "Hello World" script
│
├ Do you want to use TypeScript?
│ typescript no
│
├ Copying files from "simple" template
│
╰ Application created

╭ Installing dependencies Step 2 of 3
│
├ Installing dependencies
│ installed via `npm install`
│
╰ Dependencies Installed

╭ Deploy with Cloudflare Step 3 of 3
│
├ Do you want to deploy your application?
│ no deploying via `npm run deploy`
│
├  APPLICATION CREATED  Deploy your application with npm run deploy
│
│ Run the development server npm run dev
│ Deploy your application npm run deploy
│ Read the documentation https://developers.cloudflare.com/workers
│ Stuck? Join us at https://discord.gg/cloudflaredev
│
╰ See you again soon!
$ cd test-langchain

下記、コマンド実行して、動作確認しておきます。

ローカルサーバが起動して、ローカルで動作確認することができます。 bを押すと自動的にブラウザが開きます。

Hello Worldと画面上に表示されていればOKです

$ npm run start

動作確認できたら、ローカルサーバを停止しておきます。

ライブラリインストール

langchainとWebページを読み込むときに利用するcheerioをインストールしておきます。

$ npm install langchain cheerio

今回はCherryioを使っていますが、LangChainは他にもPuppeteerPlaywrightなど多くのライブラリに対応しているので、Webローダーを変更して試してみることもできます。

Web Loaders | ?️? Langchain

実装

LangChainを使ってWebページに関する質問ができるように workers.jsを下記のように修正します。

src/worker.js

import { CheerioWebBaseLoader } from 'langchain/document_loaders/web/cheerio';
import { OpenAIEmbeddings } from 'langchain/embeddings/openai';
import { MemoryVectorStore } from 'langchain/vectorstores/memory';
import { OpenAI } from 'langchain/llms/openai';
import { RetrievalQAChain } from 'langchain/chains';

export default {
  async fetch(request, env, ctx) {
	url = 'https://classmethod.jp/english/leadership-principles/';
    const loader = new CheerioWebBaseLoader(url);
    const docs = await loader.load();
    const store = await MemoryVectorStore.fromDocuments(docs, new OpenAIEmbeddings({ openAIApiKey: env.OPENAI_API_KEY }));

    const model = new OpenAI({ openAIApiKey: env.OPENAI_API_KEY });
    const chain = RetrievalQAChain.fromLLM(model, store.asRetriever());

    const { searchParams } = new URL(request.url);
    const question = searchParams.get('question') ?? 'この記事は何ですか?CLPとはなんですか?';
    const res = await chain.call({
      query: question,
    });
    return new Response(res.text);
  },
};

簡単に解説していきます。

  • CheerioWebBaseLoader

CheerioWebBaseLoaderを使用して指定したウェブサイト(今回はhttps://classmethod.jp/english/leadership-principles/)からデータをロードします。Cloudflareのブログでは読み込むページがそれなりに規模の大きいページなのでloadAndSplitを使っていますが、今回は小さいページなのでloadのまま利用しています。

  • MemoryVectorStore

ベクトル情報を保存する場所として、一時的なメモリ内ベクトルストアであるMemoryVectorStoreを使用します。

  • OpenAIEmbeddings

'OpenAIEmbeddings'を使用して、読み込んだドキュメントからベクトル情報を作成します。OpenAIのAPIキーを使用します。

  • RetrievalQAChain

'OpenAI'と'RetrievalQAChain'を使用して、質問応答のモデルを作成します。このモデルは、Embeddingされたドキュメントと質問を入力として受け取り、質問に対する回答を生成します。

  • fetch関数

'fetch'関数内で、リクエストから質問を取得し、質問応答モデルを使用して回答を生成します。質問はURLの'question'パラメータから取得します。もし質問がない場合は、デフォルトの質問'この記事は何ですか?CLPとはなんですか?'が使用されます。

ローカルで動作確認

ローカルでOpenAIのAPIキーの環境変数を読み込むために.dev.varsを作成しておきます

.dev.vars

OPENAI_API_KEY=sk-XXXXXXXXXX

下記コマンドでローカルサーバが起動して、ローカルで動作確認することができます。 ローカルサーバが起動したら、bを押すと自動的にブラウザが開きます。

$ npm run start

URLのクエリパラメータに ?question=質問内容 とすることで質問して、回答が返ってくるか試してみましょう。

環境変数をCloudflare上に登録

デプロイの前に環境変数をCloudflare Workersに登録しておきます。

下記コマンドを実行すると、valueがきかれるのでOpenAIのAPIキーを入力して登録します。

$ npx wrangler secret put OPENAI_API_KEY

登録できたらCloudflare Workersの画面上から確認することができます。

デプロイ

下記コマンドでCloudflare上にデプロイできます。

$ npm run deploy

デプロイが完了したらCloudflare WorkersのURLが発行されるのでアクセスして、ローカルと同様に動作する確認しましょう。

さいごに

Cloudflare Workers上でLangChainを動かし指定したWebサイトについて質問できるチュートリアルを試してみました。

これから、LangChain、Cloudflare Workersを使ってアプリケーションを作るための、はじめの一歩として活用できるかなと思います。

誰かの参考になれば幸いです。