/# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
# Install dependencies (first time only)
uv sync
# Start the server
./run.sh
# or manually:
cd backend && uv run uvicorn app:app --reload --port 8000Requires a .env file in the project root with ANTHROPIC_API_KEY=... (see .env.example).
The app serves on http://localhost:8000. The backend auto-loads all .txt, .pdf, and .docx files from docs/ on startup.
This is a RAG chatbot: a FastAPI backend with a vanilla JS frontend, served as static files from the same server.
Request flow for a user query:
frontend/script.js—sendMessage()POSTs{ query, session_id }to/api/querybackend/app.py—query_documents()creates/resolves session, delegates toRAGSystem.query()backend/rag_system.py—RAGSystemis the central orchestrator: loads conversation history, callsAIGenerator, collects sources, saves the exchange back to sessionbackend/ai_generator.py— makes the first Claude API call with thesearch_course_contenttool available; if Claude decides to search,_handle_tool_execution()runs the tool and makes a second Claude API call to synthesize the final answerbackend/search_tools.py—CourseSearchTool.execute()callsVectorStore.search(), tracks sources for the UIbackend/vector_store.py—VectorStorewraps two ChromaDB collections:course_catalog(course titles/metadata) andcourse_content(chunked lesson text). Semantic course name resolution happens via vector search oncourse_catalogbefore filteringcourse_content
Key design decisions:
- Claude drives retrieval via tool use (
tool_choice: auto) rather than a fixed retrieve-then-generate pipeline. One search per query maximum. SessionManagerstores conversation history in memory (not persisted across restarts). History is passed in the system prompt, not as message history.- Course title is used as the unique ID in ChromaDB — duplicate titles are skipped on ingestion.
Course documents in docs/ must follow this text format for DocumentProcessor to parse them correctly:
Course Title: <title>
Course Link: <url>
Course Instructor: <name>
Lesson 1: <lesson title>
Lesson Link: <url>
<lesson content...>
Lesson 2: <lesson title>
...
| Setting | Default | Purpose |
|---|---|---|
ANTHROPIC_MODEL |
claude-sonnet-4-20250514 |
Claude model used for generation |
EMBEDDING_MODEL |
all-MiniLM-L6-v2 |
SentenceTransformer model for ChromaDB |
CHUNK_SIZE |
800 | Max characters per content chunk |
CHUNK_OVERLAP |
100 | Overlap between adjacent chunks |
MAX_RESULTS |
5 | Max chunks returned per vector search |
MAX_HISTORY |
2 | Conversation exchanges kept in session |
CHROMA_PATH |
./chroma_db |
ChromaDB persistence directory (relative to backend/) |