Semantic Chunking

Semantic Chunking is a strategy for splitting documents into smaller pieces (chunks) based on meaning, rather than on fixed character counts or simple separators. It tries to keep sentences or paragraphs that are about the same topic together, and split where the topic changes. Think of it as “a smart editor who knows where one idea ends and the next begins.
语义分块(Semantic Chunking)是一种基于语义(意思)将文档切分成小片段(chunk)的策略,而不是根据固定字符数或简单分隔符来切。它尽量把讨论同一个主题的句子或段落放在一起,在话题发生转折的地方切分。可以把它比喻为:“一个聪明的编辑,知道一个想法在哪里结束,下一个想法从哪里开始

We use an embedding model to measure the semantic similarity between consecutive sentences or small text segments. If the similarity drops below a threshold, we split at that point, creating a new chunk.

Code Example

import numpy as np
from typing import List, Tuple
import requests  # 用于直接调用 embedding API,你也可以换成 openai 库

# ============================================================================
# 0. 配置部分 - 你可以换成自己的 API Key 和 Endpoint
# ============================================================================
API_KEY = "your-api-key"
ENDPOINT = "https://api.openai.com/v1/embeddings"  # 或 Azure/DeepSeek 的 embedding endpoint
MODEL_NAME = "text-embedding-ada-002"                # 或 text-embedding-3-small

# ============================================================================
# 1. 工具函数:获取单个文本的 embedding
# ============================================================================
def get_embedding(text: str) -> List[float]:
    """
    Call the embedding API and return the embedding vector.
    调用 Embedding API 并返回 embedding 向量。
    """
    headers = {
        "Authorization": f"Bearer {API_KEY}",
        "Content-Type": "application/json",
    }
    payload = {
        "input": text,
        "model": MODEL_NAME,
    }
    resp = requests.post(ENDPOINT, headers=headers, json=payload)
    resp.raise_for_status()
    data = resp.json()
    # 从返回的 JSON 中提取 embedding 向量
    embedding = data["data"][0]["embedding"]
    return embedding

# ============================================================================
# 2. 批量获取 embeddings(一次请求处理多个句子,节省 API 调用次数)
# ============================================================================
def get_embeddings_batch(texts: List[str]) -> List[List[float]]:
    """
    Get embeddings for multiple texts in one API call.
    一次性获取多个文本的 embedding。
    """
    headers = {
        "Authorization": f"Bearer {API_KEY}",
        "Content-Type": "application/json",
    }
    payload = {
        "input": texts,
        "model": MODEL_NAME,
    }
    resp = requests.post(ENDPOINT, headers=headers, json=payload)
    resp.raise_for_status()
    data = resp.json()
    # 按输入顺序提取所有 embedding
    embeddings = [item["embedding"] for item in data["data"]]
    return embeddings

# ============================================================================
# 3. 计算余弦相似度
# ============================================================================
def cosine_similarity(vec_a: List[float], vec_b: List[float]) -> float:
    """
    Compute cosine similarity between two vectors.
    计算两个向量的余弦相似度。
    """
    a = np.array(vec_a)
    b = np.array(vec_b)
    dot_product = np.dot(a, b)                           # 点积
    norm_a = np.linalg.norm(a)                           # L2 范数
    norm_b = np.linalg.norm(b)
    if norm_a == 0 or norm_b == 0:
        return 0.0
    return dot_product / (norm_a * norm_b)               # 余弦相似度

# ============================================================================
# 4. 语义分块核心函数
# ============================================================================
def semantic_chunk(
    document: str,
    similarity_threshold: float = 0.8,
    min_chunk_sentences: int = 3
) -> List[str]:
    """
    Split document into semantic chunks based on embedding similarity.
    根据 embedding 相似度将文档切分成语义块。

    Args:
        document: 输入文档字符串
        similarity_threshold: 相似度阈值,低于此值则切分
        min_chunk_sentences: 每个 chunk 至少包含的句子数

    Returns:
        分块后的字符串列表
    """
    # ---- 4.1 简单分句(生产环境建议用 nltk/spaCy)----
    # 以句号、问号、感叹号等进行分割,保留分隔符后处理
    import re
    raw_sentences = re.split(r'(?<=[.!?])\s+', document)
    # 过滤掉空字符串
    sentences = [s.strip() for s in raw_sentences if s.strip()]

    if len(sentences) == 0:
        return []

    # ---- 4.2 获取所有句子的 embedding (批量)----
    embeddings = get_embeddings_batch(sentences)

    # ---- 4.3 计算相邻句子之间的相似度 ----
    similarities = []
    for i in range(len(sentences) - 1):
        sim = cosine_similarity(embeddings[i], embeddings[i+1])
        similarities.append(sim)
        # 记录下相似度,便于调试
        print(f"  Sentence {i} -> {i+1}: similarity = {sim:.4f}")

    # ---- 4.4 定位分割点 ----
    # 分割点放在相似度低于阈值的位置
    breakpoints = []
    for idx, sim in enumerate(similarities):
        if sim < similarity_threshold:
            # 分割点位于 idx 和 idx+1 之间
            breakpoints.append(idx + 1)

    print(f"Detected breakpoints at: {breakpoints}")

    # ---- 4.5 按照分割点组合句子生成 chunks ----
    chunks = []
    start = 0
    for bp in breakpoints:
        # 如果当前 segment 满足最小句子数要求,则独立成 chunk
        if bp - start >= min_chunk_sentences:
            chunk_text = " ".join(sentences[start:bp])
            chunks.append(chunk_text)
            start = bp
        # 否则跳过这个分割点,继续向后合并(保证 chunk 不过于零碎)
        # (你也可以改为强制分割,取决于业务需求)

    # 最后一段剩余句子
    if start < len(sentences):
        chunk_text = " ".join(sentences[start:])
        chunks.append(chunk_text)

    return chunks

# ============================================================================
# 5. 演示:用一段多主题的文本测试语义分块
# ============================================================================
if __name__ == "__main__":
    # 示例文档包含三个自然段落,话题明显不同
    sample_doc = (
        "The cat sat on the mat. It was a sunny day. The cat looked very happy. "
        "Quantum computing uses qubits instead of classical bits. Qubits can exist in superposition. "
        "Entanglement allows qubits to be correlated with each other. "
        "The best pasta is made with durum wheat semolina. Fresh pasta requires only eggs and flour. "
        "Many Italian grandmothers have their own secret recipe."
    )

    print("Original document:\n", sample_doc)
    print("\n--- Performing Semantic Chunking ---")
    result_chunks = semantic_chunk(sample_doc, similarity_threshold=0.75, min_chunk_sentences=2)

    print("\n--- Resulting Chunks ---")
    for i, chunk in enumerate(result_chunks):
        print(f"Chunk {i+1}: {chunk}\n")

Key Takeaways

要点ENCN
语义分块依据Splits are based on semantic similarity, not fixed length.切分依据是语义相似度,而非固定长度。
核心工具Embedding model + cosine similarity.使用 Embedding 模型 + 余弦相似度。
分割点判定Similarity drops below threshold → new chunk.相似度低于阈值 → 分割点。
最小块约束min_chunk_sentences prevents overly small chunks.设置最小句子数防止块过小。
优势Keeps complete ideas together, improves retrieval and downstream LLM understanding.保持完整语义单元,提高检索和下游 LLM 理解效果。
生产注意事项Use proper sentence tokenizer (nltk/spaCy), handle API rate limits, consider caching embeddings.生产中用专业分句工具,注意 API 频率限制,可缓存 embedding。

Recursive Chunking

Recursive Chunking is a hierarchical text splitting strategy that uses a priority list of separators (e.g., ["\n\n", "\n", " ", """]), starting with the highest-level (semantically strongest) separator. If a chunk still exceeds the chunk_size limit after splitting, it recursively applies the next-level separator to that chunk, continuing until all chunks meet the size requirement.
递归分块是一种层次化的文本分块策略,它使用一个分隔符优先级列表(如 ["\n\n", "\n", " ", ""]),从最高级(语义最强的分隔符)开始尝试分割文本。如果分割后的某个块仍然超过 chunk_size 限制,则对该块递归地使用下一级分隔符继续分割,直到所有块都符合大小要求

Core Content

Separator Priority

The separator list is the “brain” of the Recursive Chunking algorithm. It is not a random list—it follows a strict semantic hierarchy. Higher-priority separators represent stronger semantic boundaries.

默认分隔符: ["\n\n", "\n", " ", ""]
优先级分隔符含义语义强度
1 (最高)\n\n双换行 → 段落边界最强
2\n单换行 → 行边界中等
3空格 → 单词边界较弱
4 (最低)""空字符串 → 字符级别最弱(保底)

Core Parameters

参数说明建议值
chunk_size每个块的最大大小(默认按字符数计算)
The maximum size of a chunk. In LangChain, the default length_function is len() (character count). However, for LLMs, token count is more accurate because different LLMs have different tokenizers. A rule of thumb: for OpenAI gpt-4, use 512–1024 tokens (approx 2000–4000 characters for English). For Chinese, since each character is often 1-2 tokens, use smaller character counts (e.g., 500 chars).
200-500 字符
chunk_overlap块之间的重叠字符数,防止上下文在边界丢失

The number of overlapping characters/tokens between adjacent chunks. Why is this needed? Consider a sentence that spans the boundary between chunk 1 and chunk 2. Without overlap, when the user asks a question about that sentence, both chunks lack the full context. Overlap ensures that boundary sentences appear in full in at least one chunk. Best practice: set to 10-20% of chunk_size. If your data has long, continuous paragraphs, use a higher overlap (e.g., 20%).
chunk_size 的 15-20%
separators自定义分隔符列表根据文档语言调整
length_function计算块大小的函数,默认 len
The function used to measure the length of a piece of text. The default is len() (characters). You can replace it with a token counter (e.g., using tiktoken) for precise token budgeting. You can also use a word counter for multilingual documents where character counts are misleading.
可换为 token 计数
is_separator_regex If set to True, the separators are treated as regular expressions. This is powerful for complex splits like “split by one or more newlines” (\n+) or “split by punctuation followed by space” ([.!?]). Default is False for literal matching.

Chinese Language Support

中文分隔符列表

chinese_separators = [
“\n\n”, # 段落
“\n”, # 行
“。”, # 句号
“?”, # 问号
“!”, # 感叹号
“,”, # 逗号
“、”, # 顿号
” “, # 空格(如果有)
“” # 保底
]

4. Code Implementation

4.1 Basic Usage

</>bash
pip install langchain-text-splitters
%pip install langchain-text-splitters

# ============================================================
# 导入 RecursiveCharacterTextSplitter
# Import RecursiveCharacterTextSplitter
# ============================================================
from langchain_text_splitters import RecursiveCharacterTextSplitter

# ============================================================
# 准备示例文本
# Prepare example text
# ============================================================
sample_text = """
第一章:人工智能概述

人工智能是计算机科学的一个分支,致力于创建能够执行通常需要人类智能的任务的系统。
这些任务包括视觉感知、语音识别、决策制定和语言翻译等。

第二章:机器学习基础

机器学习是人工智能的核心子领域。它通过算法让计算机从数据中学习规律。
机器学习主要分为监督学习、无监督学习和强化学习三大类。
"""

# ============================================================
# 初始化 RecursiveCharacterTextSplitter
# Initialize RecursiveCharacterTextSplitter
# 
# 参数说明 (Parameter Description):
#   - chunk_size: 每个块的最大字符数 / Maximum characters per chunk
#   - chunk_overlap: 块之间的重叠字符数 / Overlap characters between chunks
#   - separators: 分隔符优先级列表 / Separator priority list
#   - length_function: 计算长度的函数 / Function to measure length
# ============================================================
text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=100,           # 每块最多100字符 / Max 100 chars per chunk
    chunk_overlap=20,         # 块间重叠20字符 / 20 chars overlap
    length_function=len,      # 用 len() 计算长度 / Use len() for length
    separators=["\n\n", "\n", "。", ",", " ", ""],  # 中文分隔符 / Chinese separators
    is_separator_regex=False, # 是否按正则解析 / Whether to parse as regex
)

# ============================================================
# 方式1: split_text() - 返回字符串列表
# Method 1: split_text() - Returns list of strings
# ============================================================
chunks = text_splitter.split_text(sample_text)

print(f"共生成 {len(chunks)} 个块")
print("-" * 50)
for i, chunk in enumerate(chunks):
    print(f"块 {i+1} (长度: {len(chunk)}):")
    print(f"  {chunk[:50]}...")  # 只显示前50字符
# debug
print ('-'*50)
print (chunks)
--------------------------------------------------
['第一章:人工智能概述\n\n人工智能是计算机科学的一个分支,致力于创建能够 ....、无监督学习和强化学习三大类。']



# ============================================================
# 方式2: create_documents() - 返回 Document 对象列表
# Method 2: create_documents() - Returns list of Document objects
# 
# Document 对象包含 page_content 和 metadata,适合下游 RAG 流程
# Document objects contain page_content and metadata, suitable for downstream RAG
# ============================================================
from langchain_core.documents import Document

# 创建 Document 对象 / Create Document objects
documents = text_splitter.create_documents([sample_text])

# 可以附加元数据 / Can attach metadata
documents_with_meta = text_splitter.create_documents(
    [sample_text],
    metadatas=[{"source": "sample.txt", "chapter": "AI基础"}]
)

#debug
for doc in documents_with_meta:
    print(f"内容: {doc.page_content[:50]}...")
    print(f"元数据: {doc.metadata}")
    print("-" * 50)

内容: 第一章:人工智能概述

人工智能是计算机科学的一个分支,致力于创建能够执行通常需要人类智能的任务的系...
元数据: {'source': 'sample.txt', 'chapter': 'AI基础'}
内容: 第二章:机器学习基础

机器学习是人工智能的核心子领域。它通过算法让计算机从数据中学习规律。
机器学...
元数据: {'source': 'sample.txt', 'chapter': 'AI基础'}

4.2 从文件加载并分块(Load from File and Chunk)

<Bash>pip install langchain_community
<python>%pip install langchain_community

# ============================================================
# 从文件加载文档并分块
# Load document from file and chunk
# ============================================================
from langchain_community.document_loaders import TextLoader

# ============================================================
# 1. 加载文档 / Load document
# ============================================================
loader = TextLoader("my_document.txt")
documents = loader.load()  # 返回 List[Document]

# ============================================================
# 2. 配置分块器 / Configure splitter
# ============================================================
text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=500,          # 技术文档用较大块 / Larger chunks for tech docs
    chunk_overlap=80,        # 重叠约16% / ~16% overlap
    separators=[
        "\n\n",              # 段落 / Paragraphs
        "\n",                # 行 / Lines
        "。", "?", "!",    # 中文句末标点 / Chinese sentence endings
        ",", "、",          # 中文句中标点 / Chinese mid-sentence punctuation
        " ",                 # 空格 / Spaces
        ""                   # 保底 / Fallback
    ]
)

# ============================================================
# 3. 执行分块 / Execute chunking
# ============================================================
chunked_docs = text_splitter.split_documents(documents)

print(f"原始文档数: {len(documents)}")
print(f"分块后文档数: {len(chunked_docs)}")

# ============================================================
# 4. 查看分块统计 / View chunk statistics
# ============================================================
chunk_lengths = [len(doc.page_content) for doc in chunked_docs]
print(f"块长度统计: 最小={min(chunk_lengths)}, 最大={max(chunk_lengths)}, 平均={sum(chunk_lengths)/len(chunk_lengths):.0f}")

4.3 按 Token 数分块(Token-based Chunking)

%pip install langchain_openai
%pip  install tiktoken

# ============================================================
# 按 Token 数分块(更精确控制 LLM 上下文)
# Token-based chunking (more precise control for LLM context)
# ============================================================
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_openai import OpenAIEmbeddings

# ============================================================
# 使用 tiktoken 编码器计算 token 数
# Use tiktoken encoder to count tokens
# ============================================================
text_splitter = RecursiveCharacterTextSplitter.from_tiktoken_encoder(
    encoding_name="cl100k_base",  # OpenAI 的编码器 / OpenAI's encoder
    chunk_size=512,               # 每块 512 tokens
    chunk_overlap=50,             # 重叠 50 tokens
)

chunks = text_splitter.split_text(sample_text)

#debug
print(f"共生成 {len(chunks)} 个块")
print(chunks)
共生成 1 个块
['第一章:人工智能概述\n\n人......无监督学习和强化学习三大类。']


# 验证 token 数 / Verify token count
import tiktoken
enc = tiktoken.get_encoding("cl100k_base")
for i, chunk in enumerate(chunks):
    token_count = len(enc.encode(chunk))
    print(f"块 {i+1}: {token_count} tokens")

块 1: 172 tokens

4.4 自定义长度函数(Custom Length Function)

# ============================================================
# 自定义长度函数:按单词数而非字符数
# Custom length function: count words instead of characters
# ============================================================
def word_count(text: str) -> int:
    """计算文本中的单词数 / Count words in text"""
    return len(text.split())

text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=100,           # 每块100个单词 / 100 words per chunk
    chunk_overlap=20,         # 重叠20个单词 / 20 words overlap
    length_function=word_count,  # 使用自定义长度函数 / Use custom length function
    separators=["\n\n", "\n", "。", ",", " ", ""]
)

chunks = text_splitter.split_text(sample_text)
for i, chunk in enumerate(chunks):
    print(f"块 {i+1}: {word_count(chunk)} 个单词")

Complete RAG Chunking Pipeline

# ============================================================
# 完整 RAG 分块流程:加载 → 分块 → 向量化 → 存入向量库
# Complete RAG chunking pipeline: Load → Chunk → Embed → Vector Store
# ============================================================

from langchain_community.document_loaders import TextLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_openai import OpenAIEmbeddings
from langchain_community.vectorstores import Chroma

# ============================================================
# Step 1: 加载文档 / Load documents
# ============================================================
loader = TextLoader("knowledge_base.txt",encoding="utf-8")
docs = loader.load()
print(f"✅ 加载了 {len(docs)} 个文档")

# ============================================================
# Step 2: 递归分块 / Recursive chunking
# ============================================================
text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=400,           # 适中大小 / Moderate size
    chunk_overlap=80,         # 20% 重叠 / 20% overlap
    separators=[
        "\n\n", "\n", 
        "。", "?", "!", 
        ",", "、", 
        " ", ""
    ]
)

chunked_docs = text_splitter.split_documents(docs)
print(f"✅ 分块完成: {len(chunked_docs)} 个块")
✅ 分块完成: 1 个块


%pip install chromadb
%pip install langchain-chroma
# ============================================================
# Step 3: 向量化并存入向量数据库 / Embed and store in vector DB
# ============================================================
from langchain_chroma import Chroma
from langchain_openai import OpenAIEmbeddings
from langchain_community.embeddings import OllamaEmbeddings   # <- I installed Ollama,runslocal
import os
#embeddings = OpenAIEmbeddings(model="text-embedding-3-small", api_key=your_API_KEY )

# I installed Ollama, running local
embeddings = OllamaEmbeddings(
    model="nomic-embed-text",
    base_url="http://localhost:11434",
    show_progress=True  # 显示下载进度
)

vectorstore = Chroma.from_documents(
    documents=chunked_docs,
    embedding=embeddings,
    persist_directory="./chroma_db"  # 持久化目录 / Persist directory
)

print(f"✅ 向量库创建完成,共 {vectorstore._collection.count()} 个向量")
OllamaEmbeddings: 100%|██████████| 1/1 [00:43<00:00, 43.13s/it]
✅ 向量库创建完成,共 1 个向量


# ============================================================
# Step 4: 测试检索 / Test retrieval
# ============================================================
query = "什么是机器学习?"
results = vectorstore.similarity_search(query, k=3)

print(f"\n🔍 查询: {query}")
print("-" * 50)
for i, doc in enumerate(results):
    print(f"结果 {i+1}: {doc.page_content[:100]}...")

Key Takeaways

要点 (Key Point)ENCN
分隔符顺序决定语义完整性Separator order determines semantic integrity. Always go from coarse (paragraph) to fine (character).分隔符顺序决定语义完整性。永远从粗(段落)到细(字符)。
chunk_overlap 防止边界信息丢失chunk_overlap prevents information loss at boundaries. Set to 10-20% of chunk_size.chunk_overlap 防止边界信息丢失。设置为 chunk_size 的 10-20%。
中文必须自定义分隔符Chinese text must use custom separators (). Never use the default English list.中文文本必须使用自定义分隔符()。切勿使用默认的英文列表。
元数据重复是隐藏的陷阱Metadata duplication is a hidden trap. When using split_documents(), be careful with unique ID fields.元数据重复是隐藏的陷阱。使用 split_documents() 时,注意唯一 ID 字段。
大文件要用流式处理For large files (> 1 GB), implement streaming chunking to avoid OOM errors.对于大文件(> 1 GB),实现流式分块以避免 OOM 错误。
字符数 vs Token 数Character count is fast but inaccurate. Token count is accurate but slower. Choose based on your use case.字符数快但不准确。Token 数准确但较慢。根据您的用例选择。

RAG 2.0

RAG (Retrieval-Augmented Generation) is an AI architecture that retrieves relevant information from external knowledge sources and provides it to an LLM, enabling the model to generate accurate, up-to-date, and context-aware responses.

LLM = Answer from Training
while
RAG = Search First + Then Answer

What is RAG 2.0? There is no official industry standard that defines “RAG 1.0”, “RAG 2.0”, or “RAG 3.0”.

The concept of “RAG 2.0”, known as Agentic RAG, represents a shift from a “simple data retrieval plugin” to a “deeply integrated, agentic system with reasoning capabilities.” The industry has indeed evolved from 1.0 and is now progressing toward 3.0.

Simplest Way to Remember

VersionMeaning
RAG 1.0Search Once
RAG 2.0Search + Reason
RAG 3.0
(coming ? on the way?)
Agent + Search + Tools + Workflow
RAG Foundation: Embedding

Embedding is a fundamental technology in machine learning and natural language processing that transforms discrete or complex objects (such as words, sentences, or images) into numerical vector representations of a fixed dimension

more …

RAG Foundation: RAG Pipeline

A simple RAG pipeline has two phases and five stages

  • Phase 1: Indexing (Offline / 离线阶段)
    Build the searchable knowledge base before users ask questions.
    离线阶段(索引):先把所有文档加载进来,切分成小块,调用 Embedding 模型转成向量,最后存进 FAISS 等向量数据库里。
  • Phase 2: Retrieval & Generation (Online / 在线阶段)
    Execute at query time for each user question.
    在线阶段(检索+生成):用户提问时,先把问题也转成向量,去库里找最相似的 Top-K 个块,把这几个块作为“参考资料”连同问题一起扔给 GPT,让它写出最终回答。

more …

In AI, a chunking strategy is the method used to break down large pieces of information—like long documents, complex prompts, or even audio and video—into smaller, more manageable segments called “chunks”. These chunks are the fundamental units that AI systems, especially Large Language Models (LLMs), work with to understand, process, and retrieve information efficiently.

Common Chunking Strategies

The best strategy depends on the type of data and the specific task. Here are the most common approaches:

StrategyDescriptionBest For
Fixed-Size ChunkingSplits text into chunks of a predetermined size (e.g., a specific number of words, characters, or tokens). Often uses a “sliding window” with overlap to preserve context across boundaries.Simple implementation; works well when document structure is uniform and not critical.
Semantic ChunkingGroups text based on meaning, using algorithms to find natural topic boundaries and keep related ideas together.Maintaining the coherence of ideas within each chunk for better understanding.
Structure-Aware ChunkingRespects the natural format of the document, splitting at points like paragraphs, sentences, or headers.Documents with clear structure (e.g., articles, reports, code) where breaking mid-section would lose meaning.
Recursive ChunkingStarts with large chunks and recursively splits them into smaller ones until they meet a target size, trying to respect natural boundaries like paragraphs or sentences.A balanced approach that aims to create the largest possible meaningful chunks.
Multimodal ChunkingExtends the concept to non-text data, such as segmenting audio by silences, video by scene changes, or identifying objects within images.AI systems that process images, audio, and video, not just text
Chunking Strategy: Recursive Chunking

Recursive Chunking is a hierarchical text splitting strategy that uses a priority list of separators (e.g., ["\n\n", "\n", " ", """]), starting with the highest-level (semantically strongest) separator. If a chunk still exceeds the chunk_size limit after splitting, it recursively applies the next-level separator to that chunk, continuing until all chunks meet the size requirement.

more …

Chunking Strategy: Semantic Chunking

Semantic Chunking is a strategy for splitting documents into smaller pieces (chunks) based on meaning, rather than on fixed character counts or simple separators. It tries to keep sentences or paragraphs that are about the same topic together, and split where the topic changes. Think of it as “a smart editor who knows where one idea ends and the next begins

more …

Chunking Strategy: Parent-Child Retrieval

Parent-Child Retrieval (also known as Small-to-Big Retrieval) is a two-tier hierarchical indexing strategy.

more …


Hybrid Search refers to a search technique that combines multiple search algorithms simultaneously to retrieve the most relevant results. It most commonly merges Lexical (Keyword) Search with Semantic (Vector/Dense) Search.
基于关键词的搜索(词汇搜索)与基于语义的搜索(向量/稠密搜索)

  1. Lexical Search (Sparse Retrieval): Typically powered by algorithms like BM25 or TF-IDF. It relies on exact keyword matching and statistical term frequency. It excels at finding specific proper nouns, IDs, or rare terminology (e.g., “error code 404”).
    词汇搜索(稀疏检索): 通常由 BM25 或 TF-IDF 等算法驱动。它依赖于精确的关键词匹配和统计词频。它在查找特定的专有名词、ID 或罕见术语时表现出色(例如:“错误代码 404”)。
  2. Semantic Search (Dense Retrieval): Powered by embedding models (e.g., Sentence-BERT). It converts text into high-dimensional vectors and retrieves documents based on “meaning” rather than exact words. It excels at understanding synonyms, context, and natural language queries (e.g., “How to fix a broken internet connection”).
    语义搜索(稠密检索): 由嵌入模型(如 Sentence-BERT)驱动。它将文本转换为高维向量,并根据“含义”而非精确词汇来检索文档。它在理解同义词、上下文和自然语言查询(例如:“如何修复断开的网络连接”)方面表现出色。
BM25 (keyword-based search)

BM25 (Best Matching 25) is a keyword-based ranking algorithm used in information retrieval to score and rank documents based on their relevance to a search query. It’s called “Best Matching 25” because it was the 25th variant in a series of scoring functions proposed by its creators. BM25 is the default ranking algorithm in Elasticsearch and most production search engines

more …

RRF

RRF stands for Reciprocal Rank Fusion. It is an algorithm that merges multiple ranked result lists from different search systems into a single unified ranking.
全称是 Reciprocal Rank Fusion(倒数排名融合)。它是一种将来自不同检索系统的多个排名结果列表合并成一个统一排名的算法.

more …

Vector Database Selection

Compare normal DB, such as SQL DB, MySQL, PostgreSQL, They fundamental difference is what they search for and how they find it. A traditional SQL database (like MySQL, PostgreSQL without pgvector) is built for exact matching and structured queries. It answers questions like: “Find the customer with ID = 12345” or “Give me all orders over $100.” A Vector Database is built for semantic similarity and unstructured data. It answers questions like: “Find all documents that talk about the same topic as this paragraph” or “Show me products that look visually similar to this image.”

Normal DB vs Vector DB

要点ENCN
核心:精确匹配 vs. 语义相似度Core: Exact matching vs. Semantic similarity核心:精确匹配 vs. 语义相似度
SQL存结构化数据(数字/字符串),Vector存浮点数数组(含义)SQL stores structured data (numbers/strings); Vector stores float arrays (meaning)SQL存结构化数据,Vector存浮点数数组(含义)
SQL查询用WHERE精确条件;Vector查询用ORDER BY距离SQL queries use WHERE exact conditions; Vector queries use ORDER BY distanceSQL查询用WHERE精确条件;Vector查询用ORDER BY距离
SQL用B-Tree/哈希(精确查找);Vector用HNSW/IVF(近似查找)SQL uses B-Tree/Hash (exact lookup); Vector uses HNSW/IVF (approximate)SQL用B-Tree/哈希(精确);Vector用HNSW/IVF(近似)
SQL结果是二元的(匹配/不匹配);Vector结果是排序的(相似度分数)SQL results are binary (match/no match); Vector results are ranked (similarity scores)SQL结果是二元的;Vector结果是排序的
SQL适合事务、财务报表;Vector适合RAG、推荐、AISQL suits transactions, ledgers; Vector suits RAG, recommendations, AISQL适合事务、报表;Vector适合RAG、推荐、AI
专用向量库不能做JOIN和ACID;但pgvector可以在PostgreSQL中兼得Dedicated vector DBs can’t do JOINs/ACID; pgvector lets you have both in PostgreSQL专用向量库不能做JOIN和ACID;pgvector可以让两者兼得
在实际RAG中,两者是互补的,不是替代关系In real-world RAG, they are complementary, not replacements在实际RAG中,两者是互补的,不是替代关系

Vector database selection is the process of choosing the right vector database technology for your AI application from dozens of available options — Milvus, Qdrant, Weaviate, Pinecone, pgvector, Chroma, and more.

Mainstream Vector Database Landscape

CategoryExamplesCN
Fully Managed (PaaS)Pinecone, Zilliz Cloud, Weaviate Cloud全托管云服务
Self-Hosted Open SourceQdrant, Milvus, Weaviate, Chroma自托管开源
Database Extensionspgvector, MongoDB Vector Search, Elasticsearch数据库扩展
Cloud Provider ServicesAzure AI Search, AWS S3 Vectors, Tencent Cloud VDB云厂商服务
Embedded/SpecializedSQLite (vector), LanceDB嵌入式/专用

Detailed Comparison

DatabaseAvg Query TimeCost (1M @ 1536-dim)Best ForCN 最适合
Milvus/Zilliz50.7ms$115/moFastest queries + good flexibility最快查询+灵活性好
Weaviate51.7ms$160/moNative datetime/geo + hybrid search原生时间/地理+混合检索
Qdrant73.1ms$103/moBest balance (speed + flexibility + cost)最佳平衡(速度+灵活性+成本)
Pinecone106.3ms$30/moCheapest (⚠️ poor schema flexibility)最便宜(⚠️ Schema灵活性差)
Chroma275.4ms$139/moEasiest setup + prototyping最简单设置+原型开发

7 Types of Data Stored in VectorDB in AI Projects

类型ENCN更新频率过滤器主要用途
RAG 文档块RAG Document ChunksRAG 文档块source, page问答
用户记忆 (Mem0)User Memory (Mem0)用户记忆 (Mem0)user_id个性化
工具 SchemaTool Schemas工具 Schematool_category工具选择
Agent 轨迹Agent TrajectoriesAgent 轨迹user_id, outcome经验复用
黄金数据集Golden Dataset黄金数据集category评估
语义缓存Semantic Cache语义缓存降本提速
代码索引Code Index代码索引language, path代码生成

Reranker is a sophisticated machine learning model designed to refine and reorder a list of candidate items—such as search results, document passages—to maximize their relevance to a specific query or context.

Reranker(重排序器)是一种复杂的机器学习模型,旨在优化并重新排序候选项目列表(如搜索结果、文档片段),以最大程度提高它们与特定查询或上下文的相关性。

Reranker

Reranker实战


Advanced RAG (Advanced Retrieval-Augmented Generation) is an evolutionary upgrade over the basic “Naive RAG” pipeline. It adds a suite of optimization techniques at every stage of the RAG workflow — pre-retrieval, retrieval, post-retrieval, and evaluation — to systematically improve retrieval precision, recall, and generation quality.

Advanced RAG

Query Rewrite

Multi Query Retrieval

Context Compression


Frequently Used GenAI & LLM Concepts (Simple Explanations)

Agent

An AI Agent is a system that can autonomously break down tasks, make decisions, and execute actions using tools and reasoning.

Agentic Workflow

An agentic workflow is a multi-step autonomous process where an AI system completes tasks without continuous human intervention.
or says: AI auto-complete entire process without human intervention.
e.g.
apply for –> validation –> calculation –> output results
human intervention.

Chunking

Splitting big documents into small pieces so AI can handle them better.

e.g. There are 200 pages in a PDF file, AI cannot read all at once, so splitting file into many small pieces/chunks.
1st piece: 1- 500 words;
2nd piece/chunk: 501 – 1000 words;
3rd piece/chunk: 1001 – 1500 words;
…..
each chunk will become embedding.
It is commonly used in RAG systems to prepare documents for embedding and retrieval.

Cosine Similarity

Cosine similarity measures how similar two vectors are in meaning by comparing their direction in vector space.
or says: A way to measure how similar two pieces of meaning are.
e.g.
apple vs banana : yes, they are very similar.
apple vs car: no, they are not similar at all.

Context Window

Context window is the maximum amount of text an LLM can process at once.

Embedding

Embeddings convert text into numerical vectors that represent meaning.

apple” become [0.12, -0.98, 0.33, ……]
orange” become [0.12, -0.98, 0.456, ,,,,,,,] too,
so AI will find
apple = Fruit,
apple != car
or says “simile to a fruit”, and it is not a car. Similar meanings result in closer vector distances, allowing machines to compare semantic similarity instead of exact words.

Fine-tuning

Fine-tuning is the process of further training a pre-trained model on domain-specific data to improve performance in a specialized area.

Hallucination

Hallucination occurs when an LLM generates incorrect or fabricated information while sounding confident.

LangChain

LangChain is a framework for building applications powered by LLMs by connecting models with tools, APIs, and data sources.
in short, chaining interlinkage/link AI , Data, Tools …….
or says “A tool to connect LLMs, data, and tools into applications.”

LangGraph

LangGraph is a framework for building stateful, graph-based AI workflows where agents can loop, branch, and maintain memory across steps.
or says: A workflow system that lets AI follow multi-step flows with loops and decisions.
e.g. SQL Agent,
Write SQL script –> Execute –> Error Alert –> Fix –> Re-try

LLM

Large Language Model. The AI brain that can understand and generate language.

e.g. user asks AI “please write an email”, then output a completed email.
Company uses it to generate Report, analyst Data, auto reply client, …..

MCP

MCP (Model Context Protocol) defines a standardized way for LLMs to interact with external tools, APIs, and data systems.
or says: A standard way for AI to use tools and data systems.

Model Drift

Model drift occurs when a deployed model’s performance degrades due to changes in real-world data over time.
or says: After the AI was put into use, it started to make mistakes.
why/what’s happened?
maybe, training used old data, now data has changed/updated.

Prompt

A prompt is the instruction given to an LLM.
Well-designed prompts significantly improve the quality and accuracy of model outputs.
e.g.
bad prompt: “write a letter”, — not clearly, what letter you need, thank you letter? complaining letter? ,,,,
good prompt: “Please write a thank you letter to Mary since she gave me a gift.”

Prompt Engineering

Prompt engineering is the practice of designing effective prompts to guide LLM behavior and improve output quality.
or say: Designing better instructions to improve AI responses.

RAG

Retrieval-Augmented Generation. Retrieval-Augmented Generation combines retrieval and generation.
The system first retrieves relevant documents, then uses an LLM to generate an answer based on that information.
e.g. look up HR documents –> pass documents to GPT –> GPT summary then answer question.

Retrieval

Retrieval is the process of searching a knowledge base or vector database to find relevant information before generating an answer.
e.g.
“what is the return policy?” , AI system will look up in “vector DB”, find out “policy document”, pass it to GPT, then answer the question – what is the return policy?

Token

Tokens are the smallest units of text that an LLM processes.

e.g. a sentence like “I love Toronto”, AI splits “I love Toronto” into smaller pieces before the model can understand it.

  • I
  • love
  • Toronto

these are tokens,
Token count also determines cost and context limits in LLM systems.

Tool Calling

Tool calling allows LLMs to execute external functions such as APIs, databases, or code to perform real-world actions.
e.g. “AI can “take action”.
>search order
> search database

Vector DB

A database that stores meaning-based vectors for similarity search. It allows AI systems to retrieve semantically relevant documents instead of keyword-based search.
e.g.
there are 10000 file,
HR policy,
IT manual,
Finance report,
……
all of those files become embedding saved in Vector DB. When user asks question, AI will not use “Key-words” to seek, it uses “mean” to match.

Vector Search

Vector search retrieves results based on semantic similarity rather than keyword matching.
or says: Searching by meaning instead of exact words.