跳到正文
GitHub·· 6 天前AI 评分37

Prismis:本地优先的 AI 研究助手,聚合 RSS/Reddit/YouTube 并智能排序

nickpending/prismis

AI 导读

Prismis 是一款本地优先的 AI 研究助手,持续监控 RSS/Atom、Reddit、YouTube 字幕和静态文件,用 AI 按个人兴趣排序并通过终端 TUI 与局域网 Web 界面推送。

正文

Your AI-powered research department that never sleeps

GitHub | Issues | Roadmap

Status Built with Go Python License

Buy Me A Coffee


Prismis transforms information overload into intelligence. It continuously monitors your RSS feeds, Reddit communities, and YouTube channels, uses AI to surface what matters to YOU personally, then delivers it through a blazing-fast terminal interface.

Think of it as having a research assistant who reads everything and only interrupts you for the important stuff.

Status: Alpha

This is early software that works but has rough edges. It's been in daily use for 3 months, handling 500+ items/day across 30+ sources, but expect quirks. Version 0.3.0 adds semantic search, remote TUI mode, smart archival, and static file monitoring. Each release gets more polished.

✨ Features

  • 🚀 Instant TUI - Launches in <100ms with gorgeous Bubbletea interface
  • 🧠 AI-Powered Priority - LLM analyzes content against YOUR interests (HIGH/MEDIUM/LOW)
  • 🔬 Deep Extraction - Two-tier LLM synthesis on HIGH-priority items: Counterintuitive findings, buried ledes, "so what" actions, quotable lines
  • 👍 Preference Learning - Upvote/downvote content to train AI prioritization over time
  • 🔍 Semantic Search - Local embeddings enable vector similarity search across all content
  • 🏷️ Content Kind - Each item is tagged as one of ten kinds (release, news, analysis, vulnerability, incident, research, tutorial, experience, question, humor) by OpenRouter's Jev decisions model; filter by kind in the TUI, CLI, API and search
  • 🤖 Context Assistant - LLM analyzes flagged items to suggest context.md improvements with gap analysis
  • 🌐 Remote TUI Mode - Access your daemon from anywhere with incremental sync
  • 🎨 Fabric Integration - 200+ AI analysis patterns with tab completion (:fabric <TAB> to browse)
  • 🔒 Local-First - Your data never leaves your machine. SQLite + Go binary
  • 📡 Multi-Source - RSS/Atom feeds, Reddit (API optional), YouTube transcripts, static files
  • 🎯 Personal Context - Define what matters in simple markdown
  • 🔔 Smart Notifications - Desktop alerts only for HIGH priority content
  • 🌐 Web Interface - Beautiful daily briefing accessible from any device on your network
  • 🗄️ Smart Archival - Priority-aware retention policy automatically manages old content
  • ⚡ Zero-Ops - No Docker, no PostgreSQL, no cloud services needed

🎬 Quick Start

# Install everything (macOS/Linux)
make install

# Set your LLM key (the default config uses OpenRouter)
edit ~/.config/prismis/.env  # Set OPENROUTER_API_KEY

# First run: writes ~/.config/prismis/config.toml, then exits
prismis-daemon

# Upgrading from an older install? Bring config to current shape:
prismis-daemon migrate-config

# Smoke-check that everything is wired up (config + LLM services + sources)
prismis-daemon verify

# Tell Prismis what you care about: print an interview prompt, paste it into any
# chatbot, answer its questions, then save the context.md it returns to
# ~/.config/prismis/context.md. It also gives you `prismis-cli source add` lines to run.
# (The sample context.md written on first run is a placeholder until you replace it.)
prismis-cli context bootstrap

# Check the saved context.md (and everything else) again
prismis-daemon verify

# Add your favorite sources
prismis-cli source add https://simonwillison.net/atom/everything/
prismis-cli source add reddit://rust
prismis-cli source add youtube://UCsBjURrPoezykLs9EqgamOA

# Launch the TUI
prismis

Press 1 for HIGH priority. Press Enter to read. Press :audio for audio briefing. Press :fabric <TAB> to explore 200+ AI patterns. Or visit http://localhost:8989 in any browser for the web interface.

🎮 Usage

Web Interface

The daemon serves a beautiful web interface on your local network:

# Start the daemon
prismis-daemon &

# Access from any device on your network
# On Mac: http://localhost:8989
# On iPad/phone: http://YOUR_MAC_IP:8989

Features:

  • 📱 Mobile-responsive daily briefing view (last 24 hours)
  • ⭐ Top 3 Must-Reads with interest matching badges
  • 🎧 Generate audio briefings directly from the UI
  • 🔄 Auto-refreshes every 30 seconds
  • 🎯 Priority filtering and mark-as-read

Configuration for LAN access:

# ~/.config/prismis/config.toml
[api]
host = "0.0.0.0"  # Allow access from other devices (default: 127.0.0.1)

Terminal Interface

prismis           # Launch instantly (local mode)
prismis --remote  # Remote mode with incremental sync from server daemon

Essential Keys:

  • 1/2/3 - View HIGH/MEDIUM/LOW priority content
  • j/k - Navigate up/down (vim-style)
  • Enter - Read full article
  • +/- - Upvote/downvote content (trains AI prioritization)
  • i - Flag item as interesting (for context analysis)
  • : - Command mode (see below)
  • S - Manage sources
  • K - Cycle the kind filter
  • ? - Show all keyboard shortcuts
  • q - Quit

Command Mode (press : to enter):

  • :fabric <pattern> - Run any of 200+ AI patterns (tab completion available)
    • :fabric extract_wisdom - Extract key insights
    • :fabric summarize - Create concise summary
    • :fabric analyze_claims - Fact-check claims
    • :fabric explain_terms - Explain technical terms
  • :kind <kind> - Filter by kind (e.g. :kind vulnerability)
  • :context suggest - Get LLM topic suggestions from flagged items (requires flagging with i)
  • :context edit - Open context.md in $EDITOR
  • :context review - Show count of flagged items ready for analysis
  • :audio - Generate audio briefing from HIGH priority items (requires lspeak)
  • :export sources - Copy all configured sources to clipboard for backup
  • :mark - Mark article as read/unread
  • :copy - Copy article content
  • :prune - Remove unprioritized items (with y/n confirmation)
  • :prune! - Force remove without confirmation
  • :prune 7d - Remove items older than 7 days
  • :help - Show all available commands

Context Assistant Workflow

Improve your context.md over time by flagging interesting unprioritized items:

  1. Flag interesting items - Press i on unprioritized content that should have matched your topics but didn't
  2. Get suggestions - Run :context suggest to analyze flagged items with LLM
  3. Review analysis - Suggestions copied to clipboard with gap analysis:
    • Add: New topic area not covered
    • Expand: Existing topic too narrow
    • Narrow: Existing topic too broad
    • Split: One topic covering unrelated things
  4. Update context.md - Run :context edit or manually update based on suggestions
  5. Repeat - As you flag more items, patterns emerge and your context improves

The LLM studies your existing topic style (length, phrasing, tone) and matches it in suggestions.

Managing Sources

# RSS/Atom feeds
prismis-cli source add https://news.ycombinator.com/rss

# Reddit (fetches top comments for richer analysis)
# Note: Comment fetching increases LLM analysis costs. Configure max_comments in config.toml
prismis-cli source add reddit://programming

# YouTube channels (extracts transcripts)
prismis-cli source add youtube://UC9-y-6csu5WGm29I7JiwpnA

# Static file monitoring (GitHub changelogs, release notes)
prismis-cli source add file:///path/to/CHANGELOG.md

# List all sources
prismis-cli source list

# Remove a source
prismis-cli source remove 3

# Semantic search across all content
prismis-cli search "local-first database innovations"
prismis-cli search "prompt injection" --kind tutorial,research   # only these kinds

# Backfill deep-extraction synthesis on HIGH-priority items
prismis-cli extract --priority high --limit 3   # Process 3 items
prismis-cli extract --priority high --limit 100 # Larger batch

# Retry failed LLM analysis
prismis-cli analyze repair

# Classify the kind of items analysed before kind classification existed
prismis-cli analyze kinds --since-days 30   # shows count and cost, asks to confirm

# Clean up unprioritized content
prismis-cli prune               # Remove all unprioritized items
prismis-cli prune --days 7      # Remove unprioritized items older than 7 days

# View system statistics
prismis-cli statistics          # Content and source counts

Archival Policy

Prismis automatically archives old content based on priority (configurable in ~/.config/prismis/config.toml):

Retention Windows:

  • HIGH priority: Kept until read, then archived after 30 days
  • MEDIUM priority: 14 days unread / 30 days read
  • LOW priority: 7 days unread / 30 days read

Protected from archival:

  • Favorited items (⭐)
  • Items with notes
  • Unread HIGH priority items (kept indefinitely)

This ensures important content stays visible until you've seen it, while automatically cleaning up old read content.

CLI Automation

Query and export content for automation workflows:

# Get a single entry (formatted display)
prismis-cli get <entry-id>

# Get raw content for piping to external tools
prismis-cli get <entry-id> --raw | fabric --pattern extract_wisdom

# List recent entries
prismis-cli list --limit 10
prismis-cli list --priority high --unread
prismis-cli list --kind release,vulnerability

# Export in JSON or CSV format
prismis-cli export --format json > backup.json
prismis-cli export --format csv --priority high > high-priority.csv

LLM-Friendly JSON Output:

Most CLI commands support --json for machine-readable output, perfect for AI agent integration:

# Get structured data for LLM processing
prismis-cli statistics --json              # System metrics
prismis-cli search "topic" --compact --json # Search results (compact: 24x smaller)
prismis-cli list --json                    # Content list
prismis-cli get <id> --json                # Entry metadata
prismis-cli source list --json             # All sources
prismis-cli source add <url> --json        # Source creation response

# Example: Let AI analyze your reading backlog
prismis-cli list --priority high --unread --json | llm "Summarize my reading queue"

Running the Daemon

The daemon fetches and analyzes content every fetch_interval minutes ([daemon] in ~/.config/prismis/config.toml, default 30):

# One-time fetch (testing)
prismis-daemon --once

# Run continuously in background
prismis-daemon &

# Or run in foreground to see logs
prismis-daemon

# Stop the daemon
make stop

# Post-deploy smoke check (config valid, LLM services reachable, ≥1 source)
prismis-daemon verify

# Idempotent config migration (after upgrading from older Prismis)
prismis-daemon migrate-config

Note: You can run the daemon however you prefer - in a tmux session, as a background process, or with any process manager you're comfortable with. It's just a regular Python program.

prismis-daemon verify is read-only and safe to run against a production daemon. It checks config validity, light LLM service reachable, deep LLM service reachable (or "not configured"), kind service reachable (or "not configured"), at least one active source, and that your saved context.md has every required section and no code-fence lines. It exits 0 on all-pass / 1 on any failure.

🏗️ Architecture

Prismis uses a multi-process architecture optimized for responsiveness:

Internet Sources          Python Daemon           Go TUI
     │                         │                     │
     └──► Fetchers ──► LLM ──► SQLite (WAL) ◄────── Read
          (RSS/Reddit)  (AI)      │
                                  └──► Notifications
                                       (HIGH only)
  • Python Daemon: Fetches content, analyzes with AI, manages database
  • Go TUI: Lightning-fast terminal interface with instant launch
  • SQLite WAL: Enables concurrent access without locks
  • LLM Analysis: Uses your personal context to assign priorities

🔧 Installation

Install with Homebrew (macOS)

Each component installs on its own. Install the ones the machine needs:

brew install nickpending/prismis/prismis-tui     # the terminal UI, for reading
brew install nickpending/prismis/prismis-cli     # the CLI, for agents and scripts
brew install nickpending/prismis/prismis-daemon  # the daemon, for the machine that fetches

prismis-tui builds from source and pulls in Go; prismis-daemon downloads its pinned Python wheels (including torch) at install time. Each formula prints its setup steps when it finishes (brew info <formula> shows them again). The formulas install the client-only CLI; on the daemon host, use make install below to get the CLI's local-mode commands too.

Prerequisites (for building from source)

  • macOS or Linux
  • Go 1.21+ for the TUI
  • Python 3.14+ for the daemon
  • LLM API key - OpenRouter by default; OpenAI or any OpenAI-compatible endpoint, or a local server, by editing [services.*] in config.toml
  • Fabric (optional) - AI content analysis patterns with tab completion
  • lspeak (optional) - Text-to-speech for audio briefings (uv tool install git+https://github.com/nickpending/lspeak.git)

Install from Source

git clone https://github.com/nickpending/prismis.git
cd prismis
make install

# Edit the .env file with your LLM key (the default config uses OpenRouter)
edit ~/.config/prismis/.env
# Change: OPENROUTER_API_KEY=sk-your-key-here

make install installs the CLI with its local-mode commands (analyze, embeddings), which import the daemon and only work on the machine running it. On a machine that only talks to a remote daemon, make install-cli installs the client-only CLI; on the daemon host, reinstall the CLI after each update with make install-cli-local.

Configuration

Prismis follows XDG standards:

  • Config: ~/.config/prismis/
  • Data: ~/.local/share/prismis/
  • Logs: Wherever you redirect them (stdout/stderr by default)

Security: API keys are stored in ~/.config/prismis/.env with 600 permissions (only you can read). Config references them with api_key = "env:VARIABLE_NAME" pattern for security.

🚀 Advanced Features

LLM Configuration (Dual-Service)

Prismis routes LLM calls through two services so routine work and deep synthesis can use different models. The daemon talks to every service through the openai Python SDK directly (daemon/src/prismis_daemon/llm_client.py) — one client for both api.openai.com and openrouter.ai, since both speak the same chat-completions wire format. Services are resolved from the [services.*] tables of ~/.config/prismis/config.toml; the daemon only references service names.

# ~/.config/prismis/config.toml
[llm]
light_service = "openrouter"            # required — used for priority/summary/context analysis
deep_service  = "deep"                  # optional — second-tier synthesis on HIGH items
kind_service  = "kind"                  # optional — content kind classification
auto_extract  = "high"                  # "high" | "medium" | "none" — gate for auto deep extraction

The light service handles every routine call (fetch-cycle priority, summarization, context analyzer). The deep service runs the second-tier synthesis prompt that produces the Counterintuitive / Buried lede / So what / Pushback sections plus quotables. When deep_service is unset, the daemon runs in light-only mode (graceful degradation — deep extraction failures never block storage). The kind service classifies each newly analysed item into one of the ten content kinds; an item it isn't confident about (below 0.7) stays unclassified, and when kind_service is unset no kind call is made.

Services are defined in the same config.toml, one [services.<name>] table each, with a base_url, a model and an api_key. The default config ships one, openrouter, and light_service names it:

# ~/.config/prismis/config.toml
[services.openrouter]
base_url = "https://openrouter.ai/api/v1"
model    = "openai/gpt-5.4-nano"
api_key  = "env:OPENROUTER_API_KEY"

Keys come from the environment, never from config.toml. api_key is always env:NAME: the daemon reads the variable NAME from its environment when it makes a call. Put it in ~/.config/prismis/.env (loaded at startup; a variable already in the environment wins) or export it. A literal key in api_key, or a missing variable, fails with an error naming the service and the variable. A service with no api_key line takes no key — use that for a local server.

Using OpenAI directly instead of OpenRouter: edit [services.openrouter] — set base_url = "https://api.openai.com/v1", a model such as gpt-5-mini, and api_key = "env:OPENAI_API_KEY" — then put OPENAI_API_KEY in .env.

More services, for the deep and kind roles and for a local server:

[services.deep]
base_url = "https://openrouter.ai/api/v1"
model    = "anthropic/claude-sonnet-4.5"   # reasoning-class model recommended for deep synthesis
api_key  = "env:OPENROUTER_API_KEY"

[services.kind]
adapter  = "decisions"             # OpenRouter's Decisions endpoint, not chat completions
base_url = "https://openrouter.ai/api/alpha/decisions"   # the full endpoint URL
model    = "typesafe/jev-1.13"
api_key  = "env:OPENROUTER_API_KEY"

[services.local]
base_url = "http://localhost:8080/v1"   # any OpenAI-compatible local server
model    = "llama2"                     # no api_key: keyless

Optional app_title and app_url fields set the attribution headers OpenRouter shows. Every service except the kind service must speak the OpenAI chat-completions wire format — the daemon's client talks to base_url directly, with no per-provider translation.

Upgrading from an install whose services lived in a shared services.toml: run prismis-daemon migrate-config once. It appends the services your [llm] section names to config.toml as [services.*] tables (keeping your comments, after saving a timestamped backup), points each api_key at an environment variable such as env:OPENROUTER_API_KEY, and never copies a key value. Export that variable where the daemon runs. Running it again changes nothing.

Reddit API (optional - improves reliability):

# Add to ~/.config/prismis/.env for better Reddit access
REDDIT_CLIENT_ID=your-reddit-client-id
REDDIT_CLIENT_SECRET=your-reddit-client-secret

Fabric Integration

Built-in AI analysis using 200+ Fabric patterns. Tab completion helps you discover all available patterns:

# In TUI, select an article and press ':'
:fabric <TAB>              # Browse all available patterns
:fabric extract_wisdom     # Extract key insights
:fabric summarize          # Create concise summary

Note: Fabric analyzes the original/raw article content, not the AI-generated summary. This gives you deeper, unfiltered insights directly from the source material.

Results are automatically copied to your clipboard. Requires Fabric to be installed.

Audio Briefings

Generate Jarvis-style audio briefings from your HIGH priority content:

# In TUI
:audio                     # Generates MP3 briefing, saved to ~/.local/share/prismis/audio/

# Configure TTS provider (optional)
# ~/.config/prismis/config.toml
[audio]
provider = "system"        # Free macOS/Linux TTS (default)
# provider = "elevenlabs"  # Premium quality ($0.30/1K chars)
# voice = "your-voice-id"  # ElevenLabs voice ID (optional)

Requires lspeak for TTS generation:

uv tool install git+https://github.com/nickpending/lspeak.git

# For ElevenLabs (optional premium quality)
export ELEVENLABS_API_KEY=your-api-key

API Access

The daemon exposes a REST API for custom integrations and the web interface.

Full API Documentation: See API.md for complete endpoint reference, authentication, request/response formats, and client examples.

Quick Examples:

# Get last 24 hours of content (daily briefing)
curl -H "X-API-Key: your-api-key" "http://localhost:8000/api/entries?since_hours=24"

# Get high priority items only
curl -H "X-API-Key: your-api-key" "http://localhost:8000/api/entries?priority=high&since_hours=24"

# Mark item as read
curl -X PATCH -H "X-API-Key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{"read": true}' \
  "http://localhost:8000/api/entries/CONTENT_ID"

# Get context suggestions from flagged items
curl -X POST -H "X-API-Key: your-api-key" \
  "http://localhost:8000/api/context"

API Key: Found in ~/.config/prismis/config.toml under [api] -> api_key

Interactive Docs: http://localhost:8000/docs (Swagger UI)

🧪 Development

# Run tests
make test

# Development mode
make dev        # Run daemon once
make dev-tui    # Run TUI with live reload

# Build binaries
make build

./.specify/verify.sh — the project gate make test and CI both run — needs only Go, uv and Python: the Go toolchain provides staticcheck and gitleaks (the committed-secrets scan) through tool directives in tui/go.mod.

Project Structure

prismis/
├── daemon/     # Python daemon (fetching, analysis, API)
├── tui/        # Go terminal interface  
├── cli/        # Python CLI for management
└── scripts/    # Installation and service scripts

📚 Documentation

🤝 Contributing

Prismis is open source and welcomes contributions! Check out our Contributing Guide to get started.

Some areas we'd love help with:

  • Additional content sources (Mastodon, BlueSky, etc.)
  • Enhanced LLM analysis patterns
  • Cross-platform notification support
  • TUI themes and customization

📈 Why Prismis?

The Problem: You have 50+ sources generating 500+ items daily. Current RSS readers show everything chronologically. You miss important stuff, waste time on noise.

The Solution: Prismis reads everything and uses AI to understand what matters to YOU specifically. High priority content triggers notifications. Medium priority waits in your TUI. Low priority is there if you're bored. Unprioritized items auto-cleanup.

The Philosophy: Your attention is precious. Software should protect it, not exploit it.

Known Issues & Limitations

Current limitations in v0.3.0-alpha:

  • Daemon process management - Manual start/stop (workaround: use tmux or prismis-daemon &)
  • YouTube age-gating - Some videos fail to extract transcripts (workaround: add RSS feed directly)
  • Fabric errors - May timeout on very long content (workaround: use shorter patterns like summarize)

What works well:

  • ✅ RSS/Reddit/YouTube/file ingestion with full content extraction
  • ✅ Reddit comment enrichment for richer LLM analysis
  • ✅ Semantic search with local embeddings and vector similarity
  • ✅ Remote TUI mode with incremental sync from server daemon
  • ✅ Priority-aware archival policy for automated retention
  • ✅ Clear API naming (/api/entries with consistent error codes)
  • ✅ CLI automation with single-command invocation and piping support
  • ✅ Fabric integration with 200+ patterns and tab completion
  • ✅ Web interface with mobile-responsive daily briefing
  • ✅ Audio briefing generation with Jarvis personality
  • ✅ Instant TUI launch (<100ms) and navigation

🎯 Roadmap

v0.3.0 (Current):

  • Semantic search with local embeddings
  • Remote TUI mode with incremental sync
  • Priority-aware archival policy
  • Static file monitoring for changelogs
  • CLI automation improvements

v0.4.0 (Next):

  • Enhanced TUI filtering (date range, source, topics)
  • Daemon process management (systemd/launchd)
  • Better source error handling and recovery
  • Export markdown format for Obsidian integration

v1.0.0 (Future):

  • MCP server for AI agent queries
  • Papers support (arxiv RSS, PDF ingestion)
  • Manual content ingestion (one-off URLs/PDFs)
  • Performance optimizations and full test coverage

📄 License

MIT - Use it, fork it, make it yours.

🙏 Acknowledgments

Built with amazing tools:

  • Bubbletea - Delightful TUI framework
  • openai-python - Official OpenAI SDK, called directly for every LLM completion
  • uv - Blazing fast Python package manager

来源:GitHub · github.com