Closed3

Cloudflare Vectorize を使ってみる

Mamoru AmanoMamoru Amano

インデックスの作成

dimensionsは利用するEmbedding APIによって変わる。
代表的なものはドキュメントに記載してあるのでそちらを参照する。 https://developers.cloudflare.com/vectorize/learning/create-indexes/#dimensions

今回はOpenAIを利用するので、1536を指定する。

pnpm exec wrangler vectorize create ingredients --metric=cosine --dimensions=1536

しかし vectorize.not_entitled [code: 1005] とのエラーと共に作成に失敗した。

WorkersをPaidプランに変更する。

現状だと Vactorize は Workers を有料プランに変更しないといけないので変更する。
https://github.com/cloudflare/workers-sdk/issues/4042

再度インデックスの作成

pnpm exec wrangler vectorize create ingredients --metric=cosine --dimensions=1536

成功した。ここで指定する metric と dimentions の値は後から変更できないので注意。

Mamoru AmanoMamoru Amano

Workerのコードを書く。

概ね https://developers.cloudflare.com/vectorize/get-started/intro/#1-create-a-worker を参考にしつつも、今回はR2に保存したjsonを使ってInsertをしたかったので、それができるように修正した。

R2を使うにあたって、wrangler.toml に以下を追記している。

account_id = "{Account ID}"
workers_dev = true

[[r2_buckets]]
binding = 'BUCKET'
bucket_name = '{R2 Bucket Name}'

コードは以下の通り。

  • /insertにアクセスすると Vectorize へのインサートを行う。
  • /q=でクエリ実行。
import OpenAI from 'openai';

export interface Env {
	VECTORIZE_INDEX: VectorizeIndex;
	OPENAI_API_KEY: string;
	BUCKET: R2Bucket;
}

export default {
	async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
		const path = new URL(request.url).pathname;

		if (path.startsWith('/insert')) {
			const json = await env.BUCKET.get('data.json');
			const data = (await json?.json()) as any[];

			const vectors = data.map((d: any) => {
				return {
					id: String(d.id), // Stringじゃなきゃいけない
					values: d.embedding,
					metadata: {
						name: d.name,
					},
				};
			});

			const inserted = await env.VECTORIZE_INDEX.insert(vectors);

			return Response.json(inserted);
		}

		const openai = new OpenAI({ apiKey: env.OPENAI_API_KEY });
		const query = new URL(request.url).searchParams.get('q');

		if (!query) {
			return Response.json({ error: 'Missing query parameter' }, { status: 400 });
		}

		const embeddingsResult = await openai.embeddings.create({
			model: 'text-embedding-ada-002',
			input: query,
		});

		const vector = embeddingsResult.data[0].embedding;

		const matches = await env.VECTORIZE_INDEX.query(vector, { topK: 3, returnVectors: true });

		return Response.json({
			matches: matches,
		});
	},
};

そしてデプロイ。

pnpm exec wrangler deploy 
このスクラップは2023/10/03にクローズされました