<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: PyramidBuilder</title>
    <description>The latest articles on DEV Community by PyramidBuilder (@pyramidbuilder).</description>
    <link>https://dev.to/pyramidbuilder</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F572434%2F53529801-39c5-4a8b-9c39-125475fe7fc7.png</url>
      <title>DEV Community: PyramidBuilder</title>
      <link>https://dev.to/pyramidbuilder</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pyramidbuilder"/>
    <language>en</language>
    <item>
      <title>El secreto para no saturar el contexto de tu IA: El patrón de agentes en capas</title>
      <dc:creator>PyramidBuilder</dc:creator>
      <pubDate>Tue, 10 Nov 2026 08:44:45 +0000</pubDate>
      <link>https://dev.to/pyramidbuilder/como-ahorrar-tokens-en-opencode-2pb2</link>
      <guid>https://dev.to/pyramidbuilder/como-ahorrar-tokens-en-opencode-2pb2</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;La imagen de portada pertenece a &lt;a href="https://unsplash.com/es/@jonakoh" rel="noopener noreferrer"&gt;jonakoh_&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Si como yo, has utilizado la suscripción de Opencode &lt;a href="https://opencode.ai/console/go" rel="noopener noreferrer"&gt;OpencodeGo&lt;/a&gt; quizás te cueste llegar a fin de mes con los tokens que se ofrecen.&lt;/p&gt;

&lt;p&gt;Tras un año usando Opencode te puedo decir que la solución no está en los prompts, sino en la forma en que implementamos distintos patrones arquitecturales para hacer el trabajo. Podemos expresar estos patrones haciendo uso de las capacidades de definir &lt;a href="https://opencode.ai/docs/agents/" rel="noopener noreferrer"&gt;agentes&lt;/a&gt; dentro de un espacio de trabajo con OpenCode. Este feature desata el verdadero potencial de la herramienta.&amp;nbsp;&lt;/p&gt;

&lt;p&gt;Hoy te enseñare el primer patrón que he descubierto haciendo utilización de los agentes mediante la creación de un tablero Kanban para demostrar su implementación.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzyepsujs9x6mukikmjy5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzyepsujs9x6mukikmjy5.png" alt="Tablero Kanban con dos columnas" width="800" height="694"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Tipos de agentes en Opencode
&lt;/h2&gt;

&lt;p&gt;En Opencode tenemos dos tipos de agentes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Primarios: Son los agentes a los que se puede acceder desde la caja de interacción de la ventana principal de Opencode (shift+tab).&lt;strong&gt;build&lt;/strong&gt; y &lt;strong&gt;plan&lt;/strong&gt; son agentes primarios.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sub-agentes: Son agentes que pueden ser invocados por los agentes primarios. El agente &lt;strong&gt;general&lt;/strong&gt; y &lt;strong&gt;explore&lt;/strong&gt; subagentes.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Si en nuestro proyecto creamos una carpeta llamada &lt;code&gt;.opencode&lt;/code&gt; con una sub-carpeta llamada &lt;code&gt;agents&lt;/code&gt; podemos definir tanto agentes primarios como secundarios en nuestro proyecto.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layered Agent Pattern
&lt;/h2&gt;

&lt;p&gt;Primero visualicemos su forma mas general antes de ir a la implementación:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F31hszjll9hq6nj45dbrz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F31hszjll9hq6nj45dbrz.png" alt="Generalización del Patrón Layered Agent Pattern" width="442" height="162"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;En este caso vamos a hacer tenemos un esquema lineal para abrir la mente sobre la utilización de estos agentes, de a poco iremos añadiendo mas complejidad en futuras entregas.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;El agente primario es el orquestador, que funciona como un bus principal donde está todo el historial de cambios del proyecto. Como es un bus principal, el objetivo es mantenerlo limpio con un contexto sumamente acotado y que pueda tener todos los mensajes de principio a fin sin necesidad de compactar ni de crear nuevas conversaciones, como se ve en la imágen:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgc09v60rczlpluxjccu3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgc09v60rczlpluxjccu3.png" alt="Orquestador al final del proyecto, solo se ha utilizado un 5% del contexto" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Los subagentes tienen contextos vacíos al comienzo de cada petición, esto permite que la atención del modelo no se diluya.&amp;nbsp;&lt;/p&gt;

&lt;p&gt;Otra cosa fundamental es acotar bien las restricciones de los agentes, esto permitirá utilizar menos tokens y reducir la incertidumbre de los agentes, permitiendo que tengan menos libertad y opciones para realizar, esto permitirá que el modelo divage menos se centre en acabar la taréa&lt;/p&gt;

&lt;h2&gt;
  
  
  FastKanban
&lt;/h2&gt;

&lt;p&gt;El proyecto a desarrollar es un proyecto de juguete diseñado para este blog, que es un Kanban que permite crear proyectos y cada proyecto tiene su propia pizarra Kanban. Puedes definir distintas columnas y también arrastrar notas de una columna a otra, es bastante simple para no saturar el blog y poder completarlo en pocos prompts.&lt;/p&gt;

&lt;p&gt;La definición de los agentes depende del proyecto a desarrollar, no existe una formula, es parte de la ingeniería del proyecto. Para este proyecto decidí usar el siguiente Stack Tecnologico:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Next.JS: Framework web fullstack.&lt;/li&gt;
&lt;li&gt;Sqlite: Base de datos en un archivo.&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Estas decisiones fueron tomadas para facilitar el proceso de creación.&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ft9o3a4ih69l4actq42br.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ft9o3a4ih69l4actq42br.png" alt="Arquitectura de agentes para FastKanban" width="762" height="182"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;La carpeta de mi proyecto tiene los siguiente contenidos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;.
└── .opencode
&amp;nbsp; &amp;nbsp; └── agents
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ├── auditor.md
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ├── backend.md
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ├── database.md
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ├── frontend.md
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ├── integrador.md
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ├── orchestrator.md
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; └── qa.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Los contenidos de cada archivo son:&lt;/p&gt;

&lt;p&gt;auditor.md&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;---
description: "Audita el código buscando antipatrones y fallos de arquitectura. Solo lectura."
mode: subagent
steps: 8
permissions:
&amp;nbsp; - action: "*"
&amp;nbsp; &amp;nbsp; resource: "*"
&amp;nbsp; &amp;nbsp; effect: deny
&amp;nbsp; - action: read
&amp;nbsp; &amp;nbsp; resource: "*"
&amp;nbsp; &amp;nbsp; effect: allow
&amp;nbsp; - action: shell
&amp;nbsp; &amp;nbsp; resource: "git diff*"
&amp;nbsp; &amp;nbsp; effect: allow
---

Eres el auditor de calidad.

OBJETIVO
Detectar código duplicado, funciones huérfanas o antipatrones mediante &lt;span class="sb"&gt;`git diff`&lt;/span&gt;.

FORMATO DE SALIDA (máximo 12 líneas)
&lt;span class="sb"&gt;`ruta:línea severidad hallazgo`&lt;/span&gt; (ordenado por alta, media, baja). Si no hay fallos: &lt;span class="sb"&gt;`OK`&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Como podemos observar los permisos son limitados, primero se deniegan todas las acciones, para luego definir las acciones permitidas. En este caso el auditor puede leer archivos pero no ejecutar comandos de shell libremente.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;backend.md&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;---
description: Implementa rutas de API y lógica de servidor en Next.js.
mode: subagent
steps: 8
permissions:
&amp;nbsp; - action: "*"
&amp;nbsp; &amp;nbsp; resource: "*"
&amp;nbsp; &amp;nbsp; effect: deny
&amp;nbsp; - action: read
&amp;nbsp; &amp;nbsp; resource: "*"
&amp;nbsp; &amp;nbsp; effect: allow
&amp;nbsp; - action: edit
&amp;nbsp; &amp;nbsp; resource: "*"
&amp;nbsp; &amp;nbsp; effect: allow
&amp;nbsp; - action: glob
&amp;nbsp; &amp;nbsp; resource: "*"
&amp;nbsp; &amp;nbsp; effect: allow
---

Eres el desarrollador backend de Next.js.

OBJETIVO
Implementar los endpoints (API Routes del App Router) requeridos por el orquestador.

REGLAS
&lt;span class="k"&gt;- &lt;/span&gt;Cambios mínimos. Limítate a la carpeta &lt;span class="sb"&gt;`src/app/api/`&lt;/span&gt;.
&lt;span class="k"&gt;- &lt;/span&gt;Conéctate limpiamente con Prisma. No edites componentes gráficos (frontend).

FORMATO DE SALIDA (máximo 20 líneas)
&lt;span class="k"&gt;- &lt;/span&gt;Archivos tocados (rutas).
&lt;span class="k"&gt;- &lt;/span&gt;Endpoints implementados.
&lt;span class="k"&gt;- &lt;/span&gt;Bloqueos o decisiones pendientes.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Aquí debemos ser mas permisivos para que el agente pueda trabajar&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;database.md&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;---
description: Crea esquemas de base de datos y migraciones con Prisma y SQLite.
mode: subagent
steps: 8
permissions:
&amp;nbsp; - action: "*"
&amp;nbsp; &amp;nbsp; resource: "*"
&amp;nbsp; &amp;nbsp; effect: deny
&amp;nbsp; - action: read
&amp;nbsp; &amp;nbsp; resource: "*"
&amp;nbsp; &amp;nbsp; effect: allow
&amp;nbsp; - action: edit
&amp;nbsp; &amp;nbsp; resource: "*"
&amp;nbsp; &amp;nbsp; effect: allow
&amp;nbsp; - action: glob
&amp;nbsp; &amp;nbsp; resource: "*"
&amp;nbsp; &amp;nbsp; effect: allow
&amp;nbsp; - action: shell
&amp;nbsp; &amp;nbsp; resource: "*"
&amp;nbsp; &amp;nbsp; effect: allow
---

Eres el especialista en base de datos.

OBJETIVO
Implementar esquemas en &lt;span class="sb"&gt;`prisma/schema.prisma`&lt;/span&gt; y funciones con SQLite mediante Prisma.

REGLAS
&lt;span class="k"&gt;- &lt;/span&gt;Cambios mínimos. No toques archivos de UI ni rutas de API.
&lt;span class="k"&gt;- &lt;/span&gt;Motor: SQLite. ORM: Prisma.

FORMATO DE SALIDA (máximo 20 líneas)
&lt;span class="k"&gt;- &lt;/span&gt;Archivos tocados (rutas).
&lt;span class="k"&gt;- &lt;/span&gt;Comandos ejecutados y resultado (OK/FALLO).
&lt;span class="k"&gt;- &lt;/span&gt;Decisiones o bloqueos.
No vuelques código completo en la respuesta.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;frontend.md&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;---
description: Implementa componentes y páginas de la interfaz en Next.js y Tailwind CSS.
mode: subagent
steps: 8
permissions:
&amp;nbsp; - action: "*"
&amp;nbsp; &amp;nbsp; resource: "*"
&amp;nbsp; &amp;nbsp; effect: deny
&amp;nbsp; - action: read
&amp;nbsp; &amp;nbsp; resource: "*"
&amp;nbsp; &amp;nbsp; effect: allow
&amp;nbsp; - action: edit
&amp;nbsp; &amp;nbsp; resource: "*"
&amp;nbsp; &amp;nbsp; effect: allow
&amp;nbsp; - action: glob
&amp;nbsp; &amp;nbsp; resource: "*"
&amp;nbsp; &amp;nbsp; effect: allow
---

Eres el desarrollador frontend.

OBJETIVO
Implementar vistas y componentes en Next.js utilizando Tailwind CSS.

REGLAS
&lt;span class="k"&gt;- &lt;/span&gt;Cambios mínimos. Limítate a &lt;span class="sb"&gt;`src/app/`&lt;/span&gt; (vistas y componentes visuales).
&lt;span class="k"&gt;- &lt;/span&gt;No modifiques esquemas de base de datos ni lógica de servidor interna.

FORMATO DE SALIDA (máximo 20 líneas)
&lt;span class="k"&gt;- &lt;/span&gt;Archivos tocados (rutas).
&lt;span class="k"&gt;- &lt;/span&gt;Componentes creados o modificados.
&lt;span class="k"&gt;- &lt;/span&gt;Bloqueos o decisiones pendientes.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;---
description: Ejecuta pruebas, typecheck y compilación del proyecto Next.js. Solo lectura.
mode: subagent
steps: 10
permissions:
&amp;nbsp; - action: "*"
&amp;nbsp; &amp;nbsp; resource: "*"
&amp;nbsp; &amp;nbsp; effect: deny
&amp;nbsp; - action: read
&amp;nbsp; &amp;nbsp; resource: "*"
&amp;nbsp; &amp;nbsp; effect: allow
&amp;nbsp; - action: glob
&amp;nbsp; &amp;nbsp; resource: "*"
&amp;nbsp; &amp;nbsp; effect: allow
&amp;nbsp; - action: shell
&amp;nbsp; &amp;nbsp; resource: "npm run *"
&amp;nbsp; &amp;nbsp; effect: allow
&amp;nbsp; - action: shell
&amp;nbsp; &amp;nbsp; resource: "npx tsc *"
&amp;nbsp; &amp;nbsp; effect: allow
&amp;nbsp; - action: shell
&amp;nbsp; &amp;nbsp; resource: "npx vitest *"
&amp;nbsp; &amp;nbsp; effect: allow
---

Eres QA del proyecto.

OBJETIVO
Verificar la compilación, tipos y pruebas del código sin alterarlo (solo lectura).

FORMATO DE SALIDA (máximo 15 líneas)
- Comando ejecutado y resultado (OK/FALLO).
- Error exacto con `archivo:línea` si aplica.
- Siguiente acción recomendada.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Y por ultimo el orquestador, como veremos el orquestador esta bastante limitado y tiene todos los subagentes como recursos a su disposicion. Se enfoca en la comunicación y acotar la petición con preguntas:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;---
description: Pregunta al usuario, define el alcance mínimo y delega en el equipo de Next.js y base de datos. No lee ni edita código.
mode: primary
steps: 12
permissions:
&amp;nbsp; - action: "*"
&amp;nbsp; &amp;nbsp; resource: "*"
&amp;nbsp; &amp;nbsp; effect: deny
&amp;nbsp; - action: question
&amp;nbsp; &amp;nbsp; resource: "*"
&amp;nbsp; &amp;nbsp; effect: allow
&amp;nbsp; - action: subagent
&amp;nbsp; &amp;nbsp; resource: "backend"
&amp;nbsp; &amp;nbsp; effect: allow
&amp;nbsp; - action: subagent
&amp;nbsp; &amp;nbsp; resource: "frontend"
&amp;nbsp; &amp;nbsp; effect: allow
&amp;nbsp; - action: subagent
&amp;nbsp; &amp;nbsp; resource: "database"
&amp;nbsp; &amp;nbsp; effect: allow
&amp;nbsp; - action: subagent
&amp;nbsp; &amp;nbsp; resource: "qa"
&amp;nbsp; &amp;nbsp; effect: allow
&amp;nbsp; - action: subagent
&amp;nbsp; &amp;nbsp; resource: "auditor"
&amp;nbsp; &amp;nbsp; effect: allow
---

Eres el orquestador de un equipo que construye una aplicación Next.js con Prisma y SQLite.

TU ROL
&lt;span class="k"&gt;- &lt;/span&gt;Hablas con el usuario y delegas. No lees archivos, no escribes código y no ejecutas comandos.
&lt;span class="k"&gt;- &lt;/span&gt;Usa la herramienta &lt;span class="sb"&gt;`question`&lt;/span&gt; para decisiones de alcance. Si la petición es clara, delega directo.

DESCOMPOSICIÓN Y FLUJO
&lt;span class="k"&gt;- &lt;/span&gt;Si una tarea mezcla áreas distintas (DB, API, UI, tests), divídela antes de delegar.
&lt;span class="k"&gt;- &lt;/span&gt;Cada llamada a un subagente pide un cambio mínimo y verificable en una sola área.
&lt;span class="k"&gt;- &lt;/span&gt;Orden recomendado: Esquema DB → API/Backend → Componentes Frontend → Tests → Auditoría e Integración.

AHORRO DE TOKENS (OBLIGATORIO)
&lt;span class="k"&gt;- &lt;/span&gt;No repitas contexto; envía a cada trabajador solo lo que necesita.
&lt;span class="k"&gt;- &lt;/span&gt;Limita los informes de los subagentes a un máximo de 20 líneas.
&lt;span class="k"&gt;- &lt;/span&gt;Responde en español, breve y directo.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Habiendo mostrado las instrucciones de cada agente vamos con los prompts que se hicieron para el desarrollo del proyecto.&lt;/p&gt;

&lt;h2&gt;
  
  
  Desarrollo&amp;nbsp;
&lt;/h2&gt;

&lt;p&gt;Para desarrollar yo opto por usar un archivo llamado &lt;code&gt;prompts.md&lt;/code&gt; que es mi fuente de verdad por si algún día necesito recrear el proyecto. también de esta manera puedo trabajar mejor el formato de cada petición.&lt;/p&gt;

&lt;p&gt;Prompt 1: Vista de proyectos&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;
Crea la vista inicial (#1: Dashboard de Proyectos) para la aplicación FastKanban usando Next.js (App Router, TypeScript y Tailwind CSS).

Requerimientos de la vista:
1. Estado Vacío (sin proyectos):
&amp;nbsp; &amp;nbsp;- Mostrar un botón principal cuadrado con bordes punteados (border-dashed) que diga "Agregar proyecto".
2. Lista de Proyectos (con datos presentes):
&amp;nbsp; &amp;nbsp;- Renderizar una cuadrícula (grid) de tarjetas de proyectos.
&amp;nbsp; &amp;nbsp;- Cada tarjeta debe mostrar el nombre del proyecto y un preview temporal que diga "Proyecto 1" (placeholder mientras se implementa la vista detallada del Kanban).
&amp;nbsp; &amp;nbsp;- Incluir el botón "Agregar proyecto" al final de la lista.
3. Funcionalidad mínima:
&amp;nbsp; &amp;nbsp;- Manejar un estado local/simulado para alternar entre el estado vacío y la lista de proyectos al hacer clic en "Agregar proyecto".

Instrucciones para los agentes:
&lt;span class="k"&gt;- &lt;/span&gt;Limitarse estrictamente a la Vista #1.
&lt;span class="k"&gt;- &lt;/span&gt;No implementar el tablero Kanban detallado aún.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Prompt 2: DB Proyectos&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;Implementa la base de datos para la vista de proyectos:
&lt;span class="k"&gt;- &lt;/span&gt;Los proyectos tienen un nombre.
&lt;span class="k"&gt;- &lt;/span&gt;Una fecha de creación.
&lt;span class="k"&gt;- &lt;/span&gt;Una fecha de actualización.
&lt;span class="k"&gt;- &lt;/span&gt;Un Blob para el preview (Por ahora un placeholder).
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Prompt 3: Tablero Kanban&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;
Crea un tablero de Kanban para los proyectos:

1. Sidebar:
&amp;nbsp; &amp;nbsp; - Un botón para crear colas.
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; - Cuando se presione el botón debe aparecer un dialog para escoger el color de la cola y el nombre.
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; - Para el color un color picker.&amp;nbsp;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; - Para el nombre un input estilizado.&amp;nbsp;

2. El tablero de kanban con las colas:
&amp;nbsp; &amp;nbsp; - Cada cola tiene que tener el nombre y su color en la parte superior.
&amp;nbsp; &amp;nbsp; - Un espacio mas oscuro para delimitar la colulmna.
&amp;nbsp; &amp;nbsp; - Cada cola ocupa una columna con un overflow.

3. Cuando se haga click en la cola:
&amp;nbsp; &amp;nbsp; - Aparece un dialog para agregar la nota con soporte para markdown.
&amp;nbsp; &amp;nbsp; - El dialog tiene un look como de postit con el color correspondiente a la cola.
&amp;nbsp; &amp;nbsp; - El texto debe ser blanco o negro dependiendo del color de cada cola.
&amp;nbsp; &amp;nbsp; - No debe tener un campo para el titulo de la nota explicito.
&amp;nbsp; &amp;nbsp; - El titulo de la nota es el primer header de la nota y si no tiene se pone como (sin titulo).
&amp;nbsp; &amp;nbsp; - Hay un hint al principio que indica que el titulo es el primer header.&amp;nbsp;

4. La nota en la cola:
&amp;nbsp; &amp;nbsp; - Se representa como un titulo con su contenido parcial oculto con ...

5. Cuando arrastro una nota:
&amp;nbsp; &amp;nbsp; - La puedo cambiar de cola lo que hara mutar so color.
&amp;nbsp; &amp;nbsp; - Hay una animación drag and drop con framer-motion.

6. Esquema de datos:
&amp;nbsp; &amp;nbsp; - La nota tiene que tener los campos:
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; - Titulo.
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; - Fecha de cracion.
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; - Fecha de actualización.
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; - Cola a la que pertenece.
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; - Proyecto al cual pertenece (FK)
&amp;nbsp; &amp;nbsp; - La cola debe tener los campos:
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; - Titulo
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; - Fecha de creación
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; - Color
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; - Proyecto al cual pertenece (FK)
Cualquier detalle omitido debera ser tomado en cuenta para la creación la compatibulidad
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
&amp;nbsp;&lt;/p&gt;

&lt;p&gt;Prompt 4: Limpieza y detalles&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;1. La nota al arrastrarla debe quedar por encima de todos los elementos de la pagina.
2. Añadir soporte para quitar colas (un botón X arriba a la derecha de cada cola).
3. Añadir soporte para quitar notas (Un botón X arriba a la derecha de cada nota).
4. En la pantalla principal al crear un proyecto debe existir un dialogo que te permita definir el titulo del proyecto.&amp;nbsp;
5. Soporte de edición de los titulos de proyecto y las notas: Si clickeo cualquier de una cola o un proyecto debo poder editarlo. Se indica con un lapiz y un background gris al hacer hover en el elemento.&amp;nbsp;
6. Verificar que todos los elementos tengan un CRUD completo en el frontend.
7. Agregar un botón de navegación para volver a la ventana de proyectos.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Prompt 5: Ultimos detalles&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;Corrige los puntos.

1. Integra los snapshots y mejora los cards de proyectos.
&amp;nbsp; &amp;nbsp; - Un header gris con el nombre&amp;nbsp;
&amp;nbsp; &amp;nbsp; - En el cuerpo un snapshot del kanban creado
&amp;nbsp; &amp;nbsp; - Si no hay un kanban reemplazar por una tarjeta en blanco&amp;nbsp;
2. Modo oscuro:
&amp;nbsp; &amp;nbsp; - Para la vista de proyectos y vista del kanban.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Y estos son los prompts que utilice en este proyecto. Por la misma naturaleza del proyecto no se necesitaron mas recursos.&lt;/p&gt;

&lt;p&gt;Adjunto algunas imágenes del resultado&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpa4gm056qxtp6fhm8gyb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpa4gm056qxtp6fhm8gyb.png" alt="Vista de proyecto" width="800" height="330"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7bltxqaef2eo0cbd8xae.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7bltxqaef2eo0cbd8xae.png" alt="Vista del Kanban Board" width="799" height="719"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusión
&lt;/h2&gt;

&lt;p&gt;En lo personal este patrón me ha ayudado a ahorrar tokens al momento de crear una gran variedad de proyecto, si bien este no es el único patrón de mi caja de herramientas es una base solida para ir mejorando. Es adaptable a cada necesidad y se pueden encadenar distintas rutinas de utilizacion de herramientas de auditoria como SonarQube, ReactDoctor, entre otras. Cada agente puede tener un stack de herramientas a las que puede recurrir y eso hace que esta forma de plantear la utilización de la herramienta sea bastante flexible.&amp;nbsp;&lt;/p&gt;

&lt;p&gt;Si bien este es el inicio de una serie de artículos sobre ingeniería de agentes aplicada a Opencode creo que es una base solida para ir construyendo intuición sobre una utilización mas avanzada de la herramienta&lt;/p&gt;

&lt;p&gt;¿Que opinas de este patron de diseño?. Dímelo en la caja de comentarios.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Desestandarízate: filosofía, programación y el peligro de hacer siempre “lo correcto”</title>
      <dc:creator>PyramidBuilder</dc:creator>
      <pubDate>Sun, 30 Aug 2026 06:10:14 +0000</pubDate>
      <link>https://dev.to/pyramidbuilder/desestandarizate-un-manifiesto-existencial-contra-la-tirania-de-la-norma-497n</link>
      <guid>https://dev.to/pyramidbuilder/desestandarizate-un-manifiesto-existencial-contra-la-tirania-de-la-norma-497n</guid>
      <description>&lt;p&gt;Jean-Paul Sartre sentenció que "el hombre está condenado a ser libre". Sin embargo, la filosofía existencialista nos advierte sobre el vértigo que acompaña a tal sentencia: la angustia. El ser humano, aterrado ante la inmensidad de su propia libertad, a menudo huye de ella. Sartre llamó a esto "mala fe": la cobardía de engañarse a uno mismo, asumiendo que solo son cosas determinadas por el entorno y no sujetos libres.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fz2g9db2cc68zpk4acpg2.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fz2g9db2cc68zpk4acpg2.jpg" alt="Mirando el Abismo" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Creo que no soy el único de mi círculo cercano a quien le aterra esa libertad. Nos hemos inventado todo tipo de justificaciones racionales para mantenernos restringidos a roles preconcebidos. Pero este miedo está tomando dimensiones peligrosas en nuestra era: cada vez más personas afirmando que existe una "forma correcta" de hacer las cosas, una verdad absoluta sobre cómo entender y moldear el mundo. Esto, fundamentalmente, es un error epistemológico que castra nuestra creatividad y anula nuestra agencia.&lt;/p&gt;

&lt;p&gt;Desde gurús que venden la "forma correcta" de estructurar sistemas, hasta recetas dogmáticas como ciertas lecturas rígidas de clean code, pasando por concepciones inamovibles sobre cómo debemos trabajar. Hoy ha llegado el día de decir ¡ALTO! ¿A qué? A la ilusión de que hay algo intrínsecamente malo en atreverse a habitar la disonancia y hacer las cosas de una manera diferente.&lt;/p&gt;

&lt;h2&gt;
  
  
  La ilusión del control y la anestesia del "se"
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff9g5xmfg8jajj13bfap7.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff9g5xmfg8jajj13bfap7.jpg" alt="Panoptico" width="800" height="589"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Gran parte de nosotros nos aferramos a los estándares porque nos brindan algo que el existencialismo nos niega: LA ilusión de control. Creemos que, al atenernos estrictamente a una metodología, a un patrón de diseño o a un manual de "buenas prácticas", estamos construyendo un escudo contra el caos o el juicio ajeno. Si el sistema colapsa siguiendo una regla, la culpa es de la regla; pero si colapsa por una desviación, la culpa es enteramente nuestra. Los estándares, en el fondo, operan como un mecanismo de defensa psicológica contra la ansiedad de la responsabilidad. Nos convencemos de que, si seguimos el mapa al pie de la letra, el territorio no nos sorprenderá.&lt;/p&gt;

&lt;p&gt;Conviene hacer una concesión honesta antes de seguir: en un proyecto donde veinte personas necesitan leer, mantener y extender el mismo código, ciertas convenciones compartidas no son un lujo, son una condición de posibilidad. Sin ellas, el caos no es libertad; es simplemente ruido. El problema no es la convención. EL problema es la sacralización de la convención: el momento en que una preferencia estilística o una heurística útil se convierte en verdad ontológica, en ley moral, en criterio de pertenencia a la tribu, es ahí donde la herramienta deja de servir al artesano y empieza a gobernarlo.&lt;/p&gt;

&lt;p&gt;Aquí es donde la filosofía de Michel Foucault resulta reveladora. Foucault nos enseñó que el control en las sociedades modernas no se ejerce principalmente a través de la fuerza bruta o la prohibición, sino a través de la norma. En su análisis sobre las sociedades disciplinarias y el panóptico, demostró cómo el poder termina por internalizarse: el individuo se convierte en su propio carcelero. En nuestra industria, el panóptico no es una torre de vigilancia física; es la revisión de código, la opinión de la comunidad, el dogma del framework de moda y la tiranía del "así se hace". Hemos internalizado la mirada del otro. Nos autocensuramos, pulimos nuestras ideas hasta dejarlas perfectamente simétricas y predecibles, no porque sea lo más eficiente para el problema, sino para evitar el castigo social de ser tildados de "herejes", "inexpertos" o "disruptivos".&lt;/p&gt;

&lt;p&gt;Martin Heidegger describió esta misma dinámica con otra palabra: Das man, el "se" impersonal. El "se dice", el "se hace así", el "se espera que". Esa fuerza anónima que nos dicta cómo debemos pensar, sentir y actuar para ser aceptados por la manada. La estandarización llevada al dogma es la anestesia del espíritu: nos conecta con nuestro instinto más primitivo de supervivencia social, pero nos desconecta de la pregunta más incómoda de toda ética: ¿A quién le estamos rindiendo cuentas? ¿Al "se" impersonal, o a nuestra propia consciencia?&lt;/p&gt;

&lt;p&gt;Sin embargo, esta obsesión por la normalización es una trampa mortal. Al optimizar nuestros sistemas y nuestras mentes para la predictibilidad, eliminamos la fricción, pero también eliminamos la chispa. La verdadera innovación nunca nace en el centro de la norma; nace en los márgenes, en la anomalía, en el "error" que resulta ser un descubrimiento. Cuando imponemos una única epistemología sobre cómo debe construirse el software, no estamos garantizando el éxito; estamos asegurando el estancamiento. Cambiamos el asombro del descubrimiento por la comodidad de la burocracia técnica.&lt;/p&gt;

&lt;h2&gt;
  
  
  La ceguera ontológica de Kodak
&lt;/h2&gt;

&lt;p&gt;En 1975, Steven Sasson, un ingeniero de Kodak, inventó la primera cámara digital. Tenía el tamaño de una tostadora, grababa imágenes en blanco y negro en un casete y tardaba 23 segundos en tomar una foto.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fksuahbhkx5ynlw4hp3sg.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fksuahbhkx5ynlw4hp3sg.jpg" alt="Camara" width="800" height="1200"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cuando Sasson presentó el prototipo a la alta dirección, la reacción fue de rechazo inmediato. No porque la tecnología fuera inválida, sino porque atentaba contra el dogma de la compañía. Kodak sufrió de lo que en filosofía podríamos llamar ceguera ontológica: confundieron el ente con el ser del ente. Se quedaron mirando la película, el papel, los químicos (los entes concretos que llenaban sus estanterías) y olvidaron el ser que esos entes estaban revelando: la captura de luz, la preservación de la memoria, el deseo humano de detener el tiempo. Al aferrarse a su "forma correcta" de dominar el mundo, se convirtieron en prisioneros de su propio éxito. Años después, competidores sin los sesgos ni el miedo de Kodak cambiaron el paradigma para siempre. Kodak intentó reaccionar demasiado tarde y murió en 2012, aplastada por el peso de su propia ortodoxia.&lt;/p&gt;

&lt;h2&gt;
  
  
  Carmack y la voluntad de poder sobre el código
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqgczzq7s1f0qz96rj8ez.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqgczzq7s1f0qz96rj8ez.jpg" alt="Computer" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A principios de los 90, la teleología de la industria dictaba que las PCs no tenían potencia para renderizar 3D en tiempo real. El "estándar" exigía estaciones de trabajo de decenas de miles de dólares o limitarse al 2D.&lt;/p&gt;

&lt;p&gt;John Carmack no consultó los manuales de arquitectura ni pidió permiso a la academia. Para crear Commander Keen, Wolfenstein 3D y Doom, desarrolló trucos matemáticos fuera de la norma, como el Binary Space Partitioning adaptado de papers militares de los 70 que la ortodoxia comercial ignoraba. En lugar de seguir estructuras de código convencionales, escribió rutinas en ensamblador y C con optimizaciones agresivas que desafiaban la teoría establecida. Carmack entendió que la pureza teórica es inútil si no dialoga con la realidad del hardware.&lt;/p&gt;

&lt;p&gt;Nietzsche habló de la Wille zur Macht, la voluntad de poder, no como dominio sobre otros, sino como la fuerza autoafirmativa de la vida que impone una forma propia sobre la materia resistente, que se supera a sí misma en el acto de crear. Carmack ejerció exactamente eso: no se sometió a los valores dados por la industria, no esperó a que el hardware "madurara" para que el problema se volviera legítimo. Forjó su propia solución y, al hacerlo, no solo escribió código; alteró la fenomenología de lo que creíamos posible en una máquina. Si se hubiera paralizado buscando "la forma correcta", la revolución 3D se habría retrasado años.&lt;/p&gt;

&lt;h2&gt;
  
  
  La hipertrofia del mapa y el olvido del territorio
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbu8lemknit3thzkm2joj.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbu8lemknit3thzkm2joj.jpg" alt="Territory" width="640" height="428"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vivimos en la era de la hipertrofia del mapa y el olvido del territorio. Tenemos un exceso de información y de "buenas prácticas" que actúan como un panóptico multiplicado: múltiples voces dispuestas a refutar nuestra forma de crear antes de que siquiera termine de nacer. En el diseño de sistemas no existen verdades absolutas; solo existen estados donde una solución supera a otra en un contexto dado. Y sin embargo, cada propuesta alternativa es recibida como una transgresión.&lt;/p&gt;

&lt;p&gt;El fenómeno no es nuevo, pero se ha intensificado. La cantidad de manuales sobre cómo hacer las cosas "correctamente" a la que un desarrollador podía acceder en los años 80 o 90 era infinitamente menor a la de hoy. Y, sin embargo, los cimientos tecnológicos que sostienen el mundo (desde los primeros sistemas operativos hasta Linux o FFmpeg) nacieron en esa era de experimentación libre. La ausencia de un manual rígido no fue un impedimento; fue un catalizador. No tenían un mapa, pero tenían la valentía de explorar el territorio.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hacia un pluralismo epistemológico: la IIT y el coraje de borrar fronteras
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F95eh5vn6yu2fgt3kppx4.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F95eh5vn6yu2fgt3kppx4.jpg" alt="Rubik" width="640" height="1138"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;¿Qué esperas para desestandarizarte? No te digo que hagas las cosas mal a propósito, sino que dejes de buscar en un manual el patrón correcto y empieces a fluir hacia una forma más orgánica de crear. Al igual que la informática, existen formas de programar que aún no se han descubierto y otras fascinantes que, por estar encasilladas en dominios rígidos, ignoramos en el diseño de aplicaciones cotidianas.&lt;/p&gt;

&lt;p&gt;El verdadero salto no ocurre dentro de las fronteras de una disciplina, sino en su intersección. Pensemos en la Teoría de la Información Integrada (IIT), propuesta por el neurocientífico Giulio Tononi para explicar matemáticamente la consciencia. Esta teoría no habría podido ser concebida si hubiéramos mantenido la teoría de la información, la cibernética de segundo orden (que estudia al observador dentro del sistema) y la fenomenología como campos aislados. Si hubiéramos aceptado el dogma de que la fenomenología "no es para ingenieros" o que la cibernética "no tiene nada que ver con la experiencia subjetiva", seguiríamos atrapados en el reduccionismo. Fue precisamente la osadía de borrar las fronteras entre lo que mide la información, lo que regula el sistema y lo que experimenta el fenómeno, lo que permitió dar el salto.&lt;/p&gt;

&lt;p&gt;Esa misma osadía es la que necesitamos en el software. Trascender la visión newtoniana y la cartesiana (rígida, determinista y predecible) y atrevernos a pensar en sistemas que se autorregulan como organismos, en soluciones que evolucionan por mutación e iteración en lugar de seguir reglas fijas, en el coraje de integrar el azar y la probabilidad aceptando que el universo no es determinista y que a veces la mejor solución emerge del ruido. No se trata de abandonar la lógica, sino de dejar de creer que la lógica es lo único que hay.&lt;/p&gt;

&lt;h2&gt;
  
  
  La eudaimonía del creador
&lt;/h2&gt;

&lt;p&gt;Desestandarizarse no es un acto de rebeldía vacía; es un imperativo ético. Los antiguos griegos, específicamente Aristóteles, acuñaron el término eudaimonía, que a menudo se traduce de forma reduccionista como "felicidad", pero significa con mayor precisión "florecimiento humano": la realización del máximo potencial de un ser a través de la excelencia y la virtud.&lt;/p&gt;

&lt;p&gt;Cuando un programador se atreve a desestandarizarse, a fusionar la biología con el silicio, o el azar con la lógica, no solo está escribiendo código más interesante. Está alcanzando la eudaimonía de su oficio. Pasa de ser un obrero alienado que ensambla piezas prefabricadas según un manual a un pensador libre que da forma a la realidad. La verdadera creatividad no es elegir entre dos patrones de diseño aceptados; es la capacidad de mirar el vacío entre las disciplinas y ver un puente.&lt;/p&gt;

&lt;p&gt;Al disolver los muros que separan a la computación de la biología, la lógica de la fenomenología, los datos de la consciencia, no solo estamos mejorando nuestra tecnología. Estamos expandiendo los límites de lo que significa ser humano en un mundo digital. Al escribir tu próxima línea de código, no estás solo resolviendo un problema técnico; estás tomando una decisión existencial sobre cómo quieres que sea el mundo.&lt;/p&gt;

&lt;p&gt;Hay una ironía que no puedo ignorar, y que me obligó a señalar: este ensayo está construido con citas de Sartre, Foucault, Heidegger, Nietzsche y Aristóteles. Uso el lenguaje del canon para cuestionar el canon. Uso la autoridad de los muertos para defender la libertad de los vivos. No se me escapa la contradicción. Pero asumo porque Sartre mismo la asumió: no hay forma de hablar desde fuera del lenguaje que uno ha heredado. Lo que importa no es la pureza del origen, sino qué haces con lo que tienes en las manos. Yo elegí usar estas herramientas para abrir una puerta, no para cerrar una más.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Por qué estudié filosofía?
&lt;/h2&gt;

&lt;p&gt;Permítanme una confesión personal, porque este artículo no habría existido sin ella. Hace unos años, cuando decidí que comenzaría a estudiar filosofía, mis congéneres (colegas desarrolladores, amigos de la universidad) se rieron de mí. Con esa mezcla de burla y condescendencia que solo tienen los que creen poseer la verdad, me dijeron que ahora sí estaba "perdiendo lo que me quedaba de vida". Que la filosofía era inútil, que no me daría trabajo, que no era "aplicable". Que estaba traicionando el pragmatismo sagrado de nuestra profesión.&lt;/p&gt;

&lt;p&gt;Y tenían razón en algo: la filosofía no me dio trabajo. No me enseñó un framework nuevo. No me hizo más rápido escribiendo código.&lt;/p&gt;

&lt;p&gt;Pero lo que sí hizo fue algo infinitamente más valioso: me dio las herramientas para pensar sobre el código, sobre la industria, sobre mí mismo.&lt;/p&gt;

&lt;p&gt;Si no hubiera cruzado mis habilidades autodidactas previas con la filosofía, nunca habría podido escribir este artículo. Nunca habría podido articular de esta forma los pensamientos que quería expresar. La filosofía no reemplazó lo que ya sabía; lo potenció, lo profundizó, lo transformó. Me permitió ver que la angustia que sentía ante los estándares no era un defecto mío, sino un síntoma de algo mucho más grande: la tiranía de la norma, la internalización del panóptico, la ceguera ontológica.&lt;br&gt;
Hubo momentos en que pensé que tenían razón. Momentos en que dudé. Momentos en que casi dejo la filosofía. Pero algo me mantuvo leyendo, pensando, cuestionando. Y ese algo, creo, era la misma angustia que describo en este ensayo: la sensación de que había algo más, algo más profundo, algo que los manuales no me estaban dando.&lt;/p&gt;

&lt;p&gt;Y aquí está la ironía más profunda: aquellos que se rieron de mí no lo hicieron por maldad. Lo hicieron porque estaban atrapados en la misma ansiedad que yo describo en este ensayo. Estaban tan asustados de la libertad que necesitaban convencerse de que yo estaba equivocado. Ellos no perdieron la vida; la están pasando siguiendo un mapa que alguien más dibujó. Y eso, en el fondo, es trágico.&lt;/p&gt;

&lt;p&gt;La filosofía, en el fondo, es el acto más subversivo que puede cometer un programador. Es la decisión de preguntar por qué antes de preguntar cómo. Es la negativa a aceptar que la única forma de ser útil es ser inmediatamente aplicable. Es entender que lo que parece "inútil" hoy puede ser lo que te dé las herramientas para ver el mundo de una forma completamente nueva mañana.&lt;/p&gt;

&lt;p&gt;Y eso, mis congéneres, no es perder la vida.&lt;/p&gt;

&lt;p&gt;Es empezar a vivirla.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>discuss</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>Cómo escribir una herramienta para generar gráficos con lenguaje natural usando ChatGPT.</title>
      <dc:creator>PyramidBuilder</dc:creator>
      <pubDate>Wed, 22 Mar 2023 03:19:29 +0000</pubDate>
      <link>https://dev.to/pyramidbuilder/como-escribir-una-herramienta-para-generar-graficos-con-lenguaje-natural-usando-chatgpt-2hop</link>
      <guid>https://dev.to/pyramidbuilder/como-escribir-una-herramienta-para-generar-graficos-con-lenguaje-natural-usando-chatgpt-2hop</guid>
      <description>&lt;p&gt;Con el rápido desarrollo de los grandes modelos del lenguaje, han surgido varias oportunidades de automatización a través del uso del lenguaje natural. En este artículo vamos a ir paso a paso por la creación guiada de un sistema de IA para generar gráficos a partir de un conjunto de datos de forma automatizada. Es una herramienta teórica, y está desarrollada para mostrar lo fácil que es usar la API de ChatGPT para crear nuestros propios proyectos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Zero Shot o Few Shots, el concepto clave
&lt;/h2&gt;

&lt;p&gt;¿Te imaginas usar un modelo de inteligencia artificial para resolver tareas para las que no fue entrenado específicamente? Con el auge de los modelos del lenguaje se han generado modelos preentrenados que nos permiten aprovechar una técnica llamada Zero Shot Learning y es fácilmente aplicable usando modelos como ChatGPT.&lt;/p&gt;

&lt;p&gt;ChatGPT es una herramienta de procesamiento del lenguaje. Su principal aplicación es la de conversar con los usuarios, por eso generalmente se le clasifica dentro de los modelos conversacionales.&lt;/p&gt;

&lt;p&gt;Si bien fue creada para mantener conversaciones con los usuarios, ChatGPT al estar basada en modelos de procesamiento del lenguaje natural, puede ayudarnos a desarrollar muchas tareas de procesamiento del lenguaje usando una técnica llamada “Zero Shot”.&lt;/p&gt;

&lt;p&gt;Los modelos donde se pueden aplicar estas técnicas son los modelos preentrenados. Estos representan una gran oportunidad para poder acelerar nuestro trabajo respecto al Deep Learning, debido a que han sido previamente entrenados en grandes volúmenes de datos. Usar modelos preentrenados para resolver tareas rutinarias en nuestras aplicaciones de inteligencia artificial nos puede ahorrar mucho tiempo y recursos.&lt;/p&gt;

&lt;p&gt;¿Pero qué es Zero Shot? El concepto de “Zero Shot Learning” no es nuevo, lleva varios años dando vueltas por el campo de la inteligencia artificial. El Zero Shot Learning es un paradigma para trabajar con modelos preentrenados. Este paradigma nos indica que los modelos preentrenados pueden desarrollar tareas para las que no fueron entrenados explícitamente.&lt;/p&gt;

&lt;p&gt;Las técnicas de Zero Shot representan una oportunidad para el desarrollo de múltiples aplicaciones, esto debido a que permiten usar y adaptar modelos para tareas distintas a las que fueron entrenados.&lt;/p&gt;

&lt;p&gt;No tenemos que confundir las técnicas de Zero Shot con las técnicas de Transfer Learning. En el Transfer Learning se reentrena un modelo para aplicarlo a un problema distinto al original. Para el Zero Shot no se necesita entrenamiento adicional, simplemente saber cómo expresar la tarea a resolver.&lt;/p&gt;

&lt;p&gt;Un ejemplo Zero Shot Q&amp;amp;A:&lt;/p&gt;

&lt;p&gt;Q: Roger tenía 16 pelotas de distintos tipos. La mitad eran pelotas de golf y la mitad de las pelotas de golf eran azules. ¿Cuántas pelotas azules tenía Roger?&lt;br&gt;
A: &lt;/p&gt;

&lt;p&gt;Respuesta:&lt;br&gt;
Roger tenía 4 pelotas azules.&lt;/p&gt;

&lt;p&gt;Si la mitad de las 16 pelotas eran de golf, eso significa que tenía 8 pelotas de golf. Y si la mitad de las pelotas de golf eran azules, entonces tenía 4 pelotas de golf azules. Por lo tanto, Roger tenía 4 pelotas azules en total.&lt;/p&gt;

&lt;p&gt;Si bien esta técnica es efectiva para desarrollar aplicaciones, podemos mejorarla cuando le damos ejemplos y seguimos un patrón más parecido al aprendizaje por una muestra (one-shot learning).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0plt3kkw24uojve87zn9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0plt3kkw24uojve87zn9.png" alt="One Shot Learning Prompt" width="800" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Dentro de este prompt podemos reconocer 4 secciones importantes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;El prompt principal, el que provee instrucciones y una descripción general de la tarea&lt;/li&gt;
&lt;li&gt;Las categorías a clasificar&lt;/li&gt;
&lt;li&gt;El texto a clasificar&lt;/li&gt;
&lt;li&gt;Las instrucciones adicionales.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjpl2evtgay3wd7r0zfyv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjpl2evtgay3wd7r0zfyv.png" alt="One Shot Learning Anotated" width="799" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pero vamos a volver al tema más adelante, por ahora solo mantén en mente que este patrón de pregunta es más efectivo para las respuestas que un patrón basado en &lt;strong&gt;Zero Shot Learning&lt;/strong&gt; o &lt;strong&gt;One Shot&lt;/strong&gt; para usarlo en tareas relativas al &lt;strong&gt;Natural Language Understanding&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A pesar de las ventajas que ofrecen el &lt;strong&gt;Zero Shot Learning&lt;/strong&gt; y el &lt;strong&gt;One Shot Learning&lt;/strong&gt;, como la posibilidad de aplicar modelos preentrenados a una gran variedad de tareas que involucran el procesamiento del lenguaje natural y la reducción del costo computacional y temporal, también hay que reconocer los desafíos y limitaciones asociados a estas dos técnicas, como la falta de consistencia y la dificultad para evaluar los resultados generados por los modelos.&lt;/p&gt;
&lt;h2&gt;
  
  
  Pensando en ChatGPT como un compresor de datos
&lt;/h2&gt;

&lt;p&gt;Los compresores de datos son programas que tienen por finalidad reducir el tamaño de los datos. Los modelos de lenguaje son modelos capaces de predecir la siguiente palabra de una secuencia de palabras, pero ¿cómo podemos relacionar estos dos conceptos?&lt;/p&gt;

&lt;p&gt;Si tomamos en cuenta el volumen de los datos con los que está entrenado ChatGPT, podemos cuantificarlo de muchas formas, pero no se puede negar que ChatGPT es una representación compacta de esa cantidad masiva de datos.&lt;/p&gt;

&lt;p&gt;Una manera de considerar al &lt;strong&gt;prompt&lt;/strong&gt;, es como una herramienta para filtrar información que el modelo tiene en sus datos de entrenamiento, y al modelo como una estructura que codifica toda la información que queremos obtener.&lt;/p&gt;

&lt;p&gt;Por ejemplo, supongamos que queremos usar a ChatGPT para generar una pregunta para un examen de sociologia podriamos usar el siguiente prompt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Pregunta teorica para un examen de sociologia.

Si consideramos el concepto Materialismo historico propuesto por Karl Marx, podriamos afirmar que:

a. ___________ (Alternativa a maximo 200 caracteres)
b. ___________ (Alternativa b maximo 200 caracteres)
c. ___________ (Alternativa c maximo 200 caracteres)
d. ___________ (Alternativa d maximo 200 caracteres)

Repuesta correcta:
_ (Alternativa para la respuesta correcta)

¿Puedes completar la plantilla?

Respuesta:
Si consideramos el concepto Materialismo histórico propuesto por Karl Marx, ¿podríamos afirmar que:

a. La economía es el motor de la historia, y los conflictos entre clases sociales son la principal fuerza impulsora del cambio social.

b. El desarrollo tecnológico y científico es el principal factor que determina el curso de la historia.

c. La religión es la fuente de todos los conflictos sociales y políticos.

d. El individualismo es la principal causa de la desigualdad social.

La respuesta correcta es:
a. La economía es el motor de la historia, y los conflictos entre clases sociales son la principal fuerza impulsora del cambio social.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En este ejemplo podemos observar que al utilizar un &lt;strong&gt;prompt&lt;/strong&gt; específico, estamos filtrando la información que el modelo ChatGPT posee respecto al concepto de &lt;strong&gt;materialismo histórico&lt;/strong&gt;. Estamos guiando de cierta manera al modelo a generar una pregunta relacionada con esta teoría sociológica en particular. De esta manera, el &lt;strong&gt;prompt&lt;/strong&gt; tiene la función de controlar el tipo de información que el modelo utiliza para generar la respuesta deseada. Con esto podemos observar cómo se puede percibir al &lt;strong&gt;prompt&lt;/strong&gt; como &lt;em&gt;una herramienta para filtrar la información de un modelo de procesamiento del lenguaje&lt;/em&gt;, en este caso ChatGPT.&lt;/p&gt;

&lt;p&gt;Si lo pensamos de esta manera, el &lt;strong&gt;prompt&lt;/strong&gt; es la forma de buscar información dentro de ChatGPT, en cierta manera una forma de filtrar ese volumen masivo de datos comprimidos dentro de sus parámetros. Por lo tanto, para filtrar exactamente la información que queremos tenemos que seguir algunos pasos que he podido notar en mi proceso de experimentación directo con ChatGPT:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Ser específico: Siempre tenemos que intentar ser lo más específico posible y eliminar cualquier posible concepto ambiguo en nuestro prompt.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Proveer ejemplos: Proveer ejemplos sobre cómo contestar es clave para poder obtener buenas respuestas por parte del modelo. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Proveer un formato claro de respuesta: Proveer plantillas y un formato claro de cómo responder puede ser bastante ventajoso al momento de ocupar ChatGPT para desarrollar aplicaciones, debido a que si podemos hacer que el modelo facilite el proceso, de postprocesado de datos, ahorraremos mucho tiempo de escritura de código.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;La pregunta más grande que se puede generar en este momento es: ¿Por qué estos consejos funcionan?.&lt;/p&gt;

&lt;h2&gt;
  
  
  Los modelos de lenguaje son aprendices de pocas muestras
&lt;/h2&gt;

&lt;p&gt;En 2020, OpenAI publicó un artículo llamado "Language Models Are &lt;strong&gt;Few Shot Learning&lt;/strong&gt;" que puede ayudarnos a comprender cómo mejorar los prompts de &lt;strong&gt;ChatGPT&lt;/strong&gt;. En él, se explican algunas pistas sobre cómo entrenaron a GPT-3 utilizando una técnica llamada &lt;strong&gt;"Few Shot Learning"&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Esta técnica se basa en el aprendizaje automático que permite realizar una tarea específica a partir de pocos ejemplos de entrenamiento y generalizarlos a nuevas aplicaciones. Se inspira en la forma en que los humanos aprendemos, donde no solo adquirimos conocimientos teóricos, sino que también aprendemos a partir de ejemplos concretos.&lt;/p&gt;

&lt;p&gt;Por ejemplo, si vemos un animal con cuatro patas, pelo y cola, podemos deducir que es un mamífero, mientras que si vemos un animal con aletas, escamas y agallas, podemos decir que es un animal marino. Esto demuestra que el conocimiento no se basa únicamente en teorías, &lt;strong&gt;sino que también se relaciona con ejemplos concretos que nos ayudan a realizar las tareas que se nos piden&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Sabiendo los detalles del &lt;em&gt;proceso de entrenamiento&lt;/em&gt; de &lt;strong&gt;GPT-3&lt;/strong&gt;, podemos mejorar nuestras capacidades de prompting. Por ejemplo, en lugar de pedirle a &lt;strong&gt;ChatGPT&lt;/strong&gt; que "Describa un león", es recomendable proporcionar varios ejemplos para aclarar el concepto de "descripción", proporcionando ejemplos de descripciones de otros animales, por ejemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Ejemplos de descripción de animales:
- El tigre es un animal con 4 patas, pelo y cola. Los tigres se encuentran en hábitats increíblemente diversos, por ejemplo "selvas tropicales" (...)

- El búho es un ave con 2 patas, 2 alas, y plumas. Los búhos habitan típicamente en los bosques (...)

Ahora, describe un león.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Estos ejemplos ayudarán a &lt;strong&gt;ChatGPT&lt;/strong&gt; a entender el tipo de descripción precisa que estás buscando y pueden lograr que &lt;strong&gt;ChatGPT&lt;/strong&gt; te proporcione detalles específicos, use una plantilla, etc.&lt;/p&gt;

&lt;p&gt;Pero hay que tener en cuenta que las peticiones deben contener información relevante sobre cómo resolver la tarea que estamos pidiendo. Es importante dividir tu petición en partes pequeñas que aporten los detalles necesarios para responder a la petición de manera adecuada.&lt;/p&gt;

&lt;p&gt;Con estos conceptos en mente, podemos mejorar los prompts que hacemos a &lt;strong&gt;ChatGPT&lt;/strong&gt; para lograr respuestas más efectivas y útiles en diversas aplicaciones.&lt;/p&gt;

&lt;p&gt;Para pedir a &lt;strong&gt;ChatGPT&lt;/strong&gt; que resuelva una tarea específica, es importante proporcionarle varios ejemplos sobre cómo resolverla y cómo responder a la petición. Esto se debe a que los &lt;em&gt;modelos de lenguaje&lt;/em&gt;, como &lt;strong&gt;ChatGPT&lt;/strong&gt;, están diseñados para aprender a partir de pocos ejemplos utilizando la técnica de &lt;strong&gt;Few Shot Learning&lt;/strong&gt;, que se basa en la idea de que los humanos también aprendemos a partir de ejemplos.&lt;/p&gt;

&lt;p&gt;Además, es importante entender el concepto de &lt;em&gt;"tokens"&lt;/em&gt;. Los &lt;em&gt;tokens&lt;/em&gt; son las unidades mínimas utilizadas para procesar texto. Cuando se procesa texto para &lt;strong&gt;ChatGPT&lt;/strong&gt;, se divide en &lt;em&gt;tokens&lt;/em&gt; para poder procesarlo de manera efectiva. La cantidad de &lt;em&gt;tokens&lt;/em&gt; en una entrada determina la calidad de la respuesta generada por el modelo. Sin embargo, no es solo la cantidad de &lt;em&gt;tokens&lt;/em&gt; lo que importa. También es importante que los &lt;em&gt;tokens&lt;/em&gt; sean relevantes y proporcionen información adicional sobre la respuesta específica que se busca.&lt;/p&gt;

&lt;p&gt;Si deseas conocer la cantidad de &lt;em&gt;tokens&lt;/em&gt; que tiene tu petición y aprender más sobre cómo se preprocesa el texto de entrada para GPT-3, puedes usar el siguiente enlace, que utiliza una implementación de GPT-3-Encoder: &lt;a href="https://platform.openai.com/tokenizer" rel="noopener noreferrer"&gt;https://platform.openai.com/tokenizer&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  El verdadero potencial oculto en LangChain 🦜
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;LangChain&lt;/strong&gt; es una herramienta que facilita la creación de aplicaciones basadas en modelos del lenguaje. Algunos ejemplos de los modelos que se pueden utilizar mediante la librería &lt;strong&gt;LangChain&lt;/strong&gt; son GPT-3, BERT o ChatGPT.&lt;/p&gt;

&lt;p&gt;Los modelos del lenguaje se pueden emplear para realizar diferentes tareas, como se ha demostrado anteriormente, aprovechando la capacidad de generalización de un modelo para realizar diversas tareas. Para explotar el potencial de los diferentes modelos del lenguaje es necesario crear una infraestructura de código que les permita interactuar con otras herramientas y fuentes de datos o con el usuario final.&lt;/p&gt;

&lt;p&gt;Aquí es donde entra &lt;strong&gt;LangChain&lt;/strong&gt;. Con esta librería se pueden crear diferentes cadenas de ejecución, gestionar los prompts, diseñar agentes, gestionar y almacenar los datos generados por los diferentes modelos, etc.&lt;/p&gt;

&lt;p&gt;Conocí Langchain leyendo el código de &lt;strong&gt;Visual ChatGPT&lt;/strong&gt; publicado por Microsoft. El paper presentaba un nuevo paradigma para el desarrollo de agentes conversacionales capaces de &lt;strong&gt;enviar y recibir imágenes a través del chat&lt;/strong&gt;. Esto me pareció muy innovador y así fue como se me ocurrió el siguiente proyecto.&lt;/p&gt;

&lt;p&gt;En concreto &lt;strong&gt;Visual ChatGPT&lt;/strong&gt; usaba Langchain para comunicar a GPT-3 con una serie de &lt;em&gt;modelos fundamentales visuales&lt;/em&gt; especializados en distintos dominios. Por ejemplo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Modelos para editar imágenes&lt;/li&gt;
&lt;li&gt;Modelos para generar imágenes&lt;/li&gt;
&lt;li&gt;Modelos pix2pix&lt;/li&gt;
&lt;li&gt;etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Todos estos modelos conformaban un &lt;em&gt;toolkit&lt;/em&gt; y se usaba &lt;strong&gt;ChatGPT&lt;/strong&gt; como un intermediario entre el usuario y estas herramientas; es decir, &lt;strong&gt;ChatGPT&lt;/strong&gt; sabía operar con este &lt;em&gt;toolkit&lt;/em&gt;. Lo que más me llamó la atención es que no era necesario reentrenar al modelo para poder aplicar el paradigma y ahí es donde vi la innovación. De pronto se me ocurrió implementar este mismo patrón para varios proyectos, incluido el que voy a mostrar a continuación.&lt;/p&gt;

&lt;p&gt;No voy a profundizar en cada una de las capacidades de LangChain, pero si estás interesado en saber más sobre la librería, puedes visitar su documentación: &lt;a href="https://langchain.readthedocs.io/en/latest/index.html" rel="noopener noreferrer"&gt;https://langchain.readthedocs.io/en/latest/index.html&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Para este proyecto solo usaré el Prompt Template y el LLMChain, ya que son bastante fáciles de implementar y entender incluso si no tienes conocimientos previos sobre LangChain, pero los explicaré brevemente antes de pasar al código:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;El prompt template es &lt;strong&gt;una forma estandarizada para definir la entrada y la salida esperada de un modelo del lenguaje&lt;/strong&gt;, como hemos visto anteriormente, tenemos que pensar en el prompt como una herramienta para filtrar datos; por lo tanto, el PromptTemplate nos permite &lt;strong&gt;adaptar el modelo a una tarea específica o personalizar su comportamiento&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;El LLMChain &lt;strong&gt;permite definir una llamada al modelo del lenguaje con los parámetros que queramos usar&lt;/strong&gt;, se usa para comunicarse con la &lt;strong&gt;API de un modelo y recibir una respuesta en formato string&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  PlotGPT: Una aplicación creada con ChatGPT.
&lt;/h2&gt;

&lt;p&gt;PlotGPT es una herramienta que facilita la generación de visualizaciones simples de los datos usando a &lt;strong&gt;ChatGPT&lt;/strong&gt; como una interfaz. Se basa en &lt;strong&gt;ChatGPT&lt;/strong&gt; del lenguaje especializado en conversaciones, el rol que cumple es interpretar las peticiones del usuario y producir el código en Python y los gráficos correspondientes.&lt;/p&gt;

&lt;p&gt;La entrada de PlotGPT es una petición en &lt;em&gt;lenguaje natural&lt;/em&gt; que especifica el tipo y los datos a utilizar en el gráfico a generar, por ejemplo: "Show me a bar plot with the month revenues". El código generado se puede modificar para personalizar le gráfico posteriormente.&lt;/p&gt;

&lt;p&gt;Esta implementación no es más que una prueba de concepto que ilustra las posibilidades de ChatGPT cuando se combina con LangChain. No se trata de una solución optima ni definitiva, sino una forma de explorar las capacidades del modelo y sus limitaciones. Este proyecto ésta hecho con propositos de investigación y no se trata de un producto real.&lt;/p&gt;

&lt;p&gt;El primer paso es obtener nuestro &lt;em&gt;api key de OpenAI&lt;/em&gt; y configurarla como variable del sistema.&lt;/p&gt;

&lt;p&gt;Para obtener un &lt;em&gt;API key de openAI&lt;/em&gt;, puedes dirigirte al siguiente &lt;a href="https://platform.openai.com/" rel="noopener noreferrer"&gt;enlace&lt;/a&gt;, registrarte, y solicitarla.&lt;/p&gt;

&lt;p&gt;Despues vamos a instalar las siguientes librerias:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;pip&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="n"&gt;langchain&lt;/span&gt;
&lt;span class="n"&gt;pip&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="n"&gt;openai&lt;/span&gt;
&lt;span class="n"&gt;pip&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="n"&gt;pandas&lt;/span&gt;
&lt;span class="n"&gt;pip&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="n"&gt;matplotlib&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Una vez hecho esto, podemos empezar. Lo primero que tenemos que hacer para desarrollar la aplicación es crear nuestro sistema de archivos para organizar el código. Mi estructura es la siguiente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;carpeta_principal
|
+-- src
    |
    |_src.py
|_ main.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;El archivo src.py puede tener el nombre que prefieras. Yo le decidí llamar &lt;code&gt;templates.py&lt;/code&gt;, debido a que ahí tengo todos los templates de los prompts para ChatGPT.&lt;/p&gt;

&lt;p&gt;Lo primero que vamos a revisar es cómo hacer los &lt;em&gt;prompts&lt;/em&gt; para que ChatGPT haga lo que esperamos. La forma en que yo lo hice fue subdividir las tareas en 3 partes: la primera recibe el &lt;em&gt;prompt del usuario&lt;/em&gt; y genera código; la segunda extrae el código de Python; y la tercera detecta las dependencias del código generado, esto es con el propósito de saber si hay que instalar librerías adicionales.&lt;/p&gt;

&lt;p&gt;Para el primer ejemplo hice una estructura con 3 ejemplos, los cuales son los siguientes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;    &lt;span class="p"&gt;{&lt;/span&gt;        
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;question&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Can you select the &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt; and &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;age&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt; columns from the database&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;       
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;answer&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pandas_dataframe.loc[:, [&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;, &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;age&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;]]&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;    
        &lt;span class="p"&gt;{&lt;/span&gt;        
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;question&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Can you calculate the average of the &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;age&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt; column from the database&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;        
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;answer&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pandas_dataframe[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;age&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;].mean()&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;    
        &lt;span class="p"&gt;},&lt;/span&gt;    
        &lt;span class="p"&gt;{&lt;/span&gt;        
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;question&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Can you plot the &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;age&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt; and &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;income&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt; columns from the database&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;        
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;answer&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pandas_dataframe.plot(x=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;age&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;, y=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;income&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;    
        &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lo que pretendo hacer con estos ejemplos es proveer suficiente información al modelo sobre cómo resolver la tarea:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;El lenguaje de programación, en este caso Python.&lt;/li&gt;
&lt;li&gt;El uso de pandas para filtrar los datos.&lt;/li&gt;
&lt;li&gt;El formato de respuesta.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;El prompt completo que incluye todos los ejemplos es el siguiente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;    &lt;span class="n"&gt;database_query_prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;PromptTemplate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;input_variables&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;columns&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;query&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Following the reasoning: &lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;For example: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;examples&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;question&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;examples&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;answer&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;examples&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;question&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;examples&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;answer&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;examples&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;question&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;examples&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;answer&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;Within the following database we have the following columns&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{columns}. How can I {query} from the variable pandas_dataframe?. Give only one answer and don&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;t include any library imports. Actual code: \```

py import pandas as pd&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;import matplotlib.pyplot as plt&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;pandas_dataframe(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;db_csv&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;)&lt;/span&gt;&lt;span class="se"&gt;\
&lt;/span&gt;&lt;span class="s"&gt;
``` continue the code
        &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;,
    )
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;PromptTemplate&lt;/em&gt; Es un objeto que se comunica con LangChain para poder llevar a cabo la cadena de ejecución.&lt;/p&gt;

&lt;p&gt;El resto del prompt especifica a ChatGPT que siga los ejemplos anteriores, y también se les provee el nombre de las columnas del dataframe utilizado, y también se le provee el input del usuario, esto específicamente en este punto:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;columns&lt;/span&gt;&lt;span class="p"&gt;}.&lt;/span&gt; &lt;span class="n"&gt;How&lt;/span&gt; &lt;span class="n"&gt;can&lt;/span&gt; &lt;span class="n"&gt;I&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Los inputs variables son los identificadores de las variables dentro del template. Esto permite que LangChain pueda sustituir los identificadores por los valores correspondientes a la cadena, pero esto lo explicaremos más adelante.&lt;/p&gt;

&lt;p&gt;A continuación, defino otros parámetros como la variable &lt;code&gt;pandas_dataframe&lt;/code&gt;, y también especifico el formato de las respuestas y le indico a ChatGPT que utilice las librerías &lt;code&gt;matplotlib&lt;/code&gt; y &lt;code&gt;pandas&lt;/code&gt;. Después le pido que genere el código.&lt;/p&gt;

&lt;p&gt;El siguiente prompt que creé fue para filtrar la salida del primer prompt. La finalidad del segundo prompt es extraer únicamente el código del primero. Esto se debe a que la salida de ChatGPT no era muy precisa, pese a todas las indicaciones previas. Por eso, elaboré un segundo prompt con ejemplos que es el siguiente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;code_extraction_prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;PromptTemplate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;input_variables&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;generated_text&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
        This are 3 examples of how extract code from text:
           Begin Example 1
              User Input:
                The answer for the question can you make a program that prints hello world is:
                \```


                print(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hello world&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;)
                &lt;/span&gt;&lt;span class="se"&gt;\
&lt;/span&gt;&lt;span class="s"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;            However, the code is very basic because it only prints hello world.
          Your Output:
            \```
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                print("hello world")
            \
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;            End Example 1
            Begin Example 2
                User Input:
                    The answer for the "fibonacci sequence of 10" is:
                    def fibonacci(n):
                        if n &amp;lt;= 1:
                            return n
                        else:
                            return(fibonacci(n-1) + fibonacci(n-2))
                    print(fibonacci(10))
                    Note that the variable n is the number of the fibonacci sequence. is the number of the fibonacci sequence.
                Your Output:
                    \```


                    def fibonacci(n):
                        if n &amp;lt;= 1:
                            return n
                        else:
                            return(fibonacci(n-1) + fibonacci(n-2))
                    print(fibonacci(10))
                    \

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        End Example 2
        Begin Example 3
            User Input:
                The code for select the columns 'name' and 'age' from the database is:
                    pandas_dataframe.loc[:, ['name', 'age']]
                However it seems the columns names that you provide are not corect.
            Your Output:
                \```
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                pandas_dataframe.loc[:, ['name', 'age']]
                \
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;            End Example 3

            Now that you have seen 3 examples of how to extract code from text, please extract the code from the following text:
            Important:  Only give your answer, dont give any additional text, only the answer.

            User Input:
                {generated_text}
            Your Output: 
         """
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En este caso, integré los ejemplos al prompt completamente. Además, definí claramente dónde empieza y termina cada ejemplo. Por lo general, este segundo método funciona mucho mejor que el primero.&lt;/p&gt;

&lt;p&gt;Los 3 ejemplos muestran cómo extraer el código del prompt previo. Este prompt no depende del nombre de las columnas ni de las variables ni nada parecido. Su única función es separar el código del texto generado por ChatGPT. Después de los 3 ejemplos proporcionados se indica la tarea a realizar y se sigue el mismo formato que en los ejemplos.&lt;/p&gt;

&lt;p&gt;Decidí hacerlo así porque las IAs como ChatGPT están diseñadas para predecir la siguiente palabra de una secuencia. Así que si les das ejemplos de cómo completar la secuencia y al final les das una plantilla igual a la de los ejemplos es más probable que el modelo siga la secuencia de los ejemplos dados al inicio del prompt.&lt;/p&gt;

&lt;p&gt;Y para acabar le damos un prompt para obtener más información del código generado por ChatGPT con el siguiente y último prompt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;code_analysis_prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;PromptTemplate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;input_variables&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;generated_code&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
        There is a lot of information that can be extracted from code. I will give you 3 examples of how to extract information from code.
        Begin Example 1
            User Input:
                pandas_dataframe[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Sex&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;].value_counts().plot(kind=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;bar&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;)
                plt.xticks([0, 1], [&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Man&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;, &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Woman&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;])
                plt.show()
            Your Thought Process Will be:
                Dependencies: Pandas, Matplotlib
                Requires Plotting: True
                Requires Result Printing: False
            Your Output:
                [&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Pandas, Matplotlib&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;, True, False]
        End Example 1

        Begin Example 2
            User Input:
                def fibonacci(n):
                    if n &amp;lt;= 1:
                        return n
                    else:
                        return(fibonacci(n-1) + fibonacci(n-2))
                print(fibonacci(10))
            Your Thought Process Will be:
                Dependencies: None
                Requires Plotting: False
                Requires Result Printing: True
            Your Output:
                [&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;None&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;, False, True]
        End Example 2

        Begin Example 3
            User Input:
                pandas_dataframe[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;age&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;].mean()
            Your Thought Process Will be:
                Dependencies: Pandas
                Requires Plotting: False
                Requires Evaluation: True
            Your Output:
                [&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Pandas&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;, False, True]
        Can you give me Your Output for the following code supressing your thought process, is important that you only give me the output, not the input or any other text, and dont repeat &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Your Output:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt; Only give me the dependecies, requires ploting, and requires result printing nothing more.
            {generated_code}
        Your Output:
        &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aquí adopto un tercer patrón para optimizar los prompts. Como este proyecto es solo una muestra, los 3 prompts tienen patrones distintos. En este caso quiero que identifique las dependencias, si necesita generar un gráfico o si solo necesita evaluar el código y mostrar un resultado. Estas 3 categorías son fundamentales para saber cómo ejecutar el código, crear la plantilla o guardar una imagen del gráfico si hace falta.&lt;/p&gt;

&lt;p&gt;Cuando llegué a este último prompt pensé en formas más elaboradas de comunicarme con ChatGPT, pero vi que lo más sencillo era darle ejemplos de cómo obtener los valores finales y que me devolviera directamente una lista de Python fácil de &lt;em&gt;"parsear"&lt;/em&gt; con Python. Entonces le digo "Your Thought Process Will be"... Así ChatGPT sabe cómo conseguir los valores que va a poner en la lista.&lt;/p&gt;

&lt;p&gt;Ya enseñé los prompts, pero creo que antes de continuar con mi implementación hay que detenerse y preguntarse: ¿Por qué esto funciona realmente?&lt;/p&gt;

&lt;h3&gt;
  
  
  Stop para profundizar
&lt;/h3&gt;

&lt;p&gt;¿Recuerdas que al inicio hablamos sobre dejar la explicación del Few Shot Learning para el final?&lt;/p&gt;

&lt;p&gt;Sin embargo, los casos en que usamos los paradigmas One Shot y Zero Shot no entregaban buenos resultados. El nivel de especificidad de los resultados no era suficiente para desarrollar una aplicación. Esto se debe principalmente a que en el paradigma Zero Shot el modelo intenta adivinar lo que nosotros le estamos pidiendo y responder de una manera que satisface las condiciones que les entregamos.&lt;/p&gt;

&lt;p&gt;Por eso elegí el estilo Few Shot. El modelo tiene bastante más información sobre cómo realizar la tarea e incluso puede sortear las ambigüedades que irán apareciendo en la respuesta. En este caso el modelo no está encontrando la mejor forma de responder a una pregunta sino que está replicando el formato que le proveímos y adaptándolo a una respuesta generada por él mismo.&lt;/p&gt;

&lt;p&gt;Según mis observaciones para el desarrollo de tareas relacionadas con el NLU (Natural Language Understanding) siempre necesitaremos proveer ejemplos a los modelos de procesamiento del lenguaje actual.&lt;/p&gt;

&lt;p&gt;También es recomendable para evitar ambigüedades como en el último ejemplo darle ejemplos sobre cómo se llega a la respuesta final. Esto una vez más puede ayudar a quitar las ambigüedades que puedan presentarse en la respuesta del modelo. Una vez dicho esto vamos a continuar con la implementación.&lt;/p&gt;

&lt;h3&gt;
  
  
  Explicando el resto de la implementación en Python
&lt;/h3&gt;

&lt;p&gt;A continuación definimos las cadenas. Las cadenas son secuencias de pasos que permiten transferir la información desde nuestro programa a los modelos de lenguaje. Para ello debemos añadir el siguiente código en Python:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;    &lt;span class="n"&gt;chain_code_generation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;LLMChain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;database_query_prompt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;chain_code_extraction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;LLMChain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;code_extraction_prompt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;chain_code_analysis&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;LLMChain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;code_analysis_prompt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A continuación definí los parámetros de entrada del primer modelo en un diccionario y ejecuté la cadena completa. Luego realicé una limpieza básica a los resultados:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;    &lt;span class="n"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;columns&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;pandas_dataframe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;columns&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;query&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;output&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;chain_code_generation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;chain_code_extraction&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;generated_text&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Actual code is between the "\`\`\`py" and "\`\`\`"
&lt;/span&gt;    &lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s"&gt;`\`\`py&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;\`\`\`&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;analysis&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;chain_code_analysis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;generated_code&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;analysis&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Luego cree un par de funciones auxiliares para generar el archivo final y ejecutarlo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;code_inyection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;generated_code_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;db_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;model_code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;model_analysis&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Inyection&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;generated_code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="c1"&gt;# Agregamos pandas
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Pandas&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;model_analysis&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;generated_code&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;import pandas as pd&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# Agregamos matplotlib
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Matplotlib&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;model_analysis&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;generated_code&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;import matplotlib.pyplot as plt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Agregamos los preparativos teniendo en cuenta el nombre del dataframe es los ejemplo 
&lt;/span&gt;    &lt;span class="c1"&gt;# Proveidos en los prompts
&lt;/span&gt;    &lt;span class="n"&gt;generated_code&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pandas_dataframe = pd.read_csv(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;db_path&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;model_code&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;plt.show()&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;

    &lt;span class="c1"&gt;# Corregimos cualquier problema de indentaión
&lt;/span&gt;    &lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Model Analysis input: ["Pandas, Matplotlib", True, False]
&lt;/span&gt;    &lt;span class="c1"&gt;# Parseamos el analisis de dependencias
&lt;/span&gt;    &lt;span class="n"&gt;model_analysis&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model_analysis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;]&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"'"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;, &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# Guardamos el codigo y la imagen
&lt;/span&gt;    &lt;span class="n"&gt;plot_image_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;model_analysis&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;True&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;plot_image_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;plot.png&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="n"&gt;generated_code&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;plt.savefig(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;plot_image_path&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;generated_code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;generated_code&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;generated_code_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;w+&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;generated_code&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;generated_code_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;plot_image_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;generated_code&lt;/span&gt;

&lt;span class="c1"&gt;# Usamos os.system para ejecutar el codigo generado
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;execute_code&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file_path&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Excecuting&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;system&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;python &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;file_path&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para finalizar la implementación, cree una API Simple en Flask:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;src.templates&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;fake_db_lookup&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;code_inyection&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;execute_code&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;flask&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Flask&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;jsonify&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain.llms&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OpenAI&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;pathlib&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;
&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Flask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nd"&gt;@app.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;index&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="c1"&gt;# Función de prueba
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;jsonify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hello&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;World&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="n"&gt;llm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;openai_api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;OPENAI&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;temperature&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Parse the text query and return the code and analysis
&lt;/span&gt;&lt;span class="nd"&gt;@app.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/generate_code&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;methods&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GET&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;generate_code&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="c1"&gt;# Recibimos los parametros y extraemos el Query
&lt;/span&gt;    &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;query&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Si falta el Query enviamos un error
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;jsonify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;error&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;No query provided&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="c1"&gt;# Generamos el codigo 
&lt;/span&gt;    &lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;analysis&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;db_lookup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;file_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;plot_image_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;generated_code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;code_inyection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/home/yo/code.py&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;db.csv&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;analysis&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;execute_code&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file_path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;plot_image_path&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;absolute&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;plot_image_path&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Not Provided&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

    &lt;span class="c1"&gt;# Generamos una respuesta en JSON
&lt;/span&gt;    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;code&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;generated_code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;plot&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;


    &lt;span class="c1"&gt;# Retornamos la respuesta en formato JSON hacia el frontend
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;jsonify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;debug&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Y con eso tenemos cubierta la porción mas significativa del backend de mi implementación.&lt;/p&gt;

&lt;p&gt;No entraré en detalles con el frontend, lo unico que puedo decir es que use electron ya que la aplicación la pense para el uso local, pero igualmente el codigo del frontend y el backend estan disponibles en el siguiente enlace:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/harpiechoise/PlotGPT" rel="noopener noreferrer"&gt;https://github.com/harpiechoise/PlotGPT&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Resultados
&lt;/h2&gt;

&lt;p&gt;El dataset utilizado para hacer estas pruebas, es el dataset Titanic, se puede encontrar fácilmente en Kaggle.&lt;/p&gt;

&lt;p&gt;Prompt Original&lt;br&gt;
Can you select 'Sex' column and make a plot with a pie chart and replace the axis labels with 'men' and 'woman' respectively&lt;/p&gt;

&lt;p&gt;Resultado:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4q57g3ftpnn3xk7979h2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4q57g3ftpnn3xk7979h2.png" alt="Imagen resultado del prompt #1" width="800" height="410"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Prompt Original&lt;br&gt;
Can you select 'Sex' column and make a plot them with a bar chart then rotate the X axis labels 45° and make green and red bars respectly. &lt;/p&gt;

&lt;p&gt;Resultado:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjcjiclkpni1z4ntwv8hh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjcjiclkpni1z4ntwv8hh.png" alt="Imagen resultado del prompt #2" width="800" height="414"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Prompt Original:&lt;br&gt;
Can you make an histogram for 'Age' variable with 10 bins with the title "Age distribution on titanic dataset", with red colored bins?&lt;/p&gt;

&lt;p&gt;Resultado:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3qvj1sgkngvd62mfljxk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3qvj1sgkngvd62mfljxk.png" alt="Imagen resultado del prompt #3" width="800" height="408"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusión
&lt;/h2&gt;

&lt;p&gt;En este artículo hemos visto cómo ChatGPT representa una gran oportunidad para agilizar el desarrollo de aplicaciones que antes eran impensables gracias a su gran capacidad de generar textos coherentes y creativos a partir de una entrada entregada por el usuario. Hemos facilitado un punto de entrada para combinar expandir las capacidades de ChatGPT, este mismo patrón se puede aplicar con el fin de generar audio, imágenes, textos, etc. Sin duda siento que en el futuro saldrán otros avances para expandir las fronteras de lo que podríamos lograr gracias a la inteligencia artificial. &lt;/p&gt;

&lt;p&gt;Sin embargo, también hemos conocido que existen algunos riesgos y desafíos asociados a estos patrones de diseño, la ética y la seguridad de los contenidos es nuestra responsabilidad. Por ello, es que gracias a los patrones presentados tenemos la oportunidad de agregar una capa de seguridad a las respuestas del modelo, solo con el uso de prompts. &lt;/p&gt;

&lt;p&gt;En mi opinión, tecnologías como ChatGPT y los modelos similares aportan un avance muy valioso y si sabemos ver la oportunidad, podemos usarlo para facilitar nuestro trabajo y enriquecer nuestra experiencia de usuario. No obstante, tenemos que ser conscientes de sus limitaciones y potenciales peligros.&lt;/p&gt;

&lt;p&gt;Espero que este artículo te haya parecido interesante e informativo. Si tienes cualquier duda o comentario sobre el tema, puedes dejarlo en cualquiera de las publicaciones donde haya compartido el link a este artículo. Gracias por leer hasta el final y nos vemos en el próximo artículo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bibliografia
&lt;/h2&gt;

&lt;p&gt;Brown, T. B., Mann, B., Ryder, N., Subbiah, M., Kaplan, J., Dhariwal, P., Neelakantan, A., Shyam, P., Sastry, G., Askell, A., Agarwal, S., Herbert-Voss, A., Krueger, G., Henighan, T., Child, R., Ramesh, A., Ziegler, D. M., Wu, J., Winter, C., … Amodei, D. (2020). Language Models are Few-Shot Learners (arXiv:2005.14165). arXiv. &lt;a href="https://doi.org/10.48550/arXiv.2005.14165" rel="noopener noreferrer"&gt;https://doi.org/10.48550/arXiv.2005.14165&lt;/a&gt;&lt;br&gt;
Fedewa, J. (s.&amp;nbsp;f.). What Is ChatGPT, and Why Is It Important? Recuperado 20 de marzo de 2023, de &lt;a href="https://www.howtogeek.com/871071/what-is-chatgpt/" rel="noopener noreferrer"&gt;https://www.howtogeek.com/871071/what-is-chatgpt/&lt;/a&gt;&lt;br&gt;
Murzone, F. (2020, octubre 5). Procesamiento de texto para NLP 1: Tokenización. EscuelaDeInteligenciaArtificial. &lt;a href="https://medium.com/escueladeinteligenciaartificial/procesamiento-de-texto-para-nlp-1-tokenizaci%C3%B3n-4d533f3f6c9b" rel="noopener noreferrer"&gt;https://medium.com/escueladeinteligenciaartificial/procesamiento-de-texto-para-nlp-1-tokenizaci%C3%B3n-4d533f3f6c9b&lt;/a&gt;&lt;br&gt;
Raja, A. (s.&amp;nbsp;f.). (12) Zero-Shot, One-Shot, Few-Shot Learnings: How the different types of N-Short learning disciplines help Data scientists?! | LinkedIn. Recuperado 20 de marzo de 2023, de &lt;a href="https://www.linkedin.com/pulse/zero-shot-one-shot-few-shot-learnings-how-different-types-raja-csm/" rel="noopener noreferrer"&gt;https://www.linkedin.com/pulse/zero-shot-one-shot-few-shot-learnings-how-different-types-raja-csm/&lt;/a&gt;&lt;br&gt;
S, A. (S. F.). Welcome to LangChain—🦜🔗 LangChain 0.0.118. &lt;a href="https://langchain.readthedocs.io/en/latest/index.html" rel="noopener noreferrer"&gt;https://langchain.readthedocs.io/en/latest/index.html&lt;/a&gt;&lt;br&gt;
Shanahan, M. (2023). Talking About Large Language Models (arXiv:2212.03551). arXiv. &lt;a href="http://arxiv.org/abs/2212.03551" rel="noopener noreferrer"&gt;http://arxiv.org/abs/2212.03551&lt;/a&gt;&lt;br&gt;
Soto, J. A. (2019, diciembre 11). Winrar vs 7-Zip vs Winzip - ¿Cual es el mejor descompresor para Windows? - Guía. GEEKNETIC. &lt;a href="https://www.geeknetic.es/Noticia/17666/Winrar-vs-7-Zip-vs-Winzip-Cual-es-el-mejor-descompresor-para-Windows.html" rel="noopener noreferrer"&gt;https://www.geeknetic.es/Noticia/17666/Winrar-vs-7-Zip-vs-Winzip-Cual-es-el-mejor-descompresor-para-Windows.html&lt;/a&gt;&lt;br&gt;
Torres, M. E. (2020, abril 22). Modelos de lenguaje en el NLP. Medium. &lt;a href="https://monica-echeverrt.medium.com/modelos-de-lenguaje-en-el-nlp-8922dc34753b" rel="noopener noreferrer"&gt;https://monica-echeverrt.medium.com/modelos-de-lenguaje-en-el-nlp-8922dc34753b&lt;/a&gt;&lt;br&gt;
Wu, C., Yin, S., Qi, W., Wang, X., Tang, Z., &amp;amp; Duan, N. (2023). Visual ChatGPT: Talking, Drawing and Editing with Visual Foundation Models (arXiv:2303.04671). arXiv. &lt;a href="https://doi.org/10.48550/arXiv.2303.04671" rel="noopener noreferrer"&gt;https://doi.org/10.48550/arXiv.2303.04671&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Introducción a la computación cuantica (Parte 1)</title>
      <dc:creator>PyramidBuilder</dc:creator>
      <pubDate>Sat, 18 Feb 2023 00:09:41 +0000</pubDate>
      <link>https://dev.to/pyramidbuilder/introduccion-a-la-computacion-cuantica-parte-1-37dl</link>
      <guid>https://dev.to/pyramidbuilder/introduccion-a-la-computacion-cuantica-parte-1-37dl</guid>
      <description>&lt;p&gt;&lt;em&gt;La imagen de portada fue hecha por &lt;a href="https://unsplash.com/es/@manueljota?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Manuel&lt;/a&gt; y rescatada de &lt;a href="https://unsplash.com/es" rel="noopener noreferrer"&gt;Unplash&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;Esta es una serie donde voy a documentar mi proceso de aprendizaje, voy a investigar sobre la computación cuántica, como funciona, como programar con Qiskit y otros temas a futuro. Esta serie va a detallar mi viaje por el conocimiento de uno de los temas que en mi opinión personal considero importante para el futuro de la computación. &lt;/p&gt;

&lt;p&gt;La estructura de los artículos y su orden se basa en la estructura de distintos libros de computación cuántica que puedes encontrar en la bibliografía.&lt;/p&gt;

&lt;p&gt;Computación cuántica es un campo multidisciplinario que consiste en usar los fenómenos y conocimientos actuales de la mecánica cuántica a pequeña escala para poder realizar cálculos sobre estructuras informáticas con una mayor velocidad respecto a la computación cotidiana (computación clásica).&lt;/p&gt;

&lt;p&gt;Si bien los computadores cuánticos no ofrecen un reemplazo a los computadores actuales, si nos ofrecen un gran complemento para poder acelerar las capacidades de cómputo actuales. &lt;/p&gt;

&lt;p&gt;Actualmente, la computación cuántica se usa como complemento en muchos casos al hardware común. En este artículo veremos algunas diferencias y conceptos básicos para entender la computación cuántica y los artículos futuros. &lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Por qué es importante la computación cuántica?
&lt;/h2&gt;

&lt;p&gt;En 1985, en un artículo llamado "Simulating Physics with computers" publicado en 1982, Richard Feynman (Físico teórico) habló sobre el problema de simular la física cuántica con computación clásica, y planteo un sistema de computación para simular sistemas cuánticos con mayor precisión, ese sistema se llamó Computadora Cuántica. También planteo que los problemas que podía resolver el nuevo sistema de computación, no eran posibles de simular en una computadora clásica.&lt;/p&gt;

&lt;h3&gt;
  
  
  Superposición y el Q-Bit
&lt;/h3&gt;

&lt;p&gt;La superposición es algo curioso, nosotros damos por hecho de que si compramos un cuaderno rojo en la tienda, si lo llevamos a una capa de abstracción, podríamos pensar en el color del cuaderno como una propiedad, y tendríamos el color rojo como una constante en nuestra estructura, lo compramos rojo, no tendría sentido que mañana fuera azul. &lt;/p&gt;

&lt;p&gt;Ahora, si pensamos en términos de mecánica cuántica, es un poco distinto, el cuaderno sigue teniendo una propiedad color, el cual puede ser rojo y azul al mismo tiempo, es decir, pensando en términos cuánticos, el cuaderno en su propiedad de color tiene dos colores al mismo tiempo, es decir, es rojo y azul al mismo tiempo. &lt;/p&gt;

&lt;p&gt;Entendiendo que el color es una &lt;strong&gt;propiedad física&lt;/strong&gt; inherente al cuaderno, imagina que hacemos una medición sobre esa propiedad, lo curioso es que la medición solo nos arrojará un resultado, &lt;strong&gt;rojo&lt;/strong&gt; o &lt;strong&gt;azul&lt;/strong&gt;, nunca nos dará un indicio que es de dos colores al mismo tiempo. &lt;/p&gt;

&lt;p&gt;Aunque esto suene un poco extraño, es la forma exacta sobre como funcionan los Q-Bits, ahora hagamos el paralelo donde la propiedad de color, la renombramos como "espín". Pero más adelante volveremos a esta noción, pero para abrir el apetito, a decir lo siguiente: Las computadoras clásicas se basan en 0 y 1, y también hay una notación simbólica parecida en la computación cuántica y es, |0〉 y |1〉. Por ahora solo quédate con esta noción de la superposición y la propiedad de espín.&lt;/p&gt;

&lt;h3&gt;
  
  
  Aplicaciones
&lt;/h3&gt;

&lt;p&gt;El título intenta dar razones para aprender computación cuántica, y aquí vamos a repasar aplicaciones comunes para la computación cuántica. &lt;/p&gt;

&lt;h4&gt;
  
  
  Simulaciones Físicas
&lt;/h4&gt;

&lt;p&gt;La computación cuántica, como la planteó Feynman fue principalmente propuesta por su potencial de simular sistemas cuánticos complejos con mayor precisión, podríamos por ejemplo simular materiales, reacciones químicas, o interacciones moleculares. Esto nos podría ayudar a entender mejor estos sistemas y como manipularlos.&lt;/p&gt;

&lt;h4&gt;
  
  
  Machine Learning
&lt;/h4&gt;

&lt;p&gt;La computación cuántica podría acelerar de gran el proceso de entrenamiento y evaluación de modelos de Machine Learning, en la computación cuántica el aprendizaje de máquina aún es un campo relativamente prematuro, pero los avances de la tecnología nos ayudará a seguir expandiendo las capacidades de estas máquinas. &lt;/p&gt;

&lt;p&gt;Otra forma de aprovechar las capacidades cuánticas en este campo  es la computación híbrida, en esta se combinarían ambos enfoques, el clásico y el cuántico y de este modo hacer procesamiento de imágenes o procesamiento del lenguaje natural. &lt;/p&gt;

&lt;h4&gt;
  
  
  Finanzas
&lt;/h4&gt;

&lt;p&gt;También la computación cuántica puede tener aplicaciones en las finanzas, principalmente por su capacidad de optimizar y automatizar con más fidelidad el proceso de toma de decisiones de inversión, también se podría mejorar significativamente el proceso de evaluación de riesgos de inversión y significativamente mejorar las predicciones.&lt;/p&gt;

&lt;h4&gt;
  
  
  Criptografía
&lt;/h4&gt;

&lt;p&gt;La criptografía está más presente que nunca en nuestro día a día seamos conscientes o no. La criptografía clásica se apoya en un principio que informalmente se describiría así: "Confío que tu tecnología no es tan avanzada como para factorizar este gran número", ese gran número se llama llave, y nos sirve para encriptar y desencriptar mensajes&lt;/p&gt;

&lt;p&gt;Este campo está actualmente en crecimiento y hay bastante investigación al respecto. &lt;/p&gt;

&lt;h4&gt;
  
  
  Y más
&lt;/h4&gt;

&lt;p&gt;La computación cuántica aún es un campo poco explorado respecto a la computación clásica, por lo tanto, los avances están a la orden del día, y el número de aplicaciones igualmente va al alza, es por esto que te recomiendo que no cierres tu mente solo a las posibilidades expuestas aquí, hay mucho más que aún no se ha descubierto. &lt;/p&gt;

&lt;p&gt;¿En qué son diferentes las computadoras cuánticas a las clásicas?, si estás aquí es porque algo sabes del tema, siempre se dice que la computación cuántica es distinto a la computación clásica, pero ¿en qué son distintas?, ¿realmente sabes por qué lo son?&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Es el computador cuántico, parecido a un computador clásico?
&lt;/h2&gt;

&lt;p&gt;Cuando te sientas en tu computador, aunque sepas poco sobre &lt;em&gt;arquitectura de computación&lt;/em&gt;, sabes más o menos cuáles son las partes principales que componen tu computador, por ejemplo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CPU (Unidad de procesamiento central)&lt;/li&gt;
&lt;li&gt;RAM (Memoria de acceso aleatorio)&lt;/li&gt;
&lt;li&gt;GPU (Unidad de procesamiento de gráficos)&lt;/li&gt;
&lt;li&gt;Discos Duros&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;De todos estos dispositivos de la computación clásica, para entender la diferencia entre la computación cuántica y la clásica, primero detallaré como funcionan todos estos dispositivos, la placa madre y la fuente de poder se excluyen a propósito.&lt;/p&gt;

&lt;p&gt;Las unidades de procesamiento central, son los cerebros de nuestros computadores, y en la computación moderna se componen de distintas partes: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CU (Unidad de control)&lt;/li&gt;
&lt;li&gt;ALU (Unidad Aritmética Lógica)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No entraré en muchos detalles, sino que daré una explicación bastante escueta de cada una de las tareas que cumple cada una: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CU: La unidad de control decodifica las operaciones del ciclo de instrucciones. La principal (MU o RAM) función de la unidad de control es decodificar las instrucciones que se leen de la memoria principal del computador. La forma en que la unidad de control obtiene la información desde la memoria principal es usando el contador de programa (PC), el PC es un registro del procesador que retiene la dirección de la instrucción que se está ejecutando en el momento, alterando el registro se pueden acceder a distintos sectores de la RAM. La unidad de control también se encarga de regular la velocidad del ciclo de instrucciones, regulando la velocidad del reloj. La unidad de control igualmente regula las operaciones de varios componentes del hardware del computador, generando las señales de control. Estas señales de control son transmitidas al hardware a través de los Bus de control. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ALU: es la encargada de ejecutar las instrucciones aritméticas y lógicas, la unidad de control se encarga de decodificar la información como operandos y operadores para que la ALU pueda llevar a cabo las operaciones del procesador.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Las operaciones de las que se encarga la ALU son: suma, resta, incremento, decremento, and, or, xor, rotl, rotr, comparaciones y complementos.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;La memoria RAM funciona como un almacenamiento temporal, la RAM almacena valores en que se usan los programas para realizar sus operaciones, puede almacenar tanto resultados completos como incompletos. El procesador accede a la RAM para leer instrucciones, la dirección se almacena en el PC. A través de los buses de conexión de la RAM se pueden leer y escribir valores, cada vez que abrimos un programa en nuestros computadores, cada variable, instrucción, se va directamente a la memoria RAM.&lt;/p&gt;

&lt;p&gt;La GPU es un poco distinta al procesador, debido a que la GPU puede procesar una cantidad mayor de valores al mismo tiempo. Las GPU son sumamente eficientes en la manipulación, cálculo y transformación de matrices, es por eso que la forma principal de usarlas es a través de transformaciones lineales (&lt;a href="https://www.youtube.com/watch?v=YJfS4_m_0Z8&amp;amp;t=326s&amp;amp;ab_channel=3Blue1BrownEspa%C3%B1ol]" rel="noopener noreferrer"&gt;¿Qué son las transformaciones lineales?&lt;/a&gt;). Las GPU también tienen su memoria RAM donde almacenan los datos que el procesador mueva para que la GPU pueda calcular y comunicar los resultados de vuelta a la unidad de control.&lt;/p&gt;

&lt;p&gt;Teniendo todo esto en cuenta, quizás una de las representaciones más pobres en donde encaja nuestro computador cuántico, es en la comparación directa con la GPU, Aunque son distintos a las GPU en la mayoría de los aspectos, ambas requieren al álgebra lineal para comunicarse, quizás la forma de trabajar con ambos sea totalmente distinta, pero su funcionamiento más que pensar en una pieza de Hardware completa como la que tenemos en nuestros hogares, bolsillos etc., es pensarlo como un complemento para acelerar la computación. &lt;/p&gt;

&lt;h2&gt;
  
  
  Aritmetica
&lt;/h2&gt;

&lt;p&gt;Como bien sabemos, los procesadores normales trabajan con la aritmética binaria. La forma en que tenemos de generar resultados con los computadores convencionales es a través de manipulación de bits. Los bits tienen un valor conocido que puede ser 1 o 0. Por otro lado, en la computación cuántica, tenemos que hacer manipulación de Qbits, estos pueden estar en un estado de superposición, es decir, que pueden ser 0 y 1 a la vez. &lt;/p&gt;

&lt;p&gt;La manipulación de Qbits se basa en las leyes de la mecánica cuántica, lo cual puede llevarnos a fenómenos cuánticos como la interferencia o entrelazamiento cuántico. Pero el funcionamiento de los Qbits a fondo, será tema para el siguiente artículo, espero que este artículo haya servido para abrir tu apetito respecto al potencial de la computación cuántica. &lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusión
&lt;/h2&gt;

&lt;p&gt;Si bien la computación clásica no será reemplazada por la computación cuántica, es importante aprender a usarla, ya que puede acelerar la capacidad de cómputo considerablemente. Hoy en día "computación cuántica" es un término empleado por las personas comunes, pero no todas saben exactamente a que se refiere, espero este primer artículo te dé una mejor idea sobre a lo que se refiere el término "computación cuántica".&lt;/p&gt;

&lt;h2&gt;
  
  
  Agradecimientos
&lt;/h2&gt;

&lt;p&gt;Si estás leyendo esto, te agradezco el interés por este artículo, recuerda compartirlo con tus contactos, seguirme para estar enterado de los futuros artículos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bibliografia
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Sutor. Robert. &lt;em&gt;Dancing with Qubits&lt;/em&gt;. 1st ed. Packt Publishing Ltd.; 2019.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fisher, Tim. Everything You Need to Know About Computer Hardware. Lifewire. Accessed February 17, 2023. &lt;a href="https://www.lifewire.com/computer-hardware-2625895" rel="noopener noreferrer"&gt;https://www.lifewire.com/computer-hardware-2625895&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Wong D. How to Backdoor Diffie-Hellman. Accessed February 17, 2023. &lt;a href="https://eprint.iacr.org/2016/644.pdf" rel="noopener noreferrer"&gt;https://eprint.iacr.org/2016/644.pdf&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Wong D. How to Backdoor Diffie-Hellman. Published online 2016. Accessed February 17, 2023. &lt;a href="https://eprint.iacr.org/2016/644" rel="noopener noreferrer"&gt;https://eprint.iacr.org/2016/644&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ledin J, Farley D. &lt;em&gt;Modern Computer Architecture and Organization: Learn x86, ARM, and RISC-V architectures and the design of smartphones, PCs, and cloud servers, 2nd Edition&lt;/em&gt;.; 2022.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;IBM. Quantum computing use cases for financial services. IBM. Published September 12, 2019. Accessed February 17, 2023. &lt;a href="https://www.ibm.com/thought-leadership/institute-business-value/en-us/report/exploring-quantum-financial" rel="noopener noreferrer"&gt;https://www.ibm.com/thought-leadership/institute-business-value/en-us/report/exploring-quantum-financial&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Grasselli F. &lt;em&gt;Quantum Cryptography: From Key Distribution to Conference Key Agreement&lt;/em&gt;. Springer International Publishing; 2021. doi:10.1007/978-3-030-64360-7&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Li T, Yin ZQ. Quantum superposition, entanglement, and state teleportation of a microorganism on an electromechanical oscillator. &lt;em&gt;Science Bulletin&lt;/em&gt;. 2016;61(2):163-171. doi:10.1007/s11434-015-0990-x&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Feynman RP. Simulating physics with computers. &lt;em&gt;Int J Theor Phys&lt;/em&gt;. 1982;21(6):467-488. doi:10.1007/BF02650179&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sutor. Robert. What’s inside a computer? In: &lt;em&gt;Dancing With Qubits&lt;/em&gt;. 1st ed. Packt Publishing Ltd.; 2019:445.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>react</category>
      <category>productivity</category>
      <category>refactor</category>
    </item>
  </channel>
</rss>
