Asopitech With · ノートアプリ
Evernote Web Clipper with Alopex DB
Evernote Web Clipperは、ノートアプリのEvernoteに、Webページや記事をノートとして保存する機能です。これをAlopex DBを使って再現すると…?
更新: 2026/10/12
どんなサービスか
EvernoteのWeb Clipperは、Webページ、記事、PDFをノートとして保存します。保存したものにはタグを付け、ノートブックに分けて、キーワードで探せます。扱うデータは、ページの本文、URL、タグ、ノートブックです。
データの置き場所
- SQLテーブル:クリップ、ノートブック、タグをテーブルに持ちます。
- JSON:ページのタイトル、URL、取得した日時など、ページごとに形が違う情報をJSONの列に持ちます。
- 全文検索:本文に全文検索の索引を張り、キーワードで探します。
- ベクトル:本文の埋め込みをベクトル列に持ち、「去年保存した、旅行の宿の記事」のような問いで探します。
ページの取り込みと埋め込みの計算は、アプリが行います。
配置の形
Alopex DBを、端末とデスクトップのアプリに組み込みます。クリップは端末の中の1つのファイルに入ります。チームで共有するときは、同じSQLのまま、Alopex DBをサーバーとして動かします。
Alopex DBが合う理由
クリップは、あとで見つけられて初めて役に立ちます。Alopex DBは、決まった形のテーブルと、ページごとに違うJSONを同じSQLで扱い、キーワードと意味の両方で探せます。
コードで見る
クリップとタグをテーブルに持ち、キーワード(本文に語を含む)と意味(埋め込みの近さ)の両方で探します。探す部分だけを取り出したコードです。
import alopex
import numpy as np
# 端末のアプリに組み込む想定
db = alopex.Database.open("evernote.alopex")
# クリップ(本文+埋め込み)とタグを持つ。埋め込みはアプリが作る
db.execute_sql("""
CREATE TABLE IF NOT EXISTS clips (
id INTEGER PRIMARY KEY,
title TEXT,
url TEXT,
body TEXT,
embedding VECTOR(4)
)
""")
db.execute_sql("""
CREATE TABLE IF NOT EXISTS clip_tags (
clip_id INTEGER,
tag TEXT
)
""")
# クリップを保存する(ベクトルは説明用の小さな値。実際はモデルの埋め込み)
clips = [
(1, "京都の宿", "https://ex.com/kyoto", "旅行で泊まった宿の記事", [0.9, 0.1, 0.0, 0.0], "旅行"),
(2, "確定申告のやり方", "https://ex.com/tax", "税金の手続きのまとめ", [0.0, 0.0, 0.9, 0.1], "お金"),
]
for cid, title, url, body, emb, tag in clips:
db.execute_sql(
"INSERT INTO clips (id, title, url, body, embedding) VALUES (?, ?, ?, ?, ?)",
[cid, title, url, body, np.array(emb, dtype=np.float32)],
)
db.execute_sql("INSERT INTO clip_tags (clip_id, tag) VALUES (?, ?)", [cid, tag])
# キーワードで探す(本文に語を含む)
for row in db.execute_sql("SELECT title FROM clips WHERE body LIKE ?", ["%宿%"]):
print("keyword:", row["title"])
# 意味で探す(「旅行」に近い埋め込みを上位に)
query = np.array([1.0, 0.0, 0.0, 0.0], dtype=np.float32)
rows = db.execute_sql(
"SELECT title, vector_similarity(embedding, ?, 'cosine') AS score FROM clips ORDER BY score DESC LIMIT 1",
[query],
)
for row in rows:
print("semantic:", round(row["score"], 3), row["title"])語での検索と、埋め込みの近さでの検索を、同じSQLで扱えます。言葉が思い出せなくても、意味の近さでたどり着けます。
決まった形のテーブルとページごとのJSONを同じSQLで扱うAlopex DBは、クリップのアプリによく合います。まずはクイックスタートをのぞいてみてください。