Stack empresarial del agente
Propósito
Section titled “Propósito”Este documento mapea la brecha entre la implementación de referencia actual de la demo y lo que requeriría un despliegue de producción. Sirve a los operadores que planean adaptar la demo a un despliegue real, y a los lectores que evalúan la conciencia de producción de la implementación de referencia.
La arquitectura se presenta a lo largo de cinco capas (Cómputo/Hospedaje, Almacenamiento/Datos, IA/ML, Observabilidad, Seguridad/Cumplimiento) usando diagramas Mermaid para mayor claridad visual.
Alcance
Section titled “Alcance”Esto cubre el agente conversacional de adherencia a la medicación tal como está desplegado en Google Cloud Run, la canalización de CI/evaluación y una arquitectura de referencia de producción genérica. La demo corre en un host específico (Cloud Run); la referencia de producción no prescribe un proveedor de nube específico: identifica lo que un despliegue real necesitaría, no qué proveedor usar.
1. Diagrama de contexto del sistema
Section titled “1. Diagrama de contexto del sistema”La vista de más alto nivel: quién usa el sistema, de qué sistemas externos depende y qué datos fluyen entre ellos.
graph TB
Patient[Patient / Caregiver<br/>Chat + Voice UI]
Operator[Operator / Reviewer<br/>Demo Key Mgmt + HITL Review]
Agent[Medication Adherence Agent<br/>FastAPI + LangGraph]
LLM[LLM Providers<br/>OpenAI + Anthropic<br/>Groq judge fallback]
TTS[ElevenLabs<br/>TTS + STT]
KB[Knowledge Base<br/>Chroma Embedded<br/>38 Synthetic KB Cards]
Obs[Observability<br/>OTel / Langfuse / Phoenix]
Supabase[(Supabase<br/>Demo Operational Data)]
Patient -->|Chat / Voice Input| Agent
Operator -->|Key Mgmt + Review| Agent
Agent -->|Generate + Judge| LLM
Agent -->|TTS / STT| TTS
Agent -->|Retrieve + Cite| KB
Agent -->|Spans + Metrics| Obs
Agent -->|Keys + Sessions + Interactions| Supabase
Agent -->|Response| Patient
Límites clave:
- El agente es el único límite de confianza. Todo el input del usuario entra a través de FastAPI y pasa por la canalización de barreras de seguridad antes de alcanzar cualquier sistema externo.
- Los proveedores de LLM, ElevenLabs y los destinos de observabilidad son dependencias externas. El agente se degrada con elegancia cuando alguno de ellos no está disponible.
- Supabase almacena datos operativos (claves de la demo, interacciones, sugerencias de mejora) pero el agente sigue sirviendo turnos si está caído.
2. Diagramas de contenedores
Section titled “2. Diagramas de contenedores”Tres contextos de despliegue: la demo en vivo, la canalización de CI/evaluación y una referencia de producción.
2.1 Contenedor de la demo (actual)
Section titled “2.1 Contenedor de la demo (actual)”graph TB
subgraph CloudRun["Google Cloud Run<br/>Single Instance (max-instances 1)<br/>us-central1 / scale-to-zero"]
FastAPI[FastAPI<br/>Single Uvicorn Worker]
Graph[LangGraph StateGraph<br/>6 Nodes + Optional HITL]
MemorySaver[MemorySaver<br/>In-Memory Checkpointer]
Chroma[Chroma Embedded<br/>DuckDB + Parquet<br/>38 Synthetic Cards]
Resilience[Resilience Layer<br/>Rate Limiter + Fallback + Cache]
OTel[OTel Exporter]
end
subgraph External["External Services"]
OpenAI[OpenAI<br/>gpt-4o-mini<br/>Primary Completions]
Anthropic[Anthropic<br/>claude-haiku-4-5<br/>Fallback + Eval Judge]
Langfuse[Langfuse Cloud Hobby<br/>50K obs/month]
Supabase[(Supabase Free Tier<br/>500 MB Postgres)]
ElevenLabs[ElevenLabs<br/>TTS + STT<br/>Entitlement-gated]
end
FastAPI --> Graph
Graph --> MemorySaver
Graph --> Chroma
Graph --> Resilience
Resilience --> OpenAI
Resilience --> Anthropic
FastAPI --> OTel
OTel --> Langfuse
FastAPI --> Supabase
FastAPI --> ElevenLabs
Costo: cerca de $0/mes a escala de demo. El hospedaje (la franquicia siempre gratuita de Cloud Run bajo una única instancia con escala a cero), la observabilidad (Langfuse Cloud Hobby, 50K obs/mes) y los datos operativos (nivel gratuito de Supabase) se mantienen dentro de niveles gratuitos con tráfico de demo (50-150 revisores, 5-10 turnos cada uno). Las completaciones del LLM corren en proveedores de pago (OpenAI primario, Anthropic de respaldo), medidas por el registro de costos “como si se pagara” y acotadas por un cortacircuitos de presupuesto diario, de modo que el gasto de la demo está acotado. La primera solicitud tras que la instancia escala a cero paga un arranque en frío del contenedor. La misma imagen también corre a costo genuinamente $0 en Hugging Face Spaces como destino secundario.
2.2 Contenedor de CI/evaluación
Section titled “2.2 Contenedor de CI/evaluación”graph TB
subgraph GitHub["GitHub Actions<br/>ubuntu-latest"]
Build[Docker Build<br/>Same Dockerfile]
Pytest[pytest Runner<br/>Deterministic Core<br/>Coverage Gate]
end
subgraph Eval["Eval Pipeline"]
Deterministic[Deterministic Scorers<br/>Citation + Refusal<br/>Escalation + Recall]
Judge[LLM-as-Judge<br/>Anthropic claude-haiku-4-5<br/>Groundedness + Faithfulness]
DeepEval[DeepEval<br/>Hallucination Metric]
Promptfoo[Promptfoo Nightly<br/>OWASP LLM Top 10 subset]
end
subgraph TestInfra["Test Infrastructure"]
StubLLM[StubLLMClient<br/>Deterministic, Key-Free]
Phoenix[Phoenix Self-Hosted<br/>Docker Compose Profile]
GoldenCorpus[Golden Corpus<br/>315 Cases / 3 Locales<br/>JSONL Format]
end
Build --> Pytest
Pytest --> StubLLM
Pytest --> Deterministic
Pytest --> Judge
Pytest --> DeepEval
Pytest --> Phoenix
Pytest --> GoldenCorpus
Promptfoo --> GoldenCorpus
Garantía de determinismo: La puerta de CI pasa sin claves a través de un cliente LLM de prueba (stub) determinista. Los scorers respaldados por juez se activan únicamente cuando se configura una clave del proveedor juez (Anthropic). La misma imagen de Docker que pasa la CI es la imagen que se entrega a Cloud Run.
2.3 Contenedor de referencia de producción
Section titled “2.3 Contenedor de referencia de producción”graph TB
subgraph Cloud["Cloud Hosting<br/>e.g., AWS / GCP / Azure"]
LB[Load Balancer<br/>TLS Termination]
FastAPIProd[FastAPI<br/>Multiple Workers<br/>Behind Reverse Proxy]
GraphProd[LangGraph StateGraph<br/>Same 6 Nodes]
PostgresSaver[AsyncPostgresSaver<br/>Durable Checkpointer]
ManagedVector[Managed Vector Store<br/>e.g., Qdrant Cloud / Pinecone]
ResilienceProd[Resilience Layer<br/>Redis-backed Rate Limiting<br/>Circuit Breakers]
end
subgraph LLMProd["LLM Providers"]
LLMPrimary[Primary LLM<br/>SLA-backed API]
LLMFallback[Fallback LLM<br/>Different Vendor]
LLMJudge[Judge Model<br/>Dedicated Instance]
end
subgraph SecurityProd["Security + Compliance"]
WAF[Web Application Firewall]
SIEM[SIEM Integration<br/>Audit Log Export]
SecretsMgr[Secrets Manager<br/>Vault / Cloud Secret Manager]
KMS[Key Management Service]
end
LB --> WAF
WAF --> FastAPIProd
FastAPIProd --> GraphProd
GraphProd --> PostgresSaver
GraphProd --> ManagedVector
FastAPIProd --> ResilienceProd
ResilienceProd --> LLMPrimary
ResilienceProd --> LLMFallback
FastAPIProd --> SIEM
FastAPIProd --> SecretsMgr
FastAPIProd --> KMS
Brecha de producción: La demo se ejecuta en una única instancia con escala a cero y estado en memoria. Producción necesita escalado horizontal tras un balanceador de carga, persistencia durable, secretos gestionados, WAF, SIEM y proveedores de LLM respaldados por SLA. La arquitectura es la misma (StateGraph de LangGraph de seis nodos) — solo cambian las capas de infraestructura.
3. Diagrama de componentes: interioridades del grafo del agente
Section titled “3. Diagrama de componentes: interioridades del grafo del agente”El StateGraph de LangGraph de seis nodos con el séptimo nodo opcional de HITL.
graph LR
Intake[intake<br/>Mark turn start<br/>Seed trace_id<br/>PII redaction]
GuardPre[guardrail_pre<br/>Scope classification<br/>Escalation detection<br/>Out-of-domain routing]
Retrieve[retrieve_context<br/>RAG from Chroma<br/>Citation matching]
Generate[generate_response<br/>LLM generation<br/>Citation enforcement]
GuardPost[guardrail_post<br/>Output safety check<br/>Refusal verification]
Closing[closing<br/>Duration calculation<br/>OTel span close]
Review[review_response<br/>HITL pause<br/>Optional 7th node]
Intake --> GuardPre
GuardPre -->|in-scope| Retrieve
GuardPre -->|out-of-domain| Generate
GuardPre -->|escalation| Closing
Retrieve --> Generate
Generate --> GuardPost
GuardPost -->|safe| Closing
GuardPost -->|flagged| Review
Review -->|approved| Closing
Review -->|rejected| Generate
Flujo de datos:
- intake — marca el inicio del turno, siembra el ID de traza, aplica la redacción de PII.
- guardrail_pre — ejecuta el clasificador de alcance. Los mensajes dentro del alcance avanzan a la recuperación RAG. Los mensajes fuera de dominio omiten la recuperación y obtienen una alternativa elegante. Los mensajes que disparan escalamiento hacen cortocircuito hacia el cierre con una derivación.
- retrieve_context — consulta Chroma embebido en busca de tarjetas de KB relevantes. Si ninguna tarjeta coincide, el agente se rehúsa en lugar de alucinar.
- generate_response — llama al proveedor de LLM configurado con el contexto recuperado y un prompt que exige citación.
- guardrail_post — verifica que la respuesta generada no contenga contenido de dosificación, diagnóstico u otro contenido fuera de alcance. Las respuestas marcadas se enrutan a la revisión HITL.
- closing — calcula la duración del turno, cierra el span de OTel y devuelve la respuesta.
- review_response (opcional) — una interrupción de LangGraph para la revisión con humano en el ciclo de los turnos marcados. Desactivada por defecto en el modo de evaluación.
4. Comparación de cinco capas: demo vs producción
Section titled “4. Comparación de cinco capas: demo vs producción”| Capa | Demo (actual) | Referencia de producción |
|---|---|---|
| Cómputo/Hospedaje | Google Cloud Run; una única instancia de contenedor (--max-instances 1); región us-central1; escala a cero cuando está inactivo; despliegue sin llaves gatillado por etiqueta desde la misma imagen que CI | Hospedaje en la nube (cualquier proveedor); múltiples instancias tras un balanceador de carga; autoescalado; despliegues sin tiempo de inactividad; disponibilidad respaldada por SLA |
| Almacenamiento/Datos | Chroma embebido (DuckDB+Parquet) para RAG; MemorySaver en memoria para el estado de la conversación; nivel gratuito de Supabase (500 MB) para los datos operativos de la demo | Almacén de vectores gestionado (Qdrant Cloud / Pinecone) para RAG; AsyncPostgresSaver para el estado durable de la conversación; Postgres gestionado (RDS / Cloud SQL) con respaldos para los datos operativos; cifrado de datos en reposo |
| IA/ML | OpenAI gpt-4o-mini (primario) con Anthropic claude-haiku-4-5 (respaldo) para las completaciones; juez de evaluación Anthropic claude-haiku-4-5 (Groq como respaldo del juez); embeddings gestionados de Voyage voyage-3.5 (primario) con un fallback local integrado BAAI/bge-small-en-v1.5; cliente LLM de prueba (stub) determinista para CI; tarjetas de KB sintéticas | API de LLM respaldada por SLA con throughput dedicado; una instancia de juez dedicada; servicio de embeddings gestionado; base de conocimiento expandida con revisión clínica; evaluación continua con detección de deriva |
| Observabilidad | Spans de OTel con convenciones de OpenInference; Langfuse Cloud Hobby (50K obs/mes); Phoenix autohospedado en Docker para las corridas de evaluación; Arize AX como tablero secundario; exportación OTLP | Stack completo de OTel con colector, muestreo y políticas de retención; backend de observabilidad dedicado (Datadog / Grafana / Honeycomb); alertas sobre latencia, tasa de error y anomalías de costo; exportación de registros de auditoría a SIEM |
| Seguridad/Cumplimiento | Sin secretos en el repo (gitleaks en CI); lockfile anclado; Dependabot habilitado; sin PHI / sin EHR real; encuadre de General Wellness de la FDA; redacción de PII en el ingreso y el egreso; borde de Cloudflare (Turnstile, origin-lock) | Protección WAF / DDoS; secretos gestionados (Vault / Cloud Secret Manager); BAA con todos los proveedores de LLM; cumplimiento de la HIPAA Security Rule; SOC 2 Type II; pruebas de penetración; plan de respuesta a incidentes |
Cronograma de producción (cualitativo)
Section titled “Cronograma de producción (cualitativo)”La comparación de cinco capas nombra qué cambia entre la demo y un despliegue de producción; esta banda esboza cuándo, como fases cualitativas en lugar de fechas comprometidas. Cada fase está condicionada a la anterior, y el código del agente (el grafo de seis nodos y sus barreras de seguridad) atraviesa las cuatro sin cambios: el trabajo está en las capas de infraestructura y gobernanza.
graph LR
A[Demo today<br/>Cloud Run single instance<br/>synthetic data, near $0] --> B[Hardening<br/>durable state + shared store<br/>managed vector store]
B --> C[Pilot<br/>clinical KB review<br/>BAA + compliance controls]
C --> D[Production<br/>multi-instance autoscale<br/>SLA + alerting + SIEM]
La demo ya entrega la parte difícil determinante -el comportamiento del agente medido y controlado por puertas-, así que el cronograma está dominado por el trabajo de infraestructura y cumplimiento, no por reconstruir el agente.
Costo a volumen (ilustrativo)
Section titled “Costo a volumen (ilustrativo)”La demo corre cerca de $0 / mes: hosting scale-to-zero, observabilidad y
datos operativos en niveles gratuitos, y completions de LLM medidos por el
libro de costos as-if-paid bajo un cortacircuitos diario duro. El costo de
producción no es ese número escalado linealmente: tiene dos partes que escalan
distinto.
- El costo variable es la inferencia del LLM: tokens por turno por la tarifa del proveedor. Escala más o menos linealmente con el tráfico y es la línea dominante a volumen. El libro as-if-paid ya lo mide por turno, así que una cotización real parte de una base medida y no de una suposición.
- El costo fijo es el piso de infraestructura: una instancia caliente, un vector store gestionado, un Postgres gestionado y un backend de observabilidad con retención. Aparece como un escalón al salir de los niveles gratuitos y se mantiene bastante plano a lo ancho de una amplia banda de tráfico.
La forma, como bandas ilustrativas de orden de magnitud -las cifras reales dependen del contrato del proveedor, el modelo, el tamaño de recuperación y el uso de voz:
| Turnos mensuales | Qué domina | Forma del costo |
|---|---|---|
| Demo (cientos) | niveles gratuitos + LLM medido | cerca de $0, acotado por el cortacircuitos diario |
| Miles bajos | tokens de LLM por turno | gasto variable pequeño; infra aún casi-gratis |
| Decenas de miles | tokens de LLM + instancia caliente + stores gestionados | aparece un piso de infra fijo; domina el costo variable de LLM |
| Cientos de miles+ | throughput de LLM + retención | territorio de contrato con el proveedor: negocia throughput y tarifas |
Dos palancas mueven la línea variable sin tocar el agente: un modelo de generación más pequeño o más barato, y una recuperación que mantenga el prompt ajustado (menos tokens por turno). Ambas son configuración, no una reconstrucción.
5. Detalles de las capas
Section titled “5. Detalles de las capas”5.1 Cómputo/Hospedaje
Section titled “5.1 Cómputo/Hospedaje”Estado actual. La demo se ejecuta en Google Cloud Run como una única
instancia de contenedor (--max-instances 1, región us-central1), escalando
a cero cuando está inactiva. Los despliegues son sin llaves (Workload Identity
Federation) y están condicionados a una matriz de CI en verde para la etiqueta
de versión; el mismo Dockerfile se construye en CI, en el desarrollo local y en
Cloud Run. El techo de una sola instancia es deliberado: el limitador de tasa,
la caché de respuestas y el checkpointer de HITL son en proceso.
Brecha de producción. Un despliegue de producción necesita múltiples instancias tras un balanceador de carga, autoescalado para manejar los picos de tráfico, despliegues sin tiempo de inactividad y disponibilidad respaldada por SLA (típicamente 99,9% o más). Los arranques en frío deben eliminarse con un conteo mínimo de instancias calientes. El código del agente en sí es portable — FastAPI con uvicorn funciona tras cualquier proxy inverso — pero la capa de infraestructura necesita una inversión significativa.
Ruta de migración. La misma imagen de Docker puede desplegarse en cualquier host con capacidad de Docker; Hugging Face Spaces está documentado como destino secundario (consulta despliegue). Escalar hacia afuera en Cloud Run significa elevar el techo de instancias, agregar una instancia mínima caliente y mover el limitador de tasa, la caché y el checkpointer en proceso a un almacén compartido (Redis, Postgres) para que se comporten de forma consistente entre instancias.
5.2 Almacenamiento/Datos
Section titled “5.2 Almacenamiento/Datos”Estado actual. La recuperación RAG usa Chroma embebido (DuckDB+Parquet),
que es de cero red y se ejecuta enteramente dentro de la memoria de la
instancia. El estado de la conversación usa MemorySaver en memoria por
defecto; se pierde al reiniciar la instancia. Los datos operativos de la demo
(claves, sesiones, interacciones) se almacenan en el nivel gratuito de Supabase
(500 MB de Postgres gestionado). La base de conocimiento contiene tarjetas de
KB sintéticas en formato JSONL.
Brecha de producción. Un despliegue de producción necesita estado de
conversación durable (AsyncPostgresSaver mediante una cadena de conexión de
Postgres). La recuperación RAG debería usar un almacén de vectores gestionado
(Qdrant Cloud, Pinecone o pgvector en el Postgres operativo) para la
persistencia, el soporte de corpus más grandes y el desempeño de consultas a
escala. Los datos operativos necesitan un Postgres gestionado con respaldos
automatizados, recuperación a un punto en el tiempo y cifrado en reposo.
Ruta de migración. El agente ya provisiona una fábrica de checkpointer de Postgres durable mediante una cadena de conexión. Cambiar de Chroma embebido a un almacén de vectores gestionado requiere actualizar la configuración del recuperador pero no el grafo del agente en sí. El formato JSONL versionado ya es compatible con la carga masiva en cualquier almacén de vectores.
5.3 IA/ML
Section titled “5.3 IA/ML”Estado actual. Las completaciones del LLM corren una cascada de dos
proveedores: OpenAI gpt-4o-mini como primario, con respaldo en Anthropic
claude-haiku-4-5 ante una falla transitoria del upstream. El juez de
evaluación es Anthropic claude-haiku-4-5, con Groq
llama-3.3-70b-versatile como nivel de respaldo del juez. Los embeddings usan
por defecto el embedder gestionado de Voyage cuando hay una clave de Voyage
presente y recaen en BAAI/bge-small-en-v1.5 localmente (sin llamada a API).
El arnés de evaluación es un núcleo de pytest hecho a mano más DeepEval
(métrica de Alucinación), un LLM-como-juez de Anthropic y Promptfoo
(red-team), ejecutado contra casos golden sintéticos a lo largo de tres
locales (en, es-419, pt-BR). La base de conocimiento cubre varios dominios de
adherencia a la medicación con 38 tarjetas sintéticas.
Brecha de producción. Las API de los proveedores tienen límites de tasa e infraestructura compartida. Un despliegue de producción necesita proveedores de LLM respaldados por SLA con throughput y latencia garantizados. El juez de evaluación debería ejecutarse en una instancia dedicada para la consistencia. La base de conocimiento necesitaría revisión clínica y expansión más allá de los datos sintéticos. La evaluación continua con detección de deriva es esencial para la seguridad de producción.
Ruta de migración. El Protocol del cliente hace que cambiar de proveedor sea un cambio de configuración. Agregar un nuevo proveedor requiere implementar el Protocol (a lo sumo un puñado de métodos) y configurar la cascada de generación mediante configuración. El arnés de evaluación ya puntúa contra umbrales configurables y está controlado por CI.
5.4 Observabilidad
Section titled “5.4 Observabilidad”Estado actual. Los spans de OpenTelemetry con convenciones semánticas de OpenInference envuelven cada nodo, llamada al LLM, recuperación y decisión de barrera de seguridad. Destinos: Langfuse Cloud Hobby para la demo en vivo (50K observaciones/mes, retención de 30 días), Phoenix autohospedado vía Docker Compose para las corridas de evaluación, y Arize AX como tablero secundario. No hay alertas configuradas.
Brecha de producción. Un despliegue de producción necesita un stack completo de OTel: un colector con muestreo configurable, un backend dedicado con retención larga (90+ días), alertas sobre percentiles de latencia, tasas de error y anomalías de costo, y exportación de registros de auditoría a SIEM para el cumplimiento. Los spans actuales ya portan los atributos correctos; la brecha está en la infraestructura del backend, no en la instrumentación.
Ruta de migración. La instrumentación de OTel es neutral respecto del
proveedor. Cambiar de backend es un cambio de configuración del exportador
OTLP. Los atributos de span existentes (interaction.*, llm.*,
retrieval.*) son compatibles con cualquier backend compatible con OTel.
5.5 Seguridad/Cumplimiento
Section titled “5.5 Seguridad/Cumplimiento”Estado actual. Sin secretos en el repositorio (impuesto por gitleaks en CI). Las dependencias están ancladas mediante el lockfile con monitoreo de Dependabot. Sin PHI, sin datos reales de EHR, sin información identificatoria de pacientes (datos 100% sintéticos). El agente opera bajo el encuadre de General Wellness / CDS de la FDA 2026 (consulta la postura regulatoria). La redacción de PII se aplica tanto en el ingreso como en el egreso. Un borde de Cloudflare (verificación de bots con Turnstile, origin-lock) protege el servicio. La huella digital de las claves de la demo usa una huella sha256 seudonimizada (re-identificable), no anonimización.
Brecha de producción. Un despliegue de producción que maneje datos reales de pacientes necesitaría: Web Application Firewall y protección DDoS, secretos gestionados (Vault, Cloud Secret Manager), Acuerdos de Asociado de Negocio con todos los proveedores de LLM, cumplimiento de la HIPAA Security Rule (evaluación de riesgos, notificación de brechas, acceso mínimo necesario), certificación SOC 2 Type II, pruebas de penetración regulares y un plan de respuesta a incidentes. La postura regulatoria pasaría de General Wellness a un marco de cumplimiento completo.
Ruta de migración. La arquitectura de barreras de seguridad está diseñada para producción: la clasificación de alcance determinista, las plantillas de rechazo auditables y el escalamiento basado en reglas son todos patrones de grado de producción. La brecha de seguridad está principalmente en la infraestructura (WAF, gestión de secretos, cifrado) y en el proceso (evaluaciones de riesgos, calendarios de auditoría), no en el código de la aplicación.
Referencias cruzadas
Section titled “Referencias cruzadas”| Tema | ADR |
|---|---|
| Marco de orquestación (StateGraph de seis nodos) | ADR-0001 |
| Abstracción de proveedor de LLM (Protocol + adaptadores) | ADR-0002 |
| Arnés de evaluación (pytest + DeepEval + juez Anthropic + Promptfoo) | ADR-0003 |
| Stack de RAG (Chroma embebido) | ADR-0004 |
| Barreras de seguridad (alcance + rechazo + escalamiento) | ADR-0005 |
| Observabilidad (OTel + OpenInference) | ADR-0006 |
| Despliegue (Google Cloud Run) | ADR-0007 |
| Capa de datos (nivel gratuito de Supabase) | ADR-0010 |
| Extensión de voz (ElevenLabs TTS/STT) | ADR-0013 |
| Arquitectura de streaming (eventos SSE) | ADR-0009 |