Las preguntas después de la demo
Construís un agente. En la demo anda perfecto: razona, llama herramientas, entrega un resultado prolijo. Después intentás ponerlo delante de un cliente regulado y empiezan las preguntas. ¿Podés demostrar que solo va a ejecutar las acciones que se aprobaron? Cuando hace algo mal, ¿podés reconstruir exactamente por qué? ¿Quién, del lado de compliance, puede leer qué tiene permitido hacer sin leer tu código?
El reflejo es ir a buscar un framework mejor (LangGraph, CrewAI, Microsoft Agent Framework) o un modelo mejor. Ninguno de los dos cierra la brecha, porque la brecha no está en la composición ni en la calidad del razonamiento. Hay tres cosas que frenan la puesta en producción, y las tres son estructurales:
- Lo que el agente puede hacer lo limita solamente su propio código. Un agente impecable en la demo igual puede proponer una acción que nadie aprobó, ante un prompt que no anticipaste.
- La gobernanza se agrega de afuera. Los registros de auditoría se reconstruyen después de un incidente. La aprobación humana la cablea en el agente quien lo programa, así que lo que el agente tiene permitido solo lo pueden leer los ingenieros; compliance no.
- Construir en casa la infraestructura que falta es un proyecto en sí mismo: multi-tenancy, un log de eventos, ejecución determinística, máquinas de estados para la intervención humana.
Las tres están en la infraestructura, por debajo de la aplicación.
Los frameworks no son el runtime
Los frameworks de agentes viven en la capa de aplicación. Te ayudan a componer un agente en el que después confiás para decidir y actuar. Es una postura agent-first: confiar en el agente y controlarlo mejor. Los frameworks traen primitivas de control, y los tres las ponen en el código del propio agente: una llamada a interrupt() en un nodo de LangGraph, human_input en una tarea de CrewAI, approval_mode en una herramienta de Microsoft Agent Framework.
Un runtime parte de la postura opuesta, system-first. El agente es probabilístico, así que por diseño no tiene autoridad de ejecución. El trabajo del modelo es traducir lo que dice el usuario a un intent estructurado, y el runtime decide si ese intent llega a ser una acción.
El stack tiene cuatro capas, y el runtime es la tercera:
Interacción → chat, voz, UI
Razonamiento → el LLM
Control → intents, gobernanza, máquinas de estados, auditoría ← el runtime
Ejecución → bases de datos, APIs externas
El runtime es la capa de control en sí: corre los agentes, los gobierna y guarda el registro de lo que hicieron.
El contrato
El runtime se configura con un único artefacto declarativo: el contrato, escrito en YAML. Un contrato declara el modelo de datos, el control de acceso hasta el nivel de campo, los workflows determinísticos, las reglas de gobernanza (las precondiciones y con cuánta rigidez obligan las de cada acción, qué pasos necesitan una persona), el proceso de negocio y las integraciones externas. El runtime lee el contrato y se configura solo. No hay framework que envolver ni boilerplate que escribir: el contrato es el programa y el runtime es el intérprete.
Ingeniería, producto y compliance pueden leer el contrato, y es el contrato lo que firma compliance.
Y el runtime lo aplica con rigor: sin contrato, no hay acción. Una acción fuera de la superficie declarada no tiene ninguna herramienta que el modelo pueda llamar. Si el modelo la nombra igual, falla como acción desconocida antes de cualquier otro chequeo, y la ruta REST de acciones responde unknown_action.
Estas son, tal cual, tres de las acciones del contrato de referencia de triage de soporte, y cada una declara el estado que requiere, lo que escribe y la fase del proceso a la que pertenece.
actions:
- name: create_ticket
entity: tickets
type: create
preconditions:
- op: entity_exists
entity: users
scope: owner
effects:
writes:
- entity: tickets
field: status
phases:
- intake
- name: classify_ticket
entity: tickets
type: update
preconditions:
- op: entity_state
entity: tickets
field: status
values:
- open
effects:
writes:
- entity: tickets
field: status
phases:
- triage
- name: escalate_ticket
entity: tickets
type: update
preconditions:
- op: entity_state
entity: tickets
field: status
values:
- triaged
effects:
writes:
- entity: tickets
field: status
phases:
- resolution
Las precondiciones son aserciones sobre el estado que chequea una máquina; al LLM nunca se le pide que las respete. Donde tiene que dar el visto bueno una persona, el contrato lo dice en la transición. Dos de las transiciones del contrato de crédito fintech:
- from: policy_validated
to: hitl_required
allowed_roles:
- system
rules:
- condition: requested_amount > credit_accounts.current_limit * 1.25
message: high_value_requires_review
- from: hitl_required
to: approved
allowed_roles:
- risk_officer
effect: confirm
Lo que manda un pedido a revisión es una condición sobre los datos. Para aprobarlo hace falta el rol risk_officer, y effect: confirm, que escribió en la transición quien redactó el contrato, hace que el runtime no la ejecute hasta que quien aprueba la confirme. En ninguna de las dos decisiones entra un score del modelo.
Lo que el runtime hace cumplir
Son propiedades del runtime, que es el único lugar donde se pueden hacer cumplir.
- Barrera de tema. Un límite regulado que declara el contrato se rechaza antes de que corra el modelo que responde: un clasificador etiqueta el mensaje, y el rechazo sale con palabras fijas y falla cerrado (ver El rechazo es una salida de control). Lo demás que queda fuera de tema se deja pasar a propósito: un pedido poco claro sigue, antes que arriesgarse a bloquear uno legítimo.
- Pipeline de gobernanza. Toda escritura sobre un registro pasa por los mismos chequeos en el mismo orden (permiso, fase, precondiciones, binding de valores), venga del agente o de la API REST. Las propuestas del agente pasan antes por la barrera de tema, y una escritura que el contrato marca para confirmación espera a una persona.
- La intervención humana como estado persistido de primera clase. Un paso de flow que necesita a una persona devuelve
suspended: true; el flow se persiste y se retoma cuando esa persona confirma o decide, con el intent original intacto. La confirmación queda atada a la escritura exacta que aprueba, y el contrato declara dónde hace falta una (persistir la pausa es la mitad fácil). - Decisiones registradas. Cada veredicto sobre una escritura propuesta, rechazos incluidos, se encadena por hash antes de que la escritura corra, con la versión del contrato que lo decidió; cada transición de estado y cada paso de flow también es un evento encadenado por hash. Un trace id los une: los veredictos, las precondiciones que fallaron y, en una transición de estado, el rol que tenía el actor.
- Multi-tenancy nativa. Un solo deployment atiende a muchas unidades de negocio o tenants de clientes, aislados con row-level security en PostgreSQL, de modo que el aislamiento lo aplica la base de datos en cada consulta.
La versión honesta de "determinístico"
"Determinístico" es hoy la palabra más gastada de esta categoría, y por eso importa decirlo con precisión: un arquitecto detecta la exageración enseguida.
En un flow que declara el contrato, el grafo de ejecución es determinístico; el intent, la respuesta y cualquier paso que el contrato le deja a un modelo no lo son.
El LLM queda confinado a los lugares que nombra el contrato. Al empezar un turno convierte lo que dijo el usuario en un intent estructurado, y eso incluye elegir el flow y completar sus inputs. Al final redacta la respuesta. Un flow también puede declarar un paso de modelo, como hace el triage de soporte para clasificar el mensaje, y cuando ese paso declara un schema de salida, lo que devuelve tiene que cumplirlo antes de que algo lo lea. Todo lo del medio (qué acción se arma, si está permitida, qué efectos corren, qué queda registrado) lo conduce el contrato: con el mismo contrato, el mismo intent y las mismas salidas de sus pasos de modelo, el flow recorre el mismo camino. Fuera de un flow declarado, cuando el modelo planifica varios pasos por su cuenta, la secuencia es adaptativa: cada paso pasa por los controles, y el orden lo pone el modelo.
Si el modelo tuviera autoridad operativa sobre la ejecución, ninguna de esas garantías sobreviviría. La gobernanza, la multi-tenancy, un log de eventos y las máquinas de estados para la intervención humana solo se pueden hacer cumplir como propiedades del runtime; montadas encima de un agente probabilístico, quedan en recomendaciones. La contraoferta mejor construida promete lo contrario: el Agent Governance Toolkit de Microsoft, del que Venkat Peri, que trabaja en infraestructura de IA agéntica para gestión patrimonial en Advisor360°, dice en su reseña: "No reescribís el código de tu agente" [1]. El agente propone trata sobre dónde termina esa promesa: según el README del propio toolkit, el motor de políticas y los agentes que gobierna corren en el mismo proceso.
Para quién es esto
Hay dos tipos de equipo que se chocan con esta pared.
El primero despliega agentes internamente en operaciones reguladas o de alto riesgo (servicios financieros, seguros, legal), donde el costo de que un agente haga algo indebido se mide en plata o en exposición regulatoria.
El segundo es donde más pesa el modelo de runtime: equipos de SaaS B2B que les entregan agentes a sus propios clientes regulados. Si le vendés software a bancos y aseguradoras, la gobernanza no puede ser una dependencia que le alquilás al gateway de una nube. Tus clientes están repartidos en entornos distintos, así que los controles tienen que ser infraestructura que viaje con tu producto y no un lock-in que compartís con ellos.
Si tu equipo está llevando agentes a operaciones reguladas y está evaluando gobernanza, huecos de auditoría o si construir o comprar, hablemos.
Las citas están traducidas por el autor. Los originales, en inglés:
- Peri, reseña del toolkit: "You do not rewrite your agent code."
Nicolás Moreno construye Zarel: operaciones de IA gobernadas, donde la IA propone y el contrato dispone.