Nouvelles
Modèles
API
keyboard_arrow_down
Lecteur
Lisez les URL et effectuez des recherches sur le Web pour de meilleurs LLM de base.
Intégrations
Intégrations multimodales et multilingues de classe mondiale.
Reclasseur
Récupérateur neuronal de classe mondiale pour maximiser la pertinence de la recherche.
Service d'inférence élastique
Exécutez les modèles Jina nativement au sein d'Elasticsearch.
MCP terminalCLIarticlellms.txtsmart_toyAgentsdata_objectSchémamenu_bookDocuments



Se connecter
login
Sélectionner des extraits de contenus longs
Classement des URLs pour la prochaine lecture
Conclusion
Blog technique
mars 12, 2025

Sélection d'extraits et classement des URL dans DeepSearch/DeepResearch

Ces deux détails transforment votre DeepSearch de moyen à exceptionnel : la sélection des meilleurs extraits des pages web volumineuses et le classement des URLs avant le crawling.
Han Xiao
Han Xiao • 11 minutes lues
Guide pratique pour implémenter DeepSearch/DeepResearch
QPS dehors, profondeur dedans. DeepSearch est la nouvelle norme. Trouvez des réponses à travers des boucles de lecture-recherche-raisonnement. Découvrez ce que c'est et comment le construire.
Jina AIHan Xiao

Si vous avez déjà lu notre guide d'implémentation DeepSearch/DeepResearch, plongeons plus profondément dans certains détails qui peuvent grandement améliorer la qualité. Dans cet article, nous nous concentrerons sur deux défis clés : l'utilisation des embeddings pour la sélection d'extraits de pages web longues et l'utilisation de rerankers pour prioriser les URLs à crawler.

Certains se souviendront de notre conclusion précédente indiquant que "les embeddings n'étaient utiles que pour la déduplication de requêtes comme les tâches STS (similarité textuelle sémantique), tandis que les rerankers ne faisaient même pas partie de notre implémentation originale de DeepSearch." Il s'avère que les deux sont toujours très utiles - juste pas de la manière conventionnelle à laquelle on pourrait s'attendre. Nous avons toujours suivi la voie la plus simple possible. Nous n'ajoutons pas de composants juste pour justifier leur existence ou notre valeur en tant que fournisseur d'embeddings et de rerankers. Nous sommes pragmatiques - sur ce dont la recherche a réellement besoin comme fondation.

Ainsi, après des semaines d'expériences et d'itérations, nous avons découvert des utilisations peu communes mais efficaces pour les deux dans les systèmes DeepSearch/DeepResearch. En les appliquant, nous avons significativement amélioré la qualité de Jina DeepSearch (n'hésitez pas à l'essayer). Nous aimerions partager ces insights avec nos collègues praticiens travaillant dans ce domaine.

tagSélectionner des extraits de contenus longs

Le problème est le suivant : après avoir utilisé Jina Reader pour lire le contenu d'une page web, nous devons l'ajouter comme élément de connaissance au contexte de l'agent pour le raisonnement. Bien que déverser tout le contenu dans la fenêtre de contexte du LLM soit la façon la plus simple, ce n'est pas optimal en considérant les coûts en tokens et la vitesse de génération. En pratique, nous devons identifier quelles parties du contenu sont les plus pertinentes pour la question et ajouter sélectivement uniquement ces parties comme connaissance au contexte de l'agent.

💡
Nous parlons des cas où le contenu reste trop long même après le nettoyage markdown de Jina Reader. Cela arrive souvent avec les longues pages comme les issues GitHub, les discussions Reddit, les fils de forum et les articles de blog (y compris beaucoup des nôtres sur jina.ai/news).

Le filtrage basé sur LLM a les mêmes problèmes de coût et de latence, alors cherchons des solutions avec des modèles plus petits : nous avons besoin de modèles plus petits et moins coûteux, mais toujours multilingues – un facteur crucial puisque nous ne pouvons pas garantir que la requête ou les documents seront toujours en anglais.

Nous avons une question d'un côté (soit la requête originale soit une question de gap) et un grand contenu markdown de l'autre côté, où la plupart du contenu est non pertinent. Nous devons sélectionner les extraits les plus pertinents pour la requête. Cela ressemble au problème de chunking auquel la communauté RAG est confrontée depuis 2023 - récupérer uniquement les chunks pertinents en utilisant des modèles de retrieval à placer dans la fenêtre de contexte pour la synthèse. Cependant, il y a deux différences clés dans notre cas :

  1. Chunks limités d'un nombre limité de documents. Si chaque chunk contient environ 500 tokens, alors un document web long typique a environ 200 000 tokens (p50) à 1 000 000 tokens (p99), et nous utilisons Jina Reader pour récupérer 4-5 URLs à chaque étape, cela donnerait environ des centaines de chunks - signifiant des centaines de vecteurs d'embedding et des centaines de similarités cosinus. C'est facilement gérable avec JavaScript en mémoire sans base de données vectorielle.
  2. Nous avons besoin de chunks consécutifs pour former des extraits de connaissance efficaces. Nous ne pouvons pas accepter des extraits combinant des phrases dispersées comme [1-2, 6-7, 9, 14, 17, ...]. Un extrait de connaissance plus utile suivrait des motifs comme [3-15, 17-24, ...] - maintenant toujours un texte consécutif. Cela facilite la copie et la citation par le LLM depuis la source de connaissance et réduit l'hallucination.

Le reste concerne tous les problèmes dont les praticiens se plaignent : chaque chunk ne peut pas être trop long puisque les modèles d'embedding ne peuvent pas bien gérer les longs contextes ; le chunking introduit une perte de contexte et rend les embeddings de chunks i.i.d ; et comment même trouver les meilleurs indices de frontière qui maintiennent à la fois la lisibilité et la sémantique ? Si vous savez de quoi nous parlons, alors vous avez probablement été hanté par ces problèmes dans vos implémentations RAG.

Mais pour faire court - le late-chunking avec jina-embeddings-v3 résout magnifiquement les trois problèmes. Le late chunking maintient l'info de contexte pour chaque chunk, est insensible aux indices de frontière, et jina-embeddings-v3 lui-même est SOTA dans les tâches de recherche multilingue asymétrique. Les lecteurs intéressés peuvent suivre nos articles de blog ou papers pour les détails, mais voici l'implémentation globale.

Ce diagramme illustre l'algorithme de sélection d'extraits, qui fonctionne de manière similaire à Conv1D. Le processus commence par diviser un long document en chunks de longueur fixe, qui sont ensuite intégrés avec jina-embeddings-v3 avec l'option late-chunking activée. Après avoir calculé les scores de similarité entre chaque chunk et la requête, une fenêtre glissante se déplace à travers les scores de similarité pour trouver la fenêtre avec la valeur moyenne la plus élevée.
Ce qu'est réellement le Late Chunking et ce qu'il n'est pas : Partie II
Partie 2 de notre exploration du Late Chunking, une plongée profonde dans les raisons pour lesquelles c'est la meilleure méthode pour les embeddings de chunks et l'amélioration des performances de recherche/RAG.
Jina AIHan Xiao
jina-embeddings-v3 : Embeddings multilingues avec Task LoRA
Nous présentons jina-embeddings-v3, un nouveau modèle d'embedding de texte avec 570 millions de paramètres, qui atteint des performances état de l'art sur les données multilingues et les tâches de recherche en contexte long, supportant des longueurs de contexte jusqu'à 8192 tokens. Le modèle inclut un ensemble d'adaptateurs Low-Rank Adaptation (LoRA) spécifiques aux tâches pour générer des embeddings de haute qualité pour la recherche requête-document, le clustering, la classification et la correspondance de texte. L'évaluation sur le benchmark MTEB montre que jina-embeddings-v3 surpasse les derniers embeddings propriétaires d'OpenAI et Cohere sur les tâches en anglais, tout en obtenant des performances supérieures par rapport à multilingual-e5-large-instruct sur toutes les tâches multilingues. Avec une dimension de sortie par défaut de 1024, les utilisateurs peuvent réduire de manière flexible les dimensions d'embedding jusqu'à 32 sans compromettre les performances, grâce à l'apprentissage de représentation Matryoshka.
arXiv.orgSaba Sturua
Late Chunking : Embeddings de chunks contextuels utilisant des modèles d'embedding à contexte long
De nombreux cas d'utilisation nécessitent de récupérer de plus petites portions de texte, et les systèmes de recherche basés sur des vecteurs denses fonctionnent souvent mieux avec des segments de texte plus courts, car la sémantique est moins susceptible d'être sur-compressée dans les embeddings. Par conséquent, les praticiens divisent souvent les documents textuels en plus petits chunks et les encodent séparément. Cependant, les embeddings de chunks créés de cette manière peuvent perdre des informations contextuelles des chunks environnants, résultant en des représentations sous-optimales. Dans cet article, nous introduisons une nouvelle méthode appelée late chunking, qui exploite des modèles d'embedding à contexte long pour d'abord intégrer tous les tokens du texte long, avec le chunking appliqué après le modèle transformer et juste avant le mean pooling - d'où le terme late dans son nom. Les embeddings de chunks résultants capturent l'information contextuelle complète, conduisant à des résultats supérieurs à travers diverses tâches de recherche. La méthode est suffisamment générique pour être appliquée à une large gamme de modèles d'embedding à contexte long et fonctionne sans entraînement supplémentaire. Pour augmenter davantage l'efficacité du late chunking, nous proposons une approche de fine-tuning dédiée pour les modèles d'embedding.
arXiv.orgMichael Günther
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");
}

Utilisation du découpage tardif et du pooling moyen de type Conv1D pour sélectionner le meilleur extrait par rapport à la question.

Assurez-vous d'appeler l'API Jina Embeddings avec le paramètre task de retrieval, late_chunking et truncate définis comme ci-dessous :

await axios.post(
  'https://api.jina.ai/v1/embeddings',
  {
    model: "jina-embeddings-v3",
    task: "retrieval.passage",
    late_chunking: true,
    input: chunks,
    truncate: true
  }, 
  { headers }); 

Pour l'embedding de la question, assurez-vous de changer task en retrieval.query et de désactiver late_chunking

L'implémentation complète est disponible sur Github :

node-DeepResearch/src/tools/jina-latechunk.ts at main · jina-ai/node-DeepResearch
Keep searching, reading webpages, reasoning until it finds the answer (or exceeding the token budget) - jina-ai/node-DeepResearch
GitHubjina-ai

tagClassement des URLs pour la prochaine lecture

Le problème est le suivant : pendant une session DeepSearch, vous allez probablement collecter beaucoup d'URLs à partir des pages de résultats des moteurs de recherche (SERP) et en découvrir encore plus à chaque fois que vous lisez des pages web individuelles (ces liens sur la page). Le nombre total d'URLs uniques peut facilement atteindre les centaines. Encore une fois, simplement déverser toutes les URLs directement dans le contexte du LLM est inefficace - cela gaspille un espace précieux dans la fenêtre de contexte et, plus problématique encore, nous avons constaté que les LLMs choisissent essentiellement les URLs au hasard. Il est crucial de guider le LLM vers les URLs qui ont la plus grande probabilité de contenir la réponse dont vous avez besoin.

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"

Meilleure option pour utiliser Jina Reader pour explorer une page dans DeepSearch. Cela collectera tous les liens de la page dans un champ links séparé, et les supprimera du champ content.

Considérez ce problème comme un PageRank en contexte où nous devons pondérer des centaines d'URLs pendant une session. Nous classons les URLs en fonction de multiples facteurs qui combinent la dernière mise à jour, la fréquence du domaine, la structure du chemin et, plus important encore, la pertinence sémantique par rapport à la requête pour créer un score composite. Rappelez-vous que nous ne pouvons utiliser que les informations disponibles avant de visiter réellement l'URL :

Signaux de fréquence : Les URLs qui apparaissent plusieurs fois à travers différentes sources reçoivent un poids supplémentaire. Les URLs provenant de domaines qui apparaissent fréquemment dans les résultats de recherche reçoivent un boost, car les domaines populaires contiennent souvent du contenu faisant autorité.

Structure du chemin : Nous analysons les chemins des URLs pour identifier les clusters de contenu. Les URLs au sein de hiérarchies de chemins communes reçoivent des scores plus élevés, avec un facteur de décroissance appliqué aux chemins plus profonds.

Pertinence sémantique : Nous utilisons jina-reranker-v2-base-multilingual pour évaluer la pertinence sémantique entre la question et les informations textuelles de chaque URL, ce qui est un problème classique de reclassement. Les informations textuelles de chaque URL proviennent de :

  • Titre et extraits des résultats de l'API SERP (https://s.jina.ai/ avec 'X-Respond-With': 'no-content')
  • Texte d'ancrage des URLs de la page (https://r.jina.ai avec 'X-With-Links-Summary': 'all')

Dernière mise à jour : Certaines requêtes DeepSearch sont sensibles au temps, donc les URLs récemment mises à jour sont plus précieuses que les anciennes. Sans être un moteur de recherche majeur comme Google, déterminer de manière fiable la dernière date de mise à jour est un défi. Nous avons implémenté une approche multicouche qui combine les signaux suivants et fournit un horodatage avec score de confiance qui priorise le contenu plus récent lorsque nécessaire.

  • Filtres API SERP (comme le paramètre tbs de s.jina.ai pour filtrer par récence)
  • Analyse des en-têtes HTTP (Last-Modified, ETag)
  • Extraction de métadonnées (meta tags, horodatages Schema.org)
  • Reconnaissance de motifs de contenu (dates visibles en HTML)
  • Indicateurs spécifiques aux CMS pour les plateformes comme WordPress, Drupal et Ghost

Contenu restreint : Certains contenus sur les plateformes de médias sociaux sont restreints ou simplement derrière des paywalls, et sans connexion ou violation de leurs CGU, il n'y a pas de moyen légitime d'accéder à ce contenu. Nous devrions activement maintenir une liste d'URLs et de noms d'hôtes problématiques pour réduire leurs classements, évitant ainsi de perdre du temps sur du contenu inaccessible.

Diversité des domaines : Dans certains cas, les URLs les mieux pondérées proviennent toutes des mêmes noms d'hôtes, ce qui peut piéger DeepSearch dans un optimum local et réduire la qualité finale des résultats. Regardez les exemples ci-dessus où toutes les URLs principales proviennent de StackOverflow. Pour améliorer la diversité, nous pouvons implémenter une approche d'exploration-exploitation en sélectionnant les k URLs les mieux classées de chaque nom d'hôte.

L'implémentation complète du classement des URLs est disponible sur notre Github.

node-DeepResearch/src/utils/url-tools.ts at main · jina-ai/node-DeepResearch
Keep searching, reading webpages, reasoning until it finds the answer (or exceeding the token budget) - jina-ai/node-DeepResearch
GitHubjina-ai
<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>

N'oubliez pas d'inclure les poids des URL dans le contexte de l'agent et d'instruire les LLM à respecter ces poids.

tagConclusion

Depuis la sortie de notre système DeepSearch le 2 février 2025, nous avons découvert deux détails d'implémentation qui ont considérablement amélioré la qualité. Fait remarquable, les deux utilisent des embeddings et des rerankers multilingues de manière « in-context » - opérant à une échelle beaucoup plus petite que les index pré-calculés que ces modèles nécessitent habituellement. Cela explique notre oubli initial.

Cela indique une fascinante polarisation dans l'avenir de la technologie de recherche. Considérons un cadre analogue à la théorie du double processus de Kahneman :

  • Pensée rapide (grep, BM25, SQL) : Mise en correspondance de motifs rapide et régie par des règles avec des exigences de calcul minimales.
  • Pensée lente (LLM) : Raisonnement complet avec une compréhension contextuelle approfondie, nécessitant des calculs importants.
  • Pensée intermédiaire (embeddings, rerankers) : Pris dans les limbes ? Trop « avancé »/sémantique pour une simple correspondance de motifs mais manquant de véritables capacités de raisonnement.

Nous assistons peut-être à la popularité d'une architecture bifurquée où SQL/BM25 léger et efficace gère la récupération initiale du contenu, alimentant directement des LLM puissants pour un traitement approfondi. Ces LLM intègrent de plus en plus les fonctions sémantiques qui nécessitaient auparavant des modèles spécialisés de niveau intermédiaire. Le rôle restant pour les modèles de pensée intermédiaire se déplace vers des tâches in-context spécialisées : filtrage, déduplication et opérations à portée limitée où un raisonnement complet serait inefficace.

Néanmoins, la sélection d'extraits critiques et le classement des URL restent des composants fondamentaux ayant un impact direct sur la qualité du système DeepSearch/DeepResearch. Nous espérons que nos observations susciteront des améliorations dans vos propres implémentations.

L'expansion des requêtes continue d'être un autre déterminant crucial de la qualité. Nous évaluons activement plusieurs approches, allant des réécritures basiques basées sur les prompts aux petits modèles de langage et aux méthodes basées sur le raisonnement. Attendez-vous à nos prochaines découvertes sur ce front bientôt. Restez à l'écoute.

Catégories:
Blog technique
rss_feed

En savoir plus
mars 11, 2026 • 7 minutes lues
Bootstrapping d'embeddings audio à partir de LLM multimodaux
Han Xiao
Abstract illustration of a sound wave or heartbeat, formed by blue, orange, and gray dots on a white background.
mars 06, 2026 • 6 minutes lues
Identifier les modèles d'embeddings à partir de valeurs numériques brutes
Han Xiao
Fingerprint illustration made from numbers, showcasing digital and high-tech design on a light background.
septembre 09, 2025 • 11 minutes lues
Les Embeddings multimodaux dans Llama.cpp et GGUF
Andrei Ungureanu
Alex C-G
Cartoon llama in the center of a white background, emitting laser-like beams from its eyes. The illustration creates a playfu
Des bureaux
location_on
Sunnyvale, Californie
710 Lakeway Dr, Ste 200, Sunnyvale, CA 94085, États-Unis
location_on
Berlin, Allemagne
Prinzessinnenstraße 19-20, 10969 Berlin, Allemagne
Fondation Recherche
Lecteur
Intégrations
Reclasseur
Service d'inférence élastique
open_in_new
Obtenir la clé API Jina
Limite de taux
Statut de l'API
Entreprise
À propos de nous
Contacter le service commercial
Rédaction
Programme de stage
Télécharger le logo Jina
open_in_new
Télécharger le logo Elastic
open_in_new
Termes
Sécurité
termes et conditions
Confidentialité
Gérer les cookies
email
Jina AI par Elastic © 2020-2026.