AI agent framework for data analysis — write and execute Python code to answer questions about data
Project description
parsimony-agents
Build AI agents that discover, fetch, and analyze data.
Why parsimony-agents?
LLM frameworks are generic by design. parsimony-agents is purpose-built for data analysis: agents write and execute Python code against typed data connectors, track provenance for every data fetch, and produce reproducible datasets and Altair visualizations. Works with any LLM provider supported by LiteLLM (OpenAI, Anthropic, Google, Azure, local models, and more).
Quick Start
from parsimony_agents import Agent
from parsimony import discover
connectors = discover.load_all().bind_env()
agent = Agent(
model="claude-sonnet-4-6",
connectors=connectors,
)
result = await agent.ask("Show me US GDP trends over the last 20 years")
print(result.text) # Natural language response
print(result.datasets) # {"us_gdp": <DataFrame>}
print(result.code) # {"main": Script(...), ...} — named scripts keyed by notebook name
Installation
pip install parsimony-agents
Requires parsimony (installed automatically as a dependency).
Features
Code execution with provenance
Agents write Python code that runs in a sandboxed executor. Every data fetch is tracked with full provenance — source, parameters, timestamps.
# Agent writes this code automatically:
result = await client["fred_fetch"](series_id="GDPC1", observation_start="2005-01-01")
gdp = result.data # pandas DataFrame with provenance attached
Composable data sources
Plug in any combination of data sources via parsimony connectors:
from parsimony import Connectors, discover
from parsimony_fred import CONNECTORS as FRED
from parsimony_sdmx import CONNECTORS as SDMX
from parsimony_fmp import CONNECTORS as FMP
# Either compose explicitly...
connectors = Connectors.merge(
FRED.bind(api_key="..."),
SDMX,
FMP.bind(api_key="..."),
)
# ...or autodiscover everything installed and bind from env vars.
connectors = discover.load_all().bind_env()
agent = Agent(
model="claude-sonnet-4-6",
connectors=connectors,
)
Two consumption modes
Simple mode — ask a question, get a structured result:
result = await agent.ask("Compare Apple and Microsoft revenue growth")
result.text # str — natural language analysis
result.datasets # dict[str, Dataset] — returned datasets
result.charts # dict[str, Chart] — returned charts
result.code # dict[str, Script] — named scripts (order preserved)
result.ok # bool — True if no errors
Streaming mode — consume events as they arrive (see examples/event_stream.py for a runnable version):
async for event in agent.run("Analyze S&P 500 returns"):
match event.type:
case "text_delta":
print(event.content, end="", flush=True)
case "tool_event" if event.completed:
print(f"\n[Tool: {event.tool_name}]")
case "error":
print(f"\nError: {event.message}")
Multi-turn conversations
State persists across calls — the agent remembers previous data and code:
await agent.ask("Fetch quarterly US GDP since 2010")
await agent.ask("Now calculate year-over-year growth rates")
result = await agent.ask("Plot the growth rates as a bar chart")
Notebooks and artifacts
Agents organize code into notebooks (editable, re-executable cells) and produce typed artifacts:
- Dataset — a curated dataset with metadata, provenance, and version tracking
- Chart — an Altair/Vega-Lite visualization linked to its source dataset
Built-in tools
| Tool | Description |
|---|---|
return_notebook |
Write notebook cells to disk |
edit_notebook |
Edit individual cells within an existing notebook |
dry_execute_code |
Preview code output without committing to state |
write_file |
Write a file to the working directory |
edit_file |
Apply a patch to an existing file |
read_file |
Read a file from the working directory |
read_data |
Fetch data from a bound connector |
list_files |
List files in the working directory |
restart_kernel |
Clear the executor namespace |
return_dataset |
Finalize a dataset as a deliverable |
return_chart |
Finalize a chart as a deliverable |
return_report |
Finalize a report document as a deliverable |
edit_report |
Edit an in-progress report |
refresh |
Re-fetch connector data |
output_read |
Read a previously returned artifact |
output_search |
Semantic search across outputs (requires [rag] extra) |
Architecture
parsimony (connectors, catalog, Result model)
|
parsimony-agents (this package)
|
+-- Agent — LLM loop, tool orchestration
+-- CodeExecutor — in-process Python execution; workspace files are the notebook source of truth
+-- Notebooks — editable, re-executable code cells
+-- Artifacts — typed deliverables (datasets, charts, reports)
+-- OutputFactory — value -> typed output dispatch
+-- RAG (optional) — semantic + keyword search over outputs
Power Usage
For full control, use Agent directly with explicit configuration:
from parsimony_agents import Agent
from parsimony_agents.agent.config import AgentGuardrails
from parsimony_agents.execution.executor import CodeExecutor
from parsimony_agents.execution.factory import OutputFactory
agent = Agent(
model_config={"model": "claude-sonnet-4-6", "api_key": "..."},
instructions="You are a specialized economic research agent...",
code_executor=CodeExecutor(cwd="/tmp/work", output_factory=OutputFactory(local_dir="/tmp/work")),
output_factory=OutputFactory(local_dir="/tmp/work"),
guardrails=AgentGuardrails(max_iterations=30, max_execution_time_s=120.0),
connectors=my_connectors,
)
Optional extras
pip install parsimony-agents[rag] # ChromaDB + Tantivy for semantic search
pip install parsimony-agents[sql] # DuckDB for SQL over DataFrames
pip install parsimony-agents[display] # Rich terminal output for streaming events
pip install parsimony-agents[all] # Everything
Supported LLM Providers
parsimony-agents uses LiteLLM for LLM access, which supports 100+ providers:
| Provider | Model example |
|---|---|
| Anthropic | claude-sonnet-4-6 |
| OpenAI | gpt-4o |
gemini/gemini-2.0-flash |
|
| Azure | azure/gpt-4o |
| Local (Ollama) | ollama/llama3 |
Pass any LiteLLM-compatible model string to Agent(model="...").
Troubleshooting
Missing LLM API key: Set the appropriate environment variable for your provider (ANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY, etc.) or pass api_key= to the Agent constructor.
Code execution errors: The agent executes Python code in-process. If you see import errors, ensure the required packages are installed in your environment (e.g., pandas, numpy).
Timeout errors: For long-running analyses, increase the guardrails: Agent(guardrails=AgentGuardrails(max_execution_time_s=600.0)).
Streaming not printing: Use stream_to_display() for formatted terminal output, or iterate agent.run() events manually.
Documentation
Comprehensive guides for developing, deploying, and operating parsimony-agents:
Start with Documentation Index → — Choose your path by role (API developer, operations, architect, contributor)
| Guide | Purpose |
|---|---|
| ARCHITECTURE.md | System design, components, data flow, extension points |
| API.md | Complete API reference for Agent, CodeExecutor, artifacts, and tools |
| RUNBOOK.md | Deployment, monitoring, performance tuning, and troubleshooting |
| COMMANDS.md | Development commands: testing, linting, building, packaging |
| CODEMAPS.md | Code structure, module organization, and public API exports |
License
Apache 2.0
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 parsimony_agents-0.1.0.tar.gz.
File metadata
- Download URL: parsimony_agents-0.1.0.tar.gz
- Upload date:
- Size: 423.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7ecb3666de991502cfe74924c840c33e29a51a74ce2723dc2868cd1426819736
|
|
| MD5 |
d16c01695146f0aaec1d3d9c5fa81e17
|
|
| BLAKE2b-256 |
34b34a55441c6bb53c8c4a26ff062d3aa24f17f2466cd6aa2de0f35de1c8b06a
|
Provenance
The following attestation bundles were made for parsimony_agents-0.1.0.tar.gz:
Publisher:
publish.yml on ockham-sh/parsimony-agents
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
parsimony_agents-0.1.0.tar.gz -
Subject digest:
7ecb3666de991502cfe74924c840c33e29a51a74ce2723dc2868cd1426819736 - Sigstore transparency entry: 1643634989
- Sigstore integration time:
-
Permalink:
ockham-sh/parsimony-agents@2a1d0df211a0014f6f57e0c1768b710f817f298a -
Branch / Tag:
refs/heads/main - Owner: https://github.com/ockham-sh
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@2a1d0df211a0014f6f57e0c1768b710f817f298a -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file parsimony_agents-0.1.0-py3-none-any.whl.
File metadata
- Download URL: parsimony_agents-0.1.0-py3-none-any.whl
- Upload date:
- Size: 226.2 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 |
f742f4421f42cb6db81a08d9207440784e6be980e7e273b13e22a9eea465f649
|
|
| MD5 |
1683d355dc720c7223db25d8ef793b66
|
|
| BLAKE2b-256 |
9333612f5963dd53fcbf0d3b82c40dfc38fde2a68883bf50a185b04a81da6f31
|
Provenance
The following attestation bundles were made for parsimony_agents-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on ockham-sh/parsimony-agents
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
parsimony_agents-0.1.0-py3-none-any.whl -
Subject digest:
f742f4421f42cb6db81a08d9207440784e6be980e7e273b13e22a9eea465f649 - Sigstore transparency entry: 1643635005
- Sigstore integration time:
-
Permalink:
ockham-sh/parsimony-agents@2a1d0df211a0014f6f57e0c1768b710f817f298a -
Branch / Tag:
refs/heads/main - Owner: https://github.com/ockham-sh
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@2a1d0df211a0014f6f57e0c1768b710f817f298a -
Trigger Event:
workflow_dispatch
-
Statement type: