Agents d’IA LLM programació amb IA MCP Subagents BettaTech Harness engineering Go

Com construir un agent de codi amb IA des de zero: el harness de BettaTech en Go

BettaTech desmunta un agent de programació peça per peça i publica un projecte educatiu en Go. El vídeo explica el bucle agentiu, les eines, els permisos, els proveïdors, els subagents, la memòria i la compactació del context.

Què transforma un model de llenguatge en un agent capaç de llegir fitxers, executar ordres i delegar feina? BettaTech dedica gairebé 49 minuts a construir aquesta capa intermèdia, coneguda com a harness o arnès, i a explicar les decisions que normalment queden amagades dins d’eines com els agents de programació. El resultat és Build Your Own Coding Agent, un repositori educatiu en Go amb llicència MIT i una guia web en castellà i anglès.

La idea central és senzilla: el model és el motor, però el harness decideix què veu, què recorda, quines eines pot tocar i quan ha de tornar a preguntar. El vídeo no presenta un producte llest per desplegar en producció. Presenta una base deliberadament llegible perquè qualsevol desenvolupador pugui modificar-la, trencar-la i entendre com canvia el comportament de l’agent.

Dos bucles converteixen el xat en un agent

BettaTech compara l’arquitectura amb el game loop d’un videojoc. A la capa exterior hi ha un bucle REPL: llegeix l’entrada de l’usuari, l’avalua, mostra el resultat i torna a esperar. És el que veiem a la terminal quan escrivim una instrucció i, al final, recuperem el cursor.

La part decisiva és el bucle interior. El harness envia el missatge, l’historial, el system prompt i les definicions d’eines al model. La resposta pot ser text final o una petició per utilitzar una eina. Si demana llegir un fitxer, el programa executa aquesta operació, incorpora el resultat a la conversa i torna a cridar el model. El cicle continua fins que la resposta indica que la tasca ha acabat. El model proposa l’acció; és el codi local qui realment l’executa.

El repositori inclou un exemple mínim d’unes poques centenes de línies per fer visible aquest mecanisme abans d’afegir-hi abstraccions. Aquesta separació ajuda a entendre que un agent no és una sola resposta especialment llarga, sinó una successió controlada de decisions, accions i observacions.

Eines amb descripció, esquema i porta de permisos

Les primeres eines del projecte permeten executar ordres de shell, llegir fitxers i escriure’n. Cada eina té una definició que el model rep —nom, descripció i paràmetres— i una implementació que només coneix el harness. Una descripció ambigua pot fer que el model triï malament; una implementació insegura pot convertir una petició equivocada en una ordre real sobre l’ordinador.

Per això el projecte interposa una porta d’aprovació abans de l’execució. L’usuari veu què s’intenta fer i pot acceptar-ho o rebutjar-ho. La guia també proposa evolucionar aquest mecanisme cap a polítiques diferents: permetre lectures, preguntar per ordres de shell o denegar escriptures fora del directori de treball. És una distinció important: donar eines al model no implica haver de concedir-li autoritat il·limitada.

L’especificació de Model Context Protocol reforça aquesta precaució: les eines poden desencadenar execució de codi i el host ha de controlar consentiment, autorització i fronteres entre components. El vídeo aplica el mateix principi encara que l’exemple inicial sigui local.

Canviar de model sense reescriure l’agent

El primer prototip parla directament amb l’SDK d’Anthropic. La versió completa introdueix una interfície Provider perquè la resta del programa treballi amb missatges, eines i respostes genèriques. Cada adaptador tradueix aquests tipus al format concret d’Anthropic, OpenAI o qualsevol backend local que s’hi vulgui afegir.

Aquesta capa evita escampar dependències específiques per tot el codi. També permet crear un proveïdor simulat per fer proves sense gastar tokens. El model i el proveïdor es poden canviar durant una sessió, però això no converteix tots els backends en equivalents: cada API té capacitats, formats, costos i comportaments propis que l’adaptador ha de gestionar.

La documentació d’Anthropic confirma el flux que es veu al vídeo: el client envia les definicions de les eines, Claude pot retornar un bloc de petició d’eina i l’aplicació client n’executa la implementació. El patró no depèn d’una interfície gràfica concreta.

Subagents: una eina que obre un altre bucle

El projecte encapsula un agent com la combinació d’un proveïdor, un system prompt, un historial i un conjunt d’eines. Això permet instanciar un agent arrel i crear subagents especialitzats. Un podria investigar sense permisos d’escriptura; un altre podria treballar només amb Git.

La delegació tampoc és màgia. El harness registra una eina que, quan el model la selecciona, crea un altre agent i posa en marxa un nou bucle interior. El desenvolupador decideix quina descripció veu l’agent principal, quines eines rep el subagent i si hereta o no l’historial. En l’exemple, el subagent comença amb context buit. Aquesta decisió redueix soroll, però obliga a passar-li explícitament tota la informació necessària.

El valor del disseny és precisament fer visibles aquestes opcions. Dos productes amb el mateix model poden comportar-se de manera molt diferent si un comparteix tota la conversa amb els subagents i l’altre els aïlla.

Context, compactació, memòria i cost

Una sessió llarga acumula missatges i cada nova crida pot reenviar una part considerable de l’historial. El harness ofereix estratègies intercanviables: no compactar, conservar una finestra recent o demanar al mateix model que resumeixi els torns antics. Aquesta última opció estalvia context posterior, però també consumeix tokens i pot perdre detalls.

El mode de depuració mostra el payload enviat, la resposta, els tokens i una estimació del cost. Així es veu que un AGENTS.md extens o un system prompt inflat es torna a pagar a cada torn. El mode detallat també permet comparar l’historial abans i després de compactar-lo.

La memòria persistent es resol amb dues eines més: recordar i desar. La implementació de mostra utilitza fitxers JSON i un índex de sessions, però la interfície es podria connectar a SQL o a un servei remot. El model decideix quan invocar-les segons la descripció; el programa determina com es busca, què es conserva i durant quant de temps.

MCP, interfície de terminal i extensió del projecte

Per connectar serveis externs, BettaTech embolcalla les eines de MCP dins del mateix registre. La configuració carrega servidors i incorpora les seves eines; la càrrega es fa en paral·lel per no bloquejar la interfície. MCP defineix una arquitectura host-client-servidor i primitives comunes per descobrir i cridar eines, recursos i prompts, però no decideix com l’aplicació administra el context.

La interfície de terminal està construïda amb Bubble Tea. A sobre del bucle s’hi afegeixen ordres com /help, /provider, /compact, /tokens, /debug i /subagents. Són comoditats útils, no el nucli agentiu: el mateix sistema podria presentar-se com una web, una CLI mínima o una aplicació d’escriptori.

La web del projecte ordena el material en vint lliçons, guies pràctiques i exercicis. Entre les ampliacions proposades hi ha reintents després d’errors, subagents definits en Markdown, noves polítiques de permisos i proveïdors addicionals. El repositori, per tant, funciona alhora com a codi executable i com a itinerari d’aprenentatge.

Conclusió: una base per aprendre, no un producte acabat

El principal mèrit del projecte és reduir l’agent a peces comprensibles: bucle, proveïdor, eines, permisos, context, memòria i delegació. En veure-les separades, queda clar que bona part de la qualitat percebuda no depèn només del model, sinó de les decisions que pren el programa al seu voltant.

També cal respectar el límit que assenyala l’autor. És un laboratori educatiu, no una garantia de seguretat, robustesa o bones pràctiques de producció. Abans d’utilitzar-lo amb repositoris sensibles caldria reforçar l’aïllament, validar entrades, provar errors i reintents, limitar ordres i revisar la persistència de dades. Com a mapa per entendre i experimentar amb l’enginyeria de harness, però, ofereix un punt de partida excepcionalment transparent.

Contrast i context

Fonts consultades

6 fonts
  1. 01
  2. 02
  3. 03
  4. 04
  5. 05
    Model Context Protocol Architecture overview
  6. 06

Font de treball

Transcripció amb marques de temps

15 fragments
Consulta la transcripció
  1. 0:00 , obre el vídeo en una pestanya nova

    Hoy vamos a construir un arnés desde cero. Y cuando digo arnés, me refiero a un arnés completo, a toda la estructura que permite que un modelo de inteligencia artificial deje de ser un chatbot y empiece a ser realmente un agente. Un sistema capaz de razonar en un bucle, capaz de utilizar herramientas, capaz de delegar tareas a otros agentes y también trabajar con un contexto razonable. Y no solo eso, sino que te voy a dar un repositorio extensible a modo de tutorial para que tú puedas experimentar, jugar y hasta construirte tu propio de inteligencia artificial. Vamos a ello. Pero antes de entrar en los detalles específicos de código, te quiero contar algunos conceptos que tienes que entender para realmente poder construir un arnés con sentido. Y es que este vídeo es la tercera parte de una serie en la que hablamos de Harness Engineering. Habíamos hecho un vídeo introductorio explicando qué es esta disciplina. Habíamos hecho un vídeo modificando un arnés ya existente y ahora vamos a hacer un arnés desde cero. Y es que a nivel conceptual es un poco difuso dónde empieza y dónde termina un arnés. A mí me gusta verlo como si fueran unas capas de una cebolla en las que nosotros podríamos tener aquí abajo la primera capa, el núcleo de nuestro arnés, que sería directamente el código que ejecuta las llamadas a la Llm, ¿vale? Es decir, aquí dentro tendríamos pues yo que sé el SDK de Clou, ¿no? El SDK de Open o en general pues la conectividad, las llamadas que hacemos al modelo, esto es la parte del cerebro y digamos la el control, ¿no?, de este cerebro. Y luego tendríamos otras capas que podrían ser, pues por ejemplo, aquí tendríamos la creación de tools, la creación de subagentes o incluso la creación de skills que también pueden afectar al comportamiento de esta capa interna. Es decir, aquí lo que tendríamos es que hay como una serie de conexiones en las que nosotros podemos actuar. Lo que hicimos en los vídeos anteriores fue agarrar un arnés que ya existía. En este caso estábamos utilizando Cloude, Cloud Code en específico, y modificábamos esta capa de aquí, pues gestionando, por ejemplo, un flujo de SDD. ¿Cómo? pues generando subagentes, generando tools que controlaran, pues por ejemplo cómo nosotros o cómo este cerebro, esta parte más core del arnés gestiona todo esto. En este vídeo lo que vamos a ver es a crear esta parte de aquí dentro, a crear este core, este binario y podríamos incluso verlo como crear nuestro propio cloud code. Entonces, ¿qué forma parte de este cerebro, de este binario, de esta parte más interna de nuestro arnés? lo que se conoce como el bucle de la gente. Y a mí me gusta explicar esta parte como visualización de un videojuego, ¿no? Si has programado videojuegos, seguramente esta parte la vayas a entender muy bien. Y es que en general cuando nosotros estamos programando videojuegos, tenemos un concepto que se llama game loop, que es básicamente qué ocurre en cada frame de nuestro juego. Pues por ejemplo, en un juego que va a 60 frames por segundo, lo que tendríamos es un bucle en el que lo

  2. 3:15 , obre el vídeo en una pestanya nova

    primero que hacemos es leer el input del usuario. Por ejemplo, si el usuario ha pulsado una tecla en el teclado o si ha hecho un movimiento con el mando o si ha hecho clic con el ratón en algún sitio para disparar, leemos la entrada, ese input es lo que primero ocurre en el frame. Luego tenemos la actualización del estado del juego, es decir, en base a este input, ¿qué tenemos que modificar de nuestro estado del juego? Tenemos que mover al personaje, tenemos que accionar el disparo, tenemos que aumentar la vida. Aquí entrarían, pues, por ejemplo, sistemas de física y todo esto. Luego tendríamos el renderizado del nuevo estado, es decir, una vez hemos hecho la acción sobre el estado del juego, ¿cómo se ve esto en pantalla? Tenemos que mostrar ahora un flash porque hemos disparado. Tenemos que mostrar un corazón extra porque nos hemos curado. Tenemos que mover al personaje realmente para que se renderice conforme se ha movido. Activar una animación. Finalmente, una vez hemos terminado, volveríamos a empezar el bucle del juego y así infinitamente. Así es modo de resumen cómo nosotros programaríamos un videojuego. Pues lo mismo tenemos que implementar cuando implementamos un agente. Cuando implementamos un sistema de agentes, un arnés, nuestro bucle es muy similar. Lo que tendríamos es también un bucle en el que hacemos read de la entrada, en este caso del usuario. Sería cuando nosotros escribimos, ¿no?, en abrimos cloud code, tenemos el input de chat y escribimos algo. Luego nosotros evaluamos esta entrada, es decir, hacemos algo con ella. Recordemos en el videojuego actualizábamos el estado, pues aquí agarramos la entrada y decidimos qué hacer. Se la mandamos al SDK de nuestra illa preferida. Hemos implementado que si nosotros escribimos, por ejemplo, barra command, nuestro arnés no lo delegue a la sino que ejecute algo interno para mostrarnos, por ejemplo, el listado de comandos. Hemos hecho que si el usuario escribe la palabra caca, aparezca una caca por ahí e en aski diciéndonos algo. ¿Cómo reaccionamos a nuestra entrada? Sería esta fase. Luego tendríamos la parte de print o de imprimir, es decir, cómo reacciona nuestra UI, cómo le mostramos al usuario lo que está ocurriendo, el resultado, ¿vale? Y finalmente tendríamos la parte de bucle que nos indicaría que tenemos que volver a empezar todo el bucle. Fijaros que es el mismo bucle que teníamos en un videojuego en literatura, en artículos de internet, en algunos sitios lo vais a ver como rpl, un bucle reple o un bucle de evaluación, básicamente por las siglas de read, eval, print y loop. Entonces, en este caso nosotros tendríamos un bucle que sería el bucle RPL que lo podríamos visualizar como algo así, ¿no? Lo que ya hemos comentado. Ahora bien, la parte de evaluación no es tan sencilla como parece. Cuando nosotros tenemos el input aquí y le damos a enter, lanzamos la fase de evaluación. Pero fíjate que la fase de evaluación puede tener múltiples pasos. En este caso, ahora solamente nos ha hecho un paso. Fijaros que hemos vuelto a la parte inicial del bucle, que es otra vez esperar un input. Pero si nosotros le vamos pidiendo cosas que son cada vez más complicadas a nuestro bucle, va a llegar un momento donde tenemos que hacer varias peticiones a la inteligencia artificial. En este caso le he pedido que lea diferentes ficheros,

  3. 6:31 , obre el vídeo en una pestanya nova

    por lo tanto, cada vez va ejecutando lo que se conocen como herramientas. Va decidiendo pues qué ficheros de leer, lee uno, luego lee el otro. Es decir, dentro de la propia fase de evaluación van ocurriendo múltiples cosas. En este caso, lo que significa es que dentro de esta fase de EVAL tenemos lo que se conoce como el bucle interno. Es el bucle interno el que se va comunicando con la LM, con nuestro proveedor de inteligencia artificial, en este caso con el SDK de Antropic, con el SDK de Open con nuestra IA local, lo que necesitemos. Y aquí lo tendríamos definido. ¿Qué ocurre dentro de el bucle interno del bucle de evaluación? Pues básicamente lo que podemos hacer es llamamos al modelo y el modelo nos dice qué cosas tiene que hacer. Si lo puede hacer directamente, como hemos visto, nos va a responder. Terminamos el bucle. Ahora bien, puede que tenga que ejecutar alguna tool. Veremos después cómo se implementan las tools, pero por ejemplo, una tool podría ser leer un fichero. Por lo tanto, el modelo decide que tiene que leer un fichero, devuelve lo que se conoce como un tool use, es decir, necesito utilizar esta tool. Entonces, aquí leemos el fichero, que lo podemos entender también de una forma más abstracta cómo se ejecuta la tool. Y esto lo vamos repitiendo. Se ejecuta la tool, se lo volvemos a pasar al modelo de IA, es decir, vamos a hacer una llamada, el modelo de IA decide si tiene que ejecutar otra tool o si ya termina. Vamos haciendo todo este flujo. Por lo tanto, todo esto es un bucle que una vez que el modelo diga ya he terminado, ya no tengo que hacer más llamadas a ninguna herramienta y ya puedo dar una respuesta, lo devuelve al bucle principal, al bucle RPL. Por lo tanto, si te has quedar con algo de lo que sería la agent loop, es que son dos bucles. El bucle grande que gestiona la interacción que tú ves con el usuario y el bucle pequeño, que es cuando tú le das a enter y ves que la está empezando a hacer cosas que ahora se va a un fichero, que ahora se va otro, que ahora escribe algo, que ahora escriben una cosa. Todo esto es el bucle interno, ¿vale? Y cuando termina vuelves a empezar. ¿Cómo se ve esto en código? Pues lo que hemos implementado en este repositorio es un bucle sersencillito para demostrar, para enseñar exactamente cómo lo puedes hacer tú por tu cuenta. Hemos utilizado Gol para hacer este proyecto porque al final el lenguaje no es tan importante. La idea es que tú puedas ver esto y entender el concepto. Y lo que hemos visto es, vale, nos vamos a generar una función main. Fijaros que aquí estamos importando la biblioteca, ¿no? La dependencia de Antropic, porque de momento este bucle lo vamos a tener con el modelo de Antropic, con Cloue, con Opus concretamente. Y fíjate que aquí empezamos con nuestro primer loop. En este caso imprimimos nada, una flechita para indicar que el usuario puede escribir. Y una vez el usuario ha escrito algún tipo de texto, algún tipo de prompt, se lo mandamos a Antropic, se lo mandamos a LDK para generar lo que sería el contexto, ¿vale? Aquí nosotros estamos generando el contexto que nosotros le vamos a mandar con esta función Newages. Fijaos que aquí empieza ya el agent loop, que sería el bucle interno. Es decir, este bucle de aquí es el bucle RP y este bucle de aquí es el bucle interno, el bucle de evaluación. Fijaos que el bucle de evaluación recibe, como he dicho, eh, el contexto, recibe el historial de mensajes y en

  4. 9:44 , obre el vídeo en una pestanya nova

    este caso lo que hacemos es construir los mensajes ya pensando en el SRDK de Antropic, ¿vale? Esto al final es una API que nosotros tenemos que podemos utilizar y aquí le estamos mandando directamente estos mensajes a la IA. Aquí ya estamos haciendo la llamada a nuestra llent.messages.new. Estamos haciendo la llamada a la Llm diciéndole, "Ey, tengo este mensaje de usuario." Y la LM me da una serie de respuestas. Fíjate que los mensajes de respuesta son también un array. ¿Por qué? Porque puedo recibir, como he dicho, diferentes respuestas o diferentes llamadas a diferentes herramientas. En este caso, lo que tengo que hacer es ir iterando todo este bloque de respuestas. Esto sería el bucle de ejecución, ¿no?, de cada una de las respuestas. Y fíjate que lo que hacemos es distinguir cuando me está diciendo una respuesta directamente contexto, con este caso de aquí de antropic text o cuando me está diciendo, "Ey, quiero ejecutar una herramienta." Si quiere ejecutar una herramienta, porque la LM considera que tiene que leer un fichero, que tiene que hacer un comit, que tiene que hacer cualquier cosa, que tiene que invocar un MCP, lo que sea, si detecta que ha de ejecutar una herramienta, tengo aquí una función que se llama ejecutar herramienta. Entonces la ejecuta, devuelve los resultados y finalmente cuando termina el bucle interno, en este caso con un stop reason que ya he terminado de hacer todas las ejecuciones, devuelve. Por lo tanto, fíjate que aquí tenemos el agent loop, que sería el bucle interno. Una vez termina el bucle interno, esto vuelve a empezar. ¿Qué pinta tendría esto cuando yo lo ejecuto? Pues mira, si yo me descargo el repositorio, que te dejo aquí abajo en la descripción, pues mira, si yo hago go run examples minimal main.goo para ejecutar este código que tengo aquí, yo le doy y fíjate que me sale esto de aquí. Ahora tengo el bucle RPL esperando a mi input. Yo le puedo decir, "Hello, ahora está ejecutando la llamada a la Llm y ya me ha contestado." Esto por detrás está haciendo la llamada a la API de Cloue con eh el API Key, que tenga una variable de entorno y por lo tanto lo está pudiendo hacer de forma correcta. Yo le puedo decir ahora, por ejemplo, how many files are there in this folder? Para que instancie una herramienta y me pida ejecutar. En este caso, fijaros que me está queriendo ejecutar esta herramienta de aquí, la herramienta de bash. ¿Qué serían estas herramientas que yo tengo aquí definidas? Pues mira, las tengo aquí abajo. En Execute Tool tengo la implementación de cada una de estas herramientas. Pues tengo en este caso la herramienta de bash, ¿vale?, que está aquí arriba definida y aquí la tengo. En el caso de que la Llera ejecutar bash, lo que tengo que hacer es en este caso ejecutar bash. Entonces, fíjate que estoy programando las herramientas que la IA va a poder utilizar. La IA no ejecuta las herramientas. La ella solamente las conoce y le dice al arnés, "Ey, quiero ejecutar esta herramienta." Es como ver el martillo en la mesa y decirle al arnés, quiero utilizar este martillo. Pero el LM no sabe si el martillo golpea o no golpea. Eso lo hace el arnés. El arra lo que la LM le pide y lo ejecuta en tu maquina, ¿vale? Entonces, fíjate que tengo para ejecutar bash para leer un fichero, que en este caso lo que tengo es directamente leerlo, ¿vale?, con read file y escribirá un fichero, que en este caso es escribirlo con WR file. Por lo tanto, yo aquí me programo las herramientas.

  5. 13:01 , obre el vídeo en una pestanya nova

    ¿Cómo la LLM sabe las herramientas a las que tiene acceso? ¿Cómo sabe que tiene que o que puede ejecutar bash? Porque cuando yo aquí me he construido este sistema, este ar tan pequeñito, fíjate que al SDK de Antropic le estoy pasando las herramientas que existen. Yo le tengo que decir al proveedor, ¿vale? En este caso, al SDK de Antropic, si fuera el SDK de Open seguramente tendría que hacer esto diferente y no todos los SDK soportan tools, por lo que hay que mirar eso, la documentación de cada proveedor de IA. Pero en este caso yo le digo al SD Tropic, mira, tienes la tool de bash, la tool de leer ficheros y la tool de escribir ficheros. Y fijaros que le paso la información necesaria para que la LM sepa que ha de usar. Le digo, "Mira, la tool de Bash ejecuta un comando shell y devuelve lo que devuelve a STD out y a STD." Leer fichero. Pues mira, es una tool que lee los contenidos de un fichero en un paz concreto y le digo los parámetros necesarios que le tengo que pedir a la IA. Okay, estoy mostrándole a la inteligencia artificial las herramientas a las que tiene acceso. Si yo no le defino una buena descripción, es posible que la IA no sepa que tiene que utilizar bash para hacer esto que tiene que hacer. ¿De acuerdo? Por lo importante definir bien la descripción porque en función de esto es la propia LLM quien por inferencia decide qué herramienta usar. Entonces, fíjate que yo simplemente diciéndole cómo, cuántos ficheros hay en esta carpeta, ella ya sabe que tiene que utilizar bash. Si yo le digo, "Rite me a new file with the word hello" in it, seguramente va a saber que tiene que ejecutar write file y aquí está, ha encontrado este esta tool y me la ha llamado. Entonces, esto sería el bucle principal y la definición de herramientas en un arnés de inteligencia artificial. Como veis, son 175 líneas de código simplemente con la dependencia externa de el Antropic SDK. Por lo tanto, los arneses son muy sencillos. Ahora bien, todo lo que construyas por encima de este bucle, de la gestión de las herramientas, de cómo yo llamo a la gente, de cómo interactúo con el bucle, van a ser cosas extra que yo le voy enchufando al arnés. Entonces, ahora mismo tenemos construido algo como esto. Tenemos en la parte del LLM, pues la definición de las tools, pero claro, cuando yo estoy construyendo un arnes propio, el gran poder o la gran capacidad que yo tengo cuando construyo un tipo de arnes así es poder cambiar el modelo de IA. Yo quiero poder agarrar esta LLM y que este LLM, pues por ejemplo, sea o bien clou o sea Codex. O sea, o llama, quiero poder cambiar el modelo de una forma sencilla. ¿Cómo puedo hacer esto? Con polimorfismo. De la misma manera en el que yo aquí dentro tengo este SDK y estoy llamando directamente a los SDK de Antropic, yo puedo generarme un sistema polimórfico para poder cambiar estas piezas bajo demanda. Es decir, yo me puedo generar en mi lenguaje favorito, pues yo que sé,

  6. 16:13 , obre el vídeo en una pestanya nova

    una clase, una interfaz que sea provider. en la que yo defino una serie de funcionalidades, pues por ejemplo, definirme una tool, eh, mandar un mensaje, cualquier cosa que yo necesite en mi arnessés y luego tener el Antropic Provider, el Open Provider y así poder soportar diferentes modelos de inteligencia artificial, como lo he montado yo en este repositorio. Si te vas a la carpeta internal de este repo, vas a poder ver exactamente todo lo que se está montando. Y tenemos aquí una parte que es la carpeta de provider que como ves tiene diferentes ficheros de Golan. Te voy a enseñar el fichero agnóstico, ¿vale? Lo que sería la interfaz o la parte más polimórfica, que es este fichero de provider.goo. Fíjate que provider.goo go simplemente me define una interfaz en la que yo puedo setear el modelo y leer el modelo. Básicamente porque, por ejemplo, Antropic tiene diferentes modelos, tenemos Opus, tenemos Sonet, Openite también tiene diferentes modelos, incluso versiones de cada uno y me ofrece una función para yo enviarle un mensaje. Date cuenta que le mando un mensaje, le mando las tools que tiene disponibles y le mando un contexto. Y obviamente esta interfaz me tiene que devolver una respuesta. Fíjate que todos estos tipos que hay aquí, el API Message, API Tool Def y API Response, son tipos genéricos, son tipos que yo me he creado. ¿Por qué? Porque cada SDK va a ser de su padre y de su madre. Cada SDK va a exponer distintos datos, va a tener diferente estructura. Por lo tanto, yo quiero limitar el impacto que tiene el cambiar un SDK por otro en mi código. Si quieres aprender a programar utilizando estas técnicas, aprovechándote del polimorfismo y de las interfaces, te dejo aquí abajo una serie de vídeos en la que hablo de principios solid y de patrones de diseño que puedes utilizar. Por lo tanto, estoy generando una serie de clases genéricas que van a ser convertidas después en cada uno de mis providers a las clases específicas de cada provider. Por ejemplo, en el caso de Antropic, pues aquí es el único sitio de Miarnés donde importamos el SDK de Antropic y lo que hacemos es definirnos pues las funcionalidades específicas de este SRK, cómo se construye y luego implementamos las funciones, pues por ejemplo, para obtener el modelo, para setear el modelo y aquí abajo, la más importante, para enviarle un mensaje al modelo. Fíjate que estoy reimplementando la función sent, ¿vale?, que es la función que tenemos definida en la interfaz y le estoy diciendo, mira, aparte de hacerme aquí unos los, que yo esto tengo una serie de logs para una cosa que te voy a enseñar después que está muy chula, lo que quiero es que llames al SDK de Antropic, fíjate que es la misma función eh messages new que teníamos antes, con esta información que es básicamente una traducción de los ítems genéricos que le estoy introduciendo, pues por ejemplo, las tools, los mensajes y configuraciones, por ejemplo, el máximo número de tokens que quiero que utilice. dice el modelo, si quiero que active el modo thinking o no, etcétera. Es decir, estoy abstrayendo exactamente lo que ocurre cuando le envío un mensaje a la LLM y implemento aquí dentro un bucle que me convierte las respuestas de Antropic a mis respuestas genéricas.

  7. 19:29 , obre el vídeo en una pestanya nova

    Fíjate que yo aquí estoy construyendo un out pun eh content, que es una respuesta genérica de mi arnés. Vale, estoy traduciendo la respuesta que me da Antropic en este caso a la respuesta de mi arnes genérica para finalmente devolverla. Quiero implementar openi, pues lo mismo, tengo otro fichero Open con las mismas funciones. En este caso, aquí también tengo una función send. Y fíjate que aquí lo que hago es, en vez de hacer la llamada que hacía antes Antropic, aquí la hago al SDK de Open que tiene una estructura y una forma distinta. Y luego lo mismo, vuelvo a traducir las respuestas a mi respuesta genérica, por lo tanto estoy abstrayéndome de todos los modelos y providers de inteligencia artificial. Fíjate que aquí es el único sitio donde yo estoy importando OpenI, que yo necesito ahora un modelo local para no sé qué. me puedo generar un nuevo fichero de GO, comunicarme con este modelo local, con el SDK, con la API que sea y utilizarlo. Que necesito un modelo MOC para hacer test y que no me cobren cuando yo ejecuto los test. Tengo un modelo MOC en el que reimplemento estas funciones con la función sendas aleatorias para yo poder ejecutar los test. Entonces, fíjate lo fácil que es simplemente abstraerte del proveedor de las LMs. Simplemente tienes unas APIs a las que llamas y te generas un wpper por encima. Por lo tanto, cuando yo ahora me voy a mi bucle agéntico, al mi bucle de este arnés, es decir, me voy a la función main, lo que veo es que tengo un arnés que, okay, lee un system prompt, que es un prompt que yo le he colocado aquí con una serie de explicaciones. Este es el primer prompt que se manda a cualquier modelo de inteligencia artificial. Tengo que lea también si tengo un fichero agen MD para incorporarlo también al System prompt. Ya os digo, esto es decisión del arnés. Cada arnés puede hacerlo cuando quiera, puede leerlo y meterlo en el system prompt, puede leerlo y meterlo como mensaje de usuario. Al final, estos son decisiones de cada uno de los arneses, ¿no? Podría incluso leer el repo en el que está actuando y meterlo también del system prompt para darle más contexto a la Llm. Bueno, aquí me puedo montar yo lo que necesite. Entonces, fíjate que leo el system prompt, lo genero y luego aquí me instancio el proveedor. Tengo esta función aquí, new provider, que lo que hace es, vale, mira, pues si quiero utilizar Antropic, genero el de Antropic o genero el de Openia. ¿De acuerdo? Por lo tanto, yo aquí puedo construir diferentes proveedores en función de lo que necesite. Cosas que podría hacer aquí para mejorar esto. Podría leer esto de un fichero de configuración, ¿vale? para escoger si quiero ir a un modelo o a otro. Por ejemplo, este arnés no tiene ningún sistema de configuración externo. Todo está en el código porque quiero que quede muy claro cómo el hecho de exponer partes de configuración también permiten que tú puedas modificar o afectar el arness desde fuera, ¿vale? Lo que hemos hecho de las capas, puedes hacer harness engineering en la capa de binario o puedes hacer harness engineering en la capa de configuración. Todo depende de cuánto el arness te deja o no afectar su propio comportamiento. ¿Okay? Entonces,

  8. 22:44 , obre el vídeo en una pestanya nova

    yo aquí generaría ya el proveedor de Ll y aquí en esta función le mandaría el mensaje a mi LLM, a mi agente. Por lo tanto, aquí estaría llamando ya a la función para ejecutar el loop interno. Entonces, fíjate que es un poco más complejo porque le hemos metido UI, le hemos metido un poquito de cosas por encima, pero en el fondo no deja de ser un simple bucle. Entonces, hasta aquí ya tenemos algo que empieza a parecerse a un agente real, pero ahora mismo, como hemos visto, nuestro arnés ejecuta tools sin ningún tipo de supervisión, lo que supone un riesgo de seguridad. ¿Cómo podemos evitar que la gente haga cosas sin que yo me entere, sin mi permiso? Pues obviamente implementando en el ARNES un sistema de permisos para la ejecución de cada una de estas tools. Ahora que hemos visto el código, hemos visto cómo se lanzan, cómo se ejecutan estas herramientas, podemos afectar meternos ahí dentro y implementar salvaguardas, implementar railes para que la IA no haga cosas que no tiene que hacer. ¿Cómo implemento yo un gateway de seguridad? Pues si me voy a la función que ejecuta mis tools, recordemos, eh, estamos en el bucle interno, en la parte de ejecución de las tools. Cuando ya la Llo, nos ha dicho, "Quiero ejecutar esto." Yo tengo programado que se lance esta función de aquí, ¿vale? Recordemos el ejemplo pequeño. Esto sería como irnos a nuestro bucle, irnos a nuestro agent loop, luego aquí abajo irnos a la función que nos ejecuta la tool y aquí antes de ejecutar la tool añadir la seguridad. ¿Vale? ¿Qué puede ser esta seguridad? Pues que te aparezca un mensaje de, "Ey, se quiere ejecutar esto, ¿lo vas a aceptar o no?" Si lo aceptas continúas. Si no lo aceptas, no ejecutas nada. Haces una nueva operación y te vas. ¿Vale? Recordemos que esto sería el ejemplo pequeño. En el ejemplo ya completo que hemos visto al inicio del vídeo, lo que tenemos es que la propia función para ejecutar la tool tiene aquí la salvaguarda de aprobación. Y en caso de que el usuario confirme la llamada de aprobación, es decir, si dice que okay, que se puede ejecutar la tool, vamos a continuar a partir de esta línea. Si no, terminamos diciendo que el usuario no ha permitido hacerlo. Si lo permitimos hacer, pum, llamamos al execute de la tool específica. Fijaros que yo tengo aquí construida la carpeta de tools porque cada una de las herramientas está implementada de forma independiente. Lo que hemos visto antes en el ejemplo mínimo. Eh, esta, por ejemplo, es la tool de Bash. Yo tengo aquí definida la definición y la función de ejecución utilizando de nuevo polimorfismo para poder generar tools de una forma sencilla. La descritura de fichero, lo mismo. Tengo aquí una función definition y aquí una función execute. La función definition es la que le da la descripción a la ll. La función execute es la que hace que el arnés haga la acción. Entonces, fijaros que utilizando polimorfismo, yo estoy consiguiendo montar un proyecto en el que tengo las tools, tengo los proveedores y, en general, tengo un montón de capacidad para yo poder expandir, experimentar y probar con el desarrollo de un arnés propio. Pero esto al final era un poco básico, no dejaba de ser un bucle que iba haciendo llamadas a un SDK de Antropic. Los arneses de hoy en día, como Cloud Code,

  9. 25:56 , obre el vídeo en una pestanya nova

    como Codex, tienen capacidades mucho más potentes. Por ejemplo, son capaces de generar subagentes. Yo le puedo pedir algo a Cloud Code y que de golpe me lance tres subagentes o yo puedo definir subagentes, como vimos en vídeos anteriores, para implementar el flujo de SD. ¿Cómo se haría esto cuando yo estoy trabajando en la capa core de mi herness? Pues básicamente tengo el control total. De la misma manera que yo puedo generarme un proveedor y enviarle mensajes, yo puedo generarme también agentes. Un agente no deja de ser una instancia concreta de mi proveedor. Por lo tanto, de la misma forma que yo puedo crear diferentes tools, también puedo crear diferentes agentes y lo mejor de todo, lo puedo hacer bajo demanda. Es decir, yo me puedo crear aquí este tipo agent y generarme un constructor en el que directamente estoy devolviendo un conjunto de proveedores, tools y un system prom. Fijaros aquí que estoy construyendo un agente en el propio código. Obviamente, cuando yo me genero agentes, tengo que poder mandarle mensajes a este agente, por lo que defino las funciones para setear, limpiar los mensajes, enviar los mensajes al proveedor, que esto básicamente lo que hace es lanzar el loop dentro del agente, que sería de nuevo el loop interno, y también tengo que darle a la gente la capacidad de ejecutar tools. Entonces, fíjate que estoy agarrando mi bucle interno, lo estoy guardando o empaquetando, en este caso, en una clase que me va a permitir instanciar diferentes bucles internos, como si fueran enemigos de un videojuego, como si fueran personajes de una simulación. Yo tengo el control de cuántos agentes instancio y de cómo los configuro. Fíjate que yo le paso el provider cuando estoy construyendo el agente. Por lo tanto, yo podría tener en mi mismo arnés al mismo tiempo un agente con el proveedor de Open y un agente con el proveedor de Antropic y luego también una parte en eh programación local, por lo que podría montarme arneses que en función de ciertas características hagan unos agentes u otros. También, ¿qué le defino al agente? las tools a las que tiene acceso. Quizá quiero que un modelo concreto con un proveedor o un tipo de agente solamente sea capaz de leer ficheros porque no quiero que pueda escribir o quiero tener otra agente que solo se encargue de herramientas de Git y me genero unas tools aquí de acceso a Git y que eso solamente pueda hacer cosas de Git, pero no pueda leer ficheros ni escribir ficheros en mi dispositivo. Es decir, el potencial como ya estoy en una capa tan baja del desarrollo del arness prácticamente infinito. Por lo tanto, si yo me defino estas clases de agentes, cuando yo me vaya a mi función main, a mi bucle principal, a mi bucle RPL, podemos entender que cuando yo construí el system prompt original, que es cuando yo enciendo mi arnés, cuando yo agarro el proveedor de IA que quiero utilizar, lo primero que voy a hacer, fíjate, es generarme el root agent. El root agent es el agente raíz, es el agente que recibe el system prompt que tengo yo aquí hardcodeado, que podía también tener en un fichero sin ningún tipo de problema y es el primer agente que se genera, es la raíz. Por lo tanto, fíjate qué poder tiene el hecho de empaquetar el concepto de agente dentro de una clase de código para que yo luego lo pueda instanciar de forma libre. Ahora

  10. 29:12 , obre el vídeo en una pestanya nova

    bien, quizá la pregunta que tienes es, ¿vale, Marty, he visto que aquí tienes el new, ¿no? O bueno, mejor dicho, la definición. de el root agent. Este es el root agent que está en el bucle principal. Pero esto de los subagentes, ¿cómo funciona? ¿Cómo hago yo que de golpe le pido algo y me genere subagentes? ¿Cómo hago yo que si yo le digo a mi que me lance, pues, por ejemplo, subagentes de investigación, mi arnés sea capaz de tomar la decisión y de instanciar estos subagentes? Fíjate que le he pedido que realice unas investigaciones. Me lee los ficheros y aquí ya empieza a delegar a un subagente. Fíjate que está thinking del agente de research. Eso es porque yo he configurado mi UI para que los subagentes se vean así, ¿vale? Se vean como un una flechita que va hacia dentro. Eso es que lo está haciendo otro agente. ¿Cómo hago esto? Pues en verdad ya tenemos todos los ingredientes para poder implementar algo así. Lo que queremos es que nuestro agente haga una acción. ¿Qué acciones puede hacer nuestra agente? Puedes ejecutar comandos de bash, leer ficheros, escribir ficheros. ¿Cuál es la nueva acción que queremos que pueda hacer? Delegar o instanciar subagentes. Tengo aquí una tool que es la delegate tool que es la encargada de instanciar subagentes. Fíjate que yo aquí en la definición le paso la descripción de mi subagente. Yo esto lo puedo tener guardado allí donde necesite. ¿Vale? Fíjate que aquí tengo una clase subagente en la que, por ejemplo, tengo un agente de research que tiene una descripción que explica qué es capaz de hacer este agente para darle al agente principal el contexto de la herramienta sin más. Y si yo me voy aquí a esta herramienta, pues mira, le paso la descripción, lo que el input esquema y la parte de ejecutar lo que hace es, epa, ejecutar el subente. Por lo tanto, fíjate que no es magia, es simplemente una herramienta más que la LLM puede decidir utilizar. Lo único es que esta herramienta lo que hace es instanciar un nuevo subagente, ¿vale? Con el comando run, que esto a su vez vuelve a empezar, me genera otro bucle interno, me acaba de spawnear un nuevo enemigo, me acaba de spawnear un nuevo subagente. El cómo yo spawneo este subagente ya es una decisión del propio arnés. Por ejemplo, yo aquí he tomado la decisión de que este subagente empieza con un contexto vacío, no hereda los mensajes de la gente raíz, pero lo podría hacer. Yo le podría pasar eh aquí una nueva variable, le podría pasar lo el historial de mensajes, podría tomar las decisiones que yo considere porque yo tengo el control completo de cómo estoy implementando mi arnés. Y es por esto que cambiar de un arnes a otro tiene tantas implicaciones, porque estas decisiones no siempre son las mismas. Con esto ya tenemos una base bastante potente y podemos empezar a razonar y a extender este acné como nosotros necesitemos. Y créeme, hay un montón de cosas que nosotros podemos añadir. Ahora mismo nuestra eh interfaz, nuestro arnés, es algo muy sencillo, no deja de ser muy similar a como podría ser Cloud Code, etcétera, en el que tenemos una serie de comandos, ¿vale? pues para ver las tools que tenemos disponibles y los agentes que se están ejecutando. Y tenemos un poquito un status bar que nosotros aquí podemos popular y podemos programar como queramos, pero hay un montón de cosas que nosotros podemos añadir, por ejemplo, soporte para MCPs. ¿Cómo podríamos implementar nosotros un

  11. 32:27 , obre el vídeo en una pestanya nova

    MCP en un arnes como el que tenemos? Bueno, pues depende de cómo queramos. Podríamos reutilizar nuestra herramienta de tools. Si yo me voy a la carpeta MCP, yo puedo ver que tengo un stru que se llama MCP Tool. que lo que tiene es dentro una definición de una tool. Por lo tanto, estoy haciendo un wrapper sobre mi sistema de tooling para que yo pueda crear tools utilizando MCPs. Fíjate que es exactamente lo mismo, eh, tengo una definición y tengo una función execute. La única diferencia es que en este caso yo quiero poder registrar MCPs en remoto, quiero poder pasar una URL y que se lean o se instalen los MCPs necesarios para poder trabajar. Es por esto que este MCP register tiene una función load config, que lo que hace es cargar el típico fichero de mcp.jonjon, Jason, que por ejemplo tengo aquí abajo para hacer una prueba, lee esto, agarra esto de aquí, la definición, por ejemplo, de dewky, y lo que hace es guardar aquí en un map, en una estructura, el MCP, es decir, una vez hemos leído el fichero, hace una petición al servidor mediante fetch, obtiene lo necesario y lo registra en el registry, que el registry no es nada más y nada menos que un map con las nuevas tools. De acuerdo. Como curiosidad tuve que hacer que se cargaran los MCPs en paralelo porque claro, como tenía que hacer peticiones HTTP para obtener estas tools, pues esto bloqueaba el arnés y tardaba un ratito en cargar esto, ¿no? Entonces lo puse como e una gorrutina para que lo haga en paralelo sin afectar al thread principal de la UI y va cargando las tools de MCP en background y yo, por lo tanto, puedo ir interactuando con con mi UI. ¿Qué más cosas puedo implementar? Bueno, pues por ejemplo, los slash commands. Yo puedo hacer barrah help y si le quito el modo de book voy a ver todo los comandos que tengo disponibles. Como esto es un arnés para aprender, digamos que he querido utilizar mucho polimorfismo para poder cambiar las piezas de una forma muy sencilla. Una de las piezas que se pueden cambiar es la metodología de compactación de la conversación. Ahora mismo tenemos implementadas la sliding, la Sumaris y ninguna, pero está pensado para que tú puedas experimentar. La compactación es lo que ocurre cuando tienes el contexto muy lleno en tu modelo del LM y quieres resumirlo, pues o bien para ahorrar tokens o bien para poder seguir conversando sin que se degrade la conversación, ¿no? En este caso tengo aquí la carpeta compact donde tengo las diferentes estrategias de compactación, ¿vale? La estrategia de compactación es simplemente una interfaz que recibe esto de aquí, recibe los mensajes y devuelve los mensajes compactados. Hay diferentes estrategias, o bien no resumas, que no hace nada, o bien sliding window, que como veis simplemente se queda con un trozo concreto de la ventana, y la parte de Sumaris, que sería un poquito la más interesante en la que utilizo la propia LLM para mandarle un prompt diciéndole, "Ey, resúmeme la conversación y me actualiza el contexto con la información resumida." ¿Vale? Entonces, si quieres probar nuevas estrategias, es tan fácil como irte a la carpeta de compact y implementar una nueva de estas. Y luego

  12. 35:41 , obre el vídeo en una pestanya nova

    te irías aquí a el arness barraca compact y escoges la nueva herramienta que quieres utilizar, la nueva estrategia. Lo mismo con el provider, eh, puedes cambiarlo aquí, puedes cambiar el modelo, puedes listar los subagentes, pero también que me parece interesante, puedes listar los tokens gastados y si yo le pido algo, aquí me irá saliendo el coste que me devuelve el provider del LLM. Fíjate que si te vas al código, aquí vemos los tokens que yo le he enviado, los tokens que me ha devuelto y el precio. Si te vas al código de cada uno de los providers, vas a ver que hay una serie de configuraciones de coste, ¿vale? En función del modelo tengo definido cuánto cuesta cada uno de ellos. Esto obviamente puede ir cambiando, se tiene que actualizar mediante la eh documentación, pero esto lo único que hace es que cuando me devuelve una respuesta el proveedor, yo puedo saber cuántos tokens me ha devuelto porque me lo devuelve la propia API y realizo la multiplicación y entonces ya tenemos el coste y el uso. ¿Qué otras cosas se pueden implementar que pueden ser guay? Por ejemplo, sistemas de memoria. Llega un punto cuando vas trabajando con la IA que si cierras la sesión y la vuelves a encender tal como lo teníamos hasta ahora, pues empezabas de cero, no tenías un sistema de memoria, no sabías lo que habías hecho anteriormente. ¿Por qué? Porque todo el contexto, todo lo que nosotros le pasábamos a nivel de mensajes estaba guardado en la propia RAM, en la memoria, en una variable del proceso. ¿Cómo podríamos implementar un sistema de memoria? Pues sencillamente de la misma forma que hemos implementado subagentes, en vez de tener una tool para instanciar un subagente, tendremos una tool para guardar memoria y para recordar de memoria, que son precisamente estas dos nuevas tools que añadí aquí posteriormente. La tool de recall, que es para recordar cosas de la memoria, y la tool de remember, que es para guardar cosas en la memoria. De nuevo, estos son tools. Depende de cómo yo le defina la descripción, la LLM va a decidir si las quiere utilizar o no. Es la LLM que decide si se acuerda o merece la pena acordarse de algo o merece la pena ir a buscar a su memoria algo del pasado. La implementación de estas tools, la función execute, ya depende de cada uno de nosotros. En mi caso, yo lo guardo directamente en ficheros Jason, ¿vale? Lo guardo en una carpeta con ficheros Jason, pero tú puedes implementar que esto lo guarde en SQL. Puedes implementar una librería que lo guarde en una base de datos en remoto y lo programas directamente aquí. Luego aquí en el recall pues ejecuto cómo busco la memoria, ¿no? Cómo me aseguro quiero buscar por palabra, quiero buscar por tag, cómo quiero interactuar con la memoria a nivel programático cuando la me diga, "Ey, quiero recordar, ¿vale? ¿Qué hago?" Entonces, para que tú puedas experimentar con diferentes sistemas de memoria y puedas implementarte los tuyos propios, aquí tengo la carpeta memory en la que he definido el store. En este caso, tú puedes modificar estos ficheros de memoria para acabar de definir diferentes stores. Definir recalls, definir preembles y definir save. Defines las tres funciones que interactúan con el store de memoria. Y por ejemplo, aquí tengo que tengo un store de ficheros, lo que ha comentado que son JSONs, donde yo lo guardo en un fichero de Jason con una serie de logs y errores donde voy indexando todas las instancias, las sesiones de las que me quiero acordar y tengo aquí el save y

  13. 38:55 , obre el vídeo en una pestanya nova

    tengo aquí el recall, que lo que hace es básicamente ir a buscar el fichero de memoria y fíjate hacer toda la serie también de guardados de ficheros y en general gestionar todo lo que sería mi acceso. mi interacción con la memoria, que en este caso no dejan de ser ficheros Jason, que están en este caso dentro de la carpeta harness. Si yo le pido a la Llm, dime qué hicimos ayer, esto me va a lanzar la tool de recordar. Fíjate, me está instanciando la tool de recall con esta query. Por lo tanto, esto es en mi sesión de tools recall con esta query, ¿vale? Entonces, fíjate que luego aquí ya qué hace esta tool es lo que yo implemento. Le puedo dar a yes. Sigo dándole a yes y pues ahora mismo está yendo a hacer diferentes pruebas. Fíjate que ahora mismo estoy en el bucle, ¿vale?, de aprobación de llamadas de tools en el bucle interno de este agente. Como ves, ha detectado que no tiene nada de antayer, por lo que lo que está en la memoria, que está dentro de esta carpeta, termina en ese punto, no tiene memoria de ese de ese momento. Para que veas eh directamente cómo está guardado todo esto, tengo aquí la carpeta punto harness. Esto porque yo lo he decidido así en mi código, lo podía poner en una configuración, eso es totalmente libre. Si yo entro ahí, veo mi fichero de Jason de las diferentes sesiones, donde tengo pues lo que se ha ido guardando en la memoria, ¿no? Con sus tags para luego poderlo buscar. Esto es lo que yo tengo implementado en session files. Aquí toda esta lógica de cómo se guarda lo tengo implementado aquí. Y si me voy a la parte de sessions, aquí ya tengo pues cada uno de los recuerdos más explicados. Entonces, lo que he implementado es que la memoria va a buscar en este índex a qué fichero tiene que ir y luego agarra el fichero para tener todo el contexto. Entonces, fíjate que yo aquí puedo implementarme lo que quiera. Tengo el control total de mi herness. Es que, como ves, podemos complicarlo todo lo que queramos. Podemos añadirle piezas, quitarle piezas, eh, añadirle más providers, añadirle diferentes sistemas de memoria, más comandos para cambiar más cosas. Pero al fin y al cabo, construir un arnés no deja de ser tener un bucle. Es como construir un videojuego. Tienes un bucle y lo que haces es le añades diferentes piezas de memoria, de tools, de acceso a diferentes herramientas como MCPS, de diferentes formas de UI para ver el coste. En este caso yo he utilizado una herramienta que se llama Babel T, que es básicamente una eh herramienta para poder construir herramientas de terminal de una forma muy sencilla con Go, pero que no tiene más secreto. Podría haber hecho una página web, podría haber hecho una línea de comandos o podría haber hecho una UI con.net net si hubiera querido. Y si seguiera explicando, puedo estar aquí durante horas hablando sobre cómo he montado este proyecto, pero para eso precisamente he dejado el repositorio del proyecto completo aquí abajo en la descripción para que le puedas echar un ojo. Este repositorio que voy a dejar público justo cuando publique este vídeo, pues tiene toda la explicación de todo lo que he ido explicando en este vídeo y además algunas cosas extra que he ido haciendo fuera de cámara para construir tu propio eh agente o tu propio arnés. Hay versión en inglés y versión en español. Y aquí tienes

  14. 42:09 , obre el vídeo en una pestanya nova

    básicamente todo lo que he ido haciendo, todo lo que he ido explicando con las diferentes partes, el manejador de contexto, el manejador de memoria, las herramientas, los subagentes, los servidores MCP y una especie de tutorial, una especie de capítulos que tú puedes ir leyendo para entender exactamente las decisiones y ver en ejemplos de código mucho más concretos por qué hemos tomado ciertas decisiones o hemos tomado otras. Por ejemplo, si quieres aprender más a cómo funciona el loop de agentes o lo quieres construir tú por tu cuenta desde cero, te puedes ir al capítulo número uno, ¿vale?, Vale, que está en el repositorio o al capítulo uno, pero de la página web y ver exactamente qué es lo que sucede, qué es el RPL con el ejemplo del videojuego, cómo lo puedes construir y algunos ejemplos sacados de el proceso que yo he seguido cuando he construido mi arnés para que tú puedas montarlo por tu cuenta siguiendo poco a poco cada uno de los pasos. Obviamente cuando llegas al final de cada uno de los pasos, tienes el botón de siguiente para ir implementando siguientes partes sobre tu propio proyecto. La idea de este repositorio y la idea del propio arnés es que sea un proyecto educativo. Es probable que no siga las mejores prácticas de programación en Go. Es posible que si lo quisieras comercializar como producto tuviera algunas partes que se tienen que mejorar. Por lo tanto, el objetivo de este repo es ofrecerte un proyecto suficientemente complejo para que puedas jugar, pero suficientemente sencillo para que lo puedas entender. Para que todo esto sea mucho más visual, para que puedas incluso utilizar el propio arnés que te puede descargar del repo para practicar, he implementado el modo debook. Si tú pones barra debook on, te va a aparecer aquí este sistema de aquí, que es básicamente un visualizador, como ves, de todo lo que va ocurriendo en el arnés. En este caso, pues estamos viendo que le mandado hello. Estamos viendo la llamada al provider, en este caso a antropic. Si le das a enter, puedes ver exactamente el payload, el Jason que le estamos mandando, ¿de acuerdo? y puedes ver si vas de izquierda a derecha la respuesta que hemos recibido de Antropic. Por lo tanto, tú puedes ir viendo exactamente cómo afecta pues la gestión de la memoria, cómo afecta la gestión del contexto en las llamadas que vas haciendo. Como ves aquí, el agents MD me ha hinchado el system prompt de una manera brutal. Si yo le doy ahora escape y vuelvo a poner hello 2, fíjate que se me ha sumado a tres el número de mensajes, ¿no?, que yo le he enviado, porque le voy mandando todo el historial. Si yo le doy ahora aquí a leer esto, veré el hello inicial, luego veo la respuesta de mi asistente y todo esto forma parte del contexto. Luego el hello 2 y finalmente todo el system prompt. Fíjate como el system prompt ha de ser pequeño. ¿Por qué? Porque yo lo llamo cada vez. Entonces, los input tokens van sumando. Entonces, ver esto así es muy útil. También yo podría hacer ahora el barra compact y ponerle sumar para compactar el contexto y mandarle a la, en este caso, el LM de Antropic que me genere la compactación. Le doy a esto y vale, no me ha compactado nada porque no hay mucha cosa. Vamos a añadir otro hello, le vamos a decir write me a poem, ¿vale? Y ahora le vamos a decir, ahora sí, compact sumaris. Fíjate que el Compact Sumar ahora me ha lanzado una

  15. 45:27 , obre el vídeo en una pestanya nova

    llamada a mi proveedor, por lo tanto, esta sumarización de contexto me ha consumido tokens. Le doy a enter y veo aquí lo que yo le he mandado. Sumar, hazme un resumen de la conversación de forma concisa, bla, bla, bla, bla, bla. Entonces, yo aquí puedo ir viendo exactamente y aquí la respuesta. Este sería el resultado. El contexto ahora incluye esto. El usuario me ha dicho, "Hola con hello." El asistente ha ofrecido opciones para la sesión. Pa pa. No ha habido ninguna temática escogida, no ha habido cambios de código y no ha habido llamadas de herramientas. Por lo tanto, fíjate cómo el contexto ha cambiado. ¿De acuerdo? The book on es algo superinesante que puedes utilizar para ir probando las cosas que necesites. Eh, fíjate aquí también que ves el cambio de contexto. Y si aplicas también el Verbose, no me acuerdo, creo que era así, Verbus. Vamos a poner sí, verbow on. Ahora, si yo hago compact y hago sumar, voy a ver en el propio chat el antes y el después del contexto, ¿vale? De esta forma podemos ver información más precisa. Es decir, la idea es daros un arnés, que podáis jugar con él, que podáis extenderlo, que podáis romperlo, que podáis añadir un provider, que podáis conectarlo con una IA local, que podáis añadir comandos, que podáis implementar, yo que sé, skills, que podáis implementar aquí una UI donde veáis los subagentes haciendo cosas. La idea es que juguéis, que trasteéis con esto y quién sabe si después de estar jugando un poquito con las diferentes lecciones y las diferentes cosas que nosotros tenemos en este arnés, os planteáis lanzar un nuevo producto, ¿no?, que hoy en día parece ser que sacamos un arnés hasta debajo de las piedras, pues bienvenido sea. Aparte de las lecciones con el tutorial de cómo construirlo paso a paso, en este repositorio, en esta web también compartimos una serie de tutoriales directos, ¿vale? por ejemplo, cómo añadir políticas de permisos nuevas, cómo añadir nuevos proveedores o cómo añadir nuevas herramientas para que lo puedas ir siguiendo paso a paso. Y para mí lo que creo que es más interesante de este repositorio son los ejercicios. Es posible que vayamos incorporando más ejercicios, pero de momento pues están estos seis de aquí, que es pues diferentes cosas que puedes hacer agarrando el código tal como está del repositorio para aprender algún concepto interesante. Por ejemplo, cómo modificar el agent loop para implementar reintento de errores en las herramientas y tienes aquí una serie de enunciados para poderlo hacer. También, por ejemplo, cómo añadir subagentes con Markdown, ¿no? Hasta ahora los teníamos hardcodeados. ¿Cómo puedo hacer que se cargue un Mark de este estilo, como por ejemplo hacemos en Cloud Code, y se carguen estos agentes? Pues aquí tenemos también una serie de explicaciones sobre cómo se podría implementar. Insisto, este repo es para jugar, para aprender, para trastear un poquito. Échale un ojo y deja tus comentarios. De nuevo, sin mucho más, te dejo el enlace en la descripción. Sé que este vídeo ha sido muy largo, que ha habido muchos conceptos, pero con esto cerramos ya nuestra serie de ingeniería de arneses. Espero que este repositorio te sea útil, que puedas jugar con él, que te guste. Si has sido así, por favor, suscríbete y déjame un buen like y nos vemos en el siguiente vídeo con más informática. Hasta otra. Yeah.