Sovereign AI Ecosystem

Building and Evaluating a Local-First Research Assistant with GraphRAG and [post] deterministic

Complete technical guide to building a production-ready research assistant

AIGraphRAGLocal LLMNeo4jOllamavero-evalResearch AssistantKnowledge GraphRAGAI Evaluationknowledge_systemsovereigntygraphrag

Building and Evaluating a Local-First Research Assistant with GraphRAG and vero-eval

*A comprehensive guide to creating a persona-driven AI assistant with rigorous evaluation using Neo4j, Ollama, and the vero-eval framework*

Introduction: Why Local GraphRAG Matters for Research Workflows

If you're building AI-powered applications in 2025, you've likely hit two major pain points: **context limitations** and **lack of systematic evaluation**. Large Language Models are powerful, but they struggle with long-term memory and consistent performance across edge cases. Enter GraphRAG—a methodology that combines knowledge graphs with retrieval-augmented generation to give your AI genuine memory and contextual awareness.

In this guide, we'll build a **Local Research Assistant** that: - Stores and retrieves research papers, notes, and conversations in a Neo4j knowledge graph - Uses Ollama for completely local inference (no API costs, full privacy) - Implements persona-driven responses that adapt based on RLHF feedback - **Most importantly**: Measures performance rigorously using the [vero-eval framework](https://github.com/vero-labs-ai/vero-eval)

This isn't another "hello world" tutorial. We're building production-ready infrastructure that you can deploy for real research workflows, with proper testing and evaluation baked in from day one.

Prerequisites and Starting Point

Before we dive in, you'll need:

**System Requirements:** - Python 3.9+ - Node.js 18+ - Docker (for Neo4j) - 16GB+ RAM recommended

**Core Technologies:** - [Ollama](https://ollama.ai) for local LLM inference - [Neo4j](https://neo4j.com) for graph database - [vero-eval](https://github.com/vero-labs-ai/vero-eval) for evaluation - Next.js + FastAPI (from the starter template)

**Clone the Starter Repository:**

bash git clone https://github.com/kliewerdaniel/chrisbot.git research-assistant cd research-assistant

This gives us a solid foundation with the frontend, basic chat interface, and project structure already in place. We'll extend it to build our research-focused GraphRAG system.

Part 1: Understanding the Architecture

Our Research Assistant follows the **PersonaGen architecture** pattern outlined by Daniel Kliewer, but applied to academic research workflows:

┌─────────────────────────────────────────────────────────┐ │ User Interface │ │ (Next.js Chat Interface) │ └────────────────────┬────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────┐ │ Reasoning Agent │ │ (Tool Calling + RLHF Threshold Logic) │ └────────────────────┬────────────────────────────────────┘ │ ┌──────────┴──────────┐ ▼ ▼ ┌──────────────────┐ ┌──────────────────┐ │ Neo4j Graph │ │ Ollama LLM │ │ RAG System │ │ (Mistral/Llama) │ │ │ │ │ │ • Papers │ │ • Generation │ │ • Authors │ │ • Embeddings │ │ • Concepts │ │ • Extraction │ │ • Citations │ │ │ └──────────────────┘ └──────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────┐ │ vero-eval Framework │ │ • Test Dataset Generation │ │ • Retrieval Metrics (Precision, Recall, MRR) │ │ • Generation Metrics (Faithfulness, BERTScore) │ │ • Persona Stress Testing │ └─────────────────────────────────────────────────────────┘

**Key Insight**: The persona system adapts its behavior based on evaluation feedback. If vero-eval shows poor retrieval for technical queries, the RLHF thresholds adjust to require more context before responding.

Part 2: Setting Up Neo4j GraphRAG

Neo4j is our memory layer. Following the [official Neo4j GenAI integration patterns](https://neo4j.com/docs/cypher-manual/current/genai-integrations/), we'll create a graph schema optimized for research.

Installing Neo4j GraphRAG for Python

```bash # Install the official Neo4j GraphRAG package pip install neo4j-graphrag

Install Ollama integration pip install "neo4j-graphrag[ollama]"

Start Neo4j (using Docker) docker run \ --name research-neo4j \ -p 7474:7474 -p 7687:7687 \ -e NEO4J_AUTH=neo4j/research2025 \ -v $PWD/neo4j-data:/data \ neo4j:latest ```

![Neo4j Knowledge Graph Setup for Research Assistant](/images/11152025/neo4j-knowledge-graph-setup.png)

Defining the Research Knowledge Schema

Create scripts/graph_schema.py:

```python from neo4j_graphrag import GraphSchema from dataclasses import dataclass

@dataclass class ResearchSchema(GraphSchema): """ Knowledge graph schema for research assistant. Nodes: - Paper: Research papers with metadata - Author: Paper authors with affiliation - Concept: Extracted key concepts/topics - Note: User's research notes - Question: User queries with context Relationships: - AUTHORED: Author -> Paper - CITES: Paper -> Paper - DISCUSSES: Paper -> Concept - RELATES_TO: Concept -> Concept - ANSWERS: Paper -> Question """ node_types = { 'Paper': { 'properties': ['title', 'abstract', 'year', 'doi', 'pdf_path'], 'embedding_property': 'abstract_embedding' }, 'Author': { 'properties': ['name', 'affiliation', 'h_index'], 'embedding_property': None }, 'Concept': { 'properties': ['name', 'definition', 'domain'], 'embedding_property': 'definition_embedding' }, 'Note': { 'properties': ['content', 'timestamp', 'tags'], 'embedding_property': 'content_embedding' }, 'Question': { 'properties': ['query', 'timestamp', 'answered'], 'embedding_property': 'query_embedding' } } relationship_types = { 'AUTHORED': ('Author', 'Paper'), 'CITES': ('Paper', 'Paper'), 'DISCUSSES': ('Paper', 'Concept'), 'RELATES_TO': ('Concept', 'Concept'), 'ANSWERS': ('Paper', 'Question'), 'ANNOTATES': ('Note', 'Paper') } ```

**Why this schema?** Research workflows have natural graph structures: - Papers cite each other (transitive relationships) - Concepts relate to multiple papers - Authors collaborate across papers - User notes connect to specific papers

This lets us traverse the graph to find: "What papers discussing transformer architectures were cited by papers on RAG systems after 2023?"

Building the Graph Ingestion Pipeline

Create scripts/ingest_research_data.py:

```python import ollama from neo4j import GraphDatabase from neo4j_graphrag import GraphRAG from pathlib import Path import PyPDF2

class ResearchGraphBuilder: def __init__(self, neo4j_uri="bolt://localhost:7687", neo4j_user="neo4j", neo4j_password="research2025", ollama_model="mistral"): self.driver = GraphDatabase.driver(neo4j_uri, auth=(neo4j_user, neo4j_password)) self.ollama_model = ollama_model self.graph_rag = GraphRAG(self.driver) def extract_paper_metadata(self, pdf_path: Path) -> dict: """Extract title, abstract, and key sections from PDF""" with open(pdf_path, 'rb') as file: reader = PyPDF2.PdfReader(file) # Extract first 3 pages (usually contains abstract) text = "" for page in reader.pages[:3]: text += page.extract_text() # Use Ollama to extract structured metadata prompt = f"""Extract from this researc

Sources

DanielKliewer.com blog · source

Related (3)

discusses GraphRAG conf=0.96
discusses Knowledge Systems conf=0.9
discusses Local-First / Sovereignty conf=0.6

← all Blog