Deep Agent
February 26, 2026 · View on GitHub
A Perplexity-style deep research platform combining Venice AI (LLM, web search, embeddings, vision) with a Neo4j knowledge graph, served via FastAPI and deployable to the Akash decentralized cloud.
Architecture Overview
graph TB
subgraph Clients
ST["Streamlit UI<br/>(streamlit_app.py)"]
FE["React Frontend<br/>(frontend/)"]
API_CLIENT["Any HTTP Client"]
end
subgraph "FastAPI Server (main.py :8123)"
HEALTH["/health"]
SEARCH["/search"]
RESEARCH["/research"]
INSIGHT["/insight"]
INSIGHT_CHAT["/insight/chat"]
INSIGHT_GRAPH["/insight/{case_id}/graph"]
COPILOTKIT["/copilotkit<br/>(AG-UI LangGraph)"]
end
subgraph "Agent Layer (agent.py)"
AGENT["LangGraph Agent<br/>ChatOpenAI + MemorySaver"]
DISPATCH["dispatch_mode_request"]
end
subgraph "Tool Layer (tools.py)"
WS["web_search_venice"]
DR["deep_research"]
DI["deep_insight"]
IC["insight_chat"]
SBC["search_and_build_corpus"]
QC["query_case"]
FER["find_entity_relationships"]
BCB["build_case_brief"]
AIV["analyze_image_venice"]
end
subgraph "Ingestion (ingestion.py)"
INGEST["DocumentIngestor"]
PDF["PDF extraction<br/>(PyMuPDF)"]
IMG["Image OCR<br/>(Venice Vision)"]
CHUNK["Text chunking"]
EMBED["Batch embedding"]
NER["Entity extraction<br/>(regex-based)"]
end
subgraph "Venice AI APIs"
V_CHAT["Chat Completions<br/>deepseek-v3.2"]
V_WEB["Web Search<br/>llama-3.3-70b<br/>:enable_web_search=on"]
V_EMBED["Embeddings<br/>text-embedding-3-large"]
V_VISION["Vision<br/>venice-v3-vision"]
end
subgraph "Neo4j Knowledge Graph"
N4J["Neo4j Driver"]
N_CASE["(:Case)"]
N_DOC["(:Document)"]
N_CHUNK["(:Chunk)<br/>+ vector index"]
N_ENTITY["(:Entity)"]
end
ST & FE & API_CLIENT -->|HTTP| SEARCH & RESEARCH & INSIGHT & INSIGHT_CHAT & INSIGHT_GRAPH & HEALTH
FE -->|AG-UI protocol| COPILOTKIT
COPILOTKIT --> AGENT --> DISPATCH
DISPATCH --> WS & DR & DI
SEARCH --> WS
RESEARCH --> DR
INSIGHT --> DI
INSIGHT_CHAT --> IC
INSIGHT_GRAPH --> N4J
WS --> V_WEB
DR --> V_WEB & V_CHAT
DI --> SBC --> WS
DI --> QC & FER
DI --> V_CHAT
IC --> QC & FER --> V_CHAT
BCB --> QC & FER --> V_CHAT
SBC --> INGEST
INGEST --> PDF & IMG & CHUNK & EMBED & NER
IMG --> V_VISION
EMBED --> V_EMBED
INGEST --> N4J
QC --> V_EMBED
QC --> N4J
FER --> N4J
N4J --> N_CASE -->|HAS_DOCUMENT| N_DOC -->|HAS_CHUNK| N_CHUNK
N_CHUNK -->|MENTIONS| N_ENTITY
N_ENTITY -->|RELATED_TO| N_ENTITY
Venice AI Integration
All AI capabilities are powered by the Venice AI OpenAI-compatible API (https://api.venice.ai/api/v1). No other LLM provider is used.
flowchart LR
subgraph "Venice API Endpoints Used"
direction TB
CHAT["POST /chat/completions"]
EMB["POST /embeddings"]
end
subgraph "Model Routing"
direction TB
M1["deepseek-v3.2<br/>— Agent reasoning<br/>— Report synthesis<br/>— JSON extraction"]
M2["llama-3.3-70b<br/>:enable_web_search=on<br/>&enable_web_citations=true<br/>— Real-time web search"]
M3["text-embedding-3-large<br/>— Chunk embeddings<br/>— Query embeddings"]
M4["venice-v3-vision<br/>— Image OCR<br/>— Document scanning"]
end
CHAT --> M1 & M2 & M4
EMB --> M3
Where each Venice model is called
| Venice Model | Env Var | Used In | Purpose |
|---|---|---|---|
deepseek-v3.2 | VENICE_MODEL | _venice_chat(), _venice_chat_json(), agent.py (ChatOpenAI) | LLM reasoning, report synthesis, query planning, entity analysis |
llama-3.3-70b | VENICE_WEBSEARCH_MODEL | _venice_web_search() | Real-time web search with citations (appends :enable_web_search=on&enable_web_citations=true to model name) |
text-embedding-3-large | VENICE_EMBED_MODEL | ingestion.py (_embed_text, _embed_texts) | Text chunk embeddings for Neo4j vector index |
venice-v3-vision | VENICE_VISION_MODEL | ingestion.py (_extract_text_from_image), analyze_image_venice tool | Image-to-text OCR via multimodal chat |
Agent Backend Flow
Mode Routing
The agent supports three investigation modes, each with a distinct pipeline:
flowchart TD
USER["User Query"] --> ROUTER{"Mode?"}
ROUTER -->|search| SEARCH_PIPE["web_search_venice"]
ROUTER -->|research| RESEARCH_PIPE["deep_research"]
ROUTER -->|insight| INSIGHT_PIPE["deep_insight"]
SEARCH_PIPE --> V_WEB["Venice Web Search<br/>llama-3.3-70b"]
V_WEB --> SEARCH_OUT["Search results<br/>+ citations"]
RESEARCH_PIPE --> PLAN["Plan search queries<br/>(Venice LLM)"]
PLAN --> PAR_SEARCH["Parallel web searches<br/>(ThreadPoolExecutor)"]
PAR_SEARCH --> SYNTH["Synthesize report<br/>(Venice LLM)"]
SYNTH --> RESEARCH_OUT["Research report<br/>+ timings + citations"]
INSIGHT_PIPE --> CORPUS_CHECK{"Corpus exists<br/>for case+topic?"}
CORPUS_CHECK -->|No| BUILD["search_and_build_corpus"]
CORPUS_CHECK -->|Yes| SKIP["Skip — reuse corpus"]
BUILD --> INGEST_FLOW["Web search → chunk →<br/>embed → NER → Neo4j"]
INGEST_FLOW --> QUERY_PHASE
SKIP --> QUERY_PHASE["query_case + find_entity_relationships<br/>(parallel)"]
QUERY_PHASE --> INSIGHT_SYNTH["Synthesize insight report<br/>(Venice LLM)"]
INSIGHT_SYNTH --> INSIGHT_OUT["Insight report + graph data<br/>+ entity summary"]
Deep Research Pipeline (web-only)
sequenceDiagram
participant Client
participant FastAPI as FastAPI /research
participant Planner as Venice LLM (planning)
participant WebSearch as Venice Web Search
participant Synth as Venice LLM (synthesis)
Client->>FastAPI: POST {case_id, topic, depth}
FastAPI->>Planner: Plan N search queries (depth → N)
Planner-->>FastAPI: ["query1", "query2", ...]
par Parallel web searches (ThreadPoolExecutor)
FastAPI->>WebSearch: Search query 1
FastAPI->>WebSearch: Search query 2
FastAPI->>WebSearch: Search query N
end
WebSearch-->>FastAPI: Raw web findings
FastAPI->>Synth: Synthesize findings into report
Synth-->>FastAPI: Research report
FastAPI-->>Client: {report, timings_ms, citations}
Deep Insight Pipeline (Graph-RAG)
sequenceDiagram
participant Client
participant FastAPI as FastAPI /insight
participant Neo4j
participant Venice as Venice APIs
participant Ingestor as DocumentIngestor
Client->>FastAPI: POST {case_id, topic, question, depth}
FastAPI->>Neo4j: check_corpus_exists(case_id, topic)
alt No existing corpus
FastAPI->>Venice: Plan & run web searches
Venice-->>FastAPI: Web search results
FastAPI->>Ingestor: chunk + embed + extract entities
Ingestor->>Venice: Batch embed (text-embedding-3-large)
Ingestor->>Neo4j: Bulk upsert chunks + entities
FastAPI->>Neo4j: auto_link_related_entities
end
par Parallel retrieval
FastAPI->>Venice: Embed question
Venice-->>FastAPI: Query vector
FastAPI->>Neo4j: query_similar_chunks (vector search)
FastAPI->>Neo4j: get_all_entity_relationships
end
Neo4j-->>FastAPI: Evidence chunks + relationships
FastAPI->>Venice: Synthesize insight report (deepseek-v3.2)
Venice-->>FastAPI: Insight report
FastAPI-->>Client: {insight_report, corpus_stats, entity_summary, timings_ms}
Neo4j Knowledge Graph Schema
graph LR
CASE["(:Case)<br/>case_id, topic, status"] -->|HAS_DOCUMENT| DOC["(:Document)<br/>doc_id, filename, source"]
DOC -->|HAS_CHUNK| CHUNK["(:Chunk)<br/>chunk_id, text, embedding<br/>(vector indexed)"]
CHUNK -->|MENTIONS| ENTITY["(:Entity)<br/>entity_id, type, value,<br/>normalized, confidence"]
ENTITY -->|RELATED_TO| ENTITY
style CHUNK fill:#4A90D9,color:#fff
style ENTITY fill:#E67E22,color:#fff
Entity types extracted: name, email, phone, org, money, date, url
Akash Deployment
The app is configured for deployment on the Akash Network decentralized cloud via akash.yaml (SDL v2.0).
flowchart TB
subgraph "Akash Network (Decentralized Cloud)"
subgraph "Container: python:3.11-slim"
APP["Streamlit App<br/>(:8501 → :80 global)"]
DATA["/app/data<br/>(persistent storage 10Gi)"]
end
COMPUTE["2 CPU / 4Gi RAM / 10Gi storage"]
end
subgraph "External Services"
VENICE["Venice AI API<br/>(via VENICE_API_KEY env)"]
NEO4J["Neo4j Instance<br/>(via NEO4J_URI env)"]
end
INTERNET["Internet"] -->|port 80| APP
APP --> VENICE
APP --> NEO4J
APP --> DATA
Akash SDL highlights (akash.yaml)
| Setting | Value |
|---|---|
| Base image | python:3.11-slim |
| Exposed port | 8501 → 80 (global) |
| CPU | 2 units |
| Memory | 4 Gi |
| Storage | 10 Gi (persistent mount at /app/data) |
| Pricing | 1000 uakt |
| Startup command | pip install uv && uv sync && uv run streamlit run app.py --server.port 8501 |
| Env vars needed | VENICE_API_KEY, NEO4J_URI, NEO4J_USER, NEO4J_PASSWORD |
Redis & Supabase — Akash Deployment
Redis and Supabase have been implemented as standalone modules ready to be wired into the platform when needed. They are deployed alongside the main application on the Akash decentralized cloud but are not connected to the live app yet — they exist as scaffolded services for upcoming features.
| Service | File | Akash Service | Status |
|---|---|---|---|
| Redis | redis_store.py | redis (container on Akash) | Implemented — not connected |
| Supabase | supabase_store.py | External service (env-configured) | Implemented — not connected |
Where Redis & Supabase Fit in the Architecture
graph TB
subgraph "Redis Service"
REDIS["Redis 7<br/>(:6379)<br/>🔒 not connected yet"]
REDIS_CACHE["Response Cache<br/>(TTL-based)"]
REDIS_PUBSUB["Pub/Sub<br/>(real-time events)"]
REDIS_SESSION["Session Store<br/>(user sessions)"]
end
end
subgraph "External Services"
VENICE["Venice AI API"]
NEO4J["Neo4j Knowledge Graph"]
SUPABASE["Supabase<br/>(Postgres + Auth + Storage)<br/>🔒 not connected yet"]
end
subgraph "Supabase Planned Usage"
SB_AUTH["Auth & User Management"]
SB_DB["Postgres — case metadata,<br/>user history, audit logs"]
SB_STORAGE["Object Storage —<br/>uploaded PDFs, images"]
SB_REALTIME["Realtime subscriptions"]
end
FASTAPI --> VENICE
FASTAPI --> NEO4J
FASTAPI -.->|"future: cache LLM responses<br/>& search results"| REDIS
REDIS --> REDIS_CACHE & REDIS_PUBSUB & REDIS_SESSION
REDIS_PUBSUB -.->|"future: push updates<br/>to Streamlit"| STREAMLIT_FUTURE
FASTAPI -.->|"future: auth, metadata,<br/>file storage"| SUPABASE
SUPABASE --> SB_AUTH & SB_DB & SB_STORAGE & SB_REALTIME
SB_REALTIME -.->|"future: live case<br/>notifications"| STREAMLIT_FUTURE
style REDIS fill:#D32F2F,color:#fff
style SUPABASE fill:#3ECF8E,color:#fff
style REDIS_CACHE fill:#EF9A9A,color:#000
style REDIS_PUBSUB fill:#EF9A9A,color:#000
style REDIS_SESSION fill:#EF9A9A,color:#000
style SB_AUTH fill:#A5D6A7,color:#000
style SB_DB fill:#A5D6A7,color:#000
style SB_STORAGE fill:#A5D6A7,color:#000
style SB_REALTIME fill:#A5D6A7,color:#000
Akash Deployment — Updated SDL (with Redis & Supabase)
The akash.yaml is configured to deploy both the main application and Redis as co-located services on Akash:
| Service | Image | Port | Resources | Purpose |
|---|---|---|---|---|
redaction-app | python:3.11-slim | 8501 → 80 | 2 CPU, 4Gi RAM, 10Gi disk | Main app (FastAPI + Streamlit) |
redis | redis:7-alpine | 6379 (internal) | 0.5 CPU, 512Mi RAM | Response cache, pub/sub, sessions |
| Supabase | External hosted | N/A | Managed | Auth, Postgres, Object Storage |
Environment variables (add to .env when connecting):
| Variable | Purpose |
|---|---|
REDIS_URL | Redis connection string (default: redis://localhost:6379/0) |
SUPABASE_URL | Supabase project URL |
SUPABASE_ANON_KEY | Supabase anonymous/public key |
SUPABASE_SERVICE_KEY | Supabase service-role key (server-side only) |
Project Structure
deep-agent/
├── agent/
│ ├── main.py # FastAPI server + all REST endpoints + AG-UI
│ ├── agent.py # LangGraph agent (ChatOpenAI + dispatch tool)
│ ├── tools.py # All research tools (search, research, insight, etc.)
│ ├── ingestion.py # PDF/image extraction, chunking, embedding, NER
│ ├── neo4j_store.py # Neo4j driver, schema, CRUD, vector search
│ └── pyproject.toml # Python dependencies
├── streamlit_app.py # Streamlit console (3-tab UI)
├── streamlit_app_future.py # Future Streamlit dashboard (placeholder, not connected)
├── redis_store_future.py # Redis integration scaffold (placeholder, not connected)
├── supabase_store_future.py # Supabase integration scaffold (placeholder, not connected)
├── spec.md # Implementation spec
└── README.md # This file
Environment
Set in agent/.env:
| Variable | Required | Default | Purpose |
|---|---|---|---|
VENICE_API_KEY | Yes | — | Venice AI authentication |
VENICE_BASE_URL | No | https://api.venice.ai/api/v1 | API base URL |
VENICE_MODEL | No | deepseek-v3.2 | LLM for reasoning/synthesis |
VENICE_WEBSEARCH_MODEL | No | llama-3.3-70b | Web search model |
VENICE_EMBED_MODEL | No | text-embedding-3-large | Embedding model |
VENICE_VISION_MODEL | No | venice-v3-vision | Vision/OCR model |
NEO4J_URI | Yes | — | Neo4j connection URI |
NEO4J_USERNAME | Yes | — | Neo4j username |
NEO4J_PASSWORD | Yes | — | Neo4j password |
NEO4J_DATABASE | No | neo4j | Database name |
Run
cd agent
uv venv && source .venv/bin/activate
uv pip install -e .
uv run python main.py
Server default: http://localhost:8123
Frontend (new shell):
cd ../frontend
npm install
npm run dev
Frontend default: http://127.0.0.1:5173
API Endpoints
| Method | Path | Description |
|---|---|---|
GET | /health | Health check |
POST | /search | Quick web search via Venice |
POST | /research | Deep research pipeline (web-only, depth-scaled) |
POST | /insight | Deep insight pipeline (Neo4j Graph-RAG) |
POST | /insight/chat | Fast follow-up against existing corpus |
GET | /insight/{case_id}/graph | Graph data for visualization |
POST | /copilotkit/agent/{agent_id}/run | AG-UI streaming run endpoint (CopilotKit useAgent) |
POST | /copilotkit/agent/{agent_id}/connect | AG-UI connect endpoint (SSE stream) |