This project is an agentic RAG application with:
- A Streamlit chat interface
- A LangGraph agent and router
- Tavily and SerpAPI web search tools
- Composio agent toolkits (Jira, Linear, Gmail, Google Calendar, Notion, GitHub, Typeform, Apollo, Todoist)
- LlamaCloud/LlamaParse document parsing
- Pinecone semantic retrieval
- BM25 lexical retrieval
- Neo4j knowledge-graph storage and visualization
- SQLite conversation history
- NeMo Guardrails input validation and pre-check greetings bypass
- Human approval before saving a turn to long-term graph/vector memory
This project contains three independent agentic workflows with specific design purposes, interfaces, and integration components:
- Entrypoint File: src/agents/rag_agent.py
- UI Interface: ui/app.py (Runs on port
8501) - Core Tech Stack: LangGraph (routing & node state), Pinecone (dense vector search), BM25 (lexical search), Neo4j (Knowledge Graph constraints & Cypher execution), SQLite (conversation storage), spacy (NER & relationship extraction).
- π Integrated Tools:
- Tavily & SerpAPI for real-time web searches.
- π‘οΈ NVIDIA NeMo Guardrails:
- YES, used ONLY in this agent.
- Pre-checks incoming queries against semantic intent rules in disallowed.co and config.yml.
- Blocks disallowed topics (cooking, coding, system overrides, violence) instantly before executing LangGraph nodes.
- Combines with a local fast-path greeting filter in src/utils/guardrails.py to save LLM / API token costs on simple hellos/greetings.
- π LlamaCloud (LlamaParse):
- YES, used ONLY in this agent & ingestion pipeline.
- Powers high-fidelity document parsing for uploaded files (PDF, DOCX, etc.) both in the chat UI upload and in the background ingestion pipeline (
src/pipelines/ingestion.py). - Implements SHA-256 checksum caching (
data/parsed/<sha256>.md) to avoid duplicate API calls.
- Entrypoint File: src/agents/composio_agent.py
- UI Interface: ui/composio-agent.py (Runs on port
8502) - Core Tech Stack: LangGraph ReAct loop (
create_react_agent), OpenAI GPT-4o-mini, Composio client. - π Integrated Tools: Composio Toolkits (GitHub, Jira, Linear, Slack, Gmail, Google Calendar, Notion, Typeform, Apollo, Todoist, Reddit, LinkedIn, Google Meet, Google Docs) linked to the user's sidebar OAuth sessions.
- π‘οΈ NVIDIA NeMo Guardrails: NO, not used in this agent.
- π LlamaCloud (LlamaParse): NO, not used in this agent.
- Entrypoint File: src/workflows/agent.py
- UI Interface: src/workflows/app.py (Runs on port
8503) - Core Tech Stack: LangGraph custom StateGraph (Agent node + Verifier node), OpenAI, Composio client.
- π Integrated Tools: Composio Meta-Tools (
COMPOSIO_SEARCH_TOOLS&COMPOSIO_GET_TOOL_SCHEMAS) to dynamically query action parameters and build execution schemas. - Architecture: Decouples AI Workflow Design (searching for action schemas using OpenAI and building the workflow structure) from Workflow Execution (pure, deterministic python calls via the Composio SDK, requiring zero AI calls).
- π‘οΈ NVIDIA NeMo Guardrails: NO, not used in this agent.
- π LlamaCloud (LlamaParse): NO, not used in this agent.
- Python
>=3.12,<3.14 - Poetry
- API credentials configured in
.env - Pinecone and Neo4j instances
- Windows Users: Visual Studio C++ Build Tools (specifically the Desktop development with C++ workload) is required to compile NeMo Guardrails dependencies (e.g.,
hnswlib).
To install dependencies and lock environment:
poetry lock
poetry installCreate a .env file in the repository root:
OPENAI_API_KEY=your_openai_api_key
TAVILY_API_KEY=your_tavily_api_key
SERPAPI_API_KEY=your_serpapi_api_key
LLAMA_CLOUD_API_KEY=your_llamacloud_api_key
COMPOSIO_API_KEY=your_composio_api_key
PINECONE_API_KEY=your_pinecone_key
PINECONE_INDEX_NAME=agentic-system
NEO4J_URI=bolt://localhost:7687
NEO4J_USERNAME=neo4j
NEO4J_PASSWORD=your_password
NEO4J_DATABASE=neo4jRuns on port 8501 by default.
poetry run streamlit run ui/app.pyOpen: http://localhost:8501
Runs on port 8502.
poetry run streamlit run ui/composio-agent.py --server.port 8502Open: http://localhost:8502
Runs on port 8503 (or any free port).
poetry run streamlit run src/workflows/app.py --server.port 8503Open: http://localhost:8503
ai_flow/
βββ dags/
β βββ document_ingestion_dag.py
βββ data/
β βββ uploads/ # Safe content-addressed uploads; gitignored
β βββ parsed/ # Cached LlamaCloud markdown; gitignored
β βββ conversations.db # Chat history; gitignored
β βββ bm25_index.pkl # Local lexical index; gitignored
βββ src/
β βββ agents/
β β βββ rag_agent.py # Main RAG agent logic
β β βββ composio_agent.py # Composio integrations agent
β β βββ state.py # LangGraph state configurations
β βββ guardrails/
β β βββ config.yml # NeMo Guardrails configuration
β β βββ disallowed.co # Colang disallowed intents and flows
β βββ pipelines/
β β βββ ingestion.py # Background document ingestion pipeline
β βββ tools/
β β βββ conversation_store.py
β β βββ search.py
β βββ utils/
β β βββ entity_extractor.py
β β βββ graph_store.py
β β βββ guardrails.py # Pre-check greetings & NeMo Guardrails helper functions
β β βββ hybrid_search.py
β β βββ keyword_search.py
β β βββ parser.py # LlamaParse execution helper
β β βββ uploads.py # Safe uploads service
β β βββ vector_store.py
β βββ workflows/
β βββ __init__.py # Package marker
β βββ agent.py # Custom workflow designer agent
β βββ app.py # Streamlit UI for workflow agent
β βββ schema.py # Pydantic schemas for workflows
βββ tests/
β βββ test_agents.py
β βββ test_knowledge_graph_extraction.py
β βββ test_rag_utilities.py
β βββ test_uploads_and_history.py
β βββ test_vector_store_index.py
βββ ui/
β βββ app.py # RAG Agent Streamlit interface
β βββ composio-agent.py # Composio Agent Streamlit interface
β βββ pages/
β βββ relationships.py # Neo4j relationship graph visualization
βββ pyproject.toml
We implemented NVIDIA NeMo Guardrails (v0.22.0) to check and sanitise incoming user queries before they reach the main LangGraph agent.
NeMo Guardrails is specified in pyproject.toml and is automatically installed when you run poetry install. However, on Windows, installing it has specific compilation requirements:
-
C++ Build Tools Requirement: NeMo Guardrails installs underlying packages like
hnswlib(a C++ vector database binding) and others that compile native C++ extensions during installation.- Error Symptoms: Without C++ compilers, installation will fail with errors such as
error: Microsoft Visual C++ 14.0 or greater is required.or compilation errors forhnswlib. - Solution: You must install the Build Tools for Visual Studio (Visual Studio 2022 Build Tools or newer).
- Download from Visual Studio Build Tools.
- During the installation, select the Desktop development with C++ workload.
- Ensure the MSVC v143 - VS 2022 C++ x64/x86 build tools and Windows 11 SDK (or Windows 10 SDK) components are checked.
- Error Symptoms: Without C++ compilers, installation will fail with errors such as
-
Python Version: NeMo Guardrails has strict dependencies and requires Python
>=3.12,<3.14. -
Active Loops Setup: It requires
nest_asyncioto run within Streamlit or other environments with active asyncio loops. This is automatically handled dynamically insrc/utils/guardrails.py.
NeMo Guardrails coordinates validation flows using a combination of configuration files, semantic embedding search, and Colang script logic:
- Configuration (
src/guardrails/config.yml):- Defines the engines used:
gpt-4o-minifor the LLM-based rails andtext-embedding-3-smallfor generating sentence embeddings. - Restricts Dialog flows by setting
embeddings_only: truewith asimilarity_thresholdof0.82. - Specifies a fallback intent (
unhandled_user_intent) if the query does not map to any defined intent.
- Defines the engines used:
- Colang Intent Mapping (
src/guardrails/disallowed.co):- Maps standard user query variations to specific disallowed intents:
user ask cooking recipe: Intercepts cooking/food instructions.user ask developer mode: Intercepts system prompts, developer simulations, system overrides, and jailbreak attempts.user ask python code: Intercepts general coding requests.user ask violence: Intercepts safety-critical queries.
- Defines a standard refusal response:
bot refuse request: "I cannot help you with that request. I am designed to assist only with technical documentation and tech-related web searches, not for cooking, coding, developer simulation, or harmful queries."
- Defines dialog flows connecting each disallowed intent to the refusal action (e.g., if a user asks a cooking recipe, the bot replies with the refusal response).
- Maps standard user query variations to specific disallowed intents:
- Semantic Matching: When a query is checked, NeMo Guardrails calculates its embedding and checks the similarity against the canonical examples in the
.cofile. If the similarity meets or exceeds0.82, it triggers the associated block flow.
- Pre-Check Hook: Before the query initiates the LangGraph compiler and states in
src/agents/rag_agent.py,run_agent()triggerspre_check_query(). - Fast-Path Greeting Filter: Before making any API requests,
src/utils/guardrails.pyperforms a regex check againstGREETINGS_MAP. If a greeting is matched, the predefined reply is returned instantly. This prevents latency and avoids any LLM / OpenAI token costs. - Guardrails Invocation: If it's a standard user query,
check_input_guardrails(query)is called:- It temporarily injects
NEMO_API_KEY(configured insrc/utils/guardrails.py) as theOPENAI_API_KEYenvironment variable. - It retrieves the cached
LLMRailsinstance fromget_rails_instance(). - It calls
rails.generate()with the user query. - It inspects the returned string. If the response contains any of the known refusal markers (such as
"I cannot help you with that request"or"I am designed to assist only with technical documentation"), the helper marks the query as blocked and returns the refusal message. - The refusal message is saved to the SQLite conversation table using
record_conversation_turn(), and the execution terminates immediately, short-circuiting the LangGraph router.
- It temporarily injects
- Fail-Safe Fallback: If an exception or connection failure occurs during the NeMo check, the exception is caught, logged, and the query is allowed through to prevent disrupting the user flow.
We use LlamaParse to parse documents (PDFs, Docx, images, etc.) into high-quality structured markdown before chunking and embedding.
- Deterministic Checksum Cache: Before sending a file to LlamaCloud, we compute its SHA-256 checksum and save the parsed markdown in
data/parsed/<sha256>.md. If the file is uploaded again or processed in a background job, we reuse the cached markdown instead of making another paid API request to LlamaCloud. - Chunking: The markdown is chunked using the LlamaIndex
SentenceSplitter. - Vector Ingestion: Chunks are embedded using OpenAI embeddings and stored in Pinecone.
- Knowledge Graph Ingestion: Chunks are processed via
spacyto extract entities/relationships and merged into Neo4j using Cypher. - Lexical Index Ingestion: Chunks are indexed locally using a
rank-bm25index cached indata/bm25_index.pkl.
Airflow is not the chat server and should not run each user question. Use Airflow for durable, observable background workflows such as scheduled document ingestion, nightly re-indexing, rebuilding BM25, and knowledge-graph maintenance.
Apache Airflow does not natively support Windows. Use WSL2 or Docker Desktop.
Inside Ubuntu/WSL:
export AIRFLOW_HOME=~/airflow
airflow standaloneOpen: http://localhost:8080
Link this project's dags folder into $AIRFLOW_HOME/dags.
Useful learning commands:
airflow version
airflow dags list
airflow dags list-import-errors
airflow dags trigger document_ingestion_dagRun the test suite using pytest:
poetry run pytest tests -q