Selección óptima de segmentos de texto y reordenación de URL en DeepSearch/DeepResearch
Base de conocimientos de IAPublicado hace 5 meses Círculo de intercambio de inteligencia artificial 1.2K 00
Si ya ha leído el último y largo artículo clásico de Jina, "ElDiseño y aplicación de DeepSearch/DeepResearch", entonces merece la pena profundizar un poco más en los detalles que pueden mejorar drásticamente la calidad de tu respuesta. En esta ocasión, nos centraremos en dos detalles:
Extracción de segmentos de texto óptimos de páginas web largas: Cómo utilizar algoritmos de descifrado tardío para seleccionar los fragmentos de información más relevantes de contenidos web extensos. Reorganización de las URL recopiladas¿Cómo usar el Reranker para que el Agente LLM elija inteligentemente qué URL rastrear entre cientos de URLs?
Algunos recordaréis nuestra conclusión en el post anterior de que "En DeepSearch, el modelo Embeddings sólo es adecuado para la desduplicación de consultas en tareas como STS (Semantic Textual Similarity), y Reranker ni siquiera estaba en nuestra implementación original de programación de DeepSearch."
En retrospectiva, ambos tipos de modelos de recuerdo siguen teniendo su valor, sólo que no en la forma en que normalmente pensamos en ellos. Siempre hemos seguido el principio "80-20" en la búsqueda, y no intentamos forzar modelos para ocuparnos del valor emocional, o para demostrar nuestra presencia en el mercado como proveedor de Embeddings y Reranker. Somos muy 80-20, muy pragmáticos.Pragmáticos hasta el punto de que sólo nos preocupamos de las necesidades más esenciales del sistema de búsqueda.
Así que, tras semanas de prueba e iteración, descubrimos algunas aplicaciones poco convencionales pero muy eficaces de Embeddings y Reranker en el sistema DeepSearch/DeepResearch. Después de utilizar estos métodos, mejoramos significativamente la calidad de Jina DeepSearch (te invitamos a experimentarlos). También queremos compartir estas experiencias con nuestros compañeros que están trabajando juntos en este campo.
Selección de segmentos de texto óptimos a partir de un texto largo
El problema es el siguiente: con Jina Lector Después de leer el contenido de la página web, necesitamos ponerlo en el contexto del Agente como una pieza de conocimiento sobre la que razonar. Aunque introducir todo el contenido en el contexto del LLM de una sola vez sería la forma menos engorrosa de hacerlo, dado que el Ficha Coste y velocidad de generación, ésta no es desde luego la mejor opción. En la práctica, tenemos que identificar las partes del contenido que son más relevantes para el problema y añadir sólo esas partes como conocimiento al contexto del Agente.
💡 Aquí hablamos de casos en los que el contenido sigue siendo demasiado largo incluso después de limpiarlo para limpiar Markdown con Jina Reader. Por ejemplo, en páginas largas como GitHub Issues, posts de Reddit, discusiones en foros y posts de blogs.
Los métodos de cribado basados en LLM presentan los mismos problemas de coste y latencia, por lo que habrá que averiguar si existen soluciones con modelos pequeños:Necesitamos modelos más pequeños y baratos que sigan siendo compatibles con varios idiomas.Se trata de un factor clave, ya que no hay garantías de que las preguntas o la documentación estén siempre en chino.
Por un lado tenemos la pregunta (la consulta original o pregunta "con poca información") y por el otro un montón de contenido Markdown, gran parte del cual es irrelevante. Tenemos que seleccionar los elementos más relevantes para la pregunta. Es muy parecido a RAG El problema de los trozos que la comunidad lleva intentando resolver desde 2023: utilizar el modelo Retriever para recuperar sólo los trozos relevantes y colocarlos en una ventana contextual para su resumen.
Sin embargo, hay dos diferencias clave en nuestra situación:
Un número finito de bloques de texto en un número finito de documentos.
Suponiendo que cada bloque tenga unos 500 tokens, un documento web largo típico tiene entre 200.000 y 1.000.000 de tokens (percentil 99). Utilizamos Jina Reader para rastrear de 4 a 5 URL a la vez, lo que genera unos cientos de bloques de texto. Eso significa cientos de vectores y cientos de similitudes coseno. Esto se maneja fácilmente en memoria con JavaScript, y no hay necesidad de una base de datos de vectores.
Necesitamos bloques continuos de texto para formar un resumen eficaz de los conocimientos.
No podemos aceptar resúmenes como [1-2, 6-7, 9, 14, 17, ...] Resúmenes que consisten en frases dispersas como ésta. Un resumen de conocimientos más útil sería algo como [3-15, 17-24, ...]. que mantendría mejor la coherencia del texto. Esto facilitaría a LLM la tarea de copiar y citar a partir de fuentes de conocimiento, y también reduciría el número de "ilusiones".
El resto son las mismas advertencias de las que se quejan los desarrolladores: cada bloque de texto no puede ser demasiado largo porque el modelo vectorial no puede manejar un contexto demasiado largo; la fragmentación conduce a la pérdida de contexto y hace que los vectores de cada bloque de texto se distribuyan de forma independiente e idéntica; y, ¿cómo demonios encontrar los límites óptimos que preserven tanto la legibilidad como la semántica? Si sabes de lo que estamos hablando, lo más probable es que también te hayas enfrentado a estos problemas en tus implementaciones de RAG.
En resumen: utilice jina-embeddings-v3
(utilizado como expresión nominal) Chunking tardíoResuelve perfectamente los tres problemas. La "división tardía" conserva la información contextual de cada bloque, no es sensible a los límites y jina-embeddings-v3
en tareas de recuperación multilingüe asimétrica. Los lectores interesados pueden seguir la entrada del blog o el artículo de Jina para conocer los detalles de la implementación general.
🔗 https://arxiv.org/pdf/2409.04701

Diagrama de flujo de la selección de fragmentos mediante puntuaciones tardías
Esta figura ilustra el algoritmo de selección de resúmenes, que funciona como una convolución unidimensional (Conv1D). En primer lugar, el proceso divide un documento largo en trozos de longitud fija y, a continuación, utiliza un algoritmo de partición tardía. jina-embeddings-v3
vectorizar estos bloques de texto. Tras calcular las puntuaciones de similitud entre cada bloque y la pregunta, una ventana deslizante se desplaza sobre estas puntuaciones de similitud para encontrar la ventana con la media más alta.
Este es el código esquemático: uso de partición tardía y agrupación de medias similar a la "convolución 1D" para seleccionar los pasajes más relevantes para el problema.
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");
}
Al llamar a la API de incrustaciones de Jina, recuerde establecer el parámetro task
Configurado para la recuperación, abra el late_chunking
(matemáticas) génerotruncate
También configúralo como se indica a continuación:
await axios.post(
'https://api.jina.ai/v1/embeddings',
{
model: "jina-embeddings-v3",
task: "retrieval.passage",
late_chunking: true,
input: chunks,
truncate: true
},
{ headers });
Si el problema se va a vectorizar, recuerde poner task
cambiar (algo) por (otra cosa) retrieval.query
Entonces apágalo. late_chunking
.
El código de implementación completo puede consultarse en GitHub:https://github.com/jina-ai/node-DeepResearch/blob/main/src/tools/jina-latechunk.ts
Ordenación de URL para "Leer a continuación
El problema es el siguiente: en cada proceso largo de DeepSearch, se puede recoger un montón de URLs de la página de resultados del motor de búsqueda (SERP), y cada vez que se abre una página web, se puede encontrar una gran cantidad de nuevos enlaces a lo largo del camino, incluso después de de-énfasis, sigue siendo fácilmente unos pocos cientos de URLs. Del mismo modo, rellenar los LLM con todas estas URL no va a funcionar, es un desperdicio de valiosa longitud contextual, y lo que es peor, nos dimos cuenta de que los LLM básicamente eligen a ciegas. Así que tuvimos que encontrar una forma de guiar al LLM para que eligiera las URL que tenían más probabilidades de contener la respuesta.
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"
Esta es la mejor manera de configurar Jina Reader para rastrear una página en DeepSearch. Seleccionará todos los enlaces de la página, los pondrá en el campo de enlaces y los eliminará del campo de contenido.
Puede pensar en esto como un "PageRank en contexto", salvo que estamos puntuando cientos de URL en una sola sesión.
Tenemos en cuenta varios factores: la hora de la última actualización, la frecuencia de aparición del nombre de dominio, la estructura de la ruta de la página y, lo que es más importante, la relevancia semántica para la pregunta, para calcular una puntuación compuesta. Sin embargo, sólo podemos utilizar la información disponible antes incluso de hacer clic en la URL.

1. Señales de frecuenciaSi una URL aparece varias veces en diferentes fuentes, se le da más peso. Además, si un nombre de dominio aparece con frecuencia en los resultados de búsqueda, las URL de ese dominio reciben puntos extra. Esto se debe a que, en general, los dominios populares tienden a contener contenidos con más autoridad.
2. Estructura de las rutasAnalizaremos la estructura de rutas de las URL para determinar qué contenidos están agrupados. Si varias URL pertenecen todas a la misma jerarquía de rutas, obtendrán una puntuación más alta; sin embargo, cuanto más profunda sea la ruta, la bonificación de la puntuación disminuirá gradualmente.
3. Pertinencia semánticautilizamos jina-reranker-v2-base-multilingual
para evaluar la relevancia semántica de la pregunta y la información textual (por ejemplo, título y resumen) de cada URL, que es un problema típico de reordenación. La información textual de cada URL procede de varios lugares:
API de la página de resultados del motor de búsqueda (SERP) Devuelve el título y el resumen (https://s.jina.ai/ Esta interfaz, con 'X-Respond-With': 'no-content', devuelve sólo el título y el resumen, no el contenido específico). Texto de anclaje para las URL de la página (utilizando la interfaz https://r.jina.ai y configurando 'X-With-Links-Summary': 'all' devuelve información resumida, o texto de anclaje, para todos los enlaces de la página).
4. Última actualizaciónAlgunas de las consultas de DeepSearch tienen altos requisitos de actualidad, por lo que, en general, cuanto más reciente sea la URL, mayor será el valor. Sin embargo, sin la capacidad de indexación a gran escala de Google, es difícil determinar con precisión la última hora de actualización de una página web. Utilizamos una combinación de las siguientes señales para proporcionar una marca de tiempo con una puntuación de confianza, de modo que podamos dar prioridad a mostrar el contenido más reciente cuando sea necesario:
Funciones de filtrado proporcionadas por la API SERP (por ejemplo, el parámetro tbs de s.jina.ai, que permite filtrar por tiempo). Análisis de la información del encabezado HTTP (como los campos Last-Modified y ETag). Extracción de metadatos (por ejemplo, metaetiquetas y marcas de tiempo de Schema.org). Reconocimiento de patrones de contenido (reconoce fechas visibles en HTML). Métricas para plataformas CMS específicas (por ejemplo, WordPress, Drupal, Ghost, etc.)
5. Contenidos restringidosContenido restringido: Algunas plataformas de redes sociales tienen contenido restringido o cuyo acceso requiere un pago. No hay forma de acceder legalmente a este contenido sin iniciar sesión. Por lo tanto, mantenemos activamente una lista negra de estas URL y dominios problemáticos, bajando su clasificación y evitando malgastar recursos informáticos en este contenido inaccesible.
6. Diversidad de nombres de dominioA veces, las principales URL son todas del mismo dominio, lo que puede hacer que DeepSearch caiga en un "óptimo local", afectando a la calidad de los resultados finales. Como ya se ha mencionado, las principales URL proceden todas de StackOverflow, por lo que, para aumentar la diversidad de los resultados, podemos utilizar una estrategia de "exploración y explotación": seleccionar las K principales URL de cada dominio.
El código completo de la ordenación de URL está disponible en nuestro 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>
resúmenes
Desde que DeepSearch de Jina estuvo disponible el 2 de febrero de 2025, se han descubierto dos detalles de ingeniería que pueden mejorar drásticamente la calidad.Curiosamente, ambos detalles utilizan modelos multilingües Embedding y Reranker de forma "en ventana de contexto".No es nada comparado con los enormes índices precalculados que suelen requerir estos modelos.
Esto puede presagiar que el futuro de la tecnología de búsqueda se moverá en una dirección polarizada. Podemos tomar prestada la teoría de los procesos duales de Kahneman para entender esta tendencia:
Piensa rápido. Pensar rápido (grep, BM25, SQL): búsqueda rápida de patrones basada en reglas con un cálculo mínimo. piensa despacio Pensar despacio (LLM): razonamiento exhaustivo con profunda comprensión contextual, pero intensivo desde el punto de vista computacional. mediobanda A medio pensar (Embedding, Reranker et al. Recall Model): tiene cierta comprensión semántica, mejor que la simple coincidencia de patrones, pero mucha menos inferencia que LLM.
Una posibilidad es:Las arquitecturas de búsqueda en dos niveles son cada vez más popularesEl ligero y eficiente SQL/BM25 se encarga de la entrada de la recuperación y luego alimenta los resultados directamente al LLM para la recuperación de la salida. El valor residual del modelo de nivel intermedio se desplaza entonces a tareas dentro de una ventana de contexto específica: por ejemplo, filtrado, desduplicación, ordenación, etc. En estos escenarios, sería ineficiente realizar el razonamiento completo con LLM en su lugar.
Pero en fin.Selección de clips clave responder cantando Clasificación de URL Sigue siendo el aspecto fundamental que afecta directamente a la calidad de un sistema DeepSearch/DeepResearch. Esperamos que nuestros hallazgos te ayuden a mejorar tu propio sistema.
La ampliación de la consulta es otro factor clave para determinar la calidad.Verduras.Estamos evaluando activamente una variedad de enfoques, que van desde simples reescrituras basadas en Prompt, pasando por pequeños modelos, hasta enfoques basados en la inferencia. Esté atento a los resultados de nuestras próximas investigaciones en este sentido.
© declaración de copyright
El artículo está protegido por derechos de autor y no debe reproducirse sin autorización.
Artículos relacionados
Sin comentarios...