Skip to main content

A modular multi-agent framework for building AI development workflows with Ollama

Project description

AgentChain 🔗

A minimal, zero-dependency Python library for building multi-agent workflows.

Fluent APICustom AgentsPer-Agent ModelsEvent HooksPyPI Ready


Installation

pip install agentchain

Or install from source:

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

Quick Start

from agentchain import AgentChain

AgentChain() \
    .requirements("Build a calculator app with add, subtract, multiply, divide") \
    .model("deepseek-coder-v2:16b") \
    .output("./calculator") \
    .run()

That's it. AgentChain coordinates multiple AI agents to plan and implement your project.


Core Concepts

The Default Workflow

AgentChain ships with 3 agents that form a complete development pipeline:

Agent Role Responsibility
Contractor Orchestrator Coordinates the workflow, handles retries, verifies completion
Planner Planning Breaks requirements into concrete, ordered tasks
Coder Implementation Writes code to files based on task specifications

Fluent API

Configure everything with method chaining:

AgentChain()
    .requirements("Your project description")  # What to build
    .model("llama3:8b")                         # Default model for all agents
    .configure("planner", model="llama3:70b")   # Planner gets a bigger model
    .configure("coder", model="deepseek-coder-v2:16b")  # Coder is specialized
    .output("./my_project")                     # Where to write files
    .run()

Configuration

Per-Agent Models

Use the right model for each task:

AgentChain()
    .requirements("Build a REST API")
    .configure("planner", model="llama3:70b")           # Planning: bigger model
    .configure("coder", model="deepseek-coder-v2:16b")  # Coding: code-focused model
    .output("./api")
    .run()

Agent Parameters

Pass custom parameters to specific agents:

AgentChain()
    .requirements("Build a game")
    .configure("planner", 
        model="llama3:70b",
        max_tasks=20,           # Custom parameter
        include_tests=True      # Custom parameter
    )
    .configure("coder",
        model="deepseek-coder-v2:16b",
        style="verbose",        # Custom parameter
        language="python"       # Custom parameter
    )
    .output("./game")
    .run()

LLM Configuration

Configure the LLM endpoint:

from agentchain import ChainConfig

config = ChainConfig(
    llm_base_url="http://localhost:11434",  # Ollama default
    default_model="llama3:8b",
)

AgentChain(config)
    .requirements("Build something")
    .output("./output")
    .run()

Custom Agents

Function-Based Agents

The simplest way to add an agent:

from agentchain import AgentChain, agent, AgentContext, AgentResult

@agent(name="reviewer", role="Code Reviewer")
def review_code(context: AgentContext, llm) -> AgentResult:
    code = context.get("code", "")
    
    response = llm.generate(
        "Review this code for issues:\n\n" + code,
        model="llama3:8b"
    )
    
    return AgentResult.ok({"review": response})


# Use it
AgentChain()
    .requirements("Build a CLI tool")
    .register("reviewer", review_code)  # Add to this chain
    .output("./cli")
    .run()

Class-Based Agents

For more complex agents with state:

from agentchain import Agent, agent, AgentContext, AgentResult

@agent(name="tester", role="Test Writer")
class TesterAgent(Agent):
    def execute(self, context: AgentContext) -> AgentResult:
        code_files = context.get("files", [])
        
        for file in code_files:
            test_code = self._llm.generate(
                f"Write tests for:\n{file['content']}",
                model=self._config.get("model", "llama3:8b")
            )
            # Write test file...
        
        return AgentResult.ok({"tests_created": len(code_files)})

Custom Orchestrator

Replace the entire workflow:

from agentchain import Orchestrator, orchestrator, AgentContext, AgentResult

@orchestrator(name="my_workflow", role="Custom Pipeline")
class MyOrchestrator(Orchestrator):
    def execute(self, context: AgentContext) -> AgentResult:
        # Phase 1: Your planning logic
        plan_result = self.invoke_agent("planner", context)
        
        # Phase 2: Your implementation logic
        for task in plan_result.data.get("tasks", []):
            self.invoke_agent("coder", AgentContext(
                task=task["description"],
                inputs=task
            ))
        
        # Phase 3: Your custom phase
        if self.get_agent("tester"):
            self.invoke_agent("tester", context)
        
        return AgentResult.ok({"status": "complete"})


# Use it
AgentChain()
    .requirements("Build something")
    .orchestrator(MyOrchestrator)
    .output("./output")
    .run()

Events & Callbacks

Monitor progress with event hooks:

from agentchain import AgentChain, Event

def on_progress(event_type, data):
    print(f"[{event_type}] {data.get('message', '')}")

def on_task_complete(event_type, data):
    task = data.get("task", {})
    print(f"✓ Completed: {task.get('name')}")

AgentChain()
    .requirements("Build an app")
    .on(Event.PROGRESS, on_progress)
    .on(Event.TASK_COMPLETE, on_task_complete)
    .on(Event.AGENT_ERROR, lambda e, d: print(f"Error: {d}"))
    .output("./app")
    .run()

Available Events

Event Trigger
Event.CHAIN_START Chain execution begins
Event.CHAIN_COMPLETE Chain execution finishes
Event.AGENT_START An agent starts executing
Event.AGENT_COMPLETE An agent finishes
Event.AGENT_ERROR An agent encounters an error
Event.TASK_START A task begins
Event.TASK_COMPLETE A task completes
Event.TASK_FAILED A task fails
Event.PROGRESS General progress update

CLI Usage

AgentChain includes a command-line interface:

# Basic usage
agentchain "Build a todo app with Flask" --output ./todo-app

# With specific model
agentchain "Build a calculator" --model deepseek-coder-v2:16b --output ./calc

# Verbose output
agentchain "Build a game" --output ./game --verbose

API Reference

AgentChain

The main entry point for building chains.

class AgentChain:
    def requirements(self, text: str) -> AgentChain
    def model(self, name: str) -> AgentChain
    def configure(self, agent_name: str, **kwargs) -> AgentChain
    def output(self, directory: str) -> AgentChain
    def orchestrator(self, cls: Type[Orchestrator]) -> AgentChain
    def register(self, name: str, agent: Agent | Callable) -> AgentChain
    def on(self, event: Event, handler: Callable) -> AgentChain
    def run(self) -> AgentResult

AgentContext

Data passed to agents:

class AgentContext:
    task: str          # Current task description
    inputs: dict       # Input data from previous agents
    workspace: str     # Output directory path
    
    def get(self, key: str, default=None) -> Any

AgentResult

Return value from agents:

class AgentResult:
    success: bool      # Whether execution succeeded
    data: dict         # Output data
    error: str | None  # Error message if failed
    
    @classmethod
    def ok(cls, data: dict) -> AgentResult
    
    @classmethod
    def fail(cls, error: str) -> AgentResult

Requirements

  • Python: 3.9+
  • LLM Backend: Ollama running at localhost:11434 (configurable)
  • Dependencies: None (stdlib only!)

Examples

See the examples/ directory:


License

MIT License - see LICENSE


Contributing

Contributions welcome! Please read our contributing guidelines first.

# Development install
pip install -e ".[dev]"

# Run tests
pytest

# Format code
black src/

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

llama2a-0.1.0.tar.gz (26.6 kB view details)

Uploaded Source

Built Distribution

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

llama2a-0.1.0-py3-none-any.whl (5.2 kB view details)

Uploaded Python 3

File details

Details for the file llama2a-0.1.0.tar.gz.

File metadata

  • Download URL: llama2a-0.1.0.tar.gz
  • Upload date:
  • Size: 26.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.12

File hashes

Hashes for llama2a-0.1.0.tar.gz
Algorithm Hash digest
SHA256 bed6f7ba1b3b43f4b2dfdb14a0254fe2793706efcbf7b71e2930753a35ee7aff
MD5 23f3e143f17ed46fcb512690648a147d
BLAKE2b-256 fa117411e8eb7d162ef2361c512b7261707cc40bcf36bbc1c9f1127f6fb683ec

See more details on using hashes here.

File details

Details for the file llama2a-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: llama2a-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 5.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.12

File hashes

Hashes for llama2a-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4f0772e9d4aec49a4ec696ad7dd18872f217f4567defe728614a8579aded9531
MD5 e0fe834566d8520f9ba8d69b9331eba1
BLAKE2b-256 760924f8bda66c2c4f30e0afa05ea050d57521fa2b3518e6ac5b7d957c9367fc

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