なぜ AI 概要が必要なのか#
あまり覚えていませんが、中学校の時に新聞の読み方についての文章を学んだ印象があります。
私はその時の文中で紹介された習慣を読みながらずっと維持してきました。
精読が必要ない内容は飛ばし読みができます。
今、ChatGPT が大流行した後、多くのアプリケーションが登場し、その中でも AI 概要プラグインは私にとって大いに助けになっています。
情報過多の中で、私たちは多くの低価値な情報に圧倒されており、このようなプラグインは私が記事を細かく読む価値があるかどうかを迅速に判断するのに役立ちます。
多方面を比較した結果、私は「ChatGPT 概要アシスタント - Chrome ウェブストア」をウェブブラウジング時の優先プラグインとして選びました。
その使用効果は以下の通りです:
AI 概要は必須か#
必須ではありません!
私は AI 概要を統合したのは、私と同じ読み方の習慣を持つ人々のための便利さのためです。
私の個人ブログは生活を記録し、いくつかのメモを書くことにありますが、他の人にとっては全て低価値なデータです。
私は現在、ブログに AI 概要機能を統合していますが、それはTianliGPTを使用したからです。
当時、私は「独立した開発者を支援する」という気持ちから TianliGPT のサービスを購入しました。
購入したキーはすぐに消耗し、もう一つキーを購入しましたが、それでも足りず、さらにもう一つキーを購入しました。
それでも、私のブログには AI 概要がある記事は 2/3 未満です。
このままでは、無限の穴に落ちているように感じます。
この時、AI 概要機能は歴史的な負担になってしまいました。
AI 概要機能を取り消すと、前に使った少額のお金は埋没コストになってしまいます。
情熱があるからといって、Geek 精神を妥協する必要はありません。
だから、自分で AI 概要を改造することに決めました。
これは、当初 Hugo 静的ブログに移行した目的にも合致しており、できるだけデータを静的化することを目指しています。
できるだけページデータを SSG(Static-Site Generation)/SSR(Server-Side Rendering)にしたいと思っています。
AI 概要をどう最適化するか#
おすすめ:https://github.com/Moraxyc/ai-summary-hugo を使用して summary.json を生成するための Python スクリプト
1. 方法#
AI 概要をローカルに保存するには 2 つの考え方があります:
data
ディレクトリに.json
ファイルでデータを保存する
- 概要結果を記事の
.md
ファイルのフロントマターに置く
2. データ形式#
私は方法 1 を選び、すべての AI 概要を .json
ファイルに保存しました。これにより、後のメンテナンスが容易になり、既存の記事を壊すことがありません。
データの出所:
- TianliGPT がすでに生成した概要
- スクリプトを通じて ChatGPT と Claude2 から取得した概要
私は現在、いくつかのスクリプトを使用して概要を取得していますが、完璧なスクリプトはありませんので、スクリプトは貼りません。
TianliGPT の概要は、ウェブページで F12 を押して DevTools を開くと見つけることができます:
さまざまな方法で取得した AI 概要を集約し、summary.json
ファイルを生成します。
data
ディレクトリに新しく data/summary/summary.json ファイルを作成し、すべてのデータをそこにコピーします。データ形式は以下の通りです:
{
"summaries": [
{
"title": "2010年12月15日 雪景",
"slug": "snows",
"generated": true,
"summary": "この記事は、著者が2010年12月15日に経験した雪景について述べています。著者は、雪が降る前に空には数点の星のような白い点があり、誰もこれほどの雪が降るとは予想していなかったと述べています。著者は故郷ではもっと大きな雪が降るかもしれないと考えています。記事は、住所設定やプログラムエラーに関する問題にも触れ、デジタルガーデンが愛で発電するという結末で締めくくられています。"
},
{
"title": "2011年 左へ、2010年 右へ",
"slug": "goodbye2010",
"generated": true,
"summary": "この記事は、著者が2010年を振り返り、2011年への期待を語っています。彼は、過去一年間、他人のために生きすぎて自分を失ったと考えています。新しい年には、より積極的で明るい自分になり、経験と感悟を財産としたいと願っています。最後に、彼はもう苦難を愚かに語らないと述べ、皆に新年の挨拶をしています。"
}
]
}
ここで generated
は私が自分用に使っている判断用語で、あってもなくても構いません。title
と slug
は記事のアンカーポイントに対応するためのものです。
3. AI 概要のレンダリング#
summary.json
ファイルの AI 概要を各記事の冒頭にレンダリングするには、Hugo の記事テンプレートファイルを少し修正する必要があります。
異なるテーマのテンプレートファイルは少し異なるかもしれませんが、あまり変わりません。
一般的には single.html
と呼ばれ、テーマの layouts
または Hugo のルートディレクトリの layouts
にあります。
例えば、DoIt のテンプレートは themes/DoIt/layouts/posts/single.html
にあります。
私はそれをルートディレクトリにコピーしました layouts/posts/single.html し、同名テンプレートが優先的にルートディレクトリでレンダリングされます。
記事テンプレート single.html
の {{ .Content }}
の前に以下のコードを挿入します:
<!-- 他のコード -->
<!-- データを取得 -->
{{ $summary := getJSON "data/summary/summary.json" }}
<!-- slugをアンカーポイントとして記事と概要を対応させる -->
{{ $currentSlug := .Params.slug }}
{{ $matchingSummary := index (where $summary.summaries "slug" $currentSlug) 0 }}
<div class="post-ai">
<div class="ai-title">
<i class="fas fa-robot ai-title-icon"></i>
<div class="ai-title-text">AI 概要</div>
</div>
<!-- Typeit タイピング効果 -->
<!-- <div id="ai-explanation" class="ai-explanation"></div> -->
<div class="ai-explanation ai-explanation-content">
{{ if $matchingSummary.summary }}
{{ $matchingSummary.summary }}
{{ else }}
AI概要インターフェースが一時的に失われています……
{{ end }}
</div>
</div>
<!-- 文書本文をレンダリング -->
{{ .Content }}
<!-- 他のコード -->
タイピング効果は必要ありませんので、上記の内容はすでに使用可能です。
タイピング効果が必要な場合は、<div id="ai-explanation" class="ai-explanation"></div>
のコメントを解除する必要があります。
<div class="ai-explanation-content" style="display: none;">
に display: none
を追加して隠す必要があります。これは Typeit プラグインに値を与えるためだけの役割です。
JS を追加します:
<script src="https://unpkg.com/[email protected]/dist/index.umd.js"></script>
<script>
document.addEventListener("DOMContentLoaded", function () {
// .ai-explanation-content から値を取得
const matchingSummary = document.querySelector(".ai-explanation-content").textContent;
new TypeIt("#ai-explanation", {
strings: matchingSummary,
speed: 50,
lifeLike: true,
waitUntilVisible: true,
}).go();
});
</script>
4. 簡単な CSS#
.post-ai {
background: #f5f5f5;
border-radius: 0.5rem;
padding: 0.5rem;
line-height: 1.3;
border: 1px solid #cfe6f3;
margin: 1rem 0;
}
.ai-title {
display: flex;
color: #2d96bd;
border-radius: 0.5rem;
align-items: center;
padding: 0 0.25rem;
cursor: default;
user-select: none;
}
.ai-title-icon {
width: 20px;
height: auto;
margin-right: 0.25rem;
}
.ai-title-text {
font-weight: bold;
margin-left: 0.25rem;
line-height: 1;
}
.ai-explanation {
margin-top: 1rem;
padding: 0.5rem 1rem;
background: #fff;
border-radius: 0.5rem;
border: 1px solid #cfe6f3;
font-size: 0.95rem;
line-height: 1.4;
display: inline-block;
width: 100%;
}
.ai-explanation span {
margin-left: 0.5rem;
}
/* .ai-explanation-content {
display: none !important;
} */