Loading...
Loading...
Compare original and translation side by side
gemini-embedding-001gemini-embedding-001bun add @google/genai@^1.27.0bun add -d typescript@^5.0.0bun add @google/genai@^1.27.0bun add -d typescript@^5.0.0export GEMINI_API_KEY="your-api-key-here"export GEMINI_API_KEY="your-api-key-here"import { GoogleGenAI } from "@google/genai";
const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
const response = await ai.models.embedContent({
model: 'gemini-embedding-001',
content: 'What is the meaning of life?',
config: {
taskType: 'RETRIEVAL_QUERY',
outputDimensionality: 768
}
});
console.log(response.embedding.values); // [0.012, -0.034, ...]
console.log(response.embedding.values.length); // 768import { GoogleGenAI } from "@google/genai";
const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
const response = await ai.models.embedContent({
model: 'gemini-embedding-001',
content: 'What is the meaning of life?',
config: {
taskType: 'RETRIEVAL_QUERY',
outputDimensionality: 768
}
});
console.log(response.embedding.values); // [0.012, -0.034, ...]
console.log(response.embedding.values.length); // 768gemini-embedding-001gemini-embedding-exp-03-07gemini-embedding-001gemini-embedding-exp-03-07| Dimension | Use Case | Storage | Performance |
|---|---|---|---|
| 768 | Recommended for most use cases | Low | Fast |
| 1536 | Balance between accuracy and efficiency | Medium | Medium |
| 3072 | Maximum accuracy (default) | High | Slower |
references/dimension-guide.mdreferences/model-comparison.md| 维度 | 适用场景 | 存储成本 | 性能 |
|---|---|---|---|
| 768 | 推荐用于大多数场景 | 低 | 快 |
| 1536 | 在准确性与效率间取得平衡 | 中 | 中等 |
| 3072 | 最高准确性(默认值) | 高 | 较慢 |
references/dimension-guide.mdreferences/model-comparison.md| Tier | RPM | TPM | RPD |
|---|---|---|---|
| Free | 100 | 30,000 | 1,000 |
| Tier 1 | 3,000 | 1,000,000 | - |
| 层级 | RPM | TPM | RPD |
|---|---|---|---|
| 免费层 | 100 | 30,000 | 1,000 |
| Tier 1 | 3,000 | 1,000,000 | - |
import { GoogleGenAI } from "@google/genai";
const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
const response = await ai.models.embedContent({
model: 'gemini-embedding-001',
content: 'The quick brown fox jumps over the lazy dog',
config: {
taskType: 'SEMANTIC_SIMILARITY',
outputDimensionality: 768
}
});
console.log(response.embedding.values);
// [0.00388, -0.00762, 0.01543, ...]import { GoogleGenAI } from "@google/genai";
const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
const response = await ai.models.embedContent({
model: 'gemini-embedding-001',
content: 'The quick brown fox jumps over the lazy dog',
config: {
taskType: 'SEMANTIC_SIMILARITY',
outputDimensionality: 768
}
});
console.log(response.embedding.values);
// [0.00388, -0.00762, 0.01543, ...]export default {
async fetch(request: Request, env: Env): Promise<Response> {
const apiKey = env.GEMINI_API_KEY;
const text = "What is the meaning of life?";
const response = await fetch(
'https://generativelanguage.googleapis.com/v1beta/models/gemini-embedding-001:embedContent',
{
method: 'POST',
headers: {
'x-goog-api-key': apiKey,
'Content-Type': 'application/json'
},
body: JSON.stringify({
content: {
parts: [{ text }]
},
taskType: 'RETRIEVAL_QUERY',
outputDimensionality: 768
})
}
);
const data = await response.json();
// Response format:
// {
// embedding: {
// values: [0.012, -0.034, ...]
// }
// }
return new Response(JSON.stringify(data), {
headers: { 'Content-Type': 'application/json' }
});
}
};export default {
async fetch(request: Request, env: Env): Promise<Response> {
const apiKey = env.GEMINI_API_KEY;
const text = "What is the meaning of life?";
const response = await fetch(
'https://generativelanguage.googleapis.com/v1beta/models/gemini-embedding-001:embedContent',
{
method: 'POST',
headers: {
'x-goog-api-key': apiKey,
'Content-Type': 'application/json'
},
body: JSON.stringify({
content: {
parts: [{ text }]
},
taskType: 'RETRIEVAL_QUERY',
outputDimensionality: 768
})
}
);
const data = await response.json();
// 响应格式:
// {
// embedding: {
// values: [0.012, -0.034, ...]
// }
// }
return new Response(JSON.stringify(data), {
headers: { 'Content-Type': 'application/json' }
});
}
};interface EmbeddingResponse {
embedding: {
values: number[];
};
}
const response: EmbeddingResponse = await ai.models.embedContent({
model: 'gemini-embedding-001',
content: 'Sample text',
config: { taskType: 'SEMANTIC_SIMILARITY', outputDimensionality: 768 }
});
const embedding: number[] = response.embedding.values;
const dimensions: number = embedding.length; // 768interface EmbeddingResponse {
embedding: {
values: number[];
};
}
const response: EmbeddingResponse = await ai.models.embedContent({
model: 'gemini-embedding-001',
content: 'Sample text',
config: { taskType: 'SEMANTIC_SIMILARITY', outputDimensionality: 768 }
});
const embedding: number[] = response.embedding.values;
const dimensions: number = embedding.length; // 768import { GoogleGenAI } from "@google/genai";
const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
const texts = [
"What is the meaning of life?",
"How does photosynthesis work?",
"Tell me about the history of the internet."
];
const response = await ai.models.embedContent({
model: 'gemini-embedding-001',
contents: texts, // Array of strings
config: {
taskType: 'RETRIEVAL_DOCUMENT',
outputDimensionality: 768
}
});
// Process each embedding
response.embeddings.forEach((embedding, index) => {
console.log(`Text ${index}: ${texts[index]}`);
console.log(`Embedding: ${embedding.values.slice(0, 5)}...`);
console.log(`Dimensions: ${embedding.values.length}`);
});import { GoogleGenAI } from "@google/genai";
const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
const texts = [
"What is the meaning of life?",
"How does photosynthesis work?",
"Tell me about the history of the internet."
];
const response = await ai.models.embedContent({
model: 'gemini-embedding-001',
contents: texts, // 字符串数组
config: {
taskType: 'RETRIEVAL_DOCUMENT',
outputDimensionality: 768
}
});
// 处理每个嵌入
response.embeddings.forEach((embedding, index) => {
console.log(`文本 ${index}: ${texts[index]}`);
console.log(`嵌入向量: ${embedding.values.slice(0, 5)}...`);
console.log(`维度: ${embedding.values.length}`);
});async function batchEmbedWithRateLimit(
texts: string[],
batchSize: number = 100, // Free tier: 100 RPM
delayMs: number = 60000 // 1 minute delay between batches
): Promise<number[][]> {
const allEmbeddings: number[][] = [];
for (let i = 0; i < texts.length; i += batchSize) {
const batch = texts.slice(i, i + batchSize);
console.log(`Processing batch ${i / batchSize + 1} (${batch.length} texts)`);
const response = await ai.models.embedContent({
model: 'gemini-embedding-001',
contents: batch,
config: {
taskType: 'RETRIEVAL_DOCUMENT',
outputDimensionality: 768
}
});
allEmbeddings.push(...response.embeddings.map(e => e.values));
// Wait before next batch (except last batch)
if (i + batchSize < texts.length) {
await new Promise(resolve => setTimeout(resolve, delayMs));
}
}
return allEmbeddings;
}
// Usage
const embeddings = await batchEmbedWithRateLimit(documents, 100);async function batchEmbedWithRateLimit(
texts: string[],
batchSize: number = 100, // 免费层: 100 RPM
delayMs: number = 60000 // 批次间延迟1分钟
): Promise<number[][]> {
const allEmbeddings: number[][] = [];
for (let i = 0; i < texts.length; i += batchSize) {
const batch = texts.slice(i, i + batchSize);
console.log(`处理批次 ${i / batchSize + 1} (${batch.length} 条文本)`);
const response = await ai.models.embedContent({
model: 'gemini-embedding-001',
contents: batch,
config: {
taskType: 'RETRIEVAL_DOCUMENT',
outputDimensionality: 768
}
});
allEmbeddings.push(...response.embeddings.map(e => e.values));
// 等待下一批次(最后一批次除外)
if (i + batchSize < texts.length) {
await new Promise(resolve => setTimeout(resolve, delayMs));
}
}
return allEmbeddings;
}
// 使用示例
const embeddings = await batchEmbedWithRateLimit(documents, 100);taskTypetaskType| Task Type | Use Case | Example |
|---|---|---|
| RETRIEVAL_QUERY | User search queries | "How do I fix a flat tire?" |
| RETRIEVAL_DOCUMENT | Documents to be indexed/searched | Product descriptions, articles |
| SEMANTIC_SIMILARITY | Comparing text similarity | Duplicate detection, clustering |
| CLASSIFICATION | Categorizing texts | Spam detection, sentiment analysis |
| CLUSTERING | Grouping similar texts | Topic modeling, content organization |
| CODE_RETRIEVAL_QUERY | Code search queries | "function to sort array" |
| QUESTION_ANSWERING | Questions seeking answers | FAQ matching |
| FACT_VERIFICATION | Verifying claims with evidence | Fact-checking systems |
| 任务类型 | 适用场景 | 示例 |
|---|---|---|
| RETRIEVAL_QUERY | 用户搜索查询 | "如何修补漏气的轮胎?" |
| RETRIEVAL_DOCUMENT | 待索引/搜索的文档 | 产品描述、文章 |
| SEMANTIC_SIMILARITY | 文本相似度对比 | 重复内容检测、聚类 |
| CLASSIFICATION | 文本分类 | 垃圾邮件检测、情感分析 |
| CLUSTERING | 相似文本分组 | 主题建模、内容分类 |
| CODE_RETRIEVAL_QUERY | 代码搜索查询 | "排序数组的函数" |
| QUESTION_ANSWERING | 寻求答案的问题 | FAQ匹配 |
| FACT_VERIFICATION | 用证据验证声明 | 事实核查系统 |
// When embedding user queries
const queryEmbedding = await ai.models.embedContent({
model: 'gemini-embedding-001',
content: userQuery,
config: {
taskType: 'RETRIEVAL_QUERY', // ← Use RETRIEVAL_QUERY
outputDimensionality: 768
}
});
// When embedding documents for indexing
const docEmbedding = await ai.models.embedContent({
model: 'gemini-embedding-001',
content: documentText,
config: {
taskType: 'RETRIEVAL_DOCUMENT', // ← Use RETRIEVAL_DOCUMENT
outputDimensionality: 768
}
});// 嵌入用户查询时
const queryEmbedding = await ai.models.embedContent({
model: 'gemini-embedding-001',
content: userQuery,
config: {
taskType: 'RETRIEVAL_QUERY', // ← 使用RETRIEVAL_QUERY
outputDimensionality: 768
}
});
// 嵌入待索引文档时
const docEmbedding = await ai.models.embedContent({
model: 'gemini-embedding-001',
content: documentText,
config: {
taskType: 'RETRIEVAL_DOCUMENT', // ← 使用RETRIEVAL_DOCUMENT
outputDimensionality: 768
}
});Vector dimensions do not match. Expected 768, got 3072outputDimensionality// ❌ BAD: No outputDimensionality (defaults to 3072)
const embedding = await ai.models.embedContent({
model: 'gemini-embedding-001',
content: text
});
// ✅ GOOD: Match Vectorize index dimensions
const embedding = await ai.models.embedContent({
model: 'gemini-embedding-001',
content: text,
config: { outputDimensionality: 768 } // ← Match your index
});Vector dimensions do not match. Expected 768, got 3072outputDimensionality// ❌ 错误:未指定outputDimensionality(默认3072)
const embedding = await ai.models.embedContent({
model: 'gemini-embedding-001',
content: text
});
// ✅ 正确:匹配Vectorize索引维度
const embedding = await ai.models.embedContent({
model: 'gemini-embedding-001',
content: text,
config: { outputDimensionality: 768 } // ← 与你的索引维度匹配
});429 Too Many Requests - Rate limit exceeded// ✅ GOOD: Exponential backoff
async function embedWithRetry(text: string, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
return await ai.models.embedContent({
model: 'gemini-embedding-001',
content: text,
config: { taskType: 'SEMANTIC_SIMILARITY', outputDimensionality: 768 }
});
} catch (error: any) {
if (error.status === 429 && attempt < maxRetries - 1) {
const delay = Math.pow(2, attempt) * 1000; // 1s, 2s, 4s
await new Promise(resolve => setTimeout(resolve, delay));
continue;
}
throw error;
}
}
}429 Too Many Requests - Rate limit exceeded// ✅ 正确:指数退避策略
async function embedWithRetry(text: string, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
return await ai.models.embedContent({
model: 'gemini-embedding-001',
content: text,
config: { taskType: 'SEMANTIC_SIMILARITY', outputDimensionality: 768 }
});
} catch (error: any) {
if (error.status === 429 && attempt < maxRetries - 1) {
const delay = Math.pow(2, attempt) * 1000; // 1秒、2秒、4秒
await new Promise(resolve => setTimeout(resolve, delay));
continue;
}
throw error;
}
}
}function chunkText(text: string, maxTokens = 2000): string[] {
const words = text.split(/\s+/);
const chunks: string[] = [];
let currentChunk: string[] = [];
for (const word of words) {
currentChunk.push(word);
// Rough estimate: 1 token ≈ 0.75 words
if (currentChunk.length * 0.75 >= maxTokens) {
chunks.push(currentChunk.join(' '));
currentChunk = [];
}
}
if (currentChunk.length > 0) {
chunks.push(currentChunk.join(' '));
}
return chunks;
}function chunkText(text: string, maxTokens = 2000): string[] {
const words = text.split(/\s+/);
const chunks: string[] = [];
let currentChunk: string[] = [];
for (const word of words) {
currentChunk.push(word);
// 粗略估算:1个令牌≈0.75个单词
if (currentChunk.length * 0.75 >= maxTokens) {
chunks.push(currentChunk.join(' '));
currentChunk = [];
}
}
if (currentChunk.length > 0) {
chunks.push(currentChunk.join(' '));
}
return chunks;
}RETRIEVAL_DOCUMENT// ❌ BAD: Wrong task type for RAG query
const queryEmbedding = await ai.models.embedContent({
model: 'gemini-embedding-001',
content: userQuery,
config: { taskType: 'RETRIEVAL_DOCUMENT' } // ← Wrong!
});
// ✅ GOOD: Correct task types
const queryEmbedding = await ai.models.embedContent({
model: 'gemini-embedding-001',
content: userQuery,
config: { taskType: 'RETRIEVAL_QUERY', outputDimensionality: 768 }
});RETRIEVAL_DOCUMENT// ❌ 错误:RAG查询使用错误的任务类型
const queryEmbedding = await ai.models.embedContent({
model: 'gemini-embedding-001',
content: userQuery,
config: { taskType: 'RETRIEVAL_DOCUMENT' } // ← 错误!
});
// ✅ 正确:使用正确的任务类型
const queryEmbedding = await ai.models.embedContent({
model: 'gemini-embedding-001',
content: userQuery,
config: { taskType: 'RETRIEVAL_QUERY', outputDimensionality: 768 }
});Similarity values out of range (-1.5 to 1.2)// ✅ GOOD: Proper cosine similarity
function cosineSimilarity(a: number[], b: number[]): number {
if (a.length !== b.length) {
throw new Error('Vector dimensions must match');
}
let dotProduct = 0;
let magnitudeA = 0;
let magnitudeB = 0;
for (let i = 0; i < a.length; i++) {
dotProduct += a[i] * b[i];
magnitudeA += a[i] * a[i];
magnitudeB += b[i] * b[i];
}
if (magnitudeA === 0 || magnitudeB === 0) {
return 0; // Handle zero vectors
}
return dotProduct / (Math.sqrt(magnitudeA) * Math.sqrt(magnitudeB));
}references/top-errors.mdSimilarity values out of range (-1.5 to 1.2)// ✅ 正确:标准余弦相似度计算
function cosineSimilarity(a: number[], b: number[]): number {
if (a.length !== b.length) {
throw new Error('向量维度必须匹配');
}
let dotProduct = 0;
let magnitudeA = 0;
let magnitudeB = 0;
for (let i = 0; i < a.length; i++) {
dotProduct += a[i] * b[i];
magnitudeA += a[i] * a[i];
magnitudeB += b[i] * b[i];
}
if (magnitudeA === 0 || magnitudeB === 0) {
return 0; // 处理零向量
}
return dotProduct / (Math.sqrt(magnitudeA) * Math.sqrt(magnitudeB));
}references/top-errors.mdconst embedding = await ai.models.embedContent({
model: 'gemini-embedding-001',
content: text,
config: { taskType: 'RETRIEVAL_QUERY' } // ← Always specify
});const embedding = await ai.models.embedContent({
model: 'gemini-embedding-001',
content: text,
config: { outputDimensionality: 768 } // ← Match index
});// Use exponential backoff for 429 errors (see Error 2)const cache = new Map<string, number[]>();
async function getCachedEmbedding(text: string): Promise<number[]> {
if (cache.has(text)) {
return cache.get(text)!;
}
const response = await ai.models.embedContent({
model: 'gemini-embedding-001',
content: text,
config: { taskType: 'SEMANTIC_SIMILARITY', outputDimensionality: 768 }
});
const embedding = response.embedding.values;
cache.set(text, embedding);
return embedding;
}// Single batch request vs multiple individual requests
const embeddings = await ai.models.embedContent({
model: 'gemini-embedding-001',
contents: texts, // Array of texts
config: { taskType: 'RETRIEVAL_DOCUMENT', outputDimensionality: 768 }
});const embedding = await ai.models.embedContent({
model: 'gemini-embedding-001',
content: text,
config: { taskType: 'RETRIEVAL_QUERY' } // ← 始终指定
});const embedding = await ai.models.embedContent({
model: 'gemini-embedding-001',
content: text,
config: { outputDimensionality: 768 } // ← 与索引维度匹配
});// 针对429错误使用指数退避策略(参见错误2)const cache = new Map<string, number[]>();
async function getCachedEmbedding(text: string): Promise<number[]> {
if (cache.has(text)) {
return cache.get(text)!;
}
const response = await ai.models.embedContent({
model: 'gemini-embedding-001',
content: text,
config: { taskType: 'SEMANTIC_SIMILARITY', outputDimensionality: 768 }
});
const embedding = response.embedding.values;
cache.set(text, embedding);
return embedding;
}// 单批次请求 vs 多个单独请求
const embeddings = await ai.models.embedContent({
model: 'gemini-embedding-001',
contents: texts, // 文本数组
config: { taskType: 'RETRIEVAL_DOCUMENT', outputDimensionality: 768 }
});references/rag-patterns.mdreferences/rag-patterns.mdreferences/vectorize-integration.mdreferences/vectorize-integration.mdreferences/dimension-guide.mdreferences/dimension-guide.mdreferences/model-comparison.mdreferences/model-comparison.mdreferences/top-errors.mdreferences/top-errors.mdpackage.jsonbasic-embeddings.tsembeddings-fetch.tsbatch-embeddings.tsrag-with-vectorize.tssemantic-search.tsclustering.tspackage.jsonbasic-embeddings.tsembeddings-fetch.tsbatch-embeddings.tsrag-with-vectorize.tssemantic-search.tsclustering.tsmodel-comparison.mdvectorize-integration.mdrag-patterns.mddimension-guide.mdtop-errors.mdmodel-comparison.mdvectorize-integration.mdrag-patterns.mddimension-guide.mdtop-errors.mdcheck-versions.shcheck-versions.sh/websites/ai_google_dev_gemini-api/websites/ai_google_dev_gemini-api