Skip to main content

Lightweight multi-agent framework with Trace, ReAct, A-MEM memory system

Project description

QAgent Logo

QAgent

Lightweight Multi-Agent Framework for Python

Python Version License


✨ Features

  • 🎯 Minimalist - Clean design, only 12 core modules
  • 📊 Stack-based Trace - Auto-track multi-agent interactions
  • Async-first - Full async I/O, concurrent tool execution
  • 🔄 Auto-failover - ChaterPool switches models automatically
  • 🧠 A-MEM - Self-evolving memory (arXiv:2502.12110)
  • 🤖 ReAct - Complete reasoning-action loop
  • 🛠️ MCP - Native Model Context Protocol support
  • 🌐 Multi-agent - MsgHub broadcast, Pipeline orchestration
  • 🔀 Flow - Lightweight workflow with loops, branches, parallel execution

🚀 Quick Start

import asyncio
from qagent import Agent, Memory, Chater, Runner, get_chater_cfg

agent = Agent(
    name="Assistant",
    chater=Chater(get_chater_cfg("ali")),
    memory=Memory(),
    system_prompt="You are helpful."
)

async def main():
    result = await Runner.run(agent, "Hello!")
    print(result.content)

asyncio.run(main())

Multi-Agent with Trace

from qagent import trace, Runner, Agent, Chater, Memory, get_chater_cfg

planner = Agent(name="Planner", chater=Chater(get_chater_cfg("ali")), memory=Memory())
executor = Agent(name="Executor", chater=Chater(get_chater_cfg("ali")), memory=Memory())

async def main():
    with trace("workflow"):
        result = await Runner.run_sequential(
            [planner, executor],
            "Plan and execute"
        )

asyncio.run(main())

Flow Workflow

from qagent import Flow, END, Agent, Chater, Memory, get_chater_cfg

writer = Agent(name="Writer", chater=Chater(get_chater_cfg("ali")), memory=Memory())
reviewer = Agent(name="Reviewer", chater=Chater(get_chater_cfg("ali")), memory=Memory())

flow = Flow("write_review").add("write", writer).add("review", reviewer).max_loops(3)
flow.route("write").to("review")
flow.route("review").when(lambda r: "APPROVED" in r.content).to(END).default().to("write")

result = await flow.reply("Write a haiku about coding")

📐 Architecture

graph TB
    subgraph Application["Application Layer"]
        ReActAgent[ReActAgent]
        AgenticMem[AgenticMemoryAgent]
        CustomAgent[Custom Agents]
    end

    subgraph Core["Core Layer"]
        Agent[Agent]
        Runner[Runner]
        Trace[Trace System]
    end

    subgraph Model["Model Layer"]
        ChaterPool[ChaterPool]
        Chater1[Model 1]
        Chater2[Model 2]
        ChaterN[Model N]

        ChaterPool -->|auto switch| Chater1
        ChaterPool -->|on failure| Chater2
        ChaterPool -.->|backup| ChaterN
    end

    subgraph Tools["Tool Layer"]
        ToolKit[ToolKit]
        PythonFunc[Python Functions]
        MCPTools[MCP Tools]

        ToolKit --> PythonFunc
        ToolKit --> MCPTools
    end

    subgraph Storage["Storage Layer"]
        Memory[Memory]
        VectorStore[VectorStore]
    end

    subgraph Orchestration["Orchestration Layer"]
        MsgHub[MsgHub]
        Pipeline[Pipeline]
        FlowSystem[Flow]
    end

    ReActAgent --> Agent
    AgenticMem --> Agent
    CustomAgent --> Agent

    Agent --> Runner
    Agent --> ChaterPool
    Agent --> ToolKit
    Agent --> Memory

    Runner --> Trace

    AgenticMem --> VectorStore

    MsgHub -.-> Agent
    Pipeline -.-> Agent
    FlowSystem -.-> Agent

    style Trace fill:#e1f5ff
    style Runner fill:#fff4e6
    style ChaterPool fill:#99ccff
    style MsgHub fill:#99ff99
    style FlowSystem fill:#ffccff

Features:

  • ✅ Stack-based - Auto parent-child management
  • ✅ Concurrent-safe - contextvars isolation
  • ✅ Zero-overhead - Fully disabled without trace
  • ✅ Minimal data - Agent span: type/agent_id/input/output only
  • ✅ Complete tracking - Generation/Tool/Custom spans

🔀 Flow System

Lightweight workflow with Agent-native interface:

from qagent import Flow, END, Agent, Chater, Memory, get_chater_cfg

planner = Agent(name="Planner", chater=Chater(get_chater_cfg("ali")), memory=Memory())
executor = Agent(name="Executor", chater=Chater(get_chater_cfg("ali")), memory=Memory())
reviewer = Agent(name="Reviewer", chater=Chater(get_chater_cfg("ali")), memory=Memory())

flow = Flow("plan_execute_review")
flow.add("plan", planner)
flow.add("execute", executor)
flow.add("review", reviewer)

flow.route("plan").to("execute")
flow.route("execute").to("review")
flow.route("review").when(lambda r: "APPROVED" in r.content).to(END).default().to("plan")

result = await flow.reply("Build a web app")  

Loop Pattern

flow = Flow("review_loop").add("write", writer).add("review", reviewer).max_loops(5)
flow.route("write").to("review")
flow.route("review").when(lambda r: "APPROVED" in r.content).to(END).default().to("write")

Parallel Execution

flow = Flow("parallel").parallel("experts", [tech, biz, legal]).add("summarize", summarizer)
flow.route("experts").to("summarize")

Chain Helper

from qagent import chain
flow = chain(agent_a, agent_b, agent_c)
result = await flow.reply("Start")

🙏 Acknowledgments

Inspired by:

📄 License

MIT License

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

qagent-0.1.0.tar.gz (1.4 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

qagent-0.1.0-py3-none-any.whl (85.9 kB view details)

Uploaded Python 3

File details

Details for the file qagent-0.1.0.tar.gz.

File metadata

  • Download URL: qagent-0.1.0.tar.gz
  • Upload date:
  • Size: 1.4 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for qagent-0.1.0.tar.gz
Algorithm Hash digest
SHA256 11612ce17e53ae70884c2ceb9e9eef7302c0e36ddb711ed7c5f833a7ac511f4f
MD5 658ebeaa0fea9762d25b7cbc09ac4ec9
BLAKE2b-256 fe99c57dfa669c1562ed84290eba60fe10034e65a82500029f1d8ceea05eb895

See more details on using hashes here.

File details

Details for the file qagent-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: qagent-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 85.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for qagent-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9e58d40dd7c8ca6596334cab796cdeb73a75da8db055c4b1ae8f14812ff8b091
MD5 0b743a9e2c5938d26852d14d9e3ed507
BLAKE2b-256 7578785ef010ea9884b0a679cf46f787ab5c9e297a6ea89d9af27eebdf7996aa

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page