embedding-strategies – Other skill for AI agents
Guide to selecting and optimizing embedding models for vector search applications.
Install the embedding-strategies skill with one command
Pick the tool you use, copy the command and paste it in your terminal. The skill lands in that tool's skills folder and is ready in your next session.
Claude Code
mkdir -p ~/.claude/skills && curl -fsSL https://skill.dn1nguoi.com/z/embedding-strategies-5632e.tgz | tar xz -C ~/.claude/skills
Call it in Claude Code: /embedding-strategies – then describe the task you want done.
Codex
mkdir -p ~/.codex/skills && curl -fsSL https://skill.dn1nguoi.com/z/embedding-strategies-5632e.tgz | tar xz -C ~/.codex/skills
Call it in Codex: $embedding-strategies – then describe the task you want done.
Hermes Agent
mkdir -p ~/.hermes/skills && curl -fsSL https://skill.dn1nguoi.com/z/embedding-strategies-5632e.tgz | tar xz -C ~/.hermes/skills
Call it in Hermes Agent: /embedding-strategies – then describe the task you want done.
DeepSeek
mkdir -p ~/.deepcode/skills && curl -fsSL https://skill.dn1nguoi.com/z/embedding-strategies-5632e.tgz | tar xz -C ~/.deepcode/skills
Call it in DeepSeek: /embedding-strategies – then describe the task you want done.
SKILL.md content
Embedding Strategies
Guide to selecting and optimizing embedding models for vector search applications.
Do not use this skill when
- The task is unrelated to embedding strategies
- You need a different domain or tool outside this scope
Instructions
- Clarify goals, constraints, and required inputs.
- Apply relevant best practices and validate outcomes.
- Provide actionable steps and verification.
- If detailed examples are required, open
resources/implementation-playbook.md.
Use this skill when
- Choosing embedding models for RAG
- Optimizing chunking strategies
- Fine-tuning embeddings for domains
- Comparing embedding model performance
- Reducing embedding dimensions
- Handling multilingual content
Core Concepts
Model table is a historical candidate list, not a current leaderboard. Verify exact model-card token limits, dimensions, license, revision and query/document prefixes before use; count tokens with that model’s tokenizer. Approve private-document transfer/provider cost. Preserve original text and source offsets; stripping symbols can destroy code, monetary signs, equations and identifiers.
1. Embedding Model Comparison
| Model | Dimensions | Max Tokens | Best For |
|-------|------------|------------|----------|
| text-embedding-3-large | 3072 | 8191 | High accuracy |
| text-embedding-3-small | 1536 | 8191 | Cost-effective |
| voyage-2 | 1024 | 4000 | Code, legal |
| bge-large-en-v1.5 | 1024 | 512 | Open source |
| all-MiniLM-L6-v2 | 384 | 256 | Fast, lightweight |
| multilingual-e5-large | 1024 | 512 | Multi-language |
2. Embedding Pipeline
Document → Chunking → Preprocessing → Embedding Model → Vector
↓
[Overlap, Size] [Clean, Normalize] [API/Local]Templates
Template 1: OpenAI Embeddings
from openai import OpenAI
from typing import List
import numpy as np
client = OpenAI()
def get_embeddings(
texts: List[str],
model: str = "text-embedding-3-small",
dimensions: int = None
) -> List[List[float]]:
"""Get embeddings from OpenAI."""
# Handle batching for large lists
batch_size = 100
all_embeddings = []
for i in range(0, len(texts), batch_size):
batch = texts[i:i + batch_size]
kwargs = {"input": batch, "model": model}
if dimensions:
kwargs["dimensions"] = dimensions
response = client.embeddings.create(**kwargs)
embeddings = [item.embedding for item in response.data]
all_embeddings.extend(embeddings)
return all_embeddings
def get_embedding(text: str, **kwargs) -> List[float]:
"""Get single embedding."""
return get_embeddings([text], **kwargs)[0]
# Dimension reduction with OpenAI
def get_reduced_embedding(text: str, dimensions: int = 512) -> List[float]:
"""Get embedding with reduced dimensions (Matryoshka)."""
return get_embedding(
text,
model="text-embedding-3-small",
dimensions=dimensions
)Template 2: Local Embeddings with Sentence Transformers
from sentence_transformers import SentenceTransformer
from typing import List, Optional
import numpy as np
class LocalEmbedder:
"""Local embedding with sentence-transformers."""
def __init__(
self,
model_name: str = "BAAI/bge-large-en-v1.5",
device: str = "cpu",
query_prefix: str = ""
):
self.model = SentenceTransformer(model_name, device=device)
self.query_prefix = query_prefix # Choose from the selected model card.
def embed(
self,
texts: List[str],
normalize: bool = True,
show_progress: bool = False
) -> np.ndarray:
"""Embed texts with optional normalization."""
embeddings = self.model.encode(
texts,
normalize_embeddings=normalize,
show_progress_bar=show_progress,
convert_to_numpy=True
)
return embeddings
def embed_query(self, query: str) -> np.ndarray:
"""Embed a query with the explicitly configured model prefix."""
return self.embed([self.query_prefix + query])[0]
def embed_documents(self, documents: List[str]) -> np.ndarray:
"""Embed documents for indexing."""
return self.embed(documents)
# E5 model with instructions
class E5Embedder:
def __init__(self, model_name: str = "intfloat/multilingual-e5-large"):
self.model = SentenceTransformer(model_name)
def embed_query(self, query: str) -> np.ndarray:
return self.model.encode(f"query: {query}")
def embed_document(self, document: str) -> np.ndarray:
return self.model.encode(f"passage: {document}")Template 3: Chunking Strategies
from typing import List, Tuple
import re
def chunk_by_tokens(
text: str,
chunk_size: int = 512,
chunk_overlap: int = 50,
tokenizer=None
) -> List[str]:
"""Chunk text by token count."""
if not isinstance(chunk_size, int) or not isinstance(chunk_overlap, int):
raise ValueError("chunk size and overlap must be integers")
if chunk_size <= 0 or not 0 <= chunk_overlap < chunk_size:
raise ValueError("require chunk_size > 0 and 0 <= overlap < chunk_size")
if tokenizer is None:
import tiktoken
tokenizer = tiktoken.get_encoding("cl100k_base")
tokens = tokenizer.encode(text)
chunks = []
start = 0
while start < len(tokens):
end = start + chunk_size
chunk_tokens = tokens[start:end]
chunk_text = tokenizer.decode(chunk_tokens)
chunks.append(chunk_text)
if end >= len(tokens):
break
start = end - chunk_overlap
return chunks
def chunk_by_sentences(
text: str,
max_chunk_size: int = 1000,
min_chunk_size: int = 100
) -> List[str]:
"""Group sentences by approximate character length, not tokenizer length.
min_chunk_size is not enforced; oversized individual sentences require a
second token-bounded splitting pass before embedding. NLTK resources must
already be installed; no implicit network download is supplied here.
"""
import nltk
sentences = nltk.sent_tokenize(text)
chunks = []
current_chunk = []
current_size = 0
for sentence in sentences:
sentence_size = len(sentence)
if current_size + sentence_size > max_chunk_size and current_chunk:
chunks.append(" ".join(current_chunk))
current_chunk = []
current_size = 0
current_chunk.append(sentence)
current_size += sentence_size
if current_chunk:
chunks.append(" ".join(current_chunk))
return chunks
def chunk_by_semantic_sections(
text: str,
headers_pattern: str = r'^#{1,3}\s+.+$'
) -> List[Tuple[str, str]]:
"""Chunk markdown by headers, preserving hierarchy."""
lines = text.split('\n')
chunks = []
current_header = ""
current_content = []
for line in lines:
if re.match(headers_pattern, line, re.MULTILINE):
if current_content:
chunks.append((current_header, '\n'.join(current_content)))
current_header = line
current_content = []
else:
current_content.append(line)
if current_content:
chunks.append((current_header, '\n'.join(current_content)))
return chunks
def recursive_character_splitter(
text: str,
chunk_size: int = 1000,
chunk_overlap: int = 200,
separators: List[str] = None
) -> List[str]:
"""Bounded character chunks, preferring a separator inside each window."""
if chunk_size <= 0 or not 0 <= chunk_overlap < chunk_size:
raise ValueError("require chunk_size > 0 and 0 <= overlap < chunk_size")
separators = separators or ["\n\n", "\n", ". ", " "]
chunks = []
start = 0
while start < len(text):
end = min(start + chunk_size, len(text))
if end < len(text):
for separator in separators:
if not separator:
continue
boundary = text.rfind(separator, start + chunk_overlap + 1, end)
if boundary >= 0:
end = boundary + len(separator)
break
chunks.append(text[start:end])
if end == len(text):
break
start = end - chunk_overlap
return chunksTemplate 4: Domain-Specific Embedding Pipeline
class DomainEmbeddingPipeline:
"""Pipeline for domain-specific embeddings."""
def __init__(
self,
embedding_model: str = "text-embedding-3-small",
chunk_size: int = 512,
chunk_overlap: int = 50,
preprocessing_fn=None
):
self.embedding_model = embedding_model
self.chunk_size = chunk_size
self.chunk_overlap = chunk_overlap
self.preprocess = preprocessing_fn or self._default_preprocess
def _default_preprocess(self… (full content is in the download package)
Related skills
- umap-learn – Applies UMAP-learn to nonlinear dimensionality reduction, 2D/3D embeddings, clustering…
- emergency-card – 生成紧急情况下快速访问的医疗信息摘要卡片。当用户需要旅行、就诊准备、紧急情况或询问"紧急信息"、"医疗卡片"、"急救信息"时使用此技能。提取关键信息(过敏、用药、急症、植入物),…
- employee-suggestion-hub – Suggestion register: submitter or anonymous flag, category, votes, reviewer, decision…
- energy-procurement – Codified expertise for electricity and gas procurement, tariff optimisation, demand…
- enterprise-vpn-attack – External SSL VPN / remote-access appliance attack matrix
- entropy-box – Entropy Box knowledge-compiler for embodied-AI: turns bounded requirements into grounded…
- environment-setup-guide – Guide developers through setting up development environments with proper tools…
- eol-resistor-calculator – Calculates and validates end-of-line (EOL, SEOL, DEOL, TEOL) resistor loops for…