Append Learning
append_learningBEFORE COMPOSING YOUR BATCH, filter each candidate entry. A learning is ONLY:
A reusable rule about how the agent should run, that applies to every future firing, not just this one.
A learning is NOT (these are the most common mistakes — produce zero of these):
Per-entity / per-contact facts. Anything naming a specific company, person, deal, or URL. Examples that DO NOT belong here: "Heitman LLC (heitman.com) is a real estate firm in Chicago", "Jamestown Management hired a new CFO", "Alice Chen's first name is 'Alice'", "ExampleCo: 200 waitlist, 30 live users". → Use
track_prospects(agent_id, items=[...])for per-entity lifecycle tracking, OR →update_workspace(section='outputs', key='<your_list>', value=[...])to store as an agent deliverable.Per-run summaries. Anything describing what happened on a specific date or run. Examples: "Follow-up run 2026-04-27: 0 people in 'messaged' stage", "Apr 23 scan: same source returned, no new angles". These are auto-saved to the agent's run history every run — don't duplicate them here.
General user preferences. "User wants concise emails", "user prefers Tuesday meetings". → Use
save_memory.
Valid learnings look like rules-of-thumb, not observations. They're short prose, no proper nouns, no dates, no per-entity data. Good examples:
"PostHog returns 1-day data, not an error — if the query returns one row it's complete, not partial."
"Internal team syncs rarely produce postable ideas — skip quickly to save Tavily budget."
"r/SaaS posts about LinkedIn automation pain are strong leads."
"Tavily score < 0.09 against generic signal_keyword queries is reliably tangential — keep min_score=0.09."
If you cannot rewrite your candidate entry into a rule-of-thumb
shape without naming a specific entity, date, or run number, it
doesn't belong here — store it via track_prospects or
update_workspace instead.
USAGE
Pass learnings=["...", "..."] to add one or more new entries in one
call. The whole batch is atomic — either all entries are appended or
none are (see "Cap behavior" below). Singleton case is
learnings=["..."]. Batching is strictly preferred over multiple
single-entry calls: one round-trip per run is dramatically cheaper
in latency and tokens than one round-trip per insight.
Pass replace_with=[...] to atomically replace the full list — use
this when the prior call returned a "cap reached" ModelRetry asking
you to consolidate.
Scope: per-agent and persistent. Distinct from save_memory (per-user
preferences).
CAP BEHAVIOR
The list is capped at 25 items. If a batch would push the list over
the cap (current_count + batch_size > 25), the WHOLE batch is
rejected via ModelRetry asking you to consolidate first via
replace_with. After consolidating, re-submit your full batch — no
need to track which entries "landed" since none were stored on the
rejected call. Consolidate by DROPPING entries that match the
anti-examples above (per-entity facts, per-run summaries), not by
reshuffling — the cap is a forcing function for hygiene, not a
length limit on the same content.
Dict with success, agent_id, and the new learnings count.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| agent_id | Yes | ID of the agent | |
| learnings | No | New learning entries to append in one batch (mutually exclusive with replace_with) | |
| replace_with | No | Full replacement list for consolidation (mutually exclusive with learnings) |