@h-ai/vecdb 0.1.0-alpha.66 → 0.1.0-alpha.68
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +54 -13
- package/README.ja.md +55 -14
- package/README.md +55 -14
- package/dist/index.d.ts +212 -132
- package/dist/index.js +434 -263
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/README.en.md
CHANGED
|
@@ -4,22 +4,27 @@
|
|
|
4
4
|
|
|
5
5
|
[Framework home](../../README.en.md) · Related modules: [@h-ai/core](../core/README.en.md)
|
|
6
6
|
|
|
7
|
+
## Introduction
|
|
8
|
+
|
|
7
9
|
A vector database module with a unified `vecdb` object for LanceDB, pgvector, Qdrant, and Chroma.
|
|
8
10
|
|
|
9
|
-
##
|
|
11
|
+
## Core features
|
|
12
|
+
|
|
13
|
+
- Create collections with a defined vector dimension.
|
|
14
|
+
- Store document vectors, search by similarity and filter metadata.
|
|
15
|
+
- Use LanceDB, pgvector, Qdrant or Chroma; backend setup is described below.
|
|
10
16
|
|
|
11
|
-
|
|
12
|
-
- pgvector (PostgreSQL + pgvector extension)
|
|
13
|
-
- Qdrant (high-performance vector search engine; server 1.10.0+ with the Query API)
|
|
14
|
-
- Chroma (automatically start a local service in embedded mode, or connect to an existing service)
|
|
17
|
+
## Getting started
|
|
15
18
|
|
|
16
|
-
|
|
19
|
+
### Quick start
|
|
17
20
|
|
|
18
21
|
```ts
|
|
19
22
|
import { HaiVecdbError, vecdb } from '@h-ai/vecdb'
|
|
20
23
|
|
|
21
24
|
// 初始化(LanceDB)
|
|
22
|
-
await vecdb.init({ type: 'lancedb', path: './data/vecdb' })
|
|
25
|
+
const initialized = await vecdb.init({ type: 'lancedb', path: './data/vecdb' })
|
|
26
|
+
if (!initialized.success)
|
|
27
|
+
throw new Error(initialized.error.message)
|
|
23
28
|
|
|
24
29
|
// 创建集合
|
|
25
30
|
await vecdb.collection.create('docs', { dimension: 1536 })
|
|
@@ -44,7 +49,7 @@ if (!closeResult.success) {
|
|
|
44
49
|
}
|
|
45
50
|
```
|
|
46
51
|
|
|
47
|
-
|
|
52
|
+
### Configuration
|
|
48
53
|
|
|
49
54
|
```ts
|
|
50
55
|
// LanceDB(默认,嵌入式本地存储)
|
|
@@ -76,10 +81,34 @@ await vecdb.init({ type: 'chroma', url: 'http://localhost:8000' })
|
|
|
76
81
|
```
|
|
77
82
|
|
|
78
83
|
> On Node, Chroma provides only an HTTP client, with no in-process embedded database. In embedded mode, `vecdb.init`
|
|
79
|
-
> starts a local service with `serverCommand` (default: `chroma
|
|
80
|
-
>
|
|
84
|
+
> starts a local service with `serverCommand` (default: `chroma`), and `vecdb.close` stops the process.
|
|
85
|
+
> The optional npm package `chromadb` supplies the HTTP client; install the server CLI separately. An unavailable command makes `init` return `CONNECTION_FAILED`.
|
|
86
|
+
|
|
87
|
+
Chroma `url` accepts only an HTTP(S) root endpoint, such as `https://chroma.example.com:8443/`, and takes precedence over `host/port`. URL credentials, path prefixes, query strings and fragments are rejected. Without `url`, `host/port` uses HTTP. Configuration uses the `host/port/ssl/headers` arguments of `chromadb 3.5.0`; see the [official TypeScript client](https://docs.trychroma.com/reference/typescript/client).
|
|
88
|
+
|
|
89
|
+
For Chroma, this module sends the optional `apiKey` as `Authorization: Bearer <apiKey>` to self-hosted services or gateways implementing that protocol. Use HTTPS for remote credentials. An empty string omits credentials; nonempty tokens cannot contain whitespace, control characters or non-ASCII characters. This interface uses the default tenant/database and does not configure Chroma Cloud. Initialization checks the collection-count data endpoint after heartbeat. Authentication or permission failures return `CONNECTION_FAILED` without publishing a connected state; callers must check `success`.
|
|
90
|
+
|
|
91
|
+
Direct initialization has a total deadline of 5 seconds; local server startup uses `startupTimeout`. Expiry aborts candidate HTTP requests. Successful initialization clears the timer, so this deadline does not limit subsequent business requests.
|
|
92
|
+
|
|
93
|
+
Qdrant uses the actual types and Query API of `@qdrant/js-client-rest 1.18.0`. It supports an unnamed vector field with cosine/euclidean/dot metrics. Info, writes and searches on external named-vector or Manhattan collections return `CONFIG_ERROR`, without guessing zero dimensions or a default cosine metric. Only HTTP 404 means a collection is absent. Provider URL logs use core's shared sanitizer.
|
|
94
|
+
|
|
95
|
+
Chroma metadata/filter values follow native `chromadb 3.5.0` validation. Invalid values return operation errors without dropping filters or issuing unfiltered queries. Document content may be omitted and search still returns `undefined`; internal writes use the SDK's string field. Check each backend's null, complex-metadata and filter semantics separately.
|
|
96
|
+
|
|
97
|
+
LanceDB stores dimensions in Arrow's fixed-size vector field and the collection metric in the same schema's metadata, including empty collections. The metric in `collection.create` takes precedence; the connection metric only supplies a default for new collections. Restarting or changing that default does not alter existing collections. Operations read persisted schemas and check other connections' commits. Missing or invalid definitions return `CONFIG_ERROR`, without dummy-vector probes or guessed metrics. Rebuild legacy/external tables that lack this definition; no compatibility inference is provided.
|
|
98
|
+
|
|
99
|
+
LanceDB is an embedded local-file backend. Processes share data only when they access the same persistent directory on a filesystem supporting LanceDB's concurrent commits. Identically named local paths on separate nodes do not share data. Prefer pgvector, Qdrant, or a Chroma server for distributed services. AI Knowledge requires persistent reldb and vecdb stores pointing to the same business dataset; changing embedding dimensions requires a matching rebuilt collection.
|
|
100
|
+
|
|
101
|
+
Search uses the persisted collection metric, mapping `euclidean` to LanceDB's `l2`. Scores follow the public 0–1, higher-is-more-similar contract: cosine uses `clamp(1 - distance / 2, 0, 1)`, euclidean uses `1 / (1 + squaredL2)`, and dot uses `sigmoid(dotProduct)` to preserve ranking, not to estimate probabilities. `minScore` filters converted scores; thresholds are not universally calibrated across metrics or backends.
|
|
81
102
|
|
|
82
|
-
|
|
103
|
+
Atomic LanceDB writes are verified against `@lancedb/lancedb 0.40.0 / Lance 13`. New tables declare a non-null id primary key in their initial Arrow schema. Both insert and upsert use native merge on id for strict key conflict detection. Sources: [Lance 13 table format](https://github.com/lance-format/lance/blob/v13.0.0/docs/src/format/table/index.md#unenforced-primary-key), [Lance 13 transaction](https://github.com/lance-format/lance/blob/v13.0.0/protos/transaction.proto), [Node binding 0.40.0](https://github.com/lancedb/lancedb/blob/v0.40.0/nodejs/lancedb/table.ts).
|
|
104
|
+
|
|
105
|
+
LanceDB `insert` preserves existing IDs; `upsert` inserts or replaces complete rows. Duplicate IDs within a batch, missing merge support, or missing persisted primary keys return `CONFIG_ERROR` before writing. Rebuild old tables; no automatic migration or cleanup occurs. Each merge commits atomically, with concurrent winners determined by commit order. Multiple merges and reldb/vecdb operations do not share a transaction. No delete/add fallback is used. Reconcile unknown outcomes by ID. External native add calls bypass these safeguards.
|
|
106
|
+
|
|
107
|
+
LanceDB stores `metadata` in a native JSON field, accepts nested JSON, and restores search metadata as objects. Explicit Arrow JSON input schemas encode both insert and upsert as JSONB. Writes or filters on legacy Utf8 metadata tables return `CONFIG_ERROR`; rebuild them without automatic migration.
|
|
108
|
+
|
|
109
|
+
LanceDB `filter` supports AND equality on literal top-level keys, for example `{ tenant: 'acme', page: 1, active: true, removedAt: null }`. Values may be strings, finite numbers, booleans, or null. Types remain distinct: `1` differs from `'1'`, and `true` from `'true'`. Null matches explicit JSON null, never a missing key. Dots/brackets are literal key characters; quotes, backslashes, `%`, and `_` have no SQL or wildcard meaning. An empty object adds no restriction. Objects, arrays, undefined, and nonfinite numbers return `CONFIG_ERROR`, never an unfiltered query. Filtering precedes vector topK selection; minScore then filters scores. Other providers retain native restrictions and do not promise identical null, complex-value, or path semantics. Check capabilities when switching backends. Sources: [Lance 13 JSON UDF](https://github.com/lance-format/lance/blob/v13.0.0/rust/lance-datafusion/src/udf/json.rs), [Node 0.40.0 JSON field](https://github.com/lancedb/lancedb/blob/v0.40.0/nodejs/lancedb/arrow.ts).
|
|
110
|
+
|
|
111
|
+
#### Operation logging
|
|
83
112
|
|
|
84
113
|
Enable operation logging with `operationLog` in the vector database configuration. Logs are emitted before collection/vector operations reach the real provider, without a shared wrapper in `vecdb-main.ts`.
|
|
85
114
|
|
|
@@ -111,7 +140,9 @@ await vecdb.init({
|
|
|
111
140
|
|
|
112
141
|
> Behavior: empty batch `insert/upsert/delete` calls are no-ops. Writes and searches validate vector dimensions, returning `HaiVecdbError.DIMENSION_MISMATCH` on a mismatch; missing optional drivers return `HaiVecdbError.DRIVER_NOT_FOUND`.
|
|
113
142
|
|
|
114
|
-
|
|
143
|
+
Qdrant `insert/upsert/delete` use `wait: true`, so success means the server applied that operation. `vector.count` requests an exact count rather than approximate collection statistics. Multiple operations do not form a transaction.
|
|
144
|
+
|
|
145
|
+
### Error handling
|
|
115
146
|
|
|
116
147
|
All operations return `HaiResult<T>`; check `result.success` for success or failure.
|
|
117
148
|
|
|
@@ -132,7 +163,15 @@ if (!result.success) {
|
|
|
132
163
|
}
|
|
133
164
|
```
|
|
134
165
|
|
|
135
|
-
##
|
|
166
|
+
## Production shared state
|
|
167
|
+
|
|
168
|
+
Production uses Qdrant, pgvector or remote Chroma. LanceDB and embedded Chroma are for development/explicit tests. Initialization checks apply when NODE_ENV or HAI_CORE_ENV is production; only explicit HAI_E2E=1/HAI_E2E_MOCK=1 tests are exempt. [State, concurrency and recovery (Chinese)](../../.agents/instructions/distributed-state.md)。
|
|
169
|
+
|
|
170
|
+
## Closing and recovery
|
|
171
|
+
|
|
172
|
+
close immediately stops current operations, including previously captured operation references. Failed candidates and resources that failed to close retain cleanup ownership without serving requests. Concurrent close calls coalesce; an in-flight init settles ownership before close proceeds. error.ext.cleanupPending requires retrying close on the same module. init cannot replace a resource until cleanup succeeds. Embedded Chroma waits for the actual spawn event and direct child exit: 1.5 seconds after normal termination it sends a forced signal, then waits another 1.5 seconds. Unconfirmed exit returns failure and retains the handle. Direct-child verification does not establish process-tree termination or live Chroma CLI readiness.
|
|
173
|
+
|
|
174
|
+
## Development and testing
|
|
136
175
|
|
|
137
176
|
```bash
|
|
138
177
|
pnpm --filter @h-ai/vecdb test
|
|
@@ -140,6 +179,8 @@ pnpm --filter @h-ai/vecdb test
|
|
|
140
179
|
|
|
141
180
|
> pgvector / Qdrant tests require Docker.
|
|
142
181
|
|
|
182
|
+
Source JSDoc follows the [shared conventions](../../.agents/instructions/module-conventions.md#jsdoc-与示例验证): public examples use published entry points, and internal examples are checked in their module scope. After building, run `pnpm check:jsdoc --package vecdb`; compiling examples does not replace backend behavior tests.
|
|
183
|
+
|
|
143
184
|
## License
|
|
144
185
|
|
|
145
186
|
Apache-2.0
|
package/README.ja.md
CHANGED
|
@@ -4,22 +4,27 @@
|
|
|
4
4
|
|
|
5
5
|
[フレームワークのホーム](../../README.ja.md) · 関連モジュール:[@h-ai/core](../core/README.ja.md)
|
|
6
6
|
|
|
7
|
+
## 概要
|
|
8
|
+
|
|
7
9
|
共通の `vecdb` オブジェクトで LanceDB、pgvector、Qdrant、Chroma を操作するベクトルデータベースモジュールです。
|
|
8
10
|
|
|
9
|
-
##
|
|
11
|
+
## 主な機能
|
|
12
|
+
|
|
13
|
+
- ベクトル次元を指定したコレクションの作成・管理。
|
|
14
|
+
- 文書ベクトルの保存、類似検索、メタデータ条件の絞り込み。
|
|
15
|
+
- LanceDB・pgvector・Qdrant・Chroma に対応。準備方法は下記設定を参照。
|
|
10
16
|
|
|
11
|
-
|
|
12
|
-
- pgvector(PostgreSQL + pgvector 拡張)
|
|
13
|
-
- Qdrant(高性能ベクトル検索エンジン。Query API を使用するため、サーバー 1.10.0 以降が必要)
|
|
14
|
-
- Chroma(組み込みモードでローカルサービスを自動起動、または既存サービスへ直接接続)
|
|
17
|
+
## 使い始める
|
|
15
18
|
|
|
16
|
-
|
|
19
|
+
### クイックスタート
|
|
17
20
|
|
|
18
21
|
```ts
|
|
19
22
|
import { HaiVecdbError, vecdb } from '@h-ai/vecdb'
|
|
20
23
|
|
|
21
24
|
// 初始化(LanceDB)
|
|
22
|
-
await vecdb.init({ type: 'lancedb', path: './data/vecdb' })
|
|
25
|
+
const initialized = await vecdb.init({ type: 'lancedb', path: './data/vecdb' })
|
|
26
|
+
if (!initialized.success)
|
|
27
|
+
throw new Error(initialized.error.message)
|
|
23
28
|
|
|
24
29
|
// 创建集合
|
|
25
30
|
await vecdb.collection.create('docs', { dimension: 1536 })
|
|
@@ -44,7 +49,7 @@ if (!closeResult.success) {
|
|
|
44
49
|
}
|
|
45
50
|
```
|
|
46
51
|
|
|
47
|
-
|
|
52
|
+
### 設定
|
|
48
53
|
|
|
49
54
|
```ts
|
|
50
55
|
// LanceDB(默认,嵌入式本地存储)
|
|
@@ -76,10 +81,34 @@ await vecdb.init({ type: 'chroma', url: 'http://localhost:8000' })
|
|
|
76
81
|
```
|
|
77
82
|
|
|
78
83
|
> Node 版の Chroma は HTTP クライアントのみで、プロセス内の組み込み DB はありません。組み込みモードでは `vecdb.init` が
|
|
79
|
-
> `serverCommand`(既定は `
|
|
80
|
-
>
|
|
84
|
+
> `serverCommand`(既定は `chroma`)でローカルサービスを起動し、`vecdb.close` がそのプロセスを停止します。
|
|
85
|
+
> npm の任意依存 `chromadb` は HTTP クライアントです。サーバー CLI は別途インストールしてください。コマンドが利用できない場合、`init` は `CONNECTION_FAILED` を返します。
|
|
86
|
+
|
|
87
|
+
Chroma の `url` は `https://chroma.example.com:8443/` など HTTP(S) のルートエンドポイントのみを受け付け、`host/port` より優先されます。URL の認証情報、パス接頭辞、query、fragment は拒否します。`url` がない場合は `host/port` の HTTP 接続です。`chromadb 3.5.0` の `host/port/ssl/headers` を使用します。[公式 TypeScript クライアント](https://docs.trychroma.com/reference/typescript/client)を参照してください。
|
|
88
|
+
|
|
89
|
+
Chroma の任意の `apiKey` は、このモジュールの規約として `Authorization: Bearer <apiKey>` で送信します。同じ認証方式を使うセルフホストサービスやゲートウェイ向けです。リモートの認証情報には HTTPS を使用してください。空文字列は未設定を表し、非空値では空白、制御文字、非 ASCII 文字を拒否します。既定の tenant/database を使用し、Chroma Cloud のクライアントやテナント設定は提供しません。初期化は heartbeat の後にコレクション件数のデータエンドポイントも確認します。認証・権限エラーは `CONNECTION_FAILED` を返し、接続済み状態を公開しません。呼び出し側は `success` を確認してください。
|
|
90
|
+
|
|
91
|
+
直接接続の初期化全体の期限は 5 秒です。ローカルサービス起動では `startupTimeout` を使用します。期限を超えると候補 HTTP リクエストを中止します。成功時はタイマーを解除するため、この期限は以後の業務リクエストには適用されません。
|
|
92
|
+
|
|
93
|
+
Qdrant は `@qdrant/js-client-rest 1.18.0` の実際の型と Query API を使用し、名前のない単一ベクトルフィールドと cosine/euclidean/dot に対応します。外部の named-vector・Manhattan 集合の info・書き込み・検索は `CONFIG_ERROR` を返し、ゼロ次元や既定 cosine と推測しません。集合が存在しないと判断するのは HTTP 404 のみです。Provider の URL ログは core の共通マスク処理を使います。
|
|
94
|
+
|
|
95
|
+
Chroma の metadata/filter は `chromadb 3.5.0` の検証に従います。不正値は操作エラーとなり、フィルターの削除や無条件検索にはフォールバックしません。content は省略でき、検索結果は `undefined` のままです。内部書き込みでは SDK の文字列フィールドに合わせます。null・複雑なメタデータ・フィルターの意味はバックエンドごとに確認してください。
|
|
96
|
+
|
|
97
|
+
LanceDB は次元数を Arrow の固定長 vector フィールドに、集合の metric を同じ schema の metadata に永続化し、空の集合も復元できます。`collection.create` の metric を優先し、接続設定は新規集合の既定値としてのみ使用します。再起動や既定値の変更で既存の集合は変わりません。各操作は永続 schema と他の接続のコミットを確認します。定義が欠落・不正な場合は `CONFIG_ERROR` を返し、仮のベクトルによる推測はしません。定義のない旧形式・外部テーブルは再作成してください。互換推定は提供しません。
|
|
98
|
+
|
|
99
|
+
LanceDB はローカルファイルを使う組み込みバックエンドです。同じ永続ディレクトリと LanceDB の並行コミットを支えるファイルシステムを使うプロセス間のみでデータを共有します。別ノードの同名ローカルパスは共有されません。分散サービスには pgvector、Qdrant、Chroma サーバーを推奨します。AI Knowledge は reldb と vecdb の両方を永続化し、同じ業務データセットに接続してください。embedding 次元を変更する場合は集合の再作成が必要です。
|
|
100
|
+
|
|
101
|
+
検索は集合の metric を使い、`euclidean` を LanceDB の `l2` に対応させます。score は公開 API の 0–1、高いほど類似する契約に従い、cosine は `clamp(1 - distance / 2, 0, 1)`、euclidean は `1 / (1 + squaredL2)`、dot は順位を保つ `sigmoid(dotProduct)` を使います(確率ではありません)。`minScore` は変換後に適用し、異なる metric・バックエンド間で閾値が共通に校正されているとは扱いません。
|
|
81
102
|
|
|
82
|
-
|
|
103
|
+
原子書き込みの検証対象は `@lancedb/lancedb 0.40.0 / Lance 13` です。新規集合は初期 Arrow schema で id を非 null 主キーにし、insert/upsert は id を使う原生 merge の厳密なキー競合検出を使用します。根拠:[Lance 13 table format](https://github.com/lance-format/lance/blob/v13.0.0/docs/src/format/table/index.md#unenforced-primary-key)、[Lance 13 transaction](https://github.com/lance-format/lance/blob/v13.0.0/protos/transaction.proto)、[Node binding 0.40.0](https://github.com/lancedb/lancedb/blob/v0.40.0/nodejs/lancedb/table.ts)。
|
|
104
|
+
|
|
105
|
+
LanceDB の `insert` は既存 ID を上書きせず、`upsert` は追加または行全体を置換します。バッチ内の重複 ID、merge 能力・永続主キーの欠落は書き込み前に `CONFIG_ERROR` を返します。旧形式の集合は再作成が必要で、自動移行や削除はしません。原子性は各 merge に限られ、並行処理の勝者はコミット順で決まります。複数 merge や reldb/vecdb 間の共通トランザクションはありません。delete/add への切り替えはなく、不明な結果は ID で照合します。外部の原生 add はこの保護を迂回します。
|
|
106
|
+
|
|
107
|
+
LanceDB の `metadata` はネイティブ JSON フィールドです。入れ子の JSON を保存でき、検索結果ではオブジェクトに復元します。insert/upsert とも明示的な Arrow JSON schema で JSONB に変換します。旧 Utf8 metadata テーブルへの書き込み・フィルターは `CONFIG_ERROR` を返し、再作成が必要です。自動移行はしません。
|
|
108
|
+
|
|
109
|
+
LanceDB の `filter` は最上位のリテラルキーを AND で完全一致させます。例:`{ tenant: 'acme', page: 1, active: true, removedAt: null }`。値は文字列・有限数値・真偽値・null のみで、`1` と `'1'`、`true` と `'true'` を区別します。null は明示的な JSON null のみに一致し、欠落キーには一致しません。点や括弧はパスではなくキー文字です。引用符・バックスラッシュ・`%`・`_` に SQL/ワイルドカードの意味はありません。空オブジェクトは制限なしです。オブジェクト・配列・undefined・非有限数値は `CONFIG_ERROR` を返し、無条件検索に変更しません。フィルターはベクトル topK の前、minScore はその後に適用します。他の Provider の null・複合値・パスの意味は同一とは保証しません。バックエンド変更時は固有の制約を確認してください。根拠:[Lance 13 JSON UDF](https://github.com/lance-format/lance/blob/v13.0.0/rust/lance-datafusion/src/udf/json.rs)、[Node 0.40.0 JSON field](https://github.com/lancedb/lancedb/blob/v0.40.0/nodejs/lancedb/arrow.ts)。
|
|
110
|
+
|
|
111
|
+
#### 操作ログ
|
|
83
112
|
|
|
84
113
|
ベクトルデータベース設定の `operationLog` で操作ログを有効にできます。ログはコレクション・ベクトル操作が実際の Provider に渡る前に出力され、`vecdb-main.ts` で一括ラップはしません。
|
|
85
114
|
|
|
@@ -111,7 +140,9 @@ await vecdb.init({
|
|
|
111
140
|
|
|
112
141
|
> 動作:空の一括 `insert/upsert/delete` は何もしません。書き込み・検索時にはベクトル次元を検証し、不一致なら `HaiVecdbError.DIMENSION_MISMATCH`、任意ドライバーの不足なら `HaiVecdbError.DRIVER_NOT_FOUND` を返します。
|
|
113
142
|
|
|
114
|
-
|
|
143
|
+
Qdrant の `insert/upsert/delete` は `wait: true` を使用し、成功はサーバーでの適用完了を表します。`vector.count` は集合情報の近似値ではなく正確な件数を取得します。複数操作をまとめたトランザクションではありません。
|
|
144
|
+
|
|
145
|
+
### エラー処理
|
|
115
146
|
|
|
116
147
|
すべての操作は `HaiResult<T>` を返し、`result.success` で成功・失敗を判定します。
|
|
117
148
|
|
|
@@ -132,7 +163,15 @@ if (!result.success) {
|
|
|
132
163
|
}
|
|
133
164
|
```
|
|
134
165
|
|
|
135
|
-
##
|
|
166
|
+
## 本番の共有状態
|
|
167
|
+
|
|
168
|
+
本番は Qdrant・pgvector・リモート Chroma を使います。LanceDB と組み込み Chroma は開発・明示的テスト用です。 NODE_ENV または HAI_CORE_ENV が production の場合、初期化成功前に検証します。明示的な HAI_E2E=1/HAI_E2E_MOCK=1 テストのみ除外します。 [状態・並行制御・復旧範囲(中国語)](../../.agents/instructions/distributed-state.md)。
|
|
169
|
+
|
|
170
|
+
## 終了と失敗からの回復
|
|
171
|
+
|
|
172
|
+
close は取得済みの操作参照も含めて業務処理を停止します。初期化や終了に失敗したリソースは後処理の所有権だけを保持します。同時 close は統合し、実行中の init の所有権確定を待ちます。error.ext.cleanupPending があれば同じモジュールの close を再試行し、後処理が成功するまで init は代替リソースを作成しません。内嵌 Chroma は実際の spawn と直接子プロセスの exit を確認します。通常終了から1.5秒後に強制終了へ進み、さらに1.5秒待っても確認できなければハンドルを保持して失敗を返します。直接子プロセスの検証はプロセスツリー全体や実際の Chroma CLI 起動の証明ではありません。
|
|
173
|
+
|
|
174
|
+
## 開発とテスト
|
|
136
175
|
|
|
137
176
|
```bash
|
|
138
177
|
pnpm --filter @h-ai/vecdb test
|
|
@@ -140,6 +179,8 @@ pnpm --filter @h-ai/vecdb test
|
|
|
140
179
|
|
|
141
180
|
> pgvector / Qdrant のテストには Docker が必要です。
|
|
142
181
|
|
|
143
|
-
|
|
182
|
+
ソースの JSDoc は[共通規約](../../.agents/instructions/module-conventions.md#jsdoc-与示例验证)に従います。公開例は実際の公開入口、内部例は元のモジュールスコープで型検査します。ビルド後に `pnpm check:jsdoc --package vecdb` を実行してください。例の型検査は実バックエンドの動作検証の代わりにはなりません。
|
|
183
|
+
|
|
184
|
+
## ライセンス
|
|
144
185
|
|
|
145
186
|
Apache-2.0
|
package/README.md
CHANGED
|
@@ -4,22 +4,27 @@
|
|
|
4
4
|
|
|
5
5
|
[框架首页](../../README.md) · 相关模块:[@h-ai/core](../core/README.md)
|
|
6
6
|
|
|
7
|
+
## 简介
|
|
8
|
+
|
|
7
9
|
向量数据库模块,通过统一的 `vecdb` 对象访问 LanceDB、pgvector、Qdrant、Chroma。
|
|
8
10
|
|
|
9
|
-
##
|
|
11
|
+
## 核心功能清单
|
|
12
|
+
|
|
13
|
+
- 创建和管理固定向量维度的集合。
|
|
14
|
+
- 写入文档向量,按相似度检索并过滤元数据。
|
|
15
|
+
- 支持 LanceDB、pgvector、Qdrant 与 Chroma;后端准备方式见下方配置。
|
|
10
16
|
|
|
11
|
-
|
|
12
|
-
- pgvector(PostgreSQL + pgvector 扩展)
|
|
13
|
-
- Qdrant(高性能向量搜索引擎;服务端需 1.10.0+,使用 Query API)
|
|
14
|
-
- Chroma(支持嵌入式自动拉起本地服务,或直连已有服务)
|
|
17
|
+
## 使用入门
|
|
15
18
|
|
|
16
|
-
|
|
19
|
+
### 快速开始
|
|
17
20
|
|
|
18
21
|
```ts
|
|
19
22
|
import { HaiVecdbError, vecdb } from '@h-ai/vecdb'
|
|
20
23
|
|
|
21
24
|
// 初始化(LanceDB)
|
|
22
|
-
await vecdb.init({ type: 'lancedb', path: './data/vecdb' })
|
|
25
|
+
const initialized = await vecdb.init({ type: 'lancedb', path: './data/vecdb' })
|
|
26
|
+
if (!initialized.success)
|
|
27
|
+
throw new Error(initialized.error.message)
|
|
23
28
|
|
|
24
29
|
// 创建集合
|
|
25
30
|
await vecdb.collection.create('docs', { dimension: 1536 })
|
|
@@ -44,7 +49,7 @@ if (!closeResult.success) {
|
|
|
44
49
|
}
|
|
45
50
|
```
|
|
46
51
|
|
|
47
|
-
|
|
52
|
+
### 配置
|
|
48
53
|
|
|
49
54
|
```ts
|
|
50
55
|
// LanceDB(默认,嵌入式本地存储)
|
|
@@ -76,10 +81,34 @@ await vecdb.init({ type: 'chroma', url: 'http://localhost:8000' })
|
|
|
76
81
|
```
|
|
77
82
|
|
|
78
83
|
> Chroma 在 Node 端只有 HTTP 客户端(无进程内嵌入式)。嵌入式模式下 `vecdb.init` 会
|
|
79
|
-
> 通过 `serverCommand`(默认 `chroma
|
|
80
|
-
>
|
|
84
|
+
> 通过 `serverCommand`(默认 `chroma`)拉起本地服务,`vecdb.close` 时关闭进程。
|
|
85
|
+
> npm 可选依赖 `chromadb` 提供 HTTP 客户端;服务端 CLI 需另行安装,命令不可用时 `init` 返回 `CONNECTION_FAILED`。
|
|
86
|
+
|
|
87
|
+
Chroma 直连 `url` 仅接受 HTTP(S) 根端点(例如 `https://chroma.example.com:8443/`),优先于 `host/port`;不接受 URL 凭据、路径前缀、query 或 fragment。未提供 `url` 时使用 `host/port` 的 HTTP 连接。配置使用 `chromadb 3.5.0` 的 `host/port/ssl/headers` 参数,依据:[官方 TypeScript 客户端](https://docs.trychroma.com/reference/typescript/client)。
|
|
88
|
+
|
|
89
|
+
Chroma 的可选 `apiKey` 按本模块约定发送 `Authorization: Bearer <apiKey>`,仅用于采用该认证协议的自托管服务或网关;远程凭据传输应使用 HTTPS。空串表示不带凭据,非空值不得包含空白、控制字符或非 ASCII 字符。本接口使用默认 tenant/database,不提供 Chroma Cloud 的客户端与租户配置。初始化在心跳后验证集合计数数据端点;认证/权限失败返回 `CONNECTION_FAILED`,不会发布已连接状态,调用方必须检查 `success`。
|
|
90
|
+
|
|
91
|
+
直连初始化的总截止为 5 秒,本地服务拉起使用 `startupTimeout`。超时中止候选 HTTP 请求;成功后清除初始化 timer,此截止不限制后续业务请求。
|
|
92
|
+
|
|
93
|
+
Qdrant 使用 `@qdrant/js-client-rest 1.18.0` 的实际类型与 Query API,支持未命名向量字段的 cosine/euclidean/dot 集合。外部 named-vector 或 Manhattan 集合的 info/写入/搜索返回 `CONFIG_ERROR`,不猜测为零维或默认 cosine;仅 HTTP 404 表示集合不存在。Provider 的 URL 日志复用 core 的统一脱敏。
|
|
94
|
+
|
|
95
|
+
Chroma 的 metadata/filter 遵循 `chromadb 3.5.0` 原生校验,非法值返回操作错误,不丢弃过滤或回退为无过滤查询。可省略文档 content,搜索仍返回 `undefined`;内部按 SDK 的字符串字段传递。各后端的 null、复杂元数据与过滤语义需单独核对。
|
|
96
|
+
|
|
97
|
+
LanceDB 将向量维度存于 Arrow 固定长度 vector 字段,将集合 metric 存于同一 schema 的 metadata;空表也可正确恢复。`collection.create` 中的 metric 优先于连接配置,连接 metric 仅是新集合的默认值。重启或更换默认值不会改变已有集合。每次操作读取持久 schema,并检查其它连接的提交;缺少有效集合定义时返回 `CONFIG_ERROR`,不探测假向量或猜测 metric。旧表/外部表如缺少该定义,需要重建集合,不提供兼容推断。
|
|
98
|
+
|
|
99
|
+
LanceDB 是嵌入式本地文件后端。只有访问相同持久目录、且底层文件系统支持 LanceDB 并发提交的进程才能共享数据;不同节点各自的同名本地路径互不共享。分布式服务优先选择 pgvector、Qdrant 或 Chroma 服务端。AI Knowledge 的 reldb 与 vecdb 都须持久化并指向同一业务数据集,替换 embedding 维度时须重建匹配的集合。
|
|
100
|
+
|
|
101
|
+
搜索始终使用集合 metric,`euclidean` 映射 LanceDB 的 `l2`。`score` 延续公开 API 的 0–1、越大越相似约定:cosine 为 `clamp(1 - distance / 2, 0, 1)`;euclidean 为 `1 / (1 + squaredL2)`;dot 为 `sigmoid(dotProduct)`,用于保持内积排序而非概率。`minScore` 在该转换后过滤;不同 metric/后端的阈值不应视为通用校准值。
|
|
81
102
|
|
|
82
|
-
|
|
103
|
+
LanceDB 原子写入的验证基线为 `@lancedb/lancedb 0.40.0 / Lance 13`。新集合在初始 Arrow schema 声明 id 为不可空主键;insert/upsert 均使用原生 merge,以 id 参与严格键冲突检测。依据:[Lance 13 table format](https://github.com/lance-format/lance/blob/v13.0.0/docs/src/format/table/index.md#unenforced-primary-key)、[Lance 13 transaction](https://github.com/lance-format/lance/blob/v13.0.0/protos/transaction.proto)、[Node binding 0.40.0](https://github.com/lancedb/lancedb/blob/v0.40.0/nodejs/lancedb/table.ts)。
|
|
104
|
+
|
|
105
|
+
LanceDB 的 `insert` 仅插入新 ID,已有 ID 保留不覆盖;`upsert` 新增或整体替换。同批重复 ID、缺失 merge 能力/持久主键均返回 `CONFIG_ERROR`,不执行写入。旧表需重建,不自动迁移或清空。每个 merge 独立原子提交;并发胜者由提交顺序决定,不提供多个 merge 或 reldb/vecdb 间的共同事务。框架不会回退到 delete/add;写入结果不明时按 ID 核对。直接使用原生 add 的外部写入会绕过该保护,不属于本接口保证。
|
|
106
|
+
|
|
107
|
+
LanceDB 的 `metadata` 使用原生 JSON 字段,仍可存储嵌套 JSON 对象,搜索结果还原为对象。写入时显式使用 Arrow JSON schema,确保 insert/upsert 都经过 JSONB 编码;旧 Utf8 metadata 表写入或过滤返回 `CONFIG_ERROR`,须重建,不自动迁移。
|
|
108
|
+
|
|
109
|
+
LanceDB 的 `filter` 仅支持顶层键的 AND 精确匹配,例如 `{ tenant: 'acme', page: 1, active: true, removedAt: null }`。值支持字符串、有限数值、布尔和 null,严格区分 `1`/`'1'`、`true`/`'true'`;null 只匹配显式 JSON null,不匹配缺失字段。键是字面量,点号/括号不代表嵌套路径,引号、反斜线、`%`、`_` 均无 SQL/通配符含义。空对象不筛选;对象、数组、undefined、非有限数值返回 `CONFIG_ERROR`,不会执行无过滤查询。过滤在向量 topK 选取前执行,随后应用 minScore。其它 Provider 沿用各自原生过滤约束,不保证相同 null、复杂值或路径语义;跨后端时须核对实际能力。JSON 查询依据:[Lance 13 JSON UDF](https://github.com/lance-format/lance/blob/v13.0.0/rust/lance-datafusion/src/udf/json.rs)、[Node 0.40.0 JSON field](https://github.com/lancedb/lancedb/blob/v0.40.0/nodejs/lancedb/arrow.ts)。
|
|
110
|
+
|
|
111
|
+
#### 操作日志
|
|
83
112
|
|
|
84
113
|
可在向量数据库配置中通过 `operationLog` 开启操作日志。日志在集合/向量操作进入真实 Provider 前输出,不在 `vecdb-main.ts` 中做统一包装。
|
|
85
114
|
|
|
@@ -111,7 +140,9 @@ await vecdb.init({
|
|
|
111
140
|
|
|
112
141
|
> 行为说明:空批量 `insert/upsert/delete` 会被视为 no-op;写入与搜索会校验向量维度,不匹配时返回 `HaiVecdbError.DIMENSION_MISMATCH`;缺少可选驱动时返回 `HaiVecdbError.DRIVER_NOT_FOUND`。
|
|
113
142
|
|
|
114
|
-
|
|
143
|
+
Qdrant 的 `insert/upsert/delete` 使用 `wait: true`,成功表示服务端已应用该操作;`vector.count` 使用精确计数,不使用集合信息的近似 points_count。多个操作之间仍不构成事务。
|
|
144
|
+
|
|
145
|
+
### 错误处理
|
|
115
146
|
|
|
116
147
|
所有操作返回 `HaiResult<T>`,通过 `result.success` 判断成功或失败。
|
|
117
148
|
|
|
@@ -132,7 +163,15 @@ if (!result.success) {
|
|
|
132
163
|
}
|
|
133
164
|
```
|
|
134
165
|
|
|
135
|
-
##
|
|
166
|
+
## 生产共享状态
|
|
167
|
+
|
|
168
|
+
生产使用 Qdrant、pgvector 或远端 Chroma;LanceDB 和嵌入式 Chroma 只用于开发/明确测试。 NODE_ENV 或 HAI_CORE_ENV 为 production 时在初始化发布成功前校验;仅 HAI_E2E=1/HAI_E2E_MOCK=1 明确测试可豁免。 [状态、并发和恢复边界](../../.agents/instructions/distributed-state.md)。
|
|
169
|
+
|
|
170
|
+
## 关闭与失败恢复
|
|
171
|
+
|
|
172
|
+
close 立即停止当前操作与此前取得的操作引用;连接失败候选和关闭失败资源仅作为待清理所有权保留,不再提供业务服务。并发 close 合并,进行中的 init 先确定资源归属再关闭。失败结果的 error.ext.cleanupPending 表示仍须用同一模块的 close 重试;清理成功前 init 不创建替代资源。内嵌 Chroma 等待实际 spawn,终止直接启动的服务器后等待 exit;普通终止超过 1.5 秒后升级强制终止,再等待 1.5 秒,未确认退出返回失败并保留句柄。该验证覆盖直接子进程,不把信号回执等同于进程树退出或真实 Chroma CLI 上线验收。
|
|
173
|
+
|
|
174
|
+
## 开发测试
|
|
136
175
|
|
|
137
176
|
```bash
|
|
138
177
|
pnpm --filter @h-ai/vecdb test
|
|
@@ -140,6 +179,8 @@ pnpm --filter @h-ai/vecdb test
|
|
|
140
179
|
|
|
141
180
|
> pgvector / Qdrant 测试需要 Docker。
|
|
142
181
|
|
|
143
|
-
|
|
182
|
+
源码 JSDoc 遵循[统一规范](../../.agents/instructions/module-conventions.md#jsdoc-与示例验证):公开示例使用实际发布入口,内部示例在原模块作用域检查。构建后执行 `pnpm check:jsdoc --package vecdb`;示例编译不代替真实后端行为验证。
|
|
183
|
+
|
|
184
|
+
## 许可证
|
|
144
185
|
|
|
145
186
|
Apache-2.0
|