mirror of
https://github.com/run-llama/LlamaIndexTS.git
synced 2026-07-16 07:14:29 -04:00
feat: Voyage embeddings (#1574)
Co-authored-by: Marcus Schiesser <mail@marcusschiesser.de>
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@llamaindex/voyage-ai": major
|
||||
---
|
||||
|
||||
Adding VoyageAI embedding package
|
||||
@@ -41,8 +41,15 @@ pnpm install
|
||||
|
||||
### Build the packages
|
||||
|
||||
You'll need Turbo to build the packages. If you don't have it, you can run it with `pnpx`.
|
||||
|
||||
To build all packages, run:
|
||||
|
||||
```shell
|
||||
# Build all packages
|
||||
pnpx turbo build --filter "./packages/*"
|
||||
|
||||
# Or if you have turbo installed, you can run:
|
||||
turbo build --filter "./packages/*"
|
||||
```
|
||||
|
||||
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
---
|
||||
title: VoyageAI
|
||||
---
|
||||
|
||||
To use VoyageAI embeddings, you need to import `VoyageAIEmbedding` from `@llamaindex/voyage-ai`.
|
||||
|
||||
## Installation
|
||||
|
||||
import { Tab, Tabs } from "fumadocs-ui/components/tabs";
|
||||
|
||||
<Tabs groupId="install" items={["npm", "yarn", "pnpm"]} persist>
|
||||
```shell tab="npm"
|
||||
npm install llamaindex @llamaindex/voyage-ai
|
||||
```
|
||||
|
||||
```shell tab="yarn"
|
||||
yarn add llamaindex @llamaindex/voyage-ai
|
||||
```
|
||||
|
||||
```shell tab="pnpm"
|
||||
pnpm add llamaindex @llamaindex/voyage-ai
|
||||
```
|
||||
</Tabs>
|
||||
|
||||
```ts
|
||||
import { VoyageAIEmbedding } from "@llamaindex/voyage-ai";
|
||||
import { Document, Settings, VectorStoreIndex } from "llamaindex";
|
||||
|
||||
Settings.embedModel = new VoyageAIEmbedding();
|
||||
|
||||
const document = new Document({ text: essay, id_: "essay" });
|
||||
|
||||
const index = await VectorStoreIndex.fromDocuments([document]);
|
||||
|
||||
const queryEngine = index.asQueryEngine();
|
||||
|
||||
const query = "What is the meaning of life?";
|
||||
|
||||
const results = await queryEngine.query({
|
||||
query,
|
||||
});
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- [VoyageAIEmbedding](/docs/api/classes/VoyageAIEmbedding)
|
||||
@@ -41,6 +41,7 @@
|
||||
"@llamaindex/upstash": "^0.0.7",
|
||||
"@llamaindex/vercel": "^0.0.13",
|
||||
"@llamaindex/vllm": "^0.0.24",
|
||||
"@llamaindex/voyage-ai": "^0.0.1",
|
||||
"@llamaindex/weaviate": "^0.0.7",
|
||||
"@llamaindex/workflow": "^0.0.11",
|
||||
"@notionhq/client": "^2.2.15",
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import { VoyageAIEmbedding } from "@llamaindex/voyage-ai";
|
||||
|
||||
async function main() {
|
||||
// API token can be provided as an environment variable too
|
||||
// using VOYAGE_API_TOKEN variable
|
||||
const apiKey = process.env.VOYAGE_API_TOKEN ?? "YOUR_API_TOKEN";
|
||||
const model = "voyage-3-lite";
|
||||
const embedModel = new VoyageAIEmbedding({
|
||||
model,
|
||||
apiKey,
|
||||
});
|
||||
const texts = ["hello", "world"];
|
||||
const embeddings = await embedModel.getTextEmbeddingsBatch(texts);
|
||||
console.log(`\nWe have ${embeddings.length} embeddings`);
|
||||
}
|
||||
|
||||
main().catch(console.error);
|
||||
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"name": "@llamaindex/voyage-ai",
|
||||
"description": "VoyageAI Adapter for LlamaIndex",
|
||||
"version": "0.0.1",
|
||||
"type": "module",
|
||||
"main": "./dist/index.cjs",
|
||||
"module": "./dist/index.js",
|
||||
"exports": {
|
||||
".": {
|
||||
"require": {
|
||||
"types": "./dist/index.d.cts",
|
||||
"default": "./dist/index.cjs"
|
||||
},
|
||||
"import": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"default": "./dist/index.js"
|
||||
}
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/run-llama/LlamaIndexTS.git",
|
||||
"directory": "packages/providers/voyage-ai"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "bunchee",
|
||||
"dev": "bunchee --watch"
|
||||
},
|
||||
"devDependencies": {
|
||||
"bunchee": "6.0.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@llamaindex/core": "workspace:*",
|
||||
"@llamaindex/env": "workspace:*",
|
||||
"voyageai": "0.0.3-1"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
import { BaseEmbedding } from "@llamaindex/core/embeddings";
|
||||
import type { MessageContentDetail } from "@llamaindex/core/llms";
|
||||
import { extractSingleText } from "@llamaindex/core/utils";
|
||||
import { getEnv } from "@llamaindex/env";
|
||||
import { VoyageAI, VoyageAIClient } from "voyageai";
|
||||
|
||||
const DEFAULT_MODEL = "voyage-3";
|
||||
const API_TOKEN_ENV_VARIABLE_NAME = "VOYAGE_API_TOKEN";
|
||||
// const API_ROOT = "https://api.voyageai.com/v1/embeddings";
|
||||
const DEFAULT_TIMEOUT = 60 * 1000;
|
||||
const DEFAULT_MAX_RETRIES = 5;
|
||||
|
||||
/**
|
||||
* VoyageAIEmbedding is an alias for VoyageAI that implements the BaseEmbedding interface.
|
||||
*/
|
||||
export class VoyageAIEmbedding extends BaseEmbedding {
|
||||
/**
|
||||
* VoyageAI model to use
|
||||
* @default "voyage-3"
|
||||
* @see https://docs.voyageai.com/docs/embeddings
|
||||
*/
|
||||
model: string;
|
||||
|
||||
/**
|
||||
* VoyageAI API token
|
||||
* @see https://docs.voyageai.com/docs/api-key-and-installation
|
||||
* If not provided, it will try to get the token from the environment variable `VOYAGE_API_KEY`
|
||||
*
|
||||
*/
|
||||
apiKey: string;
|
||||
|
||||
/**
|
||||
* Maximum number of retries
|
||||
* @default 5
|
||||
*/
|
||||
maxRetries: number;
|
||||
|
||||
/**
|
||||
* Timeout in seconds
|
||||
* @default 60
|
||||
*/
|
||||
timeout: number;
|
||||
/**
|
||||
* Whether to truncate the input texts to fit within the context length. Defaults to `true`.
|
||||
* If `true`, over-length input texts will be truncated to fit within the context length, before vectorized by the embedding model.
|
||||
* If `false`, an error will be raised if any given text exceeds the context length.
|
||||
*/
|
||||
truncation: boolean;
|
||||
|
||||
/**
|
||||
* VoyageAI supports `document` and `query` as input types, or it can be left undefined. Using an input type prepends the input with a prompt before embedding.
|
||||
* Example from their docs: using "query" adds "Represent the query for retrieving supporting documents:"
|
||||
* VoyageAI says these types improve performance, but it will add to token usage. Embeddings with input types are compatible with those that don't use them.
|
||||
* Setting this to `query` will use the `query` input type for getQueryEmbedding(s).
|
||||
* Setting this to `document` will use the `document` input type for getTextEmbedding(s).
|
||||
* Setting this to `both` will do both of the above.
|
||||
* By default, this is undefined, which means no input types are used.
|
||||
* @see https://docs.voyageai.com/docs/embeddings
|
||||
* @default undefined
|
||||
*/
|
||||
useInputTypes: "query" | "document" | "both" | undefined;
|
||||
|
||||
/**
|
||||
* VoyageAI client
|
||||
*/
|
||||
client: VoyageAIClient;
|
||||
|
||||
constructor(init?: Partial<VoyageAIEmbedding>) {
|
||||
super();
|
||||
|
||||
this.model = init?.model ?? DEFAULT_MODEL;
|
||||
this.apiKey = init?.apiKey ?? getEnv(API_TOKEN_ENV_VARIABLE_NAME) ?? "";
|
||||
this.maxRetries = init?.maxRetries ?? DEFAULT_MAX_RETRIES;
|
||||
this.timeout = init?.timeout ?? DEFAULT_TIMEOUT;
|
||||
this.truncation = init?.truncation ?? true;
|
||||
this.useInputTypes = init?.useInputTypes;
|
||||
this.client = new VoyageAIClient({
|
||||
apiKey: this.apiKey,
|
||||
});
|
||||
}
|
||||
|
||||
async getTextEmbedding(text: string): Promise<number[]> {
|
||||
const embeddings = await this.getVoyageAIEmbedding([text], "document");
|
||||
return embeddings[0]!;
|
||||
}
|
||||
|
||||
async getQueryEmbedding(
|
||||
query: MessageContentDetail,
|
||||
): Promise<number[] | null> {
|
||||
const text = extractSingleText(query);
|
||||
if (text) {
|
||||
const embeddings = await this.getVoyageAIEmbedding([text], "query");
|
||||
return embeddings[0]!;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
getTextEmbeddings = async (texts: string[]): Promise<number[][]> => {
|
||||
return this.getVoyageAIEmbedding(texts, "document");
|
||||
};
|
||||
|
||||
async getQueryEmbeddings(queries: string[]): Promise<number[][]> {
|
||||
return this.getVoyageAIEmbedding(queries, "query");
|
||||
}
|
||||
|
||||
private getInputType(requestType: "query" | "document") {
|
||||
if (this.useInputTypes === "both") {
|
||||
return requestType;
|
||||
} else if (this.useInputTypes === requestType) {
|
||||
return requestType;
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
private async getVoyageAIEmbedding(
|
||||
inputs: VoyageAI.EmbedRequestInput,
|
||||
inputType: VoyageAI.EmbedRequestInputType,
|
||||
): Promise<number[][]> {
|
||||
const request: VoyageAI.EmbedRequest = {
|
||||
model: this.model,
|
||||
input: inputs,
|
||||
truncation: this.truncation,
|
||||
};
|
||||
const preferredInputType = this.getInputType(inputType);
|
||||
if (preferredInputType) {
|
||||
request.inputType = preferredInputType;
|
||||
}
|
||||
const response = await this.client.embed(request);
|
||||
if (response.data) {
|
||||
return response.data.map((item) => item.embedding ?? []);
|
||||
} else {
|
||||
throw new Error("Failed to get embeddings from VoyageAI");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export { VoyageAIEmbedding } from "./embedding";
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"extends": "../../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"target": "ESNext",
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "bundler",
|
||||
"outDir": "./lib",
|
||||
"tsBuildInfoFile": "./lib/.tsbuildinfo"
|
||||
},
|
||||
"include": ["./src"],
|
||||
"references": [
|
||||
{
|
||||
"path": "../openai/tsconfig.json"
|
||||
},
|
||||
{
|
||||
"path": "../../env/tsconfig.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
Generated
+100
-2
@@ -685,6 +685,9 @@ importers:
|
||||
'@llamaindex/vllm':
|
||||
specifier: ^0.0.24
|
||||
version: link:../packages/providers/vllm
|
||||
'@llamaindex/voyage-ai':
|
||||
specifier: ^0.0.1
|
||||
version: link:../packages/providers/voyage-ai
|
||||
'@llamaindex/weaviate':
|
||||
specifier: ^0.0.7
|
||||
version: link:../packages/providers/storage/weaviate
|
||||
@@ -1443,7 +1446,7 @@ importers:
|
||||
version: link:../../../env
|
||||
chromadb:
|
||||
specifier: 1.10.3
|
||||
version: 1.10.3(cohere-ai@7.14.0)(openai@4.83.0(ws@8.18.0(bufferutil@4.0.9))(zod@3.24.2))
|
||||
version: 1.10.3(cohere-ai@7.14.0)(openai@4.83.0(ws@8.18.0(bufferutil@4.0.9))(zod@3.24.2))(voyageai@0.0.3-1)
|
||||
chromadb-default-embed:
|
||||
specifier: ^2.13.2
|
||||
version: 2.13.2
|
||||
@@ -1636,6 +1639,22 @@ importers:
|
||||
specifier: 6.3.4
|
||||
version: 6.3.4(patch_hash=pavboztthlgni7m5gzw7643oru)(typescript@5.7.3)
|
||||
|
||||
packages/providers/voyage-ai:
|
||||
dependencies:
|
||||
'@llamaindex/core':
|
||||
specifier: workspace:*
|
||||
version: link:../../core
|
||||
'@llamaindex/env':
|
||||
specifier: workspace:*
|
||||
version: link:../../env
|
||||
voyageai:
|
||||
specifier: 0.0.3-1
|
||||
version: 0.0.3-1
|
||||
devDependencies:
|
||||
bunchee:
|
||||
specifier: 6.0.3
|
||||
version: 6.0.3(typescript@5.7.3)
|
||||
|
||||
packages/readers:
|
||||
dependencies:
|
||||
'@azure/cosmos':
|
||||
@@ -4263,6 +4282,15 @@ packages:
|
||||
rollup:
|
||||
optional: true
|
||||
|
||||
'@rollup/plugin-node-resolve@15.3.1':
|
||||
resolution: {integrity: sha512-tgg6b91pAybXHJQMAAwW9VuWBO6Thi+q7BCNARLwSqlmsHz0XYURtGvh/AuwSADXSI4h/2uHbs7s4FzlZDGSGA==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
peerDependencies:
|
||||
rollup: ^2.78.0||^3.0.0||^4.0.0
|
||||
peerDependenciesMeta:
|
||||
rollup:
|
||||
optional: true
|
||||
|
||||
'@rollup/plugin-node-resolve@16.0.0':
|
||||
resolution: {integrity: sha512-0FPvAeVUT/zdWoO0jnb/V5BlBsUSNfkIOtFHzMO4H9MOklrmQFY6FduVHKucNb/aTFxvnGhj4MNj/T1oNdDfNg==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
@@ -5926,6 +5954,16 @@ packages:
|
||||
resolution: {integrity: sha512-WDtdLmJvAuNNPzByAYpRo2rF1Mmradw6gvWsQKf63476DDXmomT9zUiGypLcG4ibIM67vhAj8jJRdbmEws2Aqw==}
|
||||
engines: {node: '>=6.14.2'}
|
||||
|
||||
bunchee@6.0.3:
|
||||
resolution: {integrity: sha512-Yq/srd3ocXPAHv0KEdJvhFMNUOOVVqy0kNzaGVCirk/+MfnLdvZO5uf5BHugIHe/qSvWUQTJZ3SAfB/VABONeQ==}
|
||||
engines: {node: '>= 18.0.0'}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
typescript: ^4.1 || ^5.0
|
||||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
|
||||
bunchee@6.3.4:
|
||||
resolution: {integrity: sha512-bMy2/+tdMPXOqBAX+9BI0HTNjOXOZ2TXjgFpp5Prt0ztP15xQQUcsECnU7wuBPpLH+4id3rXakH9icdbBRZHZQ==}
|
||||
engines: {node: '>= 18.0.0'}
|
||||
@@ -11534,6 +11572,9 @@ packages:
|
||||
jsdom:
|
||||
optional: true
|
||||
|
||||
voyageai@0.0.3-1:
|
||||
resolution: {integrity: sha512-R3jN/xnILWoMBL3jPY61Ydm1JbpK3J+VmXBoHvlNg1Xz8h0xdX7sEffXeSu+sAEKQaPyWXVQDmM/jpBhPXw58g==}
|
||||
|
||||
vue-demi@0.14.10:
|
||||
resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==}
|
||||
engines: {node: '>=12'}
|
||||
@@ -14803,6 +14844,16 @@ snapshots:
|
||||
optionalDependencies:
|
||||
rollup: 4.34.6
|
||||
|
||||
'@rollup/plugin-node-resolve@15.3.1(rollup@4.34.6)':
|
||||
dependencies:
|
||||
'@rollup/pluginutils': 5.1.4(rollup@4.34.6)
|
||||
'@types/resolve': 1.20.2
|
||||
deepmerge: 4.3.1
|
||||
is-module: 1.0.0
|
||||
resolve: 1.22.10
|
||||
optionalDependencies:
|
||||
rollup: 4.34.6
|
||||
|
||||
'@rollup/plugin-node-resolve@16.0.0(rollup@4.34.6)':
|
||||
dependencies:
|
||||
'@rollup/pluginutils': 5.1.4(rollup@4.34.6)
|
||||
@@ -16932,6 +16983,31 @@ snapshots:
|
||||
dependencies:
|
||||
node-gyp-build: 4.8.4
|
||||
|
||||
bunchee@6.0.3(typescript@5.7.3):
|
||||
dependencies:
|
||||
'@rollup/plugin-commonjs': 28.0.2(rollup@4.34.6)
|
||||
'@rollup/plugin-json': 6.1.0(rollup@4.34.6)
|
||||
'@rollup/plugin-node-resolve': 15.3.1(rollup@4.34.6)
|
||||
'@rollup/plugin-replace': 6.0.2(rollup@4.34.6)
|
||||
'@rollup/plugin-wasm': 6.2.2(rollup@4.34.6)
|
||||
'@rollup/pluginutils': 5.1.4(rollup@4.34.6)
|
||||
'@swc/core': 1.10.16(@swc/helpers@0.5.15)
|
||||
'@swc/helpers': 0.5.15
|
||||
clean-css: 5.3.3
|
||||
glob: 11.0.1
|
||||
magic-string: 0.30.17
|
||||
ora: 8.2.0
|
||||
picomatch: 4.0.2
|
||||
pretty-bytes: 5.6.0
|
||||
rollup: 4.34.6
|
||||
rollup-plugin-dts: 6.1.1(rollup@4.34.6)(typescript@5.7.3)
|
||||
rollup-plugin-swc3: 0.11.2(@swc/core@1.10.16(@swc/helpers@0.5.15))(rollup@4.34.6)
|
||||
rollup-preserve-directives: 1.1.3(rollup@4.34.6)
|
||||
tslib: 2.8.1
|
||||
yargs: 17.7.2
|
||||
optionalDependencies:
|
||||
typescript: 5.7.3
|
||||
|
||||
bunchee@6.3.4(patch_hash=pavboztthlgni7m5gzw7643oru)(typescript@5.7.2):
|
||||
dependencies:
|
||||
'@rollup/plugin-commonjs': 28.0.2(rollup@4.34.6)
|
||||
@@ -17134,13 +17210,14 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- bare-buffer
|
||||
|
||||
chromadb@1.10.3(cohere-ai@7.14.0)(openai@4.83.0(ws@8.18.0(bufferutil@4.0.9))(zod@3.24.2)):
|
||||
chromadb@1.10.3(cohere-ai@7.14.0)(openai@4.83.0(ws@8.18.0(bufferutil@4.0.9))(zod@3.24.2))(voyageai@0.0.3-1):
|
||||
dependencies:
|
||||
cliui: 8.0.1
|
||||
isomorphic-fetch: 3.0.0
|
||||
optionalDependencies:
|
||||
cohere-ai: 7.14.0
|
||||
openai: 4.83.0(ws@8.18.0(bufferutil@4.0.9))(zod@3.24.2)
|
||||
voyageai: 0.0.3-1
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
|
||||
@@ -22738,6 +22815,15 @@ snapshots:
|
||||
rollup: 4.34.6
|
||||
rollup-preserve-directives: 1.1.3(rollup@4.34.6)
|
||||
|
||||
rollup-plugin-swc3@0.11.2(@swc/core@1.10.16(@swc/helpers@0.5.15))(rollup@4.34.6):
|
||||
dependencies:
|
||||
'@fastify/deepmerge': 1.3.0
|
||||
'@rollup/pluginutils': 5.1.4(rollup@4.34.6)
|
||||
'@swc/core': 1.10.16(@swc/helpers@0.5.15)
|
||||
get-tsconfig: 4.10.0
|
||||
rollup: 4.34.6
|
||||
rollup-preserve-directives: 1.1.3(rollup@4.34.6)
|
||||
|
||||
rollup-pluginutils@2.8.2:
|
||||
dependencies:
|
||||
estree-walker: 0.6.1
|
||||
@@ -24326,6 +24412,18 @@ snapshots:
|
||||
- supports-color
|
||||
- terser
|
||||
|
||||
voyageai@0.0.3-1:
|
||||
dependencies:
|
||||
form-data: 4.0.0
|
||||
formdata-node: 6.0.3
|
||||
js-base64: 3.7.2
|
||||
node-fetch: 2.7.0
|
||||
qs: 6.11.2
|
||||
readable-stream: 4.7.0
|
||||
url-join: 4.0.1
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
|
||||
vue-demi@0.14.10(vue@3.5.13(typescript@5.7.2)):
|
||||
dependencies:
|
||||
vue: 3.5.13(typescript@5.7.2)
|
||||
|
||||
Reference in New Issue
Block a user