DEV Community

PRABHU-OFFICIAL-II
PRABHU-OFFICIAL-II

Posted on

How I Built an AI Agent That Uses a Graph Database as Its Memory

Finding good open source issues to contribute to is harder than it looks.

You search "good first issue" on GitHub. You get 50,000 results. Most are stale. Half are in languages you don't use. The ones that look good have maintainers who haven't responded to a PR in eight months. And tomorrow, you'll search again and see the exact same ones you already skipped.

The real problem isn't discovery. It's memory and context.

That's what I built ContriGraph to solve.


The Idea

Most recommendation tools treat developer-issue matching as a search problem. I wanted to treat it as a graph problem.

A developer has skills. Skills connect to issues. Issues belong to repositories. Repositories have maintainers. Maintainers have response patterns. Developers follow other developers who've contributed to repos. All of this is a graph — and graphs are exactly what FalkorDB is built for.

ContriGraph is an AI agent that traverses this graph to find the right issue for you — and remembers every interaction by writing it back to the graph as a typed edge.


The Architecture

Browser (React + Vite)
    │  SSE stream
    ▼
FastAPI Backend
    │
    ├── Claude AI Agent (tool-use loop)
    │       └── find_matching_issues → FalkorDB Cypher
    │
    ├── FalkorDB (graph store)
    │
    └── GitHub API (ingestion + dynamic search)
Enter fullscreen mode Exit fullscreen mode

When you type a query, the message goes to a FastAPI streaming endpoint. A Claude agent decides which tool to call. The tool executes a Cypher query against FalkorDB. The result streams back to the browser via server-sent events.

Simple loop. Fast graph.


The Graph Schema

(Developer)-[:HAS_SKILL]->(Skill)
(Developer)-[:CONTRIBUTED_TO]->(Repository)
(Developer)-[:FOLLOWS]->(Developer)
(Developer)-[:VIEWED|BOOKMARKED|SKIPPED|APPLIED_TO]->(Issue)

(Repository)-[:HAS_ISSUE]->(Issue)
(Repository)-[:MAINTAINED_BY]->(Maintainer)
(Repository)-[:REQUIRES_SKILL]->(Skill)

(Issue)-[:NEEDS_SKILL]->(Skill)
Enter fullscreen mode Exit fullscreen mode

Every node type has a purpose. Every relationship type carries meaning. The agent doesn't query a table — it traverses a graph.


The Core Query — 4 Hops in One Shot

This is the Cypher query that powers every issue recommendation:

MATCH (d:Developer {username: $username})-[:HAS_SKILL]->(s:Skill)
      <-[:NEEDS_SKILL]-(i:Issue)
      <-[:HAS_ISSUE]-(r:Repository)
      -[:MAINTAINED_BY]->(m:Maintainer)
WHERE m.avg_response_days <= $max_response_days
  AND NOT (d)-[:SKIPPED]->(i)
  AND NOT (d)-[:APPLIED_TO]->(i)
OPTIONAL MATCH (friend:Developer)-[:FOLLOWS]-(d)-[:FOLLOWS]-(friend),
               (friend)-[:CONTRIBUTED_TO]->(r)
WITH i, r, m, count(DISTINCT friend) AS friend_contributors
RETURN i.title, i.url, i.complexity, r.full_name,
       m.avg_response_days,
       (friend_contributors * 10) AS social_score
ORDER BY social_score DESC, m.avg_response_days ASC
LIMIT 10
Enter fullscreen mode Exit fullscreen mode

Four hops. One query. Under 1ms in FalkorDB.

The NOT (d)-[:SKIPPED]->(i) and NOT (d)-[:APPLIED_TO]->(i) clauses are doing the agent memory work — filtering at the database level, not in Python. The social proximity score is calculated by counting FOLLOWS and CONTRIBUTED_TO path intersections in the same query.

This would be four separate SQL joins, a vector similarity lookup, and a Python post-processing step. In FalkorDB it's one traversal.


Agent Memory — Every Action Is a Graph Edge

This is the part I'm most proud of.

When the agent surfaces an issue, it immediately writes a VIEWED edge to FalkorDB:

MATCH (d:Developer {username: $username}), (i:Issue {issue_id: $issue_id})
CREATE (d)-[:VIEWED {timestamp: $ts, session_id: $session}]->(i)
Enter fullscreen mode Exit fullscreen mode

When you click Bookmark, Skip, or Apply on a card:

CREATE (d)-[:BOOKMARKED {timestamp: $ts, session_id: $session}]->(i)
Enter fullscreen mode Exit fullscreen mode

That's it. A typed relationship with properties. No separate actions table. No Redis cache. No session state.

The next time you query, the Cypher traversal hits those NOT clauses and skipped issues are gone — permanently, across every session, forever. Not because the app remembers. Because the graph remembers.

This is what I mean when I say the graph is the memory layer.


Dynamic Ingestion — The Graph That Grows

The first time you ask for Go issues, there might be no Go repos in the graph. Here's what happens:

  1. find_matching_issues(skill='go') returns 0 results
  2. The agent calls GitHub Search API for top Go repositories
  3. Ingests their issues into FalkorDB via CREATE statements
  4. Creates the HAS_SKILL edge: (developer)-[:HAS_SKILL]->(go_skill)
  5. Retries the Cypher traversal — now it finds matches

The graph grows on demand. Every new query makes it smarter for the next one.


What I Learned

Graph databases change how you think about data. I started this project thinking about tables and foreign keys. By the end, I was thinking in nodes and relationships. The moment you model your data as a graph, queries that would need multiple joins become single traversals.

Agent memory is just graph edges. I spent too long thinking about how to persist agent state — Redis? Postgres? A separate memory service? The answer was already in front of me. FalkorDB was already storing the data. I just needed to write the right edges back to it.

FalkorDB is fast. The 4-hop traversal across 180 nodes and 362 edges runs in under 1ms. I expected to need indexes and tuning. I didn't. The graph query engine handles it.

The graph is the UI. The live graph canvas that updates as the agent works isn't a gimmick — it's showing you exactly what's happening in FalkorDB in real time. New nodes and edges appearing as the agent ingests and traverses. That's the actual data model made visible.


What's Next

  • Deployment to FalkorDB Cloud + Railway
  • Collaborative graphs — share skill profiles with a team and find issues you can work on together
  • Maintainer scoring based on PR merge rate, not just response time
  • Multi-developer traversal: "find issues where two people on my team have complementary skills"

Demo Video


Try It Yourself

GitHub: https://github.com/PRABHU-OFFICIAL-II/contrigraph

Built for Graph Hacks 2026 by WeMakeDevs + FalkorDB.

If you've ever stared at GitHub's issue tracker wondering where to start — this was built for you.


Built with FalkorDB, FastAPI, Claude AI, React, and the GitHub API.

Top comments (0)