Perplexity-style local research agents built with LangGraph and Tavily
Project description
perplexity-at-home
perplexity-at-home is an open-source, Perplexity-style research runtime built
with LangGraph, Tavily, OpenAI, and optional Postgres persistence. It ships
three distinct research modes, defaults to openai:gpt-5.4, exposes a packaged
Streamlit dashboard, and keeps runtime configuration centralized in Pydantic
Settings.
The point of the package is simple: quick answers, broader synthesis, and real deep research should not be the same graph.
Think of the package as a ladder:
quick-search -> pro-search -> deep-research.
Each lane adds more planning, source coverage, and synthesis depth.
Why This Exists
quick-searchfor fast cited answerspro-searchfor broader multi-source synthesisdeep-researchfor iterative report-style investigation- one package surface for CLI, dashboard, and LangGraph runtime entrypoints
- optional Postgres-backed persistence for long-running threads and reloadable state
One-Minute Tour
make setup
make quick QUESTION="What changed in LangGraph recently?"
make pro QUESTION="Compare Tavily and Exa for agent retrieval."
make deep QUESTION="Research the tradeoffs between Tavily, Exa, and Perplexity."
make dashboard
Research Lanes
| Workflow | Shape | Best for | Output |
|---|---|---|---|
quick-search |
query -> search -> fetch -> summarize -> answer |
fast factual questions | concise markdown answer with citations |
pro-search |
clarify -> decompose -> parallel search -> read -> synthesize |
broader web-backed synthesis | structured markdown answer |
deep-research |
scope -> plan -> retrieve/read/analyze -> loop -> report |
report-style investigation | long-form brief with evidence and citations |
Example Questions
quick-search:What changed in LangGraph recently?pro-search:Compare Tavily and Exa for agent retrieval.deep-research:Research best practices for packaging a multi-workflow research agent.
Runnable demos also live under examples/, including
examples/quick_search_demo.py,
examples/pro_search_answer_demo.py, and
examples/deep_research_demo.py.
System Map
flowchart LR
U[User question] --> S{Surface}
S --> CLI[CLI]
S --> DASH[Streamlit dashboard]
S --> LG[LangGraph runtime]
CLI --> W{Workflow}
DASH --> W
LG --> W
W --> QS[Quick Search]
W --> PS[Pro Search]
W --> DR[Deep Research]
QS --> LLM[GPT-5.4 family]
PS --> LLM
DR --> LLM
QS --> TV[Tavily tools]
PS --> TV
DR --> TV
QS -->|optional| P[(Postgres store + checkpointer)]
PS -->|optional| P
DR -->|optional| P
QS -->|optional| LS[LangSmith tracing]
PS -->|optional| LS
DR -->|optional| LS
Workflow Graphs
The diagrams below are the public workflow shapes used by the package docs and dashboard. They intentionally show the product-level flow, not every internal node name.
Quick Search
flowchart LR
Q[Question] --> QUERY[Frame focused query]
QUERY --> SEARCH[Search the web]
SEARCH --> FETCH[Fetch or extract the best source]
FETCH --> SUMMARIZE[Summarize the evidence]
SUMMARIZE --> ANSWER[Return a fast cited answer]
quick-search stays intentionally thin. The implementation is still a compact
single-agent surface, but the mental model is shallow retrieval:
query -> search -> fetch -> summarize -> answer.
Pro Search
flowchart TD
Q[Question] --> CHECK[Complexity check]
CHECK --> CLARIFY{Need clarification or refinement?}
CLARIFY -->|yes| REFINE[Refine scope]
CLARIFY -->|no| DECOMP[Decompose question]
REFINE --> DECOMP
DECOMP --> SEARCH[Run parallel searches]
SEARCH --> READ[Read the strongest sources]
READ --> AGGREGATE[Aggregate evidence]
AGGREGATE --> SYNTHESIZE[Synthesize grounded answer]
SYNTHESIZE --> ANSWER[Markdown answer with citations]
pro-search is the middle lane. In code today it is a tight deterministic
graph around planning, batched Tavily execution, aggregation, and synthesis.
At the package level, the intended flow is:
query -> complexity/refinement -> decomposition -> parallel search -> read -> aggregate -> synthesize.
Deep Research
flowchart TD
Q[Question] --> SCOPE[Scope check]
SCOPE -->|needs clarification| CLARIFY[Clarify request]
SCOPE -->|ready| PLAN[Build research plan]
PLAN --> SUBQ[Generate subquestions]
subgraph Retrieval Loop
SUBQ --> SEARCH[Search and retrieve]
SEARCH --> READ[Read and extract evidence]
READ --> ANALYZE[Analyze gaps and confidence]
ANALYZE -->|coverage incomplete| SEARCH
end
ANALYZE -->|coverage sufficient| REPORT[Write final report]
deep-research is the real DAG-heavy lane. The concrete graph routes follow-up
work through retrieval strategies such as requery, extract, map,
crawl, and research, but the public shape is the iterative research loop
from the design notes: scope, plan, search, read, analyze, repeat, then write.
How To Run
Install the package dependencies:
make setup
See the local command surface at any time with:
make help
Minimal environment:
OPENAI_API_KEYTAVILY_API_KEYPERPLEXITY_AT_HOME_DEFAULT_MODELif you want to overrideopenai:gpt-5.4
Run each lane:
make quick QUESTION="What is Tavily?"
make pro QUESTION="What changed recently in Tavily's LangChain integration?"
make deep QUESTION="Compare Tavily, Exa, and Perplexity for agent retrieval."
Turn on durable state:
make up
make db-setup
make deep-persistent QUESTION="What is Tavily?"
Launch the dashboard:
make dashboard
You can also use the packaged CLI directly:
pdm run perplexity-at-home quick-search "What is Tavily?"
pdm run perplexity-at-home pro-search "Compare Tavily and Exa for agent retrieval."
pdm run perplexity-at-home deep-research "Research the current LangGraph persistence story."
The dashboard is built around workflow visibility: research output, sources, workflow graph, and run-state inspection. It is state-first today, not a token-stream demo surface pretending to be an agent runtime.
Dashboard Flow
Use this when you want the shortest local path:
make setup
make dashboard
If you want persistent runs in the dashboard:
make up
make db-setup
make dashboard
Inside the dashboard:
- pick
quick-searchfirst if you just want to smoke-test the app - leave persistence off unless Postgres is already up
- use
pro-searchordeep-researchonce keys are confirmed working - create a new thread when switching question families
- inspect
Sources,Workflow Graph, andRun Stateafter each run
Settings, Persistence, and Runtime Surfaces
src/perplexity_at_home/settings.pyowns OpenAI, Tavily, LangSmith, model, and nested Postgres settings.src/perplexity_at_home/core/owns the async LangGraph store, checkpointer, and persistence wrapper.langgraph.jsonexposesquick_search,pro_search, anddeep_research, plus the custom store and checkpointer entrypoints.- Workflow-specific model overrides are supported with settings such as
PERPLEXITY_AT_HOME_QUICK_SEARCH_MODELandPERPLEXITY_AT_HOME_DEEP_RESEARCH_RETRIEVAL_MODEL.
Verified Paths
Live runs were re-verified locally on April 23, 2026 against real OpenAI, Tavily, and Postgres:
quick-searchcompleted in memory.pro-searchcompleted in memory.deep-researchcompleted in memory.deep-research --persistent --setup-persistencecompleted against Postgres.
The repository now also includes a gated live E2E suite plus a GitHub Actions workflow for it:
make test-e2e
The live suite is opt-in through PERPLEXITY_AT_HOME_RUN_E2E=true so normal CI
stays fast and deterministic.
Repository Layout
src/perplexity_at_home/
agents/
quick_search/
pro_search/
deep_research/
core/ # persistence + serializer helpers
dashboard/ # packaged Streamlit app
tools/ # Tavily factories and normalization
settings.py # Pydantic settings + model selection
cli.py # package CLI
docs/ # MkDocs + Read the Docs
examples/ # runnable demos
infra/ # local Docker Compose
tests/ # unit, integration, and gated live E2E tests
Docs, Release, and Quality Gates
- Docs build with MkDocs Material and publish through Read the Docs.
- GitHub Actions cover CI, docs, live E2E, and release publishing.
pdm buildproduces the wheel and source distribution for PyPI.make lint,make test,make docs-build, andmake release-checkare the main local gates.
Releasing To PyPI
The canonical release path is a version tag from main:
git tag -a vX.Y.Z -m "vX.Y.Z"
git push origin vX.Y.Z
The Release workflow then:
- installs the locked environment
- runs Ruff, pytest, and the docs build
- builds the wheel and sdist
- runs
twine check - publishes to PyPI through GitHub trusted publishing
- creates the matching GitHub release
There is also a manual workflow_dispatch path for release preflight checks
when you want to validate the release job without pushing a tag.
Full package docs live at https://perplexity-at-home.readthedocs.io/.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file perplexity_at_home-0.1.1.tar.gz.
File metadata
- Download URL: perplexity_at_home-0.1.1.tar.gz
- Upload date:
- Size: 121.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
178c4032fc5f9324f61e29e2b78e2edd3525994c77ea0d348e544e7a3cd4cc9e
|
|
| MD5 |
e37e1bb21316c854548907c528a9dc1b
|
|
| BLAKE2b-256 |
86f96688aec16baf1ff9e6411c5dae9d3641b115d98bde743dc70ec180b973bc
|
Provenance
The following attestation bundles were made for perplexity_at_home-0.1.1.tar.gz:
Publisher:
release.yml on pr1m8/perplexity-at-home
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
perplexity_at_home-0.1.1.tar.gz -
Subject digest:
178c4032fc5f9324f61e29e2b78e2edd3525994c77ea0d348e544e7a3cd4cc9e - Sigstore transparency entry: 1365271890
- Sigstore integration time:
-
Permalink:
pr1m8/perplexity-at-home@8858b201584decfe92134481a8591b4ace185ca3 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/pr1m8
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@8858b201584decfe92134481a8591b4ace185ca3 -
Trigger Event:
push
-
Statement type:
File details
Details for the file perplexity_at_home-0.1.1-py3-none-any.whl.
File metadata
- Download URL: perplexity_at_home-0.1.1-py3-none-any.whl
- Upload date:
- Size: 136.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0df6970975ba0a6c8538e5d47719efb5361e50f517d3599354c5dd25351332aa
|
|
| MD5 |
dd6091d065ba6f24eb98f9efa9d1f3d3
|
|
| BLAKE2b-256 |
73fada35df3fd4a51cf7b4a915faa8fc1568f4dfaaffb44812649be8b209f107
|
Provenance
The following attestation bundles were made for perplexity_at_home-0.1.1-py3-none-any.whl:
Publisher:
release.yml on pr1m8/perplexity-at-home
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
perplexity_at_home-0.1.1-py3-none-any.whl -
Subject digest:
0df6970975ba0a6c8538e5d47719efb5361e50f517d3599354c5dd25351332aa - Sigstore transparency entry: 1365271973
- Sigstore integration time:
-
Permalink:
pr1m8/perplexity-at-home@8858b201584decfe92134481a8591b4ace185ca3 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/pr1m8
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@8858b201584decfe92134481a8591b4ace185ca3 -
Trigger Event:
push
-
Statement type: