Skip to main content

A self-evolving AI Agent framework with autonomous planning capabilities

Project description

coralmind

A Self-Evolving AI Agent Framework with Self-Planning Capabilities

The more it executes, the smarter it gets

PyPI version License Python version Tests Coverage

English | 简体中文


Why coralmind?

Most Agent frameworks on the market are stateless—each execution is a "first time", unable to learn from historical experience.

coralmind is different:

flowchart LR
    subgraph Traditional[Traditional Agent]
        T1[Task] --> P1[Plan] --> E1[Execute] --> O1[Output]
        style T1 fill:#f9f,stroke:#333
        style P1 fill:#f9f,stroke:#333
        style E1 fill:#f9f,stroke:#333
        style O1 fill:#f9f,stroke:#333
    end
flowchart LR
    subgraph coralmind[coralmind]
        T[Task] --> PA[PlanAdvisor]
        PA --> P[Plan]
        P --> E[Execute]
        E --> O[Output]
        O --> S[Score]
        S -->|Store| DB[(History)]
        DB -->|Reuse| PA
    end

💡 The more it executes, the better the plans, the faster the response

Core Differences:

Feature Traditional Agent coralmind
Task Planning Generate from scratch each time Reuse/optimize historical plans
Execution Experience Not retained Persistently stored
Quality Assessment None LLM auto-scoring
Self-Evolution

Use Cases:

  • Repetitive tasks (e.g., periodic report generation, code review)
  • Structured workflows (e.g., data analysis pipelines)
  • Business scenarios requiring continuous optimization

Features

  • Self-Evolution - Learns from historical executions, continuously improving plan quality
  • Intelligent Planning - Automatically decomposes complex tasks into multi-node execution plans
  • Result Validation - Dual guarantee with rule-based and semantic validation
  • Closed-Loop Feedback - Execution result scoring drives plan optimization
  • Persistent Storage - Task templates and execution plans automatically saved for cross-session reuse

Installation

pip install coralmind

Development Installation

git clone https://github.com/KoanJan/coralmind.git
cd coralmind
python -m venv venv
source venv/bin/activate
pip install -e ".[dev]"

Quick Start

from coralmind import Agent, Task, Material, LLMConfig

llm = LLMConfig(
    model_id="gpt-4",
    base_url="https://api.openai.com/v1",
    api_key="your-api-key",
)

agent = Agent(default_llm=llm)

task = Task(
    materials=[Material(name="article", content="Long text content...")],
    requirements="Summarize the input article in no more than 100 words, including core viewpoints"
)

result = agent.run(task)
print(result)

Expected Output:

Status: success
Summary: This article discusses the development history and future trends of artificial intelligence...

Core Concepts

Material

Material is the input data unit of a task, its name field has a semantic role:

class Material:
    name: str      # Semantic role identifier, determines the material's position in the execution plan
    content: str   # Specific content, different for each task instance

name is not just an identifier, but a clue for Planner to understand the material's purpose:

# ✅ Good naming: Clear semantics, Planner can design reasonable processing nodes
Material(name="market_report", content="...")      # → Analyze market node
Material(name="competitor_analysis", content="...") # → Analyze competitors node
Material(name="user_survey", content="...")        # → Analyze users node

# ❌ Bad naming: No semantics, Planner cannot distinguish roles
Material(name="input1", content="...")
Material(name="data", content="...")

Task

Task is a task instance submitted by the user, containing specific data and execution requirements:

class Task:
    materials: List[Material]  # Input data (different each time)
    requirements: str          # Task requirements (abstract description, no specific content)

TaskTemplate

TaskTemplate is a task type definition extracted from Task:

class TaskTemplate:
    material_names: List[str]  # Material role list (defines what types of inputs are needed)
    requirements: str          # Task requirements (same as Task)

TaskTemplate defines "the structure of this type of task":

  • What roles of materials are needed
  • What goals to achieve

Relationship Between Task and TaskTemplate

flowchart LR
    subgraph Task[Task Instance]
        M1["materials:<br/>- name: market_report<br/>  content: 2024 Market...<br/>- name: competitor_analysis<br/>  content: Company A share...<br/>- name: user_survey<br/>  content: Sample size 5000..."]
        R1["requirements:<br/>Develop product strategy"]
    end
    
    subgraph Template[TaskTemplate Type Definition]
        MN["material_names:<br/>- market_report<br/>- competitor_analysis<br/>- user_survey"]
        R2["requirements:<br/>Develop product strategy"]
        USE["Used to match historical records<br/>Reuse or optimize execution plans"]
    end
    
    Task -->|Extract| Template

Key Insight: TaskTemplate's material_names determines the structural complexity of the task:

material_names Task Complexity Typical Plan
["article"] Simple Single node: Direct processing
["code", "requirements"] Medium Dual nodes: Understand→Generate
["market_report", "competitor_analysis", "user_survey"] Complex Multi-node: Parallel analysis→Comprehensive decision

Reuse Mechanism

When a user submits a Task, the system's workflow:

flowchart TD
    A[Task] --> B[Extract TaskTemplate]
    B --> C[Query Historical Records]
    C --> D{Found high-score plan?}
    D -->|Yes| E{Score high enough?}
    D -->|No| F[Generate plan from scratch]
    E -->|≥ s1| G[Direct reuse USE]
    E -->|s0 ~ s1| H[Reference optimization BASE_ON]
    E -->|< s0| F

Essence of Reuse: Not reusing specific content, but reusing "methodology for handling similar problems".

⚠️ Key Constraints

1. requirements Must Be Abstract

requirements describes "what to do", should not contain specific content:

# ✅ Correct: Abstract description
requirements = "Summarize the input article in no more than 100 words"

# ❌ Wrong: Contains specific content
requirements = "Summarize this article about artificial intelligence"
#                    ^^^^^^^^^^^^^^^^^ This part breaks reusability

2. Material.name Must Have Semantics

The name is the basis for Planner to understand the material's role:

# ✅ Correct: Semantic naming
Material(name="source_code", content="...")
Material(name="test_cases", content="...")

# ❌ Wrong: Meaningless naming
Material(name="file1", content="...")
Material(name="text", content="...")

3. Only Same Template Can Be Reused

The following two Tasks cannot be reused because Templates are different:

# Task A
Task(
    materials=[Material(name="article", content="...")],
    requirements="Generate summary"
)
# Template: material_names=["article"], requirements="Generate summary"

# Task B  
Task(
    materials=[Material(name="report", content="...")],  # Different name
    requirements="Generate summary"
)
# Template: material_names=["report"], requirements="Generate summary"
#           ^^^^^^^^^^^^^^^^ Different from Task A, cannot reuse

Best Practice: Use consistent naming conventions for the same type of tasks.

Closed-Loop Learning Mechanism

The framework achieves continuous optimization through Evaluator and PlanAdvisor:

flowchart LR
    subgraph Execution[Execution Flow]
        T[Task] --> PA[PlanAdvisor]
        PA --> PL[Planner]
        PL --> E[Executor]
        E --> O[Output]
        O --> EV[Evaluator]
    end
    
    subgraph Persistence[Persistence]
        EV -->|Score| S[(Store Plan+Score)]
        S -->|Historical Records| PA
    end

Evaluator

After task execution, Evaluator scores the result (0-10):

# Scoring dimensions
- Whether requirements are met
- Output quality and completeness
- Whether there is redundant or irrelevant content

The score is stored together with the Plan, forming historical records.

PlanAdvisor

When encountering the same TaskTemplate next time, PlanAdvisor queries historical records and makes decisions:

class ThresholdStrategy:
    s0: float = 8.5   # Optimization threshold
    s1: float = 9.5   # Direct reuse threshold
    c: int = 3        # Minimum historical records

Decision logic:

Historical Records Highest Avg Score Decision
< c - Generate new plan from scratch
≥ c ≥ s1 Direct reuse (USE)
≥ c s0 ~ s1 Reference optimization (BASE_ON)
≥ c < s0 Generate new plan from scratch

Two Reuse Modes

USE (Direct Reuse): Historical plan performs excellently, use directly

flowchart LR
    H[Historical Plan] -->|Direct Use| E[Execute]

BASE_ON (Reference Optimization): Historical plan performs well, use as reference

flowchart LR
    H[Historical Plan] -->|Reference| P[Planner]
    P -->|Optimize| N[New Plan]
    N --> E[Execute]

Continuous Optimization Effect

1st execution: No history → Generate from scratch → Score 7.0 → Store
2nd execution: No history → Generate from scratch → Score 6.5 → Store
3rd execution: No history → Generate from scratch → Score 8.0 → Store
4th execution: Has history (avg 7.2) → BASE_ON optimize → Score 8.5 → Update
5th execution: Has history (avg 7.6) → BASE_ON optimize → Score 9.0 → Update
6th execution: Has history (avg 8.2) → USE direct reuse → Score 9.0 → Update
...

Core Value: The more tasks executed, the higher the plan quality, the faster the response.

Configuration

Logging Configuration

import logging

coralmind_logger = logging.getLogger('coralmind')
coralmind_logger.setLevel(logging.DEBUG)
handler = logging.StreamHandler()
handler.setFormatter(logging.Formatter(
    '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
))
coralmind_logger.addHandler(handler)

Database Path

import coralmind

coralmind.set_db_path("/path/to/your/coralmind.db")

Layered LLM Configuration

agent = Agent(
    default_llm=default_llm,
    planner_llm=planning_llm,      # Use stronger model for planning
    executor_llm=execution_llm,    # Use faster model for execution
    validator_llm=validation_llm,  # Use specialized model for validation
)

Custom Strategy

from coralmind import ThresholdStrategy

strategy = ThresholdStrategy(s0=8.0, s1=9.0, c=5)
agent = Agent(default_llm=llm, advising_strategy=strategy)

Retry Count

agent = Agent(default_llm=llm, max_retry_times_per_node=5)

Architecture

flowchart TB
    subgraph Agent
        direction TB
        T[Task] --> PA[PlanAdvisor]
        PA --> PL[Planner]
        PL --> EX[Executor]
        EX --> V[Validator]
        V --> EV[Evaluator]
        EV --> OF[OutputFormater]
        
        EV -->|Score| DB[(History)]
        DB -->|Reuse Advice| PA
    end

API Documentation

For detailed API documentation, see API Reference.

Examples

See examples/ directory for complete examples:

Running Tests

pip install -e ".[dev]"
pytest

Contributing

Contributions are welcome! See Contributing Guide.

License

MIT License

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

coralmind-0.0.3.tar.gz (35.7 kB view details)

Uploaded Source

Built Distribution

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

coralmind-0.0.3-py3-none-any.whl (31.3 kB view details)

Uploaded Python 3

File details

Details for the file coralmind-0.0.3.tar.gz.

File metadata

  • Download URL: coralmind-0.0.3.tar.gz
  • Upload date:
  • Size: 35.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.13

File hashes

Hashes for coralmind-0.0.3.tar.gz
Algorithm Hash digest
SHA256 217503d01f099e5179f70cda813767b6b66f9cc25f7c4ea6a378e16fc9594420
MD5 d345f29cdfc7e44290e4c19763aeaa09
BLAKE2b-256 cba21b809254ebda4e12e6d09c832e47539fbf9b6e55b0e42599efcffdcf3674

See more details on using hashes here.

File details

Details for the file coralmind-0.0.3-py3-none-any.whl.

File metadata

  • Download URL: coralmind-0.0.3-py3-none-any.whl
  • Upload date:
  • Size: 31.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.13

File hashes

Hashes for coralmind-0.0.3-py3-none-any.whl
Algorithm Hash digest
SHA256 1abfdd74de991368c1304eda40edc0148070f16bb822e485da84095beebadd3e
MD5 616ff3797988e1b52fb4d6b07dffe2f0
BLAKE2b-256 2262c28b5f46c599b5f6cedd38fd0f37975e6070515f22adad3f960e1563c01b

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