rayymaxx commited on
Commit
c3500b2
·
1 Parent(s): 92d190f

Modified the prompt templates

Browse files
backend/chains/router.py CHANGED
@@ -85,7 +85,6 @@ from langchain_chroma import Chroma
85
  def init_vector_store():
86
  embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
87
 
88
- # Attempt to pull prebuilt vector store
89
  try:
90
  path = fetch_vector_store_if_needed(REPO_URL, BRANCH, REPO_VECTOR_SUBFOLDER, VECTOR_STORE_PATH)
91
  print(f"📂 Using vector store from {path}")
@@ -125,7 +124,12 @@ from langchain_community.chat_message_histories import ChatMessageHistory
125
 
126
  from backend.schemas.api_models import ChatInput, ChatOutput
127
  from backend.prompts.templates import (
128
- rag_prompt, quiz_generator_prompt, flashcard_generator_prompt, condense_question_prompt
 
 
 
 
 
129
  )
130
 
131
  def format_docs(docs): return "\n---\n".join(doc.page_content for doc in docs)
@@ -144,34 +148,35 @@ def get_memory_for_session(session_id: str):
144
  # Retriever
145
  def EducationalRetriever(): return vector_store.as_retriever(search_kwargs={"k": 5})
146
 
 
147
  # Conversation chain
 
148
  def AdaptiveConversationChain():
149
  retriever = EducationalRetriever()
150
  condense = (
151
- RunnableLambda(lambda x: {"question": x["input"], "chat_history": get_buffer_string(x["chat_history"])})
152
  | condense_question_prompt | openai_llm | StrOutputParser()
153
  )
154
  return (
155
  RunnablePassthrough.assign(standalone_question=condense)
156
  .assign(context=(RunnableLambda(lambda x: x["standalone_question"]) | retriever))
157
  | RunnableParallel(
158
- answer=(
159
- RunnableLambda(lambda x: {
160
- "context": format_docs(x["context"]),
161
- "question": x["input"],
162
- "subject": x.get("subject", "the topic"),
163
- "difficulty_level": x.get("difficulty_level", "beginner"),
164
- }) | rag_prompt | finetuned_llm | StrOutputParser()
165
- ),
166
  sources=RunnableLambda(lambda x: get_sources_from_docs(x["context"])),
167
  )
168
  )
169
 
170
- # Content generation (quiz + flashcards)
171
- def ContentGenerator():
172
- retriever = EducationalRetriever()
173
- QuizChain = (
174
- RunnablePassthrough.assign(context=(RunnableLambda(lambda x: x["input"]) | retriever))
 
175
  | RunnableParallel(
176
  answer=(RunnableLambda(lambda x: {
177
  "context": format_docs(x["context"]),
@@ -181,8 +186,10 @@ def ContentGenerator():
181
  sources=RunnableLambda(lambda x: get_sources_from_docs(x["context"])),
182
  )
183
  )
184
- FlashcardChain = (
185
- RunnablePassthrough.assign(context=(RunnableLambda(lambda x: x["input"]) | retriever))
 
 
186
  | RunnableParallel(
187
  answer=(RunnableLambda(lambda x: {
188
  "context": format_docs(x["context"]),
@@ -191,29 +198,69 @@ def ContentGenerator():
191
  sources=RunnableLambda(lambda x: get_sources_from_docs(x["context"])),
192
  )
193
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
194
  return RunnableBranch(
195
- (lambda x: x.get("request_type") == "quiz_generation", QuizChain),
196
- (lambda x: x.get("request_type") == "flashcard_creation", FlashcardChain),
 
 
197
  RunnableLambda(lambda _: {"answer": "Unknown request.", "sources": []}),
198
  )
199
 
 
200
  # Analyzer stub
 
201
  def LearningAnalyzer():
202
  return RunnableLambda(lambda x: (print("LOG: LearningAnalyzer", x.get("input")), x)[1])
203
 
 
204
  # Main assistant chain
 
205
  def run_educational_assistant():
206
  return RunnableBranch(
207
  (lambda x: x.get("request_type") == "tutoring", AdaptiveConversationChain()),
208
  ContentGenerator(),
209
  )
210
 
 
211
  # Exposed pipelines
 
212
  educational_assistant_chain = run_educational_assistant() | LearningAnalyzer()
213
  chat_chain_with_history = RunnableWithMessageHistory(
214
  educational_assistant_chain, get_memory_for_session,
215
  input_messages_key="input", history_messages_key="chat_history", output_messages_key="answer"
216
  ).with_types(input_type=ChatInput, output_type=ChatOutput)
 
217
  content_generation_chain = (ContentGenerator() | LearningAnalyzer()).with_types(
218
  input_type=ChatInput, output_type=ChatOutput
219
  )
 
85
  def init_vector_store():
86
  embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
87
 
 
88
  try:
89
  path = fetch_vector_store_if_needed(REPO_URL, BRANCH, REPO_VECTOR_SUBFOLDER, VECTOR_STORE_PATH)
90
  print(f"📂 Using vector store from {path}")
 
124
 
125
  from backend.schemas.api_models import ChatInput, ChatOutput
126
  from backend.prompts.templates import (
127
+ rag_prompt,
128
+ quiz_generator_prompt,
129
+ flashcard_generator_prompt,
130
+ explanation_prompt,
131
+ definition_prompt,
132
+ condense_question_prompt
133
  )
134
 
135
  def format_docs(docs): return "\n---\n".join(doc.page_content for doc in docs)
 
148
  # Retriever
149
  def EducationalRetriever(): return vector_store.as_retriever(search_kwargs={"k": 5})
150
 
151
+ # -------------------------
152
  # Conversation chain
153
+ # -------------------------
154
  def AdaptiveConversationChain():
155
  retriever = EducationalRetriever()
156
  condense = (
157
+ RunnableLambda(lambda x: {"question": x["input"], "chat_history": get_buffer_string(x["chat_history"])} )
158
  | condense_question_prompt | openai_llm | StrOutputParser()
159
  )
160
  return (
161
  RunnablePassthrough.assign(standalone_question=condense)
162
  .assign(context=(RunnableLambda(lambda x: x["standalone_question"]) | retriever))
163
  | RunnableParallel(
164
+ answer=(RunnableLambda(lambda x: {
165
+ "context": format_docs(x["context"]),
166
+ "question": x["input"],
167
+ "subject": x.get("subject", "the topic"),
168
+ "difficulty_level": x.get("difficulty_level", "beginner"),
169
+ }) | rag_prompt | finetuned_llm | StrOutputParser()),
 
 
170
  sources=RunnableLambda(lambda x: get_sources_from_docs(x["context"])),
171
  )
172
  )
173
 
174
+ # -------------------------
175
+ # Generalized Content Chains
176
+ # -------------------------
177
+ def QuizChain():
178
+ return (
179
+ RunnablePassthrough.assign(context=(RunnableLambda(lambda x: x["input"]) | EducationalRetriever()))
180
  | RunnableParallel(
181
  answer=(RunnableLambda(lambda x: {
182
  "context": format_docs(x["context"]),
 
186
  sources=RunnableLambda(lambda x: get_sources_from_docs(x["context"])),
187
  )
188
  )
189
+
190
+ def FlashcardChain():
191
+ return (
192
+ RunnablePassthrough.assign(context=(RunnableLambda(lambda x: x["input"]) | EducationalRetriever()))
193
  | RunnableParallel(
194
  answer=(RunnableLambda(lambda x: {
195
  "context": format_docs(x["context"]),
 
198
  sources=RunnableLambda(lambda x: get_sources_from_docs(x["context"])),
199
  )
200
  )
201
+
202
+ def ExplanationChain():
203
+ return (
204
+ RunnablePassthrough.assign(context=(RunnableLambda(lambda x: x["input"]) | EducationalRetriever()))
205
+ | RunnableParallel(
206
+ answer=(RunnableLambda(lambda x: {
207
+ "context": format_docs(x["context"]),
208
+ "topic": x.get("subject", "topic"),
209
+ "difficulty_level": x.get("difficulty_level", "beginner"),
210
+ }) | explanation_prompt | finetuned_llm | StrOutputParser()),
211
+ sources=RunnableLambda(lambda x: get_sources_from_docs(x["context"])),
212
+ )
213
+ )
214
+
215
+ def DefinitionChain():
216
+ return (
217
+ RunnablePassthrough.assign(context=(RunnableLambda(lambda x: x["input"]) | EducationalRetriever()))
218
+ | RunnableParallel(
219
+ answer=(RunnableLambda(lambda x: {
220
+ "context": format_docs(x["context"]),
221
+ "term": x.get("subject", "term"),
222
+ "difficulty_level": x.get("difficulty_level", "beginner"),
223
+ }) | definition_prompt | finetuned_llm | StrOutputParser()),
224
+ sources=RunnableLambda(lambda x: get_sources_from_docs(x["context"])),
225
+ )
226
+ )
227
+
228
+ # -------------------------
229
+ # Dispatcher for content generation
230
+ # -------------------------
231
+ def ContentGenerator():
232
  return RunnableBranch(
233
+ (lambda x: x.get("request_type") == "quiz_generation", QuizChain()),
234
+ (lambda x: x.get("request_type") == "flashcard_creation", FlashcardChain()),
235
+ (lambda x: x.get("request_type") == "explanation", ExplanationChain()),
236
+ (lambda x: x.get("request_type") == "definition", DefinitionChain()),
237
  RunnableLambda(lambda _: {"answer": "Unknown request.", "sources": []}),
238
  )
239
 
240
+ # -------------------------
241
  # Analyzer stub
242
+ # -------------------------
243
  def LearningAnalyzer():
244
  return RunnableLambda(lambda x: (print("LOG: LearningAnalyzer", x.get("input")), x)[1])
245
 
246
+ # -------------------------
247
  # Main assistant chain
248
+ # -------------------------
249
  def run_educational_assistant():
250
  return RunnableBranch(
251
  (lambda x: x.get("request_type") == "tutoring", AdaptiveConversationChain()),
252
  ContentGenerator(),
253
  )
254
 
255
+ # -------------------------
256
  # Exposed pipelines
257
+ # -------------------------
258
  educational_assistant_chain = run_educational_assistant() | LearningAnalyzer()
259
  chat_chain_with_history = RunnableWithMessageHistory(
260
  educational_assistant_chain, get_memory_for_session,
261
  input_messages_key="input", history_messages_key="chat_history", output_messages_key="answer"
262
  ).with_types(input_type=ChatInput, output_type=ChatOutput)
263
+
264
  content_generation_chain = (ContentGenerator() | LearningAnalyzer()).with_types(
265
  input_type=ChatInput, output_type=ChatOutput
266
  )
backend/prompts/templates.py CHANGED
@@ -28,6 +28,27 @@ Helpful Answer:
28
  rag_prompt = ChatPromptTemplate.from_template(RAG_PROMPT_TEMPLATE)
29
 
30
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  QUIZ_GENERATOR_PROMPT_TEMPLATE = """
32
  You are an expert quiz creator for a tech learning platform.
33
  Your task is to create at least 5-question multiple-choice quiz based on the provided context for the subject of '{subject}'.
@@ -73,4 +94,26 @@ Context:
73
 
74
  Flashcards:
75
  """
76
- flashcard_generator_prompt = ChatPromptTemplate.from_template(FLASHCARD_GENERATOR_PROMPT_TEMPLATE)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  rag_prompt = ChatPromptTemplate.from_template(RAG_PROMPT_TEMPLATE)
29
 
30
 
31
+ DEFINITION_PROMPT_TEMPLATE = """
32
+ You are a helpful AI tutor for the DirectEd learning platform.
33
+
34
+ Your task is to provide ONLY the most relevant definition or explanation
35
+ from the given context for the user's question.
36
+
37
+ - Keep it clear and beginner-friendly.
38
+ - Do NOT include extra information such as applications, models, or history unless the user asks.
39
+ - If the context does not contain the answer, reply with: "I don’t know."
40
+
41
+ Context:
42
+ {context}
43
+
44
+ Question:
45
+ {question}
46
+
47
+ Beginner-friendly Definition:
48
+ """
49
+ definition_prompt = ChatPromptTemplate.from_template(DEFINITION_PROMPT_TEMPLATE)
50
+
51
+
52
  QUIZ_GENERATOR_PROMPT_TEMPLATE = """
53
  You are an expert quiz creator for a tech learning platform.
54
  Your task is to create at least 5-question multiple-choice quiz based on the provided context for the subject of '{subject}'.
 
94
 
95
  Flashcards:
96
  """
97
+ flashcard_generator_prompt = ChatPromptTemplate.from_template(FLASHCARD_GENERATOR_PROMPT_TEMPLATE)
98
+
99
+
100
+
101
+ EXPLANATION_PROMPT_TEMPLATE = """
102
+ You are a helpful AI tutor for the DirectEd learning platform.
103
+
104
+ Your task is to explain the topic '{topic}' in a way that a '{difficulty_level}' learner can understand.
105
+
106
+ - Keep it simple, step-by-step, and focused.
107
+ - Use examples or analogies where possible.
108
+ - Do NOT include unrelated details.
109
+ - If the context does not contain enough information, reply with: "I don’t know."
110
+
111
+ Context:
112
+ {context}
113
+
114
+ Topic:
115
+ {topic}
116
+
117
+ Beginner-friendly Explanation:
118
+ """
119
+ explanation_prompt = ChatPromptTemplate.from_template(EXPLANATION_PROMPT_TEMPLATE)