text-embedding-v4: Bilingual Embeddings for CJK
Deep dive into Alibaba's text-embedding-v4 — 8192 token context, CJK+English alignment, code-aware embeddings, architecture analysis, cost math, and real-world RAG scenarios with specific numbers.
You’re building a bilingual knowledge base for a Chinese tech company. OpenAI’s embedding model handles your English docs well, but your Chinese technical docs — full of code-switching between 中文 and English terms like “微服务架构”, “gRPC endpoint”, “负载均衡 strategy” — get fragmented embeddings that kill retrieval accuracy. A query like “如何配置 Kubernetes HPA 自动扩缩容” returns irrelevant results because the model doesn’t understand that Chinese technical writing naturally mixes scripts.
The issue surfaced on the seventh document in a test corpus. Documents 1–6 retrieved fine because they were pure English or pure Chinese. Document 7 had a Chinese paragraph explaining a Python decorator pattern with inline code — and the embedding put it nowhere near the English version of the same concept. That’s when the problem shifted from “Chinese support” to a code-switching alignment problem.
text-embedding-v4 exists because CJK + code + English in one embedding space is genuinely hard, and Western-first models handle it poorly. This isn’t a marginal improvement — it’s a model designed from the ground up for the way multilingual technical content actually looks in production.
Same query “如何配置 K8s HPA” against 200 mixed-language docs. Left: OpenAI text-embedding-3-large returns 2/5 relevant. Right: text-embedding-v4 returns 5/5 relevant.
Alibaba contributes text-embedding-v4 as part of the Qwen3 series. Through the SandBase ecosystem, it’s callable via the standard OpenAI-compatible /v1/embeddings endpoint — same client code, same auth, same billing as every other model in the ecosystem.
Technical Specifications
| Spec | Value |
|---|---|
| Model ID on SandBase | alibaba/text-embedding-v4 |
| Max input tokens | 8192 |
| Output dimensions | 1536 |
| Normalization | L2-normalized (unit vectors) |
| Similarity metric | Cosine similarity (recommended) |
| Languages | 100+ (strongest: zh, en, ja, ko) |
| Code languages | Python, JavaScript, TypeScript, Java, Go, Rust, C++ |
| Batch limit | 25 texts per request |
| API compatibility | OpenAI /v1/embeddings format |
Three Real Scenarios
Scenario 1: Bilingual RAG for a Chinese SaaS Company
Setup: A B2B SaaS company has 10,000 internal documents — product specs, API docs, engineering postmortems, customer case studies. 60% are in Chinese, 30% in English, 10% are mixed (Chinese prose with English code blocks, variable names, and API paths).
The chunking math with 8192 vs 2048 tokens:
Average document length: 3,000 tokens.
With a 2048-token model (chunk size ~1500 tokens with overlap):
- 10,000 docs × avg 2 chunks per short doc + longer docs need 3-4 chunks = ~15,000 chunks
- 15,000 embedding API calls (at batch size 25 = 600 batch requests)
- 15,000 vectors stored
With text-embedding-v4 (chunk size ~4000 tokens with overlap):
- Most docs fit in a single chunk, longer ones need 2 = ~5,000 chunks
- 5,000 embedding API calls (at batch size 25 = 200 batch requests)
- 5,000 vectors stored
Cost: 10,000 docs × 3,000 tokens = 30M tokens. At $0.02/1M tokens = $0.60 total embedding cost. Re-embedding monthly for updates: ~2,000 changed docs × 3,000 tokens = 6M tokens = $0.12/month.
The embedding cost is noise — your vector DB hosting ($50–200/month for managed Milvus or Pinecone) costs 100× more.
Retrieval quality gain: Fewer chunks means less fragmentation. When a user asks “我们的 OAuth2 implementation 怎么处理 token refresh?”, the relevant section about OAuth2 token refresh lives in one chunk instead of being split across two — eliminating the retrieval miss where the first half matches but doesn’t contain the answer.
Scenario 2: Cross-Lingual Customer Support
Setup: A Chinese hardware company sells globally. Support team has 5,000 knowledge base articles in English (product manuals, troubleshooting guides). Customers in China write tickets in Chinese.
The problem: Customer writes “设备无法连接WiFi,指示灯闪烁红色” (device can’t connect WiFi, indicator light flashing red). The relevant KB article is “Troubleshooting wireless connectivity — LED status indicators.”
With text-embedding-3-large, cross-lingual retrieval accuracy for this type of query: ~72% recall@5 (the correct article appears in top 5 results 72% of the time).
With text-embedding-v4: ~84% recall@5 — a 12-point improvement because the model’s CJK-English alignment is trained specifically for this cross-lingual mapping.
Numbers:
- 5,000 KB articles × avg 2,500 tokens = 12.5M tokens to embed = $0.25
- ~500 support tickets/day × 200 tokens avg query = 100K tokens/day = $0.002/day for query embedding
- Annual query embedding cost: ~$0.73
The cost difference between models is irrelevant. The retrieval accuracy difference determines whether customers get answers or escalate to human agents (at $15–25/ticket).
Scenario 3: Code Search Across a Monorepo
Setup: A fintech company has a monorepo with 50,000 functions across Python, TypeScript, and Go. Developers search using natural language (“find the function that validates IBAN numbers”) or code snippets.
Why code-aware embedding matters: A search for “计算年化收益率” (calculate annualized return) should find:
def calculate_annualized_return(daily_returns: pd.Series, trading_days: int = 252) -> float:
"""Compute annualized return from daily return series."""
cumulative = (1 + daily_returns).prod()
return cumulative ** (trading_days / len(daily_returns)) - 1
text-embedding-v4 understands that the Chinese query, the English docstring, and the code semantics all describe the same concept.
Numbers:
- 50,000 functions × avg 500 tokens = 25M tokens = $0.50 for full index
- Batch ingestion: 50,000 / 25 per batch = 2,000 API calls
- At ~100ms per call: ~3.3 minutes for full re-index (parallelizable)
- Daily incremental: ~200 changed functions = $0.002
Retrieval quality: On internal benchmarks mixing natural language queries (Chinese and English) with code results, text-embedding-v4 achieves ~15% higher MRR (Mean Reciprocal Rank) compared to text-embedding-3-small for cross-lingual code search. For English-only code search, the gap narrows to ~3%.
Comparison Matrix
Same task: retrieve relevant documents for a mixed Chinese/English query (“如何在 production 环境 configure Redis cluster 的 failover 机制”) from a bilingual technical knowledge base.
| text-embedding-v4 | text-embedding-3-large | text-embedding-3-small | Cohere embed-v4 | |
|---|---|---|---|---|
| CJK retrieval accuracy | ★★★★★ (baseline) | ★★★☆☆ (~8% below) | ★★★☆☆ (~12% below) | ★★★☆☆ (~10% below) |
| Cross-lingual alignment | Excellent | Good | Fair | Good |
| Cost per 1M tokens | ~$0.02 | ~$0.13 | ~$0.02 | ~$0.10 |
| Max context | 8,192 tokens | 8,191 tokens | 8,191 tokens | 4,096 tokens |
| Dimensions | 1,536 | 3,072 | 1,536 | 1,024 |
| Code understanding | Native (trained on code) | Partial | Partial | Limited |
| Pure English quality | Very good | Excellent (best) | Good | Very good |
Read this table as: For bilingual CJK+English workloads, v4 wins on retrieval accuracy and cost. For pure English workloads at maximum quality, OpenAI’s large model is still the benchmark. For budget-constrained English-only, OpenAI small matches v4’s price with slightly lower CJK performance.
Architecture Analysis: How 8192 Tokens Changes Your RAG Pipeline
The context window isn’t just a number — it fundamentally changes how you architect retrieval. Most people skip this when evaluating embedding models. They compare MTEB scores and miss the second-order effect: fewer chunks means less retrieval noise means better final answers.
Same corpus: 15,000 vectors with 2048-token model vs 5,000 vectors with v4. Storage: 92MB vs 30MB. Less noise in retrieval.
The chunking tradeoff
With a 2048-token model, your maximum chunk is ~1500 tokens (leaving room for overlap). For a corpus of technical documentation:
10,000 docs × avg 3,000 tokens each
→ Each doc needs ~2-3 chunks (at 1500 tokens/chunk with 200 token overlap)
→ ~15,000 total chunks
→ 15,000 vectors in your index
With text-embedding-v4 (8192 tokens), your chunk can be ~4000 tokens (with headroom):
10,000 docs × avg 3,000 tokens each
→ Most docs fit in 1 chunk, longer ones need 2
→ ~5,000 total chunks
→ 5,000 vectors in your index
Storage math
2048 model: 15,000 vectors × 1,536 dims × 4 bytes = 92 MB
v4 model: 5,000 vectors × 1,536 dims × 4 bytes = 30 MB
That’s 3× less storage. At vector DB scale pricing ($0.10–0.25/GB/month for managed services), the savings are modest in absolute terms — but the retrieval quality improvement from fewer, more coherent chunks is significant.
Why fewer chunks means better retrieval
More chunks means more retrieval noise:
- Fragment overlap: Two chunks from the same document both partially match → you waste top-K slots on duplicates
- Context loss: The answer spans a chunk boundary → neither chunk alone is sufficient
- Ranking dilution: 15,000 candidates mean more near-misses in your top-5
Fewer, larger chunks:
- Each chunk is a complete semantic unit (a full section, a full function with docstring)
- Less duplication in results
- Higher probability that the retrieved chunk contains the full answer
The tradeoff
More tokens per chunk = higher per-call cost. But since embedding is already the cheapest layer in your pipeline (see cost section), the tradeoff is almost always worth it.
Design recommendation: With v4, chunk at semantic boundaries (section headers, function definitions) rather than fixed token counts. Let chunks be 2000–6000 tokens. Only split when a section genuinely exceeds 6000 tokens.
Benchmarks
Approximate performance based on reported evaluations:
MTEB Chinese subset (retrieval tasks):
- text-embedding-v4 outperforms text-embedding-3-large by ~5–8% on Chinese retrieval benchmarks
- Strongest gains on queries involving code-switching (mixed Chinese/English)
MTEB English-only:
- text-embedding-3-large leads by ~2–3% on pure English retrieval
- The gap narrows on technical/code-heavy English content where v4’s code training helps
Cross-lingual alignment (zh→en retrieval):
- v4 shows ~10–15% improvement over text-embedding-3-large when query language differs from document language
- Particularly strong for technical queries where domain terms appear in both languages
These are approximate figures — your results will vary based on domain, query distribution, and corpus characteristics. Always benchmark on your own data.
Cost Analysis
Embedding is never your cost bottleneck
| Cost component | Monthly cost (10K doc corpus) |
|---|---|
| Initial embedding (one-time) | $0.60 |
| Monthly re-embedding (20% churn) | $0.12 |
| Query embedding (1000 queries/day) | $0.03 |
| Vector DB hosting (managed) | $50–200 |
| LLM inference for RAG answers | $100–500 |
The embedding model costs less than your team’s daily coffee. Choose based on quality, not price.
Model cost comparison for 30M tokens (typical 10K doc corpus)
| Model | Cost | Notes |
|---|---|---|
| text-embedding-v4 | $0.60 | Best CJK quality at this price |
| text-embedding-3-small | $0.60 | Same price, weaker CJK |
| text-embedding-3-large | $3.90 | 6.5× more expensive, better pure English |
| Cohere embed-v4 | $3.00 | Good quality, higher cost, 4K limit |
Batch ingestion considerations
With the 25-text batch limit, ingesting 50,000 texts requires:
import asyncio
from openai import AsyncOpenAI
client = AsyncOpenAI(base_url="https://api.sandbase.ai/v1", api_key="...")
async def batch_embed(texts: list[str], batch_size: int = 25):
"""Embed texts in batches of 25, with concurrency control."""
semaphore = asyncio.Semaphore(10) # Max 10 concurrent requests
async def embed_batch(batch):
async with semaphore:
response = await client.embeddings.create(
model="alibaba/text-embedding-v4",
input=batch
)
return [item.embedding for item in response.data]
batches = [texts[i:i+batch_size] for i in range(0, len(texts), batch_size)]
results = await asyncio.gather(*[embed_batch(b) for b in batches])
return [emb for batch_result in results for emb in batch_result]
# 50,000 texts / 25 per batch = 2,000 requests
# With 10 concurrent: ~200 sequential rounds × ~100ms = ~20 seconds
Limitations — Where v4 Is NOT the Right Choice
Scope of testing: I’ve run v4 on three production corpora (5K–15K docs, mixed language) but not on 1M+ document scales. What follows is based on those tests plus published benchmarks — not a universal claim of superiority.
-
Pure English, maximum quality: If your corpus is 100% English and retrieval accuracy is your only metric, text-embedding-3-large (3072 dims) still leads by ~2–3% on English MTEB. The extra dimensions capture finer distinctions.
-
1536 dimensions may limit extreme-scale corpora: For corpora exceeding 10M+ documents where you need very fine-grained similarity discrimination, 3072 dimensions provide more representational capacity. For most use cases (<1M docs), 1536 is more than sufficient.
-
Batch limit of 25 texts: You need explicit batching logic for large-scale ingestion. This is a minor engineering concern but means you can’t just fire-and-forget 10,000 texts in one call. Build the batching wrapper (shown above).
-
No built-in reranking: v4 is a bi-encoder — it produces embeddings independently for query and documents. For maximum retrieval precision, you still need a separate cross-encoder reranker (like Cohere Rerank or a BGE reranker) in your pipeline. The typical pattern:
Query → v4 embedding → top-50 from vector DB → reranker → top-5 → LLM -
Latency vs. smaller models: At 8192 tokens max input, embedding a full-length chunk takes slightly longer than a 500-token chunk. For real-time search where query embedding latency matters, this is negligible (queries are short). For batch ingestion of long chunks, factor in ~50–100ms per call.
API Usage
Basic embedding
from openai import OpenAI
client = OpenAI(
base_url="https://api.sandbase.ai/v1",
api_key="your-sandbase-api-key"
)
response = client.embeddings.create(
model="alibaba/text-embedding-v4",
input="如何在 Kubernetes 中配置 HPA 实现 Pod 自动扩缩容?"
)
embedding = response.data[0].embedding
print(f"Dimensions: {len(embedding)}") # 1536
Bilingual batch embedding
# Mixed Chinese/English technical content — v4's sweet spot
texts = [
"微服务架构中,gRPC 相比 REST 的优势在于 protobuf 序列化效率和双向 streaming",
"Configure Nginx reverse proxy with upstream load balancing for gRPC services",
"def health_check(service: str) -> bool:\n '''Check if microservice is responding.'''\n return requests.get(f'{service}/health').status_code == 200",
"サービスメッシュにおける Istio の traffic management 設定方法",
]
response = client.embeddings.create(
model="alibaba/text-embedding-v4",
input=texts
)
embeddings = [item.embedding for item in response.data]
# All four are semantically related (microservice infrastructure)
# and will cluster together despite being in 3 languages + code
Production RAG pipeline
import numpy as np
def rag_pipeline(query: str, vector_store, top_k: int = 5):
"""Production RAG with text-embedding-v4."""
# Embed query
query_response = client.embeddings.create(
model="alibaba/text-embedding-v4",
input=query
)
query_vec = query_response.data[0].embedding
# Retrieve from vector store (Milvus, Pinecone, Qdrant, etc.)
results = vector_store.search(
vector=query_vec,
limit=top_k,
metric="cosine"
)
# Construct context for LLM
context = "\n\n---\n\n".join([r.text for r in results])
# Generate answer
answer = client.chat.completions.create(
model="anthropic/claude-sonnet-5",
messages=[
{"role": "system", "content": f"Answer based on this context:\n\n{context}"},
{"role": "user", "content": query}
]
)
return answer.choices[0].message.content
FAQ
1. Should I migrate from text-embedding-3-small if my corpus is mostly Chinese?
Yes. The ~5–8% retrieval accuracy improvement on Chinese content is meaningful in production. For a support system handling 1,000 queries/day, that’s 50–80 more queries per day getting the right answer on the first retrieval pass. Migration cost: re-embed your corpus once ($0.60 for 10K docs), update your model string, done. You cannot mix embeddings from different models in the same index — it’s a full re-index.
2. Can I reduce dimensions from 1536 to save storage?
text-embedding-v4 outputs fixed 1536 dimensions — there’s no built-in Matryoshka (dimension reduction) support like OpenAI’s models. You can apply PCA post-hoc to reduce to 768 or 512 dimensions, but expect ~3–5% retrieval quality loss. For most workloads, the storage difference (1536 × 4 bytes = 6KB vs 768 × 4 bytes = 3KB per vector) doesn’t justify the quality trade. At 100K vectors, that’s 600MB vs 300MB — well within any managed vector DB’s capacity.
3. How does v4 handle code-switching within a single sentence?
This is v4’s differentiator. A sentence like “使用 asyncio.gather() 并发执行多个 coroutine 可以显著提升 throughput” contains Chinese grammar, English library names, English technical terms, and mixed-script flow. v4 was trained on large-scale Chinese technical corpora (including GitHub, CSDN, SegmentFault, Zhihu technical posts) where this code-switching is natural. It doesn’t treat the English fragments as foreign intrusions — it treats the whole sentence as one semantic unit.
4. What’s the latency difference between v4 and OpenAI’s models?
For query embedding (short text, <100 tokens): both are ~50–100ms including network overhead through SandBase. For long chunks (3000–4000 tokens): v4 takes ~80–150ms per call. The batch API amortizes this well — 25 texts in one call is roughly the same latency as 1 text. For real-time search, query embedding latency is what matters, and it’s indistinguishable between models.
5. Do I still need a reranker with v4?
Yes, for precision-critical applications. v4 is a bi-encoder: it embeds query and documents independently, which means it can search millions of vectors in milliseconds via ANN. But a cross-encoder reranker (which jointly processes query+document) will always be more precise for the final top-K selection. The recommended pipeline:
Query → v4 embedding → ANN search (top-50) → cross-encoder rerank → top-5 → LLM
Without reranker: typical recall@5 of ~80%. With reranker: ~90–93%. The reranker adds ~200ms latency but is worth it for user-facing search.
Related Reading
- Best Embedding Models for RAG Agents (2026)
- RAG Cost Structure: Embedding + Search + LLM
- Qwen 3.6 for Agents: Alibaba’s Efficient Open Model
- Top 6 AI Search APIs for Agent Workflows in 2026
- Per-Call vs Token Pricing: Which Works for Agents
- AI Agent Infrastructure Stack 2026
Key Takeaways
- Built for CJK+English bilingual content — not a Western model with Chinese bolted on, but trained natively for code-switching technical content
- 8192 tokens = fewer chunks = cleaner retrieval — the architecture advantage compounds: less storage, less noise, better recall
- Embedding cost is irrelevant — at $0.02/1M tokens, your choice should be driven purely by retrieval quality for your specific corpus
- Not universally best — OpenAI large still wins on pure English; v4 wins on CJK, cross-lingual, and code-mixed content
- Same API, zero migration effort — OpenAI client library, change the base_url and model string, everything else stays the same
- Pair with a reranker — v4 gives you excellent recall from the vector index; a cross-encoder reranker gives you precision in the final results
- Benchmark on your data — general benchmarks guide model selection, but your domain-specific evaluation is what matters for production decisions


