2 puntos por GN⁺ 2023-10-17 | 1 comentarios | Compartir por WhatsApp
  • Letta es un proyecto para construir IA basada en memoria avanzada que pueda aprender y mejorar por sí misma con el tiempo
  • La forma de uso se divide en Letta Code, que ejecuta agentes desde la terminal local, y Letta API, que integra agentes en aplicaciones
  • La CLI requiere Node.js 18+; se instala con npm install -g @letta-ai/letta-code y luego se ejecuta letta para correr en la computadora local un agente con memoria
  • Los agentes de Letta Code ayudan con programación y tareas que se pueden realizar en la computadora; admiten skills y subagents, e incluyen skills/subagents preconstruidos para memoria avanzada y aprendizaje continuo
  • Letta es independiente del modelo; el README recomienda Opus 4.5 y GPT-5.2 para obtener el mejor rendimiento, y enlaza el model leaderboard como referencia de ranking
  • Letta API sirve para integrar agentes con estado en aplicaciones, y ofrece una agents API completa junto con SDK para Python y TypeScript
    • Paquete TypeScript/Node.js: @letta-ai/letta-client
    • Paquete Python: letta-client
    • Los ejemplos muestran el flujo de crear un agente y enviar mensajes usando LETTA_API_KEY y una clave de Letta API
  • El uso de Letta y de los servicios relacionados de Letta está sujeto a la aceptación de la política de privacidad y los términos de servicio

1 comentarios

 
GN⁺ 2023-10-17
Comentarios de Hacker News
  • Somos los autores de MemGPT. Si tienen preguntas sobre la implementación, las respondemos.
    Si quieren probarlo directamente, pueden ver cómo funciona la edición de memoria en el bot de Discord del servidor de MemGPT (https://discord.gg/9GEQrxmVyE). Al conversar con el bot, se puede ver cómo MemGPT modifica la memoria para actualizar perfiles sobre el usuario y sobre sí mismo.
    Como todo es open source, también pueden ejecutarlo localmente con el código de https://github.com/cpacker/MemGPT. El repositorio también incluye un ejemplo centrado en documentos para conversar con MemGPT sobre la documentación de la API de LlamaIndex.

  • Me pregunto por qué procesan todo dentro de una sola ventana de contexto. Cuando experimenté con algo parecido hace unos meses, lo paralelicé con varios agentes en etapas de preprocesamiento/posprocesamiento.
    Por ejemplo, la ventana de contexto principal no sabía que se estaba creando o recuperando memoria; un posprocesador generaba y guardaba memorias automáticamente a partir de la conversación, y toda la conversación también se almacenaba en una base de datos vectorial. El preprocesador inyectaba automáticamente memorias y contexto relevantes según la conversación, e incluso reescribía el historial para que, desde el punto de vista de la ventana de contexto principal, pareciera que esas memorias ya habían estado ahí desde el principio.
    Así se podía ahorrar mucho espacio en la ventana de contexto principal, que de otro modo se gastaría en prompts de sistema innecesarios y cosas por el estilo.

    • Son buenos puntos. En el contexto de un chatbot, a quién se le encarga la gestión de memoria es una decisión de diseño, y creo que hay dos grandes enfoques: gestión implícita de memoria y gestión explícita de memoria.
      En el enfoque implícito, el “LLM principal”, o en un chat, el “hilo de conversación”, no sabe que hay gestión de memoria en segundo plano. Esa gestión puede estar a cargo de un “LLM de memoria”, un script basado en reglas, una red neuronal pequeña, etc.
      El enfoque explícito es el de MemGPT: un solo LLM se encarga de todo. La investigación existente sobre chats multisesión/de largo alcance suele usar un enfoque implícito con un proceso separado de generación de memoria, y es probable que los almacenes de memoria de los chatbots de consumo también sean mayormente implícitos.
      La gestión explícita de memoria requiere seguir instrucciones complejas, así que creo que es difícil con la mayoría de los LLM públicos actuales. Estamos explorando formas de resolverlo, como el fine-tuning de modelos abiertos.
      El trade-off es tal como dices. En el enfoque implícito, no hace falta poner todas las instrucciones de gestión de memoria en el pre-prompt del LLM. El mensaje de sistema completo de MemGPT tiene alrededor de mil tokens. En cambio, con la gestión explícita de memoria, cuando el LLM funciona correctamente, el sistema completo se vuelve mucho más simple, porque se elimina el overhead de gestionar varios modelos LLM en hilos paralelos.
    • Es un enfoque interesante. Estoy construyendo algo parecido, donde uso datos transaccionales como parte del loop de feedback y los meto en la ventana de contexto para reescribir el historial.
      Creo que los LLM y el procesamiento de lenguaje natural pueden convertirse en una interfaz más viable para datos estructurados. Cuando se generan datos en un contexto de negocio específico, se extraen, se crean embeddings y se construye una base de datos vectorial.
      En el posprocesamiento, después de que responde el modelo principal, un posprocesador genera y guarda memorias automáticamente a partir de la conversación. Así se conserva el contexto importante sin cargarle esa tarea al modelo principal. Como parte de la solicitud, también se ejecuta la lógica de negocio relevante y luego se retroalimenta al sistema.
      En el preprocesamiento, antes de enviar la nueva entrada al modelo principal, se revisan las memorias guardadas, se inyecta el contexto relevante y también se ejecuta la lógica. Es como si el preprocesador le diera al modelo principal un “repaso” de conversaciones anteriores para prepararlo a dar respuestas más coherentes e informadas.
    • Los sistemas multiagente tienen bastante potencial. Creo que hay cierta entropía en las respuestas de los agentes, lo que hace que valga más la pena intentarlo.
  • Sobre lo que escribieron en las limitaciones: si las variantes de Llama 2 70B, aunque estén afinadas para llamadas a funciones, generan llamadas a funciones incorrectas o alucinan funciones fuera del esquema proporcionado, se puede usar muestreo basado en gramática.
    Al menos se puede garantizar que las llamadas a funciones sean sintácticamente correctas.
    [0] https://github.com/ggerganov/llama.cpp/tree/master/grammars

    • El muestreo basado en gramática es una buena idea y encaja muy bien con algo como MemGPT. Cuando experimentamos con MemGPT usando modelos que no eran gpt-4, los problemas que más afectaron el rendimiento fueron el uso indebido de argumentos de función y las alucinaciones de funciones.
      Por ejemplo, incluso un modelo grande ajustado con datos de llamadas a funciones (https://huggingface.co/jondurbin/airoboros-l2-70b-2.1#agentf...) por lo general generaba JSON parseable, pero se equivocaba en los argumentos o en los nombres de las funciones.
      Por ejemplo, al intentar escribir datos, en lugar de la llamada correcta a working_context.append especificada en el pre-prompt, generaba una llamada a personal_diary.add, que no estaba especificada en absoluto.
  • Solo por el título, pensé que se trataba de la memoria neuronal de un LLM, es decir, una técnica de edición de memoria que cambia durante la conversación la memoria a nivel de pesos, no el contexto, como ROME [1].
    Me alegró ver que en realidad era un trabajo genial de RAG, y pronto voy a crear mi propia versión de MemEditGPT.
    [1] https://arxiv.org/abs/2202.05262

    • Si quieres contribuir, puedes abrir un issue o PR en el repositorio. Todo es open source y tiene licencia Apache 2.0; estamos explorando activamente cómo integrar flujos de trabajo generales en la CLI.
      Como entendiste correctamente, MemGPT no edita los pesos del LLM como ROME. La “memoria” de la que habla MemGPT no está a nivel de pesos, sino a nivel de texto/tokens.
      La idea central es darle al LLM la capacidad de editar un scratchpad de memoria de trabajo que se mantiene dentro del contexto, y de leer y escribir contexto externo mediante funciones. Un detalle importante es que, para manejar el límite finito de contexto, las lecturas siempre se hacen por páginas, es decir, por chunks.
      MemGPT puede encadenar funciones y leer/escribir varias veces de forma iterativa a partir de una sola entrada del usuario. Por eso puede buscar en una base de datos documental grande, como en el ejemplo de la documentación de la API de LlamaIndex del README, reunir información de varias fuentes y devolver una respuesta.
  • Durante un tiempo sospeché que la versión web de ChatGPT (chat.openai.com, no la API) funcionaba de esta manera dentro de una conversación. Incluso en historiales de chat muy largos, daba la sensación de que la calidad se degradaba gradualmente en vez de olvidar todo de golpe.
    Claro que quizá había muchas más pistas en el contexto de lo que yo pensaba.
    En cualquier caso, creo que ideas como esta tienen muchas probabilidades de convertirse en una función básica de todos los chatbots en el futuro.

    • El resumen recursivo es una forma simple y popular de dar la ilusión de un contexto infinito. Cuando hay que liberar espacio, basta con comprimir los N mensajes más antiguos en un solo mensaje de resumen.
      Tiene pérdidas y al final se termina perdiendo información importante, pero el rendimiento puede degradarse de forma relativamente suave. En MemGPT también se usa resumen recursivo implícito encima de toda la gestión explícita de memoria.
    • Quedan muchas más pistas de lo que uno pensaría. Además, la ventana de contexto equivale a unas 12 páginas de texto estándar en inglés, y tampoco se desperdicia mucho espacio en el prompt de sistema.
      Si se hizo una tarea aunque sea un poco interesante, la salida queda fuertemente sesgada por el prompt. Como solo hay una muestra —la salida/historial anterior— se pierde algo de información en lugar de una distribución de probabilidad suave, y como varias entradas pueden mapearse a la misma salida, se pierde algo más de información.
      Pero los prompts reales suelen ser la expresión más fácil y corta que se nos ocurre para obtener el resultado deseado. Así que, si el LLM estima ese prompt, es bastante probable que su interpretación del contexto faltante sea razonablemente correcta. Es decir, mucha información que parece haber desaparecido se conserva dentro de la salida del LLM, y aunque el contexto antiguo se desplace fuera, la cantidad de información que se pierde de una sola vez no es tan grande.
    • La razón por la que ChatGPT muestra degradación es que no hace nada especial para extender la memoria más allá de la longitud del contexto.
      Hay muchas técnicas triviales para implementar memoria con pérdidas. Por ejemplo, está el promedio por pooling de tokens, como el enfoque que usan los sentence transformers. No tengo muy claro por qué este método se usa tan poco para comprimir mucho contexto dentro del prompt. En la práctica funciona como memoria de mediano plazo.
    • No se sabe qué hacen realmente los modelos cerrados, pero algunos ataques de prompt hacen pensar que, además de lo mencionado en este hilo, también usan resumen recursivo.
    • Mi impresión es que recorta de la conversación solo la cantidad mínima necesaria de los tokens más antiguos para mantenerse por debajo del límite de tokens. No se degrada como si la conversación tuviera memoria de mediano plazo.
  • No recuerdo el nombre, pero ya existe un lenguaje de programación esotérico que ejecuta comandos de forma inestable. Si diseñas el programa con cuidado, puedes hacer que una secuencia de comandos se ejecute con una confiabilidad del 99%, 99.9%, etc.

    • Probablemente sea Java2000.
      Veinte años después, el mismo enfoque se popularizó en infraestructura, sin ironía, con el nombre de “ingeniería del caos”.
    • Se parece un poco a Malbolge, pero parece que no es exactamente lo mismo. https://en.m.wikipedia.org/wiki/Malbolge
  • Actualización: acabo de publicar un chatbot persistente para Discord implementado sobre MemGPT. Pueden probarlo aquí: https://discord.gg/9GEQrxmVyE
    Con el código de GitHub también se puede ejecutar localmente una demo del chatbot y una demo de bot de preguntas y respuestas sobre documentación, donde se le pueden hacer preguntas a MemGPT sobre la documentación de la API.

  • Creo que la mayor limitación de los LLM es la ventana de contexto. Incluso sus excelentes capacidades de razonamiento suelen chocar con el límite de la ventana de contexto en casos de uso reales.

    • Sí. Espero que las técnicas presentadas aquí ayuden a pensar en cómo diseñar chatbots persistentes.
  • Estoy de acuerdo con la explicación de que el resumen recursivo es una forma simple de manejar una ventana de contexto desbordada, pero que por naturaleza tiene pérdidas y al final crea grandes huecos en la memoria del sistema.
    Pero MemGPT hace lo mismo y tiene el mismo problema. La diferencia es apenas que, en lugar de resumir todo recursivamente, busca selectivamente en el historial y lo genera para cada solicitud. La idea está buena.
    Pero soy escéptico. Este enfoque se apoya fundamentalmente en la suposición de que el contexto existente es un contexto resumible con baja entropía y que la consulta depende solo de una parte del historial.
    Eso puede ser cierto en chats o en casos como “responder preguntas a partir de un enorme conjunto de documentos”. Pero en generación de código, donde el contexto está lleno de información que no se puede descartar, como definiciones específicas de APIs, y donde se necesita un contexto amplio, como muchas definiciones de APIs, ambas suposiciones son falsas.
    La estructura y la implementación son interesantes, y la demo también está buena, pero me parece una lástima que los papers sobre resumen no reconozcan las limitaciones fundamentales de este enfoque.

    • Gracias por leer el paper. Para evitar malentendidos, quiero dejar claro que el resumen recursivo es solo una parte de la gestión de memoria de MemGPT.
      Como dices, la cola de conversación de MemGPT se gestiona con resumen recursivo, igual que en trabajos previos o en muchas implementaciones de chatbots. Pero también existe una memoria del LLM en un área “fija” de lectura/escritura que es independiente del resumen recursivo, y en el paper la llamamos “contexto de trabajo”.
      Por lo tanto, MemGPT puede acceder tanto al resumen recursivo generado automáticamente como al contexto de trabajo que MemGPT mantiene activamente actualizado.
      Ambos son distintos del contexto externo de MemGPT, que se trae a la cola de conversación mediante llamadas a funciones. En todos los ejemplos, la lectura del contexto externo no se comprime y se hace por páginas, sin resumen.
      Cuando se activa el resumen de la cola, MemGPT recibe una notificación del sistema, de modo que, si necesita conservar detalles específicos de la cola de conversación, puede escribirlos en el contexto de trabajo antes de que se borren o se resuman.
      En los ejemplos de agentes conversacionales, el contexto de trabajo se usa para guardar hechos clave sobre el usuario y el agente, con el fin de mantener una conversación coherente. El LLM siempre ve el contexto de trabajo, así que no hace falta buscarlo por separado.
      En preguntas y respuestas sobre documentación, el contexto de trabajo puede usarse para llevar registro de la tarea/pregunta actual y su progreso. En consultas complejas, ayuda a MemGPT a seguir detalles como búsquedas anteriores y solicitudes de páginas anteriores.