proyecto_1_dentistas — plan de scaffold (E1) con investigación verificada (2026-09-26)
Contexto: complemento de [CREDENCIAL].md y
[CREDENCIAL].md. Todo lo de la sección 1 fue
verificado hoy contra las cuentas/APIs reales (solo lecturas y 3 llamadas de humo).
Nada se construye hasta aprobar este plan.
1) Hallazgos verificados
HF Router (HF_TOKEN, OpenAI-compatible):
- Vivo y funcionando: 139 modelos en
/v1/models. Test real de chat:deepseek-ai/DeepSeek-V4.1-Flashrespondió en 0.8 s. DeepSeek-V4.1-Flash— MIT, 1M contexto, tools, structured output (deepinfra), 0.60 por M tokens (deepinfra). Emitereasoning_content→ los tokens de razonamiento cuentan como salida (verificar cómo desactivarlo o usar el Flash simple).DeepSeek-V4-Flash— MIT, 0.18 (deepinfra). El más barato para bulk/rerank.DeepSeek-V4-Pro— MIT, 2.60 (deepinfra). Candidato a juez de calidad.XiaomiMiMo/MiMo-V2.5-Pro— MIT, 1.04 (novita) o 3 (deepinfra).- Corrección: MiMo-V2.6 no existe en el router ni en HF. Lo disponible es V2.5. Los planes previos que citaban MiMo-V2.6-Pro quedan corregidos.
Embeddings:
- El router NO expone
/v1/embeddings(404). - SÍ funciona
Qwen/Qwen3-Embedding-4B(Apache-2.0) víahuggingface_hubInferenceClient(provider="deepinfra")→ probado, devuelve vector. - Fallback offline:
nomic-embed-textya instalado en Ollama (0.27 GB).
Reranker:
Qwen/Qwen3-Reranker-*no está servido por ningún proveedor.BAAI/bge-reranker-v2-m3solo exponetext-classificationvía hf-inference (sin API de ranking práctica en el cliente actual).- → v0 mide dos modos:
sin rerankvsLLM-rerankcon DeepSeek-V4-Flash.
Fallbacks:
- Groq vivo con GROQ_API_KEY:
gpt-oss-120b,qwen3.8-27b,llama-prompt-guard-2-86m(útil para guardrails del E4), whisper. - Local offline (Ollama, Mac M1 Pro 16 GB):
qwen3.5:9b(6.6 GB, cabe),deepseek-r1:8b(5.2 GB),nomic-embed(0.27 GB).qwen3.6(23.9 GB) NO cabe. - Disco libre: 10 GB (Ollama ya ocupa 43 GB, HF cache 5 GB — no descargar pesos grandes).
Dependencias (resolución real con uv, Python 3.12):
- ragas 0.4.3 · faiss-cpu 1.15.1 (wheel
cp310-abi3-macosx_14_0_arm64, OK en macOS actual) · rank-bm25 · httpx · pydantic 2.13 · rich. - 337 paquetes sin LlamaIndex; 429 con LlamaIndex. Sin torch.
- → Decisión: sin LlamaIndex en E1 v0 (92 paquetes menos, menos magia).
Costos reales estimados por corrida completa de eval (50 preguntas):
- Generación: ≈ 0.10 (V4.1-Flash) o ≈ $0.55 (V4-Pro).
- Total E1 << 20 sobra con margen grande.
2) Decisiones finales del scaffold
| Tema | Decisión |
|---|---|
| Repo | ~/nef/Proyectos/proyecto_1_dentistas/ (git propio) — pendiente tu ok |
| LLM generación | DeepSeek-V4.1-Flash (HF router) |
| LLM bulk/rerank | DeepSeek-V4-Flash |
| LLM juez | DeepSeek-V4-Pro (solo eval de calidad) |
| Fallback LLM | Groq (gpt-oss-120b) · offline: Ollama qwen3.5:9b |
| Embeddings | Qwen3-Embedding-4B vía InferenceClient(deepinfra); fallback nomic |
| Rerank | modos off y llm (V4-Flash) para medir delta |
| Eval | RAGAS 0.4.3 + citation accuracy propio + contador de costos |
| Python | 3.12 gestionado por uv (instalar en scaffold) |
| NO | sin Docker, sin LlamaIndex, sin torch, sin pesos grandes |
Nota RAGAS: la doc cambió de rutas; las firmas exactas de llm_factory /
embedding_factory se verifican en la primera hora del scaffold (el router es
OpenAI-compatible, así que la vía estándar aplica).
3) Estructura del repo
proyecto_1_dentistas/
├── README.md # 3 comandos + límites conocidos
├── pyproject.toml # uv, python 3.12
├── .env.example # HF_TOKEN, GROQ_API_KEY, modelos (sin secretos)
├── .gitignore
├── Makefile # setup | index | ask | eval | smoke
├── config/default.toml # providers, modelos, precios, umbrales
├── shared/
│ ├── corpus/ # 15 docs .md (clínica ficticia) + _meta.json
│ ├── golden_set/ # v0.jsonl (20 preguntas) + schema.json
│ └── eval/ # ragas_run.py, citation_eval.py, costos.py
├── src/dentistas/
│ ├── config.py
│ ├── providers.py # hf router | groq | ollama (mismo contrato)
│ ├── embeddings.py # qwen3 (hf) | nomic (ollama)
│ ├── chunking.py # semántico 256-512 tokens + metadatos
│ ├── index.py # FAISS + BM25 persistido
│ ├── retrieve.py # híbrido RRF + rerank off/llm
│ ├── answer.py # prompt con citas + "no sé → canalizo"
│ ├── cli.py # index | ask | eval
│ └── eval_runner.py
├── artifacts/ # gitignored: índice, runs, costos
├── tests/test_smoke.py
└── marketing/ # demo-script.md, one-pager.md, pagina-servicio.md
4) Pasos de ejecución (al aprobar), cada uno con verificación
uv python install 3.12·git init· uv init · resolver deps. Verificación: instalación sin torch (uv treeno muestra torch).- config +
.env.example+ Makefile. Verificación:make setuplimpio. - Corpus v0 (15 docs) + golden set v0 (20 preguntas). Verificación: script de validación (campos, encabezado “datos ficticios de laboratorio”).
providers.pycon 3 backends; test de humo: 1 llamada por backend.- embeddings + índice FAISS/BM25 + RRF +
askcon citas. - eval RAGAS + citation + costos sobre 20 preguntas. Verificación: eval.csv + cost.json + resumen.md.
- Iterar hasta umbrales (faithfulness >0.85, precision/recall >0.75) o registrar gaps como límites conocidos.
- Plantillas de marketing (vacías de números hasta tener informe).
- Commit inicial + README (3 comandos + límites).
DoD: make setup <1.5 GB · make index reporta chunks · make ask Q="¿cuánto cuesta una limpieza?" responde con citas y costo · make eval produce los 3
archivos · make smoke verde.
5) Marketing mínimo (atado a hitos)
- M1 (sem 2-3, al pasar umbrales): guion + video demo 3-5 min (5 preguntas reales a la clínica ficticia, citas + tabla de métricas). Uso 1:1.
- M2 (sem 4): one-pager HTML→PDF. Fuente de stats de mercado: decision
[CREDENCIAL].md(ya compiladas). - M3 (sem 4-6): página de servicio en pichardo.com + artículo de método citable.
- M4 (sem 6-8): demo 15 min a 1 clínica real (el testigo).
- M5 (post-testigo): outreach 1:1, lista de 20 clínicas, cero envío masivo.
- Guardarraíles: cero testimonios ficticios · demo etiquetada “laboratorio” · números solo del informe · si un número no se sostiene, se baja la promesa.
6) Correcciones a los planes previos
- MiMo-V2.6-Pro no está disponible → DeepSeek V4.x / MiMo V2.5.
- LlamaIndex fuera de E1 v0.
- Reranker Qwen3 no disponible → LLM-rerank (V4-Flash).
- Embeddings no van por el router → InferenceClient(deepinfra) o nomic local.
7) Preguntas abiertas (2)
- ¿Repo en
~/nef/Proyectos/proyecto_1_dentistas/? (recomendado; corrige la convención de los decisions previos que decían~/nef/projects/benchmark-ia-dental/) - ¿M1/M2 como plantillas desde el scaffold y demo pública solo después del piloto? (recomendado)