Skip to main content

Self-improving agents with closed-loop learning — agents that learn to get it right

Project description

CannyForge

Reliability memory for tool-using LLM agents.

CannyForge watches your agent make mistakes, learns corrections, and injects them as SystemMessages before each LLM call — no retraining required.

Agent makes errors → CannyForge learns corrections → Agent stops repeating them

CannyForge demo: baseline → improved tool accuracy on real LLM

Quick Start (LangGraph)

from cannyforge import CannyForge
from cannyforge.adapters.langgraph import CannyForgeMiddleware
from langgraph.prebuilt import create_react_agent

forge = CannyForge()
middleware = CannyForgeMiddleware(forge)
agent = create_react_agent(model, tools,
    pre_model_hook=middleware.before_model,
    post_model_hook=middleware.after_model)

# Just run tasks. CannyForge records errors via after_model.
# After learning, before_model injects corrections as SystemMessages.

v0.3.1 — Multi-Turn Benchmark Release

This release ships FSI-80: a 15-scenario multi-turn tool-use benchmark with programmatic error injection, six anti-pattern detectors, five-dimensional scoring, four-condition ablation, and Pass^k reliability measurement.

See RELEASE-v0.3.1.md for the full release notes and canonical benchmark results.

How It Works

  1. Record errorsafter_model detects tool failures and records them
  2. Learn correctionsrun_learning_cycle() clusters errors and generates specific correction text (template or LLM-generated)
  3. Inject correctionsbefore_model prepends a SystemMessage with all active corrections before each LLM call
  4. Track effectiveness — EIR/ECR tracking records both successful corrections and ineffective injections; a stability gate stops injecting corrections below 20% effectiveness after 5+ observations

The correction is specific and actionable:

[CANNYFORGE] Learned rules for this request:
- When the task involves report, summary, sales, use `generate_report`, NOT `get_data`.
  Example: "Create a summary of Q4 sales performance"

Demo

pip install langgraph langchain-openai
# Set LLM_API_KEY in .env
python scenarios/demo_cannyforge.py

Runs a full correction-learning pipeline on tool-use tasks: baseline → learn from errors → re-run with corrections injected. See the benchmark section below for the full FSI-80 multi-turn evaluation across coding, data, and MCP domains.

Benchmark

No published benchmark measures arg_quality, sequence adherence, or error recovery at the tool-call level with programmatic verification — FSI-80 is the first.

15 multi-turn scenarios × 4 ablation conditions × 5 scoring dimensions × 6 failure-mode detectors × 3 Pass^k reliability trials. Coding, data analysis, and MCP orchestration domains.

              composite   arg_quality   Pass^1   Pass^3   inj_rate
baseline      0.924       0.837         0.733    0.667    0%
static        0.925       0.867         0.867    0.800    0%
cannyforge    0.964       1.000         0.867    0.800    27%
static+cf     0.962       1.000         0.867    0.867    27%

static+cf lifts composite +0.038 over baseline, holds Pass^3 at 0.867 with zero reliability degradation (baseline degrades -6.6pp from Pass^1 to Pass^3). CF alone lifts arg_quality from 0.837 to 1.000.

python benchmark/scenario_harness.py \
    --model deepseek-v4-flash --no-think \
    --domains coding data mcp --passk 3

See RELEASE-v0.3.1.md for the full ablation breakdown and docs/agentic-capacity-framework.md for the benchmark design framework.

Install

pip install cannyforge           # from PyPI

Or from source:

git clone https://github.com/cannyforge/cannyforge.git
cd cannyforge
pip install -e .

Scenarios

Script Purpose
scenarios/demo_cannyforge.py Canonical demo — full pipeline: baseline → learn → improve
scenarios/demo_langgraph_tool_use.py Minimal quickstart — 3-line integration
scenarios/demo.py Animated terminal demo (internal skill system)

Older demo scripts are in scenarios/archive/ for reference.

Framework Coverage

Adapter Correction loop What it does Path
LangGraph Full middleware: injects corrections before model calls, records errors after cannyforge/adapters/langgraph.py
LangChain Skill wrapper: exposes a CF skill as a BaseTool cannyforge/adapters/langchain.py
CrewAI Skill wrapper: exposes a CF skill as a CrewAI tool cannyforge/adapters/crewai.py
MCP Skill execution via MCP server protocol cannyforge/mcp_server.py
OpenAI Agents SDK planned
Anthropic SDK planned

The correction-learning loop (inject → record → cluster → generalize → re-inject) is currently only active through the LangGraph middleware. The LangChain and CrewAI adapters let you run CF skills inside those frameworks; they don’t feed errors back into the learning pipeline.

CannyForge is designed to sit on top of existing agent frameworks rather than replace them.

Core Architecture

Corrections Pipeline (LangGraph integration)

cannyforge/corrections.py    — Correction dataclass + CorrectionGenerator
cannyforge/adapters/langgraph.py — CannyForgeMiddleware (pre/post model hooks)
cannyforge/knowledge.py      — KnowledgeBase stores corrections + rules
cannyforge/learning.py       — PatternDetector + LearningEngine
cannyforge/core.py           — CannyForge orchestrator

CorrectionGenerator turns error clusters into actionable text:

  • Template mode (no LLM): groups failures by tool within error_type, extracts keywords from tool name + expected arg values, formats tool-specific guidance
  • LLM mode: sends error cluster to LLM asking for a generalized rule covering unseen tasks

CannyForgeMiddleware hooks into LangGraph's create_react_agent:

  • before_model: injects always-on corrections + conditional rules as a SystemMessage
  • after_model: records tool failures, tracks correction effectiveness

Internal Skill System

CannyForge also includes a declarative skill system for standalone use (without LangGraph):

  • Skills defined via SKILL.md files (AgentSkills.io spec)
  • Three-tier execution: custom handler → LLM multi-step → template fallback
  • PATTERN_LIBRARY with condition-based rules for internal context signals
  • Rule lifecycle: ACTIVE → PROBATION → DORMANT → resurrection
from cannyforge import CannyForge
forge = CannyForge()
result = forge.execute("Write an email about the 3 PM meeting")

See scenarios/demo.py for the animated terminal demo of this path.

How Learning Works

1. Error Recording

# Via middleware (automatic):
agent = create_react_agent(llm, tools, post_model_hook=middleware.after_model)

# Or manual:
forge.learning_engine.record_error(
    skill_name="tool_use",
    task_description="Create a Q4 summary",
    error_type="WrongToolError",
    error_message="Called get_data instead of generate_report",
    context_snapshot={...},
)

2. Learning Cycle

metrics = forge.run_learning_cycle(min_frequency=2, min_confidence=0.3)
# Produces:
#   - Condition-based rules (for internal skill system)
#   - Corrections (for LangGraph injection)

3. Correction Injection

corrections = forge.knowledge_base.get_corrections("tool_use")
# [Correction(content="When task involves report, summary... use generate_report, NOT get_data")]

# Automatically injected by middleware.before_model() as a SystemMessage

Run Tests

pytest tests/ -v

Project Structure

cannyforge/
├── cannyforge/
│   ├── core.py              # CannyForge orchestrator
│   ├── corrections.py       # Correction + CorrectionGenerator
│   ├── knowledge.py         # KnowledgeBase, Rules, Conditions, Actions
│   ├── learning.py          # PatternDetector, LearningEngine
│   ├── skills.py            # Declarative skill system
│   ├── llm.py               # LLM providers (Claude, OpenAI, DeepSeek)
│   ├── tools.py             # Tool definitions and execution
│   ├── storage.py           # Storage backends (JSON, SQLite)
│   └── adapters/
│       └── langgraph.py     # LangGraph middleware (pre/post model hooks)
│
├── scenarios/
│   ├── demo_cannyforge.py   # Canonical demo (corrections pipeline)
│   ├── demo_langgraph_tool_use.py  # Minimal quickstart
│   └── demo.py              # Animated demo (internal skill system)
│
├── tests/                   # Test suite
└── skills/                  # Built-in skill definitions (SKILL.md)

Further Reading

License

Licensed under BSL 1.1. Free to use in production, but you may not offer CannyForge as a competing hosted service. Converts to Apache 2.0 on 2030-03-01. See LICENSE for full terms.

For commercial licensing inquiries: cannyforge@gmail.com


CannyForge — Your agent makes fewer repeated mistakes over time. FSI-80 proves it.

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

cannyforge-0.3.1.tar.gz (149.4 kB view details)

Uploaded Source

Built Distribution

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

cannyforge-0.3.1-py3-none-any.whl (112.3 kB view details)

Uploaded Python 3

File details

Details for the file cannyforge-0.3.1.tar.gz.

File metadata

  • Download URL: cannyforge-0.3.1.tar.gz
  • Upload date:
  • Size: 149.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for cannyforge-0.3.1.tar.gz
Algorithm Hash digest
SHA256 7633db55afb20597155d9c4105cf26c677a09b3648c7572744091dc210596d52
MD5 48fc2862f4bc105d9e758e9b76351cfe
BLAKE2b-256 84c98ee79b85e5c0f18bd12d95bced55f18d2a8690439c42e6fe7e1024a980ce

See more details on using hashes here.

File details

Details for the file cannyforge-0.3.1-py3-none-any.whl.

File metadata

  • Download URL: cannyforge-0.3.1-py3-none-any.whl
  • Upload date:
  • Size: 112.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for cannyforge-0.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 316d748b013636e368b608148201601208a846cf1afdc4db38e1eefa9ce63238
MD5 40f9d29e639745a2a16728ca3933e01c
BLAKE2b-256 6666d04ad8a00aab66061fc167a45d14b616e53fe1327a4cdcaefa9eb2f7ff2d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page