Programador web con IA: cómo la inteligencia artificial transforma el desarrollo
La inteligencia artificial no va a reemplazar al programador web. Pero el programador web que use IA va a reemplazar al que no la use.
En 2026, la IA generativa ha transformado radicalmente cómo desarrollamos aplicaciones web. Desde asistentes de código hasta aplicaciones completas con capacidades inteligentes, la IA es ya ubicua.
En este artículo, exploraré cómo la IA está cambiando el rol del programador web, qué nuevas habilidades requiere, casos de uso reales que ya implemento, y hacia dónde vamos.
La IA como copiloto de desarrollo
El primer impacto: IA como asistente de programación.
GitHub Copilot y alternativas
Cómo funcionan:
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-comment"</span>><span class="hljs-comment">// Escribes comentario o firma de función</span></span>
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-comment"</span>></span>// function calculateShippingCost(<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-comment"</span>></span>// Y Copilot sugiere implementación completa:<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>function<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-title function_"</span>></span>calculateShippingCost<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>(<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-params"</span>></span>
<span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-attr"</span>></span>weight<span class="hljs-tag"></<span class="hljs-name">span</span>></span>: <span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-built_in"</span>></span>number<span class="hljs-tag"></<span class="hljs-name">span</span>></span>,
<span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-attr"</span>></span>destination<span class="hljs-tag"></<span class="hljs-name">span</span>></span>: <span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-built_in"</span>></span>string<span class="hljs-tag"></<span class="hljs-name">span</span>></span>,
<span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-attr"</span>></span>shippingMethod<span class="hljs-tag"></<span class="hljs-name">span</span>></span>: <span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-string"</span>></span><span class="hljs-symbol">&#x27;</span>standard<span class="hljs-symbol">&#x27;</span><span class="hljs-tag"></<span class="hljs-name">span</span>></span> | <span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-string"</span>></span><span class="hljs-symbol">&#x27;</span>express<span class="hljs-symbol">&#x27;</span><span class="hljs-tag"></<span class="hljs-name">span</span>></span> | <span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-string"</span>></span><span class="hljs-symbol">&#x27;</span>overnight<span class="hljs-symbol">&#x27;</span><span class="hljs-tag"></<span class="hljs-name">span</span>></span>
<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>): <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-built_in"</span>></span>number<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> {
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>const<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> baseRate = shippingMethod === <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-string"</span>></span><span class="hljs-symbol">&#x27;</span>standard<span class="hljs-symbol">&#x27;</span><span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> ? <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-number"</span>></span>5<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>
: shippingMethod === <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-string"</span>></span><span class="hljs-symbol">&#x27;</span>express<span class="hljs-symbol">&#x27;</span><span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> ? <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-number"</span>></span>12<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>
: <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-number"</span>></span>25<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>const<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> weightRate = weight * <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-number"</span>></span>0.5<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>const<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> destinationMultiplier =
destination === <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-string"</span>></span><span class="hljs-symbol">&#x27;</span>national<span class="hljs-symbol">&#x27;</span><span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> ? <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-number"</span>></span>1<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>
: destination === <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-string"</span>></span><span class="hljs-symbol">&#x27;</span>europe<span class="hljs-symbol">&#x27;</span><span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> ? <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-number"</span>></span>1.5<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>
: <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-number"</span>></span>2.5<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>return<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> (baseRate + weightRate) * destinationMultiplier
}
Impacto en productividad:
Según mi experiencia con GitHub Copilot:
- +30-40% velocidad en código boilerplate
- +50% velocidad en tests unitarios
- +25% velocidad en funciones comunes
Pero: Requiere revisión crítica. Copilot sugiere, tú decides.
Alternativas actuales:
- GitHub Copilot: El más maduro, integración VSCode perfecta
- Amazon CodeWhisperer: Gratuito para uso individual
- Tabnine: Enfoque en privacidad
- Codeium: Alternativa open source
Mi uso diario:
- Boilerplate: acepto ~80% sugerencias
- Lógica de negocio: acepto ~30-40%
- Tests: acepto ~60-70%
- Documentación: acepto ~50%
Tiempo ahorrado: ~15-20 horas/semana
ChatGPT y Claude como consultores técnicos
Más allá de autocompletado, LLMs como asesores:
Casos de uso diarios:
Debugging complejo
- Pego error + contexto
- LLM sugiere causas probables
- Ahorro: 30min-2h por bug difícil
Arquitectura y patrones
- "¿Cómo estructurar sistema de notificaciones real-time?"
- Recibo opciones: WebSockets, SSE, polling
- Con pros/cons de cada una
Optimización de código
- Pego función lenta
- LLM sugiere mejoras de performance
- Valido con benchmarks
Documentación
- Generar JSDoc a partir de código
- Escribir README completos
- Crear guías de usuario
Limitaciones importantes:
⚠️ Los LLMs alucinan:
- Inventan APIs que no existen
- Citan documentación incorrecta
- Mezclan versiones de librerías
Regla de oro: Siempre verificar sugerencias, especialmente en producción.
Mi workflow:
- Consultar LLM para ideas/opciones
- Validar con documentación oficial
- Testear exhaustivamente antes de integrar
Aplicaciones web con capacidades de IA
El segundo impacto: IA dentro de las aplicaciones.
Chatbots inteligentes
Los chatbots han evolucionado de scripts rígidos a asistentes contextuales:
Antes (2020):
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-comment"</span>><span class="hljs-comment">// Chatbot con if/else</span></span>
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>function<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-title function_"</span>></span>procesarMensaje<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>(<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-params"</span>></span>mensaje<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>) {
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>if<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> (mensaje.<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-title function_"</span>>includes<<span class="hljs-regexp">/span>(<span class="hljs-string">&#x27;horario&#x27;</</span>span>)) {
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>return<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-string"</span>></span><span class="hljs-symbol">&#x27;</span>Abrimos de 9 a 18h<span class="hljs-symbol">&#x27;</span><span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>
}
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">if</span><<span class="hljs-regexp">/span> (mensaje.<span class="hljs-title function_">includes</</span>span>(<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-string"</span>></span><span class="hljs-symbol">&#x27;</span>precio<span class="hljs-symbol">&#x27;</span><span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>)) {
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>return<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-string"</span>></span><span class="hljs-symbol">&#x27;</span>Nuestros precios empiezan en 100€<span class="hljs-symbol">&#x27;</span><span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>
}
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">return</span><<span class="hljs-regexp">/span> <span class="hljs-string">&#x27;No entiendo tu pregunta&#x27;</</span>span>
}
Ahora (2026):
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-comment"</span>><span class="hljs-comment">// Chatbot con GPT-4 y RAG</span></span>
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>import<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> { <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-title class_"</span>></span>ChatOpenAI<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> } <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">from</span><<span class="hljs-regexp">/span> <span class="hljs-string">&#x27;langchain/</span>chat_models&#x27;</span>
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>import<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> { loadQAChain } <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">from</span><<span class="hljs-regexp">/span> <span class="hljs-string">&#x27;langchain/</span>chains&#x27;</span>
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>async<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>function<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-title function_"</span>></span>procesarMensaje<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>(<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-params"</span>></span>
<span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-attr"</span>></span>mensaje<span class="hljs-tag"></<span class="hljs-name">span</span>></span>: <span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-built_in"</span>></span>string<span class="hljs-tag"></<span class="hljs-name">span</span>></span>,
<span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-attr"</span>></span>historial<span class="hljs-tag"></<span class="hljs-name">span</span>></span>: <span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-title class_"</span>></span>Message<span class="hljs-tag"></<span class="hljs-name">span</span>></span>[]
<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>) {
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>const<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> llm = <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>new<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-title class_"</span>></span>ChatOpenAI<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>({
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-attr"</span>></span>modelName<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>: <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-string"</span>></span><span class="hljs-symbol">&#x27;</span>gpt-4<span class="hljs-symbol">&#x27;</span><span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>,
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-attr"</span>></span>temperature<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>: <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-number"</span>></span>0.3<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>
})
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-comment"</span>><span class="hljs-comment">// Buscar info relevante en base de conocimiento</span></span>
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>const<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> context = <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>await<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> vectorStore.<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-title function_"</span>>similaritySearch<<span class="hljs-regexp">/span>(mensaje, <span class="hljs-number">3</</span>span>)
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-comment"</span>><span class="hljs-comment">// Generar respuesta contextual</span></span>
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>const<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> response = <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>await<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> chain.<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-title function_"</span>>call</span>({
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-attr"</span>></span>question<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>: mensaje,
context,
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-attr"</span>></span>chat_history<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>: historial
})
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">return</span><<span class="hljs-regexp">/span> response.<span class="hljs-property">text</</span>span>
}
Diferencia:
- Antes: Solo responde preguntas exactas programadas
- Ahora: Entiende intención, consulta conocimiento, responde naturalmente
He implementado chatbots con IA para:
- Atención al cliente 24/7: Resolución de 70-80% consultas
- Soporte técnico: Búsqueda en documentación
- Ventas conversacionales: Recomendación de productos
- Onboarding de usuarios: Guía interactiva
Coste desarrollo:
- Chatbot tradicional: 2-3 semanas, features limitadas
- Chatbot con IA: 1-2 semanas, capacidades mucho mayores
Sistemas RAG para conocimiento empresarial
RAG (Retrieval Augmented Generation) = LLM + tu información privada
Arquitectura típica:
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-comment"</span>><span class="hljs-comment">// 1. Indexar documentación empresarial</span></span>
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>import<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> { <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-title class_"</span>></span>OpenAIEmbeddings<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> } <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">from</span><<span class="hljs-regexp">/span> <span class="hljs-string">&#x27;langchain/</span>embeddings&#x27;</span>
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>import<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> { <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-title class_"</span>></span>Chroma<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> } <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">from</span><<span class="hljs-regexp">/span> <span class="hljs-string">&#x27;langchain/</span>vectorstores&#x27;</span>
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>async<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>function<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-title function_"</span>></span>indexarDocumentos<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>(<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-params"</span>></span><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-attr"</span>></span>docs<span class="hljs-tag"></<span class="hljs-name">span</span>></span>: <span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-title class_"</span>></span>Document<span class="hljs-tag"></<span class="hljs-name">span</span>></span>[]<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>) {
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>const<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> embeddings = <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>new<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-title class_"</span>></span>OpenAIEmbeddings<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>()
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">const</span><<span class="hljs-regexp">/span> vectorStore = <span class="hljs-keyword">await</</span>span> <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-title class_"</span>></span>Chroma<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>.<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-title function_"</span>>fromDocuments</span>(
docs,
embeddings,
{ <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-attr"</span>></span>collectionName<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>: <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-string"</span>></span><span class="hljs-symbol">&#x27;</span>empresa-docs<span class="hljs-symbol">&#x27;</span><span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> }
)
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">return</span></span> vectorStore
}
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-comment"</span>><span class="hljs-comment">// 2. Consultar con contexto</span></span>
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>async<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>function<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-title function_"</span>></span>preguntarDocumentos<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>(<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-params"</span>></span>
<span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-attr"</span>></span>pregunta<span class="hljs-tag"></<span class="hljs-name">span</span>></span>: <span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-built_in"</span>></span>string<span class="hljs-tag"></<span class="hljs-name">span</span>></span>,
<span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-attr"</span>></span>vectorStore<span class="hljs-tag"></<span class="hljs-name">span</span>></span>: <span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-title class_"</span>></span>Chroma<span class="hljs-tag"></<span class="hljs-name">span</span>></span>
<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>) {
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>const<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> llm = <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>new<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-title class_"</span>></span>ChatOpenAI<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>({ <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-attr"</span>></span>modelName<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>: <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-string"</span>></span><span class="hljs-symbol">&#x27;</span>gpt-4<span class="hljs-symbol">&#x27;</span><span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> })
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-comment"</span>><span class="hljs-comment">// Buscar docs relevantes</span></span>
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>const<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> docsRelevantes = <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>await<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> vectorStore
.<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-title function_"</span>>similaritySearch<<span class="hljs-regexp">/span>(pregunta, <span class="hljs-number">4</</span>span>)
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-comment"</span>><span class="hljs-comment">// LLM responde basándose en docs reales</span></span>
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>const<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> chain = <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-title function_"</span>></span>loadQAChain<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>(llm)
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">const</span><<span class="hljs-regexp">/span> response = <span class="hljs-keyword">await</</span>span> chain.<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-title function_"</span>>call</span>({
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-attr"</span>></span>input_documents<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>: docsRelevantes,
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-attr"</span>></span>question<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>: pregunta
})
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">return</span></span> {
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-attr"</span>></span>respuesta<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>: response.<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-property"</span>>text</span>,
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-attr"</span>></span>fuentes<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>: docsRelevantes.<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-title function_"</span>>map<<span class="hljs-regexp">/span>(<span class="hljs-function"><span class="hljs-params">d</</span>span> =&gt;<<span class="hljs-regexp">/span> d.<span class="hljs-property">metadata</</span>span>.<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-property"</span>>source</span>)
}
}
Casos de uso reales que implemento:
Consultas sobre políticas empresa
- "¿Cuál es nuestra política de devoluciones para productos digitales?"
- Sistema busca en docs, LLM genera respuesta
- Incluye citas de documentos originales
Soporte técnico con manuales
- "¿Cómo configurar integración con Stripe?"
- Consulta documentación interna
- Respuesta paso a paso personalizada
Knowledge base para equipos
- "¿Cómo desplegamos a producción?"
- Busca en wiki, runbooks, tickets cerrados
- Responde con procedimientos actualizados
Análisis de documentos legales
- "¿Qué dice el contrato sobre SLAs?"
- Extrae cláusulas relevantes
- Resume en lenguaje claro
Ventajas vs búsqueda tradicional:
- Búsqueda: Devuelve documentos, tú lees y extraes
- RAG: Devuelve respuesta directa con fuentes
Mis proyectos de sistemas RAG típicos: 10.000-25.000€ según volumen de documentos e integraciones.
Agentes autónomos
El siguiente nivel: sistemas que actúan, no solo responden.
Ejemplo: Agente de investigación de mercado
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">from</span></span> langchain.agents <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">import</span></span> initialize_agent, Tool
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">from</span></span> langchain.llms <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">import</span></span> OpenAI
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-comment"</span>><span class="hljs-comment"># Definir herramientas que el agente puede usar</span></span>
tools = [
Tool(
name=<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-string"</span>>&quot;Google Search&quot;</span>,
func=google_search,
description=<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-string"</span>>&quot;Busca información actualizada en internet&quot;</span>
),
Tool(
name=<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-string"</span>>&quot;Web Scraper&quot;</span>,
func=scrape_website,
description=<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-string"</span>>&quot;Extrae contenido de una URL&quot;</span>
),
Tool(
name=<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-string"</span>>&quot;Database Query&quot;</span>,
func=query_database,
description=<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-string"</span>>&quot;Consulta base de datos de competidores&quot;</span>
)
]
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-comment"</span>><span class="hljs-comment"># Inicializar agente</span></span>
agent = initialize_agent(
tools,
OpenAI(model=<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-string"</span>>&quot;gpt-<span class="hljs-number">4</span>&quot;</span>),
agent=<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-string"</span>>&quot;zero-shot-react-description&quot;</span>
)
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-comment"</span>><span class="hljs-comment"># Ejecutar tarea compleja</span></span>
result = agent.run(
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-string"</span>>&quot;Investiga precios de competidores para producto X &quot;</span>
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-string"</span>>&quot;en mercado español, genera informe comparativo&quot;</span>
)
El agente:
- Planea qué herramientas usar
- Ejecuta búsquedas en Google
- Extrae precios de webs competidores
- Consulta histórico en base de datos
- Genera informe comparativo
Todo autónomamente.
Casos de uso empresariales:
- Investigación de competencia: Precios, features, reviews
- Monitoreo de marca: Menciones, sentimiento
- Análisis de tendencias: Qué buscan usuarios
- Due diligence: Investigación de proveedores/partners
- Content research: Temas trending, keywords
He desarrollado agentes de IA para:
- Automatizar research de mercado (ahorro 20h/semana humanas)
- Monitorear menciones de marca 24/7
- Analizar feedback de clientes en tiempo real
Análisis y generación de contenido
Procesamiento de Lenguaje Natural aplicado:
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-comment"</span>><span class="hljs-comment">// Clasificación automática de tickets de soporte</span></span>
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>import<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> { <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-title class_"</span>></span>OpenAI<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> } <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">from</span><<span class="hljs-regexp">/span> <span class="hljs-string">&#x27;openai&#x27;</</span>span>
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>async<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>function<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-title function_"</span>></span>clasificarTicket<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>(<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-params"</span>></span><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-attr"</span>></span>contenido<span class="hljs-tag"></<span class="hljs-name">span</span>></span>: <span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-built_in"</span>></span>string<span class="hljs-tag"></<span class="hljs-name">span</span>></span><span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>) {
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>const<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> completion = <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>await<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> openai.<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-property"</span>>chat<<span class="hljs-regexp">/span>.<span class="hljs-property">completions</</span>span>.<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-title function_"</span>>create</span>({
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-attr"</span>></span>model<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>: <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-string"</span>></span><span class="hljs-symbol">&#x27;</span>gpt-4<span class="hljs-symbol">&#x27;</span><span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>,
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-attr"</span>></span>messages<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>: [
{
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-attr"</span>></span>role<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>: <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-string"</span>></span><span class="hljs-symbol">&#x27;</span>system<span class="hljs-symbol">&#x27;</span><span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>,
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-attr"</span>></span>content<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>: <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-string"</span>></span>`Clasifica tickets en categorías:
- bug_critico
- bug_menor
- solicitud_feature
- pregunta_uso
- queja_comercial
Responde solo con la categoría.`<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>
},
{
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-attr"</span>></span>role<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>: <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-string"</span>></span><span class="hljs-symbol">&#x27;</span>user<span class="hljs-symbol">&#x27;</span><span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>,
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-attr"</span>></span>content<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>: contenido
}
],
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-attr"</span>></span>temperature<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>: <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-number"</span>></span>0<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>
})
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">return</span><<span class="hljs-regexp">/span> completion.<span class="hljs-property">choices</</span>span>[<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-number"</span>></span>0<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>].<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-property"</span>>message<<span class="hljs-regexp">/span>.<span class="hljs-property">content</</span>span>
}
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-comment"</span>><span class="hljs-comment">// Usar en pipeline de soporte</span></span>
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>async<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>function<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-title function_"</span>></span>procesarTicket<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>(<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-params"</span>></span><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-attr"</span>></span>ticket<span class="hljs-tag"></<span class="hljs-name">span</span>></span>: <span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-title class_"</span>></span>Ticket<span class="hljs-tag"></<span class="hljs-name">span</span>></span><span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>) {
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>const<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> categoria = <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>await<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-title function_"</span>></span>clasificarTicket<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>(ticket.<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-property"</span>>contenido</span>)
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-comment"</span>><span class="hljs-comment">// Enrutar automáticamente</span></span>
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>if<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> (categoria === <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-string"</span>></span><span class="hljs-symbol">&#x27;</span>bug_critico<span class="hljs-symbol">&#x27;</span><span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>) {
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>await<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-title function_"</span>></span>notificarEquipoUrgente<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>(ticket)
} <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">else</span><<span class="hljs-regexp">/span> <span class="hljs-keyword">if</</span>span> (categoria === <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-string"</span>></span><span class="hljs-symbol">&#x27;</span>pregunta_uso<span class="hljs-symbol">&#x27;</span><span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>) {
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>await<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-title function_"</span>></span>intentarRespuestaAutomatica<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>(ticket)
}
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">await</span><<span class="hljs-regexp">/span> ticket.<span class="hljs-title function_">update</</span>span>({ categoria })
}
Otros casos que implemento:
- Análisis de sentimiento en reviews/comentarios
- Extracción de entidades (nombres, fechas, productos mencionados)
- Resumen automático de documentos largos
- Traducción manteniendo contexto técnico
- Generación de descripciones de productos para SEO
Ver mi portfolio completo de soluciones NLP.
Computer Vision para aplicaciones web
Visión artificial integrada:
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">from</span></span> openai <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">import</span></span> OpenAI
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-comment"</span>><span class="hljs-comment"># Análisis de imágenes con GPT-4 Vision</span></span>
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">def</span></span> <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-title function_"</span>>analizar_imagen</span>(<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-params"</span>>imagen_url: <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-built_in"</span>><span class="hljs-built_in">str</span></span></span>) -&gt; <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-built_in"</span>><span class="hljs-built_in">dict</span></span>:
response = client.chat.completions.create(
model=<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-string"</span>>&quot;gpt-<span class="hljs-number">4</span>-vision-preview&quot;</span>,
messages=[
{
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-string"</span>>&quot;role&quot;</span>: <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-string"</span>>&quot;user&quot;</span>,
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-string"</span>>&quot;content&quot;</span>: [
{
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-string"</span>>&quot;<span class="hljs-built_in">type</span>&quot;</span>: <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-string"</span>>&quot;text&quot;</span>,
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-string"</span>>&quot;text&quot;</span>: <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-string"</span>>&quot;Describe detalladamente esta imagen&quot;</span>
},
{
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-string"</span>>&quot;<span class="hljs-built_in">type</span>&quot;</span>: <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-string"</span>>&quot;image_url&quot;</span>,
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-string"</span>>&quot;image_url&quot;</span>: {<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-string"</span>>&quot;url&quot;</span>: imagen_url}
}
]
}
]
)
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">return</span></span> response.choices[<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-number"</span>><span class="hljs-number">0</span></span>].message.content
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-comment"</span>><span class="hljs-comment"># Casos de uso</span></span>
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">def</span></span> <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-title function_"</span>>moderacion_contenido</span>(<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-params"</span>>imagen_url: <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-built_in"</span>><span class="hljs-built_in">str</span></span></span>) -&gt; <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-built_in"</span>><span class="hljs-built_in">bool</span></span>:
descripcion = analizar_imagen(imagen_url)
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-comment"</span>><span class="hljs-comment"># Detectar contenido inapropiado</span></span>
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">return</span></span> <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">not</span></span> <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-built_in"</span>><span class="hljs-built_in">any</span></span>(word <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">in</span></span> descripcion.lower()
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">for</span></span> word <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">in</span></span> [<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-string"</span>>&<span class="hljs-comment">#x27;violencia&#x27;</span>, <span class="hljs-string">&#x27;desnudo&#x27;</span>, <span class="hljs-string">&#x27;inapropiado&#x27;</span>])</span>
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">def</span></span> <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-title function_"</span>>categorizar_producto</span>(<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-params"</span>>imagen_url: <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-built_in"</span>><span class="hljs-built_in">str</span></span></span>) -&gt; <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-built_in"</span>><span class="hljs-built_in">str</span></span>:
descripcion = analizar_imagen(imagen_url)
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-comment"</span>><span class="hljs-comment"># Clasificar automáticamente</span></span>
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-comment"</span>><span class="hljs-comment"># (ropa, electrónica, hogar, etc.)</span></span>
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">return</span></span> clasificar_por_descripcion(descripcion)
Aplicaciones reales:
Ecommerce
- Categorización automática de productos subidos
- Detección de calidad de fotos
- Búsqueda por similitud visual
Moderación de contenido
- Filtrar imágenes inapropiadas automáticamente
- Detectar spam visual
- Verificar guidelines de comunidad
Accesibilidad
- Generar alt text automático para imágenes
- Describir contenido visual para lectores de pantalla
Control de calidad
- Detectar productos defectuosos en fotos
- Verificar packaging correcto
- Validar instalaciones
Portfolio completo: soluciones de Computer Vision.
Nuevas habilidades del programador web
Para aprovechar IA, el programador web necesita nuevas skills:
1. Prompt Engineering
Saber comunicarse con LLMs es crítico:
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-comment"</span>><span class="hljs-comment">// Prompt malo (resultados inconsistentes)</span></span>
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>const<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> prompt = <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-string"</span>></span><span class="hljs-symbol">&quot;</span>Resume este texto<span class="hljs-symbol">&quot;</span><span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-comment"</span>></span>// Prompt bueno (resultados consistentes)<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>const<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> prompt = <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-string"</span>></span>`
Resume el siguiente texto en exactamente 3 puntos clave.
Cada punto debe:
- Ser una oración completa
- Tener máximo 20 palabras
- Empezar con <span class="hljs-symbol">&quot;</span>•<span class="hljs-symbol">&quot;</span>
Texto:
<span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-subst"</span>></span>${texto}<span class="hljs-tag"></<span class="hljs-name">span</span>></span>
Resume:
`<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>
Técnicas que todo programador web debe conocer:
- Few-shot learning: Dar ejemplos de input/output
- Chain-of-thought: Pedir razonamiento paso a paso
- Role prompting: "Actúa como experto en X"
- Constraints: Especificar formato, longitud, estilo
- Temperature tuning: Controlar creatividad vs consistencia
2. Vector Databases
Trabajar con embeddings y búsqueda semántica:
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">import</span><<span class="hljs-regexp">/span> { <span class="hljs-title class_">OpenAIEmbeddings</</span>span> } <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">from</span><<span class="hljs-regexp">/span> <span class="hljs-string">&#x27;langchain/</span>embeddings&#x27;</span>
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>import<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> { <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-title class_"</span>></span>PineconeStore<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> } <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">from</span><<span class="hljs-regexp">/span> <span class="hljs-string">&#x27;langchain/</span>vectorstores&#x27;</span>
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-comment"</span>></span>// Crear embeddings de texto<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>const<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> embeddings = <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>new<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-title class_"</span>></span>OpenAIEmbeddings<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>()
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">const</span><<span class="hljs-regexp">/span> textoVector = <span class="hljs-keyword">await</</span>span> embeddings.<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-title function_"</span>>embedQuery</span>(
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-string"</span>></span><span class="hljs-symbol">&quot;</span>Programador web especializado en Next.js<span class="hljs-symbol">&quot;</span><span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>
)
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-comment"</span>><span class="hljs-comment">// Resultado: [0.023, -0.891, 0.445, ...] // 1536 dimensiones</span></span>
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-comment"</span>></span>// Buscar similares<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>const<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> resultados = <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>await<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> pinecone.<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-title function_"</span>>query</span>({
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-attr"</span>></span>vector<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>: textoVector,
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-attr"</span>></span>topK<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>: <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-number"</span>></span>5<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>,
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-attr"</span>></span>includeMetadata<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>: <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-literal"</span>></span>true<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>
})
Bases de datos vectoriales:
- Pinecone: Managed, fácil de usar
- Weaviate: Open source, potente
- Chroma: Lightweight, buena para desarrollo
- Qdrant: Alto rendimiento
3. LangChain y frameworks de IA
Orquestar aplicaciones complejas con LLMs:
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">import</span><<span class="hljs-regexp">/span> { <span class="hljs-title class_">PromptTemplate</</span>span> } <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">from</span><<span class="hljs-regexp">/span> <span class="hljs-string">&#x27;langchain/</span>prompts&#x27;</span>
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>import<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> { <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-title class_"</span>></span>LLMChain<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> } <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">from</span><<span class="hljs-regexp">/span> <span class="hljs-string">&#x27;langchain/</span>chains&#x27;</span>
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-comment"</span>></span>// Template reutilizable<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>const<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> template = <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>new<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-title class_"</span>></span>PromptTemplate<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>({
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-attr"</span>></span>template<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>: <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-string"</span>></span>`
Eres un asistente de {rol}.
Contexto: {contexto}
Pregunta del usuario: {pregunta}
Proporciona una respuesta {tono}.
`<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>,
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-attr"</span>></span>inputVariables<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>: [<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-string"</span>></span><span class="hljs-symbol">&#x27;</span>rol<span class="hljs-symbol">&#x27;</span><span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>, <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-string"</span>></span><span class="hljs-symbol">&#x27;</span>contexto<span class="hljs-symbol">&#x27;</span><span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>, <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-string"</span>></span><span class="hljs-symbol">&#x27;</span>pregunta<span class="hljs-symbol">&#x27;</span><span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>, <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-string"</span>></span><span class="hljs-symbol">&#x27;</span>tono<span class="hljs-symbol">&#x27;</span><span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>]
})
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-comment"</span>><span class="hljs-comment">// Chain que usa el template</span></span>
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>const<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> chain = <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>new<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-title class_"</span>></span>LLMChain<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>({
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-attr"</span>></span>llm<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>: <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>new<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-title class_"</span>></span>ChatOpenAI<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>(),
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-attr"</span>></span>prompt<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>: template
})
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-comment"</span>><span class="hljs-comment">// Ejecutar</span></span>
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>const<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> response = <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-keyword"</span>></span>await<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span> chain.<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-title function_"</span>>call</span>({
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-attr"</span>></span>rol<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>: <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-string"</span>></span><span class="hljs-symbol">&#x27;</span>programador web senior<span class="hljs-symbol">&#x27;</span><span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>,
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-attr"</span>></span>contexto<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>: <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-string"</span>></span><span class="hljs-symbol">&#x27;</span>El usuario está construyendo un ecommerce<span class="hljs-symbol">&#x27;</span><span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>,
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-attr"</span>></span>pregunta<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>: <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-string"</span>></span><span class="hljs-symbol">&#x27;</span>¿Qué stack recomiendas?<span class="hljs-symbol">&#x27;</span><span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>,
<span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-attr"</span>></span>tono<span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>: <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hljs-string"</span>></span><span class="hljs-symbol">&#x27;</span>profesional pero accesible<span class="hljs-symbol">&#x27;</span><span class="hljs-tag"></<span class="hljs-name">span</span>></span></span>
})
Por qué LangChain:
- Abstracts complejidad de llamadas a LLMs
- Chains para workflows complejos
- Agents para tareas autónomas
- Memoria para conversaciones stateful
- Integraciones con 50+ servicios
4. MLOps y deployment de modelos
Llevar modelos a producción de forma confiable:
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-comment"</span>><span class="hljs-comment"># Ejemplo: Fine-tuning de modelo custom</span></span>
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">from</span></span> openai <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-keyword"</span>><span class="hljs-keyword">import</span></span> OpenAI
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-comment"</span>><span class="hljs-comment"># 1. Preparar dataset</span></span>
training_data = [
{
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-string"</span>>&quot;messages&quot;</span>: [
{<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-string"</span>>&quot;role&quot;</span>: <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-string"</span>>&quot;system&quot;</span>, <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-string"</span>>&quot;content&quot;</span>: <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-string"</span>>&quot;Clasificador de urgencia&quot;</span>},
{<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-string"</span>>&quot;role&quot;</span>: <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-string"</span>>&quot;user&quot;</span>, <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-string"</span>>&quot;content&quot;</span>: <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-string"</span>>&quot;El sistema está caído&quot;</span>},
{<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-string"</span>>&quot;role&quot;</span>: <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-string"</span>>&quot;assistant&quot;</span>, <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-string"</span>>&quot;content&quot;</span>: <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-string"</span>>&quot;URGENTE&quot;</span>}
]
},
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-comment"</span>><span class="hljs-comment"># ... más ejemplos</span></span>
]
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-comment"</span>><span class="hljs-comment"># 2. Subir dataset</span></span>
file = client.files.create(
file=<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-built_in"</span>><span class="hljs-built_in">open</span></span>(<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-string"</span>>&quot;training_data.jsonl&quot;</span>, <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-string"</span>>&quot;rb&quot;</span>),
purpose=<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-string"</span>>&quot;fine-tune&quot;</span>
)
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-comment"</span>><span class="hljs-comment"># 3. Fine-tune</span></span>
job = client.fine_tuning.jobs.create(
training_file=file.<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-built_in"</span>><span class="hljs-built_in">id</span></span>,
model=<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-string"</span>>&quot;gpt-<span class="hljs-number">3.5</span>-turbo&quot;</span>
)
<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-comment"</span>><span class="hljs-comment"># 4. Usar modelo custom</span></span>
completion = client.chat.completions.create(
model=job.fine_tuned_model,
messages=[
{<span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-string"</span>>&quot;role&quot;</span>: <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-string"</span>>&quot;user&quot;</span>, <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-string"</span>>&quot;content&quot;</span>: <span <span class="hljs-keyword">class</span>=<span class="hljs-string">"hljs-string"</span>>&quot;La app va lenta&quot;</span>}
]
)
Aspectos clave de MLOps:
- Versionado de modelos: Tracking de experimentos
- Monitoreo: Accuracy, latencia, costes
- A/B testing: Comparar modelos en producción
- Rollback: Volver a versión anterior si necesario
- Caching: Reducir llamadas redundantes a APIs
Portfolio completo: servicios MLOps.
Costes y ROI de IA en desarrollo web
¿Vale la pena económicamente?
Costes de APIs de IA
OpenAI GPT-4 (enero 2026):
- Input: $0.03 / 1K tokens (~750 palabras)
- Output: $0.06 / 1K tokens
Ejemplo real: Chatbot atención cliente
- 1.000 conversaciones/día
- ~500 tokens por conversación (entrada + salida)
- Coste: $25-30/día = $750-900/mes
Alternativa humana:
- 1 agente humano: 2.000€/mes
- Cubre ~500 conversaciones/día en 8h
- Para 1.000 conversaciones: 2 agentes = 4.000€/mes
Ahorro: ~3.000€/mes con chatbot IA
Costes de desarrollo
Chatbot tradicional vs IA:
| Aspecto | Tradicional | Con IA |
|---|---|---|
| Desarrollo inicial | 3-4 semanas | 1-2 semanas |
| Coste desarrollo | 6.000-10.000€ | 4.000-8.000€ |
| Features | Limitadas | Amplias |
| Mantenimiento | Alto (agregar respuestas) | Bajo (solo ajustar prompts) |
ROI típico: 3-6 meses para recuperar inversión.
Productividad del programador web
Mi experiencia personal con GitHub Copilot:
- Coste: $10/mes (despreciable)
- Ahorro tiempo: 15-20h/mes
- Equivale a: 3-5 días laborables/mes
- ROI: 150-200x el coste
No usar IA en 2026 = competir con una mano atada.
El futuro: hacia dónde vamos
Predicciones para 2027-2030
1. IA como junior developer
En 2-3 años, los LLMs podrán:
- Implementar features completas desde especificación
- Escribir tests automáticamente
- Refactorizar código legacy
- Documentar exhaustivamente
Rol del programador web evolucionará a:
- Arquitecto de sistemas
- Reviewer de código generado por IA
- Product manager técnico
- Prompt engineer especializado
2. No-code/low-code potenciado por IA
- Describir aplicación en lenguaje natural
- IA genera código completo
- Programador solo ajusta y personaliza
Esto eliminará: Código boilerplate tedioso Esto NO eliminará: Necesidad de entender arquitectura, testing, security
3. Aplicaciones 100% conversacionales
- Interfaces naturales (voz + texto)
- Apps que entienden contexto completo
- "Crea informe de ventas del último trimestre" → hecho
- Programador web debe diseñar estas experiencias
4. IA especializada por dominio
- Modelos fine-tuned para ecommerce, healthcare, finanzas
- No programadores web generalistas
- SÍ programadores web + expertos dominio + IA
Habilidades que seguirán siendo críticas
Lo que IA NO reemplazará:
✅ Entender el negocio del cliente
- IA no sabe cuáles son tus objetivos reales
- Traducir necesidades de negocio a specs técnicas
✅ Arquitectura de sistemas
- Decisiones de escalabilidad
- Trade-offs de tecnología
- Patrones para problemas complejos
✅ Seguridad y privacidad
- Auditar código para vulnerabilidades
- Implementar security best practices
- Cumplimiento legal (GDPR, etc.)
✅ Testing y calidad
- Diseñar estrategia de tests
- Casos edge que IA no considera
- Refactoring estructural
✅ Empatía y comunicación
- Entender frustración de usuario
- Explicar decisiones técnicas a no técnicos
- Gestionar expectativas
El mejor programador web del futuro:
- Domina fundamentos (algoritmos, arquitectura, patterns)
- Usa IA para acelerar ejecución
- Enfoca su tiempo en problemas complejos y strategy
Mi enfoque como programador web + IA
Combino 33 años de experiencia con IA moderna:
Qué uso IA para:
- ✅ Código boilerplate (tests, types, migrations)
- ✅ Documentación inicial
- ✅ Sugerencias de optimización
- ✅ Research de tecnologías
Qué hago personalmente siempre:
- ✅ Arquitectura de sistemas
- ✅ Decisiones técnicas críticas
- ✅ Code review exhaustivo
- ✅ Security audit
- ✅ Tests de integración y E2E
Resultado: +40% productividad sin sacrificar calidad.
Servicios que ofrezco con IA:
- Sistemas RAG para knowledge bases
- Chatbots inteligentes para atención cliente
- Agentes autónomos para automatización
- Integración de APIs de IA
- Computer Vision aplicada
- NLP para análisis de texto
- MLOps para modelos en producción
- Consultoría de arquitecturas IA
Garantía: TDD obligatorio, código documentado, garantía de por vida.
Conclusión: adaptarse o quedarse atrás
La IA no va a eliminar al programador web. Va a:
- Eliminar tareas tediosas (boilerplate, documentación básica)
- Elevar el nivel de competencia requerido
- Permitir crear aplicaciones más sofisticadas con menos tiempo
- Democratizar capacidades antes solo en empresas grandes
El programador web que prospera en 2026:
- Domina fundamentos sólidos
- Abraza IA como herramienta, no amenaza
- Se especializa en integrar IA en aplicaciones reales
- Entiende límites y capacidades de LLMs
- Nunca deja de aprender
Lo que no cambia:
- Necesidad de entender el negocio
- Importancia de arquitectura sólida
- Testing y calidad no negociables
- Comunicación y empatía con clientes
Con 33 años desarrollando, he visto docenas de "revoluciones tecnológicas". La IA es real, pero no cambia los principios fundamentales del buen desarrollo.
¿Quieres integrar IA en tu negocio? Cuéntame tu caso de uso y recibe:
- Análisis de viabilidad
- Propuesta técnica
- Estimación de ROI
- Presupuesto detallado
Todo en menos de 24 horas.
Jordi Morillo - Programador Web + AI Engineering | 33 años de experiencia | Portfolio completo de IA