Persistent AI agent backend with long-term markdown memory, Retrieval-Augmented Generation (RAG), streaming responses, and LangGraph-based reasoning.
Scratchpad Backend is a FastAPI-powered backend for building persistent AI assistants that continuously accumulate and organize knowledge over time.
Unlike traditional chatbots that rely solely on conversation history, this system maintains two complementary knowledge stores:
The backend uses LangGraph, OpenAI, LlamaIndex, and Docling to provide a persistent AI assistant capable of reasoning, remembering, retrieving, and streaming responses in real time.
The project is designed to integrate with a frontend responsible for authentication and session management using user_id and thread_id.
User
│
▼
FastAPI REST API
│
▼
LangGraph Agent
│
┌──────────────┬───────────────┬
▼ ▼ ▼
Scratchpad RAG Engine Web Tools
Repository (LlamaIndex) (Search/Scrape)
│ │ │
└──────────────┴───────────────┘
│
▼
Streaming NDJSON Response
scratchpad-backend/
│
├── create_app.py
├── main.py
├── llms/
├── prompts/
├── rag/
├── stream/
│ ├── agent_stream.py
│ └── toolset/
│
└── work/
├── scratchpad/
├── ingestion/
│ ├── raw_data/
│ ├── parsed_data/
│ └── vectorstore/
└── checkpointer/
By default, all runtime data is stored inside the configured WORK_DIR (default: work/).
work/
├── scratchpad/
│ ├── index.md
│ └── *.md
│
├── ingestion/
│ ├── raw_data/
│ ├── parsed_data/
│ └── vectorstore/
│
└── checkpointer/
└── agent_memory.sqlite
Permanent markdown knowledge repository maintained by the AI agent.
Temporary location where uploaded files are placed before ingestion.
Files are removed after successful processing.
Markdown versions of uploaded documents generated using Docling.
LlamaIndex vector databases isolated by user and thread.
SQLite database storing LangGraph checkpoints and conversation state.
| Component | Technology |
|---|---|
| Backend | FastAPI |
| Agent Framework | LangGraph |
| LLM | OpenAI |
| Embeddings | Google Generative AI |
| Vector Database | LlamaIndex |
| Document Parsing | Docling |
| Memory | SQLite |
| Web Search | DuckDuckGo |
| Website Scraping | Firecrawl |
Clone the repository:
git clone https://github.com/tuhindutta/scratchpad-backend.git
cd scratchpad-backend
Install dependencies:
pip install -r requirements.txt
Create a .env file.
OPENAI_API_KEY=sk-...
GOOGLE_API_KEY=...
FIRECRAWL_API_KEY=...
AGENT_MODEL=gpt-4o-mini
RAG_MODEL=gpt-4o-mini
WORK_DIR=work
python main.py --port 8080
The backend will start at
http://localhost:8080
http://localhost:8080
/assistant/chatStreams agent reasoning and responses in NDJSON format.
{
"message": "Summarize my meeting notes",
"credential": {
"user_id": "user123",
"thread_id": "threadABC"
}
}
{"node":"reasoning","type":"tool","tool_name":"query_RAG_agent","content":"Searching..."}
{"node":"response","content":"Here is the summary..."}
/rag/ingestIngests all files present in:
work/ingestion/raw_data/
Pipeline:
Raw Files
│
▼
Docling Parsing
│
▼
Markdown Conversion
│
▼
Vector Embedding
│
▼
LlamaIndex Storage
│
▼
Agent Notification
/assistant/chats/list
Returns all active conversation threads.
Example:
{
"active_threads":[
"thread1",
"thread2"
]
}
/assistant/chats/delete/thread
{
"thread_id":"thread1"
}
Deletes the specified conversation.
/assistant/chats/delete/full
Removes all stored conversation history.
All streaming endpoints return newline-delimited JSON (NDJSON).
Example:
{"node":"reasoning","content":"Thinking..."}
{"node":"reasoning","tool_name":"print_tree"}
{"node":"response","content":"Final answer"}
This allows frontends to progressively render:
Responsible for:
Files:
create_app.py
main.py
Implemented using LangGraph.
Responsibilities:
File:
stream/agent_stream.py
Two independent models are used.
Used for:
Default:
ChatOpenAI
Temperature:
0.3
Used for:
Temperature:
0.1
Responsible for:
Workflow:
Documents
│
▼
Docling
│
▼
Markdown
│
▼
Embeddings
│
▼
LlamaIndex
The Scratchpad is the agent’s permanent knowledge repository.
Knowledge is stored as markdown documents.
A mandatory index.md maintains the repository catalog.
The agent is responsible for:
The agent has access to a comprehensive set of tools.
User Message
│
▼
Reasoning
│
▼
Tool Selection
│
▼
Repository / RAG / Web
│
▼
Streaming Updates
│
▼
Final Response
Upload Files
│
▼
raw_data/
│
▼
Docling Parser
│
▼
Markdown
│
▼
Embeddings
│
▼
Vector Store
│
▼
Agent Notification
Conversation state is managed using LangGraph checkpoints.
Memory is isolated using:
user_id
+
thread_id
Each conversation maintains independent context and history.
The backend automatically handles:
Create additional LangChain tools inside:
stream/toolset/tools.py
Alternative implementations for Groq and Gemini are already scaffolded and can be enabled with minimal changes.
System prompts are stored in:
prompts/
A frontend should:
user_idthread_idraw_dataThis project is licensed under the MIT License.