SiddarthaRachakonda commited on
Commit
d2fe0f0
1 Parent(s): f49a532

modified rag system

Browse files
.gitignore CHANGED
@@ -1,3 +1,15 @@
1
  env.sh
2
 
3
- test_request.py
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  env.sh
2
 
3
+ test_request.py
4
+
5
+ .DS_Store
6
+
7
+ __pycache__
8
+
9
+ sources.txt
10
+
11
+ .venv
12
+
13
+ data_indexing.ipynb
14
+
15
+ app/code_data/
app/callbacks.py CHANGED
@@ -15,8 +15,8 @@ class LogResponseCallback(BaseCallbackHandler):
15
  """Run when llm ends running."""
16
  # TODO: The function on_llm_end is going to be called when the LLM stops sending
17
  # the response. Use the crud.add_message function to capture that response.
18
- print(outputs)
19
- print(outputs.generations[0][0].text)
20
  crud.add_message(self.db, schemas.MessageBase(message=outputs.generations[0][0].text, type="assistant"), self.user_request.username)
21
 
22
  def on_llm_start(
 
15
  """Run when llm ends running."""
16
  # TODO: The function on_llm_end is going to be called when the LLM stops sending
17
  # the response. Use the crud.add_message function to capture that response.
18
+ # print(outputs)
19
+ # print(outputs.generations[0][0].text)
20
  crud.add_message(self.db, schemas.MessageBase(message=outputs.generations[0][0].text, type="assistant"), self.user_request.username)
21
 
22
  def on_llm_start(
app/chains.py CHANGED
@@ -6,7 +6,9 @@ from app.prompts import (
6
  raw_prompt,
7
  raw_prompt_formatted,
8
  history_prompt_formatted,
 
9
  format_context,
 
10
  tokenizer
11
  )
12
  from app.data_indexing import DataIndexer
@@ -30,22 +32,29 @@ formatted_chain = (raw_prompt_formatted | llm).with_types(input_type=schemas.Use
30
  history_chain = (history_prompt_formatted | llm).with_types(input_type=schemas.HistoryInput)
31
 
32
  # TODO: Let's construct the standalone_chain by piping standalone_prompt_formatted with the LLM
33
- standalone_chain = None
34
 
35
- # input_1 = RunnablePassthrough.assign(new_question=standalone_chain)
36
- # input_2 = {
37
- # 'context': lambda x: format_context(data_indexer.search(x['new_question'])),
38
- # 'standalone_question': lambda x: x['new_question']
39
- # }
40
- # input_to_rag_chain = input_1 | input_2
41
 
42
  # TODO: use input_to_rag_chain, rag_prompt_formatted,
43
  # HistoryInput and the LLM to build the rag_chain.
44
- rag_chain = None
45
 
46
  # TODO: Implement the filtered_rag_chain. It should be the
47
  # same as the rag_chain but with hybrid_search = True.
48
- filtered_rag_chain = None
 
 
 
 
 
 
 
49
 
50
 
51
 
 
6
  raw_prompt,
7
  raw_prompt_formatted,
8
  history_prompt_formatted,
9
+ standalone_prompt_formatted,
10
  format_context,
11
+ rag_prompt_formatted,
12
  tokenizer
13
  )
14
  from app.data_indexing import DataIndexer
 
32
  history_chain = (history_prompt_formatted | llm).with_types(input_type=schemas.HistoryInput)
33
 
34
  # TODO: Let's construct the standalone_chain by piping standalone_prompt_formatted with the LLM
35
+ standalone_chain = (standalone_prompt_formatted | llm).with_types(input_type=schemas.HistoryInput)
36
 
37
+ input_1 = RunnablePassthrough.assign(new_question=standalone_chain)
38
+ input_2 = {
39
+ 'context': lambda x: format_context(data_indexer.search(x['new_question'])),
40
+ 'standalone_question': lambda x: x['new_question']
41
+ }
42
+ input_to_rag_chain = input_1 | input_2
43
 
44
  # TODO: use input_to_rag_chain, rag_prompt_formatted,
45
  # HistoryInput and the LLM to build the rag_chain.
46
+ rag_chain = (input_to_rag_chain | rag_prompt_formatted | llm).with_types(input_type=schemas.HistoryInput)
47
 
48
  # TODO: Implement the filtered_rag_chain. It should be the
49
  # same as the rag_chain but with hybrid_search = True.
50
+
51
+ input_1 = RunnablePassthrough.assign(new_question=standalone_chain)
52
+ input_2 = {
53
+ 'context': lambda x: format_context(data_indexer.search(x['new_question'], hybrid_search=True)),
54
+ 'standalone_question': lambda x: x['new_question']
55
+ }
56
+ filtered_input_to_rag_chain = input_1 | input_2
57
+ filtered_rag_chain = (filtered_input_to_rag_chain | rag_prompt_formatted | llm).with_types(input_type=schemas.HistoryInput)
58
 
59
 
60
 
app/code_data/langchain_repo ADDED
@@ -0,0 +1 @@
 
 
1
+ Subproject commit 82b5b77940e97f65179efa0268031c47d0584a1c
app/data_indexing.py CHANGED
@@ -38,6 +38,7 @@ class DataIndexer:
38
  )
39
 
40
  self.index = self.pinecone_client.Index(self.index_name)
 
41
  # TODO: make sure to build the index.
42
  self.source_index = self.get_source_index()
43
 
@@ -75,14 +76,19 @@ class DataIndexer:
75
  # values = self.embedding_client.feature_extraction([
76
  # doc.page_content for doc in batch
77
  # ])
78
- values = None
 
 
79
 
80
  # TODO: create a list of unique identifiers for each element in the batch with the uuid package.
81
- vector_ids = None
82
 
83
  # TODO: create a list of dictionaries representing the metadata. Capture the text data
84
  # with the "text" key, and make sure to capture the rest of the doc.metadata.
85
- metadatas = None
 
 
 
86
 
87
  # create a list of dictionaries with keys "id" (the unique identifiers), "values"
88
  # (the vector representation), and "metadata" (the metadata).
@@ -94,7 +100,7 @@ class DataIndexer:
94
 
95
  try:
96
  # TODO: Use the function upsert to upload the data to the database.
97
- upsert_response = None
98
  print(upsert_response)
99
  except Exception as e:
100
  print(e)
@@ -111,17 +117,20 @@ class DataIndexer:
111
  # TODO: embed the text_query by using the embedding model
112
  # TODO: choose your embedding model
113
  # vector = self.embedding_client.feature_extraction(text_query)
114
- # vector = self.embedding_client.embed_query(text_query)
115
- vector = None
116
-
117
  # TODO: use the vector representation of the text_query to
118
  # search the database by using the query function.
119
- result = None
 
 
 
 
120
 
121
  docs = []
122
  for res in result["matches"]:
123
  # TODO: From the result's metadata, extract the "text" element.
124
- pass
 
125
 
126
  return docs
127
 
 
38
  )
39
 
40
  self.index = self.pinecone_client.Index(self.index_name)
41
+ print(self.index.query(namespace=''))
42
  # TODO: make sure to build the index.
43
  self.source_index = self.get_source_index()
44
 
 
76
  # values = self.embedding_client.feature_extraction([
77
  # doc.page_content for doc in batch
78
  # ])
79
+ values = self.embedding_client.embed_documents([
80
+ doc.page_content for doc in batch
81
+ ])
82
 
83
  # TODO: create a list of unique identifiers for each element in the batch with the uuid package.
84
+ vector_ids = [str(uuid.uuid4()) for _ in batch]
85
 
86
  # TODO: create a list of dictionaries representing the metadata. Capture the text data
87
  # with the "text" key, and make sure to capture the rest of the doc.metadata.
88
+ metadatas = [{
89
+ 'text': doc.page_content,
90
+ **doc.metadata
91
+ } for doc in batch]
92
 
93
  # create a list of dictionaries with keys "id" (the unique identifiers), "values"
94
  # (the vector representation), and "metadata" (the metadata).
 
100
 
101
  try:
102
  # TODO: Use the function upsert to upload the data to the database.
103
+ upsert_response = self.index.upsert(vectors=vectors)
104
  print(upsert_response)
105
  except Exception as e:
106
  print(e)
 
117
  # TODO: embed the text_query by using the embedding model
118
  # TODO: choose your embedding model
119
  # vector = self.embedding_client.feature_extraction(text_query)
120
+ vector = self.embedding_client.embed_query(text_query)
 
 
121
  # TODO: use the vector representation of the text_query to
122
  # search the database by using the query function.
123
+ result = self.index.query(vector,
124
+ top_k=top_k,
125
+ filter=filter, # type: ignore
126
+ include_values=True,
127
+ include_metadata=True)
128
 
129
  docs = []
130
  for res in result["matches"]:
131
  # TODO: From the result's metadata, extract the "text" element.
132
+ # print(res.metadata)
133
+ docs.append(res.metadata['text'])
134
 
135
  return docs
136
 
app/main.py CHANGED
@@ -6,7 +6,7 @@ from langserve.serialization import WellKnownLCSerializer
6
  from typing import List
7
  from sqlalchemy.orm import Session
8
 
9
- from app.chains import simple_chain, formatted_chain, history_chain
10
  import app.crud as crud
11
  import app.models as models
12
  import app.schemas as schemas
@@ -64,7 +64,7 @@ async def history_stream(request: Request, db: Session = Depends(get_db)):
64
  chat_history_str = format_chat_history(chat_history)
65
  crud.add_message(db, schemas.MessageBase(message=user_request.question, type="user"), user_name)
66
  history_input = schemas.HistoryInput(chat_history=chat_history_str, question=user_request.question)
67
- print(history_input)
68
  return EventSourceResponse(generate_stream(history_input, history_chain, [LogResponseCallback(user_request, db)]))
69
 
70
 
@@ -77,7 +77,14 @@ async def rag_stream(request: Request, db: Session = Depends(get_db)):
77
  # - We add as part of the user history the current question by using add_message.
78
  # - We create an instance of HistoryInput by using format_chat_history.
79
  # - We use the history input within the rag chain.
80
- raise NotImplemented
 
 
 
 
 
 
 
81
 
82
 
83
  @app.post("/filtered_rag/stream")
 
6
  from typing import List
7
  from sqlalchemy.orm import Session
8
 
9
+ from app.chains import simple_chain, formatted_chain, history_chain, rag_chain
10
  import app.crud as crud
11
  import app.models as models
12
  import app.schemas as schemas
 
64
  chat_history_str = format_chat_history(chat_history)
65
  crud.add_message(db, schemas.MessageBase(message=user_request.question, type="user"), user_name)
66
  history_input = schemas.HistoryInput(chat_history=chat_history_str, question=user_request.question)
67
+ # print(history_input)
68
  return EventSourceResponse(generate_stream(history_input, history_chain, [LogResponseCallback(user_request, db)]))
69
 
70
 
 
77
  # - We add as part of the user history the current question by using add_message.
78
  # - We create an instance of HistoryInput by using format_chat_history.
79
  # - We use the history input within the rag chain.
80
+ data = await request.json()
81
+ user_request = schemas.UserRequest(**data['input'])
82
+ user_name = user_request.username
83
+ chat_history = crud.get_user_chat_history(db, user_name)
84
+ chat_history_str = format_chat_history(chat_history)
85
+ crud.add_message(db, schemas.MessageBase(message=user_request.question, type="user"), user_name)
86
+ history_input = schemas.HistoryInput(chat_history=chat_history_str, question=user_request.question)
87
+ return EventSourceResponse(generate_stream(history_input, rag_chain, [LogResponseCallback(user_request, db)]))
88
 
89
 
90
  @app.post("/filtered_rag/stream")
app/prompts.py CHANGED
@@ -30,7 +30,10 @@ def format_context(docs: List[str]):
30
  # so we need to concatenate that list into a text that can fit into
31
  # the rag_prompt_formatted. Implement format_context that takes a
32
  # like of strings and returns the context as one string.
33
- raise NotImplemented
 
 
 
34
 
35
  raw_prompt = "{question}"
36
 
@@ -44,11 +47,20 @@ helpful answer:"""
44
 
45
  # TODO: Create the standalone_prompt prompt that will capture the question and the chat history
46
  # to generate a standalone question. It needs a {chat_history} placeholder and a {question} placeholder,
47
- standalone_prompt: str = None
 
 
 
 
 
 
48
 
49
  # TODO: Create the rag_prompt that will capture the context and the standalone question to generate
50
  # a final answer to the question.
51
- rag_prompt: str = None
 
 
 
52
 
53
  # TODO: create raw_prompt_formatted by using format_prompt
54
  raw_prompt_formatted = format_prompt(raw_prompt)
 
30
  # so we need to concatenate that list into a text that can fit into
31
  # the rag_prompt_formatted. Implement format_context that takes a
32
  # like of strings and returns the context as one string.
33
+ context = ""
34
+ for doc in docs:
35
+ context += f"{doc}\n"
36
+ return context
37
 
38
  raw_prompt = "{question}"
39
 
 
47
 
48
  # TODO: Create the standalone_prompt prompt that will capture the question and the chat history
49
  # to generate a standalone question. It needs a {chat_history} placeholder and a {question} placeholder,
50
+ standalone_prompt: str = """Given the following conversation and a follow up question, rephrase the
51
+ follow up question to be a standalone question, in its original language.
52
+ Chat History:
53
+ {chat_history}
54
+ Follow Up Input: {question}
55
+ Standalone question:
56
+ """
57
 
58
  # TODO: Create the rag_prompt that will capture the context and the standalone question to generate
59
  # a final answer to the question.
60
+ rag_prompt: str = """Use the following pieces of context to answer the question at the end. If you don't know the answer, just say that you don't know. Use three sentences maximum and keep the answer concise.
61
+ {context}
62
+ Question: {question}
63
+ Helpful Answer:"""
64
 
65
  # TODO: create raw_prompt_formatted by using format_prompt
66
  raw_prompt_formatted = format_prompt(raw_prompt)