Skip to content

Latest commit

 

History

History
245 lines (200 loc) · 10.1 KB

File metadata and controls

245 lines (200 loc) · 10.1 KB

Architecture

PaperFlow is built around three layers: a thin CLI, a provider abstraction for LLMs and embeddings, and a set of agents and skills that compose the daily-pipeline / reading-report / feedback / drift loop.

                 +------------------------------------------+
                 |             paperflow CLI (typer)         |
                 |   init / doctor / daily / read / feedback |
                 |   wiki / gui / demo / eval                |
                 +------------------------------------------+
                                     |
                                     v
                 +------------------------------------------+
                 |          paperflow.providers              |
                 |   LLMProvider:    OpenAI / Anthropic /    |
                 |                   Ollama / Mock           |
                 |   EmbeddingProvider: OpenAI /             |
                 |                   sentence-transformers / |
                 |                   Ollama / Hash           |
                 +------------------------------------------+
                                     |
                                     v
+-------------+     +-------------+     +-----------------------+
|  agents/    |<--->|  skills/    |<--->|  data sources         |
|             |     |             |     |  arXiv / OpenReview / |
| coldstart   |     | fetch       |     |  journals             |
| reading     |     | parse       |     +-----------------------+
| feedback    |     | store       |
| must-read   |     | profile     |     +-----------------------+
| profile     |     | report      |     |  storage              |
| coordinator |     |             |     |  data/paperflow.db    |
+-------------+     +-------------+     |  data/embeddings_cache|
                                        +-----------------------+
                                                  ^
                                                  |
                 +----------------+----------------+---------------+
                 | deployments/desktop/             | deployments/feishu/ |
                 | local browser GUI                | webhook + daily push|
                 +----------------------------------+---------------------+

CLI layer (paperflow/cli.py)

The CLI is intentionally thin. Each command resolves its arguments, validates provider configuration, and either:

  • delegates to a project-internal Python script via subprocess.run (init, daily, read, feedback, eval, the heavyweight doctor); or
  • runs in-process to exercise the provider abstraction (demo).

Adding a new command means adding one @app.command in paperflow/cli.py — no router, no plugin discovery.

Provider abstraction (paperflow/providers/)

The provider layer defines two protocols:

class LLMProvider(Protocol):
    name: str
    model: str
    def generate(self, prompt: str, *, system: Optional[str] = None,
                 temperature: float = 0.0, max_tokens: int = 1024) -> LLMResponse: ...

class EmbeddingProvider(Protocol):
    name: str
    model: str
    dimensions: int
    def embed(self, text: str) -> List[float]: ...
    def embed_batch(self, texts: Iterable[str]) -> List[List[float]]: ...

Concrete implementations live next to the protocols and are constructed by two factory functions:

from paperflow.providers import build_llm_provider, build_embedding_provider

llm = build_llm_provider()
embed = build_embedding_provider()

Both factories read PAPERFLOW_LLM_PROVIDER / PAPERFLOW_EMBED_PROVIDER from the environment, fall back to per-provider defaults when models or dimensions aren't set, and silently substitute the deterministic mock/hash backend when credentials are missing or look like placeholders. This keeps tests and offline reproductions stable.

See providers.md for per-backend details.

Agents (agents/)

Agents are coarse-grained units that compose the user-visible pipeline:

Agent Responsibility
coldstart-agent Bootstrap a structured profile from text/PDF/homepage
reading-agent Generate per-paper personalized reading reports
feedback-agent Translate user signals into profile + drift updates
wiki-agent Ingest pushes, reading reports, feedback, drift, and topics into the local wiki
must-read-manager Maintain author/keyword anchor lists
profile-report-agent Produce long-form profile reports
master-coordinator Cross-agent orchestration, intent parsing

The Feishu daily-push agent moved out of agents/ into deployments/feishu/daily-push-agent/ to make the deployment-specific nature explicit.

Skills (skills/)

Skills are the small reusable pieces — fetchers, parsers, and storage helpers the agents call into:

Skill Purpose
arxiv-fetcher Pull papers from arXiv by date/category
openreview-fetcher Pull papers from OpenReview by venue
journal-fetcher RSS / API journal fetchers
profile-updater Score papers against profile, drift bookkeeping
storage-helper SQLite + embedding cache I/O
wiki-store Wiki nodes, edges, citations, and Markdown mirrors
feishu-reporter Card rendering for the Feishu deployment

Skills are resolved with importlib because some directory names contain hyphens. Each skill is dependency-light by design: heavy imports (openai, sentence_transformers, anthropic) happen inside the provider classes, not at module load time, so missing optional deps don't break unrelated agents.

Data flow: a daily pipeline run

  1. Fetch. daily-push-agent walks config/conferences.yaml, config/journals.yaml, and the arXiv categories baked into the user profile. Skills fetch raw papers and write them to data/paperflow.db.
  2. Score. Each paper is embedded (cached in data/embeddings_cache/), scored against the user's interest weights, given an anchor boost for author/keyword matches, and a freshness term for recency.
  3. Drift correction. skills/profile-updater compares short-window vs long-window centroids and adjusts the learning rate before applying the day's score updates.
  4. Top-20 selection. A diversity-aware ranker picks 20 papers under the display budget.
  5. Push (optional). If running under deployments/feishu/, the cards are rendered and pushed via the Feishu webhook.

Data flow: feedback and profile learning

Feedback is surface-independent. CLI feedback, GUI feedback, and Feishu/Lark chat replies all converge on the same profile-learning path for the matching user_id:

CLI paperflow feedback
GUI selected / not-interested actions
Feishu/Lark numeric replies
        |
        v
agents/feedback-agent
        |
        +--> behavior_logs in data/paperflow.db
        +--> skills/profile-updater updates topic weights and drift state
        +--> wiki-agent mirrors paper / trajectory / topic evidence

Reading reports form a second, weaker signal path:

paperflow read / GUI arXiv read / GUI local PDF read
        |
        v
agents/reading-agent
        |
        +--> local Markdown report
        +--> optional Feishu doc export
        +--> reading-signal state in the profile
        +--> wiki paper and section nodes

See feedback-loop.md for the user-facing behavior.

Storage

PaperFlow uses a single SQLite database at data/paperflow.db and a flat JSON store for user roles. Embeddings are cached as raw float arrays under data/embeddings_cache/ keyed by content hash, so swapping embedding backends invalidates the cache automatically.

Experiment surface (experiments/)

The paper experiments are runnable, reproducible scripts split by purpose:

experiments/
├── benchmark/         Public PaperFlow-Bench evaluator + packagers
├── main_experiment/   6 baselines + the PaperFlow main system
├── ablation/          Component-removal runs
├── drift/             Interest-drift experiments
├── llm_comparison/    LLM-backbone comparison
├── token_cost/        Token-usage profiling
├── simulation/        Historical-episode simulator
├── reading_reports/   Reading-report quality runs
└── analysis/          Plot + summary scripts

Each runnable folder ships both .sh (Linux/macOS) and .cmd/.ps1 (Windows) entry points. See reproduce.md and ../experiments/REPRODUCE.md.

Optional Feishu deployment (deployments/feishu/)

The Feishu/Lark integration is fully optional and lives in its own deployment directory:

deployments/feishu/
├── daily-push-agent/    Daily pipeline behind a Feishu webhook
├── feishu-reporter/     Feishu card rendering
└── webhook-server/      Webhook + ngrok launcher

CLI users never need to look at this directory. See feishu-webhook-setup.md if you want the bot.

Local GUI deployment (deployments/desktop/)

The local GUI is another deployment surface, parallel to Feishu/Lark. It uses a Python stdlib HTTP server and static HTML/CSS/JS, so it adds no runtime dependency:

deployments/desktop/
├── server.py          Local HTTP API + static-file server
├── shared/agents.py   GUI-safe wrapper around agents/skills
├── static/            Browser UI
└── README.md

paperflow gui starts the server and opens a browser. It reads and writes the same data/paperflow.db, PAPERFLOW_PDF_DIR, PAPERFLOW_READING_REPORTS_DIR, and PAPERFLOW_WIKI_DIR used by the CLI. It does not manage background schedules; scheduled push delivery remains in deployments/feishu/.