by HezaoHezao
Poirot is a deep research agent kernel built for those who care about how agents are architected.
# Add to your Claude Code skills
git clone https://github.com/HezaoHezao/poirotpoirot is an open-source ai agents skill for AI coding assistants such as Claude Code, Codex CLI, and ChatGPT, built by HezaoHezao. Poirot is a deep research agent kernel built for those who care about how agents are architected. It has 58 GitHub stars.
poirot's catalog security scan is still queued. You can run an instant dependency and prompt-injection check now with the "Scan for vulnerabilities" button above.
Clone the repository with "git clone https://github.com/HezaoHezao/poirot" and add it to your Claude Code skills directory (see the Installation section above).
poirot is primarily written in Python. It is open-source under HezaoHezao on GitHub, so you can review or fork the full source.
Yes. SkillsLLM lists many other AI Agents skills you can browse and compare side by side. Open the AI Agents category from the badge at the top of this page, or use the Related Skills and comparison links further down to weigh poirot against similar tools.
No comments yet. Be the first to share your thoughts!
Unlocks once the catalog security scan passes (runs nightly).
The deep catalog scan for this skill is still queued. Run an instant dependency check now instead.
📚 Documentation: English · 简体中文 · 日本語
ReAct Loop · Context Governance · 5-Layer Memory · Multi-Agent Orchestration · Skill Self-Evolution · Sandbox Isolation
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.
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.
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.
Poirot implements a cognitive-science-inspired memory system across five layers, each independently testable:
| Layer | Role | Key Breakthrough |
|---|---|---|
| L1 | Schema + Protocol | MemoryTrace frozen dataclass (15 fields) + MemoryType enum (episodic/semantic/procedural) + 5 atomic operations (Encode/Retrieve/Associate/Consolidate/Reconsolidate) — tools have no LLM, pure data operations |
| L2 | Default Strategies | Ebbinghaus 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 |
| L3 | Store + Retriever | MarkdownFileStore (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_*) |
| L4 | Middleware + Bootstrap | MemoryMiddleware.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) |
| L5 | Auto-Consolidation | MemoryConsolidationMiddleware.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().
Poirot supports delegating sub-tasks to external coding agents and internal self-copies:
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.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.MetricMonitor triggers when effective_rate < threshold, IVEFocuser diagnoses, LLMMutator varies, ScoreDeltaGate gates, GitRatchet rollbacks on degradation.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.
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 --rmPOIROT_SANDBOX_IDLE_TIMEOUT=600 (10min)WslDockerExecutor translates D:\foo\bar → /mnt/d/foo/bar for Docker daemon in WSL2Three 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.
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.
IVEFocuser diagnosis, LLMMutator variation, ScoreDeltaGate gating, GitRatchet ratchet rollback. Skills auto-evolve when effective rate drops below threshold.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.
poirot cli): Traditional scrolling mode with prompt_toolkit + rich. Slash-command completion + bottom toolbar.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.
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 t