Durante los últimos meses hemos convertido la palabra agente en una etiqueta demasiado cómoda.
Llamamos agente a un prompt. Llamamos agente a un modelo con dos funciones. Llamamos sistema multiagente a varios modelos enviándose texto sin estado, sin gobierno y sin una definición verificable de cuándo han terminado.
El problema no es únicamente terminológico.
Cuando confundimos el modelo con el sistema completo, terminamos construyendo soluciones que funcionan en una demo, pero que no pueden responder preguntas básicas de arquitectura:
- ¿Qué tarea está ejecutando?
- ¿Qué pasos ha completado?
- ¿Qué información ha conservado?
- ¿Qué herramientas puede utilizar?
- ¿Qué operación requiere aprobación?
- ¿Qué sucede cuando una herramienta falla?
- ¿Cuándo debe detenerse?
- ¿Cómo podemos reconstruir lo ocurrido?
Microsoft Agent Framework introduce dos conceptos que ayudan a separar correctamente estas responsabilidades:
- Agent Harness, como entorno operativo que gobierna al agente.
- CodeAct, como mecanismo para que el modelo exprese una parte del trabajo como código y la ejecute en una sandbox.
No son dos alternativas.
No debemos elegir entre Harness o CodeAct.
Agent Harness controla el trabajo. CodeAct ejecuta determinadas partes de ese trabajo de forma compacta.
No son dos capas paralelas ni dos formas alternativas de construir un agente. CodeAct se incorpora dentro del Harness como una capacidad especializada para ejecutar una parte concreta del trabajo.
El modelo no es el agente
Un modelo de lenguaje puede recibir una instrucción y producir una respuesta.
Eso no significa que pueda sostener por sí solo una tarea empresarial larga.
Supongamos que solicitamos:
Analiza ochenta aplicaciones, recupera sus incidentes, costes y dependencias, calcula un índice de riesgo, explica el ranking y crea una iniciativa para las tres primeras.
La respuesta no depende únicamente de la capacidad del modelo para razonar.
Necesitamos resolver:
- cómo descomponer el objetivo;
- cómo conservar el estado;
- cómo registrar lo completado;
- cómo administrar el contexto;
- cómo llamar a las herramientas;
- cómo solicitar aprobaciones;
- cómo recuperarse de errores;
- cómo decidir que el trabajo ha terminado.
Podemos expresar la diferencia así:
Modelo
= generación y razonamiento
Agente
= modelo
+ instrucciones
+ herramientas
+ estado
+ memoria
+ políticas
+ bucle de ejecución
+ observabilidad
+ criterio de finalización
El modelo aporta capacidad cognitiva. El Harness aporta capacidad operativa y CodeAct proporciona una forma compacta de ejecutar determinadas subtareas intensivas en herramientas.
Agent Harness: el plano de control
Microsoft define un agent harness como el andamiaje que convierte un modelo en un agente capaz de trabajar sobre tareas largas y de varios pasos.
En C#, el Harness envuelve un IChatClient mediante AsHarnessAgent(...).
Su responsabilidad no es calcular el scoring de nuestro portfolio. Su responsabilidad es controlar el proceso completo:
- planificación;
- modos de plan y ejecución;
- lista de tareas;
- sesión;
- historial;
- compactación de contexto;
- memoria;
- acceso a archivos;
- aprobaciones;
- llamadas a herramientas;
- evaluación del bucle;
- OpenTelemetry.
Ésta es la primera separación importante del artículo:
El Harness no es una herramienta que el agente llama. Es el entorno que decide cómo progresa el agente.
El flujo conceptual es:
Usuario
|
v
Harness
|
+-- interpreta la intención
+-- construye el plan
+-- crea los todos
+-- conserva el estado
+-- aplica políticas
+-- ejecuta herramientas
+-- comprueba el progreso
|
v
Resultado
Esta separación encaja con un principio que utilizo de forma recurrente en arquitectura empresarial de IA:
Elevate before Delegate.
Antes de delegar una ejecución autónoma, elevamos la intención:
- la hacemos explícita;
- identificamos restricciones;
- establecemos contratos;
- definimos evidencias;
- acordamos qué puede cambiarse.
El Harness proporciona el plano de control donde podemos implementar esa disciplina: intención explícita, planificación, seguimiento, políticas y aprobación.
Planificar no significa ejecutar
El Harness incorpora un patrón de modos que separa dos comportamientos.
Plan mode
El agente:
- comprende la solicitud;
- pregunta cuando falta una restricción imprescindible;
- propone una estrategia;
- crea una lista de tareas;
- expone qué acciones pretende ejecutar.
Execute mode
El agente:
- trabaja sobre las tareas;
- utiliza herramientas;
- actualiza el progreso;
- produce artefactos;
- continúa hasta alcanzar la condición de terminación.
Esta separación es mucho más que una mejora de experiencia de usuario.
Es una frontera de gobierno.
Cuando el usuario dice:
Ayúdame a modernizar Payments Legacy.
no debemos traducir esa frase directamente a:
crear épica
modificar repositorio
desplegar infraestructura
notificar al equipo
Primero debemos determinar qué significa modernizar:
- rehost;
- replatform;
- refactor;
- replace;
- retire;
- encapsular;
- estrangular progresivamente;
- conservar temporalmente.
El Harness controla ese proceso.
CodeAct todavía no ha aparecido, y ése es precisamente el punto.
CodeAct no resuelve intención, planificación ni gobierno. Solo debe entrar cuando el Harness ya ha determinado qué trabajo hay que ejecutar, con qué herramientas y bajo qué restricciones.
El problema de la orquestación herramienta a herramienta
Una vez aprobado el análisis, necesitamos procesar el portfolio.
Para cada aplicación debemos:
- recuperar sus datos;
- consultar incidentes;
- consultar costes;
- normalizar métricas;
- calcular una puntuación;
- agregar resultados;
- ordenar el ranking.
Con function calling tradicional, el flujo puede convertirse en:
Modelo -> get_applications
Modelo -> get_incidents(APP-001)
Modelo -> get_costs(APP-001)
Modelo -> get_incidents(APP-002)
Modelo -> get_costs(APP-002)
...
Cada llamada vuelve al modelo.
El modelo decide la siguiente herramienta, recibe el resultado, vuelve a inferir y repite.
Esto introduce:
- más turnos;
- más tokens;
- más latencia;
- más estado conversacional;
- más posibilidades de desviación;
- más dificultad para revisar el workflow como una unidad.
El cuello de botella no siempre es la inteligencia del modelo.
En muchos casos es la sobrecarga de orquestación.
CodeAct: expresar el workflow como código
CodeAct introduce una herramienta llamada execute_code.
En lugar de pedir al modelo que emita una llamada de herramienta cada vez, le permitimos escribir un programa corto que:
- utiliza bucles;
- aplica condiciones;
- transforma datos;
- agrega resultados;
- llama a herramientas del host;
- imprime un resultado estructurado.
El flujo pasa a ser:
Modelo
|
v
execute_code(programa)
|
v
Sandbox
|
+-- call_tool("get_applications")
+-- for application in applications
+-- call_tool("get_incidents", ...)
+-- call_tool("get_costs", ...)
+-- normalizar
+-- scoring
+-- ordenar
|
v
Resultado
La diferencia fundamental no es Python frente a C#.
La aplicación, las herramientas, las credenciales, los contratos y las integraciones empresariales siguen estando en C#.
Python es el lenguaje invitado que el modelo utiliza dentro de la sandbox para expresar una composición dinámica.
C# conserva el control de las capacidades. El código invitado controla el flujo dentro de esas capacidades.
Cómo encajan Harness y CodeAct
Ahora podemos conectar ambos conceptos sin mezclarlos.
Harness responde a estas preguntas:
- ¿Cuál es el objetivo?
- ¿Qué falta por hacer?
- ¿En qué modo estamos?
- ¿Qué información debe conservarse?
- ¿Qué operación requiere aprobación?
- ¿Cuándo finaliza la tarea?
- ¿Cómo observamos la ejecución?
CodeAct responde a éstas:
- ¿Cómo itero sobre cincuenta elementos?
- ¿Cómo combino tres herramientas?
- ¿Cómo filtro y agrego?
- ¿Cómo normalizo valores?
- ¿Cómo genero un resultado estructurado sin volver al modelo en cada paso?
La arquitectura completa es:
┌────────────────────────────────────────────┐
│ Usuario │
└───────────────────┬────────────────────────┘
│
v
┌────────────────────────────────────────────┐
│ Agent Harness │
│ │
│ intención · plan · todos · sesión │
│ contexto · memoria · aprobación · tracing │
└───────────────────┬────────────────────────┘
│
v
┌────────────────────────────────────────────┐
│ Modelo │
└───────────────┬─────────────────┬──────────┘
│ │
v v
execute_code herramienta directa
│ │
v v
┌──────────────────────┐ ┌───────────────────┐
│ Hyperlight sandbox │ │ operación sensible│
│ │ │ │
│ bucles │ │ crear work item │
│ cálculos │ │ enviar correo │
│ call_tool(...) │ │ modificar recurso │
└──────────┬───────────┘ └─────────┬─────────┘
│ │
v v
┌────────────────────────────────────────────┐
│ Herramientas C# acotadas │
│ CMDB · observabilidad · FinOps · DevOps │
└────────────────────────────────────────────┘
Ésta es la tesis del artículo:
Harness gobierna la autonomía. CodeAct comprime la ejecución.
En términos de implementación, CodeAct no se configura como un agente independiente…
Caso de uso: priorizar la modernización legacy
La demo trabaja con cuatro aplicaciones:
| Aplicación | Tecnología | Antigüedad (años) | Criticidad |
|---|---|---|---|
| Payments Legacy | COBOL / Mainframe | 28 | 100 |
| Customer Operations | VB6 / COM+ | 22 | 85 |
| Portfolio Reporting | .NET Framework 4.6 | 11 | 65 |
| Notification Service | .NET 8 | 2 | 45 |
Para cada aplicación disponemos además de:
- incidentes mensuales;
- incidentes de severidad 1 y 2;
- coste operativo anual;
- lead time medio de cambio.
La fórmula de scoring:
- 30% criticidad de negocio
- 25% presión de incidentes
- 20% coste operativo
- 15% lead time de cambio
- 10% antigüedad
La intención del usuario es decidir qué aplicación estudiar primero.
El análisis no debe crear automáticamente ningún elemento de trabajo. Esa operación será un paso posterior.
Primero validamos el dominio sin IA
Antes de introducir un modelo, debemos demostrar que el dominio es correcto.
La solución incluye:
src/
ModernizationAgent.Core/
ModernizationAgent.LocalDemo/
Los proyectos utilizan:
<TargetFramework>net10.0</TargetFramework>
La interfaz de lectura es deliberadamente pequeña:
public interface IPortfolioReader
{
IReadOnlyList<ApplicationInfo> GetApplications();
IncidentSummary GetIncidents(string applicationId);
CostSummary GetCosts(string applicationId);
}
No exponemos:
ExecuteSql(string sql)
CallApi(string url, string body)
RunCommand(string command)
Esas funciones no son herramientas empresariales.
Son puertas traseras semánticas.
Una herramienta de agente debe representar una capacidad concreta y revisable.
El algoritmo de scoring se ejecuta localmente y valida el ranking:
1. Payments Legacy 100.00
2. Customer Operations 68.78
3. Portfolio Reporting 37.83
4. Notification Service 18.32
Este paso importa porque evita atribuir al modelo una lógica que debemos controlar nosotros.
Este paso importa porque evita atribuir al modelo una lógica que debemos controlar nosotros.
En la demo permitiremos que el código generado reproduzca esa fórmula para mostrar el funcionamiento de CodeAct. Sin embargo, en producción los pesos y las reglas deberían estar encapsulados en una función C#, una política versionada o un servicio de dominio.
El modelo puede decidir qué datos recuperar y cómo componer el análisis. No debería tener autoridad para redefinir silenciosamente cómo la organización calcula el riesgo.
Herramientas C# para CodeAct
En la integración real registramos tres herramientas de lectura:
AIFunction getApplications = AIFunctionFactory.Create(
() => applications,
name: "get_applications",
description:
"Returns the application portfolio with ID, name, technology, " +
"age in years, and business criticality (0-100). Read-only.");
AIFunction getIncidents = AIFunctionFactory.Create(
(string applicationId) => GetIncidents(applicationId),
name: "get_incidents",
description:
"Returns incident data for an application. " +
"Parameter name: applicationId. Read-only.");
AIFunction getCosts = AIFunctionFactory.Create(
(string applicationId) => GetCosts(applicationId),
name: "get_costs",
description:
"Returns annual operating cost and change lead time. " +
"Parameter name: applicationId. Read-only.");
Los nombres de parámetros y las formas de retorno son importantes.
En function calling tradicional el modelo selecciona una herramienta.
En CodeAct el modelo escribe código contra el contrato.
Una descripción ambigua no genera únicamente una mala llamada.
Puede generar un programa incorrecto.
Registrar las herramientas dentro de CodeAct
Creamos el proveedor Hyperlight:
var codeActOptions =
HyperlightCodeActProviderOptions.CreateForWasm(
PythonGuestModule.GetModulePath());
codeActOptions.Tools =
[
getApplications,
getIncidents,
getCosts
];
using var codeAct =
new HyperlightCodeActProvider(codeActOptions);
Estas herramientas quedan disponibles dentro de la sandbox mediante:
call_tool("get_applications")
call_tool("get_incidents", applicationId="APP-001")
call_tool("get_costs", applicationId="APP-001")
No necesitamos exponerlas también como herramientas directas al modelo.
Queremos que el agente utilice una composición coherente, no que vuelva al patrón de llamadas fragmentadas.
El programa que puede generar el modelo
CodeAct podría producir un programa equivalente a:
applications = call_tool("get_applications")
rows = []
for application in applications:
application_id = application["id"]
incidents = call_tool(
"get_incidents",
applicationId=application_id
)
costs = call_tool(
"get_costs",
applicationId=application_id
)
rows.append({
"application": application,
"incidents": incidents,
"costs": costs
})
max_incidents = max(row["incidents"]["monthlyIncidents"] for row in rows)
max_cost = max(row["costs"]["annualRunCost"] for row in rows)
max_lead_time = max(row["costs"]["averageChangeLeadTimeDays"] for row in rows)
max_age = max(row["application"]["ageYears"] for row in rows)
ranking = []
for row in rows:
app = row["application"]
incidents = row["incidents"]
costs = row["costs"]
incident_score = incidents["monthlyIncidents"] / max_incidents * 100
cost_score = costs["annualRunCost"] / max_cost * 100
lead_time_score = costs["averageChangeLeadTimeDays"] / max_lead_time * 100
age_score = app["ageYears"] / max_age * 100
final_score = (
app["criticality"] * 0.30
+ incident_score * 0.25
+ cost_score * 0.20
+ lead_time_score * 0.15
+ age_score * 0.10
)
ranking.append({
"applicationId": app["id"],
"name": app["name"],
"technology": app["technology"],
"score": round(final_score, 2)
})
ranking.sort(key=lambda item: item["score"], reverse=True)
print(ranking)
El valor no está en que Python pueda dividir números.
El valor está en concentrar recuperación, iteración, transformación, normalización, scoring y ordenación en una única unidad ejecutable y revisable.
En esta demo, el programa generado contiene también la fórmula para que el flujo pueda entenderse de extremo a extremo. En producción, lo recomendable sería sustituir ese cálculo por una herramienta específica y versionada, por ejemplo `calculate_modernization_score`, manteniendo en CodeAct únicamente la composición dinámica.
Cuando entres en GitHub podrás localizar en Program.cs (\preview\HarnessCodeAct\) exactamente donde tiene lugar esto:
| Línea | Comentario |
|---|---|
| 158 | // Python generation happens here: PythonGuestModule supplies a WASM-compiled Python interpreter... |
| 174 | // The ## CodeAct section below is what causes the model to emit Python... |
El primero explica el mecanismo de ejecución (el intérprete WASM). El segundo explica la causa del comportamiento (la instrucción en el system prompt). Son los dos momentos del flujo que puedes referenciar en el artículo.
La operación de escritura debe quedar fuera
Después del análisis, el usuario puede solicitar:
Crea un work item para Payments Legacy.
La herramienta C# es:
AIFunction createModernizationWorkItem =
new ApprovalRequiredAIFunction(
AIFunctionFactory.Create(
(
string applicationId,
string title,
string rationale,
decimal priorityScore
) => CreateWorkItem(...),
name: "create_modernization_work_item",
description:
"Creates a work item in an external system. " +
"This is a side-effecting operation that requires explicit approval."));
Esta herramienta no se registra en codeActOptions.Tools.
Se añade directamente al agente:
ChatOptions = new ChatOptions
{
Instructions = instructions,
Tools = [createModernizationWorkItem]
}
¿Por qué?
Porque la aprobación de CodeAct se aplica actualmente a la llamada completa de execute_code.
Si una operación sensible queda escondida dentro de diez call_tool(...), perdemos la aprobación individual.
No todo lo que puede componerse debe componerse.
La escritura necesita una frontera distinta de la lectura: herramienta directa, identidad controlada, aprobación individual, idempotencia y trazabilidad.
Construir el HarnessAgent
La integración utiliza Microsoft Foundry:
AIAgent agent =
new AIProjectClient(
new Uri(endpoint),
new DefaultAzureCredential(),
new AIProjectClientOptions
{
RetryPolicy = new ClientRetryPolicy(3)
})
.GetProjectOpenAIClient()
.GetResponsesClient()
.AsIChatClient(deploymentName)
.AsHarnessAgent(
new HarnessAgentOptions
{
MaxContextWindowTokens = MaxContextWindowTokens,
MaxOutputTokens = MaxOutputTokens,
Name = "LegacyModernizationAgent",
OpenTelemetrySourceName = TracingSourceName,
FileMemoryStore =
new FileSystemAgentFileStore("agent-files"),
AIContextProviders = [codeAct],
ChatOptions = new ChatOptions
{
Instructions = instructions,
Tools = [createModernizationWorkItem]
}
});
En este bloque se ve la conexión completa:
- Foundry proporciona el modelo;
AsIChatClientlo adapta;AsHarnessAgentañade el plano de control;AIContextProvidersañade CodeAct;ChatOptions.Toolsconserva la herramienta sensible como llamada directa.
CodeAct no se ejecuta al lado del Harness como un agente independiente. Se incorpora dentro del Harness como un proveedor de contexto y ejecución especializado.
Ésta es la conexión técnica entre ambos conceptos y la razón por la que no compiten.
Sesión, modos y tareas
El ejemplo oficial utiliza una consola interactiva.
Esto es importante porque un Harness no está pensado únicamente para una llamada stateless.
Necesita una sesión donde conservar:
- el plan;
- los todos;
- el historial;
- las decisiones;
- las aprobaciones;
- el progreso.
La consola permite utilizar:
/mode
/todos
Un flujo de prueba razonable es:
Analiza el portfolio completo. Calcula el índice de prioridad de
modernización, ordena los resultados y explica la primera posición.
No crees ningún work item.
Después
/todos
Y finalmente:
Crea el work item para la primera aplicación.
El análisis debe ejecutarse mediante CodeAct.
La escritura debe detenerse para solicitar aprobación.
Ésa es la demo arquitectónica: comprobar que el Harness conserva el control del proceso, CodeAct ejecuta el análisis y la operación de escritura se detiene para solicitar aprobación. El objetivo no es únicamente obtener el número 100.
La sandbox no hace segura una herramienta insegura
Hyperlight ejecuta el código invitado en un entorno aislado.
Sin embargo, call_tool(...) vuelve al proceso host.
La herramienta C# puede tener:
- credenciales;
- acceso a red;
- acceso a Azure;
- clientes de bases de datos;
- acceso a sistemas corporativos.
Por tanto, la sandbox protege al host del código invitado, pero no protege nuestros sistemas de una herramienta host mal diseñada.
Una herramienta como:
RunSql(string sql)
sigue siendo peligrosa aunque sea llamada desde una micro-VM.
La seguridad real necesita:
- contratos estrechos;
- validación;
- autorización;
- mínimo privilegio;
- límites de tasa;
- timeouts;
- auditoría;
- idempotencia;
- protección frente a prompt injection indirecta.
La sandbox es una capa de aislamiento.
No es un modelo completo de gobierno.
La regla práctica es sencilla: no concedas a una herramienta más capacidad de la que estarías dispuesto a conceder a cualquier otro componente no confiable de la aplicación.
Infraestructura Azure con Bicep
La demo incluye dos plantillas.
main.bicep
Despliega:
- recurso
Microsoft.CognitiveServices/accountsconkind: AIServices; - proyecto Foundry;
- identidad administrada;
- autenticación local deshabilitada;
- asignación opcional del rol Foundry User.
La salida principal es foundryProjectEndpoint con la forma:
https://<resource>.services.ai.azure.com/api/projects/<project>
model.bicep
Despliega un modelo sobre el recurso existente.
La plantilla no codifica rígidamente una combinación de modelo, versión, formato y SKU.
La disponibilidad depende de la región, suscripción, cuota y catálogo. Primero debemos consultar:
az cognitiveservices account list-models \
--name <foundry-name> \
--resource-group <resource-group>
Después pasamos a Bicep: modelName, modelVersion, modelFormat, skuName, capacity.
Esto evita otra forma habitual de falsa reproducibilidad: publicar una plantilla que compila, pero que solo funciona en la suscripción de quien escribió el artículo.
El Bicep de la demo despliega Foundry, pero no el host de Hyperlight. Son dos planos de infraestructura distintos: Foundry proporciona el modelo y el proyecto; el backend .NET de Hyperlight en preview requiere hoy un host Linux con KVM.
¿Dónde ejecutar Hyperlight?
La infraestructura Bicep despliega Foundry.
No despliega de forma automática el host de CodeAct.
El backend .NET de Hyperlight en preview solo está disponible hoy para Linux con KVM. Hyperlight como runtime también soporta MSHV y Windows Hypervisor Platform (WHP), pero el conector de CodeAct para .NET aún no publica esas variantes.
Por tanto, podemos ejecutar la demo en:
- estación Linux compatible;
- VM Linux con virtualización adecuada;
- entorno de desarrollo que exponga KVM;
- host corporativo preparado para micro-VMs.
No debemos desplegarla de forma arbitraria en cualquier PaaS y asumir que KVM estará disponible.
En producción, la selección del host forma parte de la arquitectura:
- compatibilidad de virtualización;
- identidad administrada;
- conectividad;
- observabilidad;
- hardening;
- parcheado;
- aislamiento;
- coste.
Por tanto, no debemos afirmar que la solución completa es serverless ni que puede trasladarse sin cambios a cualquier servicio administrado de Azure. La compatibilidad de virtualización (KVM en el backend .NET actual) es un requisito de arquitectura, no un detalle de despliegue, que mantiene tu argumento sin cerrar la puerta a WHP.
Observabilidad
Un resultado correcto no demuestra que el proceso haya sido correcto.
Necesitamos conocer:
- qué plan generó el agente;
- qué herramientas utilizó;
- qué código ejecutó;
- qué argumentos proporcionó;
- qué errores encontró;
- qué aprobaciones recibió;
- cuántos tokens consumió;
- cuánto tardó;
- qué resultado devolvió.
La demo configura:
OpenTelemetrySourceName = TracingSourceName
y el ejemplo oficial escribe trazas mediante OpenTelemetry.
En una arquitectura corporativa, esas trazas deberían correlacionarse con:
- peticiones de aplicación;
- llamadas a APIs;
- operaciones de herramientas;
- cambios en sistemas externos;
- identidad ejecutora;
- aprobador;
- artefactos generados.
Un agente no debe ser una caja negra con un texto bonito al final.
Cuándo utilizar CodeAct
CodeAct encaja cuando la tarea necesita:
- muchas herramientas de lectura;
- bucles;
- filtrado;
- ramificaciones;
- agregaciones;
- cálculos;
- transformaciones;
- artefactos estructurados.
No encaja necesariamente cuando:
- solo existe una llamada;
- la operación es trivial;
- cada acción requiere aprobación;
- el flujo debe ser completamente determinista;
- una función C# normal resuelve mejor el problema.
La decisión puede resumirse en la siguiente tabla:
| Escenario | Mecanismo |
|---|---|
| Consultar una aplicación | Tool calling directo |
| Crear un ticket | Tool directo con aprobación |
| Analizar cien aplicaciones | CodeAct |
| Mantener el plan | Harness |
| Conservar sesión y contexto | Harness |
| Calcular ranking con varias fuentes | Harness + CodeAct |
| Ejecutar lógica fija de negocio | C# |
| Orquestación dinámica y acotada | CodeAct |
No debemos utilizar CodeAct porque sea nuevo.
Debemos utilizarlo cuando reduzca una sobrecarga real sin empeorar el gobierno.
De la demo a una solución corporativa
Las funciones en memoria pueden sustituirse por adaptadores:
get_applications
-> CMDB / ServiceNow / catálogo corporativo
get_incidents
-> Azure Monitor / App Insights / Splunk / Dynatrace
get_costs
-> Azure Cost Management / repositorio FinOps
get_dependencies
-> telemetría distribuida / repositorios / catálogo
create_modernization_work_item
-> Azure DevOps / GitHub / Jira
Pero la frontera debe conservarse:
Lectura y agregación
-> CodeAct
Cambio de estado
-> herramienta directa aprobable
La transición desde la demo a producción no consiste en cambiar los datos en memoria por APIs reales. Consiste en conservar las mismas fronteras cuando aparecen identidades, permisos, redes, errores, concurrencia y efectos secundarios.
Limitaciones actuales
A fecha de 27 de julio de 2026:
- Hyperlight CodeAct para .NET continúa en preview.
- El backend requiere un host compatible con KVM. Hyperlight en sí soporta también Windows (WHP) y WSL2; la restricción a Linux con KVM es del conector .NET en preview, no del runtime.
- La aprobación se aplica al bloque
execute_codecompleto. - Las herramientas llamadas mediante
call_tool(...)se ejecutan en el host. - Los contratos de herramientas deben ser muy precisos.
- La disponibilidad de modelos y SKU cambia por región y suscripción.
- La demo utiliza acceso público para simplificar la reproducción. Un entorno empresarial deberá evaluar Private Link, DNS privado, restricciones de salida y controles de red adicionales.
- La demo real se aplica sobre el repositorio oficial mientras la cadena de paquetes Hyperlight no sea completamente autónoma desde NuGet.
Estas limitaciones no invalidan el patrón.
Definen dónde debemos poner las pruebas y las fronteras.
Conclusión
Agent Harness y CodeAct resuelven problemas distintos.
Agent Harness responde a cómo debe comportarse un agente durante una tarea:
- planifica;
- conserva estado;
- administra contexto;
- aplica políticas;
- solicita aprobaciones;
- observa;
- continúa hasta terminar.
CodeAct responde a cómo ejecutar eficientemente una parte intensiva en herramientas:
- itera;
- filtra;
- transforma;
- calcula;
- agrega;
- produce resultados.
La arquitectura correcta no es:
Modelo con acceso a todo
La arquitectura correcta no es:
Harness que gobierna
+
CodeAct que ejecuta
+
herramientas C# acotadas
+
aprobaciones visibles
+
infraestructura declarativa
+
trazabilidad
No se trata de conceder más autonomía. Se trata de hacer que la autonomía tenga límites, contratos y evidencias.
Ésa es la diferencia entre una demo de agente y una arquitectura agentic.





