A lightweight framework for building LLM-powered agents with pluggable backends.
Project description
FlatAgents Python SDK
Status: Prototype
Python SDK for FlatAgents—a format for defining AI agents. Write your agent config once, run it anywhere. See the spec.
In Progress
- Unify input/output adapters for agent chaining
- Simplify output adapters
- Add workflows (flatworkflows)
- TypeScript SDK
Why FlatAgents?
Agent configs are portable. Write your agent YAML once, run it with any SDK that implements the spec. Share agents across teams, languages, and frameworks. Want an SDK for your language? Build one—the spec is simple.
Agent Definition
Define agents in YAML or JSON. Both formats are first-class.
agent.yml
spec: flatagent
spec_version: "0.6.0"
data:
name: summarizer
model:
provider: openai
name: gpt-4o-mini
system: You summarize text concisely.
user: "Summarize this: {{ input.text }}"
output:
summary:
type: str
description: A concise summary
agent.json
{
"spec": "flatagent",
"spec_version": "0.6.0",
"data": {
"name": "summarizer",
"model": {
"provider": "openai",
"name": "gpt-4o-mini"
},
"system": "You summarize text concisely.",
"user": "Summarize this: {{ input.text }}",
"output": {
"summary": {
"type": "str",
"description": "A concise summary"
}
}
}
}
from flatagents import FlatAgent
agent = FlatAgent(config_file="agent.yml") # or agent.json
result = await agent.execute(input={"text": "Long article here..."})
print(result["summary"])
Quick Start
pip install flatagents[litellm]
writer.yaml
spec: flatagent
spec_version: "0.6.0"
data:
name: writer
model:
provider: openai
name: gpt-4o-mini
system: You write short, punchy marketing copy.
user: |
Product: {{ input.product }}
{% if input.feedback %}Previous attempt: {{ input.tagline }}
Feedback: {{ input.feedback }}
Write an improved tagline.{% else %}Write a tagline.{% endif %}
output:
tagline:
type: str
description: The tagline
critic.yaml
spec: flatagent
spec_version: "0.6.0"
data:
name: critic
model:
provider: openai
name: gpt-4o-mini
system: You critique marketing copy. Be constructive but direct.
user: |
Product: {{ input.product }}
Tagline: {{ input.tagline }}
output:
feedback:
type: str
description: Constructive feedback
score:
type: int
description: Score from 1-10
run.py
import asyncio
from flatagents import FlatAgent
async def main():
writer = FlatAgent(config_file="writer.yaml")
critic = FlatAgent(config_file="critic.yaml")
product = "a CLI tool for AI agents"
draft = await writer.execute(input={"product": product})
for round in range(4):
review = await critic.execute(input={"product": product, **draft})
print(f"Round {round + 1}: \"{draft['tagline']}\" - {review['score']}/10")
if review["score"] >= 8:
break
draft = await writer.execute(input={"product": product, **review, **draft})
print(f"Final: {draft['tagline']}")
asyncio.run(main())
export OPENAI_API_KEY="your-key"
python run.py
Usage
From Dictionary
from flatagents import FlatAgent
config = {
"spec": "flatagent",
"spec_version": "0.6.0",
"data": {
"name": "calculator",
"model": {"provider": "openai", "name": "gpt-4"},
"system": "You are a calculator.",
"user": "Calculate: {{ input.expression }}",
"output": {
"result": {"type": "float", "description": "The calculated result"}
}
}
}
agent = FlatAgent(config_dict=config)
result = await agent.execute(input={"expression": "2 + 2"})
Custom Agent (Subclass FlatAgent)
from flatagents import FlatAgent
class MyAgent(FlatAgent):
def create_initial_state(self):
return {"count": 0}
def generate_step_prompt(self, state):
return f"Count is {state['count']}. What's next?"
def update_state(self, state, result):
return {**state, "count": int(result)}
def is_solved(self, state):
return state["count"] >= 10
agent = MyAgent(config_file="config.yaml")
trace = await agent.execute()
LLM Backends
Two backends available:
from flatagents import LiteLLMBackend, AISuiteBackend
# LiteLLM - model format: provider/model
backend = LiteLLMBackend(model="openai/gpt-4o", temperature=0.7)
# AISuite - model format: provider:model
backend = AISuiteBackend(model="openai:gpt-4o", temperature=0.7)
Custom Backend
Implement the LLMBackend protocol:
class MyBackend:
total_cost: float = 0.0
total_api_calls: int = 0
async def call(self, messages: list, **kwargs) -> str:
self.total_api_calls += 1
return "response"
agent = MyAgent(backend=MyBackend())
Examples
More examples are available in the examples/ directory:
- helloworld - Minimal getting started example
- writer_critic - Iterative refinement with two agents
- mdap - Multi-step reasoning with calibrated confidence
- gepa_self_optimizer - Self-optimizing prompt evolution
Known Issues
aisuite drops tools from API calls
When using the aisuite backend with tool calling (MCP), tools are silently dropped from the API request unless max_turns is set. This is a bug in aisuite's client.chat.completions.create() which pops the tools kwarg.
Workaround: The SDK includes a direct provider call for Cerebras that bypasses aisuite's client. See _call_aisuite_cerebras_direct() in flatagent.py. Other providers may need similar workarounds until aisuite fixes this upstream.
Symptoms: Model outputs tool call JSON in text content instead of using actual tool calling mechanism. Agent completes immediately with "no tool calls" when tools should have been invoked.
License
MIT License - see LICENSE for details.
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 flatagents-0.1.7.tar.gz.
File metadata
- Download URL: flatagents-0.1.7.tar.gz
- Upload date:
- Size: 2.1 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b4ab2411f52530d2055460073e3273c59dd51b6f937b68907c7192db31f913a7
|
|
| MD5 |
a1680f2e14142db4afe7b5b6242a3893
|
|
| BLAKE2b-256 |
f720ce8ce01db7df2dce70858a2f3dfdf0473337932a81162c8c00dd85729037
|
File details
Details for the file flatagents-0.1.7-py3-none-any.whl.
File metadata
- Download URL: flatagents-0.1.7-py3-none-any.whl
- Upload date:
- Size: 44.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
83cb8fe1829933a627251936b324da020e0fcfcdddc75af54b006adf702211da
|
|
| MD5 |
057b36a4e3fccf32972cfca9ed5f1f91
|
|
| BLAKE2b-256 |
e3345e211f3c0faaa083d36c4db633fe30d2455e4ba8c223db653878cdc9d79f
|