Idea en 30 segundos
Los unit tests para agentes de IA validan la lógica local: selección de herramienta, procesamiento de respuesta, stop reason y formato de salida.
Su valor principal es que son rápidos, deterministas y aislados, por eso ayudan a detectar de inmediato qué parte concreta del sistema se rompió.
Problema
Sin unit tests, los equipos suelen validar agentes solo con runs manuales o con pruebas end-to-end pesadas.
Esto crea problemas típicos:
- los errores en lógica local se detectan demasiado tarde;
- cuesta saber si se rompió el código o una dependencia externa;
- pequeñas regresiones se acumulan y llegan a producción.
Al final, incluso un cambio simple puede provocar una cadena de fallos opacos en producción.
Cuándo usarlo
Conviene escribir unit tests siempre que exista lógica local y verificable:
- selección de herramienta según tipo de solicitud;
- validación del esquema de salida;
- manejo de errores de herramientas;
- condiciones de finalización del run (
stop_reason); - reglas de seguridad a nivel de paso o función.
Si el comportamiento puede validarse sin red y sin entorno completo del agente, es un buen candidato para unit test.
Implementación
En la práctica, el unit testing de agentes sigue una regla simple: un comportamiento, una prueba, condiciones controladas. Los ejemplos de abajo son esquemáticos y no dependen de un framework concreto.
El nivel unit no sirve para evaluar calidad general de respuesta, utilidad del resultado final ni la "inteligencia" global del agente. Para eso, usa eval harness y golden datasets.
Cómo funciona en una prueba
Ciclo corto de unit test
- Test case - un comportamiento por validar.
- Setup - fakes, mocks y condiciones fijas.
- Run - ejecutar una función o paso concreto.
- Assertions - validar
tool choice,schema,stop reason.
1. Aislar la lógica de decisión del agente
def choose_tool(intent: str, tools_allowed: list[str]) -> str:
if intent == "price_lookup" and "crypto_price_api" in tools_allowed:
return "crypto_price_api"
return "web_search"
Cuantas menos dependencias laterales tenga la función, más estable será la prueba.
2. Reemplazar herramientas externas
class FakeTools:
def crypto_price_api(self, symbol: str):
return {"symbol": symbol, "price": 65000}
Un unit test debe validar lógica del agente, no disponibilidad de APIs externas.
3. Verificar más que el texto final
def test_tool_selection_and_schema():
tools = FakeTools()
agent = Agent(tools=tools)
result = agent.run("What is the price of BTC?")
assert result.selected_tool == "crypto_price_api"
assert isinstance(result.output, dict)
assert result.output["symbol"] == "BTC"
Es mejor fijar invariantes estructurales (selected_tool, schema, stop reason), no solo el texto final.
4. Probar escenarios negativos
def test_tool_error_is_handled():
tools = FailingTools()
agent = Agent(tools=tools)
result = agent.run("Find BTC price")
assert result.stop_reason == "tool_error_handled"
assert result.error is not None
Los errores de herramientas deben tener un comportamiento predecible y verificable.
5. Integrar unit tests en CI
name: unit-tests
on:
pull_request:
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.11"
- run: pip install -r requirements.txt
- run: pytest tests/unit -q
Si una prueba es lenta o inestable, pásala a eval harness o a la capa de integración.
Errores típicos
Dependencia de APIs reales
La prueba falla no por lógica del agente, sino por red o servicio externo.
Causa típica: faltan fakes o mocks para herramientas.
Probar solo el texto final
La prueba pasa, pero no garantiza selección correcta de herramienta ni formato de salida correcto.
Causa típica: faltan checks de selected_tool, schema y stop reason.
Demasiada lógica en una sola prueba
Una prueba valida varios escenarios a la vez, y al fallar no queda claro qué se rompió exactamente.
Causa típica: no existe la regla "una prueba - un comportamiento".
Entorno de prueba inestable
Incluso unit tests correctos se vuelven ruidosos si entre runs cambian dependencias, configuración o reemplazos de herramientas.
Causa típica: los unit tests aún dependen parcialmente de runtime real o llamadas externas.
Intentar cubrir todo vía runs e2e
El equipo escribe solo escenarios grandes y salta validaciones locales básicas.
Causa típica: no hay separación clara entre niveles unit, eval y regression.
Resumen
- Los unit tests de agentes validan lógica local y determinista.
- Reemplaza herramientas con fakes o mocks para eliminar ruido de red.
- Fija checks estructurales: tool choice, schema, stop reason.
- Los unit tests rápidos deben ejecutarse en cada PR.
FAQ
Q: ¿Los unit tests pueden sustituir eval harness?
A: No. Los unit tests detectan fallos locales, mientras eval harness valida el comportamiento completo del agente en escenarios cerrados.
Q: ¿Conviene conectar una LLM real en unit tests?
A: Mejor al mínimo. En nivel unit funciona mejor lógica determinista con fakes o mocks y condiciones controladas.
Q: ¿Qué debe verificar sí o sí un unit test de agente?
A: Selección de herramienta, estructura de salida, manejo de errores y stop reason en escenarios negativos.
Q: ¿Cuándo mover una prueba de nivel unit a nivel eval?
A: Cuando depende del comportamiento completo por escenario, de métricas de calidad de respuesta o de comparaciones con baseline.
Qué sigue
Después del nivel unit, agrega validación por escenarios con Eval Harness, y mantiene un conjunto estable de casos con Golden Datasets.
Para controlar cambios entre versiones, añade Regression Testing. Para analizar incidentes de producción, usa Replay and Debugging. Mantén la visión completa en Testing Strategy.