Minimal Python framework for composing agents, tools, and multi-agent workflows
Project description
Quark Agents
Experimental. An ongoing exploration into the simplest possible agentic framework — use it to learn, hack, and break agentic things.
Minimal Python framework for composing agents, tools, and multi-agent workflows. Define agents with a system prompt and tools, then compose them using the >> operator. Provider-agnostic via litellm.
Despite being a single ~350-line file, you get:
- OpenTelemetry tracing
- 100+ model providers via litellm
- Multi-agent workflows with
>> - Parallel fan-out and tool execution
- Async-first (
arun,astream) — thousands of concurrent agents on one event loop - Stateless mode — pass history in, get it back, deploy anywhere
- Streaming
- Conversation memory
Install
pip install quark-agents
# From source
git clone https://github.com/awslabs/quark-agents
cd quark-agents
pip install .
# With OpenTelemetry support
pip install "quark-agents[otel]"
Install with uv
git clone https://github.com/awslabs/quark-agents
cd quark-agents
uv venv
source .venv/bin/activate
# Core + dev dependencies (pytest, mkdocs)
uv pip install ".[dev]"
# With OpenTelemetry
uv pip install ".[dev,otel]"
# With AWS Bedrock support
uv pip install ".[dev,bedrock]"
# All extras
uv pip install ".[dev,otel,bedrock]"
Note: Editable installs (
-e) requiresetuptools>=75. If you seeModuleNotFoundError: No module named 'setuptools.backends', make surepyproject.tomlhasrequires = ["setuptools>=75"]under[build-system], or use a non-editable install (uv pip install ".[dev]"without-e).
Usage
Single agent
from quark import Agent
agent = Agent(
system="You are a helpful assistant.",
model="gpt-5.4", # or any litellm-supported model
name="assistant",
)
print(agent.run("What is the capital of France?"))
Agent with tools
def get_weather(city: str) -> str:
"""Get the current weather for a city."""
return f"Sunny, 22°C in {city}"
agent = Agent(
system="You are a weather assistant.",
model="gpt-5.4",
tools={"get_weather": get_weather},
)
print(agent.run("What's the weather in Paris?"))
Pipelines with >>
Chain agents and plain functions using >>. Output of each step becomes input to the next.
from quark import Agent
def fetch_article(url: str) -> str:
"""Fetch article content from a URL."""
return "..." # your fetch logic
summarizer = Agent(system="Summarize the article in 3 bullet points.", name="summarizer")
critic = Agent(system="List 2 weaknesses in this summary.", name="critic")
editor = Agent(system="Write a final improved summary given the feedback.", name="editor")
pipeline = fetch_article >> summarizer >> critic >> editor
result = pipeline.run("https://example.com/article")
Parallel fan-out with lists
Wrap steps in a list to run them in parallel. Their outputs are combined and passed to the next step.
pipeline = fetch_article >> summarizer >> [critic, fact_checker] >> editor
result = pipeline.run("https://example.com/article")
Composing workflows
research = fetch_article >> summarizer
review = [critic, fact_checker] >> editor
pipeline = research >> review
result = pipeline.run("https://example.com/article")
Streaming
for chunk in agent.stream("Tell me a story."):
print(chunk, end="", flush=True)
Provider-agnostic
# OpenAI
agent = Agent(model="gpt-5.4")
# Anthropic
agent = Agent(model="claude-opus-4-6")
# AWS Bedrock
agent = Agent(model="bedrock/anthropic.claude-3-5-haiku-20241022-v1:0")
# Gemini
agent = Agent(model="gemini/gemini-2.0-flash")
# Ollama (local)
agent = Agent(model="ollama/llama3")
Observability (OpenTelemetry)
Set environment variables — tracing is enabled automatically.
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317
export OTEL_SERVICE_NAME=my-app
Every Agent.run(), Workflow.run(), and tool call emits OTel spans. Compatible with Jaeger, Honeycomb, Grafana Tempo, Datadog, and any OTLP-compatible backend.
API
Agent(*, system, tools, model, max_turns, name)
| Parameter | Default | Description |
|---|---|---|
system |
"You are a helpful assistant." |
System prompt |
tools |
{} |
Dict of {name: callable} |
model |
"gpt-5.4" |
Any litellm model string |
max_turns |
10 |
Max LLM iterations per run() call |
name |
"agent" |
Name used in traces and pipeline display |
Methods:
agent.run(user, history=None)— blocking; passhistory=[]for stateless mode → returns(response, history)agent.arun(user, history=None)— async; run thousands concurrently withasyncio.gatheragent.stream(user)— yields tokens as they arriveagent.astream(user)— async streamingagent.reset()— clears conversation history, keeps system prompt
Workflow
Created automatically by >>. Call .run(input: str) -> str to execute.
workflow = agent_a >> agent_b >> agent_c
result = workflow.run("input")
Tests
# Unit tests (no API calls)
pytest tests/
# Integration tests (requires API credentials)
pytest tests/ -m integration
If using uv, prefix with uv run to ensure the venv's Python is used (avoids conflicts with conda or system Python):
uv run pytest tests/
uv run pytest tests/ -m "not integration"
uv run pytest tests/ -m integration
Why Quark?
Named after the smallest known fundamental particles — quarks need gluons to bind them together. Quark is the minimal binding layer for AI agents.
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 quark_agents-0.3.0.tar.gz.
File metadata
- Download URL: quark_agents-0.3.0.tar.gz
- Upload date:
- Size: 16.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
37c74d6630a403dd54eb74c1d8e454bb3ab3af626e7c8f660f240d9a0de5b855
|
|
| MD5 |
8a033f3bbdaafcf85a9489e8ac6e0bcc
|
|
| BLAKE2b-256 |
b4999a76cc67f90df63a55cbb65c1aa0593d22022a66b9c983134125a2bea4ca
|
Provenance
The following attestation bundles were made for quark_agents-0.3.0.tar.gz:
Publisher:
publish.yml on awslabs/quark-agents
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
quark_agents-0.3.0.tar.gz -
Subject digest:
37c74d6630a403dd54eb74c1d8e454bb3ab3af626e7c8f660f240d9a0de5b855 - Sigstore transparency entry: 1518881687
- Sigstore integration time:
-
Permalink:
awslabs/quark-agents@2d6e3813ea8b544b4fdad26e74609b5781f70f15 -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/awslabs
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@2d6e3813ea8b544b4fdad26e74609b5781f70f15 -
Trigger Event:
release
-
Statement type:
File details
Details for the file quark_agents-0.3.0-py3-none-any.whl.
File metadata
- Download URL: quark_agents-0.3.0-py3-none-any.whl
- Upload date:
- Size: 12.0 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 |
978effd0e6a791348cfc1a5b74d3123c52f198851736d015e63c05cbad5950be
|
|
| MD5 |
5437d8a44609288d25f2f32e38d737fe
|
|
| BLAKE2b-256 |
1afdca87c0a7f5a3eea070422639a5b2ed20fdcd343de76412a9b1dbf786b053
|
Provenance
The following attestation bundles were made for quark_agents-0.3.0-py3-none-any.whl:
Publisher:
publish.yml on awslabs/quark-agents
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
quark_agents-0.3.0-py3-none-any.whl -
Subject digest:
978effd0e6a791348cfc1a5b74d3123c52f198851736d015e63c05cbad5950be - Sigstore transparency entry: 1518881705
- Sigstore integration time:
-
Permalink:
awslabs/quark-agents@2d6e3813ea8b544b4fdad26e74609b5781f70f15 -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/awslabs
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@2d6e3813ea8b544b4fdad26e74609b5781f70f15 -
Trigger Event:
release
-
Statement type: