**What was implemented** - A FastAPI service exposing a single `/ask` endpoint that accepts a user question and returns an answer together with the sources used. - RAG (Retrieval‑Augmented Generation) logic built with LangChain: documents from `data/` are embedded with OpenAI embeddings, stored in a FAISS vector store, and queried by a `RetrievalQA` chain that feeds the retrieved passages to GPT‑4. - Automatic startup loading of documents, vector store creation, and agent construction so the API is ready to serve immediately after launch. **Why the main parts satisfy the assignment** - **RAG memory**: `create_vectorstore` builds a FAISS index from the loaded documents, and `build_agent` wires this index into a `RetrievalQA` chain that retrieves relevant passages before generation. - **Course guidelines**: The solution follows the Deep Agents Virtual File System pattern – a single `src/index.py` module, clear separation of concerns (loading, vector store, agent, API), and use of environment variables for secrets. - **Python implementation**: All code is pure Python 3.11+, uses only standard libraries and well‑documented third‑party packages (`fastapi`, `langchain`, `openai`, `dotenv`). - **Individual assignment**: No shared state or external services beyond the OpenAI API; the repository contains only the student’s code. **Key code excerpts** *Loading documents* (`src/index.py`) ```python def load_documents(path: Path) -> List: if not path.exists() or not path.is_dir(): print(f"Warning: Data directory '{path}' not found. No documents loaded.") return [] loader = DirectoryLoader(str(path), glob="**/*.txt") documents = loader.load() print(f"Loaded {len(documents)} documents from '{path}'.") return documents ``` *Creating the vector store* (`src/index.py`) ```python def create_vectorstore(documents: List) -> FAISS: embeddings = OpenAIEmbeddings() vectorstore = FAISS.from_documents(documents, embeddings) print("FAISS vector store created.") return vectorstore ``` *Building the RetrievalQA agent* (`src/index.py`) ```python def build_agent(vectorstore: FAISS) -> RetrievalQA: llm = OpenAI(model_name="gpt-4", temperature=0, openai_api_key=OPENAI_API_KEY) retriever = vectorstore.as_retriever(search_kwargs={"k": 4}) qa_chain = RetrievalQA.from_chain_type( llm=llm, chain_type="stuff", retriever=retriever, return_source_documents=True, ) print("RetrievalQA agent constructed.") return qa_chain ``` *FastAPI endpoint* (`src/index.py`) ```python @app.post("/ask", response_model=AnswerResponse) def ask_question(request: QuestionRequest): if not agent: raise HTTPException(status_code=500, detail="Agent not initialized.") try: result = agent({"question": request.question}) answer = result.get("answer", "") sources = [doc.metadata.get("source", "") for doc in result.get("source_documents", [])] return AnswerResponse(answer=answer, sources=sources) except Exception as e: raise HTTPException(status_code=500, detail=str(e)) ``` **Honest limitations** - The vector store is rebuilt on every server restart; no persistence across restarts. - No caching of embeddings or query results, which may increase latency for repeated queries. - Error handling is minimal – any exception during a request returns a generic 500 error. - The solution assumes all documents are plain `.txt`; other formats would need additional loaders. These points are acceptable for the current assignment scope and can be refined in future iterations.