A lightweight Agent development framework written in pure Python. No external framework dependencies.
纯 Python 实现的轻量级 Agent 开发框架,支持:
- ReAct 模式:Thought → Action → Observation 循环
- Plan-and-Execute 模式:先规划后执行
- 装饰器工具注册:
@tool简单直观 - 摘要记忆:自动压缩对话历史节省 token
- 层级多 Agent:Supervisor 委托子 Agent 协作
- 内置工具:Bash、文件读写等常用工具开箱即用
┌─────────────────────────────────────────────────────┐
│ AgentFramework │
│ (agent.run("task")) │
└─────────────────────┬───────────────────────────────┘
│
┌───────────┴───────────┐
│ │
┌─────▼─────┐ ┌─────▼─────┐
│ ReActAgent │ │ PlanAnd │
│ │ │ Execute │
└─────┬─────┘ └─────┬─────┘
│ │
└─────────┬───────────┘
│
┌──────────▼──────────┐
│ ActionExecutor │
│ (executes tools) │
└──────────┬──────────┘
│
┌──────────▼──────────┐
│ ToolRegistry │
│ @tool decorators │
└─────────────────────┘
User: "What's the weather in Beijing?"
│
▼
┌────────────────────────┐
│ Build messages │
│ (system + memory + │
│ user task) │
└───────────┬────────────┘
│
▼
┌────────────────────────┐
│ LLM.generate() │◄──────────────────┐
│ Response: │ │
│ "Thought: I should... │ │
│ Action: weather │
│ Action Args: {...}" │ │
└───────────┬────────────┘ │
│ │
▼ │
┌───────────────┐ Yes │
│ Has Action? │────────────────────────►│
└───────┬───────┘ │
│ No │
▼ │
┌───────────────┐ │
│ Has Final │ Yes │
│ Answer? │──────────┐ │
└───────┬───────┘ │ │
│ No │ │
▼ ▼ │
┌───────────────┐ ┌──────────────┐ │
│ Execute tool │ │ Return │ │
│ via Executor │ │ answer │────────┘
└───────┬───────┘ └──────────────┘
│
▼
┌───────────────┐
│ Add result to │
│ messages │
└───────┬───────┘
│
└────────────────── (loop back to LLM)
User: "Write a report about AI"
│
▼
┌─────────────────────────┐
│ PHASE 1: PLANNING │
│ LLM generates: │
│ "Step 1: Research AI │
│ Step 2: Outline │
│ Step 3: Write" │
└───────────┬─────────────┘
│
▼
┌─────────────────────────┐
│ PHASE 2: EXECUTION │
│ │
│ For each step: │
│ LLM decides action │
│ Execute tool │
│ Collect result │
└───────────┬─────────────┘
│
▼
┌─────────────────────────┐
│ PHASE 3: SYNTHESIS │
│ LLM combines all │
│ results into final │
│ answer │
└───────────┬─────────────┘
│
▼
Final Answer
User: "Write and publish a blog post"
│
▼
┌─────────────────────────────────────┐
│ SupervisorAgent.run() │
│ │
│ 1. DECOMPOSE │
│ "Subtask 1: Research │
│ Subtask 2: Write │
│ Subtask 3: Publish" │
└───────────────┬─────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ 2. DISPATCH │
│ │
│ Subtask 1 ──► Researcher Agent │
│ Subtask 2 ──► Writer Agent │
│ Subtask 3 ──► Publisher Agent │
│ │
│ (Each agent.run() independently) │
└───────────────┬─────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ 3. SYNTHESIZE │
│ │
│ LLM combines all subtask results │
│ into cohesive final answer │
└───────────────┬─────────────────────┘
│
▼
Final Answer
from agent_framework import AgentFramework, OpenAILLM
# Initialize
fw = AgentFramework(llm=OpenAILLM(api_key="your-api-key"))
# Register a tool
@fw.tool(name="weather", description="Get weather for a city")
def get_weather(city: str) -> str:
return f"{city} is sunny, 25°C"
# Run a task
result = fw.run("What's the weather in Beijing?")
print(result)# ReAct (default) — good for most tasks
fw = AgentFramework(llm=llm, mode="react")
# Plan-and-Execute — better for complex multi-step tasks
fw = AgentFramework(llm=llm, mode="plan")agent_framework/
├── __init__.py # Public API: AgentFramework, LLM, OpenAILLM, Message, @tool
├── framework.py # AgentFramework entry point
├── cli.py # Interactive chat CLI
├── core/
│ ├── llm.py # LLM abstract class + OpenAI adapter
│ ├── message.py # Message dataclass + MessageRole enum
│ ├── tool.py # @tool decorator + ToolRegistry
│ ├── executor.py # ActionExecutor — runs tools
│ ├── memory.py # SummarizationMemory
│ └── agent.py # BaseAgent, ReActAgent, PlanAndExecuteAgent
├── multi/
│ └── supervisor.py # SupervisorAgent
└── tools/
├── bash.py # BashTool — execute shell commands
├── file.py # ReadFileTool, WriteFileTool
├── search.py # SearchTool — grep-like text search
├── list_dir.py # ListDirTool — ls-like directory listing
├── web_search.py # WebSearchTool — web search via Tavily
├── calculator.py # CalculatorTool — safe math evaluation
└── datetime_tool.py # DateTimeTool — date/time utilities
from agent_framework.multi import SupervisorAgent
researcher = ReActAgent(llm=llm, executor=executor)
writer = ReActAgent(llm=llm, executor=executor)
researcher.name = "researcher"
writer.name = "writer"
supervisor = SupervisorAgent(llm=llm, sub_agents=[researcher, writer])
result = supervisor.run("Write a report about AI trends")See examples/ directory for runnable examples:
# Basic usage
OPENAI_API_KEY=sk-... python examples/01_basic_usage.py
# Built-in tools (Bash, Read, Write)
OPENAI_API_KEY=sk-... python examples/02_built_in_tools.py# Chat with the agent via CLI
OPENAI_API_KEY=sk-... TAVILY_API_KEY=tvly-... python -m agent_framework.clifrom agent_framework.core.llm import LLM
class AnthropicLLM(LLM):
def __init__(self, api_key: str):
self.api_key = api_key
def generate(self, messages: list[Message]) -> str:
# Implement Anthropic API call
return response_text框架内置常用工具(位于 agent_framework.tools):
from agent_framework import AgentFramework, OpenAILLM
from agent_framework.tools import (
BashTool, ReadFileTool, WriteFileTool,
SearchTool, ListDirTool, WebSearchTool,
CalculatorTool, DateTimeTool
)
fw = AgentFramework(llm=OpenAILLM(api_key="..."))
# Bash command
bash = BashTool(cwd="/tmp", timeout=10)
@fw.tool(name="bash", description="Run shell command")
def bash_cmd(command: str) -> str:
return bash.run(command)
# Read file
read_tool = ReadFileTool(base_dir="/tmp")
@fw.tool(name="read", description="Read a file")
def read_cmd(path: str) -> str:
return read_tool.run(path)
# Write file
write_tool = WriteFileTool(base_dir="/tmp")
@fw.tool(name="write", description="Write to a file")
def write_cmd(path: str, content: str) -> str:
return write_tool.run(path, content)
# Search in files
search_tool = SearchTool(base_dir="/tmp")
@fw.tool(name="search", description="Search text in files")
def search_cmd(pattern: str, path: str = ".") -> str:
return search_tool.run(pattern, path)
# List directory
ls_tool = ListDirTool(base_dir="/tmp")
@fw.tool(name="ls", description="List directory contents")
def ls_cmd(path: str = ".") -> str:
return ls_tool.run(path)
# Web search (requires Tavily API key)
@fw.tool(name="web_search", description="Search the web")
def web_search_cmd(query: str, max_results: int = 5) -> str:
return WebSearchTool().run(query, max_results)
# Calculator
calc_tool = CalculatorTool()
@fw.tool(name="calculator", description="Calculate math expression")
def calc_cmd(expression: str) -> str:
return calc_tool.run(expression)
# DateTime
dt_tool = DateTimeTool()
@fw.tool(name="datetime", description="Get current datetime")
def datetime_cmd(format: str = "%Y-%m-%d %H:%M:%S") -> str:
return dt_tool.run(format)@fw.tool(name="my_tool", description="Does something useful")
def my_tool(arg1: str, arg2: int) -> str:
return f"Result: {arg1}, {arg2}"MIT