How alaap-nair/adobe-deep-research works
Purpose and Top-Level Shape
This repository compares two Biology Expert KG-RAG implementations for answering OpenStax Biology questions with lightweight LLMs rather than web search. Both implement ingestion, relation extraction, knowledge-graph construction, hybrid retrieval, grounded synthesis, and RAGAS-based evaluation, but are independently runnable subprojects:
• Unified Neo4j design: team_a/src/run_all.py, team_a/ask.py
• Dual-store Neo4j + Qdrant design: team_b/src/run_all.py, team_b/ask.py
• Separate personalized Graphiti demonstration: demo/backend/server.py, demo/web/app/page.tsx
Team A: Unified Neo4j Pipeline
Team A keeps graph entities/relations, source chunks, and vector embeddings in Neo4j, minimizing storage-service boundaries. The principal batch entry point orchestrates parsing, chunking, extraction, embeddings, and graph persistence; the CLI query surface answers a user question against that unified store.
• Pipeline orchestration: team_a/src/run_all.py
• KG construction and Neo4j access: team_a/src/build_graph.py, team_a/src/neo4j_engine.py
• Query/answer interfaces: team_a/ask.py, team_a/bio_qa.py
Its extraction boundary converts source text into schema-constrained entities and triples before Neo4j writes: team_a/src/extract_entitites.py, team_a/src/extract_triples.py, team_a/src/schema.py.
Team B: Decoupled KG-RAG Pipeline
Team B separates structural and semantic retrieval: Neo4j holds the canonicalized graph, while Qdrant indexes chunks/evidence vectors using shared deterministic IDs. Its main entry point runs corpus processing; its query engine combines vector candidates, graph traversal/context, optional reranking, and LLM synthesis.
• Pipeline orchestration: team_b/src/run_all.py
• Graph and vector-store builders: team_b/src/build_graph.py, team_b/src/build_vectorstore.py
• Hybrid query path: team_b/src/query_engine.py, team_b/src/qa_client.py
• Retrieval-quality stage: team_b/src/reranker.py
Canonicalization, graph schema, and domain constraints are explicit architectural controls that reduce duplicate entities and constrain relationship meaning: team_b/src/canonicalize.py, team_b/src/graph_schema.py, team_b/src/domain_schema.py.
Ingestion and Knowledge Artifacts
The shared domain is sourced from OpenStax-derived biology text and PDFs, covering photosynthesis, genetics, and fungi. Parsing/chunking creates retrievable source units; LLM extraction produces triples; these become graph and vector records. Generated triples, answers, traces, checkpoints, and coverage results are persisted as inspectable offline artifacts.
• Team A parsing/chunking: team_a/src/parse_pdf.py, team_a/src/chunking.py
• Team B parsing/chunking/extraction: team_b/src/parse_pdf.py, team_b/src/chunking.py, team_b/src/extract_triples.py
• Corpus and evaluation truth: team_b/data/ground_truth.curated.json, data/ground_truth.json
• Existing Qdrant local data: qdrant_data/collection/chunks/storage.sqlite
Query, Evaluation, and Output Flow
At serving time, a question enters ask.py or the Team B Streamlit UI, is embedded/retrieved against graph and/or vector stores, assembled into grounded context, then sent to a configured QA model. Answers and retrieval traces are saved as JSON, enabling comparison across model configurations. Evaluation uses ground truth and RAGAS, while coverage checks assess graph completeness.
• Team B UI/API-facing path: team_b/app.py, team_b/src/ui_backend.py
• Evaluation stages: team_b/src/evaluate.py, team_b/src/run_ragas.py, team_b/src/check_coverage.py
• Representative answer/trace artifacts: team_b/outputs/model_runs/mistral_rerank/, outputs/answers/
Runtimes and External Services
Python is the primary runtime; LLM access is configured through OpenRouter credentials and model names. Neo4j is required by both architectures. Team B additionally runs Qdrant via Docker Compose. Team B’s interactive UI uses Streamlit.
• Service definition: team_b/docker-compose.yml
• Environment contract: .env.example
• Dependency boundaries: team_a/requirements.txt, team_b/requirements.txt
• Neo4j-only Graphiti demo backend: demo/backend/graphiti_setup.py, demo/backend/seed_maya.py
Personalized Graphiti Demo
The demo/ subsystem is a distinct full-stack visualization of personalized graph memory, not the primary Team A/B benchmark pipeline. A Python API exposes seeded Graphiti state and snapshots; a Next.js frontend renders graph entities, episodes, and answer comparisons.
• Backend server and snapshot API: demo/backend/server.py, demo/backend/snapshot.py
• Frontend application and graph visualization: demo/web/app/page.tsx, demo/web/components/GraphCanvas.tsx
• Frontend-to-backend boundary: demo/web/lib/api.ts, demo/web/lib/types.ts
Components 20
Team A · Unified Neo4j
Single-store KG-RAG implementation.
- Batch pipeline · Runs parsing through graph persistence.
team_a/src/run_all.py - Schema-constrained extraction · Converts chunks to validated entities and relations.
team_a/src/extract_triples.py - Unified graph builder · Stores graph, chunks, and embeddings together.
team_a/src/build_graph.py - CLI question answering · Retrieves from the unified Neo4j store and answers questions.
team_a/ask.py
Team B · Hybrid KG-RAG
Neo4j graph plus Qdrant evidence retrieval.
- Corpus pipeline · Runs graph and vector-store construction.
team_b/src/run_all.py - Canonicalization and schema · Reduces duplicate entities and constrains relation meaning.
team_b/src/canonicalize.py - Graph builder · Builds the canonicalized structural knowledge graph.
team_b/src/build_graph.py - Vector-store builder · Indexes chunks and evidence with shared deterministic IDs.
team_b/src/build_vectorstore.py - Qdrant · Semantic evidence and chunk index.
qdrant_data/collection/chunks/storage.sqlite - Streamlit UI · User-facing Team B question entry point.
team_b/app.py - Hybrid query engine · Combines vector candidates, graph context, reranking, and QA.
team_b/src/query_engine.py - Reranker
team_b/src/reranker.py - RAGAS and coverage evaluation · Scores answer quality and graph completeness against ground truth.
team_b/src/run_ragas.py - Curated ground truth
team_b/data/ground_truth.curated.json - Answers and traces · Inspectable model answers, retrieval traces, and run outputs.
Personalized Graphiti Demo
Separate graph-memory visualization application.
- Graphiti snapshot API · Exposes seeded personalized graph state and answer snapshots.
demo/backend/server.py - Next.js graph viewer · Renders entities, episodes, and answer comparisons.
demo/web/app/page.tsx
Other components
- OpenStax biology corpus · Biology PDFs and text supply both benchmark pipelines.
- OpenRouter LLMs · Configured models extract relations and synthesize answers.
.env.example - Neo4j · Required graph store for both designs and the demo.
Connections 23
- OpenStax biology corpus → Batch pipeline: parse and chunk
- Batch pipeline → Schema-constrained extraction: source units
- Schema-constrained extraction → Unified graph builder: entities and triples
- Unified graph builder → Neo4j: graph, chunks, embeddings
- CLI question answering → Neo4j: retrieve grounded context
- OpenRouter LLMs → Schema-constrained extraction: extract
- OpenRouter LLMs → CLI question answering: synthesize
- OpenStax biology corpus → Corpus pipeline: parse and chunk
- Corpus pipeline → Canonicalization and schema: extracted candidates
- Canonicalization and schema → Graph builder: canonical triples
- Canonicalization and schema → Vector-store builder: shared IDs and evidence
- Graph builder → Neo4j: canonical graph
- Vector-store builder → Qdrant: chunk vectors
- Streamlit UI → Hybrid query engine: question
- Hybrid query engine → Qdrant: vector candidates
- Hybrid query engine → Neo4j: graph traversal
- Hybrid query engine → Reranker: rank evidence
- Reranker → OpenRouter LLMs: grounded prompt
- Hybrid query engine → Answers and traces: answers and traces
- Curated ground truth → RAGAS and coverage evaluation: reference answers
- Answers and traces → RAGAS and coverage evaluation: model outputs
- Graphiti snapshot API → Neo4j: Graphiti graph state
- Next.js graph viewer → Graphiti snapshot API: snapshots and comparisons