Wenwei Lin

← All projects

University

Bookworm

I wanted to see how books connect to one another: log quotes and thoughts, let books, authors and notes form a web, and ask questions of your own notes. My undergraduate graduation project.

When
2024.01 – 2024.06
Context
Graduation project, Jiangsu University of Technology
My role
Built it alone: product design, full-stack development and the thesis
Result
Outstanding Graduation Project
Built with
Next.js · Neo4j · Qdrant · RAG · Azure OpenAI · Sigma.js · Tailwind CSS · shadcn/ui

The thesis was titled Design and Implementation of an Intelligent Reading Notes System Based on Large Language Models and Neo4j, supervised by Professor You Congzhe. In the app itself it was called 书虫, “bookworm”.

Bookworm’s library: navigation on the left and a wall of book covers; on the right, the same page on a phone

The library page on desktop and on a phone.

Why

In my gap year I started reading a lot: fiction, philosophy, psychology. I used Readwise for notes, but I read paper books, so every quote and thought had to be typed in by hand on its website.

I wanted to use their open API to build a little mobile page so I could jot notes anytime… Then I thought, all that effort just to hook into Readwise seems a waste. Why not make it bigger and better, and turn it into my graduation project!

At my defence I summed up the problem in two lines: notes always end up gathering dust; and books are connected in intricate ways that you can’t see.

Who it’s for

Readers like me:

  • who take notes to understand books better;
  • some read on paper, some on screens, and both need to work;
  • who read translated books, so a book needs room for its translator and original title.

I started from my own habits: record a book’s details (title, author, ISBN), record notes (quotes plus thoughts), tag the notes. And the one thing I wanted most:

I want to see how notes relate to each other. That’s the core value of my app: seeing how one book connects to another.

For the thesis I also compared note apps like Notion, Obsidian and flomo, and Niklas Luhmann’s slip-box method.

Use case diagram: users manage books, authors and publishers, write and tag notes, use the assistant and view statistics

The use case diagram from the thesis.

Design

The whole flow is a loop: add a book → take notes → dig through them with the assistant → look at statistics and the relationship graph.

  • Adding books: scan an ISBN and the book’s details are pulled from Douban; publishers, authors and translators can be set up first and then picked.
  • Notes: quotes and thoughts kept separate, with tags.
  • Relationship graph: books, authors and tags are nodes and their relationships are edges, laid out automatically with a force-directed layout (ForceAtlas2). There’s also a tag word cloud.
  • Assistant: ask “what have I noted about this topic?”, and it finds the relevant notes and turns them into an answer.
  • Mobile first: designed for a phone screen first, switching to a desktop layout at 768px.

Home: counts of notes, tags, books, authors and publishers, and how many notes were written each day recently

Home: how many notes and tags, and which days I wrote the most.

A corner of the relationship graph: Pride and Prejudice, The Picture of Dorian Gray and Homo Ludens connected through tags like “reason”, “sensibility” and “love”

A corner of the graph: Pride and Prejudice and The Picture of Dorian Gray connected through tags like “reason” and “sensibility”.

Tech choices and trade-offs

A graph database. I first heard of graph databases at Global Azure 2023 and thought they were “so cool”: books and authors, books and notes, notes and tags are naturally a graph. When I got to the visualisation, I realised:

You don’t need a graph database to draw a graph. Visualisation is a front-end thing; you just need to give the front end the data structure it wants. A graph database only speeds up queries in this kind of scenario (and my data was far too small to show any advantage).

Asking your own notes (RAG). Notes tend to gather dust, and putting thoughts into words is hard work. Notes are split into small pieces and stored in a vector database (Qdrant). A question first retrieves the most relevant notes, which are then handed to the model, so it answers “from your notes” and makes less up.

The Q&A flow: notes are embedded and stored; a question retrieves relevant notes, which go into the prompt for the model to answer

The assistant: asked “What is refactoring?”, the answer lists the related notes, and opening one shows the original quote and my thoughts

Ask “What is refactoring?”, and the answer lists the notes it used; open one to see the quote and what I thought.

Server Components. At my internship I’d only written React client components, so this time I tried Next.js server components: the component itself is async and fetches its own data, no useEffect needed.

Sign-in. I had planned a separate back-end API, “but I couldn’t figure out the authentication part, so I gave up”, and used Clerk. “Authentication wasn’t the most important thing, the other features were, so that was the trade-off.”

While building it I found a problem in a shadcn-style tag component I was using and sent it a PR.

Architecture: a Next.js full-stack app connected to a Neo4j graph database, a Qdrant vector database, a language model, and a Douban lookup API on Azure Functions

The architecture: one Next.js full-stack app, connected to a graph database, a vector database and a model; the ISBN-to-Douban lookup is deployed separately as a serverless function.

Testing

I stored 100 reading notes and wrote two kinds of questions, 34 each: ones answered in the notes, and ones the notes don’t cover, which need reasoning or general knowledge.

Answer in the notes Not in the notes
GPT-3.5 Turbo 74% 79%
Kimi Chat 79% 85%
GPT-4 Turbo 82% 85%
Bookworm 91% 56%

When the answer is in the notes, Bookworm is the most accurate; when it isn’t, you’re better off asking the model directly.

Looking back

It was rated an outstanding graduation project. The weakness the thesis names is that I used the most basic form of RAG, so retrieved notes sometimes don’t match the question; there’s room to move to more advanced approaches.

I poured a lot into it. It used nearly everything I’d learned at university, plus my ability to teach myself.

That year I interned during the day and worked on it at night and on weekends, and in the last month I took several days off to write the thesis at home.