Zum Hauptinhalt springen
tsecurity.de LIVE
Echtzeit-Radar & Feeds
Alle RSS Feeds
👥 Community & Social
Sichere ProgrammierungRefreshed repository pull requests page generally available(22.09.2026 um 03:25 Uhr)
Sichere ProgrammierungThe Joy of Learning the Basics Again(22.09.2026 um 03:28 Uhr)
Sichere ProgrammierungZero-Code OpenTelemetry Tracing for Dagster(22.09.2026 um 03:39 Uhr)
Linux Tipps & Hardening`prime-all`(22.09.2026 um 02:28 Uhr)
IT Security Toolsopensoho v0.15.2(22.09.2026 um 03:33 Uhr)
IT Security NachrichtenUS Proposes AI Incident Alert System in Talks With China, Bessent Says(22.09.2026 um 04:01 Uhr)
Sichere ProgrammierungRefreshed repository pull requests page generally available(22.09.2026 um 03:25 Uhr)
Sichere ProgrammierungThe Joy of Learning the Basics Again(22.09.2026 um 03:28 Uhr)
Sichere ProgrammierungZero-Code OpenTelemetry Tracing for Dagster(22.09.2026 um 03:39 Uhr)
Linux Tipps & Hardening`prime-all`(22.09.2026 um 02:28 Uhr)
IT Security Toolsopensoho v0.15.2(22.09.2026 um 03:33 Uhr)
IT Security NachrichtenUS Proposes AI Incident Alert System in Talks With China, Bessent Says(22.09.2026 um 04:01 Uhr)
Intelligence View
⚡ tsecurity.de Intelligence

LLPY-07: Integrando LLMs - OpenAI y Google Gemini

🎯 El Desafío de la Generación de Respuestas Imagina que tienes un sistema RAG funcionando perfectamente: ✅ Embeddings generados con modelos optimizados ✅ Qdrant devuelve los 5 artículos más relevantes en <50ms ✅ Reranking mejora la p…

0
↗ Quelle (dev.to)
Reagiere als Erste:r — dein Feedback zählt!




🎯 El Desafío de la Generación de Respuestas



Imagina que tienes un sistema RAG funcionando perfectamente:




  • Embeddings generados con modelos optimizados

  • Qdrant devuelve los 5 artículos más relevantes en <50ms

  • Reranking mejora la precisión al 95%+



Ahora el momento crítico: ¿cómo convertir esos documentos en una respuesta coherente, precisa y en lenguaje natural?



Necesitas un LLM (Large Language Model) que:




  • 🎯 Comprenda el contexto legal de Paraguay

  • 📝 Genere respuestas en español formal y profesional

  • 🔍 Cite artículos específicos correctamente

  • 🛡️ No invente información que no esté en el contexto (no hallucinations)

  • Responda en 1-3 segundos máximo

  • 💰 Sea cost-effective a escala

  • 🔄 Tenga fallback si un provider falla






📊 La Magnitud del Problema






Requisitos del Sistema de LLM





  1. 🤖 Multi-Provider: No depender de un solo proveedor


  2. ⚡ Async Calls: No bloquear requests mientras esperas respuesta


  3. 🔄 Retry Logic: Manejar rate limits y errores temporales


  4. 📊 Prompt Engineering: Optimizar prompts para dominio legal


  5. 🎯 Context Management: Manejar límites de tokens (4K-128K)


  6. 💰 Cost Tracking: Monitorear costos por request


  7. 🔍 Quality Control: Evaluar calidad de respuestas automáticamente


  8. 📈 Observability: Track latency, tokens, errors






Desafíos Técnicos Específicos





  1. 🕒 Latency Variable: OpenAI 1-2s, Gemini 0.5-1.5s


  2. 💸 Rate Limits: OpenAI 3,500 RPM (tier 1), Gemini 15 RPM (free tier)


  3. 🎯 Context Windows: Diferentes límites por modelo


  4. 🔀 API Differences: Cada provider tiene API distinta


  5. 🛡️ Hallucinations: LLMs pueden inventar información


  6. 💰 Costos: $0.50-$15 por 1M tokens según modelo






💡 La Solución: Multi-Provider con Abstracción






Arquitectura de Integración






┌─────────────────────────────────────────────────────────┐
│ RAGService │
│ (Orquestación del pipeline completo) │
└────────────────────┬────────────────────────────────────┘

┌───────────┴───────────┐
│ │
┌────▼────┐ ┌─────▼─────┐
│ OpenAI │ │ Gemini │
│ Client │ │ Client │
└─────────┘ └───────────┘
│ │
│ AsyncOpenAI SDK │ Google GenAI SDK
│ │
┌────▼────────────────────── ▼─────────┐
│ Retry Logic (Tenacity) │
│ Exponential Backoff │
└──────────────────────────────────────┘









¿Por Qué Multi-Provider?




































Aspecto Beneficio
Resiliencia Si OpenAI falla, usar Gemini
Cost Optimization Elegir provider más barato según caso de uso
Performance Usar provider más rápido según disponibilidad
A/B Testing Comparar calidad de respuestas entre providers
Regional Compliance Usar providers según regulaciones locales
Vendor Lock-in Evitar dependencia de un solo proveedor





🚀 Configuración Paso a Paso






1. Configuración de Variables de Entorno






# .env

# LLM Provider Configuration
API_LLM_PROVIDER=openai # Opciones: 'openai' o 'gemini'
API_LLM_MODEL=gpt-3.5-turbo # Para OpenAI

# Alternativa con Gemini:
# API_LLM_PROVIDER=gemini
# API_LLM_MODEL=gemini-1.5-flash

# API Keys
OPENAI_API_KEY=sk-proj-...
GEMINI_API_KEY=AIza...

# RAG Configuration
API_RAG_TOP_K=5






Modelos disponibles:



OpenAI:





  • gpt-3.5-turbo: Rápido, barato ($0.50-$1.50/1M tokens)


  • gpt-4: Mejor calidad ($30/1M tokens)


  • gpt-4-turbo: Balance ($10/1M tokens)


  • gpt-4o: Optimizado ($5/1M tokens)



Google Gemini:





  • gemini-1.5-flash: Rápido, barato ($0.075-$0.30/1M tokens)


  • gemini-1.5-pro: Mejor calidad ($1.25-$5/1M tokens)


  • gemini-pro: Legacy model






2. Settings con Pydantic






# src/lus_laboris_api/api/config.py

from pydantic_settings import BaseSettings

class Settings(BaseSettings):
"""Application settings"""

# LLM Configuration
api_llm_provider: str = None # 'openai' o 'gemini'
api_llm_model: str = None

# API Keys
openai_api_key: str | None = None
gemini_api_key: str | None = None

# RAG Configuration
api_rag_top_k: int = None

class Config:
env_file = ".env"
case_sensitive = False

settings = Settings()









3. Inicialización de LLM Clients






# src/lus_laboris_api/api/services/rag_service.py

import logging
from openai import AsyncOpenAI
from google import genai
from ..config import settings

logger = logging.getLogger(__name__)

class RAGService:
"""Service for RAG-based question answering"""

def __init__(self):
self.llm_provider = settings.api_llm_provider.lower()
self.llm_model = settings.api_llm_model

# Initialize LLM clients
self._initialize_llm_clients()

def _initialize_llm_clients(self):
"""Initialize LLM clients based on configured provider"""
try:
if self.llm_provider == "openai":
# AsyncOpenAI for non-blocking calls
self.openai_client = AsyncOpenAI(
api_key=settings.openai_api_key
)
logger.info("OpenAI async client initialized")

elif self.llm_provider == "gemini":
# Configure Gemini module globally
genai.configure(api_key=settings.gemini_api_key)
logger.info("Gemini configured successfully")

else:
raise ValueError(f"Unsupported LLM provider: {self.llm_provider}")

except Exception as e:
logger.exception("Failed to initialize LLM client")
raise






Características clave:




  • AsyncOpenAI: Cliente asíncrono para no bloquear requests

  • Lazy initialization: Solo se inicializa el provider configurado

  • Error handling: Fallar temprano si configuración es inválida

  • Logging: Track qué provider está activo






🎨 Prompt Engineering para Dominio Legal






1. System Prompt



El system prompt define el rol del LLM:




SYSTEM_PROMPT = """Eres un asistente especializado en derecho laboral paraguayo.
Responde la pregunta del usuario basándote únicamente en el contexto proporcionado.

CONTEXTO:
{context}

PREGUNTA: {query}

INSTRUCCIONES:
- Responde de manera clara y precisa
- Basa tu respuesta únicamente en el contexto proporcionado
- Si el contexto no contiene información suficiente, indícalo claramente
- Cita los artículos específicos cuando sea relevante
- Mantén un tono profesional y técnico apropiado para el ámbito legal

RESPUESTA:
"""






Principios de diseño:




  • Especialización: "asistente especializado en derecho laboral paraguayo"

  • Constraint: "basándote únicamente en el contexto"

  • Clarity: Instrucciones específicas y numeradas

  • Citation: Pedir citar artículos específicos

  • Tone: "tono profesional y técnico"

  • Safety: "Si no contiene información, indícalo"






2. Context Building






def _build_context(self, documents: list[dict]) -> str:
"""Build context string from retrieved documents"""
if not documents:
return "No se encontraron documentos relevantes."

context_parts = []

for i, doc in enumerate(documents, 1):
payload = doc["payload"]
articulo = payload.get("articulo", "Texto no disponible")
articulo_num = payload.get("articulo_numero", "N/A")
capitulo = payload.get("capitulo_descripcion", "N/A")

# Format: "Documento 1: [texto] [metadata]"
doc_text = (
f"Documento {i}:\n"
f"{articulo} "
f"[Capítulo: {capitulo} - Artículo número: {articulo_num}]\n"
)
context_parts.append(doc_text)

return "\n".join(context_parts)






Ejemplo de contexto generado:




Documento 1:
todo trabajador que cumpla un año de trabajo continuo al servicio del mismo empleador,
tendrá derecho a un período de vacaciones anuales remuneradas...
[Capítulo: de las vacaciones - Artículo número: 218]

Documento 2:
el trabajador perderá el derecho a las vacaciones cuando haya faltado más de quince
días sin causa justificada...
[Capítulo: de las vacaciones - Artículo número: 219]

Documento 3:
durante las vacaciones el empleador abonará al trabajador la remuneración ordinaria
correspondiente...
[Capítulo: de las vacaciones - Artículo número: 220]









3. Prompt Creation






import textwrap

def _create_prompt(self, query: str, context: str) -> str:
"""Create final prompt with context and query"""

prompt = textwrap.dedent(f"""\
Eres un asistente especializado en derecho laboral paraguayo.
Responde la pregunta del usuario basándote únicamente en el contexto proporcionado.

CONTEXTO:
{context}

PREGUNTA:
{query}

INSTRUCCIONES:
- Responde de manera clara y precisa
- Basa tu respuesta únicamente en el contexto proporcionado
- Si el contexto no contiene información suficiente, indícalo claramente
- Cita los artículos específicos cuando sea relevante
- Mantén un tono profesional y técnico apropiado para el ámbito legal

RESPUESTA:
""")

return prompt









🔄 Generación de Respuestas con OpenAI






1. Async Client para Performance






async def _generate_openai_response(self, prompt: str) -> str:
"""Generate response using OpenAI with async client"""

response = await self.openai_client.chat.completions.create(
model=self.llm_model, # 'gpt-3.5-turbo', 'gpt-4', etc.
messages=[
{
"role": "system",
"content": "Eres un asistente especializado en derecho laboral paraguayo."
},
{
"role": "user",
"content": prompt
}
],
temperature=0.2, # Baja temperatura para respuestas deterministas
max_tokens=1500, # Límite de tokens en respuesta
top_p=1.0, # Nucleus sampling
frequency_penalty=0, # No penalizar repetición (legal suele repetir conceptos)
presence_penalty=0, # No penalizar presencia de tokens
)

return response.choices[0].message.content.strip()






Parámetros clave:






































Parámetro Valor Razón
temperature 0.2 Respuestas consistentes y deterministas
max_tokens 1500 Suficiente para respuesta legal completa
top_p 1.0 No limitar vocabulario (legal requiere términos específicos)
frequency_penalty 0 Textos legales repiten conceptos por claridad
presence_penalty 0 No penalizar términos técnicos repetidos





2. Retry Logic con Tenacity






from tenacity import (
AsyncRetrying,
stop_after_attempt,
wait_exponential,
retry_if_exception_type
)
from openai import RateLimitError, APIConnectionError

async def _generate_openai_response(self, prompt: str) -> str:
"""Generate response with exponential backoff retry"""

try:
async for attempt in AsyncRetrying(
stop=stop_after_attempt(3), # Máximo 3 intentos
wait=wait_exponential(
multiplier=2, # 2^n segundos
min=2, # Mínimo 2 segundos
max=60 # Máximo 60 segundos
),
retry=retry_if_exception_type((RateLimitError, APIConnectionError)),
reraise=True
):
with attempt:
response = await self.openai_client.chat.completions.create(
model=self.llm_model,
messages=[...],
temperature=0.2,
max_tokens=1500,
)

return response.choices[0].message.content.strip()

except Exception as e:
logger.exception("OpenAI API error after retries")
raise






Retry strategy:





  • Intento 1: Inmediato


  • Intento 2: Espera 2 segundos


  • Intento 3: Espera 4 segundos


  • Falla: Propaga excepción






🔄 Generación de Respuestas con Gemini






1. Gemini Client






from google import genai
from google.genai import types

def _generate_gemini_response(self, prompt: str) -> str:
"""Generate response using Google Gemini"""

# Create model instance (lightweight - no network call)
model = genai.GenerativeModel(
model_name=self.llm_model, # 'gemini-1.5-flash', 'gemini-1.5-pro'
system_instruction="Eres un asistente especializado en derecho laboral paraguayo."
)

# Generate content
response = model.generate_content(
prompt,
generation_config=types.GenerationConfig(
temperature=0.2,
max_output_tokens=1500,
top_p=1.0,
top_k=40, # Gemini-specific: limitar candidatos
)
)

return response.text.strip()






Diferencias con OpenAI:




  • System instruction: Se pasa en el constructor del modelo

  • GenerationConfig: Configuración separada del prompt

  • top_k: Parámetro único de Gemini (limita candidatos)

  • Safety settings: Gemini tiene filtros de seguridad por defecto






2. Retry con Decorator






from tenacity import retry, stop_after_attempt, wait_exponential

@retry(
stop=stop_after_attempt(3),
wait=wait_exponential(multiplier=2, min=2, max=60),
reraise=True
)
def _generate_gemini_response(self, prompt: str) -> str:
"""Generate response with retry decorator (synchronous)"""

try:
model = genai.GenerativeModel(
model_name=self.llm_model,
system_instruction="Eres un asistente especializado en derecho laboral paraguayo."
)

response = model.generate_content(
prompt,
generation_config=types.GenerationConfig(
temperature=0.2,
max_output_tokens=1500,
)
)

return response.text.strip()

except Exception as e:
logger.exception("Gemini API error")
raise






Nota: Gemini SDK (a la fecha) no tiene cliente async nativo, por eso usamos decorator @retry en lugar de AsyncRetrying.






🔀 Abstracción Multi-Provider






async def _generate_response(
self,
query: str,
documents: list[dict],
session_id: str
) -> str:
"""Generate response using configured LLM provider"""

if not documents:
return "No se encontraron documentos relevantes para responder la pregunta."

# 1. Build context from documents
context = self._build_context(documents)

# 2. Create prompt
prompt = self._create_prompt(query, context)

# 3. Generate response based on provider
logger.info(f"Generating response with {self.llm_provider}")

start_time = time.time()

if self.llm_provider == "openai":
response = await self._generate_openai_response(prompt)

elif self.llm_provider == "gemini":
response = self._generate_gemini_response(prompt) # Sync call

else:
raise ValueError(f"Unsupported LLM provider: {self.llm_provider}")

generation_time = time.time() - start_time

# 4. Track LLM call with Phoenix
phoenix_service.track_llm_call(
session_id=session_id,
provider=self.llm_provider,
model=self.llm_model,
prompt=prompt,
response=response,
metadata={
"context_length": len(context),
"documents_count": len(documents),
"query": query,
"generation_time": generation_time,
}
)

logger.info(f"Response generated in {generation_time:.2f}s")

return response






Ventajas de la abstracción:




  • Single point of change: Cambiar provider es modificar 1 variable

  • Consistent interface: Misma API para ambos providers

  • Observability: Tracking consistente con Phoenix

  • Testing: Fácil mockear providers en tests






📊 Pipeline Completo de RAG






async def answer_question(
self,
question: str,
session_id: str | None = None
) -> dict:
"""
Complete RAG pipeline:
1. Retrieve documents from Qdrant
2. Optional reranking
3. Generate answer with LLM
4. Track with Phoenix
5. Enqueue evaluation
"""

start_time = time.time()

# Create session if not provided
if not session_id:
session_id = phoenix_service.create_session()

try:
# 1. Retrieve relevant documents (with embeddings + Qdrant search)
logger.info(f"[{session_id}] Retrieving documents for: {question[:50]}...")
documents, retrieval_metadata = self._retrieve_documents(question, session_id)

if not documents:
return {
"success": False,
"question": question,
"error": "No relevant documents found",
"processing_time_seconds": time.time() - start_time,
}

# 2. Generate answer with LLM (async)
logger.info(f"[{session_id}] Generating answer with {self.llm_provider}...")
answer = await self._generate_response(question, documents, session_id)

# 3. Calculate total processing time
processing_time = time.time() - start_time

# 4. Build context for evaluation
context_text = self._build_context(documents)

# 5. Enqueue asynchronous evaluation (non-blocking)
evaluation_service.enqueue_evaluation(
session_id=session_id,
question=question,
context=context_text,
answer=answer,
documents=documents,
metadata={
"processing_time": processing_time,
"llm_provider": self.llm_provider,
"llm_model": self.llm_model,
"reranking_applied": retrieval_metadata.get("reranking_applied", False),
}
)

# 6. Return response
return {
"success": True,
"question": question,
"answer": answer,
"processing_time_seconds": round(processing_time, 3),
"documents_retrieved": len(documents),
"top_k": self.top_k,
"reranking_applied": retrieval_metadata.get("reranking_applied", False),
"session_id": session_id,
"llm_provider": self.llm_provider,
"llm_model": self.llm_model,
"documents": [
{
"id": doc["id"],
"score": round(doc["score"], 4),
"payload": {
"articulo_numero": doc["payload"].get("articulo_numero"),
"capitulo_descripcion": doc["payload"].get("capitulo_descripcion"),
"articulo": doc["payload"].get("articulo", "")[:200] + "..."
}
}
for doc in documents
]
}

except Exception as e:
logger.exception(f"[{session_id}] Failed to answer question")

return {
"success": False,
"question": question,
"error": str(e),
"processing_time_seconds": time.time() - start_time,
"session_id": session_id,
}






Flujo del pipeline:




  1. Embedding de la pregunta (30ms)

  2. 🔍 Búsqueda en Qdrant (30ms)

  3. 📊 Reranking opcional (20ms)

  4. 🤖 LLM genera respuesta (800-2500ms) ⬅️ El cuello de botella

  5. 📈 Phoenix tracking (5ms)

  6. 🎯 Evaluation enqueue (1ms, async)



Total: 1-3 segundos (dominado por LLM)






🎯 Casos de Uso Reales






Para Aplicaciones de Producción:




"Necesito respuestas rápidas sin sacrificar calidad"



Solución: Usar Gemini 1.5 Flash (más rápido y barato)







# Configuración para producción high-traffic
export API_LLM_PROVIDER=gemini
export API_LLM_MODEL=gemini-1.5-flash

# Cost: $0.075-$0.30 / 1M tokens
# Latency: 500-1500ms
# Quality: 85-90% vs GPT-4









Para Máxima Calidad:




"Necesito las mejores respuestas posibles, costo no es problema"



Solución: GPT-4







export API_LLM_PROVIDER=openai
export API_LLM_MODEL=gpt-4

# Cost: $30 / 1M tokens
# Latency: 2000-3000ms
# Quality: 95-98%









Para Balance Costo/Calidad:




"Quiero buen balance entre costo y calidad"



Solución: GPT-3.5-turbo o GPT-4o







# Opción 1: GPT-3.5-turbo
export API_LLM_PROVIDER=openai
export API_LLM_MODEL=gpt-3.5-turbo
# Cost: $0.50-$1.50 / 1M tokens, Quality: 80-85%

# Opción 2: GPT-4o
export API_LLM_MODEL=gpt-4o
# Cost: $5 / 1M tokens, Quality: 90-95%









Para A/B Testing:




"Quiero comparar OpenAI vs Gemini en producción"



Solución: Routing dinámico por session







# Routing 50/50
import random

def get_llm_provider():
return random.choice(['openai', 'gemini'])

# En producción:
provider = get_llm_provider()
settings.api_llm_provider = provider









📊 Comparación de Modelos






Performance












































Modelo Latency (p50) Latency (p95) Throughput (req/s)
GPT-3.5-turbo 1200ms 2000ms 50-100
GPT-4 2500ms 4000ms 20-40
GPT-4o 1800ms 3000ms 40-80
Gemini 1.5 Flash 800ms 1500ms 60-120
Gemini 1.5 Pro 1500ms 2500ms 30-60





Costos












































Modelo Input ($/1M tokens) Output ($/1M tokens) Promedio RAG Query
GPT-3.5-turbo $0.50 $1.50 $0.003
GPT-4 $30 $60 $0.045
GPT-4o $5 $15 $0.010
Gemini 1.5 Flash $0.075 $0.30 $0.0002
Gemini 1.5 Pro $1.25 $5.00 $0.003


Cálculo para RAG query típico:




  • Context: ~1500 tokens (5 documentos)

  • Prompt: ~200 tokens

  • Response: ~300 tokens


  • Total: ~2000 tokens






Calidad (Evaluación Subjetiva)


















































Modelo Accuracy Completeness Clarity Legal Tone
GPT-3.5-turbo ⭐⭐⭐ ⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐
GPT-4 ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐
GPT-4o ⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐
Gemini 1.5 Flash ⭐⭐⭐ ⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐
Gemini 1.5 Pro ⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐⭐





🚀 El Impacto Transformador






Antes de LLMs:




  • 📄 Búsqueda por keywords: Devolver artículos sin explicación

  • 🤷 User interpretation: Usuario debe interpretar texto legal complejo

  • 🔍 Multiple searches: Usuario hace varias búsquedas para entender

  • ⏱️ Time consuming: 10-30 minutos para entender un concepto






Después de LLMs:




  • 💬 Lenguaje natural: Pregunta como a un abogado humano

  • 🎯 Respuesta directa: Explicación clara y profesional

  • 📚 Citas automáticas: Referencias a artículos específicos

  • Instantáneo: Respuesta en 1-3 segundos






Ejemplo Real:



Pregunta del usuario:




¿Cuántos días de vacaciones corresponden a un trabajador que lleva 2 años en la empresa?






Sin LLM (búsqueda tradicional):




Resultados:
1. Artículo 218: todo trabajador que cumpla un año...
2. Artículo 219: el trabajador perderá el derecho...
3. Artículo 220: durante las vacaciones el empleador...

[Usuario debe leer y interpretar 3 artículos completos]






Con LLM (RAG):




Según el Artículo 218 del Código del Trabajo de Paraguay, todo trabajador que cumpla 
un año de trabajo continuo al servicio del mismo empleador tiene derecho a un período
de vacaciones anuales remuneradas. En el caso de un trabajador con 2 años en la empresa,
le corresponden 12 días hábiles de vacaciones anuales.

Es importante destacar que el trabajador debe haber cumplido el año de trabajo continuo,
y según el Artículo 219, perderá este derecho si ha faltado más de quince días sin
causa justificada durante el año.

Durante las vacaciones, según el Artículo 220, el empleador debe abonar la remuneración
ordinaria correspondiente al período de descanso.









🔧 Características Técnicas Destacadas






1. Async para I/O-Bound Operations






# ❌ Synchronous - bloquea el thread
def answer_question(query):
docs = retrieve_documents(query) # Bloquea 150ms
answer = call_openai(docs) # Bloquea 2000ms
return answer

# Throughput: ~1 req/s (limitado por latencia)

# ✅ Asynchronous - no bloquea
async def answer_question(query):
docs = await retrieve_documents(query) # No bloquea
answer = await call_openai(docs) # No bloquea
return answer

# Throughput: ~50 req/s (limitado por rate limits, no latencia)









2. Retry Logic con Exponential Backoff






# Sin retry: 1 error = 1 respuesta fallida

# Con retry + exponential backoff:
# - Error transitorio (rate limit): auto-retry después de 2-4 segundos
# - Error permanente: fallar después de 3 intentos (6-8 segundos total)
# - Success rate: +15-20% en condiciones de alta carga









3. Context Window Management






def _build_context(self, documents: list[dict]) -> str:
"""Build context respecting token limits"""

max_context_tokens = 3000 # Leave room for prompt + response
current_tokens = 0
context_parts = []

for doc in documents:
doc_text = doc["payload"]["articulo"]
doc_tokens = len(doc_text) // 4 # Rough estimate: 1 token ≈ 4 chars

if current_tokens + doc_tokens > max_context_tokens:
break # Stop before exceeding limit

context_parts.append(doc_text)
current_tokens += doc_tokens

return "\n\n".join(context_parts)









💡 Lecciones Aprendidas






1. Temperatura Baja es Crucial para RAG



Con temperature=0.2, las respuestas son consistentes y basadas en el contexto. Con temperature=0.8+, el modelo tiende a "imaginar" información.






2. System Prompts Mejoran Calidad 20-30%



Definir claramente el rol ("asistente legal") y constraints ("basándote únicamente en el contexto") reduce hallucinations dramáticamente.






3. Async es No Negociable para Producción



Con llamadas LLM de 1-3 segundos, async/await es la diferencia entre 1 req/s y 50+ req/s.






4. Retry Logic Aumenta Success Rate 15%+



Rate limits y errores transitorios son comunes. Retry con exponential backoff recupera automáticamente.






5. Gemini es Más Rápido, OpenAI Más Preciso



Para alto tráfico, Gemini 1.5 Flash es imbatible. Para calidad crítica, GPT-4 lidera.






6. Multi-Provider es Resiliencia



Un solo proveedor puede fallar, tener outages, o cambiar pricing. Multi-provider es insurance.






🎯 El Propósito Más Grande



Los LLMs son el puente entre el conocimiento estructurado (artículos legales en Qdrant) y la comprensión humana. Al integrar:





  • 🤖 OpenAI GPT: Calidad de clase mundial


  • ⚡ Google Gemini: Velocidad y costo optimizado


  • 🔄 Async Architecture: Throughput de producción


  • 🛡️ Retry Logic: Resiliencia ante errores


  • 🎨 Prompt Engineering: Respuestas precisas y profesionales


  • 📊 Observability: Tracking completo con Phoenix



Estamos democratizando el acceso a asesoría legal, convirtiendo texto legal complejo en respuestas claras que cualquier persona puede entender, en segundos y a costo marginal cercano a cero.









🔗 Recursos y Enlaces






Repositorio del Proyecto








Documentación Técnica








Recursos Externos








Próximo Post: LLPY-08 - Reranking: Mejorando la Precisión de Búsqueda



En el siguiente post exploraremos cómo el reranking con modelos cross-encoder mejora la precisión de resultados RAG, cuándo usarlo, y el trade-off entre calidad y latencia.

Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten LLPY-07: Integrando LLMs - OpenAI y Google Gemini

Thematisch verwandte Begriffe: LLPY07, Integrando, LLMs, OpenAI · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Zum Aktualisieren ziehen
ZERO-DAY CVE-2026-49449 | Joplin is an open source note-taking and to-do application that organise…
Advisory →
TTS Reader • tsecurity.de Voice
tsecurity.de Icon
tsecurity.de App
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag
Themen-Radar & Intelligence Matrix
Echtzeit-Taxonomie nach Angriffsvektoren & Plattformen

tsecurity.de Live Threat Radar

🔴 LIVE RADAR
MONITORING
AKTIV
CVE-DATENBANK
LIVE
🔍
Community Radar & Live Chat
Sentinel Bot online • Live-Stream
Dein Cluster: Security Explorer
Match:
lädt…
Verbindung zum Community-Stream wird aufgebaut...
Bearbeitungsmodus — Senden überschreibt deine Nachricht
Community-Puls — was gerade passiert
lädt…
Aktivitäten deiner Analysten
lädt…
Neues Thema oder Eilmeldung einreichen

Reiche interessante Links, Zero-Days oder Debatten ein. Die Community entscheidet per Upvote über die Veröffentlichung.

Heiß diskutierte Einreichungen
🔖 Gespeicherte Artikel
📂 Keine gespeicherten Artikel vorhanden.
Zurück Ziehen Vor
Links: vorheriger Artikel Rechts: nächster Artikel unten: schließen
News NIS-2 Frühwarnung Tier-1 Intel ⏱️ 3 Min vor 10 Min
Artikeldaten werden geladen...

Zurück: vorheriger Vor: nächster
↗ Original-Quelle
Social Reaktionen Deine Reaktion zählt
Einstufung & Relevanz-Poll 0 Stimmen
In sozialen Netzwerken teilen 1-Klick