Оптимальный выбор сегмента текста и перегруппировка URL в DeepSearch/DeepResearch
Если вы уже прочитали последний длинный классический пост Джины "TheРазработка и реализация DeepSearch/DeepResearch", то стоит немного углубиться в детали, которые могут значительно улучшить качество вашего ответа. На этот раз мы сосредоточимся на двух деталях:
Извлечение оптимальных сегментов текста из длинных веб-страниц: Как использовать алгоритмы позднего чанкинга для выделения наиболее релевантных фрагментов информации из длинного веб-контента. Перегруппировка собранных URL-адресов: Как использовать реранкер, чтобы позволить LLM Agent разумно выбирать URL для ползания среди сотен URL?
Некоторые из вас, возможно, помнят наш вывод в предыдущей заметке о том, что "в DeepSearch модель Embeddings подходит только для дедупликации запросов для таких задач, как STS (Semantic Textual Similarity), а Reranker даже не был включен в нашу первоначальную программную реализацию DeepSearch".
Оглядываясь назад, можно сказать, что оба типа моделей отзыва по-прежнему имеют свою ценность, просто не в том виде, в котором мы обычно о них думаем. Мы всегда следовали принципу "80-20" в поиске, и мы не пытаемся навязать модели, чтобы позаботиться об эмоциональной ценности или доказать свое присутствие на рынке в качестве поставщика вкраплений и реранкеров. Мы придерживаемся принципа "80-20" и очень прагматичны.Прагматичны до такой степени, что заботятся только о самых необходимых потребностях поисковой системы.
Итак, после нескольких недель проб и итераций мы обнаружили несколько нетрадиционных, но очень эффективных применений Embeddings и Reranker в системе DeepSearch/DeepResearch. После использования этих методов мы значительно улучшили качество Jina DeepSearch (приглашаем вас испытать их). Мы также хотим поделиться этим опытом с нашими коллегами, которые вместе работают в этой области.
Выбор оптимальных сегментов текста из длинного текста
Проблема заключается в следующем: с Джина Ридер Прочитав содержимое веб-страницы, мы должны поместить его в контекст агента как часть знаний, о которых он должен рассуждать. Хотя впихнуть все содержимое в контекст LLM одним махом было бы наименее громоздким способом сделать это, учитывая, что Токен С учетом стоимости и скорости генерации это, конечно, не лучший вариант. На практике нам нужно определить части контента, которые наиболее релевантны проблеме, и добавить только эти части в качестве знаний в контекст агента.
💡 Здесь мы говорим о случаях, когда контент остается слишком длинным даже после очистки его в чистый Markdown с помощью Jina Reader. Например, на таких длинных страницах, как GitHub Issues, сообщения на Reddit, обсуждения на форумах и посты в блогах.
Методы скрининга на основе LLM имеют те же проблемы со стоимостью и задержкой, поэтому нам предстоит выяснить, существуют ли какие-либо решения на основе малых моделей:Нам нужны более компактные и дешевые модели, поддерживающие несколько языков.Это очень важный фактор, поскольку нет гарантии, что вопросы или документация всегда будут на китайском языке.
С одной стороны у нас есть вопрос (оригинальный запрос или вопрос о "плохой информации"), а с другой - множество материалов в формате Markdown, большая часть которых не имеет отношения к делу. Нам нужно выбрать наиболее релевантные фрагменты для вопроса. Это очень похоже на RAG Проблема фрагментации, которую сообщество пытается решить с 2023 года - использование модели Retriever для извлечения только релевантных фрагментов и помещения их в контекстное окно для обобщения.
Однако в нашей ситуации есть два ключевых отличия:
Конечное число текстовых блоков в конечном числе документов.
Если предположить, что каждый блок содержит около 500 лексем, то типичный длинный веб-документ содержит от 200 000 до 1 000 000 лексем (99-й процентиль). Мы используем Jina Reader для просмотра 4-5 URL за раз, что создает несколько сотен блоков текста. Это означает сотни векторов и сотни косинусов подобия. Все это легко обрабатывается в памяти с помощью JavaScript, и нет необходимости в базе данных векторов.
Нам нужны непрерывные блоки текста, чтобы сформировать эффективное резюме знаний.
Мы не можем принимать резюме типа [1-2, 6-7, 9, 14, 17, ...]. Резюме, состоящие из разрозненных предложений, вроде этого. Более полезным резюме знаний было бы что-то вроде [3-15, 17-24, ...]. что позволило бы лучше сохранить связность текста. Это облегчит LLM копирование и цитирование из источников знаний, а также уменьшит количество "иллюзий".
Остальное - те же предостережения, на которые жалуются разработчики: каждый блок текста не может быть слишком длинным, потому что векторная модель не справляется со слишком длинным контекстом; разбиение на части приводит к потере контекста и делает векторы в каждом блоке текста независимо и одинаково распределенными; и, черт возьми, как найти оптимальные границы, которые сохраняют и читабельность, и семантику? Если вы понимаете, о чем идет речь, то, скорее всего, вы тоже сталкивались с этими проблемами в своих реализациях RAG.
Но если говорить коротко - используйте jina-embeddings-v3
(используется в форме номинального выражения) Позднее измельчениеОн прекрасно решает все три проблемы. "Позднее разбиение" сохраняет контекстную информацию каждого блока, нечувствительно к границам и jina-embeddings-v3
себя передовым опытом в задачах асимметричного многоязычного поиска. Заинтересованные читатели могут следить за публикацией в блоге Джины или в ее статье, чтобы узнать подробности о реализации в целом.
🔗 https://arxiv.org/pdf/2409.04701

Блок-схема выбора фрагмента с использованием поздних оценок
На этом рисунке показан алгоритм выбора резюме, который работает как одномерная свертка (Conv1D). Сначала длинный документ разбивается на фрагменты фиксированной длины, а затем с помощью функции позднего разбиения jina-embeddings-v3
векторизация этих блоков текста. После вычисления баллов сходства между каждым блоком и вопросом скользящее окно перемещается по этим баллам сходства, чтобы найти окно с наибольшим средним значением.
Вот схема кода: с помощью позднего разбиения и объединения средних, похожего на "1D-свертку", выбираются наиболее релевантные для проблемы отрывки.
function cherryPick(question, longContext, options) {
if (longContext.length < options.snippetLength * options.numSnippets)
return longContext;
const chunks = splitIntoChunks(longContext, options.chunkSize);
const chunkEmbeddings = getEmbeddings(chunks, "retrieval.passage");
const questionEmbedding = getEmbeddings([question], "retrieval.query")[0];
const similarities = chunkEmbeddings.map(embed =>
cosineSimilarity(questionEmbedding, embed));
const chunksPerSnippet = Math.ceil(options.snippetLength / options.chunkSize);
const snippets = [];
const similaritiesCopy = [...similarities];
for (let i = 0; i < options.numSnippets; i++) {
let bestStartIndex = 0;
let bestScore = -Infinity;
for (let j = 0; j <= similarities.length - chunksPerSnippet; j++) {
const windowScores = similaritiesCopy.slice(j, j + chunksPerSnippet);
const windowScore = average(windowScores);
if (windowScore > bestScore) {
bestScore = windowScore;
bestStartIndex = j;
}
}
const startIndex = bestStartIndex * options.chunkSize;
const endIndex = Math.min(startIndex + options.snippetLength, longContext.length);
snippets.push(longContext.substring(startIndex, endIndex));
for (let k = bestStartIndex; k < bestStartIndex + chunksPerSnippet; k++)
similaritiesCopy[k] = -Infinity;
}
return snippets.join("\n\n");
}
При вызове Jina Embeddings API не забудьте установить значение task
Настройтесь на извлечение, откройте late_chunking
(математика) родtruncate
Также настройте его, как показано ниже:
await axios.post(
'https://api.jina.ai/v1/embeddings',
{
model: "jina-embeddings-v3",
task: "retrieval.passage",
late_chunking: true,
input: chunks,
truncate: true
},
{ headers });
Если проблема должна быть векторизована, не забудьте поставить task
обменять (что-л.) на (что-л. другое) retrieval.query
Затем выключите его. late_chunking
.
Полный код реализации можно найти на GitHub:https://github.com/jina-ai/node-DeepResearch/blob/main/src/tools/jina-latechunk.ts
Сортировка URL-адресов для последующего чтения
Проблема заключается в следующем: в каждом длительном процессе DeepSearch вы можете собрать кучу URL со страницы результатов поисковой системы (SERP), и каждый раз, когда вы открываете веб-страницу, вы можете обнаружить множество новых ссылок по пути, даже после снятия акцента, это все еще легко несколько сотен URL. Аналогично, набивать LLM всеми этими URL не получится, это пустая трата ценной контекстной длины, и, что еще хуже, мы обнаружили, что LLM в основном просто выбирают вслепую. Поэтому нам нужно было найти способ направить LLM на выбор URL, которые с наибольшей вероятностью содержат ответ.
curl https://r.jina.ai/https://example.com \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "X-Retain-Images: none" \
-H "X-Md-Link-Style: discarded" \
-H "X-Timeout: 20" \
-H "X-With-Links-Summary: all"
Это лучший способ настроить Jina Reader для просмотра страницы в DeepSearch. Он выделит все ссылки на странице, поместит их в поле links и удалит из поля content.
Вы можете считать это "контекстным PageRank", за исключением того, что мы оцениваем сотни URL за одну сессию.
Мы учитываем несколько факторов: время последнего обновления, частоту встречаемости доменного имени, структуру пути к странице и, самое главное, семантическую релевантность вопросу, чтобы вычислить составной балл. Однако мы можем использовать только ту информацию, которая доступна еще до того, как мы перейдем по URL-адресу.

1. частотные сигналы: Если URL-адрес появляется несколько раз в разных источниках, ему присваивается больший вес. Кроме того, если доменное имя часто появляется в результатах поиска, URL-адресам с этого домена присваиваются дополнительные баллы. Это связано с тем, что популярные домены, как правило, содержат более авторитетный контент.
2. Структура маршрута: Мы анализируем структуру путей URL-адресов, чтобы определить, какой контент сгруппирован вместе. Если несколько URL-адресов принадлежат к одной иерархии путей, они получат более высокий балл; однако чем глубже путь, тем постепенно уменьшается премия.
3. семантическая релевантность: мы используем jina-reranker-v2-base-multilingual
оценить семантическую релевантность вопроса и текстовую информацию (например, название и аннотацию) каждого URL, что представляет собой типичную проблему переупорядочивания. Текстовая информация для каждого URL поступает из нескольких мест:
API Search Engine Results Page (SERP) Возвращает заголовок и краткое содержание (https://s.jina.ai/ Этот интерфейс, с 'X-Respond-With': 'no-content', возвращает только заголовок и краткое содержание, а не конкретное содержимое). Анкорный текст для URL-адресов на странице (при использовании интерфейса https://r.jina.ai и установке параметра 'X-With-Links-Summary': 'all' возвращается краткая информация, она же анкорный текст, для всех ссылок на странице).
4. Последнее обновление: К некоторым запросам DeepSearch предъявляются высокие требования по своевременности, поэтому, как правило, чем новее URL, тем выше значение. Однако без масштабных возможностей индексации Google трудно точно определить время последнего обновления веб-страницы. Мы используем комбинацию следующих сигналов для получения временной метки и доверительной оценки, чтобы при необходимости приоритетно отображать самый свежий контент:
Функции фильтрации, предоставляемые SERP API (например, параметр tbs в s.jina.ai, который позволяет фильтровать по времени). Анализ информации HTTP-заголовка (например, поля Last-Modified и ETag). Извлечение метаданных (например, метатегов и временных меток Schema.org). Content Pattern Recognition (распознает даты, видимые в HTML). Метрики для конкретных платформ CMS (например, WordPress, Drupal, Ghost и т. д.)
5. ограниченный контент: На некоторых платформах социальных сетей есть контент, доступ к которому ограничен или требует оплаты. Не существует способа легально получить доступ к такому контенту без входа в систему. Поэтому мы активно ведем черный список таких проблемных URL и доменов, снижая их рейтинг и избегая траты вычислительных ресурсов на этот недоступный контент.
6. разнообразие доменных именИногда лучшие URL-адреса принадлежат одному и тому же домену, что может привести к тому, что DeepSearch попадет в "локальный оптимум", что повлияет на качество конечных результатов. Как уже говорилось, все лучшие URL-адреса - из StackOverflow, поэтому для увеличения разнообразия результатов мы можем использовать стратегию "исследуй и используй": выбрать K лучших URL-адресов из каждого домена.
Полную реализацию кода сортировки URL можно найти на нашем Github: https://github.com/jina-ai/node-DeepResearch/blob/main/src/utils/url-tools.ts#L192.
<action-visit>
- Crawl and read full content from URLs, you can get the fulltext, last updated datetime etc of any URL.
- Must check URLs mentioned in <question> if any
- Choose and visit relevant URLs below for more knowledge. higher weight suggests more relevant:
<url-list>
+ weight: 0.20 "https://huggingface.co/docs/datasets/en/loading": "Load - Hugging FaceThis saves time because instead of waiting for the Dataset builder download to time out, Datasets will look directly in the cache. Set the environment ...Some datasets may have more than one version based on Git tags, branches, or commits. Use the revision parameter to specify the dataset version you want to load ..."
+ weight: 0.20 "https://huggingface.co/docs/datasets/en/index": "Datasets - Hugging Face🤗 Datasets is a library for easily accessing and sharing datasets for Audio, Computer Vision, and Natural Language Processing (NLP) tasks. Load a dataset in a ..."
+ weight: 0.17 "https://github.com/huggingface/datasets/issues/7175": "[FSTimeoutError] load_dataset · Issue #7175 · huggingface/datasetsWhen using load_dataset to load HuggingFaceM4/VQAv2, I am getting FSTimeoutError. Error TimeoutError: The above exception was the direct cause of the following ..."
+ weight: 0.15 "https://github.com/huggingface/datasets/issues/6465": "`load_dataset` uses out-of-date cache instead of re-downloading a ...When a dataset is updated on the hub, using load_dataset will load the locally cached dataset instead of re-downloading the updated dataset."
+ weight: 0.12 "https://stackoverflow.com/questions/76923802/hugging-face-http-request-on-data-from-parquet-format-when-the-only-way-to-get-i": "Hugging face HTTP request on data from parquet format when the ...I've had to get the data from their data viewer using the parquet option. But when I try to run it, there is some sort of HTTP error. I've tried downloading ..."
</url-list>
</action-visit>
резюме
С тех пор как 2 февраля 2025 года стал доступен DeepSearch Джина, были обнаружены две инженерные детали, которые могут значительно улучшить качество.Интересно, что в обоих случаях многоязычные модели Embedding и Reranker используются в режиме "контекстного окна".Это ничто по сравнению с огромными предварительно вычисленными индексами, которые обычно требуются этим моделям.
Это может предвещать, что будущее поисковых технологий будет развиваться в полярном направлении. Для понимания этой тенденции мы можем позаимствовать теорию двойственных процессов Канемана:
Думайте быстро. Быстрое мышление (grep, BM25, SQL): быстрое сопоставление шаблонов на основе правил с минимальными вычислениями. думать медленно Медленное мышление (LLM): комплексное рассуждение с глубоким пониманием контекста, но требует больших вычислительных затрат. среднийгруппа Середина мысли (Embedding, Reranker и др. Recall Model): имеет некоторое семантическое понимание, лучше, чем простое сопоставление шаблонов, но гораздо меньше выводов, чем LLM.
Один из вариантов:Двухуровневые архитектуры поиска становятся все более популярнымиЛегкий и эффективный SQL/BM25 берет на себя входные данные для поиска, а затем передает результаты непосредственно в LLM для получения выходных данных. Остаточная ценность модели среднего уровня затем переносится на задачи в рамках определенного контекстного окна: например, фильтрация, дедупликация, сортировка и так далее. В этих сценариях было бы неэффективно выполнять все рассуждения с помощью LLM.
Но как бы то ни было.Выбор ключевых клипов ответить пением Сортировка URL По-прежнему остается фундаментальным аспектом, который напрямую влияет на качество системы DeepSearch/DeepResearch. Мы надеемся, что наши выводы помогут вам улучшить вашу собственную систему.
Расширение запросов - еще один ключевой фактор при определении качества.Овощи.Мы активно оцениваем различные подходы, начиная от простых переписываний на основе Prompt, небольших моделей и заканчивая подходами, основанными на выводах. Пожалуйста, с нетерпением ждите результатов наших последующих исследований в этом направлении!
© заявление об авторских правах
Авторское право на статью Круг обмена ИИ Пожалуйста, не воспроизводите без разрешения.
Похожие статьи
Нет комментариев...