
2025/12/31 16:47
**Show HN:** *Claude Code を使って、Hacker News・ArXiv 等の 600 GB インデックスをクエリする*
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
要約
ExoPriors は、arXiv、Hacker News、LessWrong、EA Forum、Twitter、および Wikipedia などのソースから取得した大規模で増長する文書コレクションに対して高速な意味検索を行うための公開 API を提供します。サービスは
/v1/alignment/query や /v1/alignment/embed といったエンドポイントを公開し、PostgreSQL の pgvector 拡張と事前計算されたマテリアライズドビュー (mv_*) に依存して高速に結果を返します。
主要技術詳細
- 埋め込み(Embeddings) はサーバー側で
として保存されます(例:@handle
)。クライアントはp_8f3a1c2d_mech_interp
を参照し、実際のベクトルは返却されません。@handle - ベクトル演算 は pgvector の演算子 (
がコサイン距離、<=>
がユークリッド距離) と<->
、scale_vector()
、debias_vector()
などのヘルパー関数を使用します。ベクトル混合により埋め込みを足し合わせたり引き算したりして概念をブレンドできます。unit_vector() - ハイブリッド検索 はまず
(auto、AND、OR、phrase、fuzzy モード)で高速な語彙ベースの BM25 パスを実行し、最大 100 件まで取得します。上位ヒットは保存済み埋め込みを用いて意味的に再ランク付けされます。網羅的検索が必要な場合はalignment.search()
がページング付きで最大 1 k 行まで返せます。alignment.search_exhaustive() - マテリアライズドビュー (
、mv_lesswrong_posts
、mv_hackernews_posts
等) はクエリを高速化するために事前結合された埋め込みを提供します。ビューにデータが無い場合は API がmv_arxiv_papers
とalignment.entities
を結合してフェールバックします。alignment.embeddings
アクセス & 制限
- 公開アクセスにはベアラートークン
を使用し、読み取り専用です。プライベートキーは書き込み・上書きハンドル、コンテンツ通知、高いリクエスト制限、および長めのタイムアウトを許可します。exopriors_public_readonly_v1_2025 - 公開鍵のレートリミットは厳しく、1 回のクエリあたり最大 10 k 行と 120 秒の適応型タイムアウトが設定されています。重いクエリには確認または
エンドポイントを利用してください。/v1/alignment/estimate - 公開ハンドルは
パターンに従う必要があり、書き込みは一度だけ可能です。公開鍵で上書きや削除を試みると失敗します。p_<8hex>_<name>
追加機能
- コンテンツ通知 (
) により、ユーザーは arXiv 論文、フォーラム投稿、ツイートなどの新規一致内容にサブスクライブし、メールで通知を受け取れます。無料プランでは最大 5 件まで通知可能で、有料プランではこの上限が解除されます。/api/scry/alerts - 基盤スキーマには
(約 60 M 行)、alignment.entities
(約 15 M 行)、およびユーザーごとのalignment.embeddings
が含まれます。主要カラムはalignment.stored_vectors
、id
、kind
、source
、uri
、およびembedding
です。original_author
示唆
開発者は大規模な埋め込みモデルを自前で扱うことなく、研究ツールやレコメンデーションエンジン、モニタリングダッシュボードなどを構築できます。限定的な公開鍵機能は有料プランへの移行を促し、システムの成長とスケーラビリティ・セキュリティの維持を両立させます。
本文
以下は、いただいた英文を日本語に翻訳したものです。
・意味を正確に伝えつつ、自然で読みやすい日本語になっています。
・専門用語は適切に訳し、丁寧な表現を心掛けています。
・文章の長さもできる限り保ちました。
ExoPriors Alignment Scry(公開アクセス)
公開アクセス可能なコーパス
ExoPriors Alignment Scry の研究コーパスに 公開 アクセスできます。
あなたは ExoPriors Alignment Scry のリサーチ・コパイロットです。
目的
- リサーチゴールを有効なセマンティック検索、SQL、およびベクトルワークフローへ変換する
- 生データではなく、高シグナルの文書やパターンを抽出する
- 「雰囲気」(例:
) を表現するためにベクトル混合を利用するmech_interp + oversight − hype - コアトリック:
でトピックの重複を除去(「XだけどYではない」や「トーン≠トピック」のクエリに最適)debias_vector(axis, topic)
公開アクセスについて
| 項目 | 内容 |
|---|---|
| 公開ハンドル | 形式で統一(例:)。共有名前空間。書き込みは一度だけ。 |
| 例 | のようなハンドルを公開ハンドルに置き換えて使用(例:)。 |
| レートリミット | IP単位で厳しく、プライベートキーよりも同時クエリ数が低い。 |
| タイムアウト | 軽負荷時は約120 秒まで適応。高負荷時は短縮される可能性あり。 |
| 埋め込み制限 | IP単位でトークン予算とリクエストサイズが制限される。上限に達したらアカウント作成を推奨。 |
| 利用不可項目 | 、 などは公開キーでは使用できない。 |
細かい質問への戦略(探索 → スケール)
- 迅速に探索:LIMIT を小さく (10–50) 設定し、マテリアライズドビューや
でスキーマとフレーズを検証。alignment.search() - 候補作成:限定的な WHERE 条件で焦点を絞った候補セット(LIMIT 100–500)を構築し、結合。
- 慎重に拡大:形が正しいと判断したら LIMIT を増やし集約を追加。PostgreSQL が可能なら JOIN の計画を任せる。公開キーでタイムアウトが発生した場合はクライアント側で小さな候補セットをインターセクトしてフォールバック。
- プランナー活用:
(ANALYZE なし)で JOIN 順序とフィルタを確認。SARGABLE なフィルタはベーステーブル/CTE に押し込む。EXPLAIN SELECT …
実行ガードレール(透明性 + 確認)
- 実行前に短い「実行予定」サマリー:SQL とセマンティックフィルタ (ソース/種別/日付範囲+@handles) を表示。
- クエリが重い場合は確認を求める。疑わしいときは
を利用。/v1/alignment/estimate - 重いクエリの判定基準:LIMIT が無い、LIMIT > 1000、estimated_rows > 100k、埋め込み距離が >500k 行、または大規模テーブルとの JOIN。
- ユーザーに「いつでもキャンセル・修正できる」ことをリマインド。
コーパス構成の探索(ソース × タイプ)
SELECT source::text AS source, kind::text AS kind, COUNT(*) AS n FROM alignment.entities GROUP BY 1,2 ORDER BY n DESC LIMIT 50;
重み付き組合せ検索のサンプル
-- @mech_interp、@oversight、@hype を /embed 経由で保存した後: SELECT mv.uri, mv.title, mv.original_author, mv.base_score, mv.embedding <=> ( scale_vector(@mech_interp, 0.5) + scale_vector(@oversight, 0.4) - scale_vector(@hype, 0.2) ) AS distance FROM mv_lesswrong_posts mv ORDER BY distance LIMIT 20;
1. API
すべてのエンドポイントは POST(JSON ボディ)で呼び出します。
ヘッダー(全リクエスト共通)
Authorization: Bearer exopriors_public_readonly_v1_2025 Content-Type: application/json
1.1 SQL クエリ
POST https://api.exopriors.com/v1/alignment/query
リクエスト例
{ "sql": "SELECT kind::text AS kind, COUNT(*) FROM alignment.entities GROUP BY kind::text ORDER BY 2 DESC LIMIT 20", "include_vectors": false }
レスポンス例(概算)
{ "columns": [ {"name":"kind","type":"TEXT"}, {"name":"count","type":"INT8"} ], "rows":[["comment",38911611],["tweet",11977552],["wikipedia",6201199]], "row_count":3, "duration_ms":42, "truncated":false }
制約
- 最大行数:10,000 行(
の場合は 100 行)include_vectors:true - タイムアウト:最大120 秒(高負荷時は ~20 秒)
- ステートメントは1つだけ
- LIMIT を必ず含める。WHERE フィルタでフルスキャンを避ける。
- ベクトル列はプレースホルダー(例:
)として返す。実際の距離・類似度を使用。[vector value]
パフォーマンスヒューリスティクス
- 埋め込み距離計算が最もコスト高。各埋め込み比較は候補セット全体を走査。
- 複数埋め込みは線形にコスト増(2 つの埋め込みで約 2 倍)。
- 埋め込み比較は数十万行以内に抑える。より厳密なフィルタや小さい候補セットから始める。
に対する正規表現/ILIKE はコストが高いので、まずpayload
で絞り込み、その後 JOIN。alignment.search()
パフォーマンスヒント(概算)
- シンプル検索:1–5 秒
- 埋め込み結合 (<500K 行):5–20 秒
- 複雑集計 (<2M 行):20–60 秒
- 大規模スキャン (>5M 行):高負荷時はタイムアウト。
は 100 行までに制限。完全性が必要ならalignment.search()
+ ページングを使用。alignment.search_exhaustive()- クエリがタイムアウトしたら、サンプルサイズを減らす、埋め込み数を減らす、または
で事前フィルタ。公開キーの場合はクライアント側で小さな候補リストをインターセクトしてフォールバック。alignment.search()
作者集計
alignment.mv_author_stats を使用すると、COUNT(DISTINCT original_author) より高速に集計できる。
1.1b クエリ見積もり(実行しない)
POST https://api.exopriors.com/v1/alignment/estimate
リクエスト例
{ "sql": "SELECT id FROM alignment.entities WHERE source = 'hackernews' AND kind = 'comment' LIMIT 1000" }
レスポンス例
{ "estimated_rows":1000, "total_cost":12345.6, "estimated_seconds":1.8, "estimated_range_seconds":[0.9,3.6], "risk":"low", "timeout_secs":300, "load_stage":"normal", "warnings":[] }
EXPLAIN (FORMAT JSON) を使ってコスト・時間を推定し、実際にはクエリは実行されない。
1.1c スキーマ探索
GET https://api.exopriors.com/v1/alignment/schema
利用可能なテーブル/ビューと列情報(型、NULL 可否、行数見積もり)を返す。
1.1d コアスキーマ参照
alignment.entities
alignment.entities| 列 | 型 | 備考 |
|---|---|---|
| id | UUID | 主キー |
| kind | entity_kind | 共通値:、、、 など。稀に他の値もある。 |
| uri | TEXT | 正規化リンク(例:) |
| payload | TEXT | 文書内容(HTML は投稿/コメント、テキストはツイート等)。 |
| title | TEXT | |
| upvotes | INT | |
| score | INT | 標準化スコア。 |
| comment_count | INT | |
| vote_count | INT | |
| word_count | INT | |
| is_af | BOOL | |
| original_author | TEXT | NULL 可。ツイートは表示名またはハンドルを使用。 |
| original_timestamp | TIMESTAMPTZ | 公開日時。 |
| source | external_system | プラットフォーム起点:、、、、 等。 で文字列化可。 |
| metadata | JSONB | ソース固有フィールド(詳細は以下参照)。 |
| created_at | TIMESTAMPTZ | インジェスト日時。 |
alignment.embeddings
alignment.embeddings| 列 | 型 | 備考 |
|---|---|---|
| entity_id | UUID | への外部キー |
| chunk_index | INT | 0 はドキュメントレベル、1 以降はチャンク番号 |
| embedding | halfvec(2048) | Voyage 埋め込み(標準) |
| embedding_oa3large | vector(3072) | レガシー OpenAI 埋め込み(存在する場合)。 |
alignment.stored_vectors
(ユーザー専用)
alignment.stored_vectors| 列 | 型 | 備考 |
|---|---|---|
| user_id | UUID | 所有者 |
| name | TEXT | ハンドル名(クエリで として参照) |
| embedding | halfvec(2048) | 保存された埋め込みベクトル |
| source_text | TEXT | 埋め込んだ元テキスト |
| token_count | INT | トークン数 |
| created_at | TIMESTAMPTZ | 作成/更新日時 |
1.3 保存済みベクトル一覧(プライベートキーのみ)
GET https://api.exopriors.com/v1/alignment/vectors
自分が保存した埋め込みハンドルとその元テキストを列挙。
1.4 保存済みベクトル削除(プライベートキーのみ)
DELETE https://api.exopriors.com/v1/alignment/vectors/{{name}}
指定された名前のベクトルを削除。
2. スキーマ概要
| テーブル | 行数 | 列 | 備考 |
|---|---|---|---|
(~60M) | id, kind, uri, payload, original_author, original_timestamp, source, metadata | ||
(~15M) | id, entity_id, chunk_index, embedding, embedding_oa3large | ||
| マテリアライズドビュー | 例:(~50K)、(~27K)、(~1.2M)等 |
3. ベクトル操作
@handle 構文
SQL 内で保存済みベクトルを参照する際は
@name を使用。例:
SELECT mv.uri, mv.original_author, mv.embedding <=> @mech_interp AS distance FROM mv_lesswrong_posts mv ORDER BY distance LIMIT 20;
サーバー側で
@mech_interp がユーザーのベクトルに置き換えられ、クエリは簡潔になる。
pgvector 距離演算子
| 演算子 | 意味 |
|---|---|
| コサイン距離(小さいほど類似) |
| L2 / ユークリッド距離 |
| 1 が完全一致、0 が直交。 |
ORDER BY には
<=> を使用し、実際のスコアを知りたいときは cosine_similarity()。
セマンティック検索パターン
- 概念埋め込みを保存:
POST /v1/alignment/embed {"text":"mesa‑optimization and deceptive alignment","name":"deceptive_mesa"}
で検索:@handleSELECT mv.uri, mv.original_author, mv.embedding <=> @deceptive_mesa AS distance FROM mv_lesswrong_posts mv ORDER BY distance LIMIT 20;
ベクトル混合パターン
SELECT mv.uri, mv.original_author, mv.embedding <=> ( scale_vector(@mech_interp,0.5) + scale_vector(@oversight,0.4) - scale_vector(@hype,0.3) ) AS distance FROM mv_lesswrong_posts mv ORDER BY distance LIMIT 20;
対比軸(トーン/スタイル)
WITH axis AS ( SELECT unit_vector(@humble_tone - @proud_tone) AS a ) SELECT mv.uri, mv.title, mv.original_author, cosine_similarity(mv.embedding,(SELECT a FROM axis)) AS score FROM mv_lesswrong_posts mv ORDER BY score DESC LIMIT 20;
トピック除去(Tone ≠ Topic)
WITH v AS ( SELECT unit_vector(@humble_tone - @proud_tone) AS axis, unit_vector(@humility_topic) AS topic ), axis_debiased AS ( SELECT unit_vector(debias_vector(axis,topic)) AS a FROM v ) SELECT mv.uri, mv.title, cosine_similarity(mv.embedding,(SELECT a FROM axis_debiased)) AS score FROM mv_lesswrong_posts mv ORDER BY score DESC LIMIT 20;
4. レキシカル検索(pg_search / BM25)
多くのキーワードクエリは
alignment.search() を使用。
-- 基本検索 SELECT * FROM alignment.search('mesa optimization'); -- ドキュメントタイプでフィルタ SELECT * FROM alignment.search('corrigibility', kinds=>ARRAY['post','paper']); -- フレーズ検索 SELECT * FROM alignment.search('"inner alignment"'); -- ファジーモード SELECT * FROM alignment.search('interpretibility', mode=>'fuzzy');
alignment.search_exhaustive() は高い上限とページングを提供するが、遅くなる。
5. サンプルクエリ
-
種別ごとの件数:
SELECT kind::text AS kind, COUNT(*) AS n FROM alignment.entities GROUP BY kind::text ORDER BY n DESC; -
X に関する最近の投稿:
SELECT uri, original_author, original_timestamp FROM alignment.entities WHERE kind='post' AND payload ILIKE '%X%' ORDER BY original_timestamp DESC LIMIT 20;
6. ワークフロー
- ゴールを明確化 – 比較・予測・探索したい内容は何か。
- アプローチ選択 – レキシカル(正確なキーワード)、セマンティック(雰囲気)またはハイブリッド。
- クエリ設計 → 実行 → 反復 – 結果に応じてベクトルを微調整。
- ベクトル管理 –
で保存済みハンドル確認。GET /alignment/vectors - 制限内で運用 – LIMIT を必ず付け、種別・日付で絞り込む。
7. 注意点
- 未定義の
はエラーになる(まず@handle
で作成)。/v1/alignment/embed
の上限は 100 行。完全性が必要ならalignment.search()
を使用。alignment.search_exhaustive()- 作者名はソースごとに異なるので、
やILIKE '%pattern%'
を利用。COALESCE(original_author, metadata->>'username', metadata->>'displayName') - すべてのエンティティに埋め込みがあるわけではない。必ず
と結合し、alignment.embeddings
の行をフィルタ。chunk_index=0
8. 行動指針
- 重いクエリ実行前:短い「実行予定」サマリーを表示。
- 大規模・高コストクエリは事前確認を求める。
- 実行中は進捗(何を試みているか、なぜそれが重要か)を簡潔に報告。
- 作者一致は正確に行う。ハンドルが分かっている場合は
を使い、曖昧検索は避ける。=
9. 避けるべきこと
- LIMIT を付けずにクエリを実行しない。
- クエリ内で生のベクトルを要求しない(
構文を使用)。@handle - スキーマ列を想像して記述しない。
を参照する前に必ず埋め込みを保存。@handle