Skip to main content

A lightweight agent SDK built on LiteLLM, with single-agent (ReactAgent / SkillAgent / SandboxAgent) and Entity-World-Schedule multi-agent orchestration.

Project description

EasyAgent

PyPI version License: MIT Python 3.12+

English | 简体中文

EasyAgent is a lightweight agent SDK organised as a small set of composable layers. The goal is to let you learn agent design step by step: start with a single model call, then add memory and context, build up to a ReAct loop with tools and skills, drop into a sandbox, and finally orchestrate multiple agents through the Entity-World-Schedule architecture.

Install

pip install easy-agent-sdk

From source:

git clone https://github.com/SNHuan/EasyAgent.git
cd EasyAgent
pip install -e ".[dev]"

Optional extras:

pip install easy-agent-sdk[sandbox]
pip install easy-agent-sdk[web]
pip install easy-agent-sdk[all]

Quick Start

import asyncio
from easyagent import LiteLLMModel, ReactAgent


async def main():
    agent = ReactAgent(
        model=LiteLLMModel("gpt-4o-mini"),
        system_prompt="You are a concise assistant.",
        max_iterations=5,
    )
    result = await agent.run("What is 2 + 2?")
    print(result.final_output)


asyncio.run(main())

Create easyagent/config/config.yaml or configure LiteLLM through environment variables:

debug: false

models:
  gpt-4o-mini:
    api_type: openai
    base_url: https://api.openai.com/v1
    api_key: sk-xxx

Layered Design

EasyAgent is organised around three layers:

Single-agent:    Model + Memory + Context + Tool → Agent / ReactAgent / SkillAgent / SandboxAgent
Multi-agent:     Entity + World + Schedule → Runtime
Presets:         sequential / fanout / debate / chatroom / groupchat
  • Model — provider adapter and message schema.
  • Memory + Context — store conversation history and decide what reaches the model each turn.
  • Agent — composes a model, memory, context, and any tools/skills/sandbox. Four built-in classes: Agent (single-turn) → ReactAgent (ReAct loop) → SkillAgent / SandboxAgent.
  • Entity — wraps an Agent (or any async actor) for multi-agent participation. Protocol: id property + async act(Perception) -> Action | None.
  • World — the environment entities perceive and act upon. Built-ins: ConversationWorld, PipelineWorld, SpatialWorld, StatefulWorld.
  • Schedule — determines who acts next. Built-ins: TakeTurns, RoundRobin, AllParallel, Reactive, MaxTicks, UntilIdle.
  • Runtime — the perceive-act-apply loop wiring Entity + World + Schedule.

See docs/architecture.md for the full design guide.

Public API

The root package exposes the common SDK surface:

from easyagent import (
    # single-agent
    Agent, ReactAgent, SkillAgent, SandboxAgent,
    AgentSession, AgentRunResult,
    LiteLLMModel, Message,
    EventBus, MessageEvent,
    ToolManager, SkillManager, register_tool,
    # multi-agent protocols
    Entity, World, Schedule, Runtime, RuntimeResult,
    # perception & action types
    Perception, Speak, Silent, ChatMessage,
    # entities
    LLMEntity, TeamEntity, HumanEntity,
    # worlds
    ConversationWorld, PipelineWorld, SpatialWorld, StatefulWorld, SharedState,
    # schedules
    TakeTurns, RoundRobin, AllParallel, MaxTicks, UntilIdle, Reactive,
    # presets
    sequential, fanout, debate, chatroom, groupchat,
)

Learning Path

The examples are ordered by layer. Each one introduces one new idea:

# Single agent (00–06)
python examples/00_model_call.py             # Just call the model
python examples/01_single_turn_agent.py      # Compose a minimal Agent
python examples/02_memory_and_context.py     # Memory + Context
python examples/03_react_with_tools.py       # ReactAgent + tool calls
python examples/04_skills_lazy_loading.py    # SkillAgent (SKILL.md packages)
python examples/05_sandbox_agent.py          # SandboxAgent (bash, write/read file)
python examples/06_custom_tool.py            # Define your own tool

# Multi-agent: Entity-World-Schedule (07–14)
python examples/07_two_agents_talk.py        # LLMEntity + ConversationWorld + RoundRobin
python examples/08_sequential.py             # sequential() preset
python examples/09_chatroom.py               # Manual turn-taking + if/else
python examples/10_groupchat.py              # Reactive schedule, LLM picks next
python examples/11_debate_and_judge.py       # Third-party judge after debate
python examples/12_nested.py                 # TeamEntity: Runtime-as-Entity nesting
python examples/13_shared_state.py           # SharedState + StatefulWorld blackboard
python examples/14_advanced_runtime.py       # SpatialWorld: 2D grid + range-limited perception

Tools

from easyagent import LiteLLMModel, ReactAgent, register_tool


@register_tool
class GetWeather:
    name = "get_weather"
    type = "function"
    description = "Get weather for a city."
    parameters = {
        "type": "object",
        "properties": {"city": {"type": "string"}},
        "required": ["city"],
    }

    def init(self) -> None: ...

    def execute(self, city: str) -> str:
        return f"Sunny in {city}."


agent = ReactAgent(
    model=LiteLLMModel("gpt-4o-mini"),
    tools=[GetWeather],
)

Pass tool classes or instances directly via tools=[...]. The agent automatically registers an end tool — call it to terminate the loop early.

Skills

Skills are directory packages loaded on demand. SKILL.md is the required entry file; supporting files can live alongside it:

skills/my-skill/
├── SKILL.md
├── references/
├── templates/
├── assets/
└── scripts/
from easyagent import LiteLLMModel, SkillAgent

agent = SkillAgent(
    model=LiteLLMModel("gpt-4o-mini"),
    skills=["my-skill"],
    skill_root="./skills",
)

Multi-agent

Wrap any Agent as an LLMEntity, then compose with presets:

from easyagent import LiteLLMModel, ReactAgent, LLMEntity, sequential

model = LiteLLMModel("gpt-4o-mini")
researcher = LLMEntity("researcher", ReactAgent(model=model, name="researcher", system_prompt="..."))
writer     = LLMEntity("writer",     ReactAgent(model=model, name="writer",     system_prompt="..."))
reviewer   = LLMEntity("reviewer",   ReactAgent(model=model, name="reviewer",   system_prompt="..."))

result = await sequential([researcher, writer, reviewer], "Write a product blurb.")
print(result.last_speech)

Available presets: sequential / fanout / chatroom / groupchat / debate. For recursive nesting, wrap an inner Runtime as a TeamEntity and drop it into any outer pipeline. See examples/07_* through examples/14_* for walkthroughs.

Custom World

The architecture is extensible beyond conversation. Swap the World to get entirely different behaviour with the same Entity and Schedule:

from easyagent import SpatialWorld, Grid2D, Runtime, RoundRobin, MaxTicks

grid = Grid2D()
grid.place("alice", (0, 0))
grid.place("bob", (5, 5))

world = SpatialWorld(grid=grid, listen_radius=3.0)
schedule = MaxTicks(inner=RoundRobin(ids=["alice", "bob"]), n=10)

rt = Runtime(world=world, entities={"alice": alice, "bob": bob}, schedule=schedule)
result = await rt.run("Start exploring")

Module Layout

easyagent/
├── agent/      # Agent, ReactAgent, SkillAgent, SandboxAgent, AgentSession
├── core/       # Entity, World, Schedule protocols + Runtime loop
├── entities/   # LLMEntity, TeamEntity, HumanEntity
├── worlds/     # ConversationWorld, PipelineWorld, SpatialWorld, StatefulWorld
├── presets.py  # sequential, fanout, debate, chatroom, groupchat
├── context/    # SlidingWindowContext, SummaryContext, MultiAgentFormatter
├── events/     # MessageEvent, EventBus, telemetry events
├── memory/     # InMemoryMemory
├── model/      # LiteLLMModel + Message schema
├── prompt/     # System-prompt builders
├── sandbox/    # Local / Docker sandboxes
├── skill/      # SKILL.md loading
├── tool/       # Tool registry + built-ins (bash, file, web, end)
├── config/     # Config loading
└── debug/      # Logging

License

MIT License © 2025 Yiran Peng

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

easy_agent_sdk-0.4.0.tar.gz (76.1 kB view details)

Uploaded Source

Built Distribution

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

easy_agent_sdk-0.4.0-py3-none-any.whl (72.1 kB view details)

Uploaded Python 3

File details

Details for the file easy_agent_sdk-0.4.0.tar.gz.

File metadata

  • Download URL: easy_agent_sdk-0.4.0.tar.gz
  • Upload date:
  • Size: 76.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for easy_agent_sdk-0.4.0.tar.gz
Algorithm Hash digest
SHA256 3893e84076aa7a230f3a23359002860e95962d074960c0ffee2c0b5fa493f1f7
MD5 aa29621b444aa75b4432662a336042b9
BLAKE2b-256 3045e68d7995842d0cb2e17a91885d35335873facea7a28075998e290d37b999

See more details on using hashes here.

Provenance

The following attestation bundles were made for easy_agent_sdk-0.4.0.tar.gz:

Publisher: publish.yml on SNHuan/EasyAgent

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

File details

Details for the file easy_agent_sdk-0.4.0-py3-none-any.whl.

File metadata

  • Download URL: easy_agent_sdk-0.4.0-py3-none-any.whl
  • Upload date:
  • Size: 72.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for easy_agent_sdk-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 04b3284ecb33ba13e86666e209aecfe1b33ff689f8e43075f267556aa92a2b3a
MD5 64b231f090c3cf037c339eed529c7440
BLAKE2b-256 91915f0e9591365a5eaf9f741dc5d6bdba6bc9258001e05a62b53847232885ea

See more details on using hashes here.

Provenance

The following attestation bundles were made for easy_agent_sdk-0.4.0-py3-none-any.whl:

Publisher: publish.yml on SNHuan/EasyAgent

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

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