An Autonomous Agent System demonstrating LLM-based decision-making in a closed-loop control architecture.
AgentLoop is not a chatbot or a prompt chain—it's a closed-loop decision system where an LLM repeatedly decides what action to take next based on evolving state until the goal is satisfied.
# Install from PyPI
pip install autonomous-agentloop
# Run
agentloop "Calculate first 10 Fibonacci numbers and save to file"Or try the Live Web Demo on Streamlit Cloud
This project demonstrates how an LLM can be used as a decision-making controller inside a software system, rather than as a text generator. The agent autonomously:
- ✅ Decides what to do next
- ✅ Chooses which action to invoke
- ✅ Observes results
- ✅ Recovers from failures
- ✅ Terminates when the goal is complete
The entire system is built around this explicit control loop:
while goal_not_satisfied:
decide_next_action() # LLM decides
execute_action() # System executes
observe_result() # System observes
update_state() # System updates┌─────────────────────────────────────────┐
│ User Submits Goal │
└────────────────┬────────────────────────┘
│
▼
┌─────────────────────────────────────────┐
│ Decision Engine (LLM) │
│ - Receives: Goal, State, History │
│ - Outputs: Structured Action Decision │
└────────────────┬────────────────────────┘
│
▼
┌─────────────────────────────────────────┐
│ Action Executor (System) │
│ - search_web │
│ - read_url │
│ - run_code │
│ - write_file │
│ - finish │
└────────────────┬────────────────────────┘
│
▼
┌─────────────────────────────────────────┐
│ State Management │
│ - History │
│ - Results │
│ - Errors │
└─────────────────────────────────────────┘
- Plan-Execute Separation: LLM plans, system executes
- Structured Actions: Fixed action space with strict schemas
- Explicit State: All history is tracked and passed to LLM
- Failure Recovery: Automatic retry with error context
- Safety Limits: Maximum steps and cost controls
# Option 1: Install from PyPI (recommended)
pip install autonomous-agentloop
# Option 2: Install from source
git clone https://github.com/Guri10/AgentLoop.git
cd AgentLoop
pip install -e .Create a .env file:
cp .env.example .envAdd your OpenAI API key:
OPENAI_API_KEY=sk-...
OPENAI_MODEL=gpt-4o-mini
MAX_STEPS=50
MAX_RETRIES=3
from agentloop.main import run_agent
# Submit a goal - the agent does the rest
state = run_agent(
goal="Research recent AI developments and create a summary report"
)
# Check results
print(f"Completed: {state.is_complete}")
print(f"Cost: ${state.total_cost:.4f}")# Simple web search demo
python examples/demo_simple.py
# Research and summarization
python examples/demo_research.py
# Code execution and analysis
python examples/demo_analysis.pyThe agent can only interact through these predefined actions:
Search the internet for information.
{
"action": "search_web",
"reasoning": "Need to find recent information",
"input": {
"query": "small language models 2024",
"num_results": 5
}
}Fetch and read content from a specific URL.
{
"action": "read_url",
"reasoning": "Extract actual content from the webpage",
"input": {
"url": "https://example.com/article",
"max_length": 5000
}
}Execute Python code for analysis or computation.
{
"action": "run_code",
"reasoning": "Calculate statistics from data",
"input": {
"code": "print(sum([1, 2, 3, 4, 5]))",
"timeout": 30
}
}Save content to a file.
{
"action": "write_file",
"reasoning": "Save final report",
"input": {
"filename": "report.md",
"content": "# Report\n\nFindings..."
}
}Complete the task and terminate.
{
"action": "finish",
"reasoning": "Goal accomplished",
"input": {
"summary": "Created research report with 3 key findings",
"artifacts": ["report.md"]
}
}The agent maintains complete state throughout execution:
class AgentState:
goal: str # Original goal
current_step: int # Current step number
max_steps: int # Step limit
actions_taken: list[ActionDecision] # Decision history
action_results: list[ActionResult] # Execution results
is_complete: bool # Completion status
total_cost: float # API cost trackingState is passed to the LLM at each decision point, enabling:
- Learning from past actions
- Avoiding repeated mistakes
- Contextual decision-making
AgentLoop implements robust error recovery:
- Retry Logic: Failed actions retry up to 3 times with error context
- Alternative Actions: LLM chooses different approaches after failures
- State Preservation: All failures are recorded and influence future decisions
- Safety Limits: Automatic termination at step/cost limits
The system tracks API usage and estimates costs:
# After execution
print(f"Total tokens: {agent.decision_engine.total_tokens}")
print(f"Estimated cost: ${state.total_cost:.4f}")Typical costs with GPT-4o-mini:
- Simple task (5-8 steps): $0.05 - $0.15
- Medium task (10-20 steps): $0.15 - $0.50
- Complex task (20-40 steps): $0.50 - $2.00
$ python -m agentloop.main "Find recent Python web frameworks and create a comparison"
============================================================
GOAL: Find recent Python web frameworks and create a comparison
============================================================
--- Step 1/50 ---
Decision: search_web
Reasoning: Need to find current information about Python web frameworks
Success: 5 items
--- Step 2/50 ---
Decision: search_web
Reasoning: Get more details on specific frameworks
Success: 5 items
--- Step 3/50 ---
Decision: write_file
Reasoning: Compile findings into comparison document
Success: File written successfully: ./output/framework_comparison.md
--- Step 4/50 ---
Decision: finish
Reasoning: Goal accomplished - comparison created
Success: {'summary': 'Created comparison...', 'artifacts': [...]}
Task completed!
============================================================
EXECUTION SUMMARY
============================================================
Goal: Find recent Python web frameworks and create a comparison
Status: Complete
Steps taken: 4/50
Estimated cost: $0.0234
Success rate: 4/4 actions
============================================================AgentLoop/
├── src/agentloop/
│ ├── core/
│ │ ├── agent.py # Main decision loop
│ │ └── schemas.py # Action/state schemas
│ ├── actions/
│ │ └── executor.py # Action implementations
│ ├── llm/
│ │ └── decision_engine.py # LLM interface
│ └── main.py # Entry point
├── examples/
│ ├── demo_simple.py
│ ├── demo_research.py
│ └── demo_analysis.py
├── tests/
├── output/ # Generated artifacts
├── pyproject.toml
└── README.md
Separation of Concerns:
- LLM = Decision maker (what to do)
- System = Executor (how to do it)
Benefits:
- Reduces hallucination (LLM doesn't execute)
- Improves debuggability (clear boundaries)
- Enables testing (mock executors)
- Demonstrates software engineering
All LLM outputs must match strict Pydantic schemas:
class ActionDecision(BaseModel):
action: ActionType
reasoning: str
input: Dict[str, Any]Invalid outputs are rejected and retried.
The LLM receives:
- Original goal
- Complete history (last 5 actions)
- Current step count
- Previous failures
This enables learning and adaptation.
- ✅ Systems architecture and design
- ✅ LLM integration as a system component
- ✅ Error handling and recovery patterns
- ✅ State management
- ✅ Clean code organization
- ✅ Production considerations (cost tracking, limits)
This project shows engineering discipline:
- Explicit control flow (not prompt chains)
- Structured interfaces (not free-form text)
- Testable components (separation of concerns)
- Observable behavior (complete state tracking)
Potential improvements:
- Add more actions (read_document, database_query)
- Implement state compression for long tasks
- Add web UI for real-time visualization
- Multi-agent coordination
- Tool learning (let LLM suggest new actions)
- Parallel action execution
- Cost optimization with caching
MIT License - see LICENSE file
Contributions welcome! This is a learning project demonstrating autonomous agents.
Built as a demonstration of LLM-based control systems.
Key Insight: This is not about making the smartest LLM—it's about building a system where an LLM can make reliable decisions within a controlled environment.