GoodAI-LTM equipa os agentes com memória de longo prazo baseada em texto, combinando componentes essenciais, como modelos de incorporação de texto, reclassificação, bancos de dados vetoriais, reescrita de memória e consulta, fragmentação automática, metadados de fragmentos e expansão de fragmentos. Este pacote foi projetado especificamente para oferecer um fluxo de memória centrado no diálogo para agentes sociais.
Além disso, GoodAI-LTM inclui um componente de agente conversacional (LTMAgent) para integração perfeita em aplicativos baseados em Python.
pip install goodai-ltm
Chame o método reply
de uma instância LTMAgent
para obter uma resposta do 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)
O parâmetro model
pode ser o nome de qualquer modelo suportado pela biblioteca litellm.
Um histórico de sessão é mantido automaticamente pelo agente. Se você quiser iniciar uma nova sessão, chame o método new_session
.
agent.new_session()
print(f"Number of messages in session: {len(agent.session.message_history)}")
O agente possui memória conversacional e também uma base de conhecimento. Você pode instruir o agente a armazenar conhecimento invocando o 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
é um sistema RAG integrado. O exemplo ltm_agent_with_wiki mostra como adicionar artigos da Wikipedia à base de conhecimento do agente.
Você pode persistir a configuração do agente e suas memórias/conhecimento obtendo seu estado como uma string por meio do método state_as_text
.
state_text = agent.state_as_text()
# Persist state_text to secondary storage
Para construir um agente a partir de texto de estado, chame o método from_state_text
.
agent2 = LTMAgent.from_state_text(state_text)
Observe que isso não restaura a sessão de conversação. Para persistir a sessão de conversação, chame o método state_as_text
da sessão.
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)
O trecho de código a seguir cria uma instância do LTM, carrega algum texto e, em seguida, recupera as passagens de texto mais relevantes (pedaços expandidos) de acordo com uma 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)
Uma instância de memória padrão pode ser criada da seguinte forma:
from goodai.ltm.mem.auto import AutoTextMemory
mem = AutoTextMemory.create()
Você também pode configurar a memória passando parâmetros para o método create
. No exemplo a seguir, a memória usa um tokenizer "gpt2" para fragmentação, um modelo T5 para incorporações, um índice FAISS para incorporação de armazenamento em vez de um banco de dados vetorial simples e uma configuração de fragmentação 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'))
Chame o método add_text
para adicionar texto à memória. O texto pode consistir em frases, sentenças ou documentos.
mem.add_text("Lorem ipsum dolor sit amet, consectetur adipiscing elitn")
Internamente, a memória irá fragmentar e indexar o texto automaticamente.
O texto pode ser associado a um dicionário de metadados arbitrário, como:
mem.add_text("Duis aute irure dolor in reprehenderit in voluptate velit esse cillum doloren",
metadata={'title': 'My document', 'tags': ['latin']})
A memória concatena o texto armazenado usando add_text
com qualquer texto enviado anteriormente para a memória, mas você pode chamar add_separator
para garantir que novo texto não seja adicionado aos pedaços criados anteriormente.
Para recuperar uma lista de passagens associadas a uma consulta, chame o método retrieve
:
r_memories = mem.retrieve("What does Jake propose?", k=2)
O método retrieve
retorna uma lista de objetos do tipo RetrievedMemory
, em ordem decrescente de relevância. Cada memória recuperada possui as seguintes propriedades:
passage
: O texto da memória. Isto corresponde ao texto encontrado em um bloco correspondente, mas pode ser expandido usando texto de blocos adjacentes.timestamp
: o tempo (segundos desde a época por padrão) em que o bloco recuperado foi criado.distance
: distância calculada entre a consulta e a passagem do pedaço.relevance
: um número entre 0 e 1 representando a relevância da memória recuperada.confidence
: se um modelo de correspondência de passagem de consulta estiver disponível, esta é a probabilidade atribuída pelo modelo.metadata
: metadados associados ao texto recuperado, se houver. Um modelo de incorporação é carregado da seguinte forma:
from goodai.ltm.embeddings.auto import AutoTextEmbeddingModel
em = AutoTextEmbeddingModel.from_pretrained(model_name)
O model_name
pode ser um dos seguintes:
"st:"
, por exemplo, "st:sentence-transformers/multi-qa-mpnet-base-cos-v1"
."flag:"
, por exemplo, "flag:BAAI/bge-base-en-v1.5"
."openai:"
, por exemplo, "openai:text-embedding-ada-002"
.Nome | Modelo básico | # parâmetros | # armazenamento incorporado |
---|---|---|---|
em-MiniLM-p1-01 | multi-qa-MiniLM-L6-cos-v1 | 22,7m | 1 |
em-MiniLM-p3-01 | multi-qa-MiniLM-L6-cos-v1 | 22,7m | 3 |
em-distilroberta-p1-01 | transformadores de sentença/all-distrilroberta-v1 | 82,1 milhões | 1 |
em-distilroberta-p3-01 | transformadores de sentença/all-distrilroberta-v1 | 82,1 milhões | 3 |
em-distilroberta-p5-01 | transformadores de sentença/all-distrilroberta-v1 | 82,1 milhões | 5 |
Para obter embeddings para uma lista de consultas, chame o método encode_queries
da seguinte forma:
r_emb = em.encode_queries(['hello?'])
Isso retorna uma matriz numpy. Para obter um tensor Pytorch, adicione o parâmetro convert_to_tensor
:
r_emb = em.encode_queries(['hello?'], convert_to_tensor=True)
Para obter embeddings para uma lista de passagens, chame o método encode_corpus
da seguinte maneira:
s_emb = em.encode_corpus(['it was...', 'the best of...'])
Consultas e passagens podem ter mais de uma incorporação. Os tensores de incorporação têm 3 eixos: o tamanho do lote, o número de incorporações e o número de dimensões de incorporação. Normalmente, o número de incorporações por consulta/passagem será 1, com algumas exceções.
Um modelo de correspondência/reclassificação de passagem de consulta pode ser carregado da seguinte maneira:
from goodai.ltm.reranking.auto import AutoTextMatchingModel
model = AutoTextMatchingModel.from_pretrained(model_name)
O model_name
pode ser um dos seguintes:
As instâncias de memória, por padrão, não usam um modelo de correspondência de passagem de consulta. Para habilitá-lo, ele deve ser configurado da seguinte forma:
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)
A configuração reranking_k_factor
informa à memória quantos candidatos ela deve considerar para reclassificação. O usuário solicita k
memórias. O algoritmo de reclassificação considera k * reranking_k_factor
pedaços.
O método predict
do modelo pega uma lista de tuplas de passagem de consulta e retorna uma lista de pontos flutuantes que representam probabilidades de correspondência estimadas. Exemplo:
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)
Veja o README das avaliações.
Consulte a página do projeto goodai-ltm-benchmark.
Código de exemplo adicional pode ser encontrado na pasta examples
.