🌟

LangChainを用いたVectorizeとの連携

2024/05/22に公開

今日は前回の記事に引き続きLangChainを使ってVectorizeに対する文字列を用いた検索を実装していきます。
https://zenn.dev/kameoncloud/articles/fcdf5b7ee3e3a3

LangChainとは

LangChain は、大規模言語モデル (LLM)と連携するアプリケーションを構築するためのツール群です。LangChainを用いることで様々なものが抽象化されます。例えば以下のステップでは、ベクトルデータではなく自然言語での検索を可能としますが、これは裏でLangChainが投入された質問文をベクトルデータに変換し、Vectorizeにクエリを投げてくれているためです。この記事ではLLMモデルにWorkersAIを用います。

Workers AIとは

https://zenn.dev/kameoncloud/articles/707b3b623bdb87
Cloudflare Workersが提供するGPUバンドルモデルのWorkersです。GPUが使えるだけではなくオープンソース生成AIモデルを40種類以上提供しています。勿論OpenAI等外部の著名LLMモデルとの連携も簡単に行えますが、以下のステップではWorkersAIのビルトインLLMモデルを利用します。

さっそくやってみる

LangChainがネイティブでVectorizeに対応しているため、そちらのチュートリアルをまずは試します。
https://js.langchain.com/v0.1/docs/integrations/vectorstores/cloudflare_vectorize/
まずは以下の記事を終わらせておくことを推奨します。終わらせなくてもハンズオン自体は可能ですがおそらく慣れていない方だと何のことかわからないかもしれません。
https://zenn.dev/kameoncloud/articles/fcdf5b7ee3e3a3
まずはHello Worldまで終わらせておきます。

mkdir langchainvectorize
cd .\langchainvectorize\
wrangler init
Delegating to locally-installed wrangler@3.10.0 over global wrangler@2.14.0...
Run `npx wrangler init` to use the local version directly.

 ⛅️ wrangler 3.10.0 (update available 3.57.1)
-------------------------------------------------------
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`...

using create-cloudflare version 2.0.9

╭ Create an application with Cloudflare Step 1 of 3
│
├ Where do you want to create your application?
│ dir langchainvectorize
│
├ What type of application do you want to create?
│ type "Hello World" script
│
├ Do you want to use TypeScript?
│ typescript yes
│
├ Copying files from "simple" template
│
├ Do you want to use git?
│ git no
│
╰ 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 start
│ 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 .\langchainvectorize\
wrangler deploy
Delegating to locally-installed wrangler@3.57.1 over global wrangler@2.14.0...
Run `npx wrangler deploy` to use the local version directly.

 ⛅️ wrangler 3.57.1
-------------------
√ Select an account » Harunobukameda Demo account
Total Upload: 0.19 KiB / gzip: 0.16 KiB
Uploaded langchainvectorize (0.89 sec)
Published langchainvectorize (3.65 sec)
  https://langchainvectorize.harunobukameda.workers.dev
Current Deployment ID: e348934a-7dd5-41e3-b2a7-7cc9e5bf4835
Current Version ID: e348934a-7dd5-41e3-b2a7-7cc9e5bf4835


Note: Deployment ID has been renamed to Version ID. Deployment ID is present to maintain compatibility with the previous behavior of this command. This output will change in a future version of Wrangler. To learn more visit: https://developers.cloudflare.com/workers/configuration/versions-and-deployments 

生成されたURLにブラウザでアクセスするとHello Worldが出力されるはずです。
次にVectorizeインスタンスを作成します。

wrangler vectorize create langchainvectorize --preset @cf/baai/bge-small-en-v1.5

langchainvectorizeの部分は皆さん毎に名前を変えてください。

--preset @cf/baai/bge-small-en-v1.5について解説します。前回の記事ではVectorizeインスタンスがサポートするベクトル次元であるdimensionsと検索アルゴリズムであるmetricを明示的にして言いましたが、今回はWorkersAIの組み込みモデルの一つである@cf/baai/bge-small-en-v1.5をパラメータと指定することでモデルの推奨値を設定しています。
以下のようにマネージメントコンソールでは384次元のコサイン類似度を用いたインスタンスが作成されていることがわかります。

以下の部分は後ほど使いますのでコピーしておきます。

[[vectorize]]
binding = "VECTORIZE_INDEX" # available within your Worker on env.VECTORIZE_INDEX
index_name = "langchainvectorize"

次にCloudflare用LangChainパッケージをインストールします。

npm install @langchain/cloudflare

wrangler.tomlに以下を追記します。

[[vectorize]]
binding = "VECTORIZE_INDEX" # available within your Worker on env.VECTORIZE_INDEX
index_name = "langchainvectorize"

[ai]
binding = "AI"

langchainvectorizeの部分は皆さん毎に名前を変えてください。

こうすることで、Workersのソースからは宣言が不要でenv環境変数にVectorizeインスタンスとAI関連ライブラリがセットされ操作が可能となります。
ではworkers.tsを以下に置換します。

workers.ts
// @ts-nocheck

import type {
  VectorizeIndex,
  Fetcher,
  Request,
} from "@cloudflare/workers-types";

import {
  CloudflareVectorizeStore,
  CloudflareWorkersAIEmbeddings,
} from "@langchain/cloudflare";

export interface Env {
  VECTORIZE_INDEX: VectorizeIndex;
  AI: Fetcher;
}

export default {
  async fetch(request: Request, env: Env) {
    const { pathname } = new URL(request.url);
    const embeddings = new CloudflareWorkersAIEmbeddings({
      binding: env.AI,
      model: "@cf/baai/bge-small-en-v1.5",
    });
    const store = new CloudflareVectorizeStore(embeddings, {
      index: env.VECTORIZE_INDEX,
    });
    if (pathname === "/") {
      const results = await store.similaritySearch("hello", 5);
      return Response.json(results);
    } else if (pathname === "/load") {
      // Upsertion by id is supported
      await store.addDocuments(
        [
          {
            pageContent: "hello",
            metadata: {},
          },
          {
            pageContent: "world",
            metadata: {},
          },
          {
            pageContent: "hi",
            metadata: {},
          },
        ],
        { ids: ["id1", "id2", "id3"] }
      );

      return Response.json({ success: true });
    } else if (pathname === "/clear") {
      await store.delete({ ids: ["id1", "id2", "id3"] });
      return Response.json({ success: true });
    }

    return Response.json({ error: "Not Found" }, { status: 404 });
  },
};

詳しい話は後にして一旦wrangler deployでデプロイを行います。
以下のようにbindingsが成功していることが出力されているはずです。

Your worker has access to the following bindings:
- Vectorize Indexes:
  - VECTORIZE_INDEX: langchainvectorize
- AI:
  - Name: AI

先ほどブラウザでアクセスをしたURLの後半に/loadを付け加えてアクセスすると{"success":true}と表示されるはずです。その後loadを削除してアクセスすると

[{"pageContent":"hello","metadata":{}},{"pageContent":"hi","metadata":{}},{"pageContent":"world","metadata":{}}]

と検索結果が表示されます。

簡単な解説

/loadを付けてアクセスした場合以下が実行されます。

else if (pathname === "/load") {
		// Upsertion by id is supported
		await store.addDocuments(
		  [
			{
			  pageContent: "hello",
			  metadata: {},
			},
			{
			  pageContent: "world",
			  metadata: {},
			},
			{
			  pageContent: "hi",
			  metadata: {},
			},
		  ],
		  { ids: ["id1", "id2", "id3"] }
		);
  
		return Response.json({ success: true });

これはhello,world,hiという文字列をVectorizeに投入しています。Vectorizeは当然ベクトルデータを要求します。store.addDocumentsの部分がベクトルに文字列を変換してくれています。この抽象化がLangChainを使うことのメリットです。実際に指示している部分は以下です。

  import {
	CloudflareVectorizeStore,
	CloudflareWorkersAIEmbeddings,
  } from "@langchain/cloudflare";
<snip>
  const store = new CloudflareVectorizeStore(embeddings, {
		index: env.VECTORIZE_INDEX,
	  });
<snip>
await store.addDocuments(

storeというオブジェクトが持つaddDocumentsメソッドがこれを実現しています。
URLのルートパスにアクセスした際はいかが実行され検索が行われています。

	  if (pathname === "/") {
		const results = await store.similaritySearch("hello", 5);
		return Response.json(results);

よくわからないので、もう少し・・・

前回の記事でベクトル検索がなんとなくイメージがついた方でも、上のステップではLangChainがベクトルを抽象化しているためよくわからないかもしれません。
まずはソースコードを以下に変換しwrangler deployを実行します。

// @ts-nocheck

import type {
	VectorizeIndex,
	Fetcher,
	Request,
  } from "@cloudflare/workers-types";
  
  import {
	CloudflareVectorizeStore,
	CloudflareWorkersAIEmbeddings,
  } from "@langchain/cloudflare";
  
  export interface Env {
	VECTORIZE_INDEX: VectorizeIndex;
	AI: Fetcher;
  }
  
  export default {
	async fetch(request: Request, env: Env) {
	  const { pathname } = new URL(request.url);
	  const embeddings = new CloudflareWorkersAIEmbeddings({
		binding: env.AI,
		model: "@cf/baai/bge-small-en-v1.5",
	  });
	  const store = new CloudflareVectorizeStore(embeddings, {
		index: env.VECTORIZE_INDEX,
	  });
	  if (pathname === "/") {
		const results = await store.similaritySearch("hello", 5);
		return Response.json(results);
	  } else if (pathname === "/load") {
		// Upsertion by id is supported
		await store.addDocuments(
		  [
			{
			  pageContent: "hello",
			  metadata: {},
			},
			{
			  pageContent: "world",
			  metadata: {},
			},
			{
			  pageContent: "hi",
			  metadata: {},
			},
		  ],
		  { ids: ["id1", "id2", "id3"] }
		);
  
		return Response.json({ success: true });
	  } else if (pathname === "/clear") {
		await store.delete({ ids: ["id1", "id2", "id3"] });
		return Response.json({ success: true });
	  } else if (pathname.includes("question")) {
		const params = new URLSearchParams(pathname.search);
		
		const questionParam = pathname.split('/').pop().split('=');
		const questionValue = decodeURIComponent(questionParam[1]);
		const results = await store.similaritySearch(questionValue, 5);
		return Response.json(results);
	  }
	  return Response.json({ error: "Not Found" }, { status: 404 });
	},
  };

以下の部分が追記されています。

	  } else if (pathname.includes("question")) {
		const params = new URLSearchParams(pathname.search);
		
		const questionParam = pathname.split('/').pop().split('=');
		const questionValue = decodeURIComponent(questionParam[1]);
		const results = await store.similaritySearch(questionValue, 5);
		return Response.json(results);
	  }

こうすることで<url>/question=xxxxで質問を投げると動作するようになります。
どんな文字列を投入したとしても無理やりHello,hi,worldの3つに対するコサイン類似度を導き出して検索していることがわかります。これは従来の全文検索技術とは異なるところです。

では次にVectorizeの中に何が格納されているかを見ていきます。
今度はさらにコードを以下に置換します。

// @ts-nocheck

import type {
	VectorizeIndex,
	Fetcher,
	Request,
  } from "@cloudflare/workers-types";
  
  import {
	CloudflareVectorizeStore,
	CloudflareWorkersAIEmbeddings,
  } from "@langchain/cloudflare";
  
  export interface Env {
	VECTORIZE_INDEX: VectorizeIndex;
	AI: Fetcher;
  }
  
  export default {
	async fetch(request: Request, env: Env) {
	  const { pathname } = new URL(request.url);
	  const embeddings = new CloudflareWorkersAIEmbeddings({
		binding: env.AI,
		model: "@cf/baai/bge-small-en-v1.5",
	  });
	  const store = new CloudflareVectorizeStore(embeddings, {
		index: env.VECTORIZE_INDEX,
	  });
	  if (pathname === "/") {
		let ids = ["id1", "id2", "id3"];
		const vectors = await env.VECTORIZE_INDEX.getByIds(ids);
		return Response.json(vectors);
	  } else if (pathname === "/load") {
		// Upsertion by id is supported
		await store.addDocuments(
		  [
			{
			  pageContent: "hello",
			  metadata: {},
			},
			{
			  pageContent: "world",
			  metadata: {},
			},
			{
			  pageContent: "hi",
			  metadata: {},
			},
		  ],
		  { ids: ["id1", "id2", "id3"] }
		);
 		return Response.json({ success: true });
	  } else if (pathname === "/clear") {
		await store.delete({ ids: ["id1", "id2", "id3"] });
		return Response.json({ success: true });
	  } else if (pathname.includes("question")) {
		const params = new URLSearchParams(pathname.search);
		const questionParam = pathname.split('/').pop().split('=');
		const questionValue = decodeURIComponent(questionParam[1]);
		const results = await store.similaritySearch(questionValue, 5);
		return Response.json(results);
	  }
  	  return Response.json({ error: "Not Found" }, { status: 404 });
	},
  };

変更部分は以下です。

	  if (pathname === "/") {
		let ids = ["id1", "id2", "id3"];
		const vectors = await env.VECTORIZE_INDEX.getByIds(ids);
		return Response.json(vectors);

ルートディレクトリにアクセスした場合、格納済ベクトルデータが以下のように表示されます。

[{"id":"id1","values":[-0.07858739048242569,-0.05518757179379463,0.06329193711280823,-0.06529469043016434,-0.00686682341620326,0.008863654918968678,0.07756572961807251,0.03589129075407982,0.039529215544462204,0.015869077295064926,0.013142501935362816,-0.08403453230857849,0.03443029895424843,0.05694016069173813,0.026875033974647522,-0.009031557478010654,0.044601283967494965,-0.06008705869317055,-0.12275326251983643,0.0040635098703205585,-0.006414125207811594,0.026525486260652542,-0.059128936380147934,-0.04845403879880905,0.013193795457482338,-0.0025295682717114687,0.03878190368413925,-0.007728232070803642,0.017131086438894272,-0.028045406565070152,-0.040015000849962234,0.006811859086155891,0.06166154518723488,0.017396556213498116,0.017785143107175827,-0.03222794458270073,0.04035251587629318,-0.018793350085616112,-0.0719468742609024,0.000580417166929692,0.05401783809065819,-0.05134395509958267,0.013464736752212048,-0.017443858087062836,0.041427068412303925,-0.039522960782051086,0.032168060541152954,0.06373053044080734,0.050864171236753464,-0.0280299112200737,-0.04306752234697342,0.010306356474757195,-0.014843384735286236,0.008081824518740177,0.012299452908337116,0.10594241321086884,0.0946798175573349,-0.043891675770282745,0.043804626911878586,0.020443348214030266,0.04388998821377754,0.0018578263698145747,-0.1578526496887207,0.05222703889012337,-0.0050848014652729034,-0.006859203334897757,0.002337867394089699,-0.029232705011963844,0.041843481361866,0.017749793827533722,0.024904625490307808,-0.02373937889933586,-0.010803806595504284,0.04372792690992355,0.015134034678339958,0.005191917065531015,0.04464405030012131,-0.018710413947701454,0.04829087853431702,-0.06154691055417061,-0.01918647065758705,-0.007109636440873146,-0.011615538969635963,0.015543380752205849,-0.03408541530370712,-0.03208698704838753,-0.014547977596521378,0.0793890431523323,-0.009153321385383606,-0.007571564521640539,-0.02476615086197853,0.00011746623931685463,-0.0030726606491953135,0.035529669374227524,-0.04744928330183029,-0.025394292548298836,-0.004193232860416174,0.022010304033756256,-0.08019246906042099,0.18309113383293152,-0.04864269122481346,0.012012923136353493,0.06053812429308891,-0.057982463389635086,0.008023272268474102,0.03168484568595886,0.022298365831375122,-0.008158677257597446,-0.0095672607421875,-0.01275705173611641,0.02883702702820301,-0.06440071016550064,0.017188118770718575,-0.009602687321603298,0.017404532060027122,-0.019012106582522392,0.020454486832022667,0.014946060255169868,0.0910530611872673,-0.07697191834449768,0.010780474171042442,0.0162963904440403,-0.06107855215668678,-0.005914093926548958,0.06816009432077408,-0.0419071689248085,0.03641553968191147,0.092640221118927,-0.014787215739488602,0.05050507187843323,0.0344480499625206,0.05440022423863411,-0.08319468796253204,-0.06048857793211937,-0.043202776461839676,0.008316701278090477,-0.01692861318588257,-0.037525076419115067,-0.02234259434044361,-0.062015362083911896,-0.04205074906349182,-0.09761565923690796,-0.055376484990119934,-0.1211712509393692,0.008811194449663162,-0.030347708612680435,-0.033530090004205704,0.028956817463040352,-0.025854308158159256,-0.03435605391860008,-0.02151367999613285,0.03560848906636238,-0.01912488415837288,-0.04852599278092384,0.0204942487180233,-0.025550318881869316,0.03491336107254028,0.048325903713703156,0.004299059975892305,0.05222681537270546,0.010423003695905209,-0.046573277562856674,-0.008487416431307793,-0.008018354885280132,-0.07031315565109253,-0.149518683552742,0.006581694353371859,0.006247656419873238,0.031075838953256607,0.0305606909096241,0.061548713594675064,0.016977893188595772,-0.028690651059150696,0.06118559464812279,0.09286206215620041,0.03358263149857521,0.027269499376416206,0.03312518075108528,-0.021973945200443268,-0.016237521544098854,-0.007129430305212736,-0.037340354174375534,-0.016527453437447548,-0.0019422153709456325,0.0075279357843101025,0.00118954386562109,0.004817322362214327,0.035316355526447296,0.004136811941862106,0.04837265610694885,0.01965053752064705,0.046872057020664215,0.022256603464484215,0.015602495521306992,-0.04181421920657158,0.0034291816409677267,0.0653623715043068,-0.04326909780502319,0.014947790652513504,-0.018148673698306084,0.03526782989501953,0.02346879057586193,0.026588885113596916,0.074410580098629,0.10351403057575226,-0.0019782036542892456,0.013598015531897545,-0.007723835296928883,0.06332395225763321,0.01142906490713358,-0.029839448630809784,-0.02987692318856716,0.07740498334169388,-0.02784745953977108,-0.011063666082918644,-0.06350596249103546,-0.017248038202524185,0.041541360318660736,-0.006422762759029865,0.040722671896219254,0.010429506190121174,-0.05389287695288658,-0.10298803448677063,-0.2407265454530716,0.10746218264102936,0.009032939560711384,-0.05786783993244171,0.052267614752054214,-0.017297644168138504,0.05393416807055473,-0.018458634614944458,0.11145278811454773,0.01018551830202341,0.03415551409125328,-0.04444699361920357,-0.028399258852005005,0.019378138706088066,0.014497184194624424,0.023778192698955536,0.0003105323703493923,-0.03621770441532135,0.034525252878665924,-0.04088309034705162,0.015468346886336803,0.007345230784267187,0.04729091748595238,-0.055416155606508255,-0.019893668591976166,-0.04862019419670105,0.14788015186786652,0.1666087806224823,0.06340715289115906,-0.007041553501039743,0.05038587376475334,-0.033533837646245956,-0.00942420307546854,-0.17432647943496704,0.04654280096292496,0.05285877734422684,0.01410352811217308,-0.06655514240264893,-0.07596098631620407,-0.025327404960989952,-0.03596959263086319,-0.040532805025577545,0.02091902866959572,-0.04563770815730095,-0.004227748140692711,-0.06599375605583191,-0.08031164109706879,-0.03533226251602173,-0.08190534263849258,0.0324256457388401,0.04065407067537308,-0.0236936267465353,0.039021220058202744,0.04427769035100937,-0.027077415958046913,-0.07184921950101852,-0.00013765734911430627,-0.030344415456056595,-0.03234594687819481,0.03290014714002609,-0.016265869140625,0.030844543129205704,-0.0033116741105914116,0.006246077362447977,-0.02866293303668499,0.09401340037584305,-0.03222305700182915,-0.035111986100673676,0.03923093155026436,-0.008033966645598412,-0.007301888428628445,-0.03447971120476723,-0.005264835897833109,0.003018943825736642,0.026125023141503334,0.042849648743867874,-0.008191820234060287,0.01007582526654005,-0.03140093386173248,-0.06321674585342407,0.014955893158912659,0.009541615843772888,0.0678110346198082,0.012029014527797699,0.013347502797842026,0.0449632965028286,0.056901805102825165,-0.0359998419880867,0.028988873586058617,-0.06293808668851852,-0.04918007180094719,-0.000678470591083169,0.009538072161376476,-0.13191038370132446,0.027732305228710175,-0.02965371310710907,-0.2674868702888489,0.07054328173398972,-0.02611263282597065,0.02666102908551693,-0.04690418392419815,0.0696825385093689,0.028240105137228966,0.06766811013221741,-0.08645973354578018,0.02100091427564621,-0.01836184225976467,0.0738290473818779,0.028854500502347946,0.0468628816306591,-0.041380491107702255,0.05492647364735603,0.05177422985434532,-0.0697096511721611,-0.0036408237647265196,-0.03028908185660839,-0.019586430862545967,-0.00315968063659966,0.17669059336185455,-0.06266375631093979,0.09418877214193344,0.030840007588267326,-0.022067781537771225,0.03856108337640762,0.024947894737124443,-0.022813960909843445,0.002825902309268713,0.01409818697720766,0.051409780979156494,-0.043613966554403305,0.04827408120036125,0.00994829460978508,-0.04915844276547432,0.012530234642326832,0.012461687438189983,-0.018744777888059616,-0.06210745871067047,-0.006396378390491009,-0.029210615903139114,0.03643903136253357,0.08219505101442337,-0.06503813713788986,-0.03256896883249283,0.021249350160360336,-0.030697157606482506,-0.01357246469706297,0.0019335889955982566,0.04401712864637375,0.013528172858059406,0.051175639033317566,0.010696206241846085,-0.008262217044830322,0.001054728520102799,-0.017963172867894173,0.0024026662576943636,-0.028526391834020615,-0.023807568475604057,-0.027758505195379257,0.04857239872217178,0.04342709854245186,0.004157151561230421],"metadata":{"text":"hello"}},{"id":"id2","values":[0.04459340497851372,-0.010641884058713913,0.010944396257400513,-0.03533509746193886,0.04293471574783325,0.006360142957419157,0.002290107775479555,0.06608738005161285,0.045012280344963074,-0.007005622610449791,0.02098316326737404,-0.026460008695721626,0.04245656356215477,0.062237780541181564,-0.0390424020588398,-0.0334414578974247,-0.055829714983701706,-0.07709861546754837,-0.11404114216566086,-0.01318515744060278,0.10220812261104584,-0.02547219768166542,0.029217727482318878,-0.05729328840970993,-0.004152211826294661,0.011975652538239956,-0.021704312413930893,-0.00705894036218524,-0.022046994417905807,-0.06598930060863495,-0.044926851987838745,-0.09764715284109116,-0.017284519970417023,0.058872632682323456,-0.020659394562244415,-0.03131002187728882,0.00162939028814435,0.027875306084752083,-0.06810829788446426,0.04348236694931984,0.030887946486473083,0.023597225546836853,0.005865089129656553,-0.020075298845767975,0.0043321410194039345,-0.03752490133047104,-0.025471156463027,0.011688129045069218,0.006342921406030655,-0.02898552641272545,0.002254701219499111,-0.011131222359836102,0.02267306111752987,0.01674179919064045,-0.0009216838516294956,0.0077835144475102425,0.03544309735298157,0.01566729135811329,0.0642145574092865,-0.00445335078984499,0.04150141775608063,-0.023757468909025192,-0.19504153728485107,0.09540954232215881,0.032317500561475754,0.03000173345208168,0.03525495529174805,0.04536476358771324,-0.04050406441092491,-0.005042219068855047,0.026920387521386147,-0.0024497630074620247,0.09671935439109802,0.08243570476770401,0.048454005271196365,-0.04042230546474457,0.015472829341888428,-0.03482803329825401,-0.02686762437224388,-0.026464812457561493,0.06084170192480087,-0.049870844930410385,-0.04484260454773903,-0.012771831825375557,0.0036791558377444744,0.019356731325387955,-0.02863258495926857,0.031064558774232864,-0.009045685641467571,-0.004153078887611628,-0.1272289752960205,0.003763676853850484,0.03512018173933029,0.019936829805374146,-0.032015711069107056,-0.04477280005812645,0.023305177688598633,0.003149491734802723,-0.04704558849334717,0.17262457311153412,-0.06932919472455978,0.07115200161933899,0.037318967282772064,-0.0019309463677927852,0.06296441704034805,-0.008937901817262173,-0.04176316782832146,-0.007187788374722004,-0.07411076128482819,-0.0532677099108696,-0.007799811195582151,-0.029164038598537445,0.03918367251753807,-0.002151516964659095,-0.012275132350623608,-0.0443437397480011,0.07864966988563538,0.023877419531345367,-0.01908683590590954,-0.024701643735170364,-0.05232081189751625,0.007259703241288662,0.07334530353546143,-0.0005622307653538883,0.03334574028849602,0.013120988383889198,0.07748650014400482,0.1323252171278,0.05418028309941292,-0.019611213356256485,0.0683758333325386,0.002020155545324087,-0.01662585698068142,0.0012523723999038339,0.006197719369083643,-0.03741902858018875,0.045650895684957504,-0.003985653165727854,0.034051649272441864,-0.04144257679581642,0.01781698316335678,-0.06940198689699173,-0.04520375654101372,-0.08506700396537781,0.007442481815814972,0.054331377148628235,-0.02556096762418747,0.025528592988848686,0.007752870675176382,0.0026121200062334538,-0.00895928218960762,0.051674049347639084,-0.011321489699184895,0.019231820479035378,0.007817595265805721,0.07764843106269836,0.06800736486911774,-0.01196195837110281,0.027737917378544807,0.030287504196166992,0.03738952800631523,0.03256784379482269,-0.056411419063806534,0.07766943424940109,-0.014789929613471031,-0.08754836767911911,-0.04256550967693329,-0.03864714503288269,-0.05023978278040886,-0.015539842657744884,0.036845285445451736,0.045870520174503326,-0.023818081244826317,0.04921503737568855,0.07558347284793854,-0.02437330223619938,0.04373456910252571,0.09417098015546799,0.01380974892526865,-0.01455062534660101,0.015192882157862186,-0.017607999965548515,-0.008142832666635513,-0.0007460372289642692,0.041291579604148865,-0.011692914180457592,0.02285514585673809,-0.016073044389486313,0.024440845474600792,-0.02787092700600624,0.05640218034386635,0.11541030555963516,-0.05392159894108772,-0.01428657304495573,-0.00985613465309143,-0.01436976995319128,-0.00884958915412426,-0.04501091316342354,0.04216254502534866,-0.044756531715393066,0.07033730298280716,-0.0007248413749039173,0.023259351029992104,-0.028271645307540894,0.06901601701974869,0.001928383600898087,0.011446001008152962,0.0031128583941608667,-0.015032181516289711,0.020925885066390038,0.0011805907124653459,-0.0465925894677639,0.018535157665610313,-0.02538447082042694,-0.018279150128364563,-0.08257433027029037,-0.02600211463868618,-0.022669386118650436,-0.0437481589615345,0.04760659486055374,-0.018888229504227638,-0.09621790051460266,0.025129949674010277,-0.26208731532096863,-0.0033608749508857727,-0.024592693895101547,-0.024021530523896217,0.045747216790914536,0.042478758841753006,-0.02109367772936821,-0.03479120880365372,0.06163836643099785,0.1327248513698578,0.025222258642315865,0.02942229062318802,0.04422273114323616,0.08912666887044907,0.024807170033454895,0.0021648441907018423,-0.029849983751773834,0.04792711138725281,-0.0020463727414608,-0.03722759336233139,0.009474402293562889,0.010961370542645454,-0.04432060196995735,-0.03926074504852295,0.056678853929042816,-0.0950658917427063,0.17497408390045166,0.05923128128051758,-0.018168233335018158,-0.013189115561544895,0.041409023106098175,0.032371241599321365,0.035029541701078415,-0.1927606612443924,0.0571303628385067,0.018453393131494522,0.024991745129227638,-0.05583707615733147,-0.06979478895664215,-0.06552126258611679,-0.02658742666244507,0.03928196430206299,0.02419654093682766,-0.05546317994594574,0.020803919062018394,-0.018527762964367867,0.028111925348639488,-0.01038176380097866,-0.015405216254293919,-0.018887631595134735,-0.0013373811962082982,0.007577888201922178,0.08036293834447861,0.02216232568025589,-0.07127048820257187,0.0006902655586600304,-0.024631742388010025,-0.0032759285531938076,-0.057914894074201584,0.04198828339576721,-0.015016870573163033,-0.024377107620239258,-0.041181422770023346,0.017332395538687706,-0.05641556531190872,0.03125939890742302,-0.017871258780360222,-0.014176859520375729,0.022492891177535057,-0.0770288035273552,-0.08498839288949966,0.0853755846619606,0.06350042670965195,-0.04380341246724129,0.05913591757416725,0.03822707012295723,0.06135280057787895,-0.002642634091898799,-0.08033981174230576,-0.0005067199817858636,0.10477271676063538,0.04127158597111702,0.018929583951830864,0.0205373615026474,0.05425271764397621,0.024557173252105713,0.052732959389686584,-0.022255418822169304,-0.016082536429166794,-0.01995696686208248,-0.040105607360601425,-0.05269060656428337,-0.024005768820643425,-0.07681253552436829,-0.01993706077337265,-0.04609819874167442,-0.2402649223804474,0.03317076340317726,-0.04212889075279236,0.055689986795186996,-0.01887410692870617,-0.022450894117355347,-0.0032109380699694157,0.08280666917562485,-0.008006304502487183,-0.015638353303074837,0.0068662636913359165,-0.023577775806188583,0.032272595912218094,0.026055356487631798,0.0013681123964488506,0.018328679725527763,-0.030308136716485023,-0.01476827822625637,0.08349679410457611,0.022290758788585663,0.04082503914833069,0.039100535213947296,0.1557985544204712,-0.020861230790615082,0.043347422033548355,0.016068171709775925,-0.05090876668691635,-0.02685350738465786,0.02085992880165577,-0.014307371340692043,-0.03200899064540863,-0.013569781556725502,0.029099993407726288,-0.017268868163228035,-0.014761659316718578,0.0280638188123703,0.038863636553287506,0.05610613152384758,0.03575809672474861,0.010569705627858639,-0.08324839174747467,0.06377727538347244,0.0004329041112214327,-0.012286219745874405,0.06400249898433685,-0.05099579691886902,-0.043654900044202805,-0.10685473680496216,0.021274534985423088,0.0761321410536766,-0.017270442098379135,-0.06514012068510056,0.004713690839707851,0.008619409054517746,-0.048509061336517334,0.007478795014321804,-0.002841052133589983,-0.07093366235494614,-0.031524330377578735,-0.03867708146572113,0.0042667025700211525,-0.04282635450363159,-0.05492725223302841,-0.02053096331655979,-0.05335356667637825],"metadata":{"text":"world"}},{"id":"id3","values":[-0.098116934299469,-0.02795644849538803,0.07824746519327164,-0.04175758361816406,-0.018830930814146996,-0.009534829296171665,0.085411936044693,0.059815663844347,0.042017653584480286,0.02490055374801159,0.02330232411623001,-0.11193954199552536,0.04587205499410629,0.01716076210141182,0.021197158843278885,-0.020080525428056717,0.03504439815878868,-0.049796488136053085,-0.12924109399318695,0.006198829505592585,-0.02178637869656086,0.011705446057021618,-0.04289455711841583,-0.023330314084887505,0.03891061246395111,-0.005834572482854128,-0.019717330113053322,-0.011192195117473602,-0.01978045515716076,-0.04301830008625984,-0.05687592551112175,0.02374124340713024,0.07897554337978363,0.01586185395717621,0.029038911685347557,-0.014371359720826149,0.032089248299598694,-0.03394986689090729,-0.05283375829458237,0.006804834119975567,0.03778119757771492,-0.03961816802620888,-0.01944008469581604,-0.041945550590753555,0.05414975434541702,-0.029803156852722168,0.008554715663194656,0.036776140332221985,0.041775643825531006,-0.032393231987953186,-0.030042698606848717,0.0238211490213871,-0.016660582274198532,0.023766864091157913,0.008582521229982376,0.10858285427093506,0.08340559899806976,-0.030444029718637466,0.016521479934453964,0.01264553889632225,0.029936684295535088,0.018482718616724014,-0.17950497567653656,0.04577570781111717,-0.010358537547290325,-0.005288798362016678,-0.014410555362701416,-0.028908101841807365,0.028622832149267197,0.023281099274754524,0.029394133016467094,-0.059396009892225266,0.0001659267581999302,0.0800420269370079,0.02167772687971592,0.0042122043669223785,0.05606093630194664,-0.04434385150671005,0.0560406856238842,-0.07396628707647324,0.007003559730947018,-0.01817217841744423,-0.023676790297031403,0.004432278219610453,0.016211282461881638,-0.02873183973133564,0.009101560339331627,0.05042469501495361,-0.029562173411250114,0.007955361157655716,-0.0471564456820488,-0.016585441306233406,0.0026758573949337006,0.038915716111660004,-0.03409654274582863,-0.0012500293087214231,-0.0148777449503541,0.02169971726834774,-0.08644059300422668,0.19669288396835327,-0.05307783931493759,-0.016833292320370674,0.056915875524282455,-0.037652429193258286,-0.022899281233549118,0.01148293074220419,-0.008427850902080536,-0.0037404836621135473,-0.012163722887635231,-0.0458739772439003,0.003417378757148981,-0.0784747526049614,0.013884477317333221,0.009227614849805832,0.02800411358475685,-0.0067179836332798,0.06990130245685577,0.019610174000263214,0.04777519404888153,-0.1105327159166336,0.0038705954793840647,0.026477618142962456,-0.022097162902355194,-0.009317093528807163,0.07459793984889984,-0.030590392649173737,0.03570156171917915,0.08493243157863617,0.010120169259607792,0.03870660066604614,0.024822751060128212,-0.011480366811156273,-0.07179030776023865,-0.05142201483249664,-0.03482642397284508,0.01285860687494278,0.010425536893308163,-0.04045068472623825,-0.01818637177348137,-0.03429147228598595,-0.08190620690584183,-0.11005223542451859,-0.05462846904993057,-0.08344525843858719,0.020592987537384033,-0.017994532361626625,-0.034951101988554,0.051885247230529785,-0.025005275383591652,-0.03628550469875336,-0.021626977249979973,0.028595417737960815,-0.01179128885269165,-0.058691203594207764,-0.004292374476790428,0.0010730673093348742,0.08631665259599686,0.041539497673511505,0.03376053646206856,0.027275703847408295,-0.01044109370559454,-0.041951049119234085,-0.04359401389956474,0.021228747442364693,-0.05383295565843582,-0.1206590086221695,-0.01612507365643978,0.041727229952812195,0.05032601207494736,0.07047166675329208,0.07846484333276749,0.05720049887895584,-0.04288741946220398,0.058374132961034775,0.0801127552986145,0.02608821727335453,0.020505033433437347,0.037597622722387314,-0.02710501290857792,-0.014234334230422974,-0.013989688828587532,-0.018490182235836983,-0.014303929172456264,-0.0017792921280488372,0.04675784334540367,-0.0028135753236711025,-0.005473391152918339,0.062086403369903564,0.03388194739818573,0.05155352130532265,-0.005177759099751711,0.024072496220469475,0.022852234542369843,0.04093107953667641,-0.020486904308199883,-0.007792067248374224,0.057095717638731,-0.021561820060014725,-0.008791021071374416,0.011945037171244621,0.032574571669101715,0.03095589578151703,0.01935260370373726,0.06737562268972397,0.07358073443174362,0.030680980533361435,0.01037928368896246,-0.005871662870049477,0.015238727442920208,-0.01829073391854763,-0.05632084980607033,-0.031343974173069,0.06257850676774979,0.0017043504631146789,0.00810034479945898,-0.0818357914686203,-0.003166105365380645,0.05688219517469406,-0.0356794074177742,0.03201119601726532,0.012559575960040092,-0.11246059834957123,-0.06667377054691315,-0.2529738247394562,0.06488678604364395,0.02808494120836258,-0.07009375840425491,0.04093533754348755,-0.04279755800962448,0.07836376875638962,0.003181873820722103,0.07227679342031479,0.04158100113272667,0.05909908935427666,-0.06034532189369202,-0.02196693979203701,-0.012342399917542934,0.008940652944147587,0.005558444652706385,0.00914668757468462,-0.020363211631774902,0.06020096689462662,-0.06883019208908081,0.06330811977386475,0.030512051656842232,0.05343664810061455,-0.05647541955113411,0.0011878544464707375,-0.052857182919979095,0.13443705439567566,0.14002078771591187,0.07072262465953827,-0.004088927060365677,0.027927057817578316,-0.03418053314089775,0.03062589280307293,-0.1747187077999115,0.026417763903737068,0.0408916175365448,-0.002118417527526617,-0.07180888205766678,-0.08045259118080139,-0.06717531383037567,-0.07936672121286392,-0.037087444216012955,-0.011681538075208664,-0.062046315521001816,0.026073891669511795,-0.016415923833847046,-0.06076115742325783,-0.020823752507567406,-0.07655180245637894,0.04814252629876137,0.04109019786119461,-0.03814832121133804,0.01839856430888176,0.052271611988544464,-0.05577714368700981,-0.024730313569307327,-0.038598235696554184,-0.00977261085063219,-0.03313122317194939,0.037273652851581573,0.002773455809801817,0.05666914954781532,0.012213366106152534,0.024583393707871437,-0.010415174067020416,0.07813766598701477,-0.00944860465824604,0.0075142099522054195,-0.000009126551958615892,-0.028652194887399673,-0.033455006778240204,-0.010121834464371204,-0.025408878922462463,0.017960229888558388,0.00622603390365839,0.049700990319252014,-0.01801265962421894,-0.015343278646469116,-0.051091648638248444,-0.012527244165539742,0.055670224130153656,0.007105852942913771,0.025434056296944618,0.02290559746325016,0.04034312441945076,0.03033277578651905,0.05054526776075363,-0.05059206858277321,0.0512172095477581,-0.074751116335392,-0.037872783839702606,0.03466639667749405,-0.004700660705566406,-0.11963294446468353,0.015173553489148617,-0.048478029668331146,-0.2532747983932495,0.033071402460336685,0.004590248689055443,0.028406044468283653,-0.04342702031135559,0.05964886024594307,0.009288460947573185,0.04483404383063316,-0.0664234384894371,0.010627828538417816,0.03343113884329796,0.1032976359128952,0.03421352803707123,0.062116947025060654,-0.032352279871702194,0.005032926797866821,0.03162776306271553,-0.06511731445789337,0.010414017364382744,-0.007506169844418764,-0.018110152333974838,0.02069699764251709,0.1535530835390091,-0.04722286015748978,0.09449227899312973,0.03456588461995125,-0.039541929960250854,0.047656409442424774,0.008451529778540134,-0.044518932700157166,0.0014796407194808125,0.018370402976870537,0.05881310999393463,-0.01232369989156723,0.024878282099962234,0.000804323295596987,-0.05853509157896042,-0.024341275915503502,0.03977168723940849,0.008637936785817146,-0.061153750866651535,-0.009824348613619804,-0.04515392705798149,0.008866043761372566,0.10618521273136139,-0.053562529385089874,-0.04116111993789673,0.01201598346233368,-0.025102749466896057,-0.0020543772261589766,0.02066051959991455,0.0018442511791363358,0.024269405752420425,0.051136314868927,0.009807640686631203,-0.03008287586271763,0.022839169949293137,-0.03256910666823387,-0.014599412679672241,-0.041693687438964844,-0.028076188638806343,0.01464852038770914,0.0656081810593605,0.04409999027848244,0.005707649979740381],"metadata":{"text":"hi"}}]

では最後にコードに、投入された質問文をベクトル化して投入する機能を追記します。

// @ts-nocheck

import type {
	VectorizeIndex,
	Fetcher,
	Request,
} from "@cloudflare/workers-types";

import {
	CloudflareVectorizeStore,
	CloudflareWorkersAIEmbeddings,
} from "@langchain/cloudflare";

export interface Env {
	VECTORIZE_INDEX: VectorizeIndex;
	AI: Fetcher;
}

export default {
	async fetch(request: Request, env: Env) {
		const { pathname } = new URL(request.url);
		const embeddings = new CloudflareWorkersAIEmbeddings({
			binding: env.AI,
			model: "@cf/baai/bge-small-en-v1.5",
		});
		const store = new CloudflareVectorizeStore(embeddings, {
			index: env.VECTORIZE_INDEX,
		});
		if (pathname === "/") {
			let ids = ["id1", "id2", "id3"];
			const vectors = await env.VECTORIZE_INDEX.getByIds(ids);
			return Response.json(vectors);
		} else if (pathname === "/load") {
			// Upsertion by id is supported
			await store.addDocuments(
				[
					{
						pageContent: "hello",
						metadata: {},
					},
					{
						pageContent: "world",
						metadata: {},
					},
					{
						pageContent: "hi",
						metadata: {},
					},
				],
				{ ids: ["id1", "id2", "id3"] }
			);

			return Response.json({ success: true });
		} else if (pathname === "/clear") {
			await store.delete({ ids: ["id1", "id2", "id3"] });
			return Response.json({ success: true });
		} else if (pathname.includes("question")) {
			const params = new URLSearchParams(pathname.search);

			const questionParam = pathname.split('/').pop().split('=');
			const questionValue = decodeURIComponent(questionParam[1]);
			const results = await store.similaritySearch(questionValue, 5);

			const id = Math.floor(Date.now() / 1000);
			await store.addDocuments(
				[
					{
						pageContent: questionValue,
						metadata: {},
					},
				],
				{ ids: [id] }
			);
			return Response.json(results);
		}
		return Response.json({ error: "Not Found" }, { status: 404 });
	},
};

追記部分は以下です。

const id = Math.floor(Date.now() / 1000);
			await store.addDocuments(
				[
					{
						pageContent: questionValue,
						metadata: {},
					},
				],
				{ ids: [id] }
			);

こうすることによって投入された質問を次々に記憶していくことになります。試しに以下を2回実行すると2回目の検索結果はこうなります。
https://langchainvectorize.harunobukameda.workers.dev/question=okay

https
[{"pageContent":"okay","metadata":{}},{"pageContent":"hi","metadata":{}},{"pageContent":"hello","metadata":{}},{"pageContent":"world","metadata":{}}]

いかがでしょうか。なんとなくイメージはつかめましたでしょうか?

Discussion