Modelo, capacidades y límites
Modelo en uso
Sección titulada «Modelo en uso»Todos los agentes usan Claude Haiku 4.5 (claude-haiku-4-5-20251001)
como default. La elección está fija en src/agents/base.ts:
abstract class BaseAgent { protected model = "claude-haiku-4-5-20251001"; // …}Cualquier agente puede sobrescribir model si necesita un upgrade
(ej. Sonnet para razonamiento más denso). Hoy ningún agente lo hace.
Especificaciones técnicas
Sección titulada «Especificaciones técnicas»| Característica | Valor |
|---|---|
| Familia | Claude 4.5 |
| Versión exacta | claude-haiku-4-5-20251001 |
| Context window | 200K tokens |
| Max output tokens | 8192 (configurable por agente, ver abajo) |
| Tool use | sí |
| Vision | sí (no se usa hoy en emi) |
| Idiomas | multi-idioma; respondemos según context.locale |
| Knowledge cutoff | enero 2025 |
| Latencia típica | 0.5-2s por turno (sin tool loop) |
Configuración por agente
Sección titulada «Configuración por agente»Cada agente extiende BaseAgent y puede ajustar maxTokens, tools y
buildSystemPrompt. La tabla refleja el código actual:
| Agente | App | maxTokens output | Tools | System prompt aprox |
|---|---|---|---|---|
sales | emahealth | 1024 (default) | 1 (lead_management) | ~80 líneas |
support | emaclinic | 2048 | 11 (Aidbox per-tenant) | ~75 líneas |
analytics | emavault | 2048 | 6 (Vault Supabase) | ~80 líneas |
lab_assistant | emalab | 1024 | 0 (alpha) | ~30 líneas |
pathology_assistant | emapath | 512 | 0 (planned) | ~20 líneas |
wellness_coach | emawell | — | — | retorna 501 antes de invocar Claude |
Por qué support y analytics suben a 2048
Sección titulada «Por qué support y analytics suben a 2048»Generan respuestas con datos tabulares (pacientes, finanzas) que requieren más espacio. Sales y lab/path ven menos complejidad por turno y se quedan en 1024 / 512.
Contexto dinámico
Sección titulada «Contexto dinámico»buildSystemPrompt(context, turnCount) puede inyectar:
locale— fija el idioma de la respuestaturnCount— cuántos turnos del usuario lleva la conversacióntenantId— para queries scope-adas (support / lab / path)patientId/encounterId— clínicosessionId,visitorEmail,referrer— sales (visitante anónimo)
Hoy la base implementación es identidad (return this.systemPrompt).
Cada agente puede override para inyectar contexto cuando lo necesite.
Pricing hardcoded en src/lib/cost.ts. Refleja tarifas Anthropic
publicadas a la fecha del cutover Wave 3 (2026-05-08). Wave 4 mueve esto
a emashared.model_pricing para gestión vía Vault.
Tabla de precios (USD por millón de tokens)
Sección titulada «Tabla de precios (USD por millón de tokens)»| Modelo | Input | Output |
|---|---|---|
claude-haiku-4-5-20251001 (en uso) | $1.00 | $5.00 |
claude-sonnet-4-6-20251101 | $3.00 | $15.00 |
claude-opus-4-7-20260301 | $15.00 | $75.00 |
Costo típico por invocación (estimado)
Sección titulada «Costo típico por invocación (estimado)»Para un turn promedio de Haiku con tool loop de 1-2 iteraciones:
| Agente | Input típico | Output típico | Costo USD |
|---|---|---|---|
sales | ~600 tokens | ~150 tokens | $0.0014 |
support (con 1 tool) | ~1500 tokens | ~400 tokens | $0.0035 |
analytics (con 1 tool) | ~1300 tokens | ~350 tokens | $0.0031 |
lab_assistant | ~400 tokens | ~120 tokens | $0.0010 |
pathology_assistant | ~300 tokens | ~80 tokens | $0.0007 |
Una conversación típica de 5 turnos en support ronda $0.018 USD.
Agregación a través del tool loop
Sección titulada «Agregación a través del tool loop»runAgent agrega tokens input + output a través de todas las
iteraciones del tool loop, no solo el último turn (F015). El campo
cost_usd en emi_invocations refleja el costo total de la
invocación, incluidas las llamadas intermedias del tool use.
Restricciones de privacidad y uso
Sección titulada «Restricciones de privacidad y uso»Privacidad (F005)
Sección titulada «Privacidad (F005)»Nunca se loguean ni persisten:
- Prompts completos del usuario.
- Responses completos del modelo.
- Valores PHI (nombre del paciente, RUT, diagnósticos, etc.).
Lo que sí se persiste en emi_invocations.context_summary
(summarizeContext):
- Presencia de campos sensibles:
has_patient_id: true,has_encounter_id: false. - Metadata no-PHI:
action,locale,route.
Uso (per system prompt de cada agente)
Sección titulada «Uso (per system prompt de cada agente)»Restricciones comunes inyectadas vía system prompt:
- Sales: no inventar precios, plazos ni compromisos. Derivar
decisiones comerciales reales a
cal.com. - Support: no diagnosticar. Solo asistir al profesional con datos reales del paciente. Si no hay datos, decirlo explícitamente — nunca alucinar.
- Analytics: no inventar cifras financieras. Si una tool no devuelve el dato, decir que falta.
- Lab / Pathology: avisar honestamente que las tools de validación llegan en Wave 5+/6.
- Wellness: no implementado, retorna 501.
Lo que ningún agente puede hacer
Sección titulada «Lo que ningún agente puede hacer»- Ejecutar código arbitrario (no es coding assistant).
- Acceder a datos de otro tenant — el scoping FHIR + activación per-app
meta.taglo bloquean a nivel de infraestructura.
- Llamar a APIs externas que no estén declaradas como tool del agente.
- Mantener memoria entre conversaciones (stateless).
Límites operacionales
Sección titulada «Límites operacionales»Tool loop
Sección titulada «Tool loop»MAX_TOOL_ITERATIONS = 5 // src/lib/claude.ts:5Si Claude encadena 5 tool calls sin llegar a end_turn, el loop corta
y devuelve la última respuesta del modelo. Previene loops infinitos y
costos descontrolados.
Anthropic 529 (overloaded)
Sección titulada «Anthropic 529 (overloaded)»runAgent reintenta automáticamente:
- 3 intentos.
- Backoff exponencial: 1s · 2s · 3s.
- Si los 3 fallan →
503al cliente.
Cloudflare Workers deadline
Sección titulada «Cloudflare Workers deadline»CF Workers tiene un deadline de ~30 segundos por request (CPU time limit en plan paid). En la práctica:
- Un turn simple sin tool: ~1-2s.
- Un tool loop completo: 5-15s típico.
- Si las queries a Aidbox/Supabase son lentas, el loop puede acercarse
al deadline. Logger estructurado expone
latency_mspor invocación para detectar.
Rate limit per-tenant
Sección titulada «Rate limit per-tenant»tenant_emi_access.daily_invocation_limit define cuántas invocaciones
exitosas puede hacer cada tenant por día UTC. Cuenta solo status='success'
(F004). Si supera → 403 rate limited.
Tool result size
Sección titulada «Tool result size»No hay límite hard hoy. Las tools de support/analytics que pueden
devolver mucho (ej. list_appointments sin filtro) deberían paginar
del lado de la tool. Si un tool result excede el context window, Claude
reportará el error en su siguiente turn.
Política de upgrade del modelo
Sección titulada «Política de upgrade del modelo»Anthropic publica nuevas versiones con regularidad (Haiku 4.5 → 4.6 → 5, etc.). La política de emi:
- Pinear el modelo exacto (
claude-haiku-4-5-20251001) en código. No usar alias automáticos comoclaude-haiku-latest. - Probar el modelo nuevo en staging antes de promover. Métricas a
chequear:
- Latencia p95 (no debería subir > 20%).
- Costo USD por invocación.
- Quality del tool use (que sepa cuándo invocar tool y cuándo no).
- Pricing: actualizar
cost.tscon los nuevos números antes del bump. - Rollout: change minor del SDK (ej. emi 0.2.x → 0.3.0) con nota en CHANGELOG.
Observabilidad por agente
Sección titulada «Observabilidad por agente»logger.ts emite JSON estructurado con campos:
| Campo | Ejemplo |
|---|---|
level | info / warn / error |
event | agent.run.start / agent.run.complete / tool.execute |
request_id | UUID por request |
app | emaclinic |
agent | support |
tenant_id | UUID |
latency_ms | ej. 1234 |
input_tokens | 1500 |
output_tokens | 380 |
cost_usd | 0.00345 |
Los mismos números viajan a emi_invocations para análisis histórico.