
如果你已经读过我们上一篇经典长文《DeepSearch/DeepResearch 的设计与实现》,那么不妨再深挖一些能大幅提升回答质量的细节。这次,我们将重点关注两个细节:
从长网页提取最优文本段:如何利用迟分(late-chunking)算法,从长网页内容中选取最相关的信息小片段。
对收集到的URL进行重排:如何利用重排器(Reranker) 让 LLM Agent 在几百个URL中聪明地选择爬取哪一个 URL?
可能有人还记得我们上一篇里的结论:“在 DeepSearch 中,Embeddings 模型仅适用于诸如 STS(语义文本相似度)任务之类的查询去重,而 Reranker 甚至不在我们最初的 DeepSearch 编程实现中。”
现在看来,这两类召回模型还是有其价值的,只是用法和我们常规的认知不太一样。我们做搜索一直遵循“80-20”原则,不会为了照顾情绪价值,或为证明自己作为 Embeddings 和 Reranker 提供商的市场存在感而硬上什么模型。我们非常 80-20,非常务实,务实到我们只关心搜索系统的最最本质的需求。
所以,经过数周的反复试验和迭代,我们发现了 Embeddings 和 Reranker 在 DeepSearch/DeepResearch 系统中的一些非常规但非常有效的应用。用了这些方法后,我们显著提高了 Jina DeepSearch 的质量(欢迎大家来体验)。我们也想把这些经验分享给在这个领域一起摸爬滚打的同行们。

🔗 https://search.jina.ai
从长文本中选取最优文本段
问题是这样的:用 Jina Reader 读取网页内容后,我们需要把它作为一条知识,放到 Agent 的上下文里,供它推理。虽然把全部内容一股脑塞进 LLM 的上下文是最省事的办法,但考虑到 Token 成本和生成速度,这肯定不是最好的选择。在实际应用里,我们需要找出内容中与问题最相关的部分,只把这些部分作为知识添加到 Agent 的上下文里。
💡 这里说的是,即使用 Jina Reader 清理成干净 Markdown 后,内容仍然太长的情况。比如 GitHub Issues、Reddit 帖子、论坛讨论和博客文章等长页面中。
基于 LLM 的筛选方法也有同样的成本和延迟问题,所以我们得找找有没有小模型的解决方案:我们需要更小、更便宜,但仍然支持多种语言的模型。这是个关键因素,因为我们没法保证问题或文档永远都是中文的。
我们一边是问题(原始查询或“信息差”问题),另一边是大量的 Markdown 内容,其中大部分内容都是无关紧要的。我们需要选出与问题最相关的片段。这就很像 RAG 社区自 2023 年以来一直在努力解决的分块问题——使用检索器模型只检索相关块,并放到上下文窗口中进行总结。
不过,我们的情况有两个关键区别:
有限数量文档中的有限数量的文本块。
假设每个块大约有 500 个 Token,那么一个典型的长网页文档大约有 20 万 Token(中位数)到 100 万 Token(99 分位)。我们每一步用 Jina Reader 抓取 4-5 个 URL,这样大概会产生几百个文本块。也就是说,几百个向量和几百个余弦相似度。用 JavaScript 在内存里就能轻松处理,根本不需要向量数据库。
我们需要连续的文本块来形成有效的知识摘要。
我们不能接受像 [1-2, 6-7, 9, 14, 17, ...] 这样由分散的句子组成的摘要。更有用的知识摘要应该是像 [3-15, 17-24, ...] 这样的,更能保持文本的连贯性。这样 LLM 更容易从知识源中复制和引用,也能减少“幻觉”。
剩下的都是开发者们抱怨的那些注意事项:每个文本块不能太长,因为向量模型处理不了太长的上下文;分块会导致上下文丢失,并使得每个文本块的向量都是独立同分布的;以及,到底怎么找到既保持可读性又保持语义的最佳边界?如果你知道我们在说什么,那你很可能在你的 RAG 实现中也被这些问题困扰过。
不过长话短说——使用 jina-embeddings-v3 的 迟分(Late Chunking)完美地解决了这三个问题。“迟分”保留了每个块的上下文信息,对边界不敏感,而且 jina-embeddings-v3 本身

最低0.47元/天 解锁文章
2257

被折叠的 条评论
为什么被折叠?



