面包屑图标 当前位置: 首页
AI资讯
热点详情

RAG技术构建企业级文档问答系统的Late Chunking切分

AI热点日报
AI热点日报时间:2026-07-01
热点解读

LateChunking将向量化置于切分之前,使片段向量融合上下文语义,以解决代词指代不明问题。虽在相似度计算中表现优于传统方法,但实际应用效果不佳,短句易与其他句子混淆,未能稳定提升检索质量。

Jina在2024年推出的Late Chunking(延迟切分)技术,为文本切分领域带来了一个颇具新意的思路——先整体理解语义再执行切分,而非传统的先切分后理解。本文是中文环境下首篇系统性介绍该方法的文章,力求以最简洁的方式讲清其动机、原理及实际效果。

使用RAG技术构建企业级文档问答系统:切分(5)Late Chunking

出发点

写作时使用代词是非常自然的语言习惯,但一旦进行文本切分,问题便随之而来。Jina提出的问题其实很常见:某些片段里只剩下代词,而它所指向的对象却位于前一个片段中。检索时,如果用户询问“柏林有多少居民”,而知识库里只有一个片段写着“Its more than 3.85 million inhabitants”,模型很难把这个片段和柏林联系起来——甚至很难准确召回这个片段。

举一个具体例子:如果文档按某种方式切分,第二个片段里充斥着“Its”和“it”这类指代模糊的内容,检索失败的概率会非常高。即便模型恰好召回该片段,它也无法明确“Its”指代的是Berlin。这就导致,答案明明存在于库中,却因为切分方式不当,让答案“哑巴”了。

这里有一个值得尝试的方向:在切分前,统一进行一次指代消解,将代词替换回它所指代的对象。比如上面的例子,第二段如果变为“Berlin's more than 3.85 million inhabitants…”,检索时就不会出现代词问题。感兴趣的读者可以拿这个思路做个实验,看看实际效果如何。

核心原理

RAG的标准流程是先切分、再向量化。Jina的方案则反向操作——先把整段文本向量化,随后再切分。这一做法被称为Late Chunking(延迟切分),关键在于“晚”字——向量化步骤被挪到了切分之前。

具体操作上,先将知识库中的一整篇文档送入Embedding模型,得到每个token位置的Embedding向量。然后,按照选定的切分方式(按句子、按token长度等),取特定范围内的这些向量做平均,从而获得该片段的最终Embedding向量。

举个例子:“DeepSeek是由杭州幻方量化所成立的子公司所开发的大语言模型。它真的很强大!”

假设这句话经过tokenize后得到23个token:

[, , , , , , , , , , , , , , , , , , , , , , ]

对Embedding模型设置输出每个位置的hidden state(即Token Embedding),假设维度是1024,那么“DeepSeek”这个位置就对应一个1024维的向量,“是”这个位置也一样。关键点在于,“它”这个token的hidden state因为在整句上下文中计算出来,已经融合了整个句子的信息——它“知道”自己指代的是DeepSeek。如果按句子切分,“它真的很强”对应的位置(第19-23个token)的hidden state做平均,得到的向量实际表达的是“DeepSeek真的很强大”这个语义——这正是我们想要的效果。

这里需要澄清几个细节:

  • 为什么只取一整篇文档,而不是整个知识库?因为跨文档使用代词指代的现象在实际中极少出现。Late Chunking要解决的是切分导致的指代不明问题,而不是跨文档的指代问题。
  • 最后是怎么切分的?Jina官方实现提供了几种方式:按语义切分、按句子切分、按token长度切分。切分后,每个片段的Embedding就是该片段所有Token Embedding的均值。
  • 一整篇文档过Embedding模型,会不会超长?Jina要求尽量使用支持长输入的Embedding模型。如果仍然超长怎么办?按模型支持的最大长度(比如8192)先切分,然后把这几个8192长度的向量拼接起来,再按前述方法获取片段的Embedding。这里涉及的操作细节不少:切分标准是按token长度而非句子长度,字符索引要和token索引对应,还要考虑模型第一个位置是否有特殊字符需要移除。

实验结果

官方用“Berlin”作为Query,与下面三个句子分别计算相似度。每个句子都用两种方式做向量化:传统方法(先切分再向量化)和Late Chunking。

第一个句子不含指代问题,两种方法计算的余弦相似度非常接近,符合预期。第二个句子中有“Its”和“it”,第三个句子中有“The city”,传统方法计算的余弦相似度明显较低,而Late Chunking方法则保持了较高的相似度——这正是Late Chunking的核心优势所在。

文本内容 传统方法相似度 Late Chunking相似度
Berlin is the capital and largest city of Germany, both by area and by population. 0.84862185 0.849546
Its more than 3.85 million inhabitants make it the European Union's most populous city, as measured by population within city limits. 0.7084338 0.82489026
The city is also one of the states of Germany, and is the third smallest state in the country in terms of area. 0.7534553 0.84980094

相似度高意味着什么?当知识库规模较大时,如果用户输入“柏林的常驻人口有多少”,使用Late Chunking后,第二个句子在候选中会更靠前,被召回的概率更大。而传统方法可能会把这个句子排在很靠后的位置,导致答案错失。

实际效果

从动机上看,这个思路站得住脚,原理也说得很通,但实际的实验结果却有些尴尬——效果并不理想。需要说明的是,这里的测试并非完全控制变量:除了切分方法不同外,向量模型也不同,但生成模型和评估模型与其他实验保持一致。

核心代码实现

Late Chunking最核心的部分,其实不是切分动作在前还是后,而是片段中的向量表示要能融合上下文。官方提供的代码是按英文句子、token数等方式切分,这与中文习惯差异较大,因此本文的实现仍然按换行进行切分,但每个片段的Embedding使用的是融合了整个文档语义信息的向量。

def document_to_token_embeddings(model, tokenizer, document, batch_size=256):
    tokenized_document = tokenizer(document, return_tensors="pt")
    tokens = tokenized_document.tokens()
    outputs = []
    for i in tqdm(range(1, len(tokens), batch_size)):
        start = i
        end = min(i + batch_size, len(tokens))
        batch_inputs = {k: v[:, start:end].to(device) for k, v in tokenized_document.items()}
        with torch.no_grad():
            model_output = model(**batch_inputs)
        outputs.append(model_output.last_hidden_state)
    model_output = torch.cat(outputs, dim=1)
    return model_output

def late_chunking(token_embeddings, span_annotation, max_length=2048):
    outputs = []
    for embeddings, annotations in zip(token_embeddings, span_annotation):
        if max_length is not None:
            annotations = [
                (start, min(end, max_length - 1))
                for start, end in annotations if start < (max_length - 1)
            ]
        pooled_embeddings = []
        for idx, (start, end) in enumerate(annotations):
            if (end - start) >= 1:
                pooled_embeddings.append(
                    embeddings[start:end].mean(dim=0).cpu().numpy()
                )
            else:
                pooled_embeddings.append([])
        pooled_embeddings = [
            embedding / np.linalg.norm(embedding) for embedding in pooled_embeddings
        ]
        outputs.append(pooled_embeddings)
    return outputs

# 构建span_annotations的示例逻辑
span_annotations = []
doc_input_ids = doc_tokens['input_ids'][0]
start_pos = 1
seperator_len = len(tokenizer('\n', return_tensors='pt')['input_ids'][0]) - 2
for chunk_idx, chunk in enumerate(chunks):
    chunk_input_ids = tokenizer(chunk, return_tensors='pt')['input_ids'][0][1:-1]
    chunk_token_len = len(chunk_input_ids)
    if (doc_input_ids[start_pos: start_pos + chunk_token_len] == chunk_input_ids).detach().numpy().mean() != 1.0:
        start_pos += 1
    if (doc_input_ids[start_pos: start_pos + chunk_token_len] == chunk_input_ids).detach().numpy().mean() == 1.0:
        span_annotations.append((start_pos, start_pos + chunk_token_len))
    start_pos += chunk_token_len

document_embeddings = document_to_token_embeddings(model, tokenizer, processed_doc, batch_size=256)
late_embeddings = late_chunking(document_embeddings, [span_annotations])

结果分析与讨论

考虑到测试集是中文的,而官方代码是英文的,最初怀疑是不是实现有bug。但用英文数据进行分析后,发现同样的问题依然存在。

这里只展示最关键的分析:对于一个知识库片段,用自身作为Query去检索,如果只保留Top1结果,绝大多数情况下应该检索到自身才对——但在Late Chunking中并非如此。

分析时,使用维基百科中DeepSeek词条的部分文本作为知识库,用官方代码切分得到片段。然后拿每个片段作为Query,过Embedding模型得到查询向量,与所有知识库片段两两计算相似度。结果发现,最相似的片段并不总是自己,前5个句子似乎都和第一个句子最相似。

原因其实很简单:Late Chunking是将整个片段每个位置的hidden state做平均,这意味着短句和代词较多的句子,更容易与其他句子相似。从句子长度的分析来看,长句普遍都能找到自己最相似,而短句则倾向于和其他句子相似。这一点不难理解——短句往往需要借助上下文信息,本身代词相对较多,平均后的向量容易被“拉向”其他相似意义的句子。

从RAG全流程的评估结果和英文数据的分析来看,Late Chunking并非一种非常通用、能稳定提升切分效果的方法。欢迎各位读者尝试这套代码,如果发现其中的bug,也欢迎反馈讨论。

热点追踪提示词
你是一名 AI 行业编辑,请围绕下面这条热点输出一份资讯解读:
热点:RAG技术构建企业级文档问答系统的Late Chunking切分要求:
1. 先用一句话解释这条热点在讲什么
2. 再总结它为什么重要
3. 说明会影响哪些 AI 产品或内容方向
4. 最后给出 3 个适合资讯站使用的标题
来源:https://www.53ai.com/news/RAG/2025022854162.html
ai 人工智能

游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。

相关热点
AI热点2026-07-01 19:33
EcomStat集中式分析平台一站式数据洞察与可视化

做电商的朋友都知道,利润往往藏在细节里。很多时候,光看平台表面数据是远远不够的——成本结构不清晰、各渠道数据分散、利润计算滞后,这些问题一叠加,赚钱就变成了“糊涂账”。EcomStat 正是针对这些痛点推出的一个集中式分析平台。它的核心逻辑很简单:把零散的数据拉到一个仪表盘上,让成本、利润、费用和客

AI热点2026-07-01 19:33
AI智能财务管家:GPT驱动的个人支出管理应用

说到日常记账,你是不是也试过不少App,结果往往坚持不了几天就放弃了?别急,这位AI理财助手可能不太一样——它更像身边一个默默帮你盯紧钱&包的朋友。 什么是AI Money Manager – GPT Expense? AI理财管家 – GPT消费记录,这是一款运行在Android平台上的财经应用。

AI热点2026-07-01 19:33
TaxBuzz AI税务会计专业人士人工智能浏览器扩展

财税行业的朋友们,最近发现一款非常实用的AI工具——TaxBuzz Ai,这是一款专为税务和会计专业人士设计的Chrome浏览器扩展。它的核心亮点在于:能够实时提供AI辅助与专业见解,帮助简化工作流程、提升准确性,同时确保符合IRS(美国国税局)规定。最便捷的是,它可以无缝嵌入您正在浏览的任何网页,

AI热点2026-07-01 19:33
Pump 人工智能团购云成本优化工具

想象一下,将人工智能与团购模式相结合,专门用于云成本优化——这正是Pump在做的事情。它能让初创企业在AWS、GCP或Azure上的云支出,通过自动选购性价比最高的承诺服务实现智能省钱,整个过程无需工程团队介入。而且,Pump本身完全免费,目标就是让初创公司拥有与大厂同等级别的云成本控制能力。 什么

延伸阅读