Skip to main content
Enable self_improve=True on an agent and after every task it asks itself “did I just learn something reusable?” — if yes, it writes or patches a skill for next time. Use self_improve="background" to reply first and run the review off the hot path.
Before you run any example:
  • Install the SDK: pip install praisonaiagents
  • Set your key: export OPENAI_API_KEY=sk-...
  • Every learning example needs tools= — the review gate only fires after a real tool call.
  • SKILL_WRITE_APPROVAL defaults on, so new skills are staged for approval. Set SKILL_WRITE_APPROVAL=0 for direct local writes.
  • Windows: run with python script.py.
Supported invocation paths. self_improve triggers the review after any of these end-of-turn moments — pick whichever fits your app:
  • agent.start(prompt) — the task-execution path.
  • agent.chat(prompt) — the conversational path (chatbots, REPLs).
  • agent.achat(prompt) — the async conversational path (gateways, servers).
  • Any custom loop that ends by returning through the after-agent hook.
Async tool calls (via execute_tool_async or async tool functions) are tracked identically to sync ones. Requires praisonaiagents >= 1.6.151 — earlier versions silently skipped the review on chat / achat paths (see Troubleshooting below).
The user assigns a task; after each run the agent may write or patch a skill when it learns something reusable.

Quick Start

1

Simple Usage

After the task ends, the agent runs a guarded review pass — but only if at least one tool was used. If a reusable technique emerged it may write a SKILL.md; otherwise it replies NO_SKILL.
2

With Configuration

Require at least three tool calls before a review fires:
3

Background Mode (no added latency)

Reply first, run the review turn off the hot path — ideal for latency-sensitive gateway and bot agents:
4

Chat and Async Chat

The same self_improve flag works with chat() / achat() — the review fires after any turn that used at least one tool.
The review pass is scheduled after every chat turn that used ≥1 tool — inline for self_improve=True, off the hot path for self_improve="background".

How It Works

The task phase requires tools= on the Agent. Without a tool call, the default review gate exits early and no skill is written.
After each turn — whether you called agent.start(), agent.chat(), or agent.achat(), and whether the tool ran sync or async — if self_improve is enabled:
  1. The policy checks should_review(trajectory) — by default, only when ≥1 tool was called
  2. The agent runs one extra turn with only skill_manage available
  3. The agent calls skill_manage to create/patch a skill, or replies NO_SKILL
  4. The internal review exchange is trimmed back out of chat_history

Execution Modes

self_improve accepts strings that pick when the review runs relative to the reply.
  • Inline (True, "inline", "blocking", "sync") — the review turn runs before the reply returns. Simplest; adds one extra LLM round-trip to reply latency.
  • Background ("background", "async") — the reply returns first, then the review runs off the hot path on the shared BackgroundJobManager. No added user-visible latency.
Prefer background for latency-sensitive gateway or bot agents; prefer inline for batch jobs where latency does not matter.
  • Best-effort fallback — if the background runner is unreachable, the review runs inline rather than being dropped.
  • Gateway clonesclone_for_channel() preserves the background mode on per-channel gateway clones.

Configuration Options

Agent(self_improve=...)

An unrecognised string (e.g. a typo like "backround") disables self-improvement and logs a warning rather than silently enabling a review on every reply.

DefaultSkillReviewPolicy

SkillReviewProtocol (custom policy)

trajectory shape: {"prompt": str, "response": str, "tools_used": list[str]}.

Choosing What to Pass


Inline vs Background

Choose based on how latency-sensitive the reply is.

Common Patterns

Agent that gets sharper over time

Conservative policy (only review heavy sessions)

Fully custom policy


Guarantees

  • Off by default — explicit opt-in via a single switch.
  • Never runs with the full toolset — the review turn sees only skill_manage.
  • Re-entrancy guarded — a review turn cannot trigger another review.
  • Chat-history isolated — the review exchange is trimmed back out after the pass; chatbots and REPLs are unaffected.
  • Best-effort — any failure is logged and swallowed; your main task response is never affected.
  • Distinct from reflectionreflection retries for answer quality within a task; self_improve captures durable skills for next time. They are independent flags and compose cleanly.
Background mode guarantees
  • Reply first — the user-visible response returns before the review LLM turn starts.
  • Serialized per agent — a background review holds a per-agent lock, so the next turn on the same agent waits its turn instead of racing chat-history state.
  • Unique job id — every review gets a fresh id, so overlapping reviews never overwrite each other in the background job map.
  • Falls back to inline — if the background job runner is unreachable, the review runs inline instead of being silently dropped.
  • Same guardrails as inline — restricted-tool review turn, chat-history isolation, best-effort failure swallowing all still apply.

Troubleshooting

Ran self-improve and see no SKILL.md on disk? Work through these four causes in order.
The model judged that nothing durable emerged, so it replied NO_SKILL and wrote nothing. Enable INFO logging to see the review response:
SKILL_WRITE_APPROVAL is on by default, so the review stages the skill instead of writing it. Check the pending store:
The staged proposal lives in ~/.praisonai/skills/.pending_skills.json.
./.praisonai/skills/ did not exist, so the write fell back to ~/.praisonai/skills/. Create the folder so the next run lands in the project:
On a direct write the SDK logs the exact path — grep for Skill created: after enabling INFO logging.
Self-improve only reviews when the task used at least one tool — the guarded review skips tool-less tasks. Confirm the agent has tools= and that the task actually invoked one.
On praisonaiagents < 1.6.151, the chat and async-chat paths returned without wiring tools_used into the review hook, so the default policy always saw an empty tools list and skipped the review — silently, with no warning. Upgrade to fix:
Confirm the fix with a one-line reproducer:
If the review still doesn’t run on 1.6.151+, check the other accordions — the most common causes are (a) no tools= on the Agent, (b) the task didn’t actually call a tool, or (c) SKILL_WRITE_APPROVAL staged the create rather than writing directly.

Best Practices

The default policy is conservative (≥1 tool call). Only switch to a custom min_tool_calls when you see review LLM cost you want to cut.
Skills written by the review land in the project’s ./.praisonai/skills/ when that directory exists in the cwd, otherwise in ~/.praisonai/skills/. Discovery is broader (project → ancestors → user → system), but writes only use those two locations — they never walk ancestors. Run mkdir -p .praisonai/skills in the project you want captures to accumulate in.
reflection improves this answer; self_improve captures a skill for next time. They compose cleanly — turn both on if you want both behaviors.
Any object with should_review and review_prompt satisfies SkillReviewProtocol. Use this to gate on cost, time-of-day, session length, or any other signal.
If your agent lives inside a chatbot, gateway, or bot process where users notice reply latency, pass self_improve="background" instead of True. The review still runs after every task — it just doesn’t sit in front of the reply.
SKILL_WRITE_APPROVAL is on by default, so a review that decides to save a skill stages it as a pending proposal instead of writing to disk. Approve it later, or set SKILL_WRITE_APPROVAL=0 for direct writes in trusted local tests.
When staging is on, the destination for each proposal is pinned at staging time. If you later run SkillManager.approve(id) from a different working directory — from ~, from a CI job, from another project — the approved skill is still written back to the original project’s .praisonai/skills/. You never lose the origin by approving elsewhere.Async tool calls made from achat or execute_tool_async are tracked identically to sync calls — the review fires whether the tool ran sync or async, and pending creates staged from an async turn behave the same as those staged from a sync turn.

Skill Manage

The underlying tool the review uses to create and patch skills

Skills

What skills are and how agents use them

Hooks

Where the review trigger is wired — the after-agent funnel

Self Reflection

Improves answer quality within a task