Semantic search and text generation in R. Part 2

Semantic search and text generation in R. Part 2

Introduction

In the first part, we talked about using search and generating an answer using language models. In this part, we will consider memory and agents.

Data and environment

We will use models from OpenAI. For Opensource models, the mechanism is roughly similar.

We install and connect libraries

library(reticulate)
library(data.table)
library(magrittr)
library(stringr)

py_install(c('torch', 
             'torchvision', 
             "torchaudio", 
             'langchain', 
             'docx2txt', 
             'faiss-cpu', 
             'openai==0.28.1', 
             'tiktoken',
             "google-api-python-client>=2.100.0"), pip = TRUE)


langchain <- import('langchain')

Constants

I will describe how to get a token for Google.

OPENAI_API_KEY <- '<YOUR OPENAI TOKEN>'
GOOGLE_API_KEY <- "<YOUR GOOGLE TOKEN>"
CUSTOM_SEARCH_ENGINE_ID <- "<YOUR GOOGLE SEARCH ID>"
MODEL_NAME_GPT <- "gpt-4"
TEMPERATURE <- 0.5
MAX_TOKENS <- 100L

Memory

Types of memory:

  • ConversationBufferMemory is the simplest type of memory. All previous messages are recorded in the history, which is not efficient.

  • ConversationSummaryMemory – summarizes the story before submitting it to the story. In this case, the model is called twice (answers and summarization).

  • ConversationSummaryBufferMemory – at the specified value of the window in tokens, stores stories, or more, summarizes.

  • ConversationBufferWindowMemory – stores the last k dialogues.

  • ConversationKGMemory – uses a knowledge graph to store memory.

  • ConversationEntityMemory – stores information about a certain object in the history.

ConversationBufferMemory

llm <- langchain$llms$OpenAI(temperature = TEMPERATURE, 
                             openai_api_key = OPENAI_API_KEY, 
                             max_tokens = MAX_TOKENS)
  
memory_buffer <- langchain$chains$conversation$memory$ConversationBufferMemory()
chain_buffer <- langchain$chains$ConversationChain(llm = llm, memory = memory_buffer)

chain_buffer("Знаешь кто такой конь?") 
### $input
### [1] "Знаешь кто такой конь?"
### 
### $history
### [1] ""
### 
### $response
### [1] " Да, я знаю о коне. Это животное, которое используется в качестве домашнего животного и для с"

chain_buffer("Опиши его")
### $input
### [1] "Опиши его"
### 
### $history
### [1] "Human: Знаешь кто такой конь?\nAI:  Да, я знаю о коне. Это животное, которое используется в качестве домашнего животного и для с"
### 
### $response
### [1] " Кони обычно являются высокими и мощными животными с длинной шеей, длинными ногами и плотным т"


# Для систем с использованием внутренних данных
# chain_buffer <- langchain$chains$ConversationalRetrievalChain$from_llm(llm = llm,
#                                                                        memory = memory_buffer, 
#                                                                        retriever = db_gpt$as_retriever())
# chat_history <- list()
# query <- "<Запрос 1>"
# res1 <- chain_buffer$run(list(question = query, chat_history = chat_history))
# res1
# chat_history <- c(chat_history, tuple(query, res1))
# 
# query <- "<Запрос 2>"
# res2 <- chain_buffer$run(list(question = query, chat_history = chat_history))
# res2
# chat_history <- c(chat_history, tuple(query, res2))

ConversationSummaryMemory

Summarizes memory.

memory_summary <- langchain$chains$conversation$memory$ConversationSummaryMemory(llm = llm)
chain_summary <- langchain$chains$ConversationChain(llm = llm, memory = memory_summary)

chain_summary("Знаешь кто такой конь?") 
### $input
### [1] "Знаешь кто такой конь?"
### 
### $history
### [1] ""
### 
### $response
### [1] " Да, я знаю о коне. Конь - это домашнее животное из семейства лошадей. Они используются для"

chain_summary("Опиши его")
### $input
### [1] "Опиши его"
### 
### $history
### [1] "\nThe human asks what the AI thinks of artificial intelligence. The AI thinks artificial intelligence is a force for good because it will help humans reach their full potential. The human then asks who a horse is and the AI responds that it is a domesticated animal from the horse family and is used for transportation and recreation."
### 
### $response
### [1] " A horse is a four-legged mammal with a long snout, long mane, and a short tail. It has hooves and is typically a brown or black color. It is usually around 1.5 to 1.8 meters tall and can weigh up to 900 kilograms. Horses are intelligent creatures and have been domesticated for thousands of years. They are used for transportation, recreation, and even as a source of food."

Memory

chain_summary$memory$chat_memory
### ChatMessageHistory(messages=[HumanMessage(content="Знаешь кто такой конь?"), AIMessage(content=" Да, я знаю о коне. Конь - это домашнее животное из семейства лошадей. Они используются для"), HumanMessage(content="Опиши его"), AIMessage(content=" A horse is a four-legged mammal with a long snout, long mane, and a short tail. It has hooves and is typically a brown or black color. It is usually around 1.5 to 1.8 meters tall and can weigh up to 900 kilograms. Horses are intelligent creatures and have been domesticated for thousands of years. They are used for transportation, recreation, and even as a source of food.")])

Agent

An agent is a link between a language model (LLM) and a tool (Tool). For example, you can make the language model answer from Google information (possess new knowledge).

To do this, we will create a Google API key (Google Cloud -> APIs & services -> Credentials -> Create credentials -> API key). Then go to Custom search API -> Enable. Set it up by giving a name and activating the search on the entire Internet, then take the ID of the search engine.

# Обёртка для поиска
search_engine <- langchain$utilities$GoogleSearchAPIWrapper(google_api_key = GOOGLE_API_KEY, google_cse_id = CUSTOM_SEARCH_ENGINE_ID)

# Создаём инструмент. Имя нужно указать как Intermediate Answer, по-другому ломается.
tool <- langchain$tools$Tool(name = "Intermediate Answer", func = search_engine$run, description = "Google answers")

# Гугл агент
agent_google <- langchain$agents$initialize_agent(tools = c(tool), 
                                                  llm = llm, 
                                                  agent = "self-ask-with-search", # Другие варианты: zero-shot-react-description, react-docstore, conversational-react-description
                                                  verbose = TRUE, 
                                                  max_iterations = 5)


# Запуск агента
agent_google$run("Кто такой Гемуда?")


### [1m> Entering new AgentExecutor chain...[0m
### [32;1m[1;3m Yes.
### Follow up: Что такое Гемуда?[0m
### Intermediate answer: [36;1m[1;3mГемуда, как велел Карашауай, начал скакать и прыгать по морю и по его дну туда-сюда. Когда море почернело, помутнело настолько, что под водой ничего не стало ... ... Гемуда-Секирген-таш «Камень-Через-Который-Перепрыгнул-Гемуда» и т.д.), что подтверждает тесную связь содержания богатырского эпоса и материальной культуры ... Доскакали до громадной горы,. [Гемуда] грудью [ее] ударил,. Громадную гору на две части расколол. Голубые озера — следы его копыт,. Разведение и популяризация племенных лошадей Карачаевской породы/Къ Карачаево-Черкесская Республика · ❌ПРОДАН❌ Жеребец-производитель в ПРОДАЖЕ Гемуда 2017г ... May 18, 2010 ... В мирное время Гемуда живет в подземной конюшне, питаясь рудой или железными опилками. Но самое главное - Гемуда владеет человеческой речью и ... Гемуда может принимать то облик захудалой клячи, то вид богатырского коня. Однажды он предстает в истинном виде - с крыльями орла и с рыбьим хвостом, т. е. Mar 13, 2023 ... Нарт ат – конь нарта,(Гемуда); Юч аякъ ат – крылатый конь (трёхногий в нартском эпосе, аналог современного самолета – три шасси). Жылкъы ... Sep 25, 2016 ... Так же на сколько Нарты были верны своим скакунам, и скакуны Нартам можно понять из клятвы Карашуайа и Гемуды при первой их встрече: (Гемуда): Dec 10, 2015 ... А в сказании «Карашауай и Гемуда» даже подчеркивается, что у Гемуды около ушей были жабры и он, очутившись под водой, «къулакъ орталары бла, ... Jul 6, 2021 ... легендарный конь Гемуда, рожденный на вершине. Эльбруса. Он мог скакать так, что грудью рассекал горы. Так появились Черекское и. Чегемское ...[0m
### [32;1m[1;3mSo the final answer is: Гемуда - легендарный конь, рожденный на вершине Эльбруса, который мог скакать так, что[0m
### 
### [1m> Finished chain.[0m
### [1] "Гемуда - легендарный конь, рожденный на вершине Эльбруса, который мог скакать так, что"

Conclusion

These initial solutions are the basis for the development of more complex and effective search systems and RAG. They can be refined and adapted to specific needs and working conditions using other langchain methods. It is possible to expand the functionality of the RAG system itself by adding new capabilities and tools for analyzing and classifying information. Another possible direction for expansion could be to consider different application scenarios for these systems.

If you look events in Mykolaiv – https://city-afisha.com/afisha/

Related posts