~/tools / 埋め込みと検索(RAG) / Embeddings to pgvector INSERT

Embeddings to pgvector INSERT — 埋め込みを pgvector の INSERT 文にする

embeddingにしたテキストと、Ollamaの /api/embed(またはOpenAI互換の /v1/embeddings)のレスポンスから、PostgreSQLのpgvectorテーブル向けの INSERT 文を作ります。各テキストをベクトルと順番に対応づけ、引用符をエスケープし、実行する前に件数と次元数が合っているかを確認します。データがブラウザの外に出ることはありません。

例では、読みやすいように、作り物の4次元で長さ1のベクトルを使っています。実際のembeddingは数百から数千次元です。

4 次元の 3 行。テキストは /api/embed のリクエストボディ、ベクトルは Ollama /api/embed のレスポンス として読みました。

INSERT 文

psqlなどのクライアントで実行します。行は1つのトランザクションで挿入されます。

BEGIN;

INSERT INTO documents (content, embedding) VALUES
  ('Embeddings turn text into numeric vectors.', '[0.620186,0.410123,0.550165,0.380114]'),
  ('pgvector stores vectors in PostgreSQL, next to the rest of your data.', '[0.578815,0.469039,0.518937,0.419142]'),
  ('Ollama''s /api/embed returns one vector per input, in the same order.', '[0.119982,0.809879,-0.329951,0.46993]');

COMMIT;

ベクトルの形式はpgvectorのREADMEによるもので、2026-11-04にpgvector 0.8.7で確認しました。 pgvector README

すべてブラウザ上で処理します。このツールはSQLを書くだけで、どこにも接続しません。

文書のチャンクをOllamaでembeddingにしたら、そのベクトルを、元のテキストと一緒にデータベースへ入れる必要があります。Ollamaの /api/embed は、入力の文字列1つにつきベクトルを1つ、入力と同じ順序で返すので、1つ目のテキストが1つ目のベクトルに対応します。このツールは、その対応づけをして、SQLを書きます。テキストは、/api/embed に送ったJSONのボディ(このサイトのRAG Text Chunkerが作るもの)、文字列のJSON配列、または1行に1つの形で貼り付け、レスポンスも貼り付けます。ツールは、Ollamaのレスポンス({"embeddings": [[…], …]})と、OpenAI互換のレスポンス({"data": [{"embedding": […]}]}、index順に並べ直します)を読み込みます。ベクトルは '[0.1,-0.2,0.3]' のようなpgvectorのテキスト形式で書き、各テキストはSQLの文字列定数として書きます。PostgreSQLのドキュメントによると、文字列の中の単一引用符は単一引用符を2つ重ねて書きます。バックスラッシュは、PostgreSQL 9.1以降 standard_conforming_strings がデフォルトでオンなので、そのまま残します。何かを書く前に、INSERT が失敗したり行の対応がずれたりする原因を確認します。テキストとベクトルの数が違う、ベクトルの次元数が揃っていない、次元数が列の vector(n) と違う、有限の数でない値がある(pgvectorは NaN や Infinity を受け付けません)、base64のembedding、PostgreSQLがtextに保存できない NUL 文字です。文は BEGIN と COMMIT で囲み、INSERT 1つにつき100行にまとめます。出力は、Ollamaの実際のレスポンスを使い、PostgreSQL 16上のpgvector 0.8.7で実行しました。引用符、バックスラッシュ、改行、絵文字を含むテキストも、変わらずに戻ってきました。

このツールの計算部分は、オープンソース(MIT ライセンス)で公開しています。 github.com/seigo5555/toolkitbox-lib/src/pgvector-insert.ts

こんな時に使う

  • マニュアルやFAQのチャンクと、Ollamaで作ったそのembeddingを、RAG検索のためにPostgreSQLへ読み込む
  • アプリケーションの読み込みコードを書く前に、実際の数行で検索を試す
  • 挿入が失敗する原因を調べる: 次元数の違うベクトルや、ベクトルよりテキストが多いなど

使い方

  1. embeddingにしたテキストを貼り付けます。RAG Text ChunkerのJSONボディ、文字列のJSON配列、または1行に1つのテキストです。
  2. 同じテキストを /api/embed に送り、JSONのレスポンス全体を貼り付けます。テーブル名と列名を入力し、必要なら vector(n) 列の次元数も入力します。
  3. SQLをコピーして、psqlなどのクライアントで実行します。このサイトのpgvector SQL Builderで、対応するテーブルと検索クエリを書けます。

FAQ

どのベクトルがどのテキストのものか、どうやって分かりますか?

順序で分かります。Ollamaの /api/embed は入力配列と同じ順序でembeddingを返すので、ツールは1つ目のテキストを1つ目のベクトルに、2つ目を2つ目に、というように対応づけます。件数が違うときは、推測せずにツールが止まります。

チャンクに改行があります。1行に1つの形で貼り付けられますか?

いいえ。改行があるとチャンクが2つのテキストに分かれてしまいます。代わりに、/api/embed に送ったJSONのボディか、文字列のJSON配列を貼り付けてください。各文字列の中の改行は、SQLの中でも保たれます。

引用符を含むテキストを貼り付けても安全ですか?

ツールは、すべての単一引用符を2つ重ねます。PostgreSQLのドキュメントが、文字列定数の中の引用符の書き方として示している方法です。バックスラッシュはそのままにします。これは、デフォルトの standard_conforming_strings = on なら正しい扱いです。サーバーでこれをオフにしている場合は、出力を実行しないでください。アプリケーションのコードでは、SQL文字列を組み立てる代わりに、データベースドライバーのパラメーターを使ってください。

次元数が列と合わないとどうなりますか?

pgvectorはその行を拒否し、"expected 384 dimensions, not 768" のようなエラーを返します。ツールに列の次元数を入力すると、SQLを実行する前にこれを検出できます。次元数が違うのは、たいてい別のモデルを使った、または次元数の設定が違うということです。

一度に何行まで変換できますか?

テキストとベクトルを1,000件までです。それより大きな読み込みには、pgvectorのREADMEに COPY を使った一括読み込みの例があります。

データはどこかに送信されますか?

いいえ。変換はブラウザ上で行われます。ツールがOllamaやデータベースに接続することはありません。

関連する記事

関連ツール