$shibayu36->blog;

クラスター株式会社のソフトウェアエンジニアです。エンジニアリングや読書などについて書いています。

chat-hatenablog v0.2.1をリリースした。過去のブログ記事を更新してもインデックスを差分更新できるように等

ChatGPTを使って自分のはてなブログとチャットするツールを作った - $shibayu36->blog;で紹介したchat-hatenablogのv0.2.1をリリースした。

リリース内容

https://github.com/shibayu36/chat-hatenablog/releases/tag/v0.2.0 https://github.com/shibayu36/chat-hatenablog/releases/tag/v0.2.1

今回はbreaking changeもある。

  • [breaking change] 過去のブログ記事を更新したケースでも、うまくインデックスを更新できるように
    • 元々はインデックスを作る -> 古い記事を編集 -> 再エクスポートしてインデックスを作り直しをすると、同じ記事のインデックスが複数できてしまうような問題があった
    • インデックス構造が変わっているので1からインデックスを作る必要あり
  • インデックスが変わる時しかファイル書き込みをしないようにし、差分更新を高速化
  • terminateしたタイミングによってpickleファイルが壊れてしまう問題を修正

開発メモ

古い記事の更新時にもインデックスを更新できるようにする

https://github.com/shibayu36/chat-hatenablog/pull/15 + https://github.com/shibayu36/chat-hatenablog/pull/25

元々のインデックス構造では、ファイル更新に対応できなかったため、次のようなインデックス構造に変更した。

{
    "basename1": {
        "content_hash": "...",
        "title": "title1",
        "embeddings_list": [
            {"body": ..., "embeddings": [...]},
            {"body": ..., "embeddings": [...]},
        ],
    },
    "basename2": { ... },
}

ポイントとしては

  • ブログ記事はpermalinkは変わらないという特性があるので、MovableTypeフォーマットのbasenameを記事を示す値として利用する
  • titleとbodyを含めてhash値を作ることによって、コンテンツが変わったらインデックスを更新するように
    • 記事編集日時とかでも良いが、例えばembeddingsを作るときの本文分割方法が変わった時にインデックスが更新されるようにするため、コンテンツハッシュの手法にした

./chat-hatenablog askをするときは、この構造を[(title, body, basename, embeddings), ...] の構造に変換する必要がある。Pythonだと変化も簡単だった。self.cacheに上の構造が入っているとすると、次のように書くだけで良い。リスト内包表記便利。

items = [
    [info['title'], embeddings_list['body'], basename,
        embeddings_list['embeddings']]
    for basename, info in self.cache.items()
    for embeddings_list in info.get('embeddings_list')
]

インデックスが変わる時しかファイル書き込みをしないようにし、差分更新を高速化

今までは、インデックスの更新が必要ない時でも1エントリ1回ファイル保存が走ってしまっていて、特に2回目以降のインデックス作成時に遅くなってしまっていた。こちらは単純にdirty flagを導入し、必要な時のみファイル保存をするようにした。

https://github.com/shibayu36/chat-hatenablog/pull/19

terminateしたタイミングによってpickleファイルが壊れる問題を直す

別の記事で詳しく解説した。 blog.shibayu36.org

リリースノートをちょっとだけ良い感じにする

.github/release.ymlを設置して、リリースノートをちょっとだけ良い感じにした。

以下の記事を参考にした。

初回のラベル生成は、github-label-syncを用いてさっと作った。

labels.yml

- name: add
  description: Add new features.
  color: "0e8a16"
- name: change
  description: Change existing functionality.
  color: "fbca04"
- name: deprecate
  description: Mark as soon-to-be removed features.
  color: "d93f0b"
- name: remove
  description: Remove features.
  color: "b60205"
- name: fix
  description: Fix bug.
  color: "5319e7"
- name: security
  description: In case of vulnerabilities.
  color: "0052cc"
github-label-sync --access-token ... --labels labels.yml shibayu36/chat-hatenablog --allow-added-labels