wt002 commited on
Commit
26f3037
·
verified ·
1 Parent(s): 5b6d016

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +78 -14
app.py CHANGED
@@ -250,6 +250,38 @@ def should_continue(state: AgentState) -> str:
250
  return "reason"
251
 
252
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
253
  def reasoning_node(state: AgentState) -> AgentState:
254
  """
255
  Node for the agent to analyze the question, determine next steps,
@@ -304,7 +336,42 @@ def reasoning_node(state: AgentState) -> AgentState:
304
  f"- **{t.name}**: {t.description}" for t in state.get("tools", [])
305
  ])
306
 
307
- # Enhanced system prompt for better JSON adherence
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
308
  system_prompt = (
309
  "You are an expert problem solver, designed to provide concise and accurate answers. "
310
  "Your process involves analyzing the question, intelligently selecting and using tools, "
@@ -318,21 +385,12 @@ def reasoning_node(state: AgentState) -> AgentState:
318
  "- Use **document_qa** when the question explicitly refers to a specific document or when you have content to query. Input format: 'document_text||question'.\n"
319
  "- Use **python_execution** for complex calculations, data manipulation, or logical operations that cannot be done with simple reasoning. Always provide the full Python code, ensuring it's valid and executable, and assign the final result to a variable named '_result_value' (e.g., '_result_value = 1 + 1').\n"
320
  "- Use **transcript_video** for any question involving video or audio content (e.g., YouTube). Provide the full YouTube URL or video ID.\n\n"
 
321
  "**Current Context:**\n{context}\n\n"
322
  "**Previous Reasoning Steps:**\n{reasoning}\n\n"
323
  "**Current Task:** {current_task}\n"
324
  "**Current Thoughts:** {current_thoughts}\n\n"
325
- "**Your Response MUST be a valid JSON object with the following keys:**\n"
326
- "```json\n"
327
- "{\n"
328
- " \"Reasoning\": \"Your detailed analysis of the question and why you chose a specific action. Focus on the logical steps.\",\n"
329
- " \"Action\": \"[Tool name OR 'Final Answer']\",\n"
330
- " \"Action Input\": \"[Input for the selected tool OR the complete final answer]\"\n"
331
- "}\n"
332
- "```\n"
333
- "**CRITICAL RULE: 'Action' and 'Action Input' MUST NOT be empty strings, unless 'Action' is 'Final Answer' and 'Action Input' is the conclusive response.**\n"
334
- "If you cannot determine a suitable tool or a conclusive final answer after exhausting options, return Action: 'Final Answer' with a message like 'I cannot answer this question with the available tools.' or 'More information is needed.'\n"
335
- "Ensure 'Action Input' is always the complete, valid input for the chosen 'Action'. If 'Action' is 'Final Answer', provide the complete, concise answer."
336
  )
337
 
338
  prompt = ChatPromptTemplate.from_messages([
@@ -341,6 +399,7 @@ def reasoning_node(state: AgentState) -> AgentState:
341
  ])
342
 
343
  formatted_messages = prompt.format_messages(
 
344
  context=state["context"],
345
  reasoning=state["reasoning"],
346
  question=state["question"],
@@ -498,14 +557,19 @@ class BasicAgent:
498
  python_execution,
499
  VideoTranscriptionTool()
500
  ]
 
 
 
501
  self.workflow = create_agent_workflow(self.tools)
502
-
503
  def __call__(self, question: str) -> str:
504
  print(f"\n--- Agent received question: {question[:80]}{'...' if len(question) > 80 else ''} ---")
505
 
506
  state = {
507
  "question": question,
508
- "context": {},
 
 
509
  "reasoning": "",
510
  "iterations": 0,
511
  "history": [HumanMessage(content=question)],
 
250
  return "reason"
251
 
252
 
253
+ from langchain_community.embeddings import HuggingFaceEmbeddings
254
+ from langchain_community.vectorstores import Chroma
255
+ from langchain.text_splitter import RecursiveCharacterTextSplitter
256
+ from langchain_core.documents import Document
257
+
258
+ # ====== DOCUMENT PROCESSING SETUP ======
259
+ def create_vector_store():
260
+ """Create vector store with predefined documents"""
261
+ # Define the documents
262
+ documents = [
263
+ Document(page_content="The capital of France is Paris.", metadata={"source": "geography"}),
264
+ Document(page_content="Python is a popular programming language created by Guido van Rossum.", metadata={"source": "tech"}),
265
+ Document(page_content="The Eiffel Tower is located in Paris, France.", metadata={"source": "landmarks"}),
266
+ ]
267
+
268
+ # Initialize embedding model
269
+ embeddings = HuggingFaceEmbeddings(model_name="all-MiniLM-L6-v2")
270
+
271
+ # Split documents into chunks
272
+ text_splitter = RecursiveCharacterTextSplitter(
273
+ chunk_size=500, # Smaller chunks for better precision
274
+ chunk_overlap=100
275
+ )
276
+ chunks = text_splitter.split_documents(documents)
277
+
278
+ # Create in-memory vector store
279
+ return Chroma.from_documents(
280
+ documents=chunks,
281
+ embedding=embeddings
282
+ )
283
+
284
+
285
  def reasoning_node(state: AgentState) -> AgentState:
286
  """
287
  Node for the agent to analyze the question, determine next steps,
 
336
  f"- **{t.name}**: {t.description}" for t in state.get("tools", [])
337
  ])
338
 
339
+ # ====== RAG RETRIEVAL ======
340
+ # Initialize vector store if not present
341
+ if "vector_store" not in state["context"]:
342
+ state["context"]["vector_store"] = create_vector_store()
343
+
344
+ vector_store = state["context"]["vector_store"]
345
+
346
+ # Perform retrieval
347
+ relevant_docs = vector_store.similarity_search(
348
+ state["question"],
349
+ k=3 # Retrieve top 3 most relevant chunks
350
+ )
351
+
352
+ # Format context for LLM
353
+ rag_context = "\n\n[Relevant Knowledge]\n"
354
+ rag_context += "\n---\n".join([doc.page_content for doc in relevant_docs])
355
+
356
+ # ====== RAG RETRIEVAL ======
357
+ # Initialize vector store if not present
358
+ if "vector_store" not in state["context"]:
359
+ state["context"]["vector_store"] = create_vector_store()
360
+
361
+ vector_store = state["context"]["vector_store"]
362
+
363
+ # Perform retrieval
364
+ relevant_docs = vector_store.similarity_search(
365
+ state["question"],
366
+ k=3 # Retrieve top 3 most relevant chunks
367
+ )
368
+
369
+ # Format context for LLM
370
+ rag_context = "\n\n[Relevant Knowledge]\n"
371
+ rag_context += "\n---\n".join([doc.page_content for doc in relevant_docs])
372
+
373
+ # ====== MODIFIED PROMPT ======
374
+ # Add RAG context to system prompt
375
  system_prompt = (
376
  "You are an expert problem solver, designed to provide concise and accurate answers. "
377
  "Your process involves analyzing the question, intelligently selecting and using tools, "
 
385
  "- Use **document_qa** when the question explicitly refers to a specific document or when you have content to query. Input format: 'document_text||question'.\n"
386
  "- Use **python_execution** for complex calculations, data manipulation, or logical operations that cannot be done with simple reasoning. Always provide the full Python code, ensuring it's valid and executable, and assign the final result to a variable named '_result_value' (e.g., '_result_value = 1 + 1').\n"
387
  "- Use **transcript_video** for any question involving video or audio content (e.g., YouTube). Provide the full YouTube URL or video ID.\n\n"
388
+ "**Retrieved Context:**\n{rag_context}\n\n" # ADDED RAG CONTEXT
389
  "**Current Context:**\n{context}\n\n"
390
  "**Previous Reasoning Steps:**\n{reasoning}\n\n"
391
  "**Current Task:** {current_task}\n"
392
  "**Current Thoughts:** {current_thoughts}\n\n"
393
+ # ... [rest of prompt remains same] ...
 
 
 
 
 
 
 
 
 
 
394
  )
395
 
396
  prompt = ChatPromptTemplate.from_messages([
 
399
  ])
400
 
401
  formatted_messages = prompt.format_messages(
402
+ rag_context=rag_context, # ADD THIS ARGUMENT
403
  context=state["context"],
404
  reasoning=state["reasoning"],
405
  question=state["question"],
 
557
  python_execution,
558
  VideoTranscriptionTool()
559
  ]
560
+
561
+ # Pre-initialize RAG vector store
562
+ self.vector_store = create_vector_store()
563
  self.workflow = create_agent_workflow(self.tools)
564
+
565
  def __call__(self, question: str) -> str:
566
  print(f"\n--- Agent received question: {question[:80]}{'...' if len(question) > 80 else ''} ---")
567
 
568
  state = {
569
  "question": question,
570
+ "context": {
571
+ "vector_store": self.vector_store # Include vector store in context
572
+ },
573
  "reasoning": "",
574
  "iterations": 0,
575
  "history": [HumanMessage(content=question)],