GLM 5.2 Embeddings: Generate Text Vectors with the Zhipu API

GLM 5.2 Embeddings: Generate Text Vectors with the Zhipu API

Learn how to use Zhipu AI's embedding models alongside GLM 5.2 for RAG, semantic search, and vector database workflows — with Python code examples.

If you are building a retrieval-augmented generation (RAG) system or a semantic search feature with GLM 5.2, one question comes up almost immediately: does GLM 5.2 itself generate text embeddings, or do I need a separate model?

The short answer is that GLM 5.2 (model name: glm-4-plus) is a text generation model, not an embedding model. However, Zhipu AI — the company behind GLM 5.2 — also offers two dedicated embedding models on the same API platform: embedding-2 and embedding-3. They share the same API key and base URL, so you can build a fully integrated pipeline with a single account and a single client configuration.

This tutorial walks you through everything you need: how the embedding models differ, when to use each, and how to wire them together with GLM 5.2 in a working RAG pipeline using the OpenAI Python SDK.


The Pain Point: GLM 5.2 Does Not Produce Embeddings

Many developers discover GLM 5.2's impressive benchmark scores — 89% on GPQA Diamond, 62.1% on SWE-bench Pro, a 1-million-token context window — and assume it handles the full RAG stack end-to-end. It does not, and that is by design. Large language models that are optimized for generation are trained differently from models that are optimized to produce dense vector representations of text.

If you send a standard embeddings request to the glm-4-plus endpoint, the API will return an error. The same is true for most frontier generation models: OpenAI's GPT-4o does not produce embeddings; you need text-embedding-3-small or text-embedding-3-large. Zhipu follows the same pattern.

The good news is that Zhipu's embedding models live on the exact same platform. There is no second account to create, no separate SDK to install, and no different authentication flow. Once you have a Zhipu API key for GLM 5.2, you already have access to embedding-2 and embedding-3.


Zhipu Embedding Models at a Glance

Zhipu currently provides two embedding models alongside their generation models:

ModelDimensionsMax Input TokensPrice (approx.)
embedding-21,024512~$0.0005 / 1K tokens
embedding-32,0488,192~$0.0007 / 1K tokens

embedding-2 is the lighter option. Its 512-token limit per document means it fits well for short texts — product descriptions, FAQ entries, user reviews, or code comments. At 1,024 dimensions, the resulting vectors are compact and efficient to store and query.

embedding-3 is the better choice for serious RAG workloads. The 8,192-token input ceiling means you can embed most documents, long-form articles, or code files in a single call without chunking them aggressively. Its 2,048-dimensional output captures more semantic detail, which typically translates to better retrieval precision on dense corpora.

For most production pipelines, embedding-3 paired with GLM 5.2 is the recommended combination on the Zhipu platform.


Why This Integration Works Well

The unified platform approach is a genuine differentiator. If you were to use GLM 5.2 from Hugging Face — where it is available under an MIT license — you would need to self-host or find a separate embedding provider. That means a second API key, a second billing account, and additional network latency for the embedding leg of every query.

With Zhipu's hosted API, both the embedding and generation calls share the same base URL (https://open.bigmodel.cn/api/paas/v4/) and the same API key. Your infrastructure is simpler, your debugging surface is smaller, and your billing is consolidated.

You can learn more about GLM 5.2's generation capabilities — including function calling, JSON mode, and vision inputs — in the GLM 5.2 API guide on glm5.app. This tutorial focuses specifically on the embedding side.

If you want to experiment with the complete pipeline interactively before writing any code, glm5.app gives you a browser-based interface to GLM 5.2 with no setup required.


Setting Up Your Environment

Install the OpenAI Python SDK (version 1.x or later). Zhipu's API is OpenAI-compatible, so no Zhipu-specific package is needed:

pip install openai

Export your Zhipu API key as an environment variable:

export ZHIPU_API_KEY="your_zhipu_api_key_here"

Generating Embeddings with embedding-3

The following example embeds a list of document chunks using embedding-3:

import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["ZHIPU_API_KEY"],
    base_url="https://open.bigmodel.cn/api/paas/v4/",
)

documents = [
    "GLM 5.2 is a 753-billion-parameter mixture-of-experts model from Zhipu AI.",
    "The model supports a context window of up to one million tokens.",
    "Zhipu's embedding-3 model produces 2048-dimensional vectors.",
    "RAG pipelines combine a retriever with a generative language model.",
]

response = client.embeddings.create(
    model="embedding-3",
    input=documents,
)

# Each embedding is a list of 2048 floats
for i, item in enumerate(response.data):
    print(f"Document {i}: {len(item.embedding)} dimensions")

The response.data list matches the order of input, so response.data[0].embedding is the vector for documents[0]. Each vector is a plain Python list of floats — ready to insert into any vector database.


Building a Minimal RAG Pipeline

A complete RAG system has two phases: indexing (embed your documents and store the vectors) and querying (embed the user's question, retrieve the closest documents, and generate an answer with GLM 5.2).

The example below uses an in-memory store with cosine similarity for illustration. In production you would replace the in-memory index with a vector database such as Pinecone, Qdrant, Weaviate, or pgvector.

import os
import math
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["ZHIPU_API_KEY"],
    base_url="https://open.bigmodel.cn/api/paas/v4/",
)

# ── INDEXING PHASE ─────────────────────────────────────────────────────────────

corpus = [
    "GLM 5.2 uses a mixture-of-experts architecture with 753B total parameters "
    "and 40B active parameters per forward pass.",
    "The Zhipu API is OpenAI-compatible. You can use the openai Python SDK by "
    "setting base_url to https://open.bigmodel.cn/api/paas/v4/.",
    "GLM 5.2 achieved 89% on the GPQA Diamond benchmark and 62.1% on SWE-bench Pro.",
    "Zhipu's embedding-3 model supports up to 8192 tokens per document and "
    "produces 2048-dimensional vectors.",
    "GLM-4-Air is a lightweight Zhipu model priced at approximately $0.0001 per "
    "1000 tokens, suitable for high-volume low-complexity tasks.",
]

def embed(texts: list[str]) -> list[list[float]]:
    resp = client.embeddings.create(model="embedding-3", input=texts)
    return [item.embedding for item in resp.data]

def cosine_similarity(a: list[float], b: list[float]) -> float:
    dot = sum(x * y for x, y in zip(a, b))
    norm_a = math.sqrt(sum(x ** 2 for x in a))
    norm_b = math.sqrt(sum(y ** 2 for y in b))
    return dot / (norm_a * norm_b) if norm_a and norm_b else 0.0

# Build the index
corpus_embeddings = embed(corpus)

# ── QUERYING PHASE ─────────────────────────────────────────────────────────────

def retrieve(query: str, top_k: int = 2) -> list[str]:
    """Return the top-k most relevant corpus chunks for a query."""
    query_embedding = embed([query])[0]
    scores = [
        (cosine_similarity(query_embedding, doc_emb), doc)
        for doc_emb, doc in zip(corpus_embeddings, corpus)
    ]
    scores.sort(key=lambda x: x[0], reverse=True)
    return [doc for _, doc in scores[:top_k]]

def rag_answer(question: str) -> str:
    """Retrieve context, then generate an answer with GLM 5.2."""
    context_chunks = retrieve(question)
    context = "\n\n".join(context_chunks)

    messages = [
        {
            "role": "system",
            "content": (
                "You are a helpful assistant. Answer the user's question using "
                "only the provided context. If the context does not contain "
                "enough information, say so."
            ),
        },
        {
            "role": "user",
            "content": f"Context:\n{context}\n\nQuestion: {question}",
        },
    ]

    completion = client.chat.completions.create(
        model="glm-4-plus",
        messages=messages,
        temperature=0.2,
    )
    return completion.choices[0].message.content

# Try it
question = "What benchmark scores did GLM 5.2 achieve?"
print(rag_answer(question))

This example illustrates the core pattern clearly:

  1. Index time — call embedding-3 once per document and persist the vectors.
  2. Query time — call embedding-3 once for the user's question, compute similarity scores, retrieve the top-k chunks.
  3. Generation — pass the retrieved chunks as context to glm-4-plus and let the model synthesize an answer.

The only difference in a production setup is replacing the in-memory list with a proper vector store that handles persistence, approximate nearest-neighbor search at scale, and metadata filtering.


Choosing Between embedding-2 and embedding-3

Use embedding-2 when:

  • Your documents are consistently short (under 512 tokens).
  • You are optimizing for storage cost or query latency at very large scale.
  • The semantic precision difference at your corpus size is marginal.

Use embedding-3 when:

  • You need to embed documents longer than 512 tokens without truncating.
  • Your retrieval quality matters more than marginal cost differences.
  • You are building a general-purpose knowledge base where document length varies widely.

The price difference between the two models is small (as of writing, approximately $0.0002 per 1K tokens), so for most applications the decision should be driven by document length and retrieval quality rather than cost.


Token Limits and Chunking Strategy

Even with embedding-3's 8,192-token limit, long documents (technical manuals, research papers, codebases) may exceed a single embedding call. A standard chunking strategy:

  • Chunk size: 512 tokens, with a 64-token overlap between consecutive chunks.
  • Overlap helps preserve semantic coherence across chunk boundaries.
  • Metadata: store the source document ID and chunk index alongside each vector so you can reconstruct the full document or fetch adjacent chunks after retrieval.

Libraries like langchain, llama-index, or the lightweight tiktoken + custom splitter give you fine-grained control over chunking without adding heavy dependencies.


What Comes Next

Once your embedding and retrieval pipeline is working, consider these extensions:

  • Re-ranking: after the initial vector search, apply a cross-encoder or GLM 5.2 itself to re-score the top-k results before passing them to the generator.
  • Hybrid search: combine dense vector retrieval with BM25 keyword search. Most production vector databases support hybrid queries natively.
  • Streaming generation: GLM 5.2 supports streaming responses, so you can start surfacing the generated answer to the user before retrieval completes on subsequent queries.

For a deeper look at what the GLM 5.2 generation endpoint can do — including vision inputs, function calling, and batch mode — the GLM 5.2 API overview on glm5.app covers each capability with runnable examples.

Ready to move from code samples to a live application? Explore GLM 5.2 on glm5.app — you can run prompts directly in the browser, inspect the API responses, and prototype your RAG pipeline without any local setup.


Sources

Begynd at bruge GLM 5 i dag

Prøv GLM 5 gratis — ræsonnering, kodning, agenter og billedgenerering på en platform.