Conecta un agente, envía transcripciones y lee el informe A–F — vía SDK o REST.
Visión general
Axon es la capa de calidad para agentes de IA. Envías transcripciones de conversaciones; Axon evalúa cada una con un juez LLM contra una rúbrica configurable y devuelve un informe A–F por dimensión — con evidencia citada, causa raíz y corrección concreta.
El flujo: conecta un agente → ingiere transcripciones → el juez evalúa (de forma asíncrona, en una cola durable e idempotente) → lee el informe → corrige → fíjalo en una suite de regresión → monitorea y recibe alertas de degradación.
Inicio rápido
De cero al primer informe en tres pasos.
- Genera una API key en Configuración → Integración. Guárdala como AXON_API_KEY.
- Conecta la clave de tu proveedor de IA (BYOK) en Configuración → Integración → Proveedor de IA. Las evaluaciones corren en esa clave.
- Instala el SDK (pnpm add @gabrielonrails/axon-sdk) o usa cURL.
- Envía una transcripción y lee el boletín. El agente se crea en la primera ingesta.
$ pnpm add @gabrielonrails/axon-sdk
import { Axon } from "@gabrielonrails/axon-sdk";
const axon = new Axon({ apiKey: process.env.AXON_API_KEY! });
await axon.ingest("cobranca", [{
id: "conv-001",
channel: "voz",
turns: [
{ role: "client", text: "Quero um desconto." },
{ role: "agent", text: "Posso aplicar 20% agora." },
],
}]);
const report = await axon.getReport("cobranca");
console.log(report.overall, report.dimensions);
BYOK — tu clave de IA
La evaluación corre en la clave de proveedor de IA que conectas — Anthropic, OpenAI o cualquier endpoint compatible. Es obligatoria: sin ella el juez no corre y el boletín queda vacío.
Dónde conectar: en la app, Configuración → Integración → Proveedor de IA. Pega la clave, elige el proveedor y (opcional) el modelo. La clave se cifra en reposo (AES-256-GCM).
Autenticación
Toda petición se autentica con una API key (por org) en el header Authorization: Authorization: Bearer axon_sk_….
Las keys se generan y revocan en Configuración → Integración. Solo guardamos un hash SHA-256 — la key completa se muestra una vez. La revocación es inmediata.
Authorization: Bearer axon_sk_xxxxxxxxxxxxxxxxxxxxxxxx
SDK Node
El @gabrielonrails/axon-sdk oficial es tipado, sin dependencias (fetch nativo, Node 18+), idempotente y reintenta errores transitorios automáticamente.
Define id en cada transcripción: reenviar la misma id actualiza la conversación en vez de duplicar — seguro para reintentos y replays.
Opciones del constructor
new Axon({
apiKey: string, // axon_sk_... (obrigatório)
baseUrl?: string, // default: https://axon-dev.com
maxRetries?: number, // default: 3 (429/5xx/rede, backoff)
timeoutMs?: number, // default: 30000
fetch?: typeof fetch, // fetch custom (opcional)
})
baseUrl usa la URL actual de la app por defecto y es configurable; apúntala a tu propio dominio o a un deploy self-hosted.
Métodos
axon.ingest(agent, transcripts) // → AxonIngestResult
axon.getConversation(agent, externalId) // → AxonConversationStatus
axon.getReport(agent) // → AxonReport
axon.runRegression(agent, { version? }) // → AxonRegressionResult (gate de CI)
axon.waitForEvaluation(agent, externalId, { timeoutMs?, intervalMs? })
axon.agent(name) // → { ingest, getReport, getConversation, waitForEvaluation }
Tipos
interface AxonTranscript {
id?: string; // chave de idempotência (reenviar = atualiza, não duplica)
channel?: "voz" | "chat" | "whatsapp";
turns: {
role: "client" | "agent" | "tool";
text: string;
// tool calls deste turno → habilitam a avaliação de TRAJETÓRIA do agente
toolCalls?: { name: string; arguments?: unknown; result?: unknown }[];
}[];
// Trace de agente (opcional) — quanto mais rico, mais profunda a avaliação:
system?: string; // prompt de sistema do agente (aderência/trajetória)
context?: string[]; // contexto recuperado (RAG) → tríade faithfulness
metadata?: Record<string, unknown>; // metadados livres (persistidos)
// Metadados de filtro/agrupamento (não afetam a nota):
duration?: string; // duração da conversa, ex.: "4m12s"
version?: string; // rótulo da versão do agente (alimenta a comparação A/B)
result?: string; // desfecho, ex.: "resolvido" | "transferido" (outliers
// sempre avaliam, mesmo sob amostragem)
queue?: string; // fila/operação, ex.: "financeiro-cobranca"
}
interface AxonConversationStatus {
// "blocked" = sem assinatura/crédito (pague-antes); reason explica o porquê.
status: "pending" | "running" | "done" | "failed" | "blocked" | "unknown";
reason?: "no_entitlement" | "llm_not_configured" | "evaluation_failed" | null;
evaluation: { overall: Grade; confidencePct: number;
dimensions: { key; name; grade; score }[] } | null;
}
Monitoreo en tiempo real
Axon monitorea tus agentes en streaming — no exportas un lote al final del día. El patrón es un hook de fin de conversación: en cuanto una conversación termina (el cliente cuelga, la sesión de chat se cierra, el ticket se resuelve), envía la transcripción. La evaluación corre de forma asíncrona y el dashboard se actualiza solo (la pantalla muestra un indicador "En vivo" y recarga periódicamente).
Conecta el hook donde terminan las conversaciones: un webhook call.completed de tu telefonía, el fin de la sesión de chat/WhatsApp por inactividad, o tu propio agente de IA justo tras el último mensaje.
// Chame no momento em que a conversa encerra (fim de chamada,
// sessão de chat fechada, ticket resolvido). Não bloqueie o
// encerramento esperando a Axon — o SDK já faz retry com backoff.
async function onConversationEnded(conv) {
void axon.ingest(conv.agentName, [{
id: conv.id, // mesmo id em retries → não duplica
channel: conv.channel, // "voz" | "chat" | "whatsapp"
turns: conv.turns,
}]).catch((err) => console.error("[axon] ingest falhou:", err));
}
Como cada conversación se evalúa en el momento en que llega, Axon detecta degradación casi en tiempo real — dispara alertas (email/webhook) cuando una conversación recibe nota baja (D/F) o cuando el promedio reciente del agente cae respecto a la ventana anterior, sin esperar un informe semanal.
Sin el SDK
El hook es solo un POST HTTP — no necesitas SDK. Llama al endpoint de ingesta directo desde tu backend o incluso desde el webhook de tu telefonía/chat. El id mantiene los reintentos idempotentes.
# Dispare isto no fim da conversa, do seu backend ou direto do
# webhook da telefonia/chat. Sem SDK — só HTTP.
curl -X POST https://axon-dev.com/api/v1/agents/cobranca/transcripts \
-H "Authorization: Bearer $AXON_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "transcripts": [
{ "id": "conv-001", "channel": "voz",
"turns": [ { "role": "client", "text": "..." },
{ "role": "agent", "text": "..." } ] } ] }'
# → 202 { "accepted": 1, "status": "evaluating" }
# Reenviar o mesmo "id" é idempotente: atualiza, não duplica.
API REST
Tres endpoints, todos autenticados por API key. La ingesta devuelve 202 y evalúa de forma asíncrona; haz polling del estado o lee el informe.
URL base: https://axon-dev.com
POST /api/v1/agents/{agent}/transcripts
Authorization: Bearer axon_sk_...
Content-Type: application/json
{ "transcripts": [
{ "id": "conv-001", "channel": "voz",
"turns": [ { "role": "client", "text": "..." },
{ "role": "agent", "text": "..." } ] }
] }
→ 202 { "accepted": 1, "queued": 1, // queued < accepted sob amostragem
"agent": { "id", "name" },
"conversation_ids": ["..."], "status": "evaluating" }
GET /api/v1/agents/{agent}/transcripts/{externalId}
Authorization: Bearer axon_sk_...
→ 200 { "status": "done",
"evaluation": { "overall": "C+", "confidencePct": 92,
"dimensions": [ { "key", "name", "grade", "score" } ] } }
GET /api/v1/agents/{agent}/report
Authorization: Bearer axon_sk_...
→ 200 {
"agent": { "id", "name", "channel" },
"overall": "C+", "degrading": true, "sample": 2430,
"dimensions": [...],
"problems": [
{ "severity", "title", "dimension", "impact", "rootCause",
"evidence": { "turnIndex", "quote", "verified" } } // verified = citação conferida
],
"trajectory": { // quando há tool calls: qualidade do uso de ferramentas
"assessed": true, "score": 78, "summary": "...",
"findings": [ { "type": "tool-correctness", "severity", "detail" } ]
},
"rag": { // quando há contexto recuperado: tríade RAG
"assessed": true, "faithfulness": 64, "answerRelevance": 90,
"contextRelevance": 71, "summary": "...", "findings": [...]
},
"correction": { // a correção recomendada (o diferencial)
"tags": ["política de desconto", "concessão não autorizada"],
"impactFrom": "C+", "impactTo": "A-",
"fixes": [
{ "type": "PROMPT", "title": "...", "description": "...", "code": "..." },
{ "type": "GUARDRAIL", "title": "...", "description": "...", "code": "..." },
{ "type": "EVAL", "title": "...", "description": "...", "code": "..." }
]
} // null quando ainda não há correção
}
El boletín también devuelve `correction` — la corrección recomendada (causa raíz + parches concretos de PROMPT/GUARDRAIL/EVAL), o null cuando aún no hay una.
Regresión & golden sets
Fija la calidad: convierte una conversación evaluada en un golden case (el resultado esperado). La suite de regresión revisa esos casos en cada despliegue.
El ciclo: (1) marca un caso desde un boletín/corrección; (2) ejecuta la suite; (3) activa el gate de CI — un despliegue que regresiona un caso se bloquea, con aprobación de bypass auditada.
Hoy el ciclo de regresión se opera en la app (plan Team) y los casos se crean desde conversaciones marcadas. Un endpoint REST dedicado está en el roadmap.
Gate de CI (bloquea deploys malos)
Ejecuta tu suite de regresión desde CI y falla el build si el agente empeoró. El endpoint devuelve HTTP 200 si pasa y 422 si hubo regresión, así que curl --fail bloquea solo.
Ejemplo en GitHub Actions:
name: Axon quality gate
on: [pull_request]
jobs:
gate:
runs-on: ubuntu-latest
steps:
- run: |
curl --fail -sS -X POST \
-H "Authorization: Bearer ${{ secrets.AXON_API_KEY }}" \
-H "content-type: application/json" \
-d '{"version":"${{ github.sha }}"}' \
https://axon-dev.com/api/v1/agents/YOUR_AGENT/regression
O con el SDK:
const r = await axon.runRegression("your-agent", { version: sha });
if (!r.gate) process.exit(1); // bloqueia o deploy se regrediu
Requiere el plan Pro o superior. Cada caso se reevalúa con tu clave BYOK.
FinOps & costo
Cada evaluación registra los tokens reales consumidos en tu clave (BYOK). El panel FinOps muestra costo estimado y tokens por agente, modelo y día, con presupuesto mensual y alerta al superarlo.
La visibilidad de costo vive en la app, en /finops. Un endpoint REST para leer costo/tokens está en el roadmap.
Rúbrica y notas
Cada conversación recibe nota A–F general y por dimensión (score 0–100). A/B = saludable, C = atención, D/F = crítico. La rúbrica es configurable por agente; la predeterminada tiene seis dimensiones:
A/B saludable · C atención · D/F crítico
Alertas y webhooks
Axon calcula un baseline semanal por agente y dispara una alerta de degradación cuando la nota cae vs. la semana anterior.
Las alertas llegan en la app y a los canales configurados en Configuración → Integración: webhook (POST JSON) y Slack (incoming webhook).
POST (seu endpoint)
{ "source": "axon", "severity": "alto",
"title": "Queda de qualidade em Cobrança",
"body": "A nota geral caiu 9 pontos vs. a semana anterior." }
Límites & contrato
Lo que ingeniería pregunta en la primera call:
- El throughput de evaluación está limitado por org: 3 solicitudes/min al juez, ~8k tokens de entrada y ~2k de salida por minuto. El excedente va a una cola (FIFO). La ingesta responde 202 al instante; la evaluación corre asíncrona.
- Los errores transitorios (429/5xx/red) reintentan automáticamente en el SDK con backoff exponencial.
- Recomendado ≤ 50 conversaciones por solicitud y ≤ ~100 turnos por conversación.
- Un id por conversación hace el reenvío idempotente (actualiza, no duplica).
- El boletín devuelve los 3 problemas más relevantes por agente (sin paginación).
Errores
Los errores devuelven un cuerpo JSON { error, message } con el status HTTP apropiado.