Smart Connections
Discovering Hidden Links
Why Connections Matter More Than Content
A single note about "microservices vs monoliths" is useful. But that same note connected to a bookmark on "scaling team autonomy," meeting notes about "service ownership," and an article on "Conway's Law" — that's an *insight*. The individual pieces are trivia. The connections are knowledge.
The best second brain systems don't just store — they link.
Finding Related Items
The simplest connection: for any item, find the N most similar items using the embeddings you already have.
function findRelated(targetId: string, allChunks: Chunk[], topN: number = 5): Chunk[] {
const target = allChunks.find(c => c.id === targetId);
if (!target) return [];
return allChunks
.filter(c => c.id !== targetId)
.map(c => ({ chunk: c, score: cosineSimilarity(target.embedding, c.embedding) }))
.sort((a, b) => b.score - a.score)
.slice(0, topN)
.map(r => r.chunk);
}This gives you "items like this one" for any piece of knowledge. Useful, but not surprising — similar items tend to be obviously related.
Cross-Source Connections
The highest-value connections span source types:
| Connection Type | Example | Why It's Valuable |
|---|---|---|
| Note ↔ Bookmark | Your note on caching links to a saved Redis article | Validates your thinking with external reference |
| Meeting ↔ Article | Discussion about team velocity links to a paper on flow states | Connects a problem to a potential solution |
| Project ↔ Bookmark | Project doc on API redesign links to REST best practices bookmark | Brings forgotten reference into active work |
| Note ↔ Meeting | Personal reflection on tech debt links to sprint planning discussion | Connects private thinking to team context |
To find cross-source connections, add a filter: only return results from a *different* source type than the input.
Building the Knowledge Graph
A knowledge graph makes connections explicit and navigable:
interface GraphEdge {
sourceId: string;
targetId: string;
score: number;
crossSource: boolean; // Different source types?
}
function buildGraph(chunks: Chunk[], threshold: number = 0.75): GraphEdge[] {
const edges: GraphEdge[] = [];
for (let i = 0; i < chunks.length; i++) {
for (let j = i + 1; j < chunks.length; j++) {
const score = cosineSimilarity(chunks[i].embedding, chunks[j].embedding);
if (score >= threshold) {
edges.push({
sourceId: chunks[i].id,
targetId: chunks[j].id,
score,
crossSource: chunks[i].source !== chunks[j].source,
});
}
}
}
return edges;
}Tuning the Threshold
The similarity threshold controls the density of your graph:
| Threshold | Result |
|---|---|
| 0.9+ | Very few connections — only near-duplicates |
| 0.8-0.9 | Strong connections — clearly related items |
| 0.7-0.8 | Moderate connections — good for discovery |
| Below 0.7 | Too many connections — mostly noise |
Start at 0.75 and adjust based on your data. If the graph is too sparse, lower it. If every item connects to everything, raise it.
Surfacing Surprising Connections
The most valuable connections are surprising — items that are semantically similar but differ in source type, topic area, or time period.
A "surprise score" combines semantic similarity with contextual distance:
surprise = similarity * (1 + source_bonus + time_bonus)Where source_bonus adds 0.2 if the sources differ, and time_bonus adds 0.1-0.3 based on how far apart the dates are. A connection between a note from January and a bookmark from June is more surprising (and often more insightful) than two notes from the same day.
Clusters and Themes
Beyond pairwise connections, clusters reveal themes in your knowledge:
Key Takeaways
This is chapter 5 of AI-Powered Second Brain.
Get the full hands-on course — free during early access. Build the complete system. Your projects become your portfolio.
View course details