Daimon は、投稿テキストの意味ベクトルと POV (Point of View) タグを使って、価値観の近さや「遠いけれど共通点がある」投稿を見つける SNS プロトタイプです。
単なるキーワード検索ではなく、以下を組み合わせます。
- 投稿本文を Sentence Transformers で 384 次元ベクトルにする
- Qdrant で近傍検索して候補投稿を取る
- PostgreSQL を正本として本文、ユーザー、POV、いいね、コメントを保持する
- Sense-Distance ランキングで、近い投稿だけでなく bridge 投稿も混ぜる
スタックは Go 中心で、Python は ML が本当に必要なところ(ml-service/: embedding +
spaCy POV 抽出)だけに絞っています。API・シード・スキーマ管理はすべて Go です。
compose.yml が PostgreSQL / Qdrant / Redis / ML(:8001) / Go API(:8000) を起動します。
スキーマは Go API が起動時に冪等にブートストラップ(CREATE TABLE IF NOT EXISTS)するので、
別途のマイグレーション手順はありません。テストデータは Go のシーダ(api/cmd/seed)で投入します。
| Path | 役割 |
|---|---|
frontend/ |
React + Vite + TypeScript の UI |
api/ |
Go の HTTP API(認証・投稿・検索・タイムライン・ランキング)+ cmd/seed・cmd/batch |
ml-service/ |
唯一の Python。embedding と POV 抽出だけを担当 |
docs/ |
共有ドキュメント。*.local.md は gitignore される詳細メモ用 |
compose.yml |
PostgreSQL / Qdrant / Redis / ML / Go API のローカル構成 |
Frontend (:5173)
|
| REST
v
Go API (:8000)
| |
| SQL | HTTP
v v
PostgreSQL ML service (:8001)
正本DB embedding / POV extraction
|
| post ids, metadata
v
Qdrant (:6333)
vector search index
重要な考え方はこれです。
- PostgreSQL: System of Record。消えてはいけないデータ、関係、集計の正本
- Qdrant: System of Search。再構築できる検索インデックス
- ML service: Go API から分離した CPU 推論プロセス
- Redis: 任意の read-model cache。未設定なら no-op
投稿作成時は、本文と POV を PostgreSQL に保存し、embedding が取れた場合だけ Qdrant に upsert します。Qdrant 書き込みは best-effort で、壊れても PostgreSQL から再生成できる前提です。
迷ったらこれです。
make freshこれはローカルの Docker/Podman volume を消して、DB / Qdrant / Redis / ML / Go API を build し、seed data を入れて、frontend を起動します。
毎回データを消したくない場合:
make docker
make web開く URL:
- Frontend: http://localhost:5173
- API health: http://localhost:8000/health
- Qdrant dashboard: http://localhost:6333/dashboard
seed 済みユーザーは seeduser1@example.com / password123 のような @example.com アカウントです。
Go API(:8000)と frontend(:5173)をホストで動かす場合(依存は compose):
make all # = make dev: deps-up → Go API + frontend個別に進める場合:
make deps-up # db + qdrant + redis + ml を compose で起動
make seed # Go シーダでテストデータ投入(ML 必須・実埋め込み)
make dev # Go API + frontendGo API だけをホストでデバッグしたい場合:
make deps-up
cd api
go run ./cmd/server別ターミナルで:
make web投稿作成:
- UI が
POST /postsを呼ぶ - API が本文と POV を validation する
- API が ML service の
POST /embedに本文を渡す - ML service が
paraphrase-multilingual-MiniLM-L12-v2(多言語)で 384 次元 vector を返す - API が PostgreSQL に投稿と POV を保存する
- API が Qdrant
postscollection に{post_id, user_id, tags, created_at}と vector を upsert する
タイムライン:
- UI が
POST /posts/timelineを呼ぶ - API が query text を embedding する
- Qdrant から類似候補を 100-200 件取る
- PostgreSQL から本文、POV、like/comment count を bulk load する
- ユーザー自身の投稿 vector から centroid を作る
rank_by_sense_distance/RankBySenseDistanceで並べ替える- UI に
match_reason.reason,sense_distance,is_bridgeを返す
ランキングの中心式:
near = cos(user_centroid, post_vector)
far = 1 - near
bridge = far * has_common_pov
base = alpha * near + (1 - alpha) * bridge + 0.15 * has_common_pov
最後に MMR (Maximal Marginal Relevance) で似すぎた候補を間引きます。
共有用:
- docs/README.md
- docs/PRODUCT_AND_UX.md
- docs/THEORY_TO_FEATURES.md
- docs/ARCHITECTURE.md
- docs/ROADMAP.md
- docs/CONTENT_MODERATION.md
- docs/CONCEPT_AND_RESEARCH.txt
- docs/DAIMON_PROJECT_DESCRIPTION.txt
ローカル詳細メモ:
docs/ARCHITECTURE.local.mddocs/ML_VECTOR.local.md
*.local.md は .gitignore 済みです。実装の細かい読み解き、試行錯誤、環境固有のメモはここに置けます。
make fresh # まっさらから Docker/Podman stack + seed + frontend
make docker # Docker/Podman stack 起動
make web # frontend のみ起動
make docker-logs # api / ml logs
make seed # realistic seed data
make seed-large # synthetic vectors で高負荷 seed
make down # compose down
make clean # venv / node_modules も削除CI は GitHub Actions の .github/workflows/ci.yml で管理します。
api:go test ./...、go vet ./...、cmd/server/cmd/batchの buildfrontend:pnpm install --frozen-lockfile、Biome check、Vite production buildml-service:uv sync --locked、ruff check、pytest、FastAPI app の import smoke testdeploy-config:compose.yml/cloudbuild.yamlの検証と API / ML Docker image build
依存更新は .github/dependabot.yml が frontend(npm) / api(gomod) / ml(uv) / GitHub Actions / Docker を管理します。
本番 deploy は cloudbuild.yaml から Cloud Run に出します。
- frontend: Vercel (
vercel.json) - API: Cloud Run service
daimon-api - ML: Cloud Run service
daimon-ml
Cloud Build trigger には少なくとも _QDRANT_URL を設定してください。API deploy は Secret Manager の database-url と qdrant-api-key を参照します。ML service は API からだけ呼ぶ前提で、Cloud Run ingress は internal にしています。
現時点では Bazel は導入していません。Go / pnpm / uv / Docker の境界が明確で、Bazel を入れるより GitHub Actions の job 分割と Cloud Build の image build に寄せる方が運用が軽いです。モノレポが大きくなり、生成物や多言語キャッシュを統一したくなった段階で再検討します。
0BSD. You can use, copy, modify, and distribute this project for almost any purpose.