When Simplicity Becomes Your Superpower: Meet KISS Agent Framework
"Everything should be made as simple as possible, but not simpler." — Albert Einstein
The Problem with AI Agent Frameworks Today
The AI agent ecosystem has grown increasingly complex. New frameworks appear weekly, each layered with abstractions, sprawling configuration files, and dependency trees that rival any large-scale web project. Getting a simple tool call working often requires more effort than the task itself.
There is another way.
KISS — the Keep It Simple, Stupid Agent Framework — takes a fundamentally different approach.
The Philosophy: Radical Simplicity
KISS is more than a clever acronym. It is a design philosophy that shapes every line of code in the framework.
Born from frustration with overly complex agent architectures, KISS strips away the unnecessary and focuses on what matters: getting intelligent agents to solve real problems. The API is simple enough that a coding agent can write complex AI pipelines — called AI programs — from natural language descriptions. You can also optimize an agent program using a builtin optimizer.
Every KISS agent is a ReAct agent by default:
1. You give the agent a prompt
2. The agent thinks and calls tools
3. Repeat until done
4. That's it. That's the framework.
No workflow graphs. No state machines.
Your First Agent in 30 Seconds
Here is a minimal working example:
from kiss.core.kiss_agent import KISSAgent
def calculate(expression: str) -> str:
"""Evaluate a math expression."""
return str(eval(expression))
agent = KISSAgent(name="Math Buddy")
result = agent.run(
model_name="gemini-3-flash-preview",
prompt_template="Calculate: {question}",
arguments={"question": "What is 15% of 847?"},
tools=[calculate]
)
print(result) # 127.05
That is a fully functional AI agent with tool use — no boilerplate, no annotations, no big setup.
KISS uses native function calling from the LLM providers. Python functions become tools automatically. Type hints become schemas. Docstrings become descriptions. Everything composes naturally.
Multi-Agent Orchestration is Function Composition
Here's where KISS really shines — composing multiple agents into systems greater than the sum of their parts.
Since agents are just functions, you orchestrate them with plain Python. Here's a complete research-to-article pipeline with three agents:
from kiss.core.kiss_agent import KISSAgent
# Agent 1: Research a topic
researcher = KISSAgent(name="Researcher")
research = researcher.run(
model_name="gpt-4o",
prompt_template="List 3 key facts about {topic}. Be concise.",
arguments={"topic": "Python asyncio"},
is_agentic=False # Simple generation, no tools
)
# Agent 2: Write a draft using the research
writer = KISSAgent(name="Writer")
draft = writer.run(
model_name="claude-sonnet-4-5",
prompt_template="Write a 2-paragraph intro based on:\n{research}",
arguments={"research": research},
is_agentic=False
)
# Agent 3: Polish the draft
editor = KISSAgent(name="Editor")
final = editor.run(
model_name="gemini-2.5-flash",
prompt_template="Improve clarity and fix any errors:\n{draft}",
arguments={"draft": draft},
is_agentic=False
)
print(final)
That's it. Each agent can use a different model. Each agent saves its own trajectory. And you compose them with the most powerful orchestration tool ever invented: regular Python code.
No special orchestration framework needed. No message buses. No complex state machines. Just Python functions calling Python functions.
GEPA: Teaching Your Agents to Evolve
KISS goes beyond simplicity — it offers intelligent simplicity.
GEPA (Genetic-Pareto Prompt Evolution) is a prompt optimization system built into the framework.
Traditional prompt engineering is largely manual: make changes, evaluate, iterate, and hope for convergence. GEPA automates this process:
1. Run your agent
2. Reflect on what went wrong (using AI)
3. Evolve the prompt based on insights
4. Maintain a Pareto frontier of best performers
5. Combine winning strategies through crossover
6. Repeat until convergence
This is not just iteration — it is evolution. GEPA maintains multiple prompt candidates, each optimized for different objectives. Need an agent that is both accurate and concise? GEPA finds the optimal trade-off on the Pareto frontier.
from kiss.agents.gepa import GEPA
gepa = GEPA(
agent_wrapper=my_agent_function,
initial_prompt_template="You are a helpful assistant...",
evaluation_fn=score_the_result,
max_generations=10,
population_size=8
)
best_prompt = gepa.optimize(arguments={"task": "solve problems"})
Our research behind this approach: "GEPA: Reflective Prompt Evolution Can Outperform Reinforcement Learning". The paper demonstrates that prompt evolution can outperform RL on several benchmarks.
KISSEvolve: When Algorithms Write Themselves
What if you could start with a bubble sort and end up with quicksort — without writing a single line of sorting code yourself?
KISSEvolve is an evolutionary algorithm discovery framework. You provide:
- Starting code (even a naive implementation)
- A fitness function
- An LLM to guide mutations
- It includes features of OpenEvolve and several new ideas
KISSEvolve handles the rest:
from kiss.agents.kiss_evolve.kiss_evolve import KISSEvolve
# Start with O(n²) bubble sort
initial_code = """
def sort_array(arr):
n = len(arr)
for i in range(n):
for j in range(n - i - 1):
if arr[j] > arr[j + 1]:
arr[j], arr[j + 1] = arr[j + 1], arr[j]
return arr
"""
optimizer = KISSEvolve(
initial_code=initial_code,
evaluation_fn=measure_performance,
model_names=[("gemni-3-flash-preview", 0.5),("gemni-3-pro-preview", 0.5)],
population_size=8,
max_generations=10
)
best = optimizer.evolve()
# Discovers O(n log n) algorithms like quicksort or mergesort
The framework includes several advanced features:
- Island-Based Evolution: Multiple populations evolving in parallel with periodic migration
- Novelty Rejection Sampling: Ensures diversity by filtering redundant solutions
- Power-Law and Performance-Novelty Sampling: Sophisticated parent selection strategies
- Multi-Model Support: Use different LLMs with configurable probabilities
The included kissevolve_bubblesort.py script demonstrates the discovery of O(n log n) sorting algorithms from a naive starting point.
Model Agnostic: Your LLM, Your Choice
KISS is not locked to any single provider. Out of the box, it supports:
| Provider | Models |
|---|---|
| OpenAI | GPT-4.1, GPT-4o, GPT-5 series |
| Anthropic | Claude Opus 4.5, Sonnet 4.5, Haiku 4.5 |
| Gemini 2.5/3 Pro, Gemini Flash | |
| Together AI | Llama 4, Qwen 3, DeepSeek R1/V3 |
| OpenRouter | 400+ models from all providers |
Each model includes accurate pricing, context length limits, and capability flags. Token usage and costs are tracked automatically across all agent runs.
# Switch models with a single parameter
result = agent.run(model_name="claude-sonnet-4-5", ...)
result = agent.run(model_name="gemini-3-pro-preview", ...)
result = agent.run(model_name="openrouter/x-ai/grok-4", ...)
Docker Integration: Safe Sandboxing
Giving AI agents the ability to execute code is powerful but risky. KISS includes a DockerManager that makes sandboxing straightforward:
from kiss.docker.docker_manager import DockerManager
with DockerManager("ubuntu:latest") as env:
agent = KISSAgent(name="Safe Agent")
result = agent.run(
model_name="gemini-3-flash-preview",
prompt_template="Install nginx and configure it",
tools=[env.run_bash_command]
)
The agent can execute any bash command within the container. When the context manager exits, the container is destroyed. The host system remains untouched.
Trajectory Visualization: See What Your Agents Think
Debugging AI agents is notoriously difficult. What was the agent reasoning about? Why did it make that tool call?
KISS automatically saves complete trajectories to YAML files. For easier analysis, the framework includes a web-based trajectory visualizer:
uv run python -m kiss.viz_trajectory.server artifacts
The visualizer provides:
- Dark-themed modern UI
- Markdown rendering with syntax highlighting
- Complete message history with timestamps
- Token usage and budget tracking per step
- Tool calls and their results
It turns agent debugging from guesswork into structured analysis.
Built-in Budget Tracking
AI API calls cost money. KISS tracks every token:
agent.run(
model_name="gpt-4o",
max_budget=1.0, # USD limit for this run
...
)
print(f"Budget used: ${agent.budget_used:.4f}")
print(f"Tokens used: {agent.total_tokens_used}")
print(f"Global budget: ${KISSAgent.global_budget_used:.4f}")
Set per-agent limits or global limits. Cost calculation is automatic, based on actual model pricing. No more surprise API bills.
Getting Started
# Install uv (modern Python package manager)
curl -LsSf https://astral.sh/uv/install.sh | sh
# Clone and setup
git clone https://github.com/your-repo/kiss_ai.git
cd kiss_ai
uv venv --python 3.13
uv sync --group dev
# Set your API keys
export OPENAI_API_KEY="your-key"
export ANTHROPIC_API_KEY="your-key"
export GEMINI_API_KEY="your-key"
# Run your first agent
uv run python -c "
from kiss.core.kiss_agent import KISSAgent
agent = KISSAgent('Hello World')
print(agent.run('gpt-4o', 'Say hello!', is_agentic=False))
"
Why KISS?
In a landscape increasingly defined by complexity, KISS offers a principled alternative.
It is for developers who believe that:
- Simplicity is a feature, not a limitation
- Code should be readable by humans, not just machines
- Agents should be tools, not black boxes
- Evolution beats manual engineering when the search space is vast
KISS does not try to be everything. It aims to be exactly what you need — a clean, powerful foundation for building AI agents that work.
What's Next
KISS is actively evolving. The roadmap includes:
- Additional benchmark integrations
- Enhanced multi-agent orchestration
- Improved evolution strategies
- Community-contributed tools and agents
- Asynchronous tool calling support
The core philosophy will remain unchanged: Keep It Simple, Stupid.
Resources
- GitHub: KISS Agent Framework
- GEPA Paper: arXiv:2507.19457
Built by Koushik Sen (ksen@berkeley.edu)
Because the best code is the code you don't have to write.
License: Apache-2.0
Python: ≥3.13
Philosophy: KISS


Top comments (0)