or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

azure-integration.mdchat-models.mdembeddings.mdindex.mdlanguage-models.mdtools.mdtypes-and-configuration.md
tile.json

embeddings.mddocs/

0

# Embeddings

1

2

Vector embeddings for semantic similarity, search, and retrieval-augmented generation (RAG) applications. Convert text into high-dimensional vectors for AI applications.

3

4

## Capabilities

5

6

### OpenAIEmbeddings Class

7

8

The primary embeddings class providing access to OpenAI's text embedding models.

9

10

```typescript { .api }

11

/**

12

* OpenAI embeddings integration

13

* Converts text into high-dimensional vectors for semantic similarity and search

14

*/

15

class OpenAIEmbeddings extends Embeddings {

16

17

constructor(fields?: Partial<OpenAIEmbeddingsParams>);

18

19

/** Model configuration */

20

model: string; // Default: "text-embedding-ada-002"

21

batchSize: number; // Batch size for API calls (default: 512)

22

stripNewLines: boolean; // Strip newlines from text (default: true)

23

dimensions?: number; // Output dimensions (text-embedding-3-* only)

24

25

/** Client configuration */

26

openAIApiKey?: string; // OpenAI API key

27

organization?: string; // OpenAI organization ID

28

baseURL?: string; // Custom base URL

29

timeout?: number; // Request timeout in milliseconds

30

maxRetries?: number; // Maximum retry attempts

31

32

/** Performance options */

33

maxConcurrency?: number; // Maximum concurrent requests

34

35

/** Embed multiple documents */

36

embedDocuments(texts: string[]): Promise<number[][]>;

37

38

/** Embed a single query */

39

embedQuery(text: string): Promise<number[]>;

40

41

/** Make embedding requests with retry logic */

42

embeddingWithRetry<T>(

43

request: OpenAIClient.EmbeddingCreateParams,

44

options?: OpenAICallOptions

45

): Promise<T>;

46

47

/** Get number of tokens in text */

48

getNumTokens(text: string): Promise<number>;

49

}

50

```

51

52

### OpenAI Embeddings Parameters

53

54

Configuration interface for OpenAI embeddings.

55

56

```typescript { .api }

57

interface OpenAIEmbeddingsParams extends EmbeddingsParams {

58

/** Model name for embeddings */

59

model: string;

60

61

/** Number of texts to batch together for embedding */

62

batchSize: number;

63

64

/** Whether to strip newlines from input text */

65

stripNewLines: boolean;

66

67

/** Output dimensions for embedding-3 models */

68

dimensions?: number;

69

70

/** OpenAI API configuration */

71

openAIApiKey?: string;

72

organization?: string;

73

baseURL?: string;

74

timeout?: number;

75

maxRetries?: number;

76

maxConcurrency?: number;

77

}

78

```

79

80

## Usage Examples

81

82

### Basic Embeddings

83

84

```typescript

85

import { OpenAIEmbeddings } from "@langchain/openai";

86

87

const embeddings = new OpenAIEmbeddings({

88

model: "text-embedding-3-small",

89

apiKey: process.env.OPENAI_API_KEY

90

});

91

92

// Embed a single query

93

const queryEmbedding = await embeddings.embedQuery(

94

"What is the capital of France?"

95

);

96

console.log(`Query embedding dimensions: ${queryEmbedding.length}`);

97

98

// Embed multiple documents

99

const documents = [

100

"Paris is the capital of France.",

101

"Berlin is the capital of Germany.",

102

"Tokyo is the capital of Japan.",

103

"London is the capital of the United Kingdom."

104

];

105

106

const documentEmbeddings = await embeddings.embedDocuments(documents);

107

console.log(`Embedded ${documentEmbeddings.length} documents`);

108

console.log(`Each embedding has ${documentEmbeddings[0].length} dimensions`);

109

```

110

111

### Vector Similarity Search

112

113

```typescript

114

import { OpenAIEmbeddings } from "@langchain/openai";

115

116

const embeddings = new OpenAIEmbeddings({

117

model: "text-embedding-3-small"

118

});

119

120

// Create a knowledge base

121

const knowledgeBase = [

122

"The Eiffel Tower is in Paris, France.",

123

"The Statue of Liberty is in New York, USA.",

124

"The Colosseum is in Rome, Italy.",

125

"Big Ben is in London, England.",

126

"The Sydney Opera House is in Sydney, Australia."

127

];

128

129

// Embed all documents

130

const docEmbeddings = await embeddings.embedDocuments(knowledgeBase);

131

132

// Function to calculate cosine similarity

133

function cosineSimilarity(a: number[], b: number[]): number {

134

const dotProduct = a.reduce((sum, val, i) => sum + val * b[i], 0);

135

const magnitudeA = Math.sqrt(a.reduce((sum, val) => sum + val * val, 0));

136

const magnitudeB = Math.sqrt(b.reduce((sum, val) => sum + val * val, 0));

137

return dotProduct / (magnitudeA * magnitudeB);

138

}

139

140

// Search function

141

async function searchKnowledgeBase(query: string, topK = 3) {

142

const queryEmbedding = await embeddings.embedQuery(query);

143

144

const similarities = docEmbeddings.map((docEmb, index) => ({

145

index,

146

document: knowledgeBase[index],

147

similarity: cosineSimilarity(queryEmbedding, docEmb)

148

}));

149

150

return similarities

151

.sort((a, b) => b.similarity - a.similarity)

152

.slice(0, topK);

153

}

154

155

// Find relevant documents

156

const results = await searchKnowledgeBase("famous landmarks in Europe");

157

results.forEach((result, i) => {

158

console.log(`${i + 1}. (${result.similarity.toFixed(3)}) ${result.document}`);

159

});

160

```

161

162

### Batch Processing with Optimization

163

164

```typescript

165

const embeddings = new OpenAIEmbeddings({

166

model: "text-embedding-3-large",

167

batchSize: 100, // Process 100 texts per batch

168

maxConcurrency: 5, // Max 5 concurrent requests

169

timeout: 30000, // 30 second timeout

170

maxRetries: 3

171

});

172

173

// Process large dataset efficiently

174

async function embedLargeDataset(texts: string[]) {

175

console.log(`Processing ${texts.length} texts...`);

176

177

const startTime = Date.now();

178

const embeddings_result = await embeddings.embedDocuments(texts);

179

const endTime = Date.now();

180

181

console.log(`Completed in ${(endTime - startTime) / 1000}s`);

182

console.log(`Average time per text: ${(endTime - startTime) / texts.length}ms`);

183

184

return embeddings_result;

185

}

186

187

// Example with 1000 texts

188

const largeDocs = Array.from({ length: 1000 }, (_, i) =>

189

`This is document number ${i + 1} with some sample content for testing embeddings performance.`

190

);

191

192

const results = await embedLargeDataset(largeDocs);

193

```

194

195

### Different Model Comparisons

196

197

```typescript

198

// Compare different embedding models

199

const models = [

200

"text-embedding-ada-002",

201

"text-embedding-3-small",

202

"text-embedding-3-large"

203

];

204

205

const sampleText = "Machine learning is a subset of artificial intelligence.";

206

207

for (const model of models) {

208

const embedder = new OpenAIEmbeddings({ model });

209

const embedding = await embedder.embedQuery(sampleText);

210

211

console.log(`${model}:`);

212

console.log(` Dimensions: ${embedding.length}`);

213

console.log(` First 5 values: [${embedding.slice(0, 5).map(x => x.toFixed(4)).join(', ')}]`);

214

}

215

```

216

217

### Custom Dimensions (Embedding-3 Models)

218

219

```typescript

220

// Use custom dimensions to reduce storage and improve performance

221

const compactEmbeddings = new OpenAIEmbeddings({

222

model: "text-embedding-3-small",

223

dimensions: 512 // Reduce from default 1536 to 512

224

});

225

226

const standardEmbeddings = new OpenAIEmbeddings({

227

model: "text-embedding-3-small"

228

// Uses default 1536 dimensions

229

});

230

231

const text = "This is a test for dimension comparison.";

232

233

const compact = await compactEmbeddings.embedQuery(text);

234

const standard = await standardEmbeddings.embedQuery(text);

235

236

console.log(`Compact dimensions: ${compact.length}`); // 512

237

console.log(`Standard dimensions: ${standard.length}`); // 1536

238

239

// Note: Reduced dimensions may impact quality for some use cases

240

```

241

242

### RAG (Retrieval-Augmented Generation) Setup

243

244

```typescript

245

import { OpenAIEmbeddings } from "@langchain/openai";

246

import { ChatOpenAI } from "@langchain/openai";

247

248

class SimpleRAG {

249

private embeddings: OpenAIEmbeddings;

250

private chatModel: ChatOpenAI;

251

private documents: string[] = [];

252

private docEmbeddings: number[][] = [];

253

254

constructor() {

255

this.embeddings = new OpenAIEmbeddings({

256

model: "text-embedding-3-small"

257

});

258

259

this.chatModel = new ChatOpenAI({

260

model: "gpt-4o-mini",

261

temperature: 0

262

});

263

}

264

265

async addDocuments(docs: string[]) {

266

this.documents.push(...docs);

267

const newEmbeddings = await this.embeddings.embedDocuments(docs);

268

this.docEmbeddings.push(...newEmbeddings);

269

}

270

271

async search(query: string, topK = 3): Promise<string[]> {

272

const queryEmbedding = await this.embeddings.embedQuery(query);

273

274

const similarities = this.docEmbeddings.map((docEmb, index) => ({

275

index,

276

similarity: this.cosineSimilarity(queryEmbedding, docEmb)

277

}));

278

279

return similarities

280

.sort((a, b) => b.similarity - a.similarity)

281

.slice(0, topK)

282

.map(item => this.documents[item.index]);

283

}

284

285

async answer(question: string): Promise<string> {

286

const relevantDocs = await this.search(question);

287

288

const context = relevantDocs.join('\n\n');

289

const prompt = `

290

Context:

291

${context}

292

293

Question: ${question}

294

295

Answer the question based on the provided context. If the answer cannot be found in the context, say "I cannot answer based on the provided information."

296

`;

297

298

const response = await this.chatModel.invoke(prompt);

299

return response.content as string;

300

}

301

302

private cosineSimilarity(a: number[], b: number[]): number {

303

const dotProduct = a.reduce((sum, val, i) => sum + val * b[i], 0);

304

const magnitudeA = Math.sqrt(a.reduce((sum, val) => sum + val * val, 0));

305

const magnitudeB = Math.sqrt(b.reduce((sum, val) => sum + val * val, 0));

306

return dotProduct / (magnitudeA * magnitudeB);

307

}

308

}

309

310

// Usage

311

const rag = new SimpleRAG();

312

313

await rag.addDocuments([

314

"The solar system contains eight planets: Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, and Neptune.",

315

"Earth is the third planet from the Sun and the only known planet with life.",

316

"Jupiter is the largest planet in the solar system and has over 70 moons.",

317

"Mars is often called the Red Planet due to its reddish appearance."

318

]);

319

320

const answer = await rag.answer("What is the largest planet?");

321

console.log(answer); // "Jupiter is the largest planet in the solar system..."

322

```

323

324

### Error Handling and Monitoring

325

326

```typescript

327

import { OpenAIEmbeddings } from "@langchain/openai";

328

329

const embeddings = new OpenAIEmbeddings({

330

model: "text-embedding-3-small",

331

maxRetries: 3,

332

timeout: 60000

333

});

334

335

async function robustEmbedding(texts: string[]) {

336

try {

337

const result = await embeddings.embedDocuments(texts);

338

return result;

339

} catch (error) {

340

console.error("Embedding failed:", error);

341

342

if (error.code === 'rate_limit_exceeded') {

343

console.log("Rate limit hit, implementing backoff...");

344

// Implement exponential backoff

345

await new Promise(resolve => setTimeout(resolve, 5000));

346

return robustEmbedding(texts);

347

}

348

349

if (error.code === 'context_length_exceeded') {

350

console.log("Text too long, chunking...");

351

// Split into smaller chunks

352

const chunks = texts.map(text =>

353

text.length > 8000 ? text.substring(0, 8000) : text

354

);

355

return embeddings.embedDocuments(chunks);

356

}

357

358

throw error;

359

}

360

}

361

362

// Monitor token usage

363

async function embedWithMonitoring(texts: string[]) {

364

const startTime = Date.now();

365

366

// Estimate tokens (rough approximation)

367

const estimatedTokens = texts.reduce((sum, text) =>

368

sum + Math.ceil(text.length / 4), 0

369

);

370

371

console.log(`Embedding ${texts.length} texts (~${estimatedTokens} tokens)`);

372

373

const result = await embeddings.embedDocuments(texts);

374

375

const duration = Date.now() - startTime;

376

console.log(`Completed in ${duration}ms (${(duration / texts.length).toFixed(1)}ms per text)`);

377

378

return result;

379

}

380

```

381

382

## Model Support

383

384

### Available Models

385

386

The OpenAI Embeddings class supports these models:

387

388

| Model | Dimensions | Max Input | Cost | Use Case |

389

|-------|------------|-----------|------|----------|

390

| `text-embedding-ada-002` | 1536 | 8191 tokens | Lower | General purpose (legacy) |

391

| `text-embedding-3-small` | 1536* | 8191 tokens | Lowest | High efficiency |

392

| `text-embedding-3-large` | 3072* | 8191 tokens | Higher | Maximum performance |

393

394

*Supports custom dimensions

395

396

### Model Selection Guide

397

398

```typescript

399

// For high-volume, cost-sensitive applications

400

const efficientEmbeddings = new OpenAIEmbeddings({

401

model: "text-embedding-3-small",

402

dimensions: 512 // Reduce dimensions for cost savings

403

});

404

405

// For maximum quality and performance

406

const highQualityEmbeddings = new OpenAIEmbeddings({

407

model: "text-embedding-3-large"

408

// Uses full 3072 dimensions

409

});

410

411

// For legacy compatibility

412

const legacyEmbeddings = new OpenAIEmbeddings({

413

model: "text-embedding-ada-002"

414

});

415

```

416

417

### Performance Characteristics

418

419

```typescript

420

// Optimize for throughput

421

const throughputOptimized = new OpenAIEmbeddings({

422

model: "text-embedding-3-small",

423

batchSize: 2048, // Large batches

424

maxConcurrency: 10, // High concurrency

425

dimensions: 256 // Smaller dimensions

426

});

427

428

// Optimize for quality

429

const qualityOptimized = new OpenAIEmbeddings({

430

model: "text-embedding-3-large",

431

batchSize: 100, // Smaller batches for stability

432

maxConcurrency: 3, // Conservative concurrency

433

// Full dimensions for maximum quality

434

});

435

```

436

437

## Best Practices

438

439

### Text Preprocessing

440

441

```typescript

442

const embeddings = new OpenAIEmbeddings({

443

model: "text-embedding-3-small",

444

stripNewLines: true // Remove newlines by default

445

});

446

447

// Custom preprocessing

448

function preprocessText(text: string): string {

449

return text

450

.toLowerCase() // Normalize case

451

.replace(/\s+/g, ' ') // Normalize whitespace

452

.trim() // Remove leading/trailing space

453

.substring(0, 8000); // Ensure within token limits

454

}

455

456

const documents = [

457

"This is SAMPLE text with weird spacing\n\n",

458

"Another document with\nNewlines and CAPS"

459

];

460

461

const preprocessed = documents.map(preprocessText);

462

const embeddings_result = await embeddings.embedDocuments(preprocessed);

463

```

464

465

### Caching Strategies

466

467

```typescript

468

class EmbeddingCache {

469

private cache = new Map<string, number[]>();

470

private embeddings: OpenAIEmbeddings;

471

472

constructor() {

473

this.embeddings = new OpenAIEmbeddings({

474

model: "text-embedding-3-small"

475

});

476

}

477

478

async embedQuery(text: string): Promise<number[]> {

479

const key = this.hashText(text);

480

481

if (this.cache.has(key)) {

482

console.log("Cache hit!");

483

return this.cache.get(key)!;

484

}

485

486

console.log("Cache miss, computing embedding...");

487

const embedding = await this.embeddings.embedQuery(text);

488

this.cache.set(key, embedding);

489

490

return embedding;

491

}

492

493

private hashText(text: string): string {

494

// Simple hash function - use a proper one in production

495

return Buffer.from(text).toString('base64');

496

}

497

}

498

499

const cachedEmbeddings = new EmbeddingCache();

500

```

501

502

### Chunking Long Documents

503

504

```typescript

505

function chunkDocument(text: string, maxChunkSize = 7000): string[] {

506

const sentences = text.split(/[.!?]+/).filter(s => s.trim().length > 0);

507

const chunks: string[] = [];

508

let currentChunk = "";

509

510

for (const sentence of sentences) {

511

if (currentChunk.length + sentence.length > maxChunkSize && currentChunk) {

512

chunks.push(currentChunk.trim());

513

currentChunk = "";

514

}

515

currentChunk += sentence + ". ";

516

}

517

518

if (currentChunk.trim()) {

519

chunks.push(currentChunk.trim());

520

}

521

522

return chunks;

523

}

524

525

// Usage with long documents

526

const longDocument = "Very long document text..."; // Imagine this is 20,000+ characters

527

528

const chunks = chunkDocument(longDocument);

529

const chunkEmbeddings = await embeddings.embedDocuments(chunks);

530

531

// Store with metadata for retrieval

532

const documentChunks = chunks.map((chunk, index) => ({

533

text: chunk,

534

embedding: chunkEmbeddings[index],

535

documentId: "doc_123",

536

chunkIndex: index

537

}));

538

```