AI 资讯
Automatizaciones para pymes: las cinco que siempre piden, ordenadas por lo que cuesta mantenerlas
El chatbot va último: cómo ordeno las cinco automatizaciones que más me piden Tengo 16 flujos en producción para pymes y la lista de pedidos se repite casi siempre igual. Lo que no se repite es cuál conviene hacer primero. La discusión habitual las ordena por dificultad de construcción, y esa es la métrica equivocada. Construir es la parte barata: el modelo escribe la mayor parte. Lo que se paga después es el mantenimiento, y ahí el orden se da vuelta. Van las cinco, ordenadas por lo que cuesta sostenerlas, de la peor a la mejor. 5. Responder consultas frecuentes La que todos piden primero y la que más mantenimiento tiene. Parece contenida: son las mismas veinte preguntas. No lo es, porque el contexto que necesita se mueve todo el tiempo. Cambia el catálogo, cambian los precios, cambia el horario en verano. Meta cambia requisitos de la API. El modelo se actualiza y el mismo prompt deja de comportarse igual. Y sobre todo: es la única de las cinco donde el error lo ve el cliente . Un bot que inventa un precio no genera un ticket interno, genera un reclamo. Si igual va primera —y a veces va, porque es la que se ve—, presupuestala con el abono adentro desde el día uno. 4. Turnos y reservas La más engañosa de la lista. Tomar un turno es trivial; el problema es todo lo demás. Cancelaciones, reprogramaciones, dos personas pidiendo el mismo horario con cuatro segundos de diferencia, el turno que se cargó a mano en el sistema y el bot no vio. Es estado compartido con escritura concurrente , que es un problema viejo y conocido, disfrazado de chatbot. Si la agenda vive en un sistema con API decente, baja bastante. Si vive en un Google Calendar que además tocan tres personas a mano, no la subestimes. 3. Mover datos entre sistemas La que más valor devuelve y la que menos depende de vos. El trabajo real casi nunca es la transformación de los datos: es el sistema del otro lado. Y en pymes ese sistema suele ser uno de gestión local, sin API pública, sin documentación, y con un prov
开发者
Empecé este bot por desconfianza, no por avaricia.
Diario de un bot que opera con dinero real — Entrada #0: el origen Todo empezó con un tuit. Uno de esos que seguramente también has visto: una captura de una wallet, "$100 convertidos en $10.000 en 24 horas con este bot de trading", flechas verdes, emojis de cohetes, y un "sígueme para más". Debajo, cientos de likes y gente pidiendo el enlace. Mi primera reacción no fue "quiero eso". Fue "eso es mentira". Y no hace falta ser matemático para verlo. Un retorno del 10.000% en un día no es una estrategia — es un billete de lotería premiado que alguien presenta como si fuera un método repetible. Si de verdad tuvieras un sistema que multiplica tu dinero por cien cada 24 horas, no lo estarías publicando en X pidiendo likes. Lo estarías usando en silencio hasta comprar una isla. El que regala el mapa del tesoro es porque el tesoro no existe — el verdadero producto que se vende en esos tuits no es el bot: eres tú, tu like, tu follow, tu atención. Así que no le di like. Pero me quedé pensando. La pregunta que sí valía la pena Descartado el humo, quedaba una pregunta honesta debajo: despojado de la mentira del 10.000%, ¿hay algo real ahí? Porque los bots de trading existen. La automatización de estrategias es legítima. Los mercados operan 24/7 y un programa no duerme ni entra en pánico. La idea de fondo —dejar que un sistema ejecute una estrategia con disciplina, sin la emoción que arruina las decisiones humanas— no es una estafa. La estafa es el número. La estafa es prometer un retorno imposible para vender seguidores. Entonces me hice la pregunta que inició todo esto: ¿qué pasa si alguien escéptico construye un bot de trading de verdad, con expectativas sobrias, y documenta la verdad completa — incluida la parte donde todavía no sabe si funciona? Esa es la serie que estás empezando a leer. Lo que es, y lo que no es Para que no haya malentendidos, porque tú y yo ya sabemos cómo suele terminar este tipo de contenido: Esto no es un tutorial de "hazte rico". No voy a mostrarte u
开发者
Construí 17 calculadoras sin una sola dependencia de JavaScript en el cliente
Hace unos meses empecé a construir Utiligo , una colección de calculadoras en español: horas extras, IVA, aguinaldo, préstamos, IMC. La premisa técnica era simple y me la tomé en serio: cero dependencias de JavaScript en el navegador . Sin React, sin frameworks de UI, sin librerías de gráficos. Ni una. Esto es lo que aprendí construyéndolo. Por qué cero dependencias La mayoría de estas herramientas hacen aritmética. Sumar horas, aplicar un porcentaje, dividir un salario entre 30. Enviar 40 KB de framework al navegador para calcular salario / 30 / 8 es desproporcionado, y en América Latina —donde está mi audiencia— buena parte del tráfico llega por móvil con conexiones irregulares. El stack quedó así: Astro en modo output: 'static' , que genera HTML puro <script is:inline> con JavaScript de toda la vida para la interactividad Cloudflare Pages para servirlo El resultado: páginas que funcionan antes de que termine de cargar cualquier cosa. Lo que sí duele de esta decisión Sería deshonesto contarlo como si no tuviera costes. Los gráficos hay que dibujarlos a mano. El gráfico de pastel del presupuesto mensual es SVG generado con trigonometría: var end = start + pct * 2 * Math . PI ; var x1 = cx + r * Math . cos ( start ), y1 = cy + r * Math . sin ( start ); var x2 = cx + r * Math . cos ( end ), y2 = cy + r * Math . sin ( end ); var large = pct > 0.5 ? 1 : 0 ; svg += ' <path d="M ' + cx + ' , ' + cy + ' L ' + x1 + ' , ' + y1 + ' A ' + r + ' , ' + r + ' 0 ' + large + ' ,1 ' + x2 + ' , ' + y2 + ' Z"/> ' ; Con una librería serían tres líneas. Aquí son treinta y hay que entender el arco elíptico de SVG. ¿Vale la pena? Para un gráfico, sí. Para un dashboard entero, probablemente no. No hay reactividad. Cada oninput actualiza el DOM a mano. Funciona bien con diez campos; con cien sería insostenible. El generador de QR tuve que escribirlo. Codificación Reed-Solomon incluida. Fue el fin de semana más educativo del proyecto y el que menos recomendaría repetir. El bug que me enseñó
开发者
«es» no es un mercado: el bug de i18n que nos costó reescribir una campaña entera
Nota: en Lumora construimos libros infantiles personalizados con IA, y escribimos en diez idiomas. Este artículo cuenta un problema de i18n con el que chocamos de frente y cómo lo resolvimos. Lo contamos desde dentro, con nuestro nombre, porque el error nos costó reescribir una campaña entera. Casi todos los equipos tratamos el idioma como si fuera el país. Ponemos es en el selector, sacamos las cadenas a un JSON y damos el problema por cerrado. Funciona hasta el día en que tu producto tiene algo que ver con una fecha. Y entonces descubres que es no es un mercado, son varios calendarios distintos que comparten vocabulario. El día en que el regalo no llega el 25 Teníamos una campaña de regalos escrita en español. Correcta gramaticalmente, revisada, sin errores de traducción. Y aun así estaba mal para una parte grande de quien la leía: En España , el gran momento de regalo infantil no es el 25 de diciembre: son los Reyes Magos, el 6 de enero . Un mensaje que dice "pídelo antes del 24" le está dando a una familia española una fecha límite equivocada por casi dos semanas. En México conviven las dos cosas: Navidad y Reyes, con la rosca del 6 de enero. En Argentina, Chile o Uruguay , la Navidad es el 25 de diciembre… en pleno verano . A 30 grados. Con las vacaciones escolares largas empezando, no terminando. Fíjate en lo incómodo del asunto: los tres casos hablan español. Los tres pasan el mismo test de traducción. Y los tres necesitan un mensaje distinto, una imagen distinta y una fecha límite distinta. El mismo golpe existe en portugués. En Brasil la Navidad también cae en pleno verano, enero es mes de vacaciones, y el día en que de verdad se reinicia la rutina familiar no es el 1 de enero: es la volta às aulas , en febrero. Si tu calendario de contenidos asume "año nuevo, hábitos nuevos" en enero, en Brasil llegas un mes antes de que a nadie le importe. Por qué el código de locale no te salva La respuesta obvia es "usa es-ES y es-AR ". Es correcta y casi nunca es sufic
AI 资讯
Medir si un LLM nombra a tu empresa: por qué una captura no sirve como métrica
Cada vez más gente arranca la búsqueda de un proveedor preguntándole a un modelo en vez de a un buscador. Y no pide diez opciones para comparar: pide una recomendación y recibe dos o tres nombres. Si tu empresa no está ahí, no quedaste octava. No estás en la respuesta. La pregunta que sigue es obvia: cuánto tarda en cambiar eso. Pero antes hay un problema más aburrido y más importante, que es cómo se mide. Lo escribo porque es la parte que casi nunca se cuenta y es donde se rompen los informes. Una captura de pantalla no es una medición Es el error más común y el más difícil de discutir, porque la captura parece prueba. La respuesta de una app conversacional depende del historial de la cuenta, de la sesión, del ruteo interno del proveedor, de si esa consulta activó búsqueda web o no, y de la región desde donde se pregunta. Dos personas preguntando lo mismo el mismo día reciben respuestas distintas. La misma persona preguntando dos veces también. O sea: la salida no es determinista y el instrumento no es estable. Una captura te dice qué pasó una vez, en un contexto que no podés reconstruir. Como métrica de seguimiento no sirve para nada. Lo que sí sirve es una serie: la misma consulta, literal, contra el mismo motor, con el mismo criterio de clasificación, repetida en el tiempo. El valor absoluto de un punto importa poco. Lo que importa es la diferencia entre puntos. Fijar el texto de la consulta, no la etiqueta Este es un bug de proceso que da resultados verosímiles y falsos. Si guardás en la planilla una etiqueta como "consulta de chatbot" en vez del texto exacto que preguntaste, dentro de dos meses nadie se acuerda del wording. Y el wording cambia el resultado: preguntar "quién hace X en Argentina" y "mejores empresas de X en Argentina" devuelven listas distintas. Cuando el texto se corre entre rondas, la serie deja de ser comparable, pero el gráfico sigue dibujándose igual de lindo. Guardá el string literal, versionado. Si tenés que cambiar una consulta, empezá u
AI 资讯
What Spain's Verifactu law actually does to your backend
Spain is putting a hash chain behind every invoice, and almost everything written about it so far has been written for accountants. This is the version for whoever has to ship it. The deadlines are January 1, 2027 for companies and July 1, 2027 for sole traders. If you read something last year that said 2026, that was true until RD-ley 15/2025 moved the whole calendar back twelve months. Software vendors have been on the hook since July 2025, which is a detail worth holding on to if you sell a product that issues invoices for other people. At BeeL., we sell an API for this, so read the rest with that in mind. The requirement Each invoice your software issues has to produce a registro de facturación de alta: a record containing a defined set of fields, hashed with SHA-256, where the hash of each record folds in the hash of the one before it. One chain per issuing tax ID, growing forever, never edited. Cancelling an invoice is not a delete. It's a second record type, a registro de anulación, which goes into the same chain. Same for corrections, which come in two flavours depending on whether you're amending a difference or replacing the original document. The printed invoice carries a QR code with verification data, plus the string VERI*FACTU if you're in submitting mode. Then you either push each record to the tax agency as it happens, or you keep everything locally under stricter signing and retention rules and hand it over when asked. Written down like that, it reads like an afternoon of work. A hash function, a previous_hash column, an HTTP call. Where the estimate falls apart The chain is strictly sequential, so two workers issuing invoices for the same tax ID at the same time are racing for the same link. You need a lock per issuer, or a queue, or both, and either way concurrent issuance stops being free. Retries are worse than they look. A failed submission that you retry carelessly either duplicates a record or breaks the chain, and a broken chain isn't someth
AI 资讯
Mi stack de AI coding en 2026: Mejor calidad/precio ahorrativo y competitivo🥳️
No pago $20/mes por Copilot. No tengo un Mac. Uso Linux Mint con un agente open-source, una API que cuesta céntimos y una terminal TUI. Este es mi setup real, lo bueno y lo que no te cuentan. No es postureo. Es pragmatismo. Mira, te voy a ser sincero. Cuando empecé a usar AI para programar probé de todo: Copilot, Cursor, Codeium, Continue... y cada uno tenía algo que no me cerraba. O era caro, o me ataba a un editor, o mandaba mi código a un servidor que no controlaba. Así que hice lo que haría cualquier developer cabezón: monté mi propio stack. Llevo unos meses con esta configuración y —spoiler— no he vuelto a abrir VSCode. Aquí te cuento qué uso, por qué, y lo que me costó que funcionara bien. El stack (sin humo) Linux Mint 22 ← SO base (porque funciona y no da guerra) └─ Hermes Agent TUI ← Agente open-source de Nous Research ├─ DeepSeek V4 Pro API ← El cerebro (1M contexto, $0.43/M tokens) ├─ Gemini API (free) ← Búsquedas y consultas web └─ Terminal (Alacritty) ← Donde vivo el 90% del tiempo Tres piezas. Sin IDEs de pago. Sin lock-in. Sin depender de que OpenAI no suba precios otra vez. ¿Por qué DeepSeek y no Claude/GPT? He probado los tres. Mi razonamiento: DeepSeek V4 Pro Claude Sonnet GPT-4o Precio (1M tokens in) $0.43 $3.00 $2.50 Ventana de contexto 1M tokens 200K 128K Calidad de código ⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐ Razonamiento largo ⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐ DeepSeek me da el 85-90% de la calidad de Claude por el 15% del precio. Para el 90% de las tareas diarias —refactorizar, debuggear, generar boilerplate, explicar código— la diferencia no se nota. Cuando necesito razonamiento ultra-profundo para algo muy complejo, cambio a Claude. Pero son momentos puntuales. El día a día es DeepSeek. 💡 El dato que nadie dice: Con DeepSeek V4 Pro gasto ~$5-8 al MES programando 4-6 horas al día. Con Claude o GPT estaría en $40-60. La diferencia paga mi VPS. Hermes Agent: el agente que no sabías que necesitabas Hermes Agent es un agente open-source (MIT) de Nous Research. 219K estrellas en GitHub
开发者
De x86 a ARM: la revolución silenciosa hacia una nube más verde en Microsoft Azure
Durante más de cuatro décadas, hablar de servidores era prácticamente sinónimo de hablar de arquitectura x86 . Desde los primeros servidores empresariales hasta la mayoría de los centros de datos modernos, Intel y AMD han dominado la infraestructura sobre la que funcionan nuestras aplicaciones. Sin embargo, algo está cambiando. De forma silenciosa, los principales proveedores de nube como Microsoft Azure están incorporando cada vez más procesadores ARM para ejecutar cargas de trabajo modernas. ¿La razón? No es únicamente el rendimiento. Es la eficiencia energética. El problema de los centros de datos modernos Cada vez que desplegamos una máquina virtual o un clúster de Kubernetes en Azure, detrás existe un servidor físico consumiendo energía. Ahora imaginemos un centro de datos con cientos de miles de servidores. Incluso una pequeña reducción en el consumo eléctrico por servidor representa un ahorro enorme cuando se multiplica por toda la infraestructura. Y no solo hablamos de electricidad. Menos energía implica: menos calor generado menor necesidad de refrigeración menores costos operativos menor huella de carbono Por eso la eficiencia energética se ha convertido en un factor estratégico para los hyperscalers (gigantes tecnológicos que poseen y administran infraestructuras de centros de datos masivas a nivel global). ¿Qué diferencia a ARM de x86? A grandes rasgos: x86 utiliza una arquitectura CISC (Complex Instruction Set Computing) , con un conjunto amplio de instrucciones complejas. ARM utiliza una arquitectura RISC (Reduced Instruction Set Computing) , basada en instrucciones más simples y optimizadas. Esto no significa automáticamente que ARM sea “más rápido”. Lo que sí significa es que puede realizar muchas cargas de trabajo consumiendo considerablemente menos energía. En otras palabras: ARM no busca ganar por fuerza bruta. Busca hacer más con menos. ¿Por qué ahora? Hace unos años, ARM estaba asociado principalmente a teléfonos móviles. Hoy la situación es muy
AI 资讯
Defender flujos de agentes contra el OWASP LLM Top 10
Corro varios agentes respaldados por Bedrock en producción: análisis de documentos, emparejamiento de contenido, búsqueda en registros, búsqueda semántica. Esta es una pasada honesta sobre el OWASP Top 10 para aplicaciones LLM desde el lado de la implementación : el código de verdad que defiende cada riesgo y, igual de importante, las categorías donde mi respuesta es "parcial" o "todavía no". Primero el modelo de amenazas Un flujo de agentes es un pipeline: entrada no confiable → prompt → modelo → parseo → actuar. Cada flecha es una superficie de ataque. Antes de cualquier control, la pregunta más útil que me hice fue esta: ¿qué puede HACER de verdad un agente si el modelo está completamente manipulado? Mi respuesta dio forma a todo lo de abajo. Los agentes son mayormente-de-lectura : llaman a un modelo, leen filas acotadas de la base de datos, y escriben resultados de análisis con llave del usuario que pide. Sin shell, sin SQL arbitrario, sin llamada a herramientas. El radio de impacto es chico por construcción, que es el control más barato que existe. TL;DR, estatus honesto OWASP LLM Mi estatus El control LLM10 Consumo sin límite Fuerte Límite de tasa + cortacircuitos de costo mensual + topes de tokens por modelo LLM06 Agencia excesiva Fuerte (por diseño) Sin llamada a herramientas; mayormente-de-lectura; escrituras acotadas a quien llama LLM01 Inyección de prompt Parcial Contenido del usuario enmarcado como DATOS (delimitadores + preámbulo anti-inyección) LLM02 Divulgación de info sensible Parcial Limpieza de PII por regex antes del modelo; exclusiones auditadas LLM05 Manejo inadecuado de salida Parcial Validación de esquema + chequeos de fundamentación + sanear-antes-de-renderizar LLM07 Fuga del system prompt Parcial Registro versionado de prompts + regla anti-eco LLM08 Vector/Embedding N/A (todavía no construido) (nada) AuthN/Z + interruptor de apagado Fuerte Llave interna, gateo por cuota/gama, deshabilitado por agente LLM10 Consumo sin límite: empieza aquí, e
开发者
Lo que aprendí cuando dejé de pensar solo en código y empecé a pensar en arquitectura
Durante mucho tiempo asocié el desarrollo de software con programar funcionalidades: crear entidades, armar controladores, conectar una base de datos, validar formularios y hacer que una aplicación responda correctamente. Sin embargo, durante el Trabajo Final de la asignatura Desarrollo de Aplicaciones Web , entendí que programar es solo una parte del problema. El verdadero desafío aparece antes de escribir código: decidir qué arquitectura conviene, por qué conviene, cuánto cuesta, qué riesgos resuelve y qué complejidad agrega. El trabajo consistió en diseñar un sistema de gestión clínica que comenzaba como un MVP para una única clínica y evolucionaba progresivamente hacia una plataforma SaaS multi-tenant . Aunque fue un proyecto académico, el ejercicio nos obligó a pensar como si estuviéramos tomando decisiones técnicas en un contexto real: con restricciones de negocio, costos, equipo, seguridad, datos sensibles y crecimiento futuro. La principal enseñanza fue: la mejor arquitectura es la que responde mejor al momento del producto . El primer desafío: no sobrediseñar desde el inicio Cuando empezamos a pensar el sistema, la tentación era ir directamente a una arquitectura compleja: microservicios, eventos, colas, Kubernetes, múltiples bases de datos y despliegues independientes. Pero al analizar el escenario inicial, esa decisión no tenía sentido. El sistema comenzaba para una sola clínica, con un presupuesto reducido y con requisitos todavía en etapa de validación. En ese contexto, arrancar con microservicios hubiera agregado más problemas que beneficios: comunicación entre servicios, contratos, versionado, observabilidad distribuida, debugging más difícil y mayor costo de infraestructura. Por eso, una de las decisiones más importantes fue comenzar con una arquitectura en capas , desplegada como un único proceso. Esta elección permitió separar responsabilidades sin asumir desde el principio la complejidad de un sistema distribuido. La capa de presentación se encarg
AI 资讯
Cómo solucionar el error \"Text content does not match server-rendered HTML\" en Next.js
Cómo solucionar el error "Text content does not match server-rendered HTML" en Next.js Este error ocurre cuando el HTML generado en el servidor (SSR) no coincide con el árbol de React que se construye durante la hidratación inicial en el navegador. Es un problema crítico que rompe la experiencia de usuario y puede causar comportamientos impredecibles. Causa raíz En tu caso, el error está relacionado con contenido dinámico que varía entre renderizado del servidor y renderizado del cliente , probablemente por: Uso de Date() o new Date() en el renderizado (ej. fechas de eventos como JUN 9 , JUN 11 , etc.) Uso de typeof window !== 'undefined' o APIs del navegador directamente en el render Metaetiquetas o scripts que modifican el DOM antes de la hidratación (como iOS detectando fechas como enlaces) Configuración incorrecta de librerías CSS-in-JS o Edge/CDN que modifiquen el HTML Solución definitiva (pasos) ✅ Paso 1: Aisla el contenido dinámico con suppressHydrationWarning Si el contenido que varía es intencional (como fechas de eventos), envuelve solo el elemento problemático con suppressHydrationWarning={true} : // app/page.tsx o app/events/page.tsx export default function EventsPage () { const events = [ { name : ' NEXT.JS NIGHTS ' , date : new Date ( ' 2024-06-09 ' ) }, { name : ' AMS ' , date : new Date ( ' 2024-06-11 ' ) }, { name : ' LDN ' , date : new Date ( ' 2024-06-18 ' ) }, ]; return ( < div > < h2 > VIEW EVENTS </ h2 > < ul > { events . map (( event , i ) => ( < li key = { i } > < strong > { event . name } </ strong > { /* ✅ Solo este elemento usa suppressHydrationWarning */ } < time dateTime = { event . date . toISOString () } suppressHydrationWarning > { event . date . toLocaleDateString ( ' en-US ' , { month : ' short ' , day : ' numeric ' }) } </ time > </ li > )) } </ ul > </ div > ); } ⚠️ Importante : suppressHydrationWarning solo funciona en el elemento inmediato, no en hijos. Usa span , time , div , etc., no en contenedores grandes. ✅ Paso 2: Evita Da
AI 资讯
Tipos de errores, Wrapping e Inspección en Go
Tabla de Contenidos Objetivo Restricciones de los Errores Basados en Texto Errores Personalizados en Go Conceptos Clave Implementar e Inspeccionar Errores Casos de Uso Comunes Para no morir en el intento y consejos que no pediste Conclusiones del Tema Objetivo Aprender a diseñar tipos de errores personalizados con metadatos de negocio en Go y a propagarlos correctamente a través del flujo de la aplicación sin perder su tipo ni su información de origen. Restricciones de los Errores Basados en Texto En programas sencillos, el uso de errors.New es perfecto. Sin embargo, en aplicaciones empresariales los errores necesitan transportar datos estructurados. Por ejemplo, si una validación de entrada falla, el frontend no solo quiere saber que "hubo un error", necesita saber qué campo exacto falló (ej. email ) y qué regla se violó (ej. formato inválido ). Si solo devolvemos una cadena de texto, la capa superior de nuestra aplicación tendría que parsear el texto del error con expresiones regulares para extraer los metadatos. Esto es extremadamente ineficiente, propenso a errores de formato y acopla la lógica interna a los mensajes de texto visibles al usuario. Tipos de Errores Comunes en Go Antes de analizar cómo propagar y envolver errores, es fundamental comprender los dos patrones principales que se utilizan en Go: Sentinel Errors : Son variables globales predefinidas que representan un estado de error estático y específico. Se definen a nivel de paquete y se comparan directamente por valor. Ejemplos estándar: io.EOF , sql.ErrNoRows . Creación: Generalmente declarados con errors.New (como var ErrNotFound = errors.New("not found") ). Custom Structs (Errores estructurados personalizados): Son estructuras que implementan la interfaz error y contienen campos adicionales para transportar metadatos dinámicos del fallo en tiempo de ejecución (como códigos de estado o parámetros de entrada). Creación: Un struct personalizado que implementa el método Error() (ej. type ValidationErr