DEV Community

Cover image for How I built an AI-enabled GitHub discovery tool
adospace
adospace

Posted on

How I built an AI-enabled GitHub discovery tool

I am always in search of great GitHub repositories.

I'm interested in learning new frameworks or tools, discovering niche but well-maintained projects, etc., but I'm also in a strange relationship with "GitHub trending lists", or "Top 10 trending repos in 2026" articles.
Really do not help to know that that specific repo is skyrocketing stars metric, if it's dealing with an issue I don't have or using a tool/framework not on my radar.

What if I just want to get a look at a production-ready project that could be useful for my work? Or learn a new language starting from a GitHub tutorial repo?

Here's the deal:
1) Take an AI agent powered by Claude.
2) Provide him a prompt, specific to my interests, like "search and carefully select a few GH repositories that deal with Rust, native desktop development, not a webview/web wrapper, that are well-maintained".
3) Run the agent time to time and let him pack a weekly delivered list of 3-5 repo links, with a short description, what is good, and what is less.

I took the challenge using things I already know well, the .NET stack, the newly Anthropic SDK for c#, deliver on Azure, but not an App Service, or full-blown AKS, something that can run scheduled, serverless, cheap, yes, Azure Functions. For the web page to let users register their email and provide their interests in natural language, nothing better than an Azure static web page, no stack, just plain HTML+JS (yes was ugly, initially). SQL Server to save the user emails, mailing list, etc.

With Claude's help, I got a working version (locally) in half a day.

Now the tricky parts, I tried to run the web app (func start and swa start), the Claude API usage was really high! nothing that I could realistically put in production.

Soon, I discovered that the Anthropic cache wasn't enabled. But even after enabling it, generating a single email would have cost almost 1$ (using Sonnet), far too high anyway.

   ┌──────┐
   │ User │  "Find me Rust desktop repos"
   └──┬───┘
      │
      ▼
   ┌────────────────────────────────────────┐
   │              CLAUDE                    │
   │  search GitHub  →  read each repo  →   │
   │  judge  →  write the email             │
   └─────────────────┬──────────────────────┘
                     │
                     ▼
              ┌─────────────┐
              │    Email    │   ~$1 per user
              └─────────────┘
Enter fullscreen mode Exit fullscreen mode

I tracked down the number of tokens spent to read/explore a single repo (using Octokit), and it was huge. But I thought, what if 2 or more users have similar interests? A repository explored for one user could have been of some interest for others, too.
Why not create a cache of already explored repositories?
So I created the table with all the useful info just discovered by the AI, and anytime it had to find repos for a user, it first had to look at the summarized versions.

                       ┌──────────────────┐
                       │    Repo Cache    │
                       │  summary, 👍,👎 │
                       └────────▲─────────┘
                                │  tool calls
                                │  (query, read, decide)
   ┌──────┐          ┌──────────┴────────┐          ┌───────┐
   │ User │────────> │      CLAUDE       │────────> │ Email │
   └──────┘          └──────────┬────────┘          └───────┘
                                │  if cache thin
                                ▼
                       ┌──────────────────┐
                       │  GitHub  +  LLM  │
                       │   evaluation     │
                       │  (writes cache)  │
                       └──────────────────┘
Enter fullscreen mode Exit fullscreen mode

AI costs have gotten better, but still too high. The real problem was that Claude had to navigate the cache itself, making incremental queries to find the interesting repositories, read the query result, and then take those info in count to decide whether to move the exploration to GitHub or step over. Every round trip was tokens.

I was using Claude for the wrong job — searching the cache, when I should have only used it for judging. So I moved the search out of the loop. The idea was to convert the user interests into a vector of doubles (embedding), expressing the semantic meaning of the request, and store the same for the cached repositories, including the summary, strength, and weaknesses project, etc. Then a single SQL query orders the cache by cosine distance to the user vector, takes the top 15 closest, and those go straight into Claude's first message — Claude picks from there, and only falls back to GitHub search if nothing fits. In other words was an engineering process, not a speculative one.

I soon discovered that PostgreSQL (not SQL Server) has semantic search built in (through a plugin).

For the embedding part I used Voyage AI (voyage-3 model) — text in, vector out. The vectors live in Postgres with the pgvector extension, with an HNSW index on the repo embeddings — cosine distance, single SQL query.

   ┌──────┐
   │ User │  interests in plain English
   └──┬───┘
      │
      ▼
   ┌──────────────┐
   │  Voyage AI   │   text  →  vector(1024)
   └──────┬───────┘
          │
          ▼
   ┌────────────────────┐         ┌────────────────────┐
   │     pgvector       │<────────│     Repo Cache     │
   │  cosine, top 15    │         │  (with embeddings) │
   └──────┬─────────────┘         └────────────────────┘
          │  shortlist
          ▼
   ┌──────────────┐
   │    CLAUDE    │   picks 3–5 + GitHub
   │   (judging)  │   writes email
   └──────┬───────┘
          │
          ▼
     ┌──────────────────────┐
     │  Email  (~10–20¢)    │
     └──────────────────────┘
Enter fullscreen mode Exit fullscreen mode

After the change, things got dramatically better; the AI cost per email dropped to 10/20 cents, making the whole process at least sustainable.

This is the website, subscribe and let me know if it's useful for you too:
https://finds.dev

Ado
https://github.com/adospace

Top comments (0)