Next.jsのブログにGitHub Cpoilotを使って、関連記事コンポーネントを追加する



Next.jsのブログにコンテンツレコメンドを使った関連記事表示機能を追加する
はじめに
このブログは、Next.jsのnext.js/examples/blog-starter at canary · vercel/next.jsを魔改造してSSGを利用して作成しています。
この記事では、最近(2025年7月)、ほぼすべてのコードをGitHub Copilot Agentを利用して関連記事表示機能を追加したので、開発した成果物とそのプロセスのふりかえりについて記載します。
ブログの関連記事表示で使われる代表的なアルゴリズム
Perplexityで確認した結果、以下の分類が一般的と回答がありました。個人的な見解とも一致しています。
今回実装したレコメンド機能は、コンテンツベースの関連記事表示機能です。
協調フィルタリングは、閲覧やクリック履歴に基づくアルゴリズムです。これらのデータはサイト公開後に得られるため、今回は利用できませんでした。そのため、記事データのみで実装できるコンテンツベースを採用しました。
| アルゴリズム分類 | 主な手法例 | 特徴・用途例 |
|---|---|---|
| コンテンツベース | TF-IDF, Cosine類似度, Word2Vec等 | 記事内容の類似性に基づく |
| 協調フィルタリング | アイテムベース, ユーザーベース, 行列分解 | 閲覧やクリック履歴に基づく |
| ハイブリッド | 両者の組み合わせ | 両方の長所を活かし弱点を補完 |
| ルールベース・単純 | カテゴリ一致, 人気順, 新着順等 | 実装が簡単。小規模ブログや初期導入向け |
| その他 | トレンド検出, 画像類似度 | 特定用途や高度なパーソナライズ |
実装した機能について
実装した機能は以下になります。それぞれ説明します。
- コンテンツベースレコメンド機能
1.をNext.jsのブログで利用するためのタスクや、コンポーネントの実装
1. コンテンツベースレコメンド機能
コンテンツベースレコメンドは、Pythonでの実装が多いイメージです。Next.jsで組み込む時に、Python実装のライブラリを使うか迷ったのですが、言語を統一したい気持ちが優って、以下のライブラリを利用することにしました。
stanleyfok/content-based-recommender: A simple content-based recommender implemented in javascript
ただ、ライブラリの状態として以下の点が気になったので、forkしてkemsakurai/ts-content-based-recommender: A simple content-based recommender implemented in typescript を作成しました。
- ライブラリが2020年から更新がない。
- JavaScriptでの実装。(TypeScriptにしたい)
- 日本語の形態素解析ができない。(日本語で形態素解析がしたい)
GitHub CopilotをVS CodeからAgentモードで利用して実装しました。
生成AIのモデルは、Claude Sonnet 4を利用しました。
以下、実装時にやったことを記載します。
JavaScript > TypeScriptの変換、型定義の追加
以下のpull requestで実装を行いました。
コンテンツベース推薦システムの実装 (JavaScript > TypeScriptへ変換) by kemsakurai · Pull Request #2 · kemsakurai/ts-content-based-recommender
GitHub Copilot Agentモードにほとんど任せていましたが、大きな問題は発生せず、スムーズに変更を完了できました。
日本語の形態素解析機能の追加、英語、日本語のモード切り替え
以下のpull requestでkuromoji.jsと@types/kuromojiを追加しました。
日本語形態素解析機能の実装と多言語サポートの追加 by kemsakurai · Pull Request #4 · kemsakurai/ts-content-based-recommender
GitHub Copilot Agentモードでも実装で概ね問題ありませんでしたが、行列作成処理で、バグが混入したのと、名詞や品詞の抽出処理で改善が必要だったので後々追加で修正をしています。
リファクタリング
EnglishTokenizer、JapaneseTokenizer等を作成して、言語ごとでの解析処理を整理して、Factoryクラスで実装を切り替えるように変更しました。
また、「行列作成処理のバグ」や「品詞抽出処理の改善」も合わせて行なっています。
これも、GitHub Copilot Agentモードにほとんど任せていましたが、ディレクトリの構造がforkのライブラリから意図せず変わってきてしまったので、手動でディレクトリ構成を変更した記憶があります。
パッケージ公開のための対応
作成したライブラリを、npmインストールして利用したかったため、package.jsonの調整を行いました。 公開後に、エラーになったり、ESMモジュールとして利用できなかった点を修正しています。
- バージョンを1.6.2に更新し、exportsを追加 by kemsakurai · Pull Request #13 · kemsakurai/ts-content-based-recommender
- Feature/5-パッケージ名の変更-と-publish-の準備 by kemsakurai · Pull Request #8 · kemsakurai/ts-content-based-recommender
- Feature/5 パッケージ名の変更 と publish の準備 by kemsakurai · Pull Request #7 · kemsakurai/ts-content-based-recommender
Next.jsのブログから利用するための、タスクやコンポーネントの作成
ts-content-based-recommenderの利用側は以下の機能を実装しました。
ts-content-based-recommenderを利用して、コンテンツレコメンドデータを保持するJSONデータを作成するタスク- JSONデータを読み込んで、関連記事を表示するReactコンポーネント
1. コンテンツレコメンドデータを保持するJSONデータを作成するタスク
-
generateRecommendData.mjs
以下のgistに成果物をアップロードしました。
Next.js の静的ブログに組み込んだコンテンツレコメンドデータを生成するタスク -
package.json
package.jsonには以下のスプリプトを追加して、prebuildで実行しています。
"scripts": {
"generate-recommend": "node src/tasks/generateRecommendData.mjs",
"prebuild": "npm run validate-images && npm run generate-index && npm run generate-recommend",
...
}
コンポーネントの作成
以下のgistに成果物をアップロードしました。
GitHub Copilot Agent を利用した開発の振り返り
「👍(プラス)」「👎(デルタ)」形式で記載します。
- 「👍(プラス)」動作するものができたので、概ね良かったと感じる
- 「👍(プラス)」同じものを手動で作成するよりは断然速い
- Next.jsのコンポーネントについては、手直しせずに1回で動作するものを作成できた。
- 「👍(プラス)」想像していた手順で、作業は概ねうまく行った。
- kemsakurai/ts-content-based-recommender: A simple content-based recommender implemented in typescript ライブラリの作成
- ライブラリの作成後にブログへの組み込み
- 「👎(デルタ)」ライブラリの公開に手間取った。
- 自分自身が経験のない領域は、生成AIを利用しても、間違いの判断ができない。
- 慎重な作業が必要な場合は、もっと下調べをしておくべきだったかもしれない。
- 「👎(デルタ)」関連記事コンポーネントが非同期通信をして記事データを取得していますが、事前に静的生成を行うことでパフォーマンスを向上させる余地がありそう。
- とりあえず、動作するので、いったんはリリースして別で修正することにした。
- 「👎(デルタ)」利用しない、関数ファイルができていた。
- 修正過程で最終的に利用しないTSファイルができていた。未使用の関数をリリース前にチェックする仕組みを組み込むと良いと思った。
まとめ
今回、TypeScriptベースのコンテンツベース推薦システムを実装し、Next.jsブログに関連記事表示機能を追加しました。GitHub Copilot Agentを活用することで効率的に開発を進めることができましたが、やはり自分が経験のない領域では慎重な検証が必要だと感じました。
また、2025年4月に実施した時と比べると、現状(2025年7月)ではモデルが進化しています。そのため、雑な指示でもコードの精度が高くなったと感じます。
Issueの文書の書き方、ルールファイルを改善すると精度はもっと向上しそうな気がしていて、そのあたりを試してみたいと思っています。