Milvus 3.0 开源解读|词法+语义高亮,如何解决Agent的搜索噪音?
Milvus 3.0 引入词法与语义高亮能力,针对RAG和Agent场景中检索结果冗长、噪声多、上下文成本高的问题,通过片段化提取匹配内容,降低LLM token消耗并提升人类可读性。词法高亮基于BM25/TextMatch的token匹配,语义高亮则依赖自研开源模型实现跨表述语义关联识别。
RAG与Agent的搜索噪音困境
RAG与Agent用到深水区,一定会遇到这个问题:明明检索结果没什么问题,但模型输出结果似乎总是差点意思,上下文成本也一直居高不下。
根本原因在于,为了将所有相关的内容完整召回,经常一次query,可以打捞出三五段,甚至十段文档给LLM。
如果每篇文档几千字,一个query就要消耗几万个token。但问题是,这10篇文档里,真正有用的句子可能只有几十句,而剩下的,全是噪音。
大量的噪音灌入,不仅浪费token,也分散了LLM注意力。

对人类用户来说同样如此,电商、客服RAG中,经常会有几千字的技术文档、几十页的合同或很长的客服记录,阅读者打开文档,再逐段寻找“重点”,不仅搜寻麻烦,还要多一个文档下载过程。
词法高亮:通过Token匹配高亮
作为基础、最常用的方案,词法高亮的逻辑和 BM25、Text Match 搜索一脉相承,复用同一套分词规则(analyzer)来处理查询和结果文本;匹配到命中的词汇后,直接按照它们在原文中的位置插入高亮标记,保证搜索命中的词项和结果展示的边界完全一致,不会出现错位偏差。
查询与结果文本 → analyzer → token 匹配 → 原文位置 → 高亮结果
使用上它有两种灵活的配置方式。
如果是配合 BM25 搜索使用,只需开启highlight_search_text=True,系统就会直接用当前的搜索关键词生成高亮。比如搜索 “BM25 混合搜索”,返回的标题 “BM25 与混合搜索的配置方法” 会自动标注出匹配的关键词,让用户一眼看到命中点。
from pymilvus import LexicalHighlighter, MilvusClient
client = MilvusClient(uri="http://localhost:19530")
highlighter = LexicalHighlighter(
pre_tags=["<mark>"],
post_tags=["</mark>"],
highlight_search_text=True,
)
results = client.search(
collection_name="document_titles",
data=["BM25 混合搜索"],
anns_field="title_sparse",
search_params={"metric_type": "BM25"},
limit=10,
output_fields=["title"],
highlighter=highlighter,
)
如果需要自定义匹配规则,或是给向量搜索结果补充关键词匹配证据,也可以通过highlight_query显式指定 TextMatch 条件,灵活设置目标字段和匹配文本。
highlighter = LexicalHighlighter(
highlight_search_text=False,
highlight_query=[{
"type": "TextMatch",
"field": "title",
"text": "BM25 混合搜索",
}],
pre_tags=["<mark>"],
post_tags=["</mark>"],
)
当前显式词法高亮查询支持 TextMatch。它只在已经返回的结果中查找并标记匹配 token,不扩大候选集,也不重新排序。它也可以用于向量搜索结果,为结果补充指定关键词的匹配证据。
当目标字段变成长正文时,词法高亮不会返回完整文本,而是以片段的形式输出匹配内容。
词法高亮的结果以 fragment 组织。默认 fragment_size 为 100 个字符,num_of_fragments 为 5。因此,对于超过 100 个字符的文本,高亮结果通常不会覆盖全文,而是自动返回匹配位置附近的 fragment。
如果多个匹配落在同一个 fragment 范围内,它们会合并到同一个片段;如果匹配分布在文本的不同位置,则会按原文顺序生成多个 fragment,直到达到 num_of_fragments 的限制。
例如,搜索“BM25 调优”后,一篇文档可能分别在“索引配置”“查询参数”和“性能排查”章节中出现相关内容。可以进一步调整 fragment 参数,控制上下文范围和返回数量:
highlighter = LexicalHighlighter(
pre_tags=["<mark>"],
post_tags=["</mark>"],
highlight_search_text=True,
fragment_offset=30,
fragment_size=160,
num_of_fragments=3,
)
结果可能包含:
["...创建稀疏索引时,<mark>BM25</mark> 的参数会影响...",
"...查询阶段可以通过这些配置完成 <mark>BM25</mark> <mark>调优</mark>...",
"...排查延迟时,需要同时检查 <mark>BM25</mark> 查询参数..."]
如果希望展示更完整的上下文,可以通过 fragment_offset 和 fragment_size 调整片段范围;num_of_fragments 用于控制最多返回多少段。fragment 按匹配内容在原文中的先后顺序返回,不会按照 BM25 分数重新排序。
这些片段会随每个搜索结果的 highlight 字段返回。即使正文没有作为普通输出字段返回,Milvus 也可以取得高亮所需的文本并生成片段,避免为了展示少量重点而返回完整正文。
语义高亮:对文本进行单独解读
词法高亮的匹配前提是查询和文档共享相同的词汇,但这也构成了它的能力边界。
当二者语义相关但表述完全不同时 —— 比如用户搜 “账号登不上怎么恢复”,文档里写的是 “连续验证失败后可由管理员解除账户锁定”—— 词法匹配就很难精准定位重点,这时候就需要语义高亮发挥作用。
语义高亮是可以搜索结果返回后,通过独立的语义模型对文本做二次解读,独立判断查询与各文本片段的语义关联度,筛选出最相关的内容进行标记。这样,哪怕查询和文档没有重合的关键词,只要语义相通,就都能被准确识别出来。
但是在构建语义高亮能力的过程中,我们发现,市面上各种已有的语义高亮模型,要么只支持英文,要么上下文窗口太小(512 token),要么协议不友好(不允许商业使用)。没有一个能同时满足:中英文都强、窗口够大、泛化能力好、协议友好。
所以,我们构建并开源了内部最新的Semantic Highlight(语义高亮)模型并将其作为Milvus 3.0能力的一环。
它不仅支持中英文双语处理,帮助用户更好的理解高亮核心内容。同时,由于Semantic Highlight 和 Context Pruning 上下文剪枝本质是同一技术的一体两面。这个能力也可以用于 Context Pruning 场景,在 Agent 应用中对上下文做精准裁剪,降低大模型的 token 成本。

使用时,只要通过 SemanticHighlighter 传入查询语句、待分析的文本字段和对应的模型部署 ID,返回结果就会包含带高亮标记的片段,以及对应的语义相关性分数。
from pymilvus import SemanticHighlighter
highlighter = SemanticHighlighter(
queries=["怎样恢复无法登录的账号"],
input_fields=["content"],
pre_tags=["<mark>"],
post_tags=["</mark>"],
model_deployment_id="your-model-deployment",
)
results = client.search(
collection_name="support_articles",
data=[query_embedding],
anns_field="embedding",
search_params={"metric_type": "COSINE"},
limit=10,
output_fields=["title"],
highlighter=highlighter,
)
其中,queries 提供需要理解的问题,input_fields 指定需要分析的文本字段。返回结果中除了相关片段,还可以包含对应的片段分数。
场景上,语义高亮适合长文档问答、RAG 引用、客服知识库和查询改写较多的场景。它寻找的是语义关联,而不是要求查询和文档共享相同 token。
使用须知
需要注意的是,语法高亮与语义高亮均为基于搜索结果的后处理能力,不参与召回与排序,不影响结果顺序与分数,也不能完整解释相关性分数的计算过程。
此外,当前 Milvus 实现中的语义高亮依赖配置好的外部高亮服务或模型部署,不是通用的本地离线能力。具体可用性取决于产品、部署方式和版本,应以目标环境文档为准。



JOTO 企业落地观察
- 词法高亮适用于结构清晰、术语统一的垂直领域知识库,企业可快速集成以降低RAG上下文长度,但需同步维护分词器与业务术语表的一致性。
- 语义高亮虽能缓解表述差异问题,但其依赖外部模型部署,对企业AI基础设施提出更高要求;团队需评估模型服务SLA、中文语义覆盖度及商用协议合规性。
- 两类高亮均属后处理能力,不改变原始召回结果,这意味着企业仍需在向量/稀疏检索层保障基础召回质量,不能将噪声过滤完全寄托于高亮环节。
- 高亮片段本身构成轻量级Context Pruning输出,可直接对接Agent的prompt工程模块,减少人工设计摘要模板的工作量,但需注意片段间逻辑断层对推理连贯性的影响。
立即咨询 JOTO
JOTO 提供覆盖企业智能体规划与搭建、AI 平台私有化部署、RAG 知识工程、AI 安全治理、FDE 驻场共创及持续运营优化的全周期 AI 落地服务,帮助企业把验证中的 AI 能力转化为安全、可控、可持续迭代的生产力。 联系 JOTO 获取 AI 落地咨询
想把这些做法用到你的业务里?
留下你的场景和痛点,我们帮你判断从哪一步开始。
联系我们


