← ガイダンス一覧へ戻る

5Tagの推薦と新規作成

Zettelkasten Inbox / ブロック詳細

「このノートはどの観点の話か」を決める場所。おすすめは語句の重なりの点数計算で、通信ゼロ・AIなし。無ければその場でTagを作れるが、作る前に必ず同名を照合する。

抽象度 Lv.4(技術用語+システム上のやりとりまで/製品名・ライブラリ名は書かない)

1. 概要

「このノートは、どの観点の話か」を決める場所。Tagはこのアプリの分類の背骨で、 Tagを選ばないとABC Noteの候補が1つも出ない作りになっている。

おすすめは、ノートの文とTag名の語句の重なりで点数を付けて上位3件を出す。 ここもAIは使っていない。全部ブラウザの中の計算で、通信は発生しない。

探しても無ければ、その場で新しいTagを作れる。ここだけがNotionへの書き込みで、 作る前に必ず「同じ名前が既にないか」を照合する

2. 位置づけ

3. 本文の取り出しと自動要約 → 5. Tagの推薦と新規作成 → 6. ABC Note候補の絞り込み

3. 処理内容(Lv.4)

4. なぜこの位置にあるか(設計意図)

ABC Noteより先にTagを決めさせるのが、このアプリの中心の思想。 ABC Noteは数が多く、名前だけでは似たものが並ぶ。 先に「どの観点か」を1段挟むことで、候補が数十件から数件まで一気に減る。 Tagは分類のためというより、選択肢を減らすための道具として置かれている。

推薦をサーバーに置かなかった理由。3番で作った特徴量がすでにブラウザにある。 同じものをサーバーへ送り直せば通信が要る。ブラウザで完結させたことで、 コメントを書き足して「候補を更新」を押すとその場で順位が変わる

整理用Tagを減点する理由。「あとで読む」「本」のようなTagは、 仕組み上はよく使われるので使用回数が高く、放っておくと常に上位に出る。 だが観点としては何も言っていない。45点という重い減点で、意図的に沈めている。

新規作成を保存(8番)とは別のAPIにした理由。Tagを作った時点で 画面のTag一覧に即座に加わり、選択済みになる。保存まで待たせない。 「無いなら作って、そのまま続ける」という流れを止めないための分離。

5. 詳細プロセス分解

工程主体やりとりの内容方向
5-1ブラウザ(内部)ノートの文を正規化し、2文字の並びの集合に変換
5-2ブラウザ(内部)Tagごとの点数計算と上位3件の選出
5-3ブラウザ(内部)検索入力があれば推薦を止め、絞り込みに切替
5-4ブラウザ → Tag作成API新しいTagの名前(新規作成のときだけ)
5-5Tag作成API → NotionTag DBの全件取得と同名の照合
5-6Tag作成API → Notion(同名が無ければ)ページの作成
5-7Tag作成API(内部)作成結果の検証
5-8Tag作成API → ブラウザTagの情報と、作ったか見つけたかの区別

各行を文章にすると

5-1 まず、このノートに関する文字を全部つなげて1本の文章にし、 比べやすい形に整える。整えるというのは、大文字小文字・全角半角・記号・空白のばらつきを消すこと。

技術的には つなぐのは 元の題名・編集中の新タイトル・編集中のコメント・Notion本文の4つ。 正規化は3手順:全角と半角を統一する形に変換(NFKC)、日本語向けの小文字化、 そして空白・約物・記号をすべて削除。 残った文字列を先頭から2文字ずつ重ねて切り出し、重複を消した集合にする (「知識管理」なら「知識」「識管」「管理」の3つ)。 2文字にするのは、日本語には英語のような単語の区切りが無いから。 単語に分けようとすると辞書が要るが、2文字ずつなら辞書なしで語句の重なりが測れる。

5-2 Tag1つずつに点数を付けて、高い順に3つを「おすすめ」に出す。

技術的には 重なりの測り方が2種類あり、混ぜて使う。 包含率=Tag側の並びのうち何割が本文にもあるか。 ダイス係数=共通部分の2倍を、両方の合計で割った値。 この2つを 0.72 : 0.28 で混ぜる。 包含率を重く見ているのは、短いTag名が長い本文に埋もれないようにするため―― ダイス係数だけだと、本文が長いほど分母が膨らんですべてのTagの点が下がってしまう。 そのうえで、点数は次の足し算になる。 そのまま含まれていれば140点(「知識管理」というTagが本文に丸ごと出てくる場合)、 題名の重なり×85、親Tag名と説明文の重なり×65、配下にABC Noteがあれば8点、 使用回数の常用対数×5(10件で5点、100件で10点。対数にしているのは、 よく使うTagが強くなりすぎないように差を圧縮するため)、 整理用Tagなら45点減点。上位3件が「おすすめ」、残りは使用回数順で下に並ぶ。 この計算は通信ゼロで、Tagが200件あっても一瞬で終わる。

5-3 検索窓に何か打つと、おすすめは消えて、素直な絞り込みに切り替わる。

技術的には 入力を同じ手順で正規化し、 Tag名・親Tag名・説明文をつないだ文字列に含まれるかで絞る。 並び順は使用回数の降順、同数なら日本語順。 推薦と検索を同時に見せず、はっきり切り替えるのは、 「探しに来た人」に対して機械の推測を混ぜない、という判断。

5-4 探しても無ければ、入力した名前でそのまま新しいTagを作れる。 同じ名前のTagが既にあるときは、作成ボタンが押せなくなる。

技術的には POST /api/tagsapplication/json{"title": "…"}。 ボタンを押せなくする判定はブラウザ側でも行うが、 サーバー側でも同じ照合をやり直す(画面の状態が古い可能性があるため)。 名前の上限は100文字で、これも両側で見る。

5-5 サーバーはNotionのTagを全部取ってきて、同じ名前が無いかを確かめる。

技術的には 同名かどうかの判定は、 全角半角をそろえ、小文字にし、前後の空白を落とし、連続空白を1つにまとめた形で比べる。 ここは 5-1 の正規化とは別で、記号は消さないし、空白も残す―― Tag名は表記そのものが意味を持つので、消しすぎると別のTagが同じものと判定されてしまう。 2つの正規化を使い分けているのがこのアプリの細かい所。

5-6 無ければ作る。ラベルの絵文字が自動で付く。

技術的には POST /v1/pages に、 親としてTag DBを指定し、絵文字🏷️をアイコンに、名前だけを設定して作る。 親Tagや配下のABC Noteは設定しない。階層への組み込みは、あとからNotion側で人がやる前提

5-7 作ったあとで、本当に狙いどおりに出来ているかを確かめる。

技術的には 返ってきたページに対して2つ検証する。 (1) 親が本当にTag DBか――親の種類が「データソース指定」で、 そのIDが設定と一致するか。 (2) 付いた名前が、頼んだ名前と正規化後に一致するか。 どちらか外れたら 502 +「NotionへのTag作成結果を確認できませんでした。」。 ただし、このとき作られたページは削除されない。 照合は「出来たつもりで出来ていない」を検知するためのもので、元に戻す仕組みではない。

5-8 結果を返す。「新しく作った」のか「同名が見つかった」のかを 区別して伝えるので、画面のお知らせも変わる。

技術的には {"ok": true, "tag": {…}, "created": true|false}created が偽なら「同名のTagが見つかったため、既存のTagを選択しました。」と出る。 どちらの場合もTagは選択済みになり、作業は止まらない。 作成に成功したときだけ、受信箱と全体マップの控えを捨てる関数が呼ばれる。

ワークフロー図

ブラウザ
Tag作成API
Notion API
5-1 本文を2文字の並びの集合にする
5-2 Tagごとに点数を出し上位3件を選ぶ
5-3 検索窓に入力があれば推薦を止める
5-4 POST /api/tags(新規作成時のみ)
5-5 Tag DBを全件取得して同名を照合
5-6 (無ければ)ページを作成
5-7 作成結果を検証(ずれたら502)
5-8 作ったか見つけたかの区別つきで返す

6. この分解から見えること

  • 点数の設計に、作者の判断がそのまま出ている。 「そのまま含まれていれば140点」が最大の加点で、「整理用なら45点減点」が唯一の減点。 この2つだけで順位のほとんどが決まる。 残りの項目は同点のときの並び替えに近い働きしかしていない。
  • 整理用Tagの一覧が、名前で直接書かれている。 「あとで読む」「本」「読みたい本、ブログ」「読みたい本・ブログ」の4つ。 最後の2つは中黒と読点の違いだけで、Notion側に表記ゆれのTagが実在することが窺える。 将来Tagを増やしたら、この一覧も直さないと減点が効かない。
  • 2種類の正規化を使い分けている。推薦では記号も空白も全部消し、 Tagの同名判定では記号を残す。「似ているか」と「同じか」は別の問題という理解が コードに反映されている。
  • 作成の照合が「検知するだけ」なのは、このアプリ全体の方針。 5番も8番も9番も、書いたあと読み直して照合し、合わなければ 502元に戻す処理はどこにも無い。Notionが正本なので、 直すのはNotion側で人がやる、という割り切り。
  • Tagを作るのに全件取得が必要。1つ作るために毎回Tag DBを全部取り直す。 件数が増えるほど「Tagを作る」だけの操作が重くなる。 2番の控えを使い回さず、必ず取り直すのは正しさのためだが、代償はある。

7. 失敗時の挙動

  • 名前が空/100文字超:400。Notionへは行かない。
  • Tag DBが共有されていない:Notionの 404 がそのまま返り、 画面のTag作成欄の下に赤い文字で出る。推薦や他の操作は止まらない。
  • 作成後の検証に失敗:502Notion側にはTagが作られたまま残る可能性がある。 画面には「Notion側を確認してください。」と出るだけで、自動では消さない。
  • 同名が同時に2つ作られた場合:照合と作成の間に鍵が無いので、 2人(または2つのタブ)が同時に同じ名前を作ると両方作られうる。 8番のようなノート単位の待ち行列は、Tag作成には掛かっていない。
  • どこまで進んでから失敗すると何が残るか: 5-5 までなら何も残らない。5-6 を過ぎて 5-7 で落ちると、Tagだけが残る。

8. 未確認事項

  • 点数の各係数(140/85/65/45など)が、実際の使用感から調整されたものか、最初の見当のままか
  • 整理用Tagの4つが、いま実際にNotion側に存在するか(表記ゆれの2つが両方生きているか)
  • おすすめを3件にしている根拠
  • Tag作成に待ち行列が無いのが、実害が無いという判断なのか、単に手当てされていないのか
  • 作成後の検証に失敗したTagが、Notion側でどう扱われているか

※ 2026年8月14〜15日時点の zettelkasten-inbox のプログラムを読んで作成しました。過去の設計資料は参照していません。

※ 番号は全体図・この解説・シーケンス図で共通です。工程番号は「ブロック番号-連番」で書いています。

全体図へ戻る / ブロック目次へ

akuramochi1.com — personal tools for learning and thinking.