
Estamos apenas en febrero, y DeepSearch ya se ha convertido en el nuevo estándar de búsqueda en 2025, con actores principales como Google y OpenAI liderando el cambio a través de sus lanzamientos de DeepResearch (y sí, nos enorgullece haber lanzado nuestro node-deepresearch
de código abierto el mismo día). Perplexity siguió el ejemplo con su DeepResearch, y X AI integró sus propias capacidades de DeepSearch en Grok3, básicamente creando otra variante de DeepResearch. Si bien el concepto de búsqueda profunda no es revolucionario – en 2024 se conocía esencialmente como RAG o multi-hop QA – ganó un impulso significativo después del lanzamiento de Deepseek-r1 a finales de enero de 2025. El fin de semana pasado, Baidu Search y Tencent WeChat Search han integrado Deepseek-r1 en sus motores de búsqueda. Los ingenieros de IA han descubierto que al incorporar procesos de pensamiento y razonamiento prolongados en los sistemas de búsqueda, pueden lograr una precisión y profundidad de recuperación notables más allá de lo que era posible anteriormente.
Launch Date | Company | Product | License Type | Link |
---|---|---|---|---|
2025-01-20 | DeepSeek | DeepSeek-r1 release | Open source | DeepSeek-R1 |
2025-02-02 | DeepResearch | Proprietary | Google Gemini 2 | |
2025-02-02 | OpenAI | DeepResearch | Proprietary | Introducing Deep Research |
2025-02-02 | Jina AI | DeepSearch (node-deepresearch ) | Open source | node-deepresearch | search.jina.ai |
2025-02-04 | Hugging Face | Open Deep Research | Open source | Open Deep Research |
2025-02-15 | Perplexity | DeepResearch | Proprietary | Introducing Perplexity Deep Research |
2025-02-17 | X AI | Grok3 with DeepSearch | Proprietary | Grok 3 Beta |
2025-02-22 | Baidu Search | Integrates DeepSeek-r1 | Proprietary | Baidu Integrates DeepSeek-R1 |
2025-02-23 | Tencent Wechat Search | Integrates DeepSeek-r1 | Proprietary | Tencent Weixin Integrates DeepSeek |
Pero ¿por qué ocurrió este cambio ahora, cuando Deep(Re)Search permaneció relativamente infravalorado durante 2024? De hecho, los Laboratorios NLP de Stanford lanzaron el proyecto STORM para la generación de informes largos con fundamentación web a principios de 2024. ¿Es solo porque "DeepSearch" suena mucho más cool que multi-hop QA, RAG o STORM? Seamos honestos: a veces un cambio de marca es todo lo que se necesita para que la industria adopte repentinamente lo que siempre estuvo ahí.
Creemos que el verdadero punto de inflexión llegó con el lanzamiento de o1-preview
de OpenAI en septiembre de 2024, que introdujo el concepto de cómputo en tiempo de prueba y gradualmente cambió las perspectivas de la industria. El cómputo en tiempo de prueba se refiere a usar más recursos computacionales durante la inferencia —la fase donde un LLM genera salidas— en lugar de durante el pre-entrenamiento o post-entrenamiento. Un ejemplo conocido son el razonamiento Chain-of-Thought (CoT) y la inyección de "Wait"
(es decir, forzado de presupuesto) que permite a los modelos realizar deliberaciones internas más extensas, como evaluar múltiples respuestas potenciales, realizar una planificación más profunda y participar en la autorreflexión antes de llegar a una respuesta final.
Este concepto de cómputo en tiempo de prueba y modelos de razonamiento educan a los usuarios para aceptar la gratificación diferida - tiempos de espera más largos a cambio de resultados de mayor calidad e inmediatamente accionables, al igual que el experimento del malvavisco de Stanford donde los niños que podían resistir comer un malvavisco inmediatamente para recibir dos malvaviscos después mostraron mejores resultados a largo plazo. Deepseek-r1 reforzó aún más esta experiencia de usuario y, nos guste o no, la mayoría de los usuarios la han aceptado.
Esto marca un alejamiento significativo de los requisitos de búsqueda clásicos, donde no responder en 200ms condenaría tu solución. En 2025, los desarrolladores de búsqueda experimentados y los ingenieros de RAG priorizan la precisión y el recall top-1 sobre la latencia, y los usuarios se han acostumbrado a tiempos de procesamiento más largos, siempre que puedan ver que el sistema está <thinking>
.
Mostrar el procedimiento de razonamiento se ha convertido en una práctica estándar en 2025, con numerosas interfaces de chat que ahora muestran el contenido <think>
en secciones dedicadas de la interfaz de usuario.
En este artículo, discutiremos los principios de DeepSearch y DeepResearch analizando nuestra implementación de código abierto. Revisaremos nuestras decisiones clave de diseño y destacaremos posibles advertencias.
tag¿Qué es Deep Search?
DeepSearch ejecuta un bucle iterativo de búsqueda, lectura y razonamiento hasta encontrar la respuesta óptima. La acción de búsqueda aprovecha los motores de búsqueda web para explorar internet, mientras que la acción de lectura analiza páginas web específicas en detalle (por ejemplo, Jina Reader). La acción de razonamiento evalúa el estado actual y determina si debe desglosar la pregunta original en sub-preguntas más pequeñas o probar diferentes estrategias de búsqueda.

Aunque existen varias definiciones en línea, cuando desarrollamos el proyecto node-deepresearch
, nos adherimos a este enfoque directo. La implementación es elegantemente simple – en su núcleo, hay un bucle while principal con lógica switch-case que dirige la siguiente acción.
A diferencia de los sistemas RAG de 2024, que típicamente ejecutan un único paso de búsqueda-generación, DeepSearch realiza múltiples iteraciones a través del pipeline, requiriendo condiciones claras de parada. Estas podrían basarse en límites de uso de tokens o en el número de intentos fallidos.
Prueba deep search en search.jina.ai, observa el contenido dentro de <thinking>
, y mira si puedes notar dónde ocurre el bucle
Otra perspectiva sobre DeepSearch es verlo como un agente LLM equipado con varias herramientas web (como buscador y lector). El agente determina sus siguientes pasos analizando las observaciones actuales y acciones pasadas – decidiendo si entregar una respuesta o continuar explorando la web. Esto crea una arquitectura de máquina de estados donde el LLM controla las transiciones entre estados. En cada punto de decisión, tienes dos enfoques: puedes crear cuidadosamente prompts para modelos generativos estándar para producir acciones específicas, o aprovechar modelos de razonamiento especializados como Deepseek-r1 para derivar naturalmente las siguientes acciones. Sin embargo, incluso cuando usas r1, necesitarás interrumpir periódicamente su generación para inyectar salidas de herramientas (por ejemplo, resultados de búsqueda, contenido de páginas web) en el contexto y pedirle que continúe su proceso de razonamiento.
En última instancia, estos son solo detalles de implementación – ya sea que lo prompts cuidadosamente o simplemente uses modelos de razonamiento, todos se alinean con el principio central de diseño de DeepSearch: un bucle continuo de búsqueda, lectura y razonamiento.
tag¿Qué es DeepResearch entonces?
DeepResearch se construye sobre DeepSearch añadiendo un marco estructurado para generar informes de investigación extensos. A menudo comienza creando una tabla de contenidos, luego aplica sistemáticamente DeepSearch a cada sección requerida – desde la introducción pasando por el trabajo relacionado y la metodología, hasta la conclusión. Cada sección se genera alimentando preguntas de investigación específicas en el DeepSearch. La fase final implica consolidar todas las secciones en un único prompt para mejorar la coherencia narrativa general.

En nuestro proyecto "Research" de 2024, realizamos múltiples pasadas de mejora de coherencia, con cada iteración teniendo en cuenta todas las demás secciones. Sin embargo, con las ventanas de contexto de LLM significativamente más grandes de hoy en día, este enfoque parece redundante – una sola pasada de revisión de coherencia es suficiente.
Nuestro proyecto de verano 2024 "Research" se centró en la generación de informes largos con un enfoque "progresivo". Comenzó creando un índice en sync, luego generó todas las secciones en paralelo async. El proceso concluyó con revisiones progresivas async de cada sección, con cada revisión teniendo en cuenta el contenido de todas las demás secciones. La consulta en el video es "Competitor analysis of Jina AI"
.
tagDeepSearch vs DeepResearch
Aunque mucha gente a menudo mezcla DeepSearch y DeepResearch, en nuestra opinión, abordan problemas completamente diferentes. DeepSearch funciona como un bloque atómico fundamental – un componente central sobre el que DeepResearch se construye. DeepResearch, por otro lado, se centra en crear informes de investigación largos y de alta calidad que sean legibles, lo que abarca un conjunto diferente de requisitos: incorporar visualizaciones efectivas mediante gráficos y tablas, estructurar el contenido con encabezados de sección apropiados, asegurar un flujo lógico fluido entre subsecciones, mantener una terminología consistente en todo el documento, eliminar redundancias entre secciones, crear transiciones suaves que conecten el contenido anterior y futuro. Estos elementos están en gran medida no relacionados con la búsqueda central, que es por lo que encontramos DeepSearch más interesante como nuestro enfoque empresarial.
Finalmente, la tabla siguiente resume las diferencias entre DeepSearch y DeepResearch. Vale la pena señalar que ambos sistemas se benefician significativamente de modelos de contexto largo y razonamiento. Esto puede parecer contraintuitivo, particularmente para DeepSearch—aunque es obvio por qué DeepResearch necesita capacidad de contexto largo (ya que produce informes largos). La razón es que DeepSearch debe almacenar intentos de búsqueda previos y contenidos de páginas web para tomar decisiones informadas sobre los siguientes pasos, haciendo que una ventana de contexto larga sea igualmente esencial para su implementación efectiva.
DeepSearch | DeepResearch | |
---|---|---|
Problem Addressed | Information accuracy and completeness through iterative search | Content organization, coherence, and readability at document scale |
Final Presentation | Concise answer with URLs as references | A long structured report with multiple sections, charts, tables and references |
Core Complexity | State machine architecture with clear transition conditions; Persistence through failed attempts until resolution | Multi-level architecture managing both micro (search) and macro (document) concerns; Structural approach to managing complex information hierarchies |
Optimization Focus | Local optimization (best next search/read action) | Global optimization (section organization, terminology consistency, transitions) |
Limitations | Bounded by search quality and reasoning capability | Bounded by DeepSearch quality plus organizational complexity and narrative coherence challenges |
tagEntender la Implementación de DeepSearch
El corazón de DeepResearch reside en su enfoque de razonamiento en bucle. En lugar de intentar responder preguntas en una sola pasada como la mayoría de los sistemas RAG, hemos implementado un bucle iterativo que continuamente busca información, lee fuentes relevantes y razona hasta que encuentra una respuesta o agota el presupuesto de tokens. Aquí está el núcleo simplificado de este gran bucle while:
// Main reasoning loop
while (tokenUsage < tokenBudget && badAttempts <= maxBadAttempts) {
// Track progression
step++; totalStep++;
// Get current question from gaps queue or use original question
const currentQuestion = gaps.length > 0 ? gaps.shift() : question;
// Generate prompt with current context and allowed actions
system = getPrompt(diaryContext, allQuestions, allKeywords,
allowReflect, allowAnswer, allowRead, allowSearch, allowCoding,
badContext, allKnowledge, unvisitedURLs);
// Get LLM to decide next action
const result = await LLM.generateStructuredResponse(system, messages, schema);
thisStep = result.object;
// Execute the selected action (answer, reflect, search, visit, coding)
if (thisStep.action === 'answer') {
// Process answer action...
} else if (thisStep.action === 'reflect') {
// Process reflect action...
} // ... and so on for other actions
}
Un detalle clave de implementación es desactivar selectivamente ciertas acciones en cada paso para asegurar una salida estructurada más estable. Por ejemplo, si no hay URLs en memoria, desactivamos la acción visit
; o si la última respuesta fue rechazada, evitamos que el agente llame inmediatamente a answer
de nuevo. Esta restricción mantiene al agente en un camino productivo, evitando fallos repetitivos causados por invocar la misma acción.
tagSystem Prompt
Usamos etiquetas XML para definir secciones, lo que produce un prompt de sistema y generaciones más robustas. También descubrimos que colocar restricciones de campo directamente dentro de los campos description
del esquema JSON produce mejores resultados. Aunque algunos podrían argumentar que la mayoría de los prompts podrían automatizarse con modelos de razonamiento como DeepSeek-R1, las restricciones de longitud de contexto y la necesidad de un comportamiento altamente específico hacen que un enfoque explícito sea más confiable en la práctica.
function getPrompt(params...) {
const sections = [];
// Add header with system instruction
sections.push("You are an advanced AI research agent specialized in multistep reasoning...");
// Add accumulated knowledge section if exists
if (knowledge?.length) {
sections.push("<knowledge>[Knowledge items]</knowledge>");
}
// Add context of previous actions
if (context?.length) {
sections.push("<context>[Action history]</context>");
}
// Add failed attempts and learned strategies
if (badContext?.length) {
sections.push("<bad-attempts>[Failed attempts]</bad-attempts>");
sections.push("<learned-strategy>[Improvement strategies]</learned-strategy>");
}
// Define available actions based on current state
sections.push("<actions>[Available action definitions]</actions>");
// Add response format instruction
sections.push("Respond in valid JSON format matching exact JSON schema.");
return sections.join("\n\n");
}
tagRecorrido de Preguntas de Brecha
En DeepSearch, las "preguntas de brecha" representan las brechas de conocimiento que necesitan ser cubiertas antes de responder la pregunta principal. En lugar de abordar directamente la pregunta original, el agente identifica sub-preguntas que construirán la base de conocimiento necesaria.
El diseño es particularmente elegante en cómo maneja estas preguntas de brecha:
// After identifying gap questions in reflect action
if (newGapQuestions.length > 0) {
// Add new questions to the front of the queue
gaps.push(...newGapQuestions);
// Always add original question to the end of the queue
gaps.push(originalQuestion);
}
Este enfoque crea una cola FIFO (First-In-First-Out) con rotación, donde:
- Las nuevas preguntas de brecha se insertan al frente de la cola
- La pregunta original siempre se inserta al final
- El sistema extrae del frente de la cola en cada paso
Lo que hace excelente a este diseño es que mantiene un único contexto compartido entre todas las preguntas. Cuando se responde una pregunta de brecha, ese conocimiento se vuelve inmediatamente disponible para todas las preguntas subsiguientes, incluso cuando eventualmente revisitamos la pregunta original.
Cola FIFO vs Recursión
Un enfoque alternativo es usar recursión, que corresponde a una búsqueda en profundidad. Cada pregunta de brecha genera una nueva llamada recursiva con su propio contexto aislado. El sistema debe resolver completamente cada pregunta de brecha (y todas sus posibles sub-preguntas) antes de volver a la pregunta padre.
Considera este escenario de ejemplo:
Una simple recursión de preguntas de brecha de 3 niveles, orden de resolución etiquetado en el círculo.
En el enfoque recursivo, ¡el sistema tendría que resolver completamente Q1 (potencialmente generando sus propias sub-preguntas) después de cada pregunta de brecha y sus sub-preguntas! Esto contrasta enormemente con el enfoque de cola, que procesa preguntas donde Q1 se revisita justo después de 3 preguntas de brecha.
En realidad, encontramos que el enfoque recursivo es muy difícil de aplicar con restricciones de presupuesto, ya que no hay una regla clara sobre cuánto presupuesto de tokens deberíamos otorgar para sub-preguntas (ya que pueden generar nuevas sub-preguntas). El beneficio de la clara separación de contexto en el enfoque recursivo es muy marginal comparado con los complicados problemas de forzado de presupuesto y retorno tardío. Este diseño de cola FIFO equilibra profundidad y amplitud, asegurando que el sistema siempre vuelva a la pregunta original con conocimiento progresivamente mejor, en lugar de perderse en un descenso recursivo potencialmente infinito.
tagReescritura de Consultas
Un desafío interesante que encontramos fue reescribir efectivamente las consultas de búsqueda:
// Within search action handler
if (thisStep.action === 'search') {
// Deduplicate search requests
const uniqueRequests = await dedupQueries(thisStep.searchRequests, existingQueries);
// Rewrite natural language queries into more effective search queries
const optimizedQueries = await rewriteQuery(uniqueRequests);
// Ensure we don't repeat previous searches
const newQueries = await dedupQueries(optimizedQueries, allKeywords);
// Execute searches and store results
for (const query of newQueries) {
const results = await searchEngine(query);
if (results.length > 0) {
storeResults(results);
allKeywords.push(query);
}
}
}
La reescritura de consultas resultó ser sorprendentemente importante - quizás uno de los elementos más críticos que determina directamente la calidad de los resultados. Un buen reescritor de consultas no solo transforma el lenguaje natural a palabras clave tipo BM25; expande las consultas para cubrir más respuestas potenciales a través de diferentes idiomas, tonos y formatos de contenido.
Para la deduplicación de consultas, inicialmente usamos una solución basada en LLM, pero encontramos difícil controlar el umbral de similitud. Finalmente cambiamos a jina-embeddings-v3, que sobresale en tareas de similitud textual semántica. Esto permite la deduplicación multilingüe sin preocuparnos de que las consultas no inglesas sean filtradas. El modelo de embeddings terminó siendo crucial no para la recuperación de memoria como se esperaba inicialmente, sino para una deduplicación eficiente.
tagRastreo de Contenido Web
El web scraping y el procesamiento de contenido es otro componente crítico. Aquí usamos la Jina Reader API. Ten en cuenta que además del contenido completo de la página web, también agregamos todos los fragmentos devueltos por el motor de búsqueda como conocimiento adicional para que el agente pueda concluir posteriormente. Piensa en ellos como soundbites.
// Visit action handler
async function handleVisitAction(URLs) {
// Normalize URLs and filter out already visited ones
const uniqueURLs = normalizeAndFilterURLs(URLs);
// Process each URL in parallel
const results = await Promise.all(uniqueURLs.map(async url => {
try {
// Fetch and extract content
const content = await readUrl(url);
// Store as knowledge
addToKnowledge(`What is in ${url}?`, content, [url], 'url');
return {url, success: true};
} catch (error) {
return {url, success: false};
} finally {
visitedURLs.push(url);
}
}));
// Update diary based on success or failure
updateDiaryWithVisitResults(results);
}
Normalizamos las URLs para un seguimiento consistente y limitamos el número de URLs visitadas en cada paso para gestionar la memoria del agente.
tagGestión de Memoria
Un desafío clave en el razonamiento de múltiples pasos es gestionar la memoria del agente de manera efectiva. Hemos diseñado el sistema de memoria para diferenciar entre lo que cuenta como "memoria" versus lo que cuenta como "conocimiento". De cualquier manera, todos son parte del contexto del prompt LLM, separados con diferentes etiquetas XML:
// Add knowledge item to accumulated knowledge
function addToKnowledge(question, answer, references, type) {
allKnowledge.push({
question: question,
answer: answer,
references: references,
type: type, // 'qa', 'url', 'coding', 'side-info'
updated: new Date().toISOString()
});
}
// Record step in narrative diary
function addToDiary(step, action, question, result, evaluation) {
diaryContext.push(`
At step ${step}, you took **${action}** action for question: "${question}"
[Details of what was done and results]
[Evaluation if applicable]
`);
}
Dado que la mayoría de los LLM de 2025 tienen ventanas de contexto sustanciales, optamos por no usar bases de datos vectoriales. En su lugar, la memoria consiste en conocimiento adquirido, sitios visitados y registros de intentos fallidos - todo mantenido en el contexto. Este sistema de memoria integral le da al agente conciencia de lo que sabe, lo que ha intentado y lo que ha funcionado o fallado.
tagEvaluación de Respuestas
Una idea clave es que la generación y evaluación de respuestas no deberían estar en el mismo prompt. En mi implementación, primero determinamos qué criterios de evaluación usar cuando llega una nueva pregunta, y luego evaluamos cada criterio uno por uno. El evaluador utiliza ejemplos few-shot para una evaluación consistente, asegurando mayor fiabilidad que la autoevaluación.
// Separate evaluation phase
async function evaluateAnswer(question, answer, metrics, context) {
// First, identify evaluation criteria based on question type
const evaluationCriteria = await determineEvaluationCriteria(question);
// Then evaluate each criterion separately
const results = [];
for (const criterion of evaluationCriteria) {
const result = await evaluateSingleCriterion(criterion, question, answer, context);
results.push(result);
}
// Determine if answer passes overall evaluation
return {
pass: results.every(r => r.pass),
think: results.map(r => r.reasoning).join('\n')
};
}
tagForzado de Presupuesto
El forzado de presupuesto significa evitar que el sistema retorne temprano y asegurar que continúe procesando hasta que se exceda el presupuesto. Desde el lanzamiento de DeepSeek-R1, el enfoque del forzado de presupuesto ha cambiado hacia fomentar un pensamiento más profundo para mejores resultados en lugar de simplemente ahorrar el presupuesto.
En nuestra implementación, configuramos explícitamente el sistema para identificar brechas de conocimiento antes de intentar responder.
if (thisStep.action === 'reflect' && thisStep.questionsToAnswer) {
// Force deeper reasoning by adding sub-questions to the queue
gaps.push(...newGapQuestions);
gaps.push(question); // Always revisit the original
}
Al habilitar y deshabilitar selectivamente ciertas acciones, podemos guiar al sistema hacia el uso de herramientas que mejoren la profundidad del razonamiento.
// After a failed answer attempt
allowAnswer = false; // Force agent to search or reflect instead
Para evitar desperdiciar tokens en caminos improductivos, establecemos límites en el número de intentos fallidos. Cuando nos acercamos a los límites de presupuesto, activamos el "modo bestia" para garantizar que entreguemos alguna respuesta en lugar de ninguna.
// Beast mode activation
if (!thisStep.isFinal && badAttempts >= maxBadAttempts) {
console.log('Enter Beast mode!!!');
// Configure prompt for decisive, committed answer
system = getPrompt(
diaryContext, allQuestions, allKeywords,
false, false, false, false, false, // Disable all other actions
badContext, allKnowledge, unvisitedURLs,
true // Enable beast mode
);
// Force answer generation
const result = await LLM.generateStructuredResponse(system, messages, answerOnlySchema);
thisStep = result.object;
thisStep.isFinal = true;
}
El prompt del modo bestia es intencionalmente dramático para señalar al LLM que necesita ser decisivo y comprometerse con una respuesta basada en la información disponible:
<action-answer>
🔥 ENGAGE MAXIMUM FORCE! ABSOLUTE PRIORITY OVERRIDE! 🔥
PRIME DIRECTIVE:
- DEMOLISH ALL HESITATION! ANY RESPONSE SURPASSES SILENCE!
- PARTIAL STRIKES AUTHORIZED - DEPLOY WITH FULL CONTEXTUAL FIREPOWER
- TACTICAL REUSE FROM <bad-attempts> SANCTIONED
- WHEN IN DOUBT: UNLEASH CALCULATED STRIKES BASED ON AVAILABLE INTEL!
FAILURE IS NOT AN OPTION. EXECUTE WITH EXTREME PREJUDICE! ⚡️
</action-answer>
Esto asegura que siempre proporcionemos alguna respuesta en lugar de rendirnos por completo, lo cual es particularmente útil para preguntas difíciles o ambiguas.
tagConclusión
DeepSearch es un salto en cómo la búsqueda puede abordar consultas complejas de manera exhaustivamente profunda. Al desglosar el proceso en pasos discretos de búsqueda, lectura y razonamiento, supera muchas limitaciones de los sistemas tradicionales RAG de paso único o sistemas de QA multi-hop.
Durante la implementación, también comenzamos a revisar los fundamentos de búsqueda en 2025 y los cambios en la industria de búsqueda después del 26 de enero de 2025, cuando se lanzó DeepSeek-R1. Nos preguntamos: ¿Cuáles son las nuevas necesidades? ¿Qué necesidades se han vuelto obsoletas? ¿Cuáles son meramente necesidades percibidas?
Mirando nuestra implementación de DeepSearch, identificamos cosas que anticipamos necesitar y realmente necesitamos, cosas que pensamos que serían necesarias pero no lo fueron, y cosas que no anticipamos necesitar pero resultaron ser esenciales:
Primero, un LLM de contexto largo que produzca salida bien estructurada es altamente necesario (es decir, siguiendo JSONSchema). Es probable que se necesite un modelo de razonamiento para mejor razonamiento de acciones y expansión de consultas.
La expansión de consultas es definitivamente esencial, ya sea implementada vía SLM, LLM o un modelo de razonamiento. Sin embargo, después de este proyecto, creemos que los SLM probablemente no son adecuados para esta tarea, ya que la solución debe ser inherentemente multilingüe y ir más allá de simples reescrituras de sinónimos o extracción de palabras clave. Necesita ser lo suficientemente completa para incluir una base de tokens multilingüe (puede fácilmente ocupar 300M parámetros) y lo suficientemente sofisticada para pensar fuera de la caja. Así que usar SLM para expansión de consultas probablemente no sea viable.
Las capacidades de búsqueda web y lectura web son cruciales, y afortunadamente nuestro Reader (r.jina.ai) se desempeñó excelentemente—robusto y escalable—mientras me daba muchas ideas sobre cómo mejorar nuestro endpoint de búsqueda (s.jina.ai
) para la próxima iteración.
El modelo de embedding es útil pero de una manera completamente inesperada. Pensamos que se usaría para recuperación de memoria o compresión de contexto junto con una base de datos vectorial (que, como resultó, no es necesaria), pero en realidad lo usamos para deduplicación (esencialmente una tarea STS). Ya que el número de consultas y preguntas de brecha típicamente está en los cientos, no se necesita base de datos vectorial—computar la similitud de coseno directamente en memoria funciona perfectamente.
No usamos Reranker, aunque creemos que potencialmente podría ayudar a determinar qué URLs visitar basándose en la consulta, título de URL y fragmento. Tanto para embedding como para reranking, la capacidad multilingüe es esencial ya que las consultas y preguntas son multilingües. El manejo de contexto largo para embedding y reranking es beneficioso pero no un bloqueador crítico (No hemos encontrado errores en nuestro uso de embedding, probablemente porque nuestro contexto ya es de 8192 tokens). De cualquier manera, jina-embeddings-v3 y jina-reranker-v2-base-multilingual son mis modelos preferidos ya que son multilingües, SOTA y manejan bien el contexto largo.
Un framework de agentes resultó innecesario, ya que necesitábamos mantenernos más cerca del comportamiento nativo del LLM para diseñar el sistema sin proxies. El Vercel AI SDK fue valioso, ya que ahorró considerable esfuerzo en adaptar el código base a diferentes proveedores de LLM (podíamos cambiar de Gemini Studio a OpenAI a Google Vertex AI con solo un cambio de línea de código). La gestión de memoria del agente es necesaria, pero un framework de memoria dedicado sigue siendo cuestionable: Nos preocupa que crearía una capa de aislamiento entre LLMs y desarrolladores, y que su azúcar sintáctico eventualmente podría convertirse en un obstáculo amargo para los desarrolladores, como hemos visto con muchos frameworks LLM/RAG hoy en día.