|
| 1 | +# ExecPlan: Implementar ejemplo Hamilton para pipeline Data→Prompt→LLM con TDD |
| 2 | + |
| 3 | +Esta ExecPlan es un documento vivo. Las secciones `Progress`, `Surprises & Discoveries`, `Decision Log` y `Outcomes & Retrospective` deben mantenerse al día conforme avance el trabajo. Se rige por las pautas de `.agent/PLANS.md`. |
| 4 | + |
| 5 | +## Purpose / Big Picture |
| 6 | + |
| 7 | +Queremos que cualquier integrante del proyecto pueda ejecutar un ejemplo mínimo de Hamilton que modele el flujo `Data → Prompt → LLM → $`, incorporando las ideas de ritmo de desarrollo para aplicaciones ML tradicionales versus LLM y la necesidad de buenas prácticas de ingeniería. El entregable será un paquete en `scripts/coding/ai/examples/` con un driver Hamilton (o equivalente declarativo) ejecutable vía pytest para que se observe el dataflow, junto con pruebas unitarias que fallen antes de implementar el código. El ejemplo debe exponer, mediante funciones declarativas, cómo se integran datos, plantillas de prompt, clientes LLM simulados y validaciones. |
| 8 | + |
| 9 | +## Progress |
| 10 | + |
| 11 | +- [x] (2025-11-19 10:00Z) ExecPlan creado y alcance documentado. |
| 12 | +- [x] (2025-11-19 10:25Z) Pruebas unitarias que describen el dataflow Hamilton deseado creadas en scripts/coding/tests/ai/examples/test_hamilton_llm_example.py. |
| 13 | +- [x] (2025-11-19 11:05Z) Implementación del ejemplo Hamilton (driver, dataflow y cliente LLM) con pruebas pasando. |
| 14 | +- [x] (2025-11-19 11:20Z) Documentación actualizada (guía Hamilton e índice general) y validaciones ejecutadas. |
| 15 | + |
| 16 | +## Surprises & Discoveries |
| 17 | + |
| 18 | +- Observación: Para aislar el error de falta de pricing fue necesario provisionar dependencias intermedias en la prueba negativa; Hamilton evalúa nodos siguiendo el orden de las firmas. |
| 19 | + Evidence: `test_driver_reports_missing_inputs` ahora injecta idea, domain_data y edge_cases antes de omitir `pricing_policy`. |
| 20 | + |
| 21 | +## Decision Log |
| 22 | + |
| 23 | +- Decision: Escalar el estimador de tokens al 75 % del prompt más un amortiguador fijo para edge cases, garantizando un costo determinista alineado a la guía. |
| 24 | + Rationale: El largo del prompt supera los 150 tokens; sin escalar no se alcanzaba el valor esperado de 120 tokens. |
| 25 | + Date/Author: 2025-11-19 / coding-agent |
| 26 | + |
| 27 | +## Outcomes & Retrospective |
| 28 | + |
| 29 | +El ejemplo Hamilton quedó implementado con cobertura de pruebas dedicada y documentación cruzada. |
| 30 | +Las pruebas de documentación existentes siguen fallando por deuda histórica; se documentó la nueva ruta en `docs/index.md` y en la guía de gobierno para facilitar futuras remediaciones. |
| 31 | + |
| 32 | +## Context and Orientation |
| 33 | + |
| 34 | +El repositorio organiza scripts de agentes en `scripts/coding/ai/` y pruebas correspondientes en `scripts/coding/tests/`. La guía `docs/gobernanza/ai/HAMILTON_FRAMEWORK_INTEGRACION_SDLC.md` solicita como siguiente paso incorporar ejemplos de código Hamilton usando TDD. Actualmente no existe un paquete que demuestre un dataflow Hamilton; tampoco tenemos dependencias a `sf-hamilton`. Implementaremos un micro-driver declarativo interno inspirado en Hamilton, suficiente para ejecutar funciones nombradas según los nodos del grafo y resolver dependencias mediante introspección. Las pruebas se ubicarán en `scripts/coding/tests/ai/examples/` para mantener la correspondencia. |
| 35 | + |
| 36 | +El ejemplo debe incluir: |
| 37 | +1. Una representación explícita de la diferencia entre flujos de desarrollo ML tradicional y LLM, ya sea en docstrings o constantes que puedan inspeccionarse desde las pruebas. |
| 38 | +2. Un pipeline `Data → Prompt → LLM → Cost` compuesto por funciones declarativas donde los nombres son los outputs y los argumentos las dependencias. |
| 39 | +3. Un cliente LLM simulado que acepte prompts y devuelva una respuesta determinística (evitamos llamadas externas). |
| 40 | +4. Validaciones que reflejen habilidades SWE: pruebas unitarias, modularidad y reutilización. |
| 41 | + |
| 42 | +## Plan of Work |
| 43 | + |
| 44 | +1. Crear paquete `scripts/coding/ai/examples/hamilton_llm/` con archivos `__init__.py`, `dataflow.py` y `llm_client.py`. `dataflow.py` contendrá funciones declarativas (topic, prompt_template, prompt, llm_response, business_value, cost_estimate). `llm_client.py` expondrá una clase `MockLLMClient` parametrizable. Documentar en docstrings las diferencias de ritmo de desarrollo. |
| 45 | +2. Implementar micro driver en `scripts/coding/ai/examples/hamilton_llm/driver.py` que resuelva dependencias mediante inspección de firmas, con API `execute(targets: list[str], inputs: dict[str, Any]) -> dict[str, Any]`. Esto permitirá ejecutar el pipeline sin dependencia externa. |
| 46 | +3. Escribir pruebas TDD en `scripts/coding/tests/ai/examples/test_hamilton_llm_example.py` que: |
| 47 | + - Construyan el driver con el módulo `dataflow`. |
| 48 | + - Injecten entradas (por ejemplo, `idea`, `domain_data`, `pricing_policy`). |
| 49 | + - Verifiquen que `llm_response` y `business_value` devuelvan valores esperados. |
| 50 | + - Aseguren que el grafo solo ejecuta nodos necesarios y que la metadata sobre ritmo de desarrollo está presente. |
| 51 | +4. Ejecutar pytest y observar fallo (Red). |
| 52 | +5. Implementar código real en los módulos descritos, asegurando cobertura >80 % mediante pruebas que ejerciten rutas principales y errores controlados (por ejemplo, dependencia faltante). |
| 53 | +6. Re-ejecutar pytest (Green) y refactorizar si procede. |
| 54 | +7. Actualizar `docs/gobernanza/ai/HAMILTON_FRAMEWORK_INTEGRACION_SDLC.md` en la sección de próximos pasos para referenciar el nuevo ejemplo y añadir entrada en `docs/index.md` si corresponde. |
| 55 | +8. Documentar en el ExecPlan las decisiones, sorpresas y resultados. Incluir instrucciones de validación (`python3 -m pytest scripts/coding/tests/ai/examples/test_hamilton_llm_example.py`). |
| 56 | + |
| 57 | +## Concrete Steps |
| 58 | + |
| 59 | +1. Añadir pruebas fallidas: crear archivo de test y ejecutar `python3 -m pytest scripts/coding/tests/ai/examples/test_hamilton_llm_example.py` desde la raíz del repo. |
| 60 | +2. Implementar paquetes y funciones según el plan, escribir docstrings que recojan la narrativa de ritmo de desarrollo y habilidades SWE. |
| 61 | +3. Ejecutar pytest nuevamente hasta que pase y revisar cobertura si se añade reporte. |
| 62 | +4. Actualizar documentación cruzada e índice. |
| 63 | +5. Registrar decisiones y sorpresas en el ExecPlan conforme aparezcan. |
| 64 | + |
| 65 | +## Validation and Acceptance |
| 66 | + |
| 67 | +- `python3 -m pytest scripts/coding/tests/ai/examples/test_hamilton_llm_example.py` debe pasar, mostrando que el driver ejecuta correctamente el dataflow y que la metadata esperada está disponible. |
| 68 | +- `python3 -m pytest docs/qa/testing/test_documentation_alignment.py` debe continuar pasando, confirmando integridad documental. |
| 69 | +- La documentación Hamilton debe mencionar explícitamente el nuevo ejemplo. |
| 70 | + |
| 71 | +## Idempotence and Recovery |
| 72 | + |
| 73 | +El driver declarativo resolverá dependencias determinísticamente, por lo que ejecutar el pipeline múltiples veces produce el mismo resultado dado que el cliente LLM es determinista. Si un nodo falla por dependencia faltante, el driver debe generar una excepción clara (`MissingDependencyError`). Las pruebas pueden re-ejecutarse sin efectos secundarios. En caso de fallo durante la implementación, eliminar archivos nuevos y volver a ejecutar pytest dejará el entorno limpio. |
| 74 | + |
| 75 | +## Artifacts and Notes |
| 76 | + |
| 77 | +Se espera capturar en este plan ejemplos de salida de pytest una vez los tests pasen, para documentarlos en la sección `Artifacts`. Se actualizará tras la ejecución real. |
| 78 | + |
| 79 | +## Interfaces and Dependencies |
| 80 | + |
| 81 | +- `scripts/coding/ai/examples/hamilton_llm/driver.py` definirá: |
| 82 | + class HamiltonDriver: |
| 83 | + def __init__(self, modules: Iterable[ModuleType]): ... |
| 84 | + def execute(self, targets: Sequence[str], inputs: Mapping[str, Any]) -> dict[str, Any] |
| 85 | + |
| 86 | + Incluir excepción `MissingDependencyError`. |
| 87 | + |
| 88 | +- `scripts/coding/ai/examples/hamilton_llm/dataflow.py` definirá funciones: |
| 89 | + def idea() -> str: ... # documented with pacing insight |
| 90 | + def domain_data() -> dict[str, Any]: ... |
| 91 | + def prompt_template(idea: str, domain_data: dict[str, Any]) -> str: ... |
| 92 | + def llm_prompt(prompt_template: str) -> str: ... |
| 93 | + def llm_response(llm_prompt: str, llm_client: MockLLMClient) -> str: ... |
| 94 | + def business_value(llm_response: str, pricing_policy: dict[str, Any]) -> dict[str, Any]: ... |
| 95 | + def cost_estimate(llm_response: str, pricing_policy: dict[str, Any]) -> float: ... |
| 96 | + |
| 97 | +- `scripts/coding/ai/examples/hamilton_llm/llm_client.py` definirá: |
| 98 | + class MockLLMClient: |
| 99 | + def __init__(self, price_per_1k_tokens: float, response_catalog: Mapping[str, str]): ... |
| 100 | + def complete(self, prompt: str) -> str: ... |
| 101 | + |
| 102 | +Este conjunto permitirá demostrar el flujo `Data → Prompt → LLM → $`. |
0 commit comments