Content compression for AI agents. Extract once, render per query.
Project description
Brief
Reading the web is expensive, in tokens, in time, in redundant work. Brief gives agents a shared layer for extracting and understanding content: webpages, videos, and PDFs get pulled once, summarized around the task at hand, and cached so any agent in your pipeline can reuse them instantly. Start with a headline, go deep only where it matters, and let the briefs accumulate as your system works.
Without Brief, your agent fetches a page, chunks it, summarizes it, and then finally gets to the actual question, burning tokens at every step. Brief collapses that into a single call that returns exactly as much as the agent needs, already shaped around the task.
from brief import brief
# ~9 tokens - enough to know if this page is worth reading
brief("https://fastapi.tiangolo.com/", "what is fastapi", depth=0)
# ~100 tokens - key points and top sections
brief("https://fastapi.tiangolo.com/", "what is fastapi", depth=1)
# ~700 tokens - full structured summary, re-ranked around your query
brief("https://fastapi.tiangolo.com/", "async support", depth=2)
Depth levels
The agent controls how much it reads:
depth=0 headline ~9 tokens "[WEBPAGE] FastAPI - high performance web framework"
depth=1 summary ~100 tokens + key points, top 3 sections
depth=2 detailed ~700 tokens + all sections, re-ranked by query
depth=3 full ~2000 tokens + complete extracted text
Every depth level reads from the same cached extraction. No re-fetching. When a new query is asked, Brief re-summarizes the cached content with the LLM, fast, because the expensive extraction is already done.
Works across content types
Brief handles webpages, videos, and PDFs with the same interface:
- Webpages - trafilatura strips navigation, ads, and scripts, leaving just the article. Falls back to httpx with browser headers, then optionally to Playwright for sites behind Cloudflare or bot protection (
pip install getbrief[playwright]). - Videos - yt-dlp fetches captions directly. If none exist, faster-whisper transcribes the audio locally. Falls back to video metadata (title, description, tags) when neither is available.
- PDFs - pymupdf extracts text page by page.
Common patterns
Scan many URLs cheaply, then read what matters
from brief import brief_batch, brief
headlines = brief_batch([
"https://docs.python.org/3/library/asyncio.html",
"https://fastapi.tiangolo.com/",
"https://flask.palletsprojects.com/",
], query="python async web framework", depth=0)
# Now only fetch detail on the one that looks relevant
detail = brief("https://fastapi.tiangolo.com/", "async support", depth=2)
Compare sources side by side
from brief import compare
result = compare(
["https://fastapi.tiangolo.com/", "https://flask.palletsprojects.com/"],
query="how do they handle middleware",
depth=2,
)
Check the cache before fetching
from brief import check_brief
data = check_brief("https://fastapi.tiangolo.com/")
# Returns the cached brief if it exists, None otherwise
Install
pip install getbrief
Brief uses any OpenAI-compatible LLM for summarization. Add your API key to a .env file — see Configuration. Free models work well.
Interfaces
Python
from brief import brief, brief_batch, compare, check_brief
CLI
brief --uri "https://example.com" --query "key takeaways"
brief --uri "https://example.com" --depth 0
brief --list
MCP
{
"mcpServers": {
"brief": {
"command": "uvx",
"args": ["--from", "getbrief", "brief-mcp"],
"env": {
"BRIEF_LLM_API_KEY": "sk-or-v1-your-key",
"BRIEF_LLM_BASE_URL": "https://openrouter.ai/api/v1",
"BRIEF_LLM_MODEL": "google/gemma-3-4b-it:free"
}
}
}
}
HTTP API
uvicorn brief.api:app --port 8080
The .briefs/ folder
Every brief is saved locally as soon as it's extracted:
.briefs/
├── fastapi-tiangolo-com.brief ← human-readable text
├── fastapi-tiangolo-com.brief.json ← structured data
└── _index.sqlite3 ← URI lookups
This makes .briefs/ a natural memory layer for your whole pipeline. If one agent briefs a URL, any other agent can reuse it instantly — no re-fetching needed. The more your system runs, the more it already knows.
.brief files use a clean, structured format designed for human readability:
═══ BRIEF ════════════════════════════════════════
FastAPI
https://fastapi.tiangolo.com/
Type: WEBPAGE | Extracted: 2026-02-22
─── SUMMARY ────────────────────────────────────
FastAPI is a modern, high-performance Python web framework...
─── KEY POINTS ──────────────────────────────
• Speed comparable to NodeJS and Go
• Built on Python type hints and Pydantic
• Automatic OpenAPI documentation
─── SECTIONS ──────────────────────────────────────
▸ FastAPI framework, high performance, easy to learn
▸ Fast to code: 200-300% speed increase
▸ Fewer bugs: 40% reduction in developer errors
─── LINKS ────────────────────────────────────────
→ Docs: https://fastapi.tiangolo.com
→ Typer: https://typer.tiangolo.com/
→ Uvicorn: https://www.uvicorn.dev
Configuration
Brief uses any OpenAI-compatible provider for summarization. Create a .env file in your project root:
# OpenRouter (one key, many models)
BRIEF_LLM_API_KEY=sk-or-v1-your-key
BRIEF_LLM_BASE_URL=https://openrouter.ai/api/v1
BRIEF_LLM_MODEL=google/gemma-3-4b-it:free
Also works with OpenAI, Ollama (local), and Groq. See .env.example for all options.
For videos without captions, Brief transcribes audio locally using faster-whisper. To use OpenAI's Whisper API instead:
BRIEF_STT_API_KEY=sk-your-openai-key
Contributing
Brief is designed to be easy to extend and contributions are welcome — whether that's a new content type, a better summarization strategy, or improvements to the CLI or API. New extractors live in brief/extractors/ and each one is just a single file implementing one function:
def extract(uri: str) -> list[dict[str, Any]]:
"""Return a list of chunks with 'text', 'start_sec', 'end_sec' keys."""
Adding support for a new type (audio, spreadsheets, etc.) is a single file addition. Contributions welcome.
Project details
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 getbrief-0.4.0.tar.gz.
File metadata
- Download URL: getbrief-0.4.0.tar.gz
- Upload date:
- Size: 30.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9c9b4087056c3448e11d64a656596b302d3ed8beb4a627fb41150dad296a811f
|
|
| MD5 |
500fac5f7e21f654ef346ae534bb411f
|
|
| BLAKE2b-256 |
93e73984dbcc560f5ddcaa5e1ea0a0323dfc23d5380c0cd132aa5a24fe585cae
|
Provenance
The following attestation bundles were made for getbrief-0.4.0.tar.gz:
Publisher:
publish.yml on aulesy/brief
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
getbrief-0.4.0.tar.gz -
Subject digest:
9c9b4087056c3448e11d64a656596b302d3ed8beb4a627fb41150dad296a811f - Sigstore transparency entry: 983294089
- Sigstore integration time:
-
Permalink:
aulesy/brief@c450f973a2dec1bde4a05fd0eae872b2a74faa8a -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/aulesy
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@c450f973a2dec1bde4a05fd0eae872b2a74faa8a -
Trigger Event:
release
-
Statement type:
File details
Details for the file getbrief-0.4.0-py3-none-any.whl.
File metadata
- Download URL: getbrief-0.4.0-py3-none-any.whl
- Upload date:
- Size: 32.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7dd1cfb4062ab6731c042e47e28b54c6f03ac19bc6f9b3b72801e36e006c5ff9
|
|
| MD5 |
3ed96318ff93de7a1a64bb2bb8132f02
|
|
| BLAKE2b-256 |
58dc97513a915217772b4a61a282522801a55dee0d5f2bad7729ab91c820bc93
|
Provenance
The following attestation bundles were made for getbrief-0.4.0-py3-none-any.whl:
Publisher:
publish.yml on aulesy/brief
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
getbrief-0.4.0-py3-none-any.whl -
Subject digest:
7dd1cfb4062ab6731c042e47e28b54c6f03ac19bc6f9b3b72801e36e006c5ff9 - Sigstore transparency entry: 983294100
- Sigstore integration time:
-
Permalink:
aulesy/brief@c450f973a2dec1bde4a05fd0eae872b2a74faa8a -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/aulesy
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@c450f973a2dec1bde4a05fd0eae872b2a74faa8a -
Trigger Event:
release
-
Statement type: