Cantus — A polyphonic framework for composing LLM agent harnesses (教學用)
Project description
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:
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.4.2
# Git source — escape hatch for tracking main, a feature branch, or a specific commit
pip install git+https://github.com/schola-cantorum/cantus@v0.4.2
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.4.2'
The serve extras (v0.4.0 — FastAPI app factory; pulls fastapi, uvicorn, pydantic-settings):
pip install 'cantus-agent[serve]==0.4.2'
Serve Quickstart (v0.4.0)
Spin up the bundled FastAPI app on 127.0.0.1:8765 with a fresh Registry:
from cantus 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.4.0"}
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?")
print(result.final_answer)
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?")
print(result.final_answer)
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?")
print(result.final_answer)
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?")
print(result.final_answer)
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?")
print(result.final_answer)
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?")
print(result.final_answer)
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.
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
@skillor subclassSkill. - Memory — conversation state and retrieval memory; ships
ShortTermMemory,BM25Memory,EmbeddingMemory.
Hook helpers (pre- / post-loop tooling, not protocol kinds):
- Analyzer — turn user input into a structured result before entering the agent loop. Use
@analyzeror subclassAnalyzer. - Validator — post-process the agent's output, returning a
Resultthat decides pass or retry. Use@validatoror subclassValidator.
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
Full docs live in docs/:
- Overview — architecture and design philosophy
- Quickstart — from zero to first agent in 10 minutes
- Protocols — design and usage of the two protocol kinds and the Analyzer / Validator hook helpers (workflow composition lives under
cantus.workflows) - Cookbook — patterns, error recipes, teaching tips
- llms.txt — 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:
- v0.2 → v0.3
- v0.3 → v0.3.1
- v0.3 → v0.3.2
- v0.3 → v0.3.3
- v0.3.3 → v0.3.4
- v0.3.4 → v0.3.5
- v0.3.5 → v0.3.6
- v0.3.6 → v0.4.0
- v0.4.0 → v0.4.1
- v0.4.1 → v0.4.2
The CHANGELOG.md lists everything else (additive features, internal changes, security notes).
License
ECL-2.0 — Educational Community License, Version 2.0. See LICENSE.
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 cantus_agent-0.4.3.tar.gz.
File metadata
- Download URL: cantus_agent-0.4.3.tar.gz
- Upload date:
- Size: 131.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ebbd5699918a3323ec6809d0b92c96e5f4357bb471c826b87446eeded80cbe3a
|
|
| MD5 |
33bd81412b01b2971ec6fd9256b79aab
|
|
| BLAKE2b-256 |
0c3c7d83db6ad09171fb7f082a8d74a298612a0c4b3fefc936a897215908f461
|
Provenance
The following attestation bundles were made for cantus_agent-0.4.3.tar.gz:
Publisher:
release.yml on schola-cantorum/cantus
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cantus_agent-0.4.3.tar.gz -
Subject digest:
ebbd5699918a3323ec6809d0b92c96e5f4357bb471c826b87446eeded80cbe3a - Sigstore transparency entry: 1582754258
- Sigstore integration time:
-
Permalink:
schola-cantorum/cantus@a48b6bb82efad7c6a0086abd251763c12995e419 -
Branch / Tag:
refs/tags/v0.4.3 - Owner: https://github.com/schola-cantorum
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@a48b6bb82efad7c6a0086abd251763c12995e419 -
Trigger Event:
release
-
Statement type:
File details
Details for the file cantus_agent-0.4.3-py3-none-any.whl.
File metadata
- Download URL: cantus_agent-0.4.3-py3-none-any.whl
- Upload date:
- Size: 94.5 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 |
a8724ff6945d9d59424573c7a4eaf97f11f72f63ecfdb5693830a28686c28a78
|
|
| MD5 |
b2fdd3a144f1d1cd69cfe30550f7aa69
|
|
| BLAKE2b-256 |
518cc2be0f3ec8f7b8a5d49030678cdedee5622277a525f2787ee227daf26de5
|
Provenance
The following attestation bundles were made for cantus_agent-0.4.3-py3-none-any.whl:
Publisher:
release.yml on schola-cantorum/cantus
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cantus_agent-0.4.3-py3-none-any.whl -
Subject digest:
a8724ff6945d9d59424573c7a4eaf97f11f72f63ecfdb5693830a28686c28a78 - Sigstore transparency entry: 1582754380
- Sigstore integration time:
-
Permalink:
schola-cantorum/cantus@a48b6bb82efad7c6a0086abd251763c12995e419 -
Branch / Tag:
refs/tags/v0.4.3 - Owner: https://github.com/schola-cantorum
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@a48b6bb82efad7c6a0086abd251763c12995e419 -
Trigger Event:
release
-
Statement type: