Contents

ak's wiki
Markdown Parser
Preprocessor
Postprocessor
Wiki Graph
Related Links
  • 그래프 탐색
  • 스코어링
    • Backlink 보너스
    • 결과 그룹핑
Search Index
Autocomplete
LRU Cache
URL Utilities

7 passed0 failed15 Mar 2026 16:56

Related Links

현재 문서와 관련된 문서를 그래프 탐색 + 스코어링으로 추천하는 모듈. 위키에서 "다음에 읽을 문서"를 제안하여 탐색을 돕는다.

추천 알고리즘은 세 단계로 구성된다: (1) BFS로 forward/backward 링크를 따라가며 후보를 수집하고, (2) hub 페널티(링크가 많은 허브 문서의 가중치를 낮춤)와 콘텐츠 길이 보너스(내용이 풍부한 문서 우선)로 점수를 매긴 후, (3) 문서 타입별로 그룹핑하여 사용자에게 구조화된 형태로 제공한다.

그래프 탐색

collectRelatedPages는 주어진 문서에서 depth만큼 forward/backward 링크를 따라가며 관련 문서를 수집한다. 자기 자신은 결과에서 제외되어야 한다 — "이 문서와 관련된 문서" 목록에 자기 자신이 나오면 의미가 없다.

A→B→C 체인에서 A 기준 depth 3 탐색 → B, C 수집 (자기 자신 제외)
import { collectRelatedPages } from './src/lib/graph.ts' const data = { A: { links: new Set(['B']), backlinks: new Set() }, B: { links: new Set(['C']), backlinks: new Set(['A']) }, C: { links: new Set(), backlinks: new Set(['B']) }, } const result = collectRelatedPages('A', 3, n => data[n]) console.log(JSON.stringify([...result.keys()].sort()))
collectResult=["B","C"]

run:wiki

exprexpected
.
["B","C"]

check:jq

스코어링

Backlink 보너스

Backlink는 forward link보다 높은 점수를 받는다. "나를 참조하는 문서"는 "내가 참조하는 문서"보다 관련성이 높다는 가정에 기반한다 — 누군가 명시적으로 이 문서를 언급했다면, 역방향 관계가 더 강한 연관을 의미한다.

같은 depth에서 backlink가 forward link보다 높은 점수를 받는지 확인
import { scoreRelatedPages } from './src/lib/graph.ts' const rel = new Map([ ['Fwd', { isBacklink: false, depth: 2 }], ['Bwd', { isBacklink: true, depth: 2 }], ]) const cfg = { backlinkBonus: 1.3, hubPenaltyPower: 3, lengthBonusPower: 2 } const getMeta = () => ({ links: new Set(), backlinks: new Set() }) const getLink = n => ({ pagename: n, title: n, brief: '', contentLength: 100, frontMatter: { type: 'Article' }, }) const scored = scoreRelatedPages(rel, cfg, getMeta, getLink) const fwd = scored.find(s => s.link.pagename === 'Fwd').score const bwd = scored.find(s => s.link.pagename === 'Bwd').score console.log(JSON.stringify({ backlinkHigher: bwd > fwd }))
scoreResult={"backlinkHigher":true}

run:wiki

exprexpected
.backlinkHigher
true

check:jq

결과 그룹핑

최종 결과는 문서 타입별로 그룹핑되고, 각 그룹 내에서 제목순 정렬된다. 타입별 그룹핑(Person, Article, Book 등)을 통해 사용자가 원하는 종류의 관련 문서를 빠르게 찾을 수 있다.

Person(B, A)과 Article(X)을 타입별 그룹핑, 그룹 내 제목순 정렬
import { formatRelatedPages } from './src/lib/graph.ts' const pages = [ { link: { pagename: 'B', title: 'B', frontMatter: { type: 'Person' } }, score: 0.8 }, { link: { pagename: 'A', title: 'A', frontMatter: { type: 'Person' } }, score: 0.5 }, { link: { pagename: 'X', title: 'X', frontMatter: { type: 'Article' } }, score: 0.9 }, ] const result = formatRelatedPages(pages, 10) const keys = [...result.keys()].sort() const firstPerson = result.get('Person')[0][0].pagename console.log(JSON.stringify({ types: keys, firstPerson }))
$scoreResult={"backlinkHigher":true}
fmtResult={"types":["Article","Person"],"firstPerson":"A"}

run:wiki

exprexpected
.types
["Article","Person"]
.firstPerson
A

check:jq

Related Links


github.com/corca-ai/specdown · written by ak@corca.ai