本文へ移動
cccskills
無料GitHub で公開

internal-link-graph

Build the internal link graph for a site, run PageRank-style authority distribution, detect orphan pages, and recommend new internal links via embedding-based semantic similarity (not keyword matching)..

インストール方法を見る

含まれるファイル(1)

  • SKILL.md10.2 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

Internal Link Graph & Semantic Linking

You build the internal link graph and recommend new internal links based on semantic content fit, not keyword density. Internal linking is the highest-leverage SEO control surface that doesn't require new content — and it's typically under-managed because manual audits don't scale past 500 pages.

============================================================ === PRE-FLIGHT ===

  • Site URL + sitemap: https://example.com/sitemap.xml or root URL for sitemap discovery.
  • Crawl budget: number of pages (typical 500-50,000). Above 50k, plan for distributed crawl (Scrapy-cluster or Cloudflare Browser Rendering API).
  • Output target: actionable internal linking opportunities + site architecture report.
  • Embedding model: text-embedding-3-small (OpenAI, $0.02/1M tokens) OR self-hosted all-mpnet-base-v2 (sentence-transformers).
  • JavaScript rendering: required for SPAs / heavy CSR sites. Use Playwright. CPU-bound; budget accordingly.

Recovery:

  • No sitemap: discover via robots.txt + /sitemap.xml + /sitemap_index.xml + linked-from-root crawl.
  • Crawl blocked: respect — surface and stop. Don't try to bypass.

============================================================ === PHASE 1: CRAWL ===

Generate crawler.py using httpx + selectolax for HTML parsing (faster than BS4):

class Crawler:
    def __init__(self, site_root: str, max_pages: int, render_js: bool = False):
        self.site_root = normalize(site_root)
        self.max_pages = max_pages
        self.render_js = render_js  # Playwright if True
        self.seen: set[str] = set()
    
    async def crawl(self) -> dict[str, PageData]:
        seeds = await self._sitemap_urls()
        results = {}
        async for url in self._bfs(seeds):
            html = await self._fetch(url)
            results[url] = self._extract(url, html)
            if len(results) >= self.max_pages: break
        return results
    
    def _extract(self, url, html) -> PageData:
        return PageData(
            url=url,
            title=...,
            h1=...,
            word_count=...,
            internal_links=[normalize(href) for href in ... if same_domain(href)],
            content_text=...,             # for embedding
            content_paragraphs=[...],     # for link-position recommendation
        )

Respect robots.txt. Default crawl-delay 1s. User-agent: Mozilla/5.0 ... (link-graph-builder; contact: support@yourdomain).

VALIDATION: Crawl completes within budget. Internal link extraction includes ≥ 95% of <a href="..."> elements visible in source.

============================================================ === PHASE 2: GRAPH CONSTRUCTION ===

Generate graph.py:

import networkx as nx

def build(pages: dict[str, PageData]) -> nx.DiGraph:
    G = nx.DiGraph()
    for url, p in pages.items():
        G.add_node(url, 
                   title=p.title, 
                   word_count=p.word_count,
                   indexed=p.indexed,
                   noindex=p.noindex)
    for url, p in pages.items():
        for target in p.internal_links:
            if target in pages:
                if G.has_edge(url, target):
                    G[url][target]["count"] += 1
                else:
                    G.add_edge(url, target, count=1)
    return G

# PageRank with edge weights (multi-link from same source counts more)
pr = nx.pagerank(G, alpha=0.85, weight="count")

VALIDATION: Graph node count == crawled-page count. Edges count > nodes (typical: 10-50 edges per node).

============================================================ === PHASE 3: AUDIT METRICS ===

For each page:

  • PageRank (internal authority).
  • In-degree (unique pages linking IN).
  • Out-degree (unique internal pages linked TO).
  • Avg path depth from homepage (BFS shortest path).
  • Click depth from homepage (BFS — important: Google crawls deepest pages least often).

Generate flags:

FlagDefinitionAction
OrphanIn-degree = 0 (no inbound internal links)Add ≥ 2 contextual links from related pages
Near-orphanIn-degree = 1 from a low-PR pageAdd 2-3 inbound links from cluster
Authority sinkHigh PR + low out-degreeAdd outbound links to deeper cluster pages
Dead-endOut-degree = 0 (rare for non-leaf pages)Add related-content section
Too deepClick depth > 4 from homepageRestructure nav or add internal-link shortcut
Over-linkedOut-degree > 200Possible footer/template noise diluting equity

Output link_graph_audit.csv with all flags.

VALIDATION: Audit identifies orphans + authority sinks against fixture site.

============================================================ === PHASE 4: SEMANTIC LINK RECOMMENDATION ===

The real differentiator: recommend NEW internal links based on semantic similarity, not keyword matching.

For each candidate target page (priority = orphans, high-intent pages, conversion pages):

  1. Embed the target page's title + H1 + summary.
  2. Embed each paragraph of every source page (one embedding per paragraph).
  3. Find paragraph-level cosine matches ≥ 0.72 (tunable).
  4. Rank candidate source paragraphs by similarity × source PageRank.
  5. For the top 10 paragraphs per target, propose an anchor-text + insertion point.

Generate link_recommendations.md:

## Target: /pricing
Current in-degree: 2

### Recommended new inbound links:

1. **From `/blog/pricing-models`** (PR: 0.0042, similarity: 0.81)
   - Suggested anchor: "our transparent pricing"
   - Insertion point: 3rd paragraph, after "...different pricing models exist."
   - Context: "Most SaaS uses per-seat pricing. [our transparent pricing] uses usage-based..."

2. **From `/blog/saas-buyer-guide`** ...

Limit recommendations to 5-10 per target — anything more pollutes naturalness.

VALIDATION: For a sample target page, recommended links are demonstrably relevant (not "/about" linking to "/pricing" via "click here").

============================================================ === PHASE 5: SILO / CLUSTER ANALYSIS ===

Detect topical clusters via:

  • Community detection (Louvain or Leiden algorithm on the link graph).
  • Or semantic clustering (k-means on page embeddings).
  • Reconcile: a healthy cluster has high internal cohesion AND high embedding similarity.

Output topical_clusters.md:

  • Cluster N: {topic label generated from top 5 highest-PR pages' titles}
    • Pillar candidate: page with highest within-cluster PageRank
    • Supporting pages: rest of cluster
    • Recommended pillar-to-supporting links: any missing
    • Recommended cross-cluster bridges: 1-2 per cluster (not more — diffuses focus)

VALIDATION: Cluster labels are recognizable to a human looking at the URLs.

============================================================ === PHASE 6: IMPLEMENTATION HELPER ===

For each recommended link, generate either:

  • A markdown patch if the source page is in a markdown CMS (Hugo, Jekyll, Astro, Next.js MDX).
  • A CMS-specific snippet if WordPress / Webflow / Squarespace.
  • A JSON manifest for the editorial team to insert via their CMS UI.

Output link_patches/ directory with one file per source page containing all queued link insertions.

VALIDATION: Patches are syntactically valid (markdown renders, JSON parses).

============================================================ === PHASE 7: REPORTS ===

internal-link-graph/
├── README.md
├── data/
│   ├── crawl.db
│   └── graph.gexf             # importable to Gephi for visual analysis
├── reports/
│   ├── audit_summary.md
│   ├── link_graph_audit.csv
│   ├── orphan_pages.csv
│   ├── authority_sinks.csv
│   ├── link_recommendations.md
│   ├── topical_clusters.md
│   └── pagerank_distribution.png
└── patches/
    └── {hash}.patch.md

VALIDATION: All reports render. GEXF opens in Gephi correctly.

============================================================ === SELF-REVIEW ===

  • Complete: Crawl + graph + audit + semantic linking + cluster + patches?
  • Robust: Respects robots, handles JS-rendered sites, scales to 50k pages?
  • Clean: Recommendations have specific anchor text + insertion points, not just URL pairs?
  • SEO-credible: Would a technical SEO who's read SEO Theory recognize this as legit?

Common gap: keyword-anchor-text repetition (linking 50 pages to /pricing with anchor "pricing" looks manipulative). Vary anchor text from the surrounding context.

============================================================ === LEARNINGS CAPTURE ===

~/.claude/skills/internal-link-graph/LEARNINGS.md.

============================================================ === STRICT RULES ===

  • Never propose 50+ new internal links pointing to the same target with identical anchor text. Anchor diversification is a real ranking signal.
  • Never recommend links from unrelated pages just to lift in-degree. Topical fit > raw link count.
  • Never crawl past robots.txt. Respect.
  • Always preserve the crawl history. The graph is a longitudinal artifact — month-over-month changes inform architecture decisions.
  • Always include both PageRank-weighted AND semantic recommendations. PR-only = old-school; semantic-only = misses authority flow.

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

508-audit

無料

Run a full Section 508 + WCAG 2.2 Level AA accessibility audit on a federal / .gov / public-sector website or ICT product. Triggers: "Section 508", "508 audit", "WCAG", "VPAT", "ACR".

日本語の概要は準備中です。原文の説明を表示しています。

tinh2/skills-hub-registry192026年9月5日 更新

Analyzes actuarial modeling systems for loss reserving accuracy, premium pricing methodology, mortality/morbidity tables, stochastic modeling, and capital adequacy per SOA and Solvency II standards..

日本語の概要は準備中です。原文の説明を表示しています。

tinh2/skills-hub-registry192026年9月5日 更新

Analyzes advertising yield across programmatic and direct-sold inventory including CPM/CPC/CPA performance, header bidding efficiency, fill rate optimization, inventory monetization strategies, and compliance with IAB standards and OpenRTB protocols..

日本語の概要は準備中です。原文の説明を表示しています。

tinh2/skills-hub-registry192026年9月5日 更新

adr

無料

Create and manage Architecture Decision Records using the Michael Nygard format. Triggers: you need to document architecture decisions, record technical choices, explain why a technology was chosen.

日本語の概要は準備中です。原文の説明を表示しています。

tinh2/skills-hub-registry192026年9月5日 更新

Analyzes affordable housing management software for unit allocation algorithms, waitlist management, income verification workflows, Fair Housing compliance, LIHTC and Section 8 program tracking, inspection scheduling, and tenant reporting..

日本語の概要は準備中です。原文の説明を表示しています。

tinh2/skills-hub-registry192026年9月5日 更新

Rewrites existing landing pages, blog posts, and documentation so AI search engines (Google AI Overviews, ChatGPT, Perplexity, Claude, Gemini) cite them. Triggers: an existing page underperforms in AI answers despite ranking well in classic SERPs.

日本語の概要は準備中です。原文の説明を表示しています。

tinh2/skills-hub-registry192026年9月5日 更新

tinh2 のスキルをすべて見る

このスキルの問題を報告する