How the algorithm works: it finds people who liked the same posts as you, and shows you what else they’ve liked recently.
Launched the feed a little over a year ago and it has become the most liked feed.
395 karma · joined January 9, 2021
Email is "lonk" at the above domain.
How the algorithm works: it finds people who liked the same posts as you, and shows you what else they’ve liked recently.
Launched the feed a little over a year ago and it has become the most liked feed.
The For You one uses only your likes: it finds people who liked the same posts as you, and shows you what else they've liked recently.
As an example, I built a "For You" feed https://bsky.app/profile/did:plc:3guzzweuqraryl3rdkimjamk/fe... that finds the posts you liked, finds other people who liked the same posts and shows you what else they liked.
To help me debug the algorithm I built a simple web UI that allows you to see the feed for any user by plugging their account id: https://linklonk.com/bluesky
You can switch perspective to other users and explore how the would experience the feed.
The recurrent approach is more efficient when memory bandwidth is the bottleneck. They talk about it in the paper.
This means that every attention layer can use previously calculated outputs for the same prompt prefix. So it only needs to calculate from scratch starting from the first unique token in the prompt sequence.
And the blog post author is talking about the output layer where the model has to produce an output prediction for every possible token in the vocabulary. Each output token prediction is a dot-product between the transformer hidden state (D) and the token embedding (D) (whether shared with input or not) for all tokens in the vocabulary (V). That's where the VD comes from.
It would be great to clarify this in the blog post to make it more accessible but I understand that there is a tradeoff.
You subscribe to tens or hundreds of feeds and, boom, you have another problem - how do you prioritize which feed to read .
With https://linklonk.com I'm trying to solve both problems: discovering feeds to follow and prioritizing content from all feeds.
You start with content you liked - submit links you liked and you will get connected to all feeds that included this link.
For example, there are a bunch of feeds that included this link https://simonwillison.net/2024/Feb/21/gemini-pro-video/
Those are:
- https://simonwillison.net/atom/everything/ - the original blog
- https://kagi.com/api/v1/smallweb/feed/ - a feed of "small web" links, I didn't know it existed, but one of the users must have submitted this feed.
- https://hnrss.org/newest?points=1000&count=100 - HN links that got more than 1000 points
- https://lobste.rs/rss - submissions to Lobste.rs
- https://lobste.rs/t/ai.rss - submissions to Lobste.rs with "ai" tag.
The point is, if you upvote this link on LinkLonk (https://linklonk.com/item/481037215144673280), you automatically get subscribed to all of these feeds. This is a way to discover new feeds through content you liked.
Now, being connected to hundreds or thousands of feeds might seem crazy. But we have a solution to that which also relies on what content you "liked". LinkLonk knows how often you liked content from each feed you are connected to (which is essentially the signal-to-noise ratio). So it ranks new content based on that. If you like 50% of posts from https://simonwillison.net/atom/everything/ then new posts from Simon Willison will be shown above other links from, say, https://lobste.rs/rss.
The more you like - the better the ranking of fresh content becomes.
In this world you don't have to actively manage which feeds you are subscribed to or not. You only rate content.
LinkLonk differs in these two aspects:
1. The algorithm is intentionally simple - like content to get more from that publisher (ie, RSS feeds) and from other users that liked it. Dislike - to get less. There is no AI so that you as a user could have control. For example, LinkLonk does not use your view history to guess what else you would like.
2. The list of sources is any RSS feed users have added. LinkLonk also automatically tracks any feed that posted content users liked. In this respect LinkLonk is more similar to RSS readers.
Passing the parameters from the handler to the template could be left to the user of the library.
I would make the templates library take a callback function for every public template: func(method, path string, template).
Then the user could add any custom logic to register the route handler and execute the template with any application specific inputs.
I liked the idea of defining the handle path in the name of the template and the auto-reloading on change functionality.
I wish this was a stand-alone library that I could use in my custom Golang server. Do you know if something like this exists?
Maybe it's a test to see how many power users would convert to verified?
This is more computationally intensive than sorting by the raw number of upvotes or weight upvotes by karma/popularity.
But I think this is a useful computation - the user can be more confident that the content they is is not astroturfed and comes from trustworthy users.
Details of how trust is calculated: https://linklonk.com/item/3292763817660940288
I think the problem with karma/reputation systems is that the source of karma are fungible - anyone's upvote has the same effect on the reputation. And this makes it gameable.
A personalized system can solve this by replacing global reputation with user-to-user trust. Now it matters who upvoted - a random bot or a user whose past contributions have been useful to you.
1. As an "agree" button - you upvote to get the perspective you share to be displayed more prominently to other people. It is a way for you to influence other readers.
2. As "it was useful to me and a good use of my time" button. You use it because you think other users will find it informative as well. In this case you are doing purely for the benefit of others.
3. As "it made me laugh or evoked some other emotions" button.
All three could be viewed as different dimensions of content and one item/comment can have different combinations along these dimensions.
It is complicated by the fact that content creators are actively optimizing their content along these dimensions to gain more visibility.
When I come to HN, as a reader, I want to see mostly informative content - which is only dimension 2. I don't want to be influenced or persuaded. And while I enjoy a good laugh - that's not my goal coming to HN. This makes the other two content dimensions contribute to noise.
Your suggestion to split out the upvote into separate labels like "agree", "informative" and "funny" [1] and to let users sort by the dimension of their choice may not solve the problem of separating "agree" from "informative" because there is no incentive for the voters to vote truthfully. People who upvote content they agree with want other people to see that content. If most users are sorting by informative then those voters will upvote content they agree with using the "informative" button.
I think you need to change the system of incentives in order for voters to upvote only informative content and not 1 and 3.
One way to do this is to make what you upvote have more consequences for the type of content you see in the future and less directly affect the ranking of that content for all users [2]. With a feedback loop like this the upvote button is no longer "what content do I want other people to see", but "what type of content do I want my future self to see". It makes you think before voting - "Was it worth my time?", "Is this kind of content aligned with my long term goals?"
[1] - Slashdot has something like this: "funny", "interesting", "insigthful" https://en.wikipedia.org/wiki/Slashdot#Peer_moderation but I don't think you can sort by it. Also, only a subset of users are given these moderator points.
[2] - I'm building https://linklonk.com that works this way.
""" Since it's likely that one user may upvote multiple comments from the same user, we check whether a user has already upvoted a comment from that specific user before considering their upvote. In other words, we treat user profiles as nodes and upvotes for comments as edges. """
This is a very lossy conversion of the actual data:
a. It does not distinguish if user C and D upvoted the same comment of user B or not. Maybe one comment was good and the other was bad. But when you convert it to the above graph you only get that C and D upvoted some comment of user B.
b. It does not account for the number of comments user B left - 1000 or 5? This incentivizes spam because there is no upside to not posting.
c. It ignores users that do not comment but upvote valuable comments themselves. Then the PageRank is used to weigh upvotes of users. This is backwards. The PageRank values should capture the value of each user's past upvotes in order to use it as a prediction of how valuable their future upvotes will be. But the suggested algorithm uses the value of the user's past comments as a weight of their future upvotes.
To fix this I think the graph needs to be changed to a bipartite graph of users and comments as nodes and upvotes and flags as directed edges (when the author posts a comment - this should be represented as an implicit upvote of the comment). Then you can calculate how valuable each user's upvotes (and flags) are.
2. The "gameability" of PageRank stems from the fact that the random walk algorithm treats each users equally as a starting point. It means that you can create a ton of fake users and upvote the comments of a target user you want to artificially boost in upvote-power. Each time the random walk starts at one of those fake users the walk will end up in the target user - increasing their PageRank score.
My proposal to solve the "gameability" problem is to start each walk from you - the user that views HackerNews. It means that your past upvotes become the starting step of the random walk and so the resulting PageRank will be personalized for you. Instead of a single PageRank reputation score (which captures how user A's contributions to HN have been to all users), there is a set of personalized scores that capture how useful other users have been to you.
I'm building https://linklonk.com which uses this kind of algorithm to rank both links and comments. The details of the ranking algorithm are here: https://linklonk.com/item/3292763817660940288
For example, if you submit this link: https://stratechery.com/2023/netflixs-new-chapter/ then you will get connected to two RSS feeds that posted that link: https://stratechery.com/feed/ and https://hnrss.org/newest?points=100 (ie, the HN feed of items with >100 points)
As you rate content you get connected to more and more sources.
The way it solves the oversubscription problem is - whenever a user/feed posts something - your connection to them goes down slightly. As a result you see content from sources with the highest signal-to-noise ratio first.
The differences from Artifact is:
- Artifact uses implicit signals such as read time; LinkLonk uses your explicit upvotes. I think implicit signals are fine for entertainment content, but not for informational content. Time spent is not equal to becoming better informed. I think only you can be a judge of that.
- Artifact uses an opaque AI algorithm optimized to do what they want; LinkLonk uses a transparent algorithm, where each recommendation comes from a feed or a user that you have co-liked items in common.
If I upvote what you upvoted then your votes get more weight for me.
This incentivizes each user to upvote what they truly found useful for themselves as opposed to the current incentives of social media which makes you upvote/like the stuff you want others to see.
Details of the algorithm: https://linklonk.com/item/3292763817660940288
If you limit the walk to just 3 steps then it becomes "users who upvoted what you upvoted also upvoted this".
What I like about it is that each recommendation is supported by concrete shared liked items which makes each recommendation easily explainable to the user.
I implemented this algorithm for my project (https://linklonk.com/item/3292763817660940288) that includes RSS feeds as sources of information and it's been working well as a prioritizing RSS reader. It would be great to see this algorithm tried on a bigger website like HN where there are so many upvotes/items/users to work with.
In that case every user would be a curator of content that they have chosen to upvote. If you happen to like someone's upvotes (ie, you upvote the same content as they do) then you would see their other upvoted items ranked higher for you.
The OP is just one curator that has decided to make their liked content public, but PPR would make every user of HN a potential curator of content for you.