Sandbox
@HezaoHezao/poirot

Python agent kernel with memory, skills, and sandboxing

Poirot is a reusable Python foundation for agent-led research and coding workflows. It combines a ReAct loop, long-term memory, multi-agent delegation, skill injection, MCP tools, and Docker sandbox controls into one architecture.

217 starsโ€ข18 forksโ€ขPythonโ€ขUpdated 1mo ago
Who it's for

Builders who want to assemble agent workflows with memory, tools, and subagents instead of a single chat loop.

What it delivers

You can run agent sessions that keep context, delegate work, and write artifacts in a controlled environment.

What it does

ReAct research kernel

A `LeaderAgent` runs the loop while LangGraph handles the outer flow and middleware hooks handle cross-cutting behavior.

Five-layer memory system

It stores, recalls, externalizes, and consolidates long-term memory with a markdown-backed store and hybrid retrieval.

Multi-agent delegation

It can hand tasks to external coding agents or spawn self-copy subagents that share a sandbox.

Sandbox isolation

It enforces file paths and supports local or Docker execution so agent writes persist in the right place.

Skill architecture

It loads and evolves reusable research skills, with search, selection, evaluation, and rollback support.

MCP tool ecosystem

It connects to tools through stdio, SSE, and HTTP transports with on-demand loading and fallback chains.

README

Poirot README Hero

A Deep Research Agent Kernel with Long-Term Memory

License: MIT Python 3.12+ LangGraph DeepSeek

๐Ÿ“š Documentation: English ยท ็ฎ€ไฝ“ไธญๆ–‡ ยท ๆ—ฅๆœฌ่ชž

ReAct Loop ยท Context Governance ยท 5-Layer Memory ยท Multi-Agent Orchestration ยท Skill Self-Evolution ยท Sandbox Isolation


PoirotPoirot

Overview

Poirot is a deep research agent kernel built for those who care about how agents are architected. Rather than chasing a feature checklist, Poirot establishes a clean, decoupled, evaluable foundation โ€” from the ReAct core loop to context engineering governance, from a five-layer long-term memory system to multi-agent orchestration with shared sandbox isolation, from sandbox path enforcement to a three-layer skill self-evolution system.

Every module is independently designed, independently tested, and independently verifiable. 2400+ tests guard every layer.


Core Modules

๐Ÿง  ReAct Research Kernel

A single LeaderAgent orchestrates the research loop. LangGraph handles outer flow orchestration (prepare โ†’ leader_agent โ†’ finalize), while 21 middleware cross-cut every lifecycle hook: before/after_agent, before/after_model, wrap_tool_call.

Breakthrough: Middleware are first-class citizens โ€” memory recall, skill injection, sandbox lifecycle, consolidation, tool-call pairing, help requests, and context governance are all pluggable cross-cutting concerns, not embedded in the agent loop. The app โ†’ agents dependency is strictly one-directional.

๐Ÿ“ Context Engineering Governance

The DefaultStrategy dynamically externalizes historical messages based on a live token budget. Window size is resolved by penetrating through the FallbackChatModel to the active provider's real context window โ€” no hardcoded thresholds. Dual strategies โ€” compaction (summarization) and externalization (offloading) โ€” prevent context overflow in long research sessions without losing critical information.

Breakthrough: The governance layer treats token budget as a first-class runtime concern. The fraction denominator is the real model window (resolved at call time), not a static config โ€” making P5 circuit-breaker thresholds accurate across provider switches.

๐Ÿงฌ Five-Layer Long-Term Memory

Poirot implements a cognitive-science-inspired memory system across five layers, each independently testable:

LayerRoleKey Breakthrough
L1Schema + ProtocolMemoryTrace frozen dataclass (15 fields) + MemoryType enum (episodic/semantic/procedural) + 5 atomic operations (Encode/Retrieve/Associate/Consolidate/Reconsolidate) โ€” tools have no LLM, pure data operations
L2Default StrategiesEbbinghaus decay formula (strength = baseร—(1-decay)^hours + log(1+access)ร—0.1 + importanceร—0.05) + composite forget (TTL + strength threshold) + 6 hard-wired decisions (A1-F2) โ€” lazy decay, strength computed at retrieve time, no background tasks
L3Store + RetrieverMarkdownFileStore (single traces.md truth source + <!-- trace: {id} --> separators + YAML frontmatter) + HybridRetriever (pure BM25, no vector/graph dependency) โ€” retrieve reinforcement write-back (1A:ๅ‘ฝไธญๅŽ store.update ๅผบๅŒ– strength) + forgotten filtering (3B: metadata.forgotten=True excluded) + incremental index (5B: store decorator triggers retriever.on_trace_*)
L4Middleware + BootstrapMemoryMiddleware.abefore_model โ€” per-call HumanMessage injection (protects prompt caching, hide_from_ui=True) + set_turn_id ContextVar (traceability C: actor = turn:N) + bootstrap lifecycle (lazy-load double-check lock + set_memory_config global singleton sync)
L5Auto-ConsolidationMemoryConsolidationMiddleware.aafter_model โ€” non-blocking submit every N turns + MemoryWorker (daemon thread + threading.Queue + LLM construction injection) โ€” LLM extracts episodic memories โ†’ manager.encode โ†’ candidate โ‰ฅ N โ†’ LLM generates merged content โ†’ manager.consolidate (max=10, E1) โ€” errors: log + skip, never blocks main loop

Key Design: Memory injection is per-call HumanMessage (not system prompt), protecting the LLM's prompt cache prefix. recalled_memories in state stores only indices (id+score+strength), not full content. The MemoryConfig has 4 STARTUP_ONLY fields (use/storage_path/vector_store/graph_store) โ€” the rest are runtime-swappable via set_memory_config().

๐Ÿค Multi-Agent Orchestration

Poirot supports delegating sub-tasks to external coding agents and internal self-copies:

  • Specialist Delegation โ€” delegate_to_specialist(goal, success_criteria) routes to external CLIs (pi / codex / claude) via MCP SpecialistMcpServer (8 sandbox tools exposed). Each specialist runs as a separate process with its own LLM, but shares the same Docker sandbox via --sandbox-url passthrough.
  • Subagent (Self-Copy) โ€” delegate_to_subagent(goal) creates a Poirot self-copy with isolated context (no inherited message history) but shared thread sandbox. SandboxMiddleware.abefore_model restores ContextVar from state["sandbox"] โ€” subagent reuses parent's sandbox_id without re-acquiring.
  • L2 Evolution Layer โ€” data-driven specialist self-evolution: MetricMonitor triggers when effective_rate < threshold, IVEFocuser diagnoses, LLMMutator varies, ScoreDeltaGate gates, GitRatchet rollbacks on degradation.
  • L3 Eval Layer โ€” three-layer evaluation: execution judgment (per-skill per-task LLM), task quality scoring (4-dimension weighted), response contract checking. RuntimeTracker feeds degradation signals back to L2.

Breakthrough: The "shared thread sandbox" (INV#3) is now actually implemented โ€” subagent restores ContextVar from state, specialist connects to write to the same mount area, not ephemeral container-internal paths.

๐Ÿ›ก๏ธ Sandbox Isolation with Path Enforcement

Two providers: Local (host process, for development) and Docker (container isolation, for production).

Docker mode breakthroughs:

  • DockerPathTranslator โ€” translate_path passes through (container path = bind mount path), reverse_translate maps /mnt/poirot/user-data/<x> โ†’ <sandbox_root>/<sandbox_id>/<x> (Windows host path) โ€” fixes the present_files artifact extraction chain (shutil.copy2 now gets a real Windows path, not a container path)
  • DockerPathGuard โ€” write path whitelist: write_file/str_replace paths must be under /mnt/poirot/user-data/, bash redirect targets (>{1,2}\s*(/[^\s;|&]*)) must be in mount area โ€” forces agent writes to persist, not lost in container-internal /tmp on --rm
  • Warm pool โ€” pre-created containers reduce cold-start latency
  • Idle auto-destroy โ€” POIROT_SANDBOX_IDLE_TIMEOUT=600 (10min)
  • Cross-process lock โ€” concurrent Poirot instances don't conflict (3-function lock: open/lock/unlock)
  • WSL2 executor โ€” WslDockerExecutor translates D:\foo\bar โ†’ /mnt/d/foo/bar for Docker daemon in WSL2

๐Ÿ”Œ MCP Tool Ecosystem

Three transports: stdio, sse, http. Core tools load at startup; non-core tools defer-load on demand. Tool equivalence fallback chains (e.g., web_search โ†’ MCP server โ†’ builtin ddg) ensure resilience. Tool metadata drives externalization thresholds. Configured via .poirot/mcp_servers.yaml.

๐ŸŽฏ Three-Layer Skill Architecture

Skills are research process knowledge bundles โ€” prompt-level injections, not executable functions. "How to verify a source" is a skill. "Execute a web search" is a tool.

  • Layer 1 (Base): SQLite storage with version DAG, quality-filtered LLM hybrid selection, injection middleware, and four-counter metrics (selections / applied / completions / fallbacks).
  • Layer 2 (Evolution): IVEFocuser diagnosis, LLMMutator variation, ScoreDeltaGate gating, GitRatchet ratchet rollback. Skills auto-evolve when effective rate drops below threshold.
  • Layer 3 (Eval): Three-layer evaluation โ€” execution judgment, task quality scoring (4-dimension weighted), response contract checking. RuntimeTracker monitors applied-rate trends and feeds degradation signals back to Layer 2.

36 builtin skills across 5 categories (core / research / software-development / creative / productivity). Core skills auto-load; others discoverable via /skill search.

๐ŸŽจ Dual UI

  • TUI (default): Full-screen Textual app with welcome view + conversation view. Left scrollable log, bottom input box, status bar with live token usage. Wide screens show right-side session info panel.
  • CLI (poirot cli): Traditional scrolling mode with prompt_toolkit + rich. Slash-command completion + bottom toolbar.

๐Ÿ”„ Multi-LLM Fallback

FallbackChatModel constructs a role-based routing chain (researcher / reporter). On transient API failures (rate limit, timeout, 5xx), it automatically degrades to the next provider. DeepSeek always sits at the chain tail as the ultimate fallback.

๐Ÿ“Š Observability

RunJournal records structured events (skill.select, skill.apply, memory.encode, memory.consolidate, compaction, budget). Thread directories persist run artifacts. The /expand command unfolds the previous round's full Thought text and tool results.


Architecture

Poirot Architecture

Outer flow: prepare โ†’ before_agent โ†’ LeaderAgent (ReAct loop) โ†’ after_agent โ†’ finalize. 21 middleware cross-cut every hook. Memory recall (L4) happens in before_model, consolidation (L5) in after_model. Skill injection (L1+L2+L3) in before_model. Tool calls route through Sandbox / MCP / Builtin via wrap_tool_call. Multi-agent delegation via delegate_to_specialist / delegate_to_subagent.


Quick Start

# 1. Clone
git clone <repo-url> && cd Poirot

# 2. Create environment (Python 3.12+)
python -m venv .venv
.venv\Scripts\activate         # Windows
# source .venv/bin/activate    # Linux / macOS

# 3. Install
pip install -e ".[dev]"

# 4. Configure
cp .env.example .env
# Edit .env โ€” fill in at least: DEEPSEEK_API_KEY=sk-xxx

# 5. Launch (TUI by default)
poirot

Type a question to start researching. Type / for command completion, /help for all commands.

Enable Advanced Features

# Long-term memory (L4 recall + L5 auto-consolidation)
POIROT_MEMORY_USE=default
POIROT_MEMORY_PHASE2_ENABLED=true
POIROT_MEMORY_PHASE2_TURNS=10

# Skill system (L1 base + L2 evolution + L3 eval)
POIROT_SKILL_ENABLED=true
POIROT_SKILL_EVOLVE_ENABLED=true
POIROT_SKILL_EVAL_ENABLED=true
POIROT_SKILL_MAX_INJECT=15

# Multi-Agent (specialist delegation + L2/L3)
POIROT_MULTIAGENT_ENABLED=true
POIROT_MULTIAGENT_L2_ENABLED=true
POIROT_MULTIAGENT_L3_ENABLED=true

# Docker sandbox (container isolation)
POIROT_SANDBOX_USE=poirot.backend.agents.sandbox.docker.docker_sandbox_provider:DockerSandboxProvider
POIROT_SANDBOX_EXECUTOR=wsl              # Windows + WSL2 Docker

# MCP tools
POIROT_MCP_ENABLED=true

๐Ÿ‘‰ For full configuration, commands, and troubleshooting โ€” see the Usage Guide.


Screenshots

Poirot TUI Conversation

TUI Conversation View โ€” dual-panel layout with live context governance, sandbox status, and memory recall


Tech Stack

Python LangGraph LangChain Rich Textual prompt_toolkit SQLite Docker PyYAML


Acknowledgments

Poirot stands on the shoulders of giants. The architecture draws inspiration from several outstanding open-source projects and research frameworks:

Agent Architecture โ€” The middleware-first design and ReAct loop orchestration patterns are inspired by modern-based agent frameworks. The separation of concerns โ€” where memory, skills, sandbox, and tool routing are pluggable cross-cutting middleware rather than embedded agent logic โ€” builds upon ideas from conversational agent platforms that prioritize decoupled, testable architectures.

Memory System โ€” The five-layer memory architecture (schema โ†’ strategies โ†’ store โ†’ middleware โ†’ auto-consolidation) is informed by cognitive science models of episodic, semantic, and procedural memory. The Ebbinghaus decay formula, lazy strength computation, and Markdown-as-truth-source patterns draw from long-term memory research in AI agent design. The "tools have no LLM" principle โ€” where atomic operations are pure data transformations and LLM orchestration lives in the middleware layer โ€” is inspired by memory framework designs that separate engine from orchestration.

Multi-Agent Orchestration โ€” The specialist delegation model (where Poirot delegates coding tasks to external CLI agents via MCP) and the shared-thread-sandbox concept build upon multi-agent collaboration patterns from coding agent ecosystems. The idea that a lead agent can orchestrate specialized sub-agents โ€” each with their own LLM and toolset โ€” while sharing a unified sandbox for artifact continuity, is informed by production multi-agent system designs.

Sandbox Isolation โ€” The three-component sandbox model (Runtime + PathTranslator + SecurityGuard) and the warm-pool lifecycle management are inspired by sandbox isolation patterns from deep research agent platforms. The Docker path translation and mount-area enforcement address real-world challenges of cross-platform (Windows + WSL2 + Docker) file persistence.

Skill Self-Evolution โ€” The three-layer skill architecture (base storage โ†’ LLM-driven evolution โ†’ multi-dimensional evaluation) with ratchet rollback and quality gating builds upon self-improving agent research. The concept of skills as "process knowledge bundles" (prompt-level injections, not executable functions) draws from prompt engineering and skill management frameworks.

We gratefully acknowledge the developers and researchers of these projects whose work โ€” whether through direct code patterns, architectural ideas, or research papers โ€” made Poirot possible.


License

MIT ยฉ Poirot Authors


Built for those who care about how agents are built.
If this project helps you, a โญ is appreciated.

Files in the repo

Repository payloadโ€ข12 top-level entries
  • poirot
  • resource
  • .dockerignore
  • .env.example
  • .gitignore
  • docker-compose.yml
  • Dockerfile
  • LICENSE
  • pyproject.toml
  • README.md
  • THIRD_PARTY_LICENSES.md
  • USAGE.md

Discussion (0)

Ask about usage, or say what you built with it

Sign in to join the discussion.

No comments yet. Be the first to say what this is good for.

More frameworks & sdks

HKUDS/nanobotFrameworks & SDKs

Ultra-lightweight, open-source, self-hosted personal AI agent framework in Python with WebUI, tools, memory, MCP, multi-agent workflows, automation, and chat apps

48k
microsoft/
SkillOpt
microsoft/SkillOptFrameworks & SDKs

SkillOpt is a text-space optimizer that trains reusable natural-language skills for frozen LLM agents through trajectory-driven edits, validation-gated updates, and deployable best_skill.md artifacts.

17k
omnigent-ai/omnigentFrameworks & SDKs

Omnigent is an open-source AI agent framework and meta-harness: orchestrate Claude Code, Codex, Cursor, Pi, and custom agents โ€” swap harnesses without rewriting, enforce policies and sandboxing, and collaborate in real time from any device.

9.8k
kyegomez/
OpenMythos
kyegomez/OpenMythosFrameworks & SDKs

A theoretical reconstruction of the Claude Mythos architecture, built from first principles using the available research literature.

15k
D4Vinci/ScraplingFrameworks & SDKs

๐Ÿ•ท๏ธ An adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl!

80k