Agentic AI Masterclass Curated by Arunabh Bhattacharjee
Part VII - Measurement & Improvement · Chapter 26
26

Self-Improvement

Skills, tools and memory the agent writes for itself — the verification gate, demotion, and why proposing is cheap while accepting is expensive.

28 min read · Part VII - Measurement & Improvement · Updated 9 November 2026

In this illustrative example, Reference Agent learned a useful procedure over four difficult runs. It traced a settlement discrepancy through the ledger to its originating batch. The undocumented procedure required three tools in a specific order and one non-obvious check. Reference Agent saved it as a skill. The next twelve runs of that task type took nine turns instead of twenty-two.

The fourth skill encoded a shortcut that worked for one tenant’s configuration and failed for others. Reference Agent retrieved and followed the authoritative wording. Eleven runs produced wrong answers before anyone connected them to the skill. Without a verification criterion, the system could not detect the defect.

A good self-authored artefact compounds; a bad one compounds too.

26.1What self-improvement means in production#

Self-improvement has three forms with increasing risk:

Procedural memory: saving learned procedures as skills or runbooks.

Tool synthesis — the agent writes new tools for itself, typically as code. Real value, higher risk, and a much harder verification problem.

Self-modification — the agent changes its own harness, prompts or scaffolding. The research frontier, with genuinely striking results and genuinely serious caveats.

Here, self-improvement changes external procedures or code. Weight updates are treated separately as evaluated training releases (Chapter 27); this does not rule out online adaptation.

Hermes Agent documents a skills system alongside memory files.3 OpenHands supports SKILL.md procedures with optional keyword and path triggers.4

Devin is moving Playbooks to Skills. New accounts use Skills from 24 October 2026, while existing accounts migrate gradually.5 Devin also deprecates Knowledge and migrates it to Skills in Plugins.6 These mechanisms share reusable procedures, but their scopes and trust rules differ.

26.2The asymmetry#

Proposals are cheap; acceptance requires evidence.

A proposed skill costs one model call. An accepted skill is retrieved on every matching task, followed with the authority of established procedure, and read by a model that has no way to know it was self-authored rather than written by an expert. A wrong skill can repeatedly steer later runs into error. Reasoning without one is not automatically correct either; compare both conditions on the intended task population.

The Darwin Gödel Machine study evaluates code changes empirically. It reports gains from 20.0% to 50.0% on SWE-bench and 14.2% to 30.7% on Polyglot in its experimental setup. Its authors state that “proving that most changes are net beneficial is impossible in practice.”1

That sentence is the design constraint. Broad real-world usefulness is usually not something a finite test or proof can establish. You can test it, and the whole engineering question is what test, how expensive, and what happens when it fails.

Design Rule

Never let an agent write to a store it will later trust without a gate between them. The gate does not need to be clever — structural checks reject obvious defects cheaply — but something must stand between “the agent thought of this” and “the system believes this.” Self-improvement without a gate is drift with extra steps.

26.3The skill: a unit that works#

A skill is a named procedure. What makes it engineerable rather than a note is that it carries the means of its own verification.

python
@dataclass
class Skill:
    name: str
    goal: str                            # when to use this skill
    steps: list[str] = field(default_factory=list)
    pitfalls: list[str] = field(default_factory=list)
    checks: list[str] = field(default_factory=list)   # how to verify success
    tools_used: tuple[str, ...] = ()
    status: SkillStatus = SkillStatus.PROPOSED
    version: int = 1
    author: str = "agent"
    trials: list[SkillTrial] = field(default_factory=list)

    @property
    def success_rate(self) -> float:
        if not self.trials:
            return 0.0
        return sum(1 for t in self.trials if t.passed) / len(self.trials)

goal is a trigger condition, not a title. “When an internal TLS certificate is within seven days of expiry” is retrievable; “Certificate rotation” is a filing label. This field is what retrieval matches against, so vagueness here means the skill surfaces for the wrong tasks.

checks is what makes a skill testable. “openssl reports the new expiry more than 60 days out” is a verification criterion. A skill without one is a skill whose success is the model’s opinion — and the fourth skill in the opening story had none.

pitfalls is where hard-won knowledge lives. “The CA rejects requests without a ticket reference” is exactly the kind of fact that costs three failed runs to learn and one line to record. It is also, empirically, the field the agent writes best, because it is describing something that actually happened.

tools_used lets the gate check for references to tools that do not exist, which catches a proposal built on a hallucinated capability.

Use prose for procedures that need interpretation and code for precisely specified, repeatable operations. Both can become stale when tools or policies change. Prose can hide ambiguity; code can encode a wrong assumption. Give either form explicit applicability conditions, versioned dependencies and verification criteria.

26.4The verification gate#

Two tiers separate cheap format filters from more expensive behavioural evidence.

Structural checks are inexpensive filters, not semantic verification:

python
def structural(self, skill: Skill) -> list[str]:
    problems: list[str] = []
    if len(skill.steps) < self.min_steps:
        problems.append(f"only {len(skill.steps)} step(s); need >= {self.min_steps}")
    if self.require_checks and not skill.checks:
        problems.append("no verification criteria — success cannot be judged")
    unknown = [t for t in skill.tools_used if t not in self.known_tools]
    if unknown:
        problems.append(f"references unknown tools: {unknown}")
    if len(skill.render()) > 4_000:
        problems.append("skill is too long to be worth recalling")
    for s in skill.steps:
        if re.search(r"ignore .*instructions|disable .*guardrail|skip .*approval", s, re.I):
            problems.append(f"step attempts to weaken controls: {s!r}")
    return problems

Structural checks enforce format, not usefulness or correctness. A one-step procedure may be useful; a registered tool may be misused. Require verification criteria. A self-authored artefact must not weaken an enforced control. The regex detects only a few phrases, not paraphrases, so enforce permissions independently of skill text. A proposed instruction to skip approval is a privilege-escalation attempt, whether accidental or injected (Chapter 21).

Behavioural verification runs the proposed procedure on controlled cases and checks whether it helps within its stated scope. The gate takes this as an injected function because only the host system knows how to run its own tasks:

python
@dataclass
class VerificationGate:
    known_tools: frozenset[str] = frozenset()
    min_steps: int = 2
    require_checks: bool = True
    behavioural: Verifier | None = None
    min_trials: int = 1
    min_success_rate: float = 1.0

Start by turning the originating task into a regression case (Chapter 24), then test held-out cases and compare against the no-skill baseline. Replaying the source task alone is insufficient for promotion. This connects the two chapters neatly: the skill’s justification is a test, the test joins the suite permanently, and a skill that later stops working fails a test rather than producing eleven wrong answers.

26.5An evaluation that can refuse promotion#

A behavioural gate is useful only if it can return no when a proposal appears helpful. If the test asks whether Reference Agent can complete the one task that produced the skill, the skill has already seen the answer. You have measured recall, not generalisation. The promotion experiment needs held-out cases, a no-skill control, repeated runs, and hard trajectory constraints as well as an outcome score.

The reference implementation supplies both halves but does not connect them for you. skills.py accepts a caller-supplied behavioural function that returns a SkillTrial. evals.py runs cases through outcome, trajectory and efficiency scorers. A production host must bind them: construct an Reference Agent runner with the proposed skill available, run a fixed suite, compare it with the same runner without the skill, and convert the whole decision into one trial. The SkillLibrary does not secretly perform that experiment.

python
on_report = run_eval(
    held_out_cases,
    runner_with(proposed_skill),
    scorers=[OutcomeScorer(), TrajectoryScorer(), EfficiencyScorer()],
    repeats=3,
)
off_report = run_eval(
    held_out_cases,
    runner_without(proposed_skill),
    scorers=[OutcomeScorer(), TrajectoryScorer(), EfficiencyScorer()],
    repeats=3,
)

That code shape matters more than a sophisticated judge. The two runners differ in one condition — whether the proposal is recalled — and the scorers ask three different questions. Did Reference Agent get the answer? Did it take a route you permit? Did it remain inside the cost and turn ceilings? A skill that improves the first by violating the second has found a shortcut, not an improvement.

Consider an illustrative evaluation of a settlement-reconciliation skill. You select 80 held-out cases across tenant configurations and run each case three times in each condition, producing 240 runs per arm and 240 matched skill-on versus skill-off comparisons. The model version, tools, policy, budgets and case order are fixed. Only skill recall changes.

Measure Library off Proposed skill on Difference
Outcome passes 198 / 240 (82.5%) 210 / 240 (87.5%) +5.0 percentage points
Total turns 2,640 2,160 -480 (-18.2%)
Total model cost $34.56 $31.68 -$2.88 (-8.3%)
Forbidden trajectory violations 2 / 240 7 / 240 +5 violations

The headline says promote: twelve additional answers passed, turns fell by two per run on average, and cost fell from $0.144 to $0.132 per run. The matched results are less decisive. Forty comparisons disagree: in 26, only the skill-on run passes; in 14, only the skill-off run passes. The net advantage is therefore (26 - 14) / 240 = 5%, exactly the aggregate difference, but it rests on twelve net comparisons rather than on 240 independent case wins. You need more held-out cases and cohort coverage before claiming a stable five-point gain.

You do not need more runs to act on the trajectory regression. Seven forbidden calls is worse than two, and the permission contract does not become negotiable because the final answer improved. The promotion gate rejects this version, error analysis reads those seven traces, and a revised skill enters as a new proposal. Outcome, cost and latency are optimisation objectives; control compliance is a constraint.

Predeclare the decision before running the comparison. For example: no increase in forbidden calls; no outcome regression in any high-risk tenant stratum; at least a two-point overall outcome gain; and at least a ten per cent reduction in either turns or cost. Without a written decision rule, a team will promote whichever column looks favourable after the report arrives. This is the same evaluation hygiene Chapter 24 applies to model and prompt changes, brought down to one procedural artefact.

The unit of analysis must match the intended trigger. If a skill claims to work for “settlement discrepancy”, the suite needs every supported settlement configuration. If it applies only when batch identifiers are globally unique, make that predicate part of the trigger and test only that declared population. Narrowing a truthful skill is an improvement. Broadening the evaluation until a vague skill happens to pass is not.

Freeze the candidate before the experiment. Store the rendered skill, its version or content hash, the eval-case revision, the model identifier, the tool schemas and the policy revision beside the report. If the agent edits one step after seeing a failure, that revision is a new candidate and the comparison restarts. Otherwise the promoted artefact is not the artefact you measured. This is the skill-sized version of the reproducibility contract in Chapter 24.

Treat repeated runs as repeated observations of the same cases, not as 240 newly independent tasks. The three runs improve your estimate of stochastic reliability: a case that passes once and fails twice is unstable even if the aggregate looks healthy. They do not expand coverage beyond the original 80 cases or establish stability across tenant cohorts you did not sample. Add held-out cases and cohorts for that. Report pass^k for high-consequence procedures — the fraction of cases that pass on every repeat — alongside the ordinary run pass rate. A skill that moves from 82.5% to 87.5% per run but makes the same tenant cohort fail intermittently has not earned broad recall.

The illustrative experiment costs $34.56 + $31.68 = $66.24. That looks expensive beside one proposal call and cheap beside eleven incorrect settlements. Promotion cost should scale with prospective blast radius: a read-only formatting skill may justify a short deterministic suite, while a procedure that influences payments needs enough cohort coverage to expose configuration-specific shortcuts. The gate is not one universal threshold; it is a minimum evidence contract by risk class.

Keep the holdback after promotion. An offline suite samples known failure dimensions, while production supplies combinations you did not think to encode. Route a stable share of eligible tasks through the no-skill path, compare the same business invariant by cohort, and alert on the difference. This is not permission to experiment with an unsafe action — both arms remain inside the same policy — but it preserves a counterfactual after the launch dashboard would otherwise show only the new world.

Measure the trigger separately from the procedure. In an illustrative shadow sample of 1,000 tasks, a domain label marks 180 as eligible and the retriever surfaces the skill for 210. If 162 are true matches, trigger precision is 162 / 210 = 77.1% and recall is 162 / 180 = 90%. The procedure may be perfect on those 162 tasks and still be unsafe because it intrudes on 48 others. Procedure success cannot repair trigger false positives; narrow the goal or add an authoritative applicability predicate.

26.6Demotion, versioning, and rot#

A skill that was right in March can be wrong in September, because the system it describes changed. Self-improvement without a decay mechanism is a slow accumulation of stale procedure.

python
def record_use(self, skill_id: str, passed: bool, detail: str = "") -> None:
    """Outcome feedback. A skill that stops working must stop being used —
    otherwise self-improvement compounds in the wrong direction."""
    skill = self.skills.get(skill_id)
    skill.trials.append(SkillTrial(passed=passed, detail=detail))
    if (len(skill.trials) >= self.demote_after_trials
            and skill.success_rate < self.demote_below):
        skill.status = SkillStatus.DEPRECATED

Automatic demotion on measured failure. The mechanism above. The important property is that it is automatic — the same argument as Chapter 19’s autonomy demotion: a removal that requires a meeting will not happen when it is needed.

Versioning rather than mutation. A revised skill is version N+1 and the prior version is marked deprecated, not deleted. This keeps the history auditable and makes a bad revision revertible.

python
if status is SkillStatus.VERIFIED:
    prior = self._find_by_name(skill.name)
    if prior:
        skill.version = prior.version + 1
        prior.status = SkillStatus.DEPRECATED
    self.skills[skill.id] = skill
else:
    self.skills[skill.id] = skill      # kept, but not retrievable

Note that quarantined skills are kept. They are the record of what the agent proposed and why it was rejected, which is a genuinely useful signal — a rising quarantine rate means the proposal quality is dropping, and the reasons tell you why.

Expiry for skills describing changing systems. A procedure about a service that is being migrated should carry a review date.

Periodic human review of the top skills. The same fifteen minutes a month that Chapter 10 prescribed for semantic memory, applied to the most-recalled skills. This is the cheapest quality control in the chapter and it is what would have caught the tenant-specific shortcut.

26.7The shortcut that passed its own test#

Return to the fourth skill in the opening. The symptom was not an exception or a failed tool. Reference Agent completed every run, cited the ledger rows it had read, and produced an answer in fewer turns. The operations dashboard therefore showed lower cost and normal completion while eleven answers were wrong.

The team first assumed the settlement service had become inconsistent. The errors appeared under different task wording and at different times, so the shared skill was not obvious in a transcript sample. Only a retrieval trace joined the incidents: all eleven runs had recalled the same procedure before the first tool call.

Here is the illustrative sequence. The four difficult runs from which Reference Agent learned the procedure all belonged to tenant Northstar. That tenant used globally unique batch identifiers, so looking up a batch directly and tracing backwards was valid. The proposed goal said “use for a settlement discrepancy”, not “use when the tenant guarantees globally unique batch identifiers”. Structural checks saw three steps, a known ledger tool and syntactically valid prose. Three behavioural trials replayed Northstar cases and all passed. The sample contained seven demonstrations of one configuration and none of the configurations for which the shortcut was invalid.

The next sixteen uses contained five Northstar cases and eleven cases from tenants whose batch identifiers were unique only within an account. The five Northstar answers were right. The other eleven joined rows from the wrong account. True task success was 5 / 16 = 31.25%.

Why did automatic demotion not stop it? The feedback label measured termination, not truth. The host recorded passed=True because the run reached COMPLETED and returned an answer. SkillLibrary.record_use() accepts the boolean it is given; it cannot inspect the settlement invariant or execute the natural-language contents of checks. Sixteen proxy labels therefore produced a reported success rate of 100%, while the business outcome was 31.25%. The demotion arithmetic was correct and the evidence was false.

The fix has four parts.

Failure in the chain Repair Owner
Trigger omitted the tenant configuration Add a structured applicability predicate for identifier scope Host and domain owner
Verification repeated the originating configuration Hold out cases and stratify them across supported tenant modes Evaluation owner
“Completed” stood in for “correct” Evaluate the ledger invariant: every joined row must match tenant and account Tool adapter and evaluator
Global rollout followed three passing replays Shadow recall first, then a bounded tenant canary with a holdback Release controller

The structured applicability predicate is a production extension, not a field in the reference Skill dataclass. Its value must come from authenticated tenant configuration supplied by the host, not from the document that prompted the skill and not from the model’s guess. Reference Agent may propose that a predicate is relevant; it may not assert the predicate is true for the current tenant.

Once the correct business check feeds record_use, the existing demotion rule becomes meaningful. The same trials list already contains the three successful behavioural trials, then receives five successful production outcomes before the failures begin. After eight production failures, lifetime success is therefore 8 / 16 = 50%, so the strict < 0.5 threshold does not fire. The ninth failure makes it 8 / 17 = 47.1%, and the skill becomes DEPRECATED. That is later than you would want for a financial procedure, which is why high-risk skills need a release controller that can stop on the first invariant breach rather than waiting for a generic lifetime success-rate threshold.

A deployment procedure learned only on stateless services, a customer-support reply learned only in one jurisdiction, or a data repair learned before a schema migration can pass a narrow replay and fail its real population. A skill’s scope is a testable claim. Your evaluation has to vary the dimensions named by that claim, and your runtime has to supply those dimensions from an authoritative source.

PROPOSED one model call Structural cheap · 5 checks Behavioural costs a real run VERIFIED retrievable QUARANTINED kept, not used DEPRECATED superseded / rotted RECALLED max 3 per task OUTCOME recorded per use success rate below threshold after N trials → automatic demotion TWO NECESSARY CONTROLS Nothing reaches RECALLED without passing a gate. A quarantined skill is kept as a record but is never retrievable. Demotion is automatic and does not require a human decision, because a removal that needs a meeting will not happen in time.
Figure 26.1 - The skill lifecycle. Promotion requires structural and behavioural checks. Failed feedback can demote a skill; replacement and operator actions can also end recall.
MAY SELF-AUTHOR — behind a gate Procedures · skills · runbook steps Natural language, with verification before reuse. Pitfall notes and dead ends Ground notes in observed failures; check claims before reuse. Semantic facts — with provenance Only through Chapter 10’s write gate. Confidence from the SOURCE. Tools, as sandboxed code Needs verification, isolation and host-controlled risk metadata. MAY NOT SELF-GRANT CONTROL CHANGES Guardrails · permissions · budgets · approval thresholds Independent authority must approve changes to these controls. WHY THE LINE IS WHERE IT IS Above the line: reversible and inspectable Verified external checks can detect a wrong skill; fresh failure evidence should remove it from recall. Human review supplements those checks; it does not guarantee that every wrong fact will be caught. Below the line: a change can weaken the controls Weakening an approval threshold can remove a checkpoint for later actions. The candidate cannot authorise its own wider permissions or reduced oversight. Optimising speed can create pressure to bypass a gate. The structural check, in the gate Any step matching "ignore instructions", "disable guardrail" or "skip approval" can be rejected by a simple regex. Paraphrases still require independent policy enforcement.
Figure 26.2 - Gated proposals and independently authorised controls. An agent must not approve its own wider permissions or reduced oversight.
EVIDENCE ACCUMULATES LEFT TO RIGHT; AUTHORITY EXPANDS ONLY AFTER THE NEXT GATE PASSES PROPOSED Originating run Procedure + checks No retrieval AUTHORITY: NONE STRUCTURAL Known tools Checks present No obvious bypass text CHEAP FILTER PAIRED EVAL 80 cases × 3 240 runs per arm Tenant-stratified Safety: no regression HELD OUT SHADOW Recall on traffic No influence Check trigger fit NO NEW EFFECTS BOUNDED Scoped tenant canary Holdback remains Stop on invariant LIMITED USE VERIFIED Scoped recall Outcome feedback Rolling demotion RETRIEVABLE QUARANTINED — retained as evidence, never recalled Structural failure · cohort regression · forbidden trajectory · trigger mismatch · failed invariant Revision creates a new proposal; it does not edit the rejected evidence in place. ANY FAILED GATE ILLUSTRATIVE RELEASE CONTRACT — THE PERCENTAGE AND COHORT SIZE MUST FOLLOW THE RISK OF YOUR TASK
Figure 26.3 - The production promotion ladder for a self-authored skill. The reference implementation supplies the structural gate and an injectable behavioural seam; tenant-stratified comparison, shadow observation and bounded rollout are host-system extensions.

26.8Recall discipline#

A large skill library fails in a way that is not obvious: the problem is not that the agent lacks knowledge, it is that ten mediocre skills crowd out the one good one and consume the context budget doing it.

python
@dataclass
class SkillLibrary:
    max_recall: int = 3
    demote_below: float = 0.5
    demote_after_trials: int = 4

    def recall(self, goal: str) -> list[Skill]:
        want = set(re.findall(r"[a-z0-9]{3,}", goal.lower()))
        usable = [s for s in self.skills.values() if s.status is SkillStatus.VERIFIED]
        scored = [(overlap * (0.5 + 0.5 * s.success_rate), s)
                  for s in usable if (overlap := len(want & s.keywords))]
        scored.sort(key=lambda p: -p[0])
        return [s for _, s in scored[: self.max_recall]]

Three properties worth copying. A hard cap, three in this teaching implementation, alongside a relevance threshold — a threshold lets a broad task pull in twenty skills. Success rate weights the ranking, so a skill with a track record outranks an equally-relevant one without. And only verified skills are retrievable, which is what makes the gate meaningful rather than advisory.

Shipped systems expose different relevance controls. Hermes loads bounded memory files as a frozen snapshot.3 OpenHands advertises skill metadata first, then loads the body on invocation. It also supports keyword and path activation.4 Devin’s Skills similarly expose names and descriptions before the body. Its Knowledge migration maps the old trigger to the skill description.56 Keep discovery metadata concise. Load detailed procedure when the task needs it.

26.9The reference harness stops at the control seam#

The Reference Agent implementation is deliberately small enough to inspect, and that makes its boundary unusually clear. It proves that a strict proposal parser can leave an artefact PROPOSED; structural rejection can keep it QUARANTINED; successful replacement can create version N+1 and deprecate version N; recall can exclude every status except VERIFIED; and measured failure can remove a skill from retrieval. The tests in code/tests/test_skills.py pin each of those behaviours.

It does not constitute a production self-improvement service. The default VerificationGate has behavioural=None, so a structurally valid proposal remains PROPOSED, outside retrieval, until a host evaluator is configured:

python
def evaluate_after_structural_checks(self, skill):
    if self.behavioural is None or self.min_trials < 1:
        return SkillStatus.PROPOSED, "awaiting behavioural verification"
    trials = [self.behavioural(skill) for _ in range(self.min_trials)]
    skill.trials.extend(trials)
    rate = sum(t.passed for t in trials) / len(trials)
    if rate < self.min_success_rate:
        return SkillStatus.QUARANTINED, "behavioural verification failed"
    return SkillStatus.VERIFIED, "passed structural and behavioural verification"

This excerpt omits formatting of the detailed rejection reason. Promotion uses fresh host-run trials, not success history supplied with the proposal. An empty known-tool registry accepts no claimed tools. These fail-closed defaults prevent a status from claiming evidence that does not exist; the host still owns the quality and authority of the evaluator.

The outcome path has the same boundary. record_use() trusts a caller-supplied passed boolean, appends it to the cumulative trial list, and compares the lifetime success rate with a threshold. The library does not run the skill’s checks, correlate a trial with a trace, or validate who supplied the label. Those are host responsibilities, and they need explicit interfaces because a completion status, a model-judge opinion and a verified external invariant are different grades of evidence.

Reference Reference Agent demonstrates A production service must add
Strict fenced-JSON parsing with bounded fields Authenticated provenance, proposal run id and schema version
Structural checks and a required evaluator before promotion Domain-specific invariants and evaluator provenance
Injected behavioural callback Held-out cases, on/off comparison, cohort coverage and stored reports
Keyword recall capped at three verified skills Tenant scope, applicability predicates and retrieval explanations
Cumulative success-rate demotion Risk-tiered stop rules, a rolling window and drift alarms
JSON save and load Atomic writes, concurrency control, access policy and audit retention

The cumulative threshold deserves special attention. Suppose a mature skill has 100 passing trials and the underlying service changes overnight. Four consecutive failures leave its lifetime rate at 100 / 104 = 96.2%; the default rule cannot demote it, even though the recent failure rate is 100%. Lifetime evidence answers whether the skill has ever been useful. A rolling window answers whether it is useful now. Keep both: the former supports review and the latter controls retrieval. For a high-risk procedure, also stop immediately on one failed hard invariant.

Do not collapse those evidence grades back into one boolean at the service boundary. A production trial record should carry at least the skill version, task and tenant identifiers, case or trace id, outcome score, trajectory score, invariant results, cost, turns, evaluator revision and label provenance. “Human confirmed”, “authoritative API check” and “model judge passed” may all map to a positive observation, but they do not justify the same authority. The release controller can require an external invariant for a financial skill while allowing a deterministic snapshot comparison for a document-formatting skill.

Bind trials to the exact skill version. Version 2 needs its own promotion evidence rather than inheriting version 1’s success rate. Retain version 1’s traces after deprecation so its earlier acceptance and later failure remain auditable.

Finally, evaluate the evaluator. Track label_missing_rate, disagreement between external invariants and model judges, time from a failed invariant to demotion, and the fraction of recalled skills whose current version has a reproducible promotion report. A rising skill pass rate alongside a rising missing-label rate is not improvement; it is disappearing evidence. A demotion mechanism is only as fast as the signal that reaches it.

Persistence is similarly honest about its scope. save() writes a JSON file directly and load() reconstructs the dataclasses. That proves the library can survive a process restart. It does not provide atomic replacement, concurrent-writer protection, tenant isolation or tamper evidence. If two Reference Agent workers can propose skills, put the store behind a transactional service or a single-writer log (Chapter 5); do not turn a teaching file into a shared control plane by mounting it on network storage.

This boundary is a strength when you preserve it. The reference code gives you a small state machine and tests for its invariants. Your production system supplies the evidence, authority, release process and durable storage around that machine. Blurring the two produces the most dangerous sentence in self-improvement: “the library says it is verified”, with nobody able to say what verified it.

26.10Self-authored tools#

A step up in power and in risk: the agent writes code that becomes a reusable capability.

The Voyager line of work established the pattern — an agent that writes, verifies and stores executable skills, building a library that compounds over time, with new skills composed from earlier ones.2 The result was demonstrated in Minecraft, with environmental feedback and executable skills; transfer to enterprise tools needs separate evidence.

Three conditions distinguish where this is safe.

A cheap verifier exists. The synthesised tool can be tested — deterministic output, a checkable invariant, a test suite. Without this you have unverified code in a trusted position.

It runs in a sandbox. Apply the isolation controls from Chapter 16 to model-authored code.

It cannot expand its own authority. A synthesised tool must be constrained to the capabilities already available. A tool that opens a network connection the agent did not previously have has escalated privilege, and the permission engine (Chapter 15) must evaluate synthesised tools exactly as it evaluates declared ones — which means they need risk metadata, and something must assign it.

That third point is the one designs get wrong. It is tempting to let the agent write a tool and register it. Registration is a permission decision and belongs to the harness, which means a synthesised tool needs mutates, reversible and external classified by something other than the thing that wrote it — a classifier, a conservative default, or a human.

The pragmatic recommendation: prefer skills to tools. A skill is a procedure using existing, vetted tools; a synthesised tool is new code in a trusted position. Skills capture most of the value at a fraction of the risk, and the value they capture is the same value — a procedure that took twenty-two turns now takes nine.

26.11Self-modifying agents#

The Darwin Gödel Machine maintains an archive of coding agents, samples from it, uses a foundation model to generate improved variants, and validates each empirically on coding benchmarks. Combining Darwinian evolution with open-ended exploration, it produced substantial gains: SWE-bench from 20.0% to 50.0%, Polyglot from 14.2% to 30.7%, with the system automatically improving its own coding capabilities — better code editing tools, long-context management, peer-review mechanisms. All experiments were conducted with stated safety precautions: sandboxing and human oversight.1

Automated harness search can improve performance on its evaluation tasks. Reported changes included editing tools, context management and peer review; results remain specific to the tested tasks and controls.

It requires an evaluation objective worth optimising. Coding tests check specified behaviour, with incomplete coverage and opportunities for reward hacking. For enterprise tasks, construct domain checks and held-out evaluation before applying the same search method.

It is offline, expensive, and archived. This is a search process over many candidates with empirical validation of each, not something that happens during a production run. The archive is what lets it recover from a bad branch.

The safety framing is explicit and should be copied. Sandboxing and human oversight, stated as preconditions. A self-modifying agent without both is a different and much worse proposition.

And the thing not to take from it: that your production agent should modify its own harness. The gap between “an archived, sandboxed, human-overseen research system with a ground-truth objective” and “the agent that issues credits for your customers” is very large. The transferable lesson is the method — propose, validate empirically, keep an archive, be able to revert — applied to the much smaller surface of skills.

Failure Mode

Never let an agent modify its own guardrails, permissions, budgets or approval thresholds, and treat any proposal that touches them as a signal rather than a suggestion. This is not a hypothetical concern about misalignment; it is a mundane one about injected instructions and confused optimisation. An agent asked to work faster may reasonably conclude that the approval step is the bottleneck. The gate’s control-weakening check exists for exactly this, and the surface it protects must include every control in Part VI.

26.12Does it compound?#

Turns and cost per task type, over time. The direct benefit. A task type with an accumulated skill should show a step change — twenty-two turns to nine — and then stability. No step change means the skills are not helping.

Skill hit rate. What fraction of tasks recall a skill, and of those, what fraction succeed at a higher rate than the no-skill baseline. This is the number that answers “is the library working.”

Quarantine rate and its trend. Rising means proposal quality is falling, which usually means the agent is proposing skills for tasks it does not actually understand.

Demotion rate. Rising means the environment is changing faster than the library is being maintained, which is a signal to shorten review cycles rather than to write more skills.

And the comparison that settles it: run your eval suite with the skill library enabled and disabled. The same discipline Chapter 10 prescribed for memory, and the results are frequently similar — a substantial fraction of skill libraries, measured honestly, are net-neutral on task success while adding cost and a source of confident error. Better to know that before building more of it.

Symptom Likely cause Fix
Confidently wrong on a task type with a skill Over-general skill; no verification criterion Require checks; review the top-recalled skills
Recall returns skills that do not help Vague goal fields; no relevance gate Trigger conditions, not titles; hard-cap recall
Library grows, quality flat Skills capture what was already easy Measure per-task-type turn reduction, not library size
Skills stop working after a migration No expiry, no demotion Automatic demotion; review dates on volatile procedures
A skill proposes weakening a control Injection, or misguided optimisation The gate’s control check; treat as a security event

The self-improvement contract

Write these down before enabling any self-authoring, because every one of them is a thing that goes wrong.

  • The agent may propose; only a gate may accept.
  • Every accepted artefact carries its verification criterion and its provenance — which run produced it, from which task.
  • Nothing self-authored may weaken a control. A proposal that does is a security event, not a rejected suggestion.
  • Nothing self-authored may expand authority. Synthesised tools get risk metadata from the harness, not from their author.
  • Demotion is automatic on measured failure, and does not require a human decision.
  • Recall is hard-capped, and only verified artefacts are retrievable.
  • The top artefacts are read by a human on a schedule. Fifteen minutes a month.
  • The library’s value is measured by verified outcomes, turns and cost per task type, not by its size — and by an on/off comparison on the eval suite.

Definition

Verification gate — the structural and behavioural checks a self-authored artefact must pass before it becomes retrievable.

Quarantine — a rejected proposal retained as a record but never recalled; its rate and reasons are a signal about proposal quality.

Demotion — automatic removal of an artefact from retrievability when its measured success rate falls below a threshold.

Skills improve what the agent does with a fixed model. The remaining question is whether the model itself should change — trained on the trajectories the system has been accumulating this whole time. That is the last chapter of Part VII, and the answer is more often “no” than most teams expect.

Key Takeaways

  • Self-improvement is asymmetric: proposing costs one model call, while accepting means an artefact retrieved on every matching task and followed with the authority of established procedure. Measure the proposal against a no-skill control before granting broad recall.
  • You cannot prove a self-authored change is beneficial — the research states this plainly — so the mechanism is empirical validation, and the engineering question is which test, how expensive, and what happens on failure.
  • A skill is engineerable because it carries its own verification criterion. The goal must be a trigger condition rather than a title, and pitfalls is where the hard-won knowledge lives.
  • Structural checks cheaply reject some malformed proposals: too few steps, no verification criteria, unknown tools, over-length, and — most importantly — any step that attempts to weaken a control.
  • Behavioural verification needs the originating regression case plus held-out, scoped comparisons. A passing source example alone does not establish generalisation.
  • Demotion must be automatic, versioning must replace mutation, quarantined proposals must be kept as a signal, and the top-recalled artefacts need fifteen human minutes a month.
  • Prefer skills to synthesised tools. A skill composes vetted tools; a synthesised tool is new code in a trusted position that must get its risk metadata from the harness rather than its author.
  • Self-modifying harnesses produce real and large gains under sandboxing, human oversight, an archive, and a ground-truth objective. Copy the method — propose, validate, archive, revert — not the scope.
  • Measure whether it compounds: turn and cost reduction per task type, skill hit rate, quarantine and demotion trends, and a library-on versus library-off comparison on the eval suite.
  • Promotion needs a paired skill-on versus skill-off experiment with held-out, cohort-stratified cases. Outcome, cost and turns are optimisation objectives; forbidden trajectories and failed business invariants are hard rejection conditions.
  • The reference library proves the state machine, not a production service: unconfigured behavioural verification leaves proposals pending, outcome labels come from the host, demotion uses lifetime success, and the JSON store supplies neither tenant isolation nor concurrent-writer safety.

Hands-on

Gate before you generate 1. Take the last ten procedures your team documented by hand and check each against the structural gate: two or more steps, a verification criterion, only known tools, under 4,000 characters, no control-weakening. Most hand-written runbooks fail on the verification criterion, which tells you how hard the bar is. 2. Implement the gate before enabling any self-authoring. Then let the agent propose ten skills and read the quarantine reasons — that list is the most informative artefact in this chapter. 3. Wire outcome feedback so every skill use records pass or fail, and confirm automatic demotion fires on a deliberately broken skill. 4. Turn one accepted skill’s originating task into an eval case. Now the skill has a test that will fail when the environment moves under it. 5. Run your eval suite with the library enabled and disabled. If the difference is not clearly positive, you have added cost and a source of confident error, and you have found that out cheaply. 6. Stratify that comparison by the dimensions in the trigger — tenant configuration, jurisdiction, schema version or tool capability. Replace every proxy label such as COMPLETED with the external invariant that establishes whether the task was actually correct. 7. Seed a verified skill with 100 historical passes, then record four consecutive failures. Observe why its 96.2% lifetime rate prevents default demotion, and design a rolling-window or hard-invariant stop rule appropriate to the risk.


  1. Zhang, J., Hu, S., Lu, C., Lange, R., Clune, J. Darwin Gödel Machine: Open-Ended Evolution of Self-Improving Agents. arXiv:2505.22954. https://arxiv.org/abs/2505.22954 ↩↩

  2. Wang, G. et al. Voyager: An Open-Ended Embodied Agent with Large Language Models. arXiv:2305.16291. https://arxiv.org/abs/2305.16291 ↩

  3. Memory — Hermes Agent user guide. Nous Research. https://hermes-agent.nousresearch.com/docs/user-guide/features/memory ↩↩

  4. Skills — OpenHands. https://docs.openhands.dev/overview/skills ↩↩

  5. Devin. Skills and Creating Playbooks. October 24 transition and progressive disclosure checked 2026-11-09. https://docs.devin.ai/product-guides/skills https://docs.devin.ai/product-guides/creating-playbooks ↩↩

  6. Devin. Knowledge. Deprecation and migration to Skills in Plugins checked 2026-11-09. https://docs.devin.ai/product-guides/knowledge ↩↩