[{"data":1,"prerenderedAt":1875},["ShallowReactive",2],{"article-alternates":3,"article-\u002Fes\u002Fai\u002Fgestion-deriva-embeddings-bases-datos-vectoriales-produccion":13},{"i18nKey":4,"paths":5},"ai-006-2026-05",{"de":6,"en":7,"es":8,"fr":9,"it":10,"ru":11,"tr":12},"\u002Fde\u002Fai\u002Fembedding-drift-vector-db-produktion","\u002Fen\u002Fai\u002Fembedding-drift-production-vector-databases","\u002Fes\u002Fai\u002Fgestion-deriva-embeddings-bases-datos-vectoriales-produccion","\u002Ffr\u002Fai\u002Fembedding-drift-gestion-base-donnees-vecteurs-production","\u002Fit\u002Fai\u002Fgestione-drift-embedding-database-vettoriali-produzione","\u002Fru\u002Fai\u002Fembedding-drift-vector-db-production","\u002Ftr\u002Fai\u002Fembedding-drift-uretimde-vector-dbleri-nasil-surdururuz",{"_path":8,"_dir":14,"_draft":15,"_partial":15,"_locale":16,"title":17,"description":18,"publishedAt":19,"modifiedAt":19,"category":14,"i18nKey":4,"tags":20,"readingTime":26,"author":27,"body":28,"_type":1869,"_id":1870,"_source":1871,"_file":1872,"_stem":1873,"_extension":1874},"ai",false,"","Gestión de Deriva de Embeddings: Cómo Mantener Bases de Datos Vectoriales en Producción","Incompatibilidad de embeddings en cambios de modelo, costos de re-indexación e estrategias de migración incremental — sostenibilidad de bases de datos vectoriales en producción","2026-05-18",[21,22,23,24,25],"vector-database","embedding-drift","mlops","retrieval-augmented-generation","model-migration",9,"Roibase",{"type":29,"children":30,"toc":1855},"root",[31,56,63,68,73,78,85,97,102,108,113,118,123,371,376,792,808,814,819,906,911,916,922,927,932,1014,1019,1025,1030,1040,1050,1374,1380,1401,1406,1411,1417,1422,1427,1432,1461,1475,1481,1493,1498,1844,1849],{"type":32,"tag":33,"props":34,"children":35},"element","p",{},[36,39,46,48,54],{"type":37,"value":38},"text","Cuando despliegas sistemas RAG en producción, todo funciona perfecto el primer mes. En el tercero, OpenAI lanza ",{"type":32,"tag":40,"props":41,"children":43},"code",{"className":42},[],[44],{"type":37,"value":45},"text-embedding-3-large",{"type":37,"value":47}," en lugar de ",{"type":32,"tag":40,"props":49,"children":51},{"className":50},[],[52],{"type":37,"value":53},"text-embedding-4",{"type":37,"value":55},", y tú pruebas porque \"el nuevo modelo es mejor\". Los resultados muestran un recall %4 superior. Pero tus 12 millones de documentos siguen indexados con el modelo de embedding anterior. Re-indexar requiere 18 horas y 6.400 dólares en costos de API. Aquí comienza la deriva de embeddings — actualizas el modelo pero el vector store queda obsoleto, el embedding de consulta y los embeddings almacenados se posicionan en variedades diferentes, la precisión del retrieval desciende silenciosamente. Este artículo explica en qué equilibrio costo-calidad realizar migraciones de modelos, cómo diseñar re-indexación incremental y cómo medir deriva en producción.",{"type":32,"tag":57,"props":58,"children":60},"h2",{"id":59},"qué-es-deriva-de-embeddings-y-por-qué-importa",[61],{"type":37,"value":62},"Qué es Deriva de Embeddings y Por Qué Importa",{"type":32,"tag":33,"props":64,"children":65},{},[66],{"type":37,"value":67},"Deriva de embeddings ocurre cuando el modelo de embedding de consultas difiere del modelo de embedding de documentos. Si generaste embeddings con modelo A durante la indexación y usas modelo B durante las consultas — la similitud de coseno pierde significancia. Ambos modelos operan en espacios vectoriales diferentes, por lo que las puntuaciones de \"similitud\" se vuelven engañosas.",{"type":32,"tag":33,"props":69,"children":70},{},[71],{"type":37,"value":72},"Esta situación aparece especialmente en tres escenarios: (1) el proveedor de embedding lanza una nueva versión (la transición OpenAI ada-002 → text-embedding-3-small redujo dimensionalidad %12 pero sin compatibilidad binaria), (2) migración a modelo fine-tuned (un modelo entrenado con datos específicos de dominio funciona mejor que el genérico pero requiere re-embeeding de todo el corpus), (3) cambio de modelo multilingüe (cambiar de sentence-transformers\u002Fparaphrase-multilingual-mpnet-base-v2 a intfloat\u002Fmultilingual-e5-large mejora retrieval@10 %8 pero no hay mapeo 1:1).",{"type":32,"tag":33,"props":74,"children":75},{},[76],{"type":37,"value":77},"En producción, detectar deriva es difícil porque las métricas cambian gradualmente. La primera semana los usuarios reportan \"resultados un poco peores\", la segunda semana los tickets de soporte suben %15, la tercera semana cae la retención. La señal temprana de deriva es esta: la puntuación de similitud promedio de nuevas consultas desciende comparada con la línea base del momento de indexación. Si la similitud promedia de coseno fue 0.78 durante indexación, caer a 0.71 durante consultas indica incompatibilidad de modelos.",{"type":32,"tag":79,"props":80,"children":82},"h3",{"id":81},"tradeoff-de-costos-re-indexación-vs-modelo-dual",[83],{"type":37,"value":84},"Tradeoff de Costos: Re-indexación vs Modelo Dual",{"type":32,"tag":33,"props":86,"children":87},{},[88,90,95],{"type":37,"value":89},"Considera el costo de re-indexación en tres componentes: (1) costo de llamadas API (OpenAI ",{"type":32,"tag":40,"props":91,"children":93},{"className":92},[],[94],{"type":37,"value":45},{"type":37,"value":96}," 1M token = 0.13 dólares, Cohere embed-v3 0.10 dólares), (2) tiempo de cómputo (12M documentos × 512 tokens promedio = 6.1B tokens ≈ 18 horas de procesamiento paralelo en batch), (3) riesgo de downtime (si no realizas switchover atómico, las consultas de usuarios caen en un índice parcial).",{"type":32,"tag":33,"props":98,"children":99},{},[100],{"type":37,"value":101},"Alternativa: estrategia de modelo dual — crea un índice separado para el nuevo modelo y usa pruebas A\u002FB para la migración. En este caso, el costo de almacenamiento se duplica, pero el riesgo es cero. Cuando el nuevo índice está listo, desplazas tráfico %10 → %50 → %100. Si ves regresión, el rollback es instantáneo. Sin embargo, esta estrategia duplica costos de almacenamiento vectorial (en Pinecone, un pod p1.x1 = 0.096 dólares\u002Fhora, 12M vectores 1536-dim = ~18GB ≈ 2 pods = 140 dólares\u002Fmes, índice dual = 280 dólares\u002Fmes).",{"type":32,"tag":57,"props":103,"children":105},{"id":104},"re-indexación-incremental-particionamiento-hotcold",[106],{"type":37,"value":107},"Re-indexación Incremental: Particionamiento Hot\u002FCold",{"type":32,"tag":33,"props":109,"children":110},{},[111],{"type":37,"value":112},"En lugar de re-indexar todo el corpus en una noche, particiona por frecuencia de uso — documentos que cayeron en consultas en los últimos 30 días son \"hot\", el resto \"cold\". La partición hot típicamente representa %15-25 del corpus pero atiende %80 de hits de consulta.",{"type":32,"tag":33,"props":114,"children":115},{},[116],{"type":37,"value":117},"Estrategia: re-embebe primero la partición hot con el nuevo modelo (18 horas en lugar de 3 horas, costo 6.400 → 1.200 dólares). Durante consultas, implementa routing por shard — nuevas consultas van primero al índice hot, si hay miss caen al índice cold. De esta forma obtienes %80 de mejora de accuracy el primer día, %100 en 2-3 semanas de re-indexación rolling.",{"type":32,"tag":33,"props":119,"children":120},{},[121],{"type":37,"value":122},"Para rastrear particiones, una tabla simple en PostgreSQL es suficiente:",{"type":32,"tag":124,"props":125,"children":129},"pre",{"className":126,"code":127,"language":128,"meta":16,"style":16},"language-sql shiki shiki-themes github-dark","CREATE TABLE doc_partition (\n  doc_id UUID PRIMARY KEY,\n  partition TEXT CHECK (partition IN ('hot', 'cold')),\n  last_queried_at TIMESTAMPTZ,\n  embedding_model TEXT,\n  embedding_version TEXT,\n  re_indexed_at TIMESTAMPTZ\n);\n\nCREATE INDEX idx_partition_model \n  ON doc_partition(partition, embedding_model);\n","sql",[130],{"type":32,"tag":40,"props":131,"children":132},{"__ignoreMap":16},[133,162,181,240,258,276,293,307,316,325,348],{"type":32,"tag":134,"props":135,"children":138},"span",{"class":136,"line":137},"line",1,[139,145,150,156],{"type":32,"tag":134,"props":140,"children":142},{"style":141},"--shiki-default:#F97583",[143],{"type":37,"value":144},"CREATE",{"type":32,"tag":134,"props":146,"children":147},{"style":141},[148],{"type":37,"value":149}," TABLE",{"type":32,"tag":134,"props":151,"children":153},{"style":152},"--shiki-default:#B392F0",[154],{"type":37,"value":155}," doc_partition",{"type":32,"tag":134,"props":157,"children":159},{"style":158},"--shiki-default:#E1E4E8",[160],{"type":37,"value":161}," (\n",{"type":32,"tag":134,"props":163,"children":165},{"class":136,"line":164},2,[166,171,176],{"type":32,"tag":134,"props":167,"children":168},{"style":158},[169],{"type":37,"value":170},"  doc_id UUID ",{"type":32,"tag":134,"props":172,"children":173},{"style":141},[174],{"type":37,"value":175},"PRIMARY KEY",{"type":32,"tag":134,"props":177,"children":178},{"style":158},[179],{"type":37,"value":180},",\n",{"type":32,"tag":134,"props":182,"children":184},{"class":136,"line":183},3,[185,190,195,200,205,210,215,219,225,230,235],{"type":32,"tag":134,"props":186,"children":187},{"style":141},[188],{"type":37,"value":189},"  partition",{"type":32,"tag":134,"props":191,"children":192},{"style":141},[193],{"type":37,"value":194}," TEXT",{"type":32,"tag":134,"props":196,"children":197},{"style":141},[198],{"type":37,"value":199}," CHECK",{"type":32,"tag":134,"props":201,"children":202},{"style":158},[203],{"type":37,"value":204}," (",{"type":32,"tag":134,"props":206,"children":207},{"style":141},[208],{"type":37,"value":209},"partition",{"type":32,"tag":134,"props":211,"children":212},{"style":141},[213],{"type":37,"value":214}," IN",{"type":32,"tag":134,"props":216,"children":217},{"style":158},[218],{"type":37,"value":204},{"type":32,"tag":134,"props":220,"children":222},{"style":221},"--shiki-default:#9ECBFF",[223],{"type":37,"value":224},"'hot'",{"type":32,"tag":134,"props":226,"children":227},{"style":158},[228],{"type":37,"value":229},", ",{"type":32,"tag":134,"props":231,"children":232},{"style":221},[233],{"type":37,"value":234},"'cold'",{"type":32,"tag":134,"props":236,"children":237},{"style":158},[238],{"type":37,"value":239},")),\n",{"type":32,"tag":134,"props":241,"children":243},{"class":136,"line":242},4,[244,249,254],{"type":32,"tag":134,"props":245,"children":246},{"style":158},[247],{"type":37,"value":248},"  last_queried_at ",{"type":32,"tag":134,"props":250,"children":251},{"style":141},[252],{"type":37,"value":253},"TIMESTAMPTZ",{"type":32,"tag":134,"props":255,"children":256},{"style":158},[257],{"type":37,"value":180},{"type":32,"tag":134,"props":259,"children":261},{"class":136,"line":260},5,[262,267,272],{"type":32,"tag":134,"props":263,"children":264},{"style":158},[265],{"type":37,"value":266},"  embedding_model ",{"type":32,"tag":134,"props":268,"children":269},{"style":141},[270],{"type":37,"value":271},"TEXT",{"type":32,"tag":134,"props":273,"children":274},{"style":158},[275],{"type":37,"value":180},{"type":32,"tag":134,"props":277,"children":279},{"class":136,"line":278},6,[280,285,289],{"type":32,"tag":134,"props":281,"children":282},{"style":158},[283],{"type":37,"value":284},"  embedding_version ",{"type":32,"tag":134,"props":286,"children":287},{"style":141},[288],{"type":37,"value":271},{"type":32,"tag":134,"props":290,"children":291},{"style":158},[292],{"type":37,"value":180},{"type":32,"tag":134,"props":294,"children":296},{"class":136,"line":295},7,[297,302],{"type":32,"tag":134,"props":298,"children":299},{"style":158},[300],{"type":37,"value":301},"  re_indexed_at ",{"type":32,"tag":134,"props":303,"children":304},{"style":141},[305],{"type":37,"value":306},"TIMESTAMPTZ\n",{"type":32,"tag":134,"props":308,"children":310},{"class":136,"line":309},8,[311],{"type":32,"tag":134,"props":312,"children":313},{"style":158},[314],{"type":37,"value":315},");\n",{"type":32,"tag":134,"props":317,"children":318},{"class":136,"line":26},[319],{"type":32,"tag":134,"props":320,"children":322},{"emptyLinePlaceholder":321},true,[323],{"type":37,"value":324},"\n",{"type":32,"tag":134,"props":326,"children":328},{"class":136,"line":327},10,[329,333,338,343],{"type":32,"tag":134,"props":330,"children":331},{"style":141},[332],{"type":37,"value":144},{"type":32,"tag":134,"props":334,"children":335},{"style":141},[336],{"type":37,"value":337}," INDEX",{"type":32,"tag":134,"props":339,"children":340},{"style":152},[341],{"type":37,"value":342}," idx_partition_model",{"type":32,"tag":134,"props":344,"children":345},{"style":158},[346],{"type":37,"value":347}," \n",{"type":32,"tag":134,"props":349,"children":351},{"class":136,"line":350},11,[352,357,362,366],{"type":32,"tag":134,"props":353,"children":354},{"style":141},[355],{"type":37,"value":356},"  ON",{"type":32,"tag":134,"props":358,"children":359},{"style":158},[360],{"type":37,"value":361}," doc_partition(",{"type":32,"tag":134,"props":363,"children":364},{"style":141},[365],{"type":37,"value":209},{"type":32,"tag":134,"props":367,"children":368},{"style":158},[369],{"type":37,"value":370},", embedding_model);\n",{"type":32,"tag":33,"props":372,"children":373},{},[374],{"type":37,"value":375},"Lógica de routing de consultas:",{"type":32,"tag":124,"props":377,"children":381},{"className":378,"code":379,"language":380,"meta":16,"style":16},"language-python shiki shiki-themes github-dark","def retrieve(query: str, model: str, k: int = 10):\n    query_emb = embed(query, model)\n    \n    # busca en partición hot\n    hot_results = vector_db.search(\n        collection=\"hot\",\n        vector=query_emb,\n        limit=k,\n        filter={\"embedding_model\": model}\n    )\n    \n    if len(hot_results) >= k:\n        return hot_results\n    \n    # completa desde cold si hay gap\n    cold_results = vector_db.search(\n        collection=\"cold\",\n        vector=query_emb,\n        limit=k - len(hot_results),\n        filter={\"embedding_model\": model}\n    )\n    \n    return merge_results(hot_results, cold_results)\n","python",[382],{"type":32,"tag":40,"props":383,"children":384},{"__ignoreMap":16},[385,443,461,469,478,495,517,534,551,578,586,593,622,636,644,653,670,691,707,738,762,770,778],{"type":32,"tag":134,"props":386,"children":387},{"class":136,"line":137},[388,393,398,403,409,414,418,423,428,433,438],{"type":32,"tag":134,"props":389,"children":390},{"style":141},[391],{"type":37,"value":392},"def",{"type":32,"tag":134,"props":394,"children":395},{"style":152},[396],{"type":37,"value":397}," retrieve",{"type":32,"tag":134,"props":399,"children":400},{"style":158},[401],{"type":37,"value":402},"(query: ",{"type":32,"tag":134,"props":404,"children":406},{"style":405},"--shiki-default:#79B8FF",[407],{"type":37,"value":408},"str",{"type":32,"tag":134,"props":410,"children":411},{"style":158},[412],{"type":37,"value":413},", model: ",{"type":32,"tag":134,"props":415,"children":416},{"style":405},[417],{"type":37,"value":408},{"type":32,"tag":134,"props":419,"children":420},{"style":158},[421],{"type":37,"value":422},", k: ",{"type":32,"tag":134,"props":424,"children":425},{"style":405},[426],{"type":37,"value":427},"int",{"type":32,"tag":134,"props":429,"children":430},{"style":141},[431],{"type":37,"value":432}," =",{"type":32,"tag":134,"props":434,"children":435},{"style":405},[436],{"type":37,"value":437}," 10",{"type":32,"tag":134,"props":439,"children":440},{"style":158},[441],{"type":37,"value":442},"):\n",{"type":32,"tag":134,"props":444,"children":445},{"class":136,"line":164},[446,451,456],{"type":32,"tag":134,"props":447,"children":448},{"style":158},[449],{"type":37,"value":450},"    query_emb ",{"type":32,"tag":134,"props":452,"children":453},{"style":141},[454],{"type":37,"value":455},"=",{"type":32,"tag":134,"props":457,"children":458},{"style":158},[459],{"type":37,"value":460}," embed(query, model)\n",{"type":32,"tag":134,"props":462,"children":463},{"class":136,"line":183},[464],{"type":32,"tag":134,"props":465,"children":466},{"style":158},[467],{"type":37,"value":468},"    \n",{"type":32,"tag":134,"props":470,"children":471},{"class":136,"line":242},[472],{"type":32,"tag":134,"props":473,"children":475},{"style":474},"--shiki-default:#6A737D",[476],{"type":37,"value":477},"    # busca en partición hot\n",{"type":32,"tag":134,"props":479,"children":480},{"class":136,"line":260},[481,486,490],{"type":32,"tag":134,"props":482,"children":483},{"style":158},[484],{"type":37,"value":485},"    hot_results ",{"type":32,"tag":134,"props":487,"children":488},{"style":141},[489],{"type":37,"value":455},{"type":32,"tag":134,"props":491,"children":492},{"style":158},[493],{"type":37,"value":494}," vector_db.search(\n",{"type":32,"tag":134,"props":496,"children":497},{"class":136,"line":278},[498,504,508,513],{"type":32,"tag":134,"props":499,"children":501},{"style":500},"--shiki-default:#FFAB70",[502],{"type":37,"value":503},"        collection",{"type":32,"tag":134,"props":505,"children":506},{"style":141},[507],{"type":37,"value":455},{"type":32,"tag":134,"props":509,"children":510},{"style":221},[511],{"type":37,"value":512},"\"hot\"",{"type":32,"tag":134,"props":514,"children":515},{"style":158},[516],{"type":37,"value":180},{"type":32,"tag":134,"props":518,"children":519},{"class":136,"line":295},[520,525,529],{"type":32,"tag":134,"props":521,"children":522},{"style":500},[523],{"type":37,"value":524},"        vector",{"type":32,"tag":134,"props":526,"children":527},{"style":141},[528],{"type":37,"value":455},{"type":32,"tag":134,"props":530,"children":531},{"style":158},[532],{"type":37,"value":533},"query_emb,\n",{"type":32,"tag":134,"props":535,"children":536},{"class":136,"line":309},[537,542,546],{"type":32,"tag":134,"props":538,"children":539},{"style":500},[540],{"type":37,"value":541},"        limit",{"type":32,"tag":134,"props":543,"children":544},{"style":141},[545],{"type":37,"value":455},{"type":32,"tag":134,"props":547,"children":548},{"style":158},[549],{"type":37,"value":550},"k,\n",{"type":32,"tag":134,"props":552,"children":553},{"class":136,"line":26},[554,559,563,568,573],{"type":32,"tag":134,"props":555,"children":556},{"style":500},[557],{"type":37,"value":558},"        filter",{"type":32,"tag":134,"props":560,"children":561},{"style":141},[562],{"type":37,"value":455},{"type":32,"tag":134,"props":564,"children":565},{"style":158},[566],{"type":37,"value":567},"{",{"type":32,"tag":134,"props":569,"children":570},{"style":221},[571],{"type":37,"value":572},"\"embedding_model\"",{"type":32,"tag":134,"props":574,"children":575},{"style":158},[576],{"type":37,"value":577},": model}\n",{"type":32,"tag":134,"props":579,"children":580},{"class":136,"line":327},[581],{"type":32,"tag":134,"props":582,"children":583},{"style":158},[584],{"type":37,"value":585},"    )\n",{"type":32,"tag":134,"props":587,"children":588},{"class":136,"line":350},[589],{"type":32,"tag":134,"props":590,"children":591},{"style":158},[592],{"type":37,"value":468},{"type":32,"tag":134,"props":594,"children":596},{"class":136,"line":595},12,[597,602,607,612,617],{"type":32,"tag":134,"props":598,"children":599},{"style":141},[600],{"type":37,"value":601},"    if",{"type":32,"tag":134,"props":603,"children":604},{"style":405},[605],{"type":37,"value":606}," len",{"type":32,"tag":134,"props":608,"children":609},{"style":158},[610],{"type":37,"value":611},"(hot_results) ",{"type":32,"tag":134,"props":613,"children":614},{"style":141},[615],{"type":37,"value":616},">=",{"type":32,"tag":134,"props":618,"children":619},{"style":158},[620],{"type":37,"value":621}," k:\n",{"type":32,"tag":134,"props":623,"children":625},{"class":136,"line":624},13,[626,631],{"type":32,"tag":134,"props":627,"children":628},{"style":141},[629],{"type":37,"value":630},"        return",{"type":32,"tag":134,"props":632,"children":633},{"style":158},[634],{"type":37,"value":635}," hot_results\n",{"type":32,"tag":134,"props":637,"children":639},{"class":136,"line":638},14,[640],{"type":32,"tag":134,"props":641,"children":642},{"style":158},[643],{"type":37,"value":468},{"type":32,"tag":134,"props":645,"children":647},{"class":136,"line":646},15,[648],{"type":32,"tag":134,"props":649,"children":650},{"style":474},[651],{"type":37,"value":652},"    # completa desde cold si hay gap\n",{"type":32,"tag":134,"props":654,"children":656},{"class":136,"line":655},16,[657,662,666],{"type":32,"tag":134,"props":658,"children":659},{"style":158},[660],{"type":37,"value":661},"    cold_results ",{"type":32,"tag":134,"props":663,"children":664},{"style":141},[665],{"type":37,"value":455},{"type":32,"tag":134,"props":667,"children":668},{"style":158},[669],{"type":37,"value":494},{"type":32,"tag":134,"props":671,"children":673},{"class":136,"line":672},17,[674,678,682,687],{"type":32,"tag":134,"props":675,"children":676},{"style":500},[677],{"type":37,"value":503},{"type":32,"tag":134,"props":679,"children":680},{"style":141},[681],{"type":37,"value":455},{"type":32,"tag":134,"props":683,"children":684},{"style":221},[685],{"type":37,"value":686},"\"cold\"",{"type":32,"tag":134,"props":688,"children":689},{"style":158},[690],{"type":37,"value":180},{"type":32,"tag":134,"props":692,"children":694},{"class":136,"line":693},18,[695,699,703],{"type":32,"tag":134,"props":696,"children":697},{"style":500},[698],{"type":37,"value":524},{"type":32,"tag":134,"props":700,"children":701},{"style":141},[702],{"type":37,"value":455},{"type":32,"tag":134,"props":704,"children":705},{"style":158},[706],{"type":37,"value":533},{"type":32,"tag":134,"props":708,"children":710},{"class":136,"line":709},19,[711,715,719,724,729,733],{"type":32,"tag":134,"props":712,"children":713},{"style":500},[714],{"type":37,"value":541},{"type":32,"tag":134,"props":716,"children":717},{"style":141},[718],{"type":37,"value":455},{"type":32,"tag":134,"props":720,"children":721},{"style":158},[722],{"type":37,"value":723},"k ",{"type":32,"tag":134,"props":725,"children":726},{"style":141},[727],{"type":37,"value":728},"-",{"type":32,"tag":134,"props":730,"children":731},{"style":405},[732],{"type":37,"value":606},{"type":32,"tag":134,"props":734,"children":735},{"style":158},[736],{"type":37,"value":737},"(hot_results),\n",{"type":32,"tag":134,"props":739,"children":741},{"class":136,"line":740},20,[742,746,750,754,758],{"type":32,"tag":134,"props":743,"children":744},{"style":500},[745],{"type":37,"value":558},{"type":32,"tag":134,"props":747,"children":748},{"style":141},[749],{"type":37,"value":455},{"type":32,"tag":134,"props":751,"children":752},{"style":158},[753],{"type":37,"value":567},{"type":32,"tag":134,"props":755,"children":756},{"style":221},[757],{"type":37,"value":572},{"type":32,"tag":134,"props":759,"children":760},{"style":158},[761],{"type":37,"value":577},{"type":32,"tag":134,"props":763,"children":765},{"class":136,"line":764},21,[766],{"type":32,"tag":134,"props":767,"children":768},{"style":158},[769],{"type":37,"value":585},{"type":32,"tag":134,"props":771,"children":773},{"class":136,"line":772},22,[774],{"type":32,"tag":134,"props":775,"children":776},{"style":158},[777],{"type":37,"value":468},{"type":32,"tag":134,"props":779,"children":781},{"class":136,"line":780},23,[782,787],{"type":32,"tag":134,"props":783,"children":784},{"style":141},[785],{"type":37,"value":786},"    return",{"type":32,"tag":134,"props":788,"children":789},{"style":158},[790],{"type":37,"value":791}," merge_results(hot_results, cold_results)\n",{"type":32,"tag":33,"props":793,"children":794},{},[795,797,806],{"type":37,"value":796},"Este enfoque es similar a la lógica de \"event-driven incremental sync\" usada en la arquitectura de ",{"type":32,"tag":798,"props":799,"children":803},"a",{"href":800,"rel":801},"https:\u002F\u002Fwww.roibase.com.tr\u002Fes\u002Ffirstparty",[802],"nofollow",[804],{"type":37,"value":805},"datos first-party",{"type":37,"value":807}," de Roibase — en lugar de copiar toda la data de una vez, sincronizamos continuamente el subset que cambia.",{"type":32,"tag":79,"props":809,"children":811},{"id":810},"detección-de-deriva-monitoreo-del-espacio-de-embedding",[812],{"type":37,"value":813},"Detección de Deriva: Monitoreo del Espacio de Embedding",{"type":32,"tag":33,"props":815,"children":816},{},[817],{"type":37,"value":818},"Para medir deriva en producción, usa tres métricas:",{"type":32,"tag":820,"props":821,"children":822},"table",{},[823,847],{"type":32,"tag":824,"props":825,"children":826},"thead",{},[827],{"type":32,"tag":828,"props":829,"children":830},"tr",{},[831,837,842],{"type":32,"tag":832,"props":833,"children":834},"th",{},[835],{"type":37,"value":836},"Métrica",{"type":32,"tag":832,"props":838,"children":839},{},[840],{"type":37,"value":841},"Umbral",{"type":32,"tag":832,"props":843,"children":844},{},[845],{"type":37,"value":846},"Significado",{"type":32,"tag":848,"props":849,"children":850},"tbody",{},[851,870,888],{"type":32,"tag":828,"props":852,"children":853},{},[854,860,865],{"type":32,"tag":855,"props":856,"children":857},"td",{},[858],{"type":37,"value":859},"Desplazamiento de similitud media",{"type":32,"tag":855,"props":861,"children":862},{},[863],{"type":37,"value":864},"línea base − 0.05",{"type":32,"tag":855,"props":866,"children":867},{},[868],{"type":37,"value":869},"La distancia entre embedding de consulta e índice aumentó",{"type":32,"tag":828,"props":871,"children":872},{},[873,878,883],{"type":32,"tag":855,"props":874,"children":875},{},[876],{"type":37,"value":877},"Estabilidad Top-k",{"type":32,"tag":855,"props":879,"children":880},{},[881],{"type":37,"value":882},"\u003C90% overlap",{"type":32,"tag":855,"props":884,"children":885},{},[886],{"type":37,"value":887},"La misma consulta devuelve resultados diferentes (efecto del cambio de modelo)",{"type":32,"tag":828,"props":889,"children":890},{},[891,896,901],{"type":32,"tag":855,"props":892,"children":893},{},[894],{"type":37,"value":895},"Tasa OOV (out-of-vocabulary)",{"type":32,"tag":855,"props":897,"children":898},{},[899],{"type":37,"value":900},">2%",{"type":32,"tag":855,"props":902,"children":903},{},[904],{"type":37,"value":905},"El nuevo modelo no reconoce términos en corpus antiguo",{"type":32,"tag":33,"props":907,"children":908},{},[909],{"type":37,"value":910},"Calcula el desplazamiento de similitud media en un job batch diario — toma consultas de las últimas 24 horas, embébelas con modelo anterior y nuevo, compara similitud de coseno con embeddings almacenados. Si la similitud con modelo nuevo = 0.73 y con modelo anterior = 0.78, hay 0.05 de deriva, señal de re-indexación.",{"type":32,"tag":33,"props":912,"children":913},{},[914],{"type":37,"value":915},"Para estabilidad Top-k, ejecuta el mismo conjunto de consultas de prueba (100-200 consultas) diariamente con ambos modelos, compara los primeros 10 resultados. Si el overlap cae bajo %85, necesitas migración de modelo.",{"type":32,"tag":57,"props":917,"children":919},{"id":918},"estrategia-de-migración-de-modelo-blue-green-deployment",[920],{"type":37,"value":921},"Estrategia de Migración de Modelo: Blue-Green Deployment",{"type":32,"tag":33,"props":923,"children":924},{},[925],{"type":37,"value":926},"Cuando cambies modelos, realiza switchover atómico — blue-green deployment. El índice antiguo es \"blue\", el nuevo es \"green\". El tráfico va primero a blue, mientras llenas green en background. Cuando green está listo, trasladas tráfico a green en 5 minutos. Si hay problema, rollback inmediato a blue.",{"type":32,"tag":33,"props":928,"children":929},{},[930],{"type":37,"value":931},"Pasos concretos:",{"type":32,"tag":933,"props":934,"children":935},"ol",{},[936,956,966,984,994,1004],{"type":32,"tag":937,"props":938,"children":939},"li",{},[940,946,948,954],{"type":32,"tag":941,"props":942,"children":943},"strong",{},[944],{"type":37,"value":945},"T-0:",{"type":37,"value":947}," Comienza embedding con nuevo modelo, crea índice en paralelo (",{"type":32,"tag":40,"props":949,"children":951},{"className":950},[],[952],{"type":37,"value":953},"green_index",{"type":37,"value":955},").",{"type":32,"tag":937,"props":957,"children":958},{},[959,964],{"type":32,"tag":941,"props":960,"children":961},{},[962],{"type":37,"value":963},"T+18h:",{"type":37,"value":965}," Índice green %100 listo. Índice blue aún activo.",{"type":32,"tag":937,"props":967,"children":968},{},[969,974,976,982],{"type":32,"tag":941,"props":970,"children":971},{},[972],{"type":37,"value":973},"T+18h 5m:",{"type":37,"value":975}," Añade flag ",{"type":32,"tag":40,"props":977,"children":979},{"className":978},[],[980],{"type":37,"value":981},"MODEL_VERSION=green",{"type":37,"value":983}," al query router, desplaza %10 tráfico a green.",{"type":32,"tag":937,"props":985,"children":986},{},[987,992],{"type":32,"tag":941,"props":988,"children":989},{},[990],{"type":37,"value":991},"T+18h 30m:",{"type":37,"value":993}," Sin errores, desplaza %50.",{"type":32,"tag":937,"props":995,"children":996},{},[997,1002],{"type":32,"tag":941,"props":998,"children":999},{},[1000],{"type":37,"value":1001},"T+19h:",{"type":37,"value":1003}," 100% green. Índice blue en modo read-only (backup 7 días).",{"type":32,"tag":937,"props":1005,"children":1006},{},[1007,1012],{"type":32,"tag":941,"props":1008,"children":1009},{},[1010],{"type":37,"value":1011},"T+7 días:",{"type":37,"value":1013}," Índice blue se elimina.",{"type":32,"tag":33,"props":1015,"children":1016},{},[1017],{"type":37,"value":1018},"Este enfoque es crítico especialmente en sistemas de búsqueda de e-commerce — en un cliente de Roibase (categoría cosmética, 2.4M productos, 80K\u002Fdía consultas) la migración de modelo causó pérdida de sesión %0.2 (el rollback blue-green se completó en 12 segundos).",{"type":32,"tag":79,"props":1020,"children":1022},{"id":1021},"optimización-de-costos-batch-cache",[1023],{"type":37,"value":1024},"Optimización de Costos: Batch + Cache",{"type":32,"tag":33,"props":1026,"children":1027},{},[1028],{"type":37,"value":1029},"Para reducir costo de re-indexación, usa dos técnicas:",{"type":32,"tag":33,"props":1031,"children":1032},{},[1033,1038],{"type":32,"tag":941,"props":1034,"children":1035},{},[1036],{"type":37,"value":1037},"Usar API Batch:",{"type":37,"value":1039}," OpenAI batch API es %50 más barata que API normal (0.13 → 0.065 dólares\u002F1M token). Es asincrónica — las respuestas llegan en 1-24 horas. Para re-indexación es suficiente porque no es realtime. Enviar 12M documentos a batch reduce costo 6.400 → 3.200 dólares.",{"type":32,"tag":33,"props":1041,"children":1042},{},[1043,1048],{"type":32,"tag":941,"props":1044,"children":1045},{},[1046],{"type":37,"value":1047},"Cache Semántico:",{"type":37,"value":1049}," Si el mismo documento se indexa múltiples veces con metadata diferente (ej: misma descripción de producto, diferente SKU), cachea el embedding. Deduplica con hash MD5. En experiencia de Roibase esto proporciona %12-18 reducción de costos (especialmente en fashion\u002Fbeauty donde descripciones de producto son similares).",{"type":32,"tag":124,"props":1051,"children":1053},{"className":378,"code":1052,"language":380,"meta":16,"style":16},"import hashlib\nfrom functools import lru_cache\n\n@lru_cache(maxsize=100_000)\ndef cached_embed(text: str, model: str) -> list[float]:\n    cache_key = hashlib.md5(f\"{model}:{text}\".encode()).hexdigest()\n    cached = redis.get(cache_key)\n    if cached:\n        return json.loads(cached)\n    \n    emb = openai.Embedding.create(input=text, model=model)\n    redis.setex(cache_key, 86400 * 7, json.dumps(emb))\n    return emb\n",[1054],{"type":32,"tag":40,"props":1055,"children":1056},{"__ignoreMap":16},[1057,1070,1092,1099,1131,1175,1242,1259,1271,1283,1290,1334,1362],{"type":32,"tag":134,"props":1058,"children":1059},{"class":136,"line":137},[1060,1065],{"type":32,"tag":134,"props":1061,"children":1062},{"style":141},[1063],{"type":37,"value":1064},"import",{"type":32,"tag":134,"props":1066,"children":1067},{"style":158},[1068],{"type":37,"value":1069}," hashlib\n",{"type":32,"tag":134,"props":1071,"children":1072},{"class":136,"line":164},[1073,1078,1083,1087],{"type":32,"tag":134,"props":1074,"children":1075},{"style":141},[1076],{"type":37,"value":1077},"from",{"type":32,"tag":134,"props":1079,"children":1080},{"style":158},[1081],{"type":37,"value":1082}," functools ",{"type":32,"tag":134,"props":1084,"children":1085},{"style":141},[1086],{"type":37,"value":1064},{"type":32,"tag":134,"props":1088,"children":1089},{"style":158},[1090],{"type":37,"value":1091}," lru_cache\n",{"type":32,"tag":134,"props":1093,"children":1094},{"class":136,"line":183},[1095],{"type":32,"tag":134,"props":1096,"children":1097},{"emptyLinePlaceholder":321},[1098],{"type":37,"value":324},{"type":32,"tag":134,"props":1100,"children":1101},{"class":136,"line":242},[1102,1107,1112,1117,1121,1126],{"type":32,"tag":134,"props":1103,"children":1104},{"style":152},[1105],{"type":37,"value":1106},"@lru_cache",{"type":32,"tag":134,"props":1108,"children":1109},{"style":158},[1110],{"type":37,"value":1111},"(",{"type":32,"tag":134,"props":1113,"children":1114},{"style":500},[1115],{"type":37,"value":1116},"maxsize",{"type":32,"tag":134,"props":1118,"children":1119},{"style":141},[1120],{"type":37,"value":455},{"type":32,"tag":134,"props":1122,"children":1123},{"style":405},[1124],{"type":37,"value":1125},"100_000",{"type":32,"tag":134,"props":1127,"children":1128},{"style":158},[1129],{"type":37,"value":1130},")\n",{"type":32,"tag":134,"props":1132,"children":1133},{"class":136,"line":260},[1134,1138,1143,1148,1152,1156,1160,1165,1170],{"type":32,"tag":134,"props":1135,"children":1136},{"style":141},[1137],{"type":37,"value":392},{"type":32,"tag":134,"props":1139,"children":1140},{"style":152},[1141],{"type":37,"value":1142}," cached_embed",{"type":32,"tag":134,"props":1144,"children":1145},{"style":158},[1146],{"type":37,"value":1147},"(text: ",{"type":32,"tag":134,"props":1149,"children":1150},{"style":405},[1151],{"type":37,"value":408},{"type":32,"tag":134,"props":1153,"children":1154},{"style":158},[1155],{"type":37,"value":413},{"type":32,"tag":134,"props":1157,"children":1158},{"style":405},[1159],{"type":37,"value":408},{"type":32,"tag":134,"props":1161,"children":1162},{"style":158},[1163],{"type":37,"value":1164},") -> list[",{"type":32,"tag":134,"props":1166,"children":1167},{"style":405},[1168],{"type":37,"value":1169},"float",{"type":32,"tag":134,"props":1171,"children":1172},{"style":158},[1173],{"type":37,"value":1174},"]:\n",{"type":32,"tag":134,"props":1176,"children":1177},{"class":136,"line":278},[1178,1183,1187,1192,1197,1202,1206,1211,1216,1221,1225,1229,1233,1237],{"type":32,"tag":134,"props":1179,"children":1180},{"style":158},[1181],{"type":37,"value":1182},"    cache_key ",{"type":32,"tag":134,"props":1184,"children":1185},{"style":141},[1186],{"type":37,"value":455},{"type":32,"tag":134,"props":1188,"children":1189},{"style":158},[1190],{"type":37,"value":1191}," hashlib.md5(",{"type":32,"tag":134,"props":1193,"children":1194},{"style":141},[1195],{"type":37,"value":1196},"f",{"type":32,"tag":134,"props":1198,"children":1199},{"style":221},[1200],{"type":37,"value":1201},"\"",{"type":32,"tag":134,"props":1203,"children":1204},{"style":405},[1205],{"type":37,"value":567},{"type":32,"tag":134,"props":1207,"children":1208},{"style":158},[1209],{"type":37,"value":1210},"model",{"type":32,"tag":134,"props":1212,"children":1213},{"style":405},[1214],{"type":37,"value":1215},"}",{"type":32,"tag":134,"props":1217,"children":1218},{"style":221},[1219],{"type":37,"value":1220},":",{"type":32,"tag":134,"props":1222,"children":1223},{"style":405},[1224],{"type":37,"value":567},{"type":32,"tag":134,"props":1226,"children":1227},{"style":158},[1228],{"type":37,"value":37},{"type":32,"tag":134,"props":1230,"children":1231},{"style":405},[1232],{"type":37,"value":1215},{"type":32,"tag":134,"props":1234,"children":1235},{"style":221},[1236],{"type":37,"value":1201},{"type":32,"tag":134,"props":1238,"children":1239},{"style":158},[1240],{"type":37,"value":1241},".encode()).hexdigest()\n",{"type":32,"tag":134,"props":1243,"children":1244},{"class":136,"line":295},[1245,1250,1254],{"type":32,"tag":134,"props":1246,"children":1247},{"style":158},[1248],{"type":37,"value":1249},"    cached ",{"type":32,"tag":134,"props":1251,"children":1252},{"style":141},[1253],{"type":37,"value":455},{"type":32,"tag":134,"props":1255,"children":1256},{"style":158},[1257],{"type":37,"value":1258}," redis.get(cache_key)\n",{"type":32,"tag":134,"props":1260,"children":1261},{"class":136,"line":309},[1262,1266],{"type":32,"tag":134,"props":1263,"children":1264},{"style":141},[1265],{"type":37,"value":601},{"type":32,"tag":134,"props":1267,"children":1268},{"style":158},[1269],{"type":37,"value":1270}," cached:\n",{"type":32,"tag":134,"props":1272,"children":1273},{"class":136,"line":26},[1274,1278],{"type":32,"tag":134,"props":1275,"children":1276},{"style":141},[1277],{"type":37,"value":630},{"type":32,"tag":134,"props":1279,"children":1280},{"style":158},[1281],{"type":37,"value":1282}," json.loads(cached)\n",{"type":32,"tag":134,"props":1284,"children":1285},{"class":136,"line":327},[1286],{"type":32,"tag":134,"props":1287,"children":1288},{"style":158},[1289],{"type":37,"value":468},{"type":32,"tag":134,"props":1291,"children":1292},{"class":136,"line":350},[1293,1298,1302,1307,1312,1316,1321,1325,1329],{"type":32,"tag":134,"props":1294,"children":1295},{"style":158},[1296],{"type":37,"value":1297},"    emb ",{"type":32,"tag":134,"props":1299,"children":1300},{"style":141},[1301],{"type":37,"value":455},{"type":32,"tag":134,"props":1303,"children":1304},{"style":158},[1305],{"type":37,"value":1306}," openai.Embedding.create(",{"type":32,"tag":134,"props":1308,"children":1309},{"style":500},[1310],{"type":37,"value":1311},"input",{"type":32,"tag":134,"props":1313,"children":1314},{"style":141},[1315],{"type":37,"value":455},{"type":32,"tag":134,"props":1317,"children":1318},{"style":158},[1319],{"type":37,"value":1320},"text, ",{"type":32,"tag":134,"props":1322,"children":1323},{"style":500},[1324],{"type":37,"value":1210},{"type":32,"tag":134,"props":1326,"children":1327},{"style":141},[1328],{"type":37,"value":455},{"type":32,"tag":134,"props":1330,"children":1331},{"style":158},[1332],{"type":37,"value":1333},"model)\n",{"type":32,"tag":134,"props":1335,"children":1336},{"class":136,"line":595},[1337,1342,1347,1352,1357],{"type":32,"tag":134,"props":1338,"children":1339},{"style":158},[1340],{"type":37,"value":1341},"    redis.setex(cache_key, ",{"type":32,"tag":134,"props":1343,"children":1344},{"style":405},[1345],{"type":37,"value":1346},"86400",{"type":32,"tag":134,"props":1348,"children":1349},{"style":141},[1350],{"type":37,"value":1351}," *",{"type":32,"tag":134,"props":1353,"children":1354},{"style":405},[1355],{"type":37,"value":1356}," 7",{"type":32,"tag":134,"props":1358,"children":1359},{"style":158},[1360],{"type":37,"value":1361},", json.dumps(emb))\n",{"type":32,"tag":134,"props":1363,"children":1364},{"class":136,"line":624},[1365,1369],{"type":32,"tag":134,"props":1366,"children":1367},{"style":141},[1368],{"type":37,"value":786},{"type":32,"tag":134,"props":1370,"children":1371},{"style":158},[1372],{"type":37,"value":1373}," emb\n",{"type":32,"tag":57,"props":1375,"children":1377},{"id":1376},"transición-a-modelo-fine-tuned-tradeoff-de-adaptación-de-dominio",[1378],{"type":37,"value":1379},"Transición a Modelo Fine-Tuned: Tradeoff de Adaptación de Dominio",{"type":32,"tag":33,"props":1381,"children":1382},{},[1383,1385,1391,1393,1399],{"type":37,"value":1384},"Usar un modelo de embedding específico de dominio en lugar de genérico mejora retrieval@10 %8-15 (ej: en dominio legal, ",{"type":32,"tag":40,"props":1386,"children":1388},{"className":1387},[],[1389],{"type":37,"value":1390},"paraphrase-mpnet-base-v2",{"type":37,"value":1392}," vs ",{"type":32,"tag":40,"props":1394,"children":1396},{"className":1395},[],[1397],{"type":37,"value":1398},"legal-bert-base-uncased",{"type":37,"value":1400}," + contrastive learning). Pero el fine-tuning tiene costo: (1) recopilación de datos etiquetados (1000-5000 pares query-documento), (2) tiempo de GPU (A100 8 horas ≈ 60 dólares), (3) re-indexación de corpus completo.",{"type":32,"tag":33,"props":1402,"children":1403},{},[1404],{"type":37,"value":1405},"Análisis de tradeoff: si la precisión de retrieval mejora %10 y eso contribuye %2 a conversión (ej: recomendar el artículo correcto en flow de lead gen aumenta cumplimiento de formulario %2), entonces 100K consultas\u002Fmes × 0.02 × 50 dólares AOV = 100K dólares de lift. Aquí el costo de fine-tuning + re-indexación = 10K dólares se recupera en 1 mes.",{"type":32,"tag":33,"props":1407,"children":1408},{},[1409],{"type":37,"value":1410},"Pero el costo de mantenimiento de modelo fine-tuned también existe — re-entrenar cada 6 meses con datos nuevos (domain shift). Este ciclo genera re-indexación continua. Alternativa: adapter layer — añade una capa fine-tuned pequeña sobre modelo base, así los embeddings base permanecen estáticos y solo cambia la proyección en query-time. Entonces no necesitas re-indexación pero la ganancia de accuracy cae de %15 a %8.",{"type":32,"tag":57,"props":1412,"children":1414},{"id":1413},"caso-contrario-re-indexación-innecesaria",[1415],{"type":37,"value":1416},"Caso Contrario: ¿Re-indexación Innecesaria?",{"type":32,"tag":33,"props":1418,"children":1419},{},[1420],{"type":37,"value":1421},"En algunos casos, no hacer re-indexación es la decisión correcta. Si (1) el cambio de modelo es menor (la diferencia empírica de recall entre OpenAI ada-002 y text-embedding-3-small es \u003C2%), (2) el corpus es estático (no se añaden documentos nuevos), (3) el patrón de consulta no cambia — la deriva es mínima.",{"type":32,"tag":33,"props":1423,"children":1424},{},[1425],{"type":37,"value":1426},"Especialmente en productos B2B SaaS (knowledge base interno, búsqueda de documentación), el corpus se actualiza 1-2 veces por año. En este caso, excepto para upgrades de modelo mayores (BERT → MPNet), evitar re-indexación es sensato. En su lugar, usa ensemble en query-time — recupera con ambos modelos (antiguo y nuevo), fusiona resultados con reciprocal rank fusion. Esto añade %3-5 de latencia pero el costo es menor que re-indexación.",{"type":32,"tag":33,"props":1428,"children":1429},{},[1430],{"type":37,"value":1431},"Árbol de decisión:",{"type":32,"tag":1433,"props":1434,"children":1435},"ul",{},[1436,1441,1446,1451,1456],{"type":32,"tag":937,"props":1437,"children":1438},{},[1439],{"type":37,"value":1440},"Corpus >5M documentos + nuevo modelo %5+ ganancia accuracy → re-indexación incremental hot\u002Fcold",{"type":32,"tag":937,"props":1442,"children":1443},{},[1444],{"type":37,"value":1445},"Corpus \u003C1M + %10+ ganancia → blue-green re-indexación completa",{"type":32,"tag":937,"props":1447,"children":1448},{},[1449],{"type":37,"value":1450},"Corpus \u003C1M + \u003C5% ganancia → ensemble + posponer re-indexación",{"type":32,"tag":937,"props":1452,"children":1453},{},[1454],{"type":37,"value":1455},"Modelo fine-tuned + impacto en conversión >10× costo → re-indexación",{"type":32,"tag":937,"props":1457,"children":1458},{},[1459],{"type":37,"value":1460},"Modelo fine-tuned + impacto en conversión \u003C3× costo → adapter layer o descartar",{"type":32,"tag":33,"props":1462,"children":1463},{},[1464,1466,1473],{"type":37,"value":1465},"En trabajos de ",{"type":32,"tag":798,"props":1467,"children":1470},{"href":1468,"rel":1469},"https:\u002F\u002Fwww.roibase.com.tr\u002Fes\u002Fgeo",[802],[1471],{"type":37,"value":1472},"GEO de Roibase",{"type":37,"value":1474}," existe situación similar — optimizando citaciones de LLM, decidir qué contenido re-generar y qué dejar como está. También requiere tradeoff costo-impacto.",{"type":32,"tag":57,"props":1476,"children":1478},{"id":1477},"prevención-de-deriva-pinning-de-versión-y-contract-testing",[1479],{"type":37,"value":1480},"Prevención de Deriva: Pinning de Versión y Contract Testing",{"type":32,"tag":33,"props":1482,"children":1483},{},[1484,1486,1491],{"type":37,"value":1485},"La mejor forma de protegerse contra deriva de embeddings en producción es pin'ear la versión de modelo e implementar contract testing. Si usas OpenAI ",{"type":32,"tag":40,"props":1487,"children":1489},{"className":1488},[],[1490],{"type":37,"value":45},{"type":37,"value":1492},", mantén el model ID fijo en config, no permitas upgrades automáticos. Cuando salga nueva versión, pruébalo manualmente.",{"type":32,"tag":33,"props":1494,"children":1495},{},[1496],{"type":37,"value":1497},"Ejemplo de contract test:",{"type":32,"tag":124,"props":1499,"children":1501},{"className":378,"code":1500,"language":380,"meta":16,"style":16},"def test_embedding_compatibility():\n    test_docs = [\n        \"machine learning model training\",\n        \"vector database indexing\",\n        \"semantic search optimization\"\n    ]\n    \n    # embeddings de modelo base (producción)\n    baseline = [embed(doc, model=\"text-embedding-3-large\") for doc in test_docs]\n    \n    # compara con modelo candidato\n    candidate = [embed(doc, model=\"text-embedding-4\") for doc in test_docs]\n    \n    # verifica compatibilidad de similitud de coseno\n    for i, doc in enumerate(test_docs):\n        sim = cosine_similarity(baseline[i], candidate[i])\n        assert sim > 0.95, f\"Embedding drift detectado: {doc}, sim={sim}\"\n",[1502],{"type":32,"tag":40,"props":1503,"children":1504},{"__ignoreMap":16},[1505,1522,1539,1551,1563,1571,1579,1586,1594,1649,1656,1664,1713,1720,1728,1755,1772],{"type":32,"tag":134,"props":1506,"children":1507},{"class":136,"line":137},[1508,1512,1517],{"type":32,"tag":134,"props":1509,"children":1510},{"style":141},[1511],{"type":37,"value":392},{"type":32,"tag":134,"props":1513,"children":1514},{"style":152},[1515],{"type":37,"value":1516}," test_embedding_compatibility",{"type":32,"tag":134,"props":1518,"children":1519},{"style":158},[1520],{"type":37,"value":1521},"():\n",{"type":32,"tag":134,"props":1523,"children":1524},{"class":136,"line":164},[1525,1530,1534],{"type":32,"tag":134,"props":1526,"children":1527},{"style":158},[1528],{"type":37,"value":1529},"    test_docs ",{"type":32,"tag":134,"props":1531,"children":1532},{"style":141},[1533],{"type":37,"value":455},{"type":32,"tag":134,"props":1535,"children":1536},{"style":158},[1537],{"type":37,"value":1538}," [\n",{"type":32,"tag":134,"props":1540,"children":1541},{"class":136,"line":183},[1542,1547],{"type":32,"tag":134,"props":1543,"children":1544},{"style":221},[1545],{"type":37,"value":1546},"        \"machine learning model training\"",{"type":32,"tag":134,"props":1548,"children":1549},{"style":158},[1550],{"type":37,"value":180},{"type":32,"tag":134,"props":1552,"children":1553},{"class":136,"line":242},[1554,1559],{"type":32,"tag":134,"props":1555,"children":1556},{"style":221},[1557],{"type":37,"value":1558},"        \"vector database indexing\"",{"type":32,"tag":134,"props":1560,"children":1561},{"style":158},[1562],{"type":37,"value":180},{"type":32,"tag":134,"props":1564,"children":1565},{"class":136,"line":260},[1566],{"type":32,"tag":134,"props":1567,"children":1568},{"style":221},[1569],{"type":37,"value":1570},"        \"semantic search optimization\"\n",{"type":32,"tag":134,"props":1572,"children":1573},{"class":136,"line":278},[1574],{"type":32,"tag":134,"props":1575,"children":1576},{"style":158},[1577],{"type":37,"value":1578},"    ]\n",{"type":32,"tag":134,"props":1580,"children":1581},{"class":136,"line":295},[1582],{"type":32,"tag":134,"props":1583,"children":1584},{"style":158},[1585],{"type":37,"value":468},{"type":32,"tag":134,"props":1587,"children":1588},{"class":136,"line":309},[1589],{"type":32,"tag":134,"props":1590,"children":1591},{"style":474},[1592],{"type":37,"value":1593},"    # embeddings de modelo base (producción)\n",{"type":32,"tag":134,"props":1595,"children":1596},{"class":136,"line":26},[1597,1602,1606,1611,1615,1619,1624,1629,1634,1639,1644],{"type":32,"tag":134,"props":1598,"children":1599},{"style":158},[1600],{"type":37,"value":1601},"    baseline ",{"type":32,"tag":134,"props":1603,"children":1604},{"style":141},[1605],{"type":37,"value":455},{"type":32,"tag":134,"props":1607,"children":1608},{"style":158},[1609],{"type":37,"value":1610}," [embed(doc, ",{"type":32,"tag":134,"props":1612,"children":1613},{"style":500},[1614],{"type":37,"value":1210},{"type":32,"tag":134,"props":1616,"children":1617},{"style":141},[1618],{"type":37,"value":455},{"type":32,"tag":134,"props":1620,"children":1621},{"style":221},[1622],{"type":37,"value":1623},"\"text-embedding-3-large\"",{"type":32,"tag":134,"props":1625,"children":1626},{"style":158},[1627],{"type":37,"value":1628},") ",{"type":32,"tag":134,"props":1630,"children":1631},{"style":141},[1632],{"type":37,"value":1633},"for",{"type":32,"tag":134,"props":1635,"children":1636},{"style":158},[1637],{"type":37,"value":1638}," doc ",{"type":32,"tag":134,"props":1640,"children":1641},{"style":141},[1642],{"type":37,"value":1643},"in",{"type":32,"tag":134,"props":1645,"children":1646},{"style":158},[1647],{"type":37,"value":1648}," test_docs]\n",{"type":32,"tag":134,"props":1650,"children":1651},{"class":136,"line":327},[1652],{"type":32,"tag":134,"props":1653,"children":1654},{"style":158},[1655],{"type":37,"value":468},{"type":32,"tag":134,"props":1657,"children":1658},{"class":136,"line":350},[1659],{"type":32,"tag":134,"props":1660,"children":1661},{"style":474},[1662],{"type":37,"value":1663},"    # compara con modelo candidato\n",{"type":32,"tag":134,"props":1665,"children":1666},{"class":136,"line":595},[1667,1672,1676,1680,1684,1688,1693,1697,1701,1705,1709],{"type":32,"tag":134,"props":1668,"children":1669},{"style":158},[1670],{"type":37,"value":1671},"    candidate ",{"type":32,"tag":134,"props":1673,"children":1674},{"style":141},[1675],{"type":37,"value":455},{"type":32,"tag":134,"props":1677,"children":1678},{"style":158},[1679],{"type":37,"value":1610},{"type":32,"tag":134,"props":1681,"children":1682},{"style":500},[1683],{"type":37,"value":1210},{"type":32,"tag":134,"props":1685,"children":1686},{"style":141},[1687],{"type":37,"value":455},{"type":32,"tag":134,"props":1689,"children":1690},{"style":221},[1691],{"type":37,"value":1692},"\"text-embedding-4\"",{"type":32,"tag":134,"props":1694,"children":1695},{"style":158},[1696],{"type":37,"value":1628},{"type":32,"tag":134,"props":1698,"children":1699},{"style":141},[1700],{"type":37,"value":1633},{"type":32,"tag":134,"props":1702,"children":1703},{"style":158},[1704],{"type":37,"value":1638},{"type":32,"tag":134,"props":1706,"children":1707},{"style":141},[1708],{"type":37,"value":1643},{"type":32,"tag":134,"props":1710,"children":1711},{"style":158},[1712],{"type":37,"value":1648},{"type":32,"tag":134,"props":1714,"children":1715},{"class":136,"line":624},[1716],{"type":32,"tag":134,"props":1717,"children":1718},{"style":158},[1719],{"type":37,"value":468},{"type":32,"tag":134,"props":1721,"children":1722},{"class":136,"line":638},[1723],{"type":32,"tag":134,"props":1724,"children":1725},{"style":474},[1726],{"type":37,"value":1727},"    # verifica compatibilidad de similitud de coseno\n",{"type":32,"tag":134,"props":1729,"children":1730},{"class":136,"line":646},[1731,1736,1741,1745,1750],{"type":32,"tag":134,"props":1732,"children":1733},{"style":141},[1734],{"type":37,"value":1735},"    for",{"type":32,"tag":134,"props":1737,"children":1738},{"style":158},[1739],{"type":37,"value":1740}," i, doc ",{"type":32,"tag":134,"props":1742,"children":1743},{"style":141},[1744],{"type":37,"value":1643},{"type":32,"tag":134,"props":1746,"children":1747},{"style":405},[1748],{"type":37,"value":1749}," enumerate",{"type":32,"tag":134,"props":1751,"children":1752},{"style":158},[1753],{"type":37,"value":1754},"(test_docs):\n",{"type":32,"tag":134,"props":1756,"children":1757},{"class":136,"line":655},[1758,1763,1767],{"type":32,"tag":134,"props":1759,"children":1760},{"style":158},[1761],{"type":37,"value":1762},"        sim ",{"type":32,"tag":134,"props":1764,"children":1765},{"style":141},[1766],{"type":37,"value":455},{"type":32,"tag":134,"props":1768,"children":1769},{"style":158},[1770],{"type":37,"value":1771}," cosine_similarity(baseline[i], candidate[i])\n",{"type":32,"tag":134,"props":1773,"children":1774},{"class":136,"line":672},[1775,1780,1785,1790,1795,1799,1803,1808,1812,1817,1821,1826,1830,1835,1839],{"type":32,"tag":134,"props":1776,"children":1777},{"style":141},[1778],{"type":37,"value":1779},"        assert",{"type":32,"tag":134,"props":1781,"children":1782},{"style":158},[1783],{"type":37,"value":1784}," sim ",{"type":32,"tag":134,"props":1786,"children":1787},{"style":141},[1788],{"type":37,"value":1789},">",{"type":32,"tag":134,"props":1791,"children":1792},{"style":405},[1793],{"type":37,"value":1794}," 0.95",{"type":32,"tag":134,"props":1796,"children":1797},{"style":158},[1798],{"type":37,"value":229},{"type":32,"tag":134,"props":1800,"children":1801},{"style":141},[1802],{"type":37,"value":1196},{"type":32,"tag":134,"props":1804,"children":1805},{"style":221},[1806],{"type":37,"value":1807},"\"Embedding drift detectado: ",{"type":32,"tag":134,"props":1809,"children":1810},{"style":405},[1811],{"type":37,"value":567},{"type":32,"tag":134,"props":1813,"children":1814},{"style":158},[1815],{"type":37,"value":1816},"doc",{"type":32,"tag":134,"props":1818,"children":1819},{"style":405},[1820],{"type":37,"value":1215},{"type":32,"tag":134,"props":1822,"children":1823},{"style":221},[1824],{"type":37,"value":1825},", sim=",{"type":32,"tag":134,"props":1827,"children":1828},{"style":405},[1829],{"type":37,"value":567},{"type":32,"tag":134,"props":1831,"children":1832},{"style":158},[1833],{"type":37,"value":1834},"sim",{"type":32,"tag":134,"props":1836,"children":1837},{"style":405},[1838],{"type":37,"value":1215},{"type":32,"tag":134,"props":1840,"children":1841},{"style":221},[1842],{"type":37,"value":1843},"\"\n",{"type":32,"tag":33,"props":1845,"children":1846},{},[1847],{"type":37,"value":1848},"Este test se ejecuta",{"type":32,"tag":1850,"props":1851,"children":1852},"style",{},[1853],{"type":37,"value":1854},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":16,"searchDepth":183,"depth":183,"links":1856},[1857,1860,1863,1866,1867,1868],{"id":59,"depth":164,"text":62,"children":1858},[1859],{"id":81,"depth":183,"text":84},{"id":104,"depth":164,"text":107,"children":1861},[1862],{"id":810,"depth":183,"text":813},{"id":918,"depth":164,"text":921,"children":1864},[1865],{"id":1021,"depth":183,"text":1024},{"id":1376,"depth":164,"text":1379},{"id":1413,"depth":164,"text":1416},{"id":1477,"depth":164,"text":1480},"markdown","content:es:ai:gestion-deriva-embeddings-bases-datos-vectoriales-produccion.md","content","es\u002Fai\u002Fgestion-deriva-embeddings-bases-datos-vectoriales-produccion.md","es\u002Fai\u002Fgestion-deriva-embeddings-bases-datos-vectoriales-produccion","md",1779314638889]