An autonomous, serverless, multi-agent system that tracks academic papers, extracts structured data, and weaves them into a local, interconnected Markdown knowledge graph β a Second Brain for ML research.
Built to eventually communicate with other identical systems, forming a decentralised Hive Mind.
βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β GitHub Actions CI β
β (weekly schedule + workflow_dispatch) β
βββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββ
β
ββββββββββββββΌβββββββββββββ
β Federation Agent β β consumes external public_feed.json feeds
ββββββββββββββ¬βββββββββββββ
β
ββββββββββββββΌβββββββββββββ
β Watcher β β queries ArXiv API by keyword
ββββββββββββββ¬βββββββββββββ
β RawPaper[]
ββββββββββββββΌβββββββββββββ
β Router (Skill β β routes each paper to a domain skill
β Registry) β (NLP, Vision, TimeSeries, β¦)
ββββββββββββββ¬βββββββββββββ
β Skill
ββββββββββββββΌβββββββββββββ
β Analyst β β pydantic-ai structured extraction
β (pydantic-ai) β with taxonomy injection
ββββββββββββββ¬βββββββββββββ
β PaperAnalysis
ββββββββββββββΌβββββββββββββ
β Vault Writer β β writes .md to tmp_vault/
β β generates concept stubs
β β updates public_feed.json
ββββββββββββββ¬βββββββββββββ
β atomic move
ββββββββββββββΌβββββββββββββ
β /vault β β permanent, file-based knowledge graph
β papers/ concepts/ β
β datasets/ β
βββββββββββββββββββββββββββ
research-cruise/
βββ .github/
β βββ workflows/
β βββ autonomous-tracker.yml # CI/CD pipeline
βββ vault/
β βββ papers/ # One .md file per paper
β βββ concepts/ # Auto-generated concept stubs
β βββ datasets/ # Dataset stubs
βββ swarm_notes/
β βββ config.py # Configuration & env vars
β βββ vault_manager.py # Staging pattern (tmp_vault β vault)
β βββ watcher.py # Configurable paper-source watcher
β βββ router.py # Skill registry router
β βββ analyst.py # pydantic-ai extraction agent
β βββ vault_writer.py # Markdown writer + public_feed.json
β βββ federation.py # Hive Mind federation agent
β βββ main.py # Pipeline orchestrator
βββ taxonomy.json # Controlled vocabulary (tags, domains)
βββ public_feed.json # Rolling feed of last 20 papers (for federation)
βββ requirements.txt
- Python 3.11+
- An OpenAI-compatible API key
# Install dependencies
pip install -r requirements.txt
# Set your API key
export LLM_API_KEY="sk-..."
# Optionally customise keywords
export PAPER_KEYWORDS="mamba,diffusion model,retrieval augmented generation"
# Optional: switch the watcher to Semantic Scholar
export PAPER_SOURCE="semantic_scholar"
export SEMANTIC_SCHOLAR_API_KEY="..."
# Run the pipeline
python -m swarm_notes.main| Variable | Default | Description |
|---|---|---|
LLM_API_KEY |
(required) | API key for the LLM provider |
LLM_MODEL |
openai:gpt-4o-mini |
pydantic-ai model string |
PAPER_SOURCE |
arxiv |
Paper search backend: arxiv or semantic_scholar |
PAPER_KEYWORDS |
See config.py |
Comma-separated search terms |
PAPER_MAX_RESULTS_PER_KEYWORD |
5 |
Papers fetched per keyword |
PAPER_TOTAL_CAP |
20 |
Hard cap on total papers per run |
SEMANTIC_SCHOLAR_API_KEY |
(empty) | Optional Semantic Scholar API key sent as x-api-key |
FEDERATION_FEEDS |
(empty) | Comma-separated external feed URLs |
PUBLIC_FEED_MAX_ITEMS |
20 |
Max entries kept in public_feed.json |
When PAPER_SOURCE=semantic_scholar, the watcher queries Semantic Scholar's Graph API and keeps only results that can be mapped back to an ArXiv identifier. That preserves compatibility with the rest of the pipeline, which still stores papers by arxiv_id.
Legacy ARXIV_KEYWORDS, ARXIV_MAX_RESULTS_PER_KEYWORD, and ARXIV_TOTAL_CAP are still accepted for backward compatibility, but PAPER_* names are now canonical.
Click Fork on GitHub to create your own copy of this repository.
The pipeline needs an OpenAI-compatible API key to run the LLM analyst step.
- Open your forked repository on GitHub.
- Go to Settings β Secrets and variables β Actions.
- Click New repository secret.
- Set Name to
LLM_API_KEYand Secret to your API key (e.g.sk-...). - Click Add secret.
Note: The workflow exposes
LLM_API_KEYas bothLLM_API_KEYandOPENAI_API_KEYso that pydantic-ai's OpenAI provider picks it up automatically.
By default the pipeline uses openai:gpt-4o-mini. To use a different model, add a
second repository secret (or variable) named LLM_MODEL with the pydantic-ai model
string, e.g. openai:gpt-4o or anthropic:claude-3-5-haiku.
You can also set LLM_MODEL in the workflow's env: block directly if you prefer not
to use a secret.
- Scheduled: the pipeline fires automatically every Monday at 06:00 UTC.
- Manual: go to Actions β Autonomous Research Tracker β Run workflow, optionally
override
keywords,federation_feeds, andmax_resultsin the dispatch form.
Every successful run updates public_feed.json at the root of the repository with the metadata and summaries of the last 20 processed papers.
To subscribe to another agent's feed, pass their raw public_feed.json URL:
export FEDERATION_FEEDS="https://raw.githubusercontent.com/alice/research-cruise/main/public_feed.json,https://raw.githubusercontent.com/bob/research-cruise/main/public_feed.json"
python -m swarm_notes.mainOr set federation_feeds in the workflow_dispatch inputs.
Conflict resolution: If an external feed contains a review of a paper that already exists locally, the local metadata is preserved. The external summary is appended under a ### External Perspectives section:
### External Perspectives
> "Transformers are over-engineered for this dataset." - @Agent_alice
> *(Retrieved 2024-01-15)*Each paper note uses hybrid YAML frontmatter (CSL-compatible fields + custom fields):
---
# CSL-compatible fields
title: "Attention Is All You Need"
author:
- literal: "Ashish Vaswani"
issued:
date-parts:
- [2017, 6, 12]
url: "https://arxiv.org/abs/1706.03762"
# Custom fields
arxiv_id: "1706.03762"
domain: "nlp"
tags:
- "transformer"
- "attention-mechanism"
architectures:
- "encoder-decoder"
datasets:
- "WMT 2014"
skill: "NLPSkill"
processed_at: "2024-01-15T06:00:00Z"
---Body sections: Summary, Key Contributions, Key Concepts (with relative links to ../concepts/), Datasets, Limitations, Links.
taxonomy.json contains the controlled vocabulary of tags, architectures, and domains injected into the analyst's system prompt. This prevents LLM hallucination and keeps metadata consistent. Edit taxonomy.json to add new terms.
MIT β see LICENSE.