GoodAI-LTM equipa a los agentes con memoria a largo plazo basada en texto combinando componentes esenciales como modelos de incrustación de texto, reclasificación, bases de datos vectoriales, reescritura de memoria y consultas, fragmentación automática, metadatos de fragmentos y expansión de fragmentos. Este paquete está diseñado específicamente para ofrecer un flujo de memoria centrado en el diálogo para agentes sociales.
Además, GoodAI-LTM incluye un componente de agente conversacional (LTMAgent) para una integración perfecta en aplicaciones basadas en Python.
pip install goodai-ltm
Llame al método reply
de una instancia LTMAgent
para obtener una respuesta del agente.
from goodai.ltm.agent import LTMAgent
agent = LTMAgent(model="gpt-3.5-turbo")
response = agent.reply("What can you tell me about yourself?")
print(response)
El parámetro model
puede ser el nombre de cualquier modelo admitido por la biblioteca litellm.
El agente mantiene automáticamente un historial de sesión. Si desea iniciar una nueva sesión, llame al método new_session
.
agent.new_session()
print(f"Number of messages in session: {len(agent.session.message_history)}")
El agente tiene una memoria conversacional y también una base de conocimientos. Puede decirle al agente que almacene conocimiento invocando el método add_knowledge
.
agent.clear_knowledge()
agent.add_knowledge("The user's birthday is February 10.")
agent.add_knowledge("Refer to the user as 'boss'.")
response = agent.reply("Today is February 10. I think this is an important date. Can you remind me?")
print(response)
LTMAgent
es un sistema RAG integrado. El ejemplo ltm_agent_with_wiki muestra cómo agregar artículos de Wikipedia a la base de conocimientos del agente.
Puede conservar la configuración del agente y sus recuerdos/conocimientos obteniendo su estado como una cadena a través del método state_as_text
.
state_text = agent.state_as_text()
# Persist state_text to secondary storage
Para crear un agente a partir de texto de estado, llame al método from_state_text
.
agent2 = LTMAgent.from_state_text(state_text)
Tenga en cuenta que esto no restaura la sesión de conversación. Para persistir la sesión de conversación, llame al método state_as_text
de la sesión.
from goodai.ltm.agent import LTMAgentSession
session_state_text = agent.session.state_as_text()
# session_state_text can be persisted in secondary storage
# The session.session_id field can serve as an identifier of the persisted session
# Now let's restore the session in agent2
p_session = LTMAgentSession.from_state_text(session_state_text)
agent2.use_session(p_session)
El siguiente fragmento de código crea una instancia de LTM, carga algo de texto y luego recupera los pasajes de texto más relevantes (fragmentos expandidos) dada una consulta:
from goodai.ltm.mem.auto import AutoTextMemory
mem = AutoTextMemory.create()
mem.add_text("Lorem ipsum dolor sit amet, consectetur adipiscing elitn")
mem.add_text("Duis aute irure dolor in reprehenderit in voluptate velit esse cillum doloren",
metadata={'title': 'My document', 'tags': ['latin']})
r_memories = mem.retrieve(query='dolorem eum fugiat quo voluptas nulla pariatur?', k=3)
Se puede crear una instancia de memoria predeterminada de la siguiente manera:
from goodai.ltm.mem.auto import AutoTextMemory
mem = AutoTextMemory.create()
También puede configurar la memoria pasando parámetros al método create
. En el siguiente ejemplo, la memoria utiliza un tokenizador "gpt2" para fragmentación, un modelo T5 para incrustaciones, un índice FAISS para incrustación de almacenamiento en lugar de una base de datos vectorial simple y una configuración de fragmentación personalizada.
import torch
from transformers import AutoTokenizer
from goodai.ltm.embeddings.auto import AutoTextEmbeddingModel
from goodai.ltm.mem.auto import AutoTextMemory
from goodai.ltm.mem.config import TextMemoryConfig
from goodai.ltm.mem.mem_foundation import VectorDbType
embedding_model = AutoTextEmbeddingModel.from_pretrained('st:sentence-transformers/sentence-t5-base')
tokenizer = AutoTokenizer.from_pretrained('gpt2')
config = TextMemoryConfig()
config.chunk_capacity = 30 # tokens
config.queue_capacity = 10000 # chunks
mem = AutoTextMemory.create(emb_model=embedding_model,
matching_model=None,
tokenizer=tokenizer,
vector_db_type=VectorDbType.FAISS_FLAT_L2,
config=config,
device=torch.device('cuda:0'))
Llame al método add_text
para agregar texto a la memoria. El texto puede consistir en frases, oraciones o documentos.
mem.add_text("Lorem ipsum dolor sit amet, consectetur adipiscing elitn")
Internamente, la memoria fragmentará e indexará el texto automáticamente.
El texto se puede asociar con un diccionario de metadatos arbitrario, como por ejemplo:
mem.add_text("Duis aute irure dolor in reprehenderit in voluptate velit esse cillum doloren",
metadata={'title': 'My document', 'tags': ['latin']})
La memoria concatena el texto almacenado usando add_text
con cualquier texto enviado previamente a la memoria, pero puede llamar add_separator
para asegurarse de que no se agregue texto nuevo a fragmentos creados previamente.
Para recuperar una lista de pasajes asociados con una consulta, llame al método retrieve
:
r_memories = mem.retrieve("What does Jake propose?", k=2)
El método retrieve
devuelve una lista de objetos de tipo RetrievedMemory
, en orden descendente de relevancia. Cada memoria recuperada tiene las siguientes propiedades:
passage
: El texto de la memoria. Esto corresponde al texto que se encuentra en un fragmento coincidente, pero se puede expandir utilizando texto de fragmentos adyacentes.timestamp
: la hora (segundos desde la época de forma predeterminada) en la que se creó el fragmento recuperado.distance
: Distancia calculada entre la consulta y el pasaje del fragmento.relevance
: un número entre 0 y 1 que representa la relevancia de la memoria recuperada.confidence
: si hay disponible un modelo de coincidencia de pasaje de consulta, esta es la probabilidad asignada por el modelo.metadata
: metadatos asociados con el texto recuperado, si los hubiera. Un modelo de incrustación se carga de la siguiente manera:
from goodai.ltm.embeddings.auto import AutoTextEmbeddingModel
em = AutoTextEmbeddingModel.from_pretrained(model_name)
El model_name
puede ser uno de los siguientes:
"st:"
, por ejemplo, "st:sentence-transformers/multi-qa-mpnet-base-cos-v1"
."flag:"
, por ejemplo, "flag:BAAI/bge-base-en-v1.5"
."openai:"
, por ejemplo, "openai:text-embedding-ada-002"
.Nombre | modelo base | # parámetros | # almacenamiento emb |
---|---|---|---|
em-MiniLM-p1-01 | multi-qa-MiniLM-L6-cos-v1 | 22,7 millones | 1 |
em-MiniLM-p3-01 | multi-qa-MiniLM-L6-cos-v1 | 22,7 millones | 3 |
em-distilroberta-p1-01 | transformadores-de-oraciones/all-distrilroberta-v1 | 82,1 millones | 1 |
em-distilroberta-p3-01 | transformadores-de-oraciones/all-distrilroberta-v1 | 82,1 millones | 3 |
em-distilroberta-p5-01 | transformadores-de-oraciones/all-distrilroberta-v1 | 82,1 millones | 5 |
Para obtener incrustaciones para una lista de consultas, llame al método encode_queries
, de la siguiente manera:
r_emb = em.encode_queries(['hello?'])
Esto devuelve una matriz numerosa. Para obtener un tensor de Pytorch, agregue el parámetro convert_to_tensor
:
r_emb = em.encode_queries(['hello?'], convert_to_tensor=True)
Para obtener incrustaciones de una lista de pasajes, llame al método encode_corpus
, de la siguiente manera:
s_emb = em.encode_corpus(['it was...', 'the best of...'])
Las consultas y los pasajes pueden tener más de una incrustación. Los tensores de incrustación tienen 3 ejes: el tamaño del lote, el número de incrustaciones y el número de dimensiones de incrustación. Normalmente, el número de incrustaciones por consulta/pasaje será 1, con algunas excepciones.
Un modelo de coincidencia/reclasificación de pasajes de consulta se puede cargar de la siguiente manera:
from goodai.ltm.reranking.auto import AutoTextMatchingModel
model = AutoTextMatchingModel.from_pretrained(model_name)
El model_name
puede ser uno de los siguientes:
Las instancias de memoria, de forma predeterminada, no utilizan un modelo de coincidencia de pasajes de consulta. Para habilitar uno, se debe configurar de la siguiente manera:
from goodai.ltm.embeddings.auto import AutoTextEmbeddingModel
from goodai.ltm.mem.auto import AutoTextMemory
from goodai.ltm.mem.config import TextMemoryConfig
from goodai.ltm.reranking.auto import AutoTextMatchingModel
# Low-resource embedding model
emb_model = AutoTextEmbeddingModel.from_pretrained('em-MiniLM-p1-01')
# QPM model that boosts retrieval accuracy
qpm_model = AutoTextMatchingModel.from_pretrained('em:em-distilroberta-p5-01')
config = TextMemoryConfig()
config.reranking_k_factor = 8
mem = AutoTextMemory.create(matching_model=qpm_model, emb_model=emb_model, config=config)
La configuración reranking_k_factor
le dice a la memoria cuántos candidatos debe considerar para reclasificar. El usuario solicita k
memorias. El algoritmo de reclasificación considera k * reranking_k_factor
.
El método predict
del modelo toma una lista de tuplas de pasajes de consulta y devuelve una lista de flotantes que representan probabilidades de coincidencia estimadas. Ejemplo:
model = AutoTextMatchingModel.from_pretrained('em:em-distilroberta-p5-01')
sentences = [
('Mike: What is your favorite color?', 'Steve: My favorite color is purple.'),
('Name the inner planets.', 'It was the best of times, it was the worst of times.'),
]
prob = model.predict(sentences)
print(prob)
Ver las evaluaciones README.
Consulte la página del proyecto goodai-ltm-benchmark.
Puede encontrar código de ejemplo adicional en la carpeta de examples
.