MVP desplegado: nef-bot-pilot (Widget de chat RAG para negocio)
Fecha: 2026-09-17. Stack: Cloudflare Workers + Workers AI + Vectorize + D1 + KV + Turnstile.
Producción
- URL: https://nef-bot-pilot.nef.workers.dev (chat público) /admin (ingesta)
- Widget Turnstile:
nef-bot-pilot-widget(managed), sitekey0x4AAAAAAE5wlYi026UKdjtW, dominios nef-bot-pilot.nef.workers.dev + localhost/[IP] - Secrets en Worker: TURNSTILE_SECRET, ADMIN_KEY
- Copia local de secrets (gitignored):
.env.localy.dev.varsen ~//llm-test-cf - Recursos: D1
nef-bot-pilot(id 052be1fb-…), KVNEF_BOT_KV(id 839883cb…), Vectorizenef-bot-vectors(1024d cosine)
Pitfalls aprendidos (evitar re-depurar)
run_worker_first:trueexigeassets.binding— sin él,env.ASSETSno existe → 500.- Workers AI requiere binding explícito
"ai":{"binding":"AI"}en wrangler.jsonc — sin él,env.AIes undefined → excepción 1101. - Assets resuelve pretty URLs: no reescribir
/ni/admin; pasar el request tal cual aenv.ASSETS.fetch(request). - Streaming de chat (vía binding o REST): eventos SSE
data:conchat.completion.chunk; el delta eschoices[0].delta.content;[DONE]al final;usageaparece en el último evento. NO usarresponse(acumulado/ausente). - El token OAuth de
wrangler loginno traechallenge-widgets.write; re-loguear con wrangler >=4.109 parawrangler turnstile widget create/get. - wrangler con subcomando turnstile = el del proyecto (devDep 4.133.0); el global Homebrew (4.99.0) no lo trae.
Seguridad v1 (fail closed)
Turnstile siteverify server-side (action+hostname) · rate limit KV/IP/10min · presupuesto diario de tokens en D1 (~500k ≈ U$S 1/día) · score-gate retrieval >=0.45 → “no tengo info” sin gastar generación · contexto como datos no confiables en el prompt (anti injerencia) · ingesta solo con ADMIN_KEY (timing-safe) · CSP estricta, sin inline JS · sin fetching de URLs (cero SSRF) · CORS same-origin.
Pendiente
- Prueba en navegador: Turnstile → ingest → chat RAG end-to-end.
- Vars ajustables desde wrangler.jsonc: DAILY_TOKEN_BUDGET, RATE_LIMIT_PER_WINDOW, RETRIEVAL_MIN_SCORE, TOPK, BUSINESS_NAME, MAX_OUTPUT_TOKENS.
Guía de preparación de datos (añadida al /admin como details plegable)
Principios que dictan la guía (acordes a chunking ~900 chars + similitud coseno bge-m3 + “solo responde con contexto”):
- Respuestas completas y autocontenidas: cada frase se sostiene sola.
- Una idea por párrafo (3-6 líneas); el corte respeta párrafos.
- Escribir la pregunta como la diría el cliente, respuesta directa primero, luego detalle.
- Números completos en dígitos; sin “después/arriba”; el contexto no tiene orden.
- Evitar: contradicciones, fechas que caducan, “ver sección”/enlaces, jerga sin definir, tablas gigantes.
- Checklist previo + prueba rápida en chat tras subir. Nota: el dedupe es por hash del contenido — re-subir un doc editado cuenta como nuevo y deja cohabitando versiones.