Spaces:
Sleeping
Sleeping
Update app.py
Browse files
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 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
-
|
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)],
|