A lightweight agent SDK built on LiteLLM, with single-agent (ReactAgent / SkillAgent / SandboxAgent) and Entity-World-Schedule multi-agent orchestration.
Project description
EasyAgent
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:
idproperty +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
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 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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3893e84076aa7a230f3a23359002860e95962d074960c0ffee2c0b5fa493f1f7
|
|
| MD5 |
aa29621b444aa75b4432662a336042b9
|
|
| BLAKE2b-256 |
3045e68d7995842d0cb2e17a91885d35335873facea7a28075998e290d37b999
|
Provenance
The following attestation bundles were made for easy_agent_sdk-0.4.0.tar.gz:
Publisher:
publish.yml on SNHuan/EasyAgent
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
easy_agent_sdk-0.4.0.tar.gz -
Subject digest:
3893e84076aa7a230f3a23359002860e95962d074960c0ffee2c0b5fa493f1f7 - Sigstore transparency entry: 1397379011
- Sigstore integration time:
-
Permalink:
SNHuan/EasyAgent@217259bc98d5a009957c06bc6b8d938f769c77e5 -
Branch / Tag:
refs/tags/v0.4 - Owner: https://github.com/SNHuan
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@217259bc98d5a009957c06bc6b8d938f769c77e5 -
Trigger Event:
release
-
Statement type:
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
04b3284ecb33ba13e86666e209aecfe1b33ff689f8e43075f267556aa92a2b3a
|
|
| MD5 |
64b231f090c3cf037c339eed529c7440
|
|
| BLAKE2b-256 |
91915f0e9591365a5eaf9f741dc5d6bdba6bc9258001e05a62b53847232885ea
|
Provenance
The following attestation bundles were made for easy_agent_sdk-0.4.0-py3-none-any.whl:
Publisher:
publish.yml on SNHuan/EasyAgent
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
easy_agent_sdk-0.4.0-py3-none-any.whl -
Subject digest:
04b3284ecb33ba13e86666e209aecfe1b33ff689f8e43075f267556aa92a2b3a - Sigstore transparency entry: 1397379015
- Sigstore integration time:
-
Permalink:
SNHuan/EasyAgent@217259bc98d5a009957c06bc6b8d938f769c77e5 -
Branch / Tag:
refs/tags/v0.4 - Owner: https://github.com/SNHuan
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@217259bc98d5a009957c06bc6b8d938f769c77e5 -
Trigger Event:
release
-
Statement type: