Skip to main content

Cantus — a polyphonic framework for composing LLM agent harnesses

PyPI version license ECL-2.0 Open In Colab

Cantus

A polyphonic framework for composing LLM agent harnesses — designed for teaching on Google Colab.

Cantus (Latin: song, chant) is a teaching-oriented LLM agent framework. Two protocol kinds (Skill / Memory) plus hook helpers (Analyzer / Validator) and the cantus.workflows building blocks let learners and operators compose agents on Google Colab, backed by 4-bit-quantised Gemma 4 models.

The Chinese-speaking LLM community refers to prompt engineering as yǒng chàng — literally "to chant" or "to incant". Cantus treats agent composition as a polyphonic chant — each protocol is a voice, and together they form an agent that sings back.

In Cantus, your code IS the chant — every Skill, Memory, and Agent is a verse that wields the LLM. The PyPI name cantus-agent makes the relationship explicit: you chant, the agent answers.

Open in Colab — 5-minute path

The fastest way to experience Cantus is to launch the bundled notebooks directly:

Notebook Audience One-click launch
notebooks/task_template.ipynb End user — build your first agent Open In Colab
notebooks/admin_setup.ipynb Administrator — mirror Gemma 4 weights to Drive (run once before downstream users) Open In Colab

See notebooks/README.md for the recommended order and tag-pinning conventions.

Install

# PyPI (recommended — reproducible, no Git clone). Distribution name is `cantus-agent`; import name remains `cantus`.
pip install cantus-agent==0.6.0

# Git source — escape hatch for tracking main, a feature branch, or a specific commit
pip install git+https://github.com/schola-cantorum/cantus@v0.6.0
pip install git+https://github.com/schola-cantorum/cantus@main
pip install git+https://github.com/schola-cantorum/cantus@<commit-sha>

The runtime extras (Gemma 4 + transformers + bitsandbytes) require:

pip install 'cantus-agent[runtime]==0.6.0'

The serve extras (v0.4.0 — FastAPI app factory; pulls fastapi, uvicorn, pydantic-settings):

pip install 'cantus-agent[serve]==0.6.0'

Serve Quickstart (v0.4.0)

Spin up the bundled FastAPI app on 127.0.0.1:8765 with a fresh Registry:

from cantus.serve import serve
from cantus.core.registry import Registry
import uvicorn
app = serve(Registry())
uvicorn.run(app, host="127.0.0.1", port=8765)

Hit the health endpoint to confirm the server is up:

curl http://localhost:8765/health
# {"status":"ok","cantus_version":"0.6.0"}

Desktop (Win / macOS / Linux)

Desktop and laptop users — see docs/quickstart-desktop.md for a 5-minute API-key-backed walkthrough that works on Windows, macOS, and Linux. The Colab path below remains the recommended route for 4-bit local Gemma.

30-second Quickstart

from cantus import skill, Agent, mount_drive_and_load

@skill
def add(a: int, b: int) -> int:
    """Add two integers."""
    return a + b

model_handle = mount_drive_and_load(variant="E4B")
agent = Agent(model=model_handle)

result = agent.run("What is 17 plus 25?")
final = result.stream[-1]  # FinalAnswerAction when the loop converged
print(getattr(final, "answer", final))

Multi-provider quickstart (v0.2.1)

Tier 2 ChatModel adapters let you point the same Agent at OpenAI, Anthropic, Google Gemini, Groq, or NVIDIA NIM instead of local Gemma. You MUST wrap a ChatModel with ChatModelAsHandle before passing it to Agent — the Agent only speaks the Tier 1 .generate(prompt) -> str protocol.

OpenAI (install pip install 'cantus-agent[openai]', set OPENAI_API_KEY):

from cantus import Agent, ChatModelAsHandle, load_chat_model

chat = load_chat_model("openai/gpt-4o-mini")
agent = Agent(model=ChatModelAsHandle(chat, system="You are terse."))
result = agent.run("What is 17 plus 25?")
final = result.stream[-1]  # FinalAnswerAction when the loop converged
print(getattr(final, "answer", final))

Anthropic (install pip install 'cantus-agent[anthropic]', set ANTHROPIC_API_KEY):

from cantus import Agent, ChatModelAsHandle, load_chat_model

chat = load_chat_model("anthropic/claude-sonnet-4-6")
agent = Agent(model=ChatModelAsHandle(chat, system="You are terse."))
result = agent.run("What is 17 plus 25?")
final = result.stream[-1]  # FinalAnswerAction when the loop converged
print(getattr(final, "answer", final))

Google Gemini (install pip install 'cantus-agent[google]', set GOOGLE_API_KEY; uses google-genai, not the legacy google-generativeai):

from cantus import Agent, ChatModelAsHandle, load_chat_model

chat = load_chat_model("google/gemini-2.0-flash")
agent = Agent(model=ChatModelAsHandle(chat, system="You are terse."))
result = agent.run("What is 17 plus 25?")
final = result.stream[-1]  # FinalAnswerAction when the loop converged
print(getattr(final, "answer", final))

Groq (install pip install 'cantus-agent[groq]', set GROQ_API_KEY):

from cantus import Agent, ChatModelAsHandle, load_chat_model

chat = load_chat_model("groq/llama-3.3-70b-versatile")
agent = Agent(model=ChatModelAsHandle(chat, system="You are terse."))
result = agent.run("What is 17 plus 25?")
final = result.stream[-1]  # FinalAnswerAction when the loop converged
print(getattr(final, "answer", final))

NVIDIA NIM (install pip install 'cantus-agent[openai]' — NIM runs on the OpenAI SDK, so there is no cantus-agent[nvidia] extras; set NVIDIA_API_KEY):

from cantus import Agent, ChatModelAsHandle, load_chat_model

chat = load_chat_model("nvidia/meta/llama-3.3-70b-instruct")
agent = Agent(model=ChatModelAsHandle(chat, system="You are terse."))
result = agent.run("What is 17 plus 25?")
final = result.stream[-1]  # FinalAnswerAction when the loop converged
print(getattr(final, "answer", final))

cantus-agent[providers] installs the four primary adapters (OpenAI / Anthropic / Google / Groq) at once. NVIDIA NIM ships through cantus-agent[openai] since the NIM endpoint is OpenAI-compatible. cantus intentionally does not depend on LiteLLM at any layer, and the Google extras pulls only google-genai (the new unified Gemini API SDK), never google-generativeai.

Cantus protocol kinds (Skill, Memory) plus Analyzer / Validator hook helpers and cantus.workflows building blocks

Two protocol kinds + hook helpers + workflows building blocks

Two protocol kinds (the things cantus formally registers and dispatches):

  • Skill — a function the agent can call (tool use). Decorate with @skill or subclass Skill.
  • Memory — conversation state and retrieval memory; ships ShortTermMemory, BM25Memory, EmbeddingMemory, MarkdownMemory, plus the AutoMemory wrapper that exposes any backend to the LLM as four Skills.

Hook helpers (pre- / post-loop tooling, not protocol kinds):

  • Analyzer — turn user input into a structured result before entering the agent loop. Use @analyzer or subclass Analyzer.
  • Validator — post-process the agent's output, returning a Result that decides pass or retry. Use @validator or subclass Validator.

Workflows building block:

  • cantus.workflows — composition templates that chain skills, analyzers, and validators into a fixed flow. No longer a protocol kind in v0.3.0; pick the building block that fits your scenario.

Documentation

The docs are published as a VitePress site in English and 繁體中文, with the source under docs/site/. Run npm run docs:build to build it locally. The docs.yml workflow builds both locales on every push and pull request; publishing to Cloudflare Pages is configured outside this repository, so no deploy step lives here. Two other artifacts round it out: a NotebookLM-ready corpus under docs/api/, and an interactive manual at cantus-manual.html.

The site is the canonical home for the overview, quickstart, protocol guides, and cookbook. Two references live outside it:

  • llms.txt — single-file priming document for external LLMs
  • Developer LLM Wiki — internal contributor knowledge base (research, coding style, architecture, future work)

Upgrade Guides

Per-version migration guides for breaking changes between adjacent releases:

The CHANGELOG.md lists everything else (additive features, internal changes, security notes).

License

ECL-2.0 — Educational Community License, Version 2.0. See LICENSE.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cantus_agent-0.6.0.tar.gz (213.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cantus_agent-0.6.0-py3-none-any.whl (155.6 kB view details)

Uploaded Python 3

File details

Details for the file cantus_agent-0.6.0.tar.gz.

File metadata

  • Download URL: cantus_agent-0.6.0.tar.gz
  • Upload date:
  • Size: 213.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for cantus_agent-0.6.0.tar.gz
Algorithm Hash digest
SHA256 bd5e702b743bd48861a1f610f93e873070a743ca6081dffdf6c972f0716b6faa
MD5 b38885abbd6b35e2f1fc3c8ce0b45312
BLAKE2b-256 642370e599a62280fc36043c71ff61411c7663c9df428d94ba39951f850af1be

See more details on using hashes here.

Provenance

The following attestation bundles were made for cantus_agent-0.6.0.tar.gz:

Publisher: release.yml on schola-cantorum/cantus

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file cantus_agent-0.6.0-py3-none-any.whl.

File metadata

  • Download URL: cantus_agent-0.6.0-py3-none-any.whl
  • Upload date:
  • Size: 155.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for cantus_agent-0.6.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e7c8a9c38fb7c20e085134e10bdc8af2cd97663d2c75bd2f0685975255359a5d
MD5 0d1a532c213292afc8d2d0aef9298dc7
BLAKE2b-256 4eda700ebd2c2f00d70f1200e0c432f77abf4e6149c77221ff6cf7327bfd2b7f

See more details on using hashes here.

Provenance

The following attestation bundles were made for cantus_agent-0.6.0-py3-none-any.whl:

Publisher: release.yml on schola-cantorum/cantus

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.6.0 This release

2 files

0.5.0

2 files

0.4.7

2 files

0.4.4

2 files

0.4.3

2 files

0.4.2

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page