Skip to content

Latest commit

 

History

History
400 lines (310 loc) · 16.4 KB

File metadata and controls

400 lines (310 loc) · 16.4 KB

StaticFlow

CLI 使用手册

本地优先的动态博客系统:后端在本地运行,通过本地 Nginx + pb-mapper 对外暴露 HTTPS API;文章与图片统一写入 LanceDB,由前端直接请求云端映射端点访问。

除了内容系统本身,StaticFlow 当前还内置了一套对外 LLM Access 能力:Codex 的 OpenAI-compatible 网关、Kiro 的 Anthropic-compatible 网关、provider 级上游代理解析、可配额度的 gateway key,以及统一的 usage 账本。实现细节见 docs/llm-access-and-kiro-gateway-implementation.md

核心理念

"Don't build agents, build skills instead."Anthropic Expert Talk

本项目不开发独立 AI Agent。

策略:

  • 智能能力:交给 Claude Code/Codex + skills
  • 工程工具:CLI 只做 LanceDB 读写

项目结构

static-flow/
├── frontend/     # Yew WASM 前端
├── backend/      # Axum 后端(LanceDB 查询层)
├── shared/       # 共享类型
├── cli/          # LanceDB CLI 工具
└── content/      # 示例 Markdown 与图片

数据仓库(Hugging Face)

static-flow 对应网站:https://acking-you.github.io/

本项目将运行时数据放在两个 Hugging Face 数据集仓库和一个本地音乐库中管理:

  • 当前本地数据根目录:/mnt/wsl/data4tb/static-flow-data

  • Content DB(内容主库 + 请求表 + 交互镜像 + LLM gateway)

    • HF 数据集仓库:LB7666/my_lancedb_data
    • 远端地址:git@hf.co:datasets/LB7666/my_lancedb_data
    • 本地数据目录:/mnt/wsl/data4tb/static-flow-data/lancedb
    • 表:articles, images, taxonomies, article_views, api_behavior_events, article_requests, article_request_ai_runs, article_request_ai_run_chunks, interactive_pages, interactive_page_locales, interactive_assets, llm_gateway_keys, llm_gateway_usage_events, llm_gateway_runtime_config, llm_gateway_proxy_configs, llm_gateway_proxy_bindings, llm_gateway_token_requests, llm_gateway_account_contribution_requests, llm_gateway_sponsor_requests
  • Comments DB(评论审核与 AI 运行记录)

    • HF 数据集仓库:LB7666/static-flow-comments
    • 远端地址:git@hf.co:datasets/LB7666/static-flow-comments
    • 本地数据目录:/mnt/wsl/data4tb/static-flow-data/lancedb-comments
    • 表:comment_tasks, comment_published, comment_audit_logs, comment_ai_runs, comment_ai_run_chunks
  • Music DB(本地优先音乐库)

    • 本地数据目录:/mnt/wsl/data4tb/static-flow-data/lancedb-music
    • 表:songs, music_plays, music_comments, music_wishes, music_wish_ai_runs, music_wish_ai_run_chunks

推荐流程:

  1. 先通过 sf-cli 写入/更新数据(保证 schema 与索引一致)。
  2. 再用 Git 对数据快照做版本提交。
  3. 最后 push 到 Hugging Face 数据集远端。

快速配置(SSH + Git Xet):

# 1) 准备 SSH key,并把公钥添加到 https://huggingface.co/settings/keys
ls ~/.ssh/id_ed25519.pub || ssh-keygen -t ed25519 -C "LB7666@hf"
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
mkdir -p ~/.ssh
ssh-keyscan -H hf.co >> ~/.ssh/known_hosts
chmod 600 ~/.ssh/known_hosts
ssh -T git@hf.co

# 2) 将本地数据目录绑定到 HF 数据集远端
cd /mnt/wsl/data4tb/static-flow-data/lancedb
git init -b main
git remote remove origin 2>/dev/null || true
git remote add origin git@hf.co:datasets/LB7666/my_lancedb_data
git fetch origin main
git checkout -B main origin/main

# 3) 安装并启用 Git Xet
bash <(curl -fsSL https://raw.githubusercontent.com/huggingface/xet-core/main/git_xet/install.sh)
export PATH="$HOME/.local/bin:$PATH"
git xet install
git xet track "*.lance"
git xet track "*.txn"
git xet track "*.manifest"

# 4) 日常同步
git add -A
git commit -m "data: sync $(date '+%F %T')" || echo "no changes"
git push origin main

说明:执行 git xet track 后,.gitattributes 中仍出现 filter=lfs 属于正常现象, 这是 Hugging Face 的 Xet 兼容传输实现方式。

部署模式

模式 A:自托管(推荐)

后端同时提供 API 和前端静态文件,通过 pb-mapper + Caddy 对外暴露 HTTPS。

浏览器 -> https://ackingliu.top
       -> Caddy (TLS) -> pb-mapper tunnel -> 本地 backend (127.0.0.1:39080)
                                              ├── /api/*        → API handler
                                              ├── /posts/:id    → SEO 注入页
                                              ├── /sitemap.xml  → 动态 sitemap
                                              └── /*            → 前端静态文件 (SPA fallback)

启动方式:

# 1. 构建前端(API_BASE=/api,同源请求)
bash scripts/build_frontend_selfhosted.sh

# 2. 启动后端(自动 serve 前端静态文件)
bash scripts/start_backend_selfhosted.sh --daemon

# 日志查看
tail -f /tmp/staticflow-backend.log

# 前端代码改动后需要重新构建 + 重启后端(后端启动时缓存 index.html)
bash scripts/build_frontend_selfhosted.sh
bash scripts/start_backend_selfhosted.sh --daemon

模式 B:本地开发(trunk 热重载)

前端由 trunk dev server 提供,支持热重载;trunk 自动代理 /api 到后端。

# 1. 启动后端
bash scripts/start_backend_selfhosted.sh

# 2. 启动前端(trunk serve,自动代理 /api -> localhost:39080)
bash scripts/start_frontend_with_api.sh --open

后端: http://127.0.0.1:39080 | 前端: http://127.0.0.1:38080

模式 C:GitHub Pages(纯前端)

前端部署到 GitHub Pages,API 通过 pb-mapper 隧道访问本地后端。 CI 自动构建,STATICFLOW_API_BASE 由 GitHub repo variables 配置。

浏览器 -> https://acking-you.github.io (GitHub Pages 静态文件)
       -> fetch(STATICFLOW_API_BASE/api/...) -> pb-mapper -> 本地 backend

参考配置:

  • 自托管 Caddy:云端 /etc/caddy/Caddyfile
  • GitHub Pages CI:.github/workflows/deploy.yml
  • 旧版 Nginx 配置:deployment-examples/

LLM Access / Kiro Access

自托管模式下,StaticFlow 现在不只是内容站点,也会对外暴露两条公开接入面:

  • /llm-access:Codex 接入页,底层走 OpenAI-compatible 的 /api/llm-gateway/v1
  • /kiro-access:Kiro 接入页,底层走 Anthropic-compatible 的 /api/kiro-gateway

当前实现的共性:

  • 两条接入线都由 StaticFlow backend 代理,不直接暴露上游真实账号
  • 上游代理解析统一走共享的 provider 级代理注册表
  • key、runtime config、proxy config、proxy binding、usage event 都统一落在 LLM gateway 存储里
  • 详细运行时实现、代理优先级、账号路由、缓存刷新和排障路径见 docs/llm-access-and-kiro-gateway-implementation.md

如果你只关心 Codex 接入,公开页会额外给出:

  • 已带 /v1 的 OpenAI-compatible Base URL
  • 可公开分发的 API key
  • 现成的 Codex provider 配置片段
  • auth.json 备用写法和 curl / Python 示例

推荐的 Codex provider 配置如下:

model_provider = "staticflow"

[model_providers.staticflow]
name = "OpenAI"
base_url = "https://your-host/api/llm-gateway/v1"
wire_api = "responses"
requires_openai_auth = true
supports_websockets = false

这个配置的目的,是让 Codex 保持在远端 /responses/responses/compact 路径上工作,避免退回本地兼容路径。

快速开始

# 前置依赖
rustup target add wasm32-unknown-unknown
cargo install trunk

# 编译二进制
make bin-all

# 初始化 LanceDB
cd cli
../target/release/sf-cli init --db-path ../data/lancedb

# --- 自托管模式(推荐) ---
cd ..
bash scripts/build_frontend_selfhosted.sh
bash scripts/start_backend_selfhosted.sh --daemon

# --- 本地开发模式 ---
cd ..
bash scripts/start_backend_selfhosted.sh          # 前台启动后端
bash scripts/start_frontend_with_api.sh --open     # 另一个终端,trunk 热重载

CLI 命令

cd cli

# 编译 CLI 二进制
make bin-cli

# 一键跑完整 CLI 回归测试(docs + images + CRUD + API)
cd ..
./scripts/test_cli_e2e.sh
# 或:BUILD_PROFILE=release ./scripts/test_cli_e2e.sh
cd cli

# 初始化 LanceDB 表结构
../target/release/sf-cli init --db-path ../data/lancedb

# 手动重跑所有应建索引(适合批量导入后)
# - articles.content(全文索引)
# - articles.vector_en / articles.vector_zh(向量索引)
# - images.vector(向量索引)
# - taxonomies 表用于分类/标签元数据(无向量索引)
# - article_views 为 backend 运行时统计表(CLI 无需管理其索引)
../target/release/sf-cli ensure-indexes --db-path ../data/lancedb

# write-article / write-images / sync-notes 默认会自动执行 index-only optimize
# 用于把新写入数据纳入索引覆盖;批量流水线可通过 --no-auto-optimize 关闭

# 写入单篇文章
../target/release/sf-cli write-article \
  --db-path ../data/lancedb \
  --file ../content/post-001.md \
  --date "2026-02-12" \
  --summary "文章摘要" \
  --tags "rust,wasm" \
  --category "Tech" \
  --category-description "Engineering notes about Rust + WASM" \
  --content-en-file ../tmp/content_en.md \
  --summary-zh-file ../tmp/detailed_summary_zh.md \
  --summary-en-file ../tmp/detailed_summary_en.md

# 也可写在 markdown frontmatter 中
# category_description: "Rust 与 WASM 的工程实践"
# date: "2026-02-12"
# content_en: |
# detailed_summary:
#   zh: |
#   en: |
# 若两者同时提供,以 CLI --date 为准。
# `--summary-zh-file` 与 `--summary-en-file` 必须成对提供。

# 批量写入图片
../target/release/sf-cli write-images \
  --db-path ../data/lancedb \
  --dir ../content/images \
  --recursive \
  --generate-thumbnail

# 缩略图实现细节
# - 仅在 --generate-thumbnail 时生成,尺寸由 --thumbnail-size 控制(默认 256)
# - 缩略图统一存为 PNG 二进制到 images.thumbnail
# - 读取 /api/images/:id-or-filename?thumb=true 时,thumbnail 为空会自动回退原图 data

# 同步本地笔记目录(markdown + 图片)
# - 自动把 markdown 中引用的本地图片写入 images 表
# - 自动把 markdown 图片链接改写为 images/<sha256_id>
# - 自动 upsert 文章到 articles 表
# - 自动 upsert 分类/标签元数据到 taxonomies 表
../target/release/sf-cli sync-notes \
  --db-path ../data/lancedb \
  --dir ../content \
  --recursive \
  --generate-thumbnail

# 查询验证
../target/release/sf-cli query --db-path ../data/lancedb --table articles --limit 10
../target/release/sf-cli query --db-path ../data/lancedb --table articles --limit 1 --format vertical

# 数据库风格管理(增删改查 + 索引)
../target/release/sf-cli db --db-path ../data/lancedb list-tables
../target/release/sf-cli db --db-path ../data/lancedb describe-table articles
../target/release/sf-cli db --db-path ../data/lancedb query-rows articles --where "category='Tech'" --columns id,title,date --limit 5
../target/release/sf-cli db --db-path ../data/lancedb query-rows articles --limit 1 --format vertical
../target/release/sf-cli db --db-path ../data/lancedb count-rows articles --where "vector_en IS NOT NULL"
../target/release/sf-cli db --db-path ../data/lancedb update-rows articles --set "category='Notes'" --where "id='post-001'"
../target/release/sf-cli db --db-path ../data/lancedb delete-rows articles --where "id='draft-001'"
../target/release/sf-cli db --db-path ../data/lancedb list-indexes articles --with-stats
../target/release/sf-cli db --db-path ../data/lancedb ensure-indexes
../target/release/sf-cli db --db-path ../data/lancedb optimize articles
../target/release/sf-cli db --db-path ../data/lancedb optimize images
# 一键立即清理孤儿文件(仅 prune,不做全量重写)
../target/release/sf-cli db --db-path ../data/lancedb cleanup-orphans --table images
# 对全部清理目标表统一清理孤儿文件(含 article_views;若不存在会自动跳过)
../target/release/sf-cli db --db-path ../data/lancedb cleanup-orphans

# 核心表结构(sf-cli 管理)
# - articles:文章内容/元数据 + 向量
# - images:图片二进制 + 向量
# - taxonomies:分类/标签元数据(`kind`、`key`、`name`、`description`)
# 运行时统计表(backend 管理)
# - article_views:浏览事件与日/小时分桶(首次调用 `/api/articles/:id/view` 自动创建)

# 与 backend 同款 API 调试命令
../target/release/sf-cli api --db-path ../data/lancedb list-articles --category "Tech"
../target/release/sf-cli api --db-path ../data/lancedb get-article frontend-architecture
../target/release/sf-cli api --db-path ../data/lancedb search --q "staticflow"
../target/release/sf-cli api --db-path ../data/lancedb semantic-search --q "前端 架构"
../target/release/sf-cli api --db-path ../data/lancedb related-articles frontend-architecture
../target/release/sf-cli api --db-path ../data/lancedb list-tags
../target/release/sf-cli api --db-path ../data/lancedb list-categories
../target/release/sf-cli api --db-path ../data/lancedb list-images
../target/release/sf-cli api --db-path ../data/lancedb search-images --id <image_id>
../target/release/sf-cli api --db-path ../data/lancedb get-image <image_id_or_filename> --thumb --out ./tmp-thumb.bin

API 列表

端点 说明
GET /api/articles 文章列表(支持 tag/category 过滤)
GET /api/articles/:id 文章详情
POST /api/articles/:id/view 记录文章浏览(默认同一文章+客户端 60 秒去重)
GET /api/articles/:id/view-trend 文章浏览趋势(按天/按小时,按 Asia/Shanghai 分桶)
GET /api/articles/:id/related 相关文章(向量相似)
GET /api/search?q= 全文搜索
GET /api/semantic-search?q= 语义搜索(向量,含跨语言回退与语义片段高亮)
GET /api/images 图片列表
GET /api/images/:id-or-filename 从 LanceDB 读取图片二进制(支持 ?thumb=true,无缩略图则回退原图)
GET /api/image-search?id= 以图搜图
GET /api/tags 标签列表
GET /api/categories 分类列表

可观测性:每个 backend 响应都会返回 x-request-idx-trace-id,并且 backend/shared 的请求内日志会带同一组 ID,便于串联排障。

查询路径可观测:日志会输出 query/path/fastest_path/is_fastest/reason/rows/elapsed_ms,可直接判断是否命中索引或发生回退。

语义高亮模式:/api/semantic-search 默认走快速高亮;追加 &enhanced_highlight=true 可启用高精度片段重排(更慢)。

浏览统计:建议在文章详情页加载时调用 /api/articles/:id/view;后端默认按“文章 + 客户端指纹”做 60 秒去重(可通过本地 admin 接口 /admin/view-analytics-config 调整),并按 Asia/Shanghai 维护日/小时趋势分桶。

检索说明:若你更新了代码但仍看到“英文语义检索无结果”,请重新编译二进制(cargo build --release -p sf-cli -p static-flow-backend),旧二进制不会包含向量列回退逻辑。

关键环境变量

后端(由 scripts/start_backend_selfhosted.sh 自动设置):

  • DB_ROOT(默认 /mnt/wsl/data4tb/static-flow-data,自动解析 content/comments/music 三个 DB)
  • PORT(默认 39080
  • HOST(默认 127.0.0.1
  • SITE_BASE_URL(默认 https://ackingliu.top,用于 SEO 注入)
  • FRONTEND_DIST_DIR(默认 ../frontend/dist,自托管模式的静态文件目录)
  • RUST_ENVdevelopmentproduction
  • ALLOWED_ORIGINS(生产可选,逗号分隔 CORS 白名单)

前端构建时:

  • STATICFLOW_API_BASE
    • 自托管模式:/api(由 build_frontend_selfhosted.sh 设置)
    • GitHub Pages:绝对 URL(由 CI workflow 的 repo variables 设置)
    • 本地开发:http://127.0.0.1:39080/api(由 start_frontend_with_api.sh 设置)

开发命令

# Workspace
cargo build --workspace
cargo test --workspace
cargo fmt --all
cargo clippy --workspace -- -D warnings

# Frontend(自托管构建)
bash scripts/build_frontend_selfhosted.sh

# Frontend(trunk 热重载开发)
bash scripts/start_frontend_with_api.sh --open

# Backend
make bin-backend
bash scripts/start_backend_selfhosted.sh           # 前台
bash scripts/start_backend_selfhosted.sh --daemon   # 后台(日志: /tmp/staticflow-backend.log)

License

MIT