100 lines
2.9 KiB
TypeScript
100 lines
2.9 KiB
TypeScript
/**
|
|
* Basic Gemini Embeddings Example (SDK)
|
|
*
|
|
* Demonstrates single text embedding generation using the @google/genai SDK.
|
|
*
|
|
* Setup:
|
|
* 1. npm install @google/genai@^1.27.0
|
|
* 2. export GEMINI_API_KEY="your-api-key"
|
|
* 3. Get API key from: https://aistudio.google.com/apikey
|
|
*
|
|
* Usage:
|
|
* npx tsx basic-embeddings.ts
|
|
*/
|
|
|
|
import { GoogleGenAI } from "@google/genai";
|
|
|
|
async function generateEmbedding(text: string) {
|
|
// Initialize client with API key
|
|
const ai = new GoogleGenAI({
|
|
apiKey: process.env.GEMINI_API_KEY
|
|
});
|
|
|
|
if (!process.env.GEMINI_API_KEY) {
|
|
throw new Error('GEMINI_API_KEY environment variable not set');
|
|
}
|
|
|
|
console.log(`\nGenerating embedding for: "${text}"\n`);
|
|
|
|
// Generate embedding
|
|
const response = await ai.models.embedContent({
|
|
model: 'gemini-embedding-001', // Stable production model
|
|
content: text,
|
|
config: {
|
|
taskType: 'SEMANTIC_SIMILARITY', // Optimize for similarity comparison
|
|
outputDimensionality: 768 // Recommended for most use cases
|
|
}
|
|
});
|
|
|
|
const embedding = response.embedding.values;
|
|
|
|
console.log(`✅ Embedding generated successfully!`);
|
|
console.log(`Dimensions: ${embedding.length}`);
|
|
console.log(`First 10 values: [${embedding.slice(0, 10).map(v => v.toFixed(4)).join(', ')}...]`);
|
|
console.log(`\nVector magnitude: ${Math.sqrt(embedding.reduce((sum, v) => sum + v * v, 0)).toFixed(4)}`);
|
|
|
|
return embedding;
|
|
}
|
|
|
|
// Example usage
|
|
async function main() {
|
|
try {
|
|
const text = "What is the meaning of life?";
|
|
const embedding = await generateEmbedding(text);
|
|
|
|
// Compare with another text
|
|
const text2 = "What is the purpose of existence?";
|
|
console.log(`\nGenerating embedding for: "${text2}"\n`);
|
|
|
|
const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
|
|
const response2 = await ai.models.embedContent({
|
|
model: 'gemini-embedding-001',
|
|
content: text2,
|
|
config: {
|
|
taskType: 'SEMANTIC_SIMILARITY',
|
|
outputDimensionality: 768
|
|
}
|
|
});
|
|
|
|
const embedding2 = response2.embedding.values;
|
|
|
|
// Calculate cosine similarity
|
|
const cosineSimilarity = (a: number[], b: number[]): number => {
|
|
let dotProduct = 0, magA = 0, magB = 0;
|
|
for (let i = 0; i < a.length; i++) {
|
|
dotProduct += a[i] * b[i];
|
|
magA += a[i] * a[i];
|
|
magB += b[i] * b[i];
|
|
}
|
|
return dotProduct / (Math.sqrt(magA) * Math.sqrt(magB));
|
|
};
|
|
|
|
const similarity = cosineSimilarity(embedding, embedding2);
|
|
console.log(`\n🔗 Similarity between texts: ${(similarity * 100).toFixed(2)}%`);
|
|
console.log('(1.0 = identical, 0.0 = completely different)\n');
|
|
|
|
} catch (error: any) {
|
|
console.error('❌ Error:', error.message);
|
|
|
|
if (error.status === 401) {
|
|
console.error('\nCheck that GEMINI_API_KEY is set correctly');
|
|
} else if (error.status === 429) {
|
|
console.error('\nRate limit exceeded. Free tier: 100 requests/minute');
|
|
}
|
|
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
main();
|