Skip to content

About

Persistent-memory research AI agent with CAR, multi-memory architecture, advanced retrieval, MCP integrations, and continuous knowledge evolutio

Resources

Stars

1 star

Watchers

0 watching

Forks

Latest commit

Β 

History

8 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Research.ai β€” A Research Assistant


πŸš€ Running the Demo

Important

The live demo runs as a Streamlit app. Follow these steps to get it up in under a minute.

1. Clone & enter the repo

git clone <repo-url>
cd Global-AI-Hackathon-main

2. Create and activate a virtual environment

python3 -m venv venv
source venv/bin/activate

3. Install dependencies

pip install -r requirements.txt
pip install streamlit openai python-dotenv

4. Add your API key to .env

# .env (at project root)
GOOGLE_API_KEY="your-gemini-api-key-here"

5. Launch the demo

streamlit run demo/app.py

Open http://localhost:8501 in your browser.

5-Step Demo Flow

Step What to do What to observe
1 Type: "I'm researching Mem0's token efficiency, they achieve about 6.7K tokens per query" Right panel shows πŸ” Extracted + πŸ’Ύ Stored (serial 1)
2 Check the sidebar mem0_token_efficiency (serial 1) visible under All Stored Concepts
3 Click πŸ”„ Start New Session Chat clears, new session ID generated β€” SQLite untouched
4 Ask: "What was I researching about Mem0?" Agent recalls 6.7K from prior session; panel shows 🧠 Retrieved (Semantic β€” CAR Resolved)
5 Say: "Actually the number is 8K not 6.7K" then ask again Panel shows serial 2 stored; agent now answers 8K

The Problem

Every AI assistant today forgets you the moment the session ends. Ask it about a paper today, come back tomorrow, and you're re-explaining everything from scratch β€” what you've read, what you concluded, what contradicted what. For researchers juggling dozens of papers across weeks, this isn't a minor annoyance β€” it's the difference between an assistant that compounds your understanding over time and one that's permanently stuck at zero.

Generic "RAG + vector database" memory doesn't fix this. It retrieves similar text, not relevant truth β€” it can't tell you which of two contradicting papers is more current, it can't distinguish a one-off detail from a durable fact, and it blows through context budgets stuffing in everything that's vaguely related instead of what actually matters.

Synapse is a research-assistant agent that remembers like a researcher does β€” distinguishing what happened (episodic), what's true (semantic), how to behave (procedural), and what's relevant right now (working) β€” and gets measurably more accurate the more you use it.


What Makes This Different

Most memory-agent submissions in this category are a single vector store wrapped in a chat loop. Synapse instead implements:

  • Four distinct memory systems, each with its own storage shape, decay behavior, and retrieval logic β€” not one generic "memory blob"
  • Conflict-Aware Retrieval (CAR) β€” factual freshness is resolved with a deterministic max(serial) operation in plain Python, not an LLM guessing which fact is more current (which is where most memory agents silently hallucinate)
  • Query-time graph reasoning β€” episodic relationships are computed on demand from a single Postgres source of truth, avoiding the dual-write consistency bugs that plague systems maintaining a separate persistent graph store
  • A real context-window budget β€” retrieved memories are ranked, fused, and packed to fit a token budget, with graceful compression rather than silent truncation
  • Autonomous experience accumulation via MCP β€” the agent doesn't just wait to be told things; it can search arXiv, fetch papers, and re-verify its own stale beliefs against fresh sources
  • Benchmarked, not just demoed β€” evaluated against a LoCoMo/LongMemEval subset with real Recall@k and token-cost numbers, not just a scripted "look, it remembered!" moment

Architecture

                     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                     β”‚        User Query            β”‚
                     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                    β–Ό
                     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                     β”‚      Query Router             β”‚  ← does this need memory at all?
                     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                    β–Ό
                     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                     β”‚  Coreference Resolver         β”‚  ← resolves "that", "it" via working memory
                     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                    β–Ό
              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
              β–Ό                                            β–Ό
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚  Semantic Retrieval   β”‚                      β”‚  Episodic Retrieval  β”‚
   β”‚  (Postgres + pgvector β”‚                      β”‚  (Postgres graph +   β”‚
   β”‚   + CAR resolver)     β”‚                      β”‚   NetworkX traversal)β”‚
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                    β–Ό
                     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                     β”‚       Fusion & Ranking         β”‚
                     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                    β–Ό
                     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                     β”‚     Context Packer             β”‚  ← fits ranked results into token budget
                     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                    β–Ό
                     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                     β”‚  Working Memory (assembled)   β”‚  ← + procedural skills + persona
                     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                    β–Ό
                     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                     β”‚   Qwen Response Generation    β”‚  ← + MCP tools (arXiv, web search)
                     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                    β–Ό
                     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                     β”‚   Extraction (query + reply)  β”‚
                     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                    β–Ό
                     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                     β”‚        Write-Back              β”‚  ← routes to semantic/episodic/procedural
                     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Orchestrated as a LangGraph state graph β€” conditional edges, not a monolithic ReAct loop β€” so control flow is deterministic, inspectable, and independently testable node by node.


The Four Memory Systems

Type What it holds Storage Lifecycle
Working Active context: persona rules, current plan, retrieved facts for this turn In-memory blocks, session-scoped (LangGraph checkpointer) Overwritten every turn
Episodic Specific events β€” "read paper X on date Y" Postgres (rows), traversed via query-time NetworkX subgraphs Decays by activation weight, consolidated over time
Semantic Durable facts and preferences β€” "Mem0 achieves ~6.7K tokens/query" Postgres + pgvector, resolved via CAR (max(serial)) Never overwritten β€” new evidence appends a new row; freshest always wins at read time
Procedural How to behave β€” "always cite the source paper when comparing benchmarks" Flat file registry (SKILL.md, YAML frontmatter) Static, human-curated

Why Conflict-Aware Retrieval (CAR) instead of LLM-judged conflict resolution

Standard memory agents ask the LLM "which of these facts is correct?" β€” but LLMs exhibit a documented failure mode called prior-override, defaulting to their pretrained knowledge over the context you actually gave them. CAR sidesteps this entirely: every new fact for a given concept gets the next monotonic serial number on write. At read time, resolution is one line of deterministic Python β€” max(rows, key=lambda r: r["serial"]) β€” no LLM judgment, no hallucination risk, no prior-override possible.

Why a single Postgres instance instead of a dedicated graph database

Rather than maintaining a separately-persisted graph engine (introducing a second source of truth to keep in sync), Synapse stores all episodic events and relationships as rows in Postgres and treats graph traversal as a stateless, query-time computation: pull the relevant subgraph out of Postgres, load it into a throwaway NetworkX object, run spreading-activation traversal, discard it. This eliminates cross-system consistency risk entirely while still enabling associative recall β€” e.g., surfacing a schedule-conflict memory in response to a query about anxiety, even when the two never share literal text.


Retrieval Pipeline

  1. Query Router β€” classifies whether the query needs memory at all, and which stores are relevant, before spending any retrieval cost
  2. Coreference Resolver β€” de-references ambiguous queries ("what's the formula for that?") using recent working-memory context before retrieval runs
  3. Fan-out retrieval β€” semantic and episodic stores are queried in parallel, each wrapped in error handling so one store's failure doesn't take down the other
  4. Fusion β€” merges semantic confidence scores and episodic graph-proximity weights into a single ranked list
  5. Context Packer β€” greedily fills the token budget with top-ranked results, compressing or summarizing the long tail instead of silently dropping it
  6. Explicit no-context fallback β€” if nothing relevant is found, the agent says so honestly instead of letting the LLM fabricate a plausible-sounding memory

Autonomous Tools (MCP)

  • arXiv search β€” pulls in new papers relevant to the conversation, feeding them directly into the extraction pipeline as if they were conversation turns
  • Paper fetch β€” retrieves full text/abstracts to verify a claim when a contradiction is flagged
  • Staleness verification β€” before answering with an old or preprint-sourced fact, autonomously re-checks it against fresh search results and flags contradictions
  • Citation graph β€” grounds episodic graph edges in real citation relationships rather than inferred concept overlap alone

Benchmarks

Evaluated against a subset of the LoCoMo / LongMemEval public benchmarks:

Metric Result
Recall@5 [fill in after running benchmarks/run_locomo_subset.py]
Mean tokens/query [fill in]
Mean latency [fill in]

(Full methodology and raw output in benchmarks/results.json)


Tech Stack

  • LLM & orchestration: Qwen Cloud (extraction, memory-op decisions, response generation, consolidation) via LangGraph state graph
  • Storage: PostgreSQL + pgvector (unified episodic + semantic store)
  • Graph computation: NetworkX (stateless, query-time traversal)
  • Keyword retrieval: BM25
  • Tool integration: Model Context Protocol (MCP) β€” arXiv, web search, citation graph
  • Serving: FastAPI
  • Demo UI: Streamlit β€” live chat + real-time memory panel (what was stored, retrieved, forgotten, and token cost per turn)

Repository Structure

See ARCHITECTURE.md for the full module breakdown and design rationale.

src/
β”œβ”€β”€ clients/       # Qwen Cloud API wrapper
β”œβ”€β”€ tools/         # MCP registry, tool schemas, executor
β”œβ”€β”€ checkpoint/    # Session/thread state (LangGraph)
β”œβ”€β”€ extraction/    # Raw text β†’ structured candidate facts
β”œβ”€β”€ memory/        # Working, episodic, semantic, procedural stores
β”œβ”€β”€ ops/           # Memory-op routing, conflict/contradiction detection, decay
β”œβ”€β”€ retrieval/     # Router, coreference resolver, fusion, context packer
β”œβ”€β”€ consolidation/ # Episodic β†’ semantic distillation
└── generation/    # Final response assembly

Roadmap / Beyond the Hackathon

  • Package the memory subsystem as a standalone SDK usable by any LLM agent, not just this one
  • Expand procedural memory from static skill files to feedback-driven behavioral weighting
  • Multi-user shared knowledge graphs for lab/team research settings
  • Fine-grained confidence decay tied to citation counts and retraction tracking

Team

Name Role
Roaim Khan Lead Developer β€” Memory Architecture & LangGraph Orchestration
Muhammad Ahmed Qasim AI Systems Engineer β€” Retrieval Pipeline, CAR Conflict Resolution & Evaluation

About

Persistent-memory research AI agent with CAR, multi-memory architecture, advanced retrieval, MCP integrations, and continuous knowledge evolutio

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages