<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: agents</title>
    <description>The latest articles tagged 'agents' on DEV Community.</description>
    <link>https://dev.to/t/agents</link>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tag/agents"/>
    <language>en</language>
    <item>
      <title>Inside Zambo: 138+ Tools, a Receipt for Every Call, and Memory That Follows You Across AIs</title>
      <dc:creator>rambo</dc:creator>
      <pubDate>Wed, 14 Oct 2026 14:59:04 +0000</pubDate>
      <link>https://dev.to/rambozambo/inside-zambo-138-tools-a-receipt-for-every-call-and-memory-that-follows-you-across-ais-16go</link>
      <guid>https://dev.to/rambozambo/inside-zambo-138-tools-a-receipt-for-every-call-and-memory-that-follows-you-across-ais-16go</guid>
      <description>&lt;p&gt;Most AI still works like this: you type a job, the model talks back, and you take its word for what happened. It cannot browse for you, build for you, check a price, scan a contract, or prove any of it afterward. Zambo exists to end that arrangement. It is a single MCP server at &lt;a href="https://zambo.dev/mcp" rel="noopener noreferrer"&gt;https://zambo.dev/mcp&lt;/a&gt; that any AI client can connect to, and behind that one URL sits a working stack: 138+ tools, a verifiable receipt minted for every call, and a continuity layer that lets work started in one AI continue in another. This is the deep tour: what is actually in there, how the receipt system works down to the hash, and how the memory pieces fit together.&lt;/p&gt;

&lt;h2&gt;
  
  
  One URL, and the AI can search the toolbox itself
&lt;/h2&gt;

&lt;p&gt;The connection is one URL: &lt;a href="https://zambo.dev/mcp" rel="noopener noreferrer"&gt;https://zambo.dev/mcp&lt;/a&gt;. Claude, ChatGPT, Gemini, Cursor, Grok, Windsurf, VS Code, LangChain, CrewAI, Muse: if the client speaks MCP, it can connect. Three entry tools matter more than any others.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;capability_search&lt;/strong&gt; searches the whole catalog by use case and returns the relevant tools with relevance scores. This is the answer to the most common failure mode of a big toolbox, which is not that the tool is missing but that nobody finds it. An agent that knows what it wants to do can ask what exists, in plain language, and pull the right tool itself.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;zambo_universal&lt;/strong&gt; and &lt;strong&gt;zambo_invoke&lt;/strong&gt; route natural language and exact tool names across the full catalog through one dispatch surface, so a client with a small default tool list can still reach everything behind it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;zambo_help&lt;/strong&gt; and &lt;strong&gt;zambo_ask&lt;/strong&gt; answer questions about the stack itself: products, pricing, routing, how to do a specific thing. The stack explains itself, in band, while you use it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The toolbox, family by family
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Making things.&lt;/strong&gt; video_create generates video through the Zambo video engine, and video_status reports what the engine can honestly do and where a generation stands. gif_animate turns a description into a cinematic animated GIF. meme_forge builds a meme image with your caption. image_generate produces AI images, and image_analyze reads images back: description, OCR text extraction, and screenshot review, including reading error messages off a screen. voice_transcribe turns audio into text. qr_generate makes QR codes for URLs, text, WiFi credentials, and contact cards.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Knowing things.&lt;/strong&gt; live_price returns real time cryptocurrency prices. market_pulse aggregates a live intelligence snapshot across AI, agents, and research. doc_intel extracts structured intelligence from documents: contracts, reports, PDFs, whitepapers. pdf_extract pulls clean text from any public URL. agent_brief generates a machine readable briefing on any URL, product, company, API, or codebase. weather and translate cover the everyday basics, live weather for any city and translation across 100+ languages, no API key required from you.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Judgment.&lt;/strong&gt; zambo_score grades any startup, idea, repo, or business from 0 to 100 with a letter grade and the bottleneck named. model_oracle ranks AI models for your specific task against your token budget and cost limits. zambot_fix diagnoses broken AI generated code and names the exact failure mode. code_review returns severity rated issues, security flags, and specific fixes. provibe_audit audits a public repo and scores it. ghost_audit_site runs the Achilles 10 stage audit on a website: SEO gaps, AI discoverability, conversion leaks, brand issues, with ghost_audit_report returning the full findings.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Safety and trust checks.&lt;/strong&gt; prompt_shield detects prompt injection, jailbreak, and policy bypass attempts and returns a risk score. scam_check answers "should I interact with this?" for a wallet, contract, domain, or URL. email_verify parses SPF, DKIM, and DMARC to check whether an email is really from who it claims. structlock takes messy AI output or raw text and enforces your schema on it, returning clean typed JSON every time. sybil_detect, basehawk_score, and monad_score score wallet risk and reputation from live chain intelligence.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real work.&lt;/strong&gt; write produces publication quality content of any type. email_write handles everything from a pitch to a negotiation. contract_scan reads a contract or terms of service and flags the red flags in plain English. bill_audit finds errors and overcharges in bills and subscriptions. resume_boost tailors a resume to a job description. salary_script builds a full negotiation script with rebuttals. sql_from_english turns plain English questions into working SQL. regex_build and git_changelog handle the small sharp jobs developers hit daily. thread_craft turns an idea into a ready X thread. fridge_forge builds a dinner plan from whatever is in your fridge, meal_plan builds a full plan with macros and a shopping list, and workout_build builds a training plan with progression.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Trading, with the math outside the model.&lt;/strong&gt; trading_strategy_compile converts a natural language strategy into a strict versioned schema. trading_risk_gate is a pure math position check: no AI in it, so no hallucination is possible, hard enforcing position size against your limits. trading_propose runs the full flow: load the strategy, run the risk gate, capture live market data. trading_journal and trading_stats keep the record and the scoreboard.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Agents finding and hiring agents.&lt;/strong&gt; find_agent searches the Zambo Agent Registry, a public phone book for AI agents, by capability or name. signal_register and signal_lookup give an agent a persistent identity and a trust passport. agent_hire is an x402 marketplace where agents browse, hire, and list each other. zambo_swarm spawns a coordinated multi agent swarm around a goal with a division of labor. agent_network coordinates permissioned rooms across humans and agents. The coordination boards go one step further: coord_claim lets an agent claim a task, and coord_complete only completes it after the supplied Zambo receipt verifies. The receipt is the key that closes the task.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Strategy.&lt;/strong&gt; zambot_spark runs the Zambo Agent Council on any goal: five specialist agents arguing from biology, game theory, military strategy, and more. zambot_swarm_debate stress tests a decision. zambot_drift detects the silent divergence between what an agent was built to do and what it is actually doing. zambo_compose chains the intelligence tools into one autopilot run. proof_certify certifies any AI generated content with a SHA-256 provenance certificate.&lt;/p&gt;

&lt;h2&gt;
  
  
  Every call leaves a receipt
&lt;/h2&gt;

&lt;p&gt;Here is the part that makes the stack different from a pile of tools. Every call through Zambo mints a receipt at the moment it runs: the tool, the arguments it was given, the exact result bytes that came back, the timestamp, and digests that let anyone recompute the commitments from the saved record. The format is AER-1, an IETF Internet-Draft currently at revision 19 (&lt;a href="https://datatracker.ietf.org/doc/draft-zambo-aer1/19/" rel="noopener noreferrer"&gt;https://datatracker.ietf.org/doc/draft-zambo-aer1/19/&lt;/a&gt;), written by Zambo's creator, with independent implementations from other builders and a public conformance kit.&lt;/p&gt;

&lt;p&gt;The claim is narrow on purpose, and it is worth stating exactly. A receipt proves the saved result was not changed since it was saved. It does not prove the result was correct, and it says nothing about quality or intent. That narrowness is the feature: it is a claim that can be checked mechanically, by a stranger, without trusting Zambo or the agent.&lt;/p&gt;

&lt;p&gt;Check one yourself. This receipt records a live_price call from the public demo: &lt;a href="https://zambo.dev/run/92874efd-7bc4-427c-b262-862dfcf6d82d" rel="noopener noreferrer"&gt;https://zambo.dev/run/92874efd-7bc4-427c-b262-862dfcf6d82d&lt;/a&gt;. Open it, take the saved output bytes, recompute the SHA-256 digest, and compare it to the digest on the record: sha256:65faa90980caf70dfb5fc14f3c38c82db8a154ce3a6e2d274e943b83209b1d06. It matches. Whether that Bitcoin price was right is a question the receipt deliberately does not answer. Run the demo and mint your own: &lt;a href="https://zambo.dev/demo/" rel="noopener noreferrer"&gt;https://zambo.dev/demo/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Receipts compose. A session's receipts accumulate under one job, and workflow_close snapshots the eligible receipts into an immutable record whose root is a Merkle tree computed over the step receipt identifiers, exactly as AER-1 Section 8.1 specifies, so any single step can be checked against the root of the whole job. workflow_seal seals a closed workflow for durable export. journal_log and secondary_receipt go the other direction: they let work performed outside Zambo be logged and receipted too, with the evidence scored conservatively and the basis stated on the record. On the coordination boards, on the marketplace, and anywhere else work changes hands, the receipt is what travels: small, checkable, and readable by any party with no account and no permission.&lt;/p&gt;

&lt;h2&gt;
  
  
  Continuity: the work follows you across AIs
&lt;/h2&gt;

&lt;p&gt;Tools answer "what can my AI do." Continuity answers "where did my work go." Start a job in Claude on your laptop, continue it in ChatGPT on your phone, verify the record in Cursor: the session, the memory, and the receipt timeline are the same underneath, because they live in Zambo, not in any one client.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sessions.&lt;/strong&gt; new_session starts a fresh context and returns a session id that subsequent calls reuse. zambo_session loads a session back, resuming your exact context from any client or device.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Memory.&lt;/strong&gt; zambo_remember stores information in your private Zambo memory, permanently, across every session, device, and AI client. zambo_recall retrieves it from anywhere. The AI you switch to next week knows what the AI you used today was told, because the memory was never the client's to lose.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Threads and the receipt timeline.&lt;/strong&gt; continuity_start_thread opens a named thread under a job. continuity_get_recent reads the private receipt timeline for a job or thread, continuity_list_threads and continuity_open_thread navigate them, and continuity_set_prefs controls what gets captured. The thread id can be passed as the session id by another AI client, which means a second AI can open the exact thread the first one was working in and read the receipted history of what already happened, instead of a summary it has to trust.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Identity.&lt;/strong&gt; agent_identity establishes a persistent agent identity that survives client switches and model updates, and the Signal registry ties claimed credentials and skills to it. An agent that did good work last month under one client is recognizably the same agent under another.&lt;/p&gt;

&lt;h2&gt;
  
  
  Access, and agents paying for themselves
&lt;/h2&gt;

&lt;p&gt;Every tool carries a free tier with no account, and the limits vary by tool. A Day Pass unlocks the full stack for 24 hours for $0.99: humans check out by card or PayPal, and agents pay on their own through x402, USDC on Base, with day_pass_activate handling the agent native flow and zambo_pay receiving the x402 challenge. Beyond the day: Zambo Pass is $29 a month or $290 a year, and $19 a month for $ZAMBO holders. zambo_limit shows exactly where your usage stands at any moment, and reliability_score publishes machine verified pass rates and latency for the tools themselves. The stack receipts its own work and scores its own reliability in public.&lt;/p&gt;

&lt;p&gt;There is also a Receipt Bot for Grok (&lt;a href="https://zambo.dev/receipt-bot/" rel="noopener noreferrer"&gt;https://zambo.dev/receipt-bot/&lt;/a&gt;) that collects, verifies, and files a verifiable receipt for every job your bots do, then sends a nightly digest of links. Same idea, one more surface: the work leaves a record wherever it happens.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this shape
&lt;/h2&gt;

&lt;p&gt;A tool stack makes an AI capable for a session. Receipts make its work checkable by anyone, forever, in a format an open Internet-Draft defines and independent builders implement. Continuity makes the capability and the record survive the switch from one AI to the next, which is how people actually work now: whichever model is open, whichever device is in hand. Put the three together and "my AI said it did the work" stops being the end of the conversation. The work has a toolbox, the toolbox leaves receipts, and the receipts follow you.&lt;/p&gt;

&lt;p&gt;Your AI said "done." For $0.99, prove it: &lt;a href="https://zambo.dev/day-pass/" rel="noopener noreferrer"&gt;https://zambo.dev/day-pass/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>programming</category>
      <category>mcp</category>
    </item>
    <item>
      <title>Escalate on a budget, not an error: when an AI agent should hand off to a human</title>
      <dc:creator>TaskPool AI</dc:creator>
      <pubDate>Wed, 14 Oct 2026 14:38:42 +0000</pubDate>
      <link>https://dev.to/taskpool_ai_461d0838c8f56/escalate-on-a-budget-not-an-error-when-an-ai-agent-should-hand-off-to-a-human-2810</link>
      <guid>https://dev.to/taskpool_ai_461d0838c8f56/escalate-on-a-budget-not-an-error-when-an-ai-agent-should-hand-off-to-a-human-2810</guid>
      <description>&lt;p&gt;&lt;em&gt;A retry is not a fresh draw, and waiting for an exception means waiting past the point where anything was recoverable. Four counters you can read before the failure, a handoff packet, and Python that runs.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Mercor's best agent on APEX-Agents passes &lt;a href="https://arxiv.org/abs/2601.14242" rel="noopener noreferrer"&gt;24.0% of its tasks on one attempt&lt;/a&gt;. Give it eight attempts and &lt;a href="https://www.mercor.com/blog/introducing-apex-agents/" rel="noopener noreferrer"&gt;it reaches about 40%&lt;/a&gt;. A flat 24% chance per attempt would put eight tries near 89%, so most of those failures belong to the task and not to the dice. That inference is mine. Nothing I read in Mercor's write-up says it, and you are free to argue with it.&lt;/p&gt;

&lt;p&gt;The usual answer to a failed run is another run, often resumed from the same conversation. &lt;a href="https://arxiv.org/abs/2509.09677" rel="noopener noreferrer"&gt;Sinha and colleagues&lt;/a&gt; found that models make more mistakes when their own earlier mistakes sit in the context, and that scaling the model does not remove the effect, although thinking models mitigate it. Their tasks were synthetic, with the plan handed to the model, so carrying the result over to a production retry is my extension and not theirs.&lt;/p&gt;

&lt;p&gt;That leaves a move most harnesses never budget for: stopping on purpose and giving the work to someone else. The rest of this post covers the trigger logic and the packet, and then what it costs. If you came for code, skip to the section called "Counters that fire before the exception".&lt;/p&gt;

&lt;h2&gt;
  
  
  Read the stop reason first
&lt;/h2&gt;

&lt;p&gt;I'm putting the objection ahead of the fix. A lot of what looks like an agent giving up is a harness limit doing exactly what it was configured to do, and handing that to a person means paying a stranger to find your bug. I wrote up &lt;a href="https://taskpool.ai/blog/agent-stops-mid-task" rel="noopener noreferrer"&gt;six causes of agents stopping mid-task&lt;/a&gt; on the Taskpool blog, and five of them live in the harness. Run that triage before you wire up anything below.&lt;/p&gt;

&lt;h2&gt;
  
  
  Counters that fire before the exception
&lt;/h2&gt;

&lt;p&gt;The class below watches four things per tool call: an identical call repeating inside a short window, steps since the last verified checkpoint, total steps, and wall-clock time. It returns a reason string the moment one trips and &lt;code&gt;None&lt;/code&gt; otherwise.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;__future__&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;annotations&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;hashlib&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;collections&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;deque&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;dataclasses&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;dataclass&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Callable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Optional&lt;/span&gt;


&lt;span class="nd"&gt;@dataclass&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Budget&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;max_steps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;           &lt;span class="c1"&gt;# set from your own successful runs, not a default
&lt;/span&gt;    &lt;span class="n"&gt;max_seconds&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;
    &lt;span class="n"&gt;max_repeats&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;     &lt;span class="c1"&gt;# identical tool call (name + args) this many times...
&lt;/span&gt;    &lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;          &lt;span class="c1"&gt;# ...inside the last N calls
&lt;/span&gt;    &lt;span class="n"&gt;stall_steps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;    &lt;span class="c1"&gt;# steps allowed without a verified checkpoint
&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Tripwire&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;budget&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Budget&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;clock&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Callable&lt;/span&gt;&lt;span class="p"&gt;[[],&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;monotonic&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;budget&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;clock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;clock&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;t0&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;clock&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;steps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;since_checkpoint&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;recent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;deque&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;deque&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;maxlen&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;budget&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;observe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;checkpoint_advanced&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Optional&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
        &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Call once per tool call. Returns a reason string when it is time to hand off.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;steps&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;since_checkpoint&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;checkpoint_advanced&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;since_checkpoint&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

        &lt;span class="n"&gt;blob&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;sort_keys&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;fp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;hashlib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sha256&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;blob&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;hexdigest&lt;/span&gt;&lt;span class="p"&gt;()[:&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;recent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;recent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;max_repeats&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;repeated_action&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;since_checkpoint&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stall_steps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;checkpoint_stall&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;steps&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;max_steps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;step_budget&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clock&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;t0&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;max_seconds&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;time_budget&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;


&lt;span class="nd"&gt;@dataclass&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Handoff&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;goal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;                &lt;span class="c1"&gt;# one sentence, readable by someone with no context
&lt;/span&gt;    &lt;span class="n"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;              &lt;span class="c1"&gt;# which tripwire fired
&lt;/span&gt;    &lt;span class="n"&gt;last_verified&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;       &lt;span class="c1"&gt;# last checkpoint that passed its check
&lt;/span&gt;    &lt;span class="n"&gt;tried&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;         &lt;span class="c1"&gt;# short descriptions, not the transcript
&lt;/span&gt;    &lt;span class="n"&gt;ask&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;                 &lt;span class="c1"&gt;# the single thing the human has to do
&lt;/span&gt;    &lt;span class="n"&gt;accept_if&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;           &lt;span class="c1"&gt;# how you will judge what comes back
&lt;/span&gt;    &lt;span class="n"&gt;deadline_hours&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;
    &lt;span class="n"&gt;spend_cap_pence&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;     &lt;span class="c1"&gt;# integer minor units, never floats
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The thresholds are defaults I picked so the tests had something to assert. They are not measured. &lt;code&gt;max_steps&lt;/code&gt; is the one that matters, and I'd start from the longest successful run you have on file, add slack, and then look at which counter actually fires.&lt;/p&gt;

&lt;p&gt;The checkpoint counter is the best signal and the most expensive to earn. A checkpoint here means a state something outside the model confirmed, such as a passing test or a row that exists in the database. If you cannot say what a checkpoint is for your task, stall detection is not available to you yet, and defining it will take longer than writing the class.&lt;/p&gt;

&lt;p&gt;Arguments are serialised with sorted keys before hashing, so &lt;code&gt;{"a": 1, "b": 2}&lt;/code&gt; and &lt;code&gt;{"b": 2, "a": 1}&lt;/code&gt; count as the same call. Without that, an agent can loop forever while shuffling its arguments.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the human is handed
&lt;/h2&gt;

&lt;p&gt;The transcript stays out. It carries the model's own errors, which is what the Sinha result says to keep away from the next attempt, and it costs a person real time to read. The &lt;code&gt;Handoff&lt;/code&gt; dataclass above is the replacement: a goal a stranger can follow, which counter fired, the last checkpoint that passed, short descriptions of what was tried, one ask, and a deadline.&lt;/p&gt;

&lt;p&gt;Two fields do more than they look like. &lt;code&gt;accept_if&lt;/code&gt; forces you to write the check before the work leaves, which is the point where it is cheapest to be strict. &lt;code&gt;spend_cap_pence&lt;/code&gt; is an integer because money held as a float eventually produces a bug report.&lt;/p&gt;

&lt;p&gt;Wiring it to LangGraph takes one node. Its &lt;a href="https://docs.langchain.com/oss/python/langgraph/interrupts" rel="noopener noreferrer"&gt;interrupt docs&lt;/a&gt; require a checkpointer and a &lt;code&gt;thread_id&lt;/code&gt;, and resuming goes through &lt;code&gt;Command(resume=...)&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;dataclasses&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;asdict&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langgraph.types&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;interrupt&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;escalate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;packet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Handoff&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;goal&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Confirm the shop sign matches the listing&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;reason&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;reason&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;last_verified&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;listing page parsed&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;tried&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;fetched listing twice&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;street view unavailable&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;ask&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Photograph the shopfront and sign&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;accept_if&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Sign text legible in at least one photo&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;deadline_hours&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;48&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;spend_cap_pence&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# Nothing with side effects above this line.
&lt;/span&gt;    &lt;span class="n"&gt;answer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;interrupt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;asdict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;packet&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;human_result&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;answer&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The comment is not decoration. The docs say the node restarts from its first line when you resume, so anything above &lt;code&gt;interrupt()&lt;/code&gt; runs twice, and they warn against wrapping the call in a bare &lt;code&gt;try/except&lt;/code&gt; because the pause is implemented as an exception. I ran this round trip against &lt;code&gt;langgraph&lt;/code&gt; 1.2.15 with the in-memory checkpointer and it passes, along with five tests for the counters. In production the checkpointer has to outlive your process, because a person who answers in two days will not be answering a process that is still running.&lt;/p&gt;

&lt;h2&gt;
  
  
  Not every handoff goes to a stranger
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;The run is stuck because&lt;/th&gt;
&lt;th&gt;Hand it to&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;The next step needs a decision only your team has authority to make&lt;/td&gt;
&lt;td&gt;The on-call engineer or the account owner&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;The output exists but needs judgement you already employ&lt;/td&gt;
&lt;td&gt;An in-house reviewer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;The next step needs a person in a particular place, or an independent check of the agent's own claim&lt;/td&gt;
&lt;td&gt;An outside verified human&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Only the last row is a job for a marketplace. Sending the first two to a stranger gets you an answer from someone with no authority and no context.&lt;/p&gt;

&lt;h2&gt;
  
  
  If the destination is a job board
&lt;/h2&gt;

&lt;p&gt;I co-founded Taskpool International, which runs a marketplace where AI agents post tasks for verified humans, so weight this section accordingly. The Python above is vendor-neutral and I have not wired it to any marketplace in this post. What follows comes from reading &lt;a href="https://taskpool.ai/agent/docs" rel="noopener noreferrer"&gt;Taskpool's agent docs&lt;/a&gt;, not from a run, and each point applies to any board you might use.&lt;/p&gt;

&lt;p&gt;Listings are public. In Taskpool's case the task description appears on the public job board, so the &lt;code&gt;ask&lt;/code&gt; field must never carry credentials or customer data. Plan for a stranger to read it.&lt;/p&gt;

&lt;p&gt;Handoffs have a floor price. The docs set a minimum payout of £5.00 per worker and a 10% platform fee on top, so the cheapest single slot costs £5.50. That number changes which runs are worth escalating at all.&lt;/p&gt;

&lt;p&gt;Silence can pay. The docs say a submission still in review seven days after the worker's deadline is accepted automatically and paid. Run your &lt;code&gt;accept_if&lt;/code&gt; check from a webhook, not from someone remembering.&lt;/p&gt;

&lt;p&gt;A loop that escalates forever is a retry loop that sends you invoices. Cap spend per key as well as per task; Taskpool's docs describe a monthly budget per API key that refuses funding before any money moves.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to change on Monday
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Log the stop reason on every model call before you theorise. It costs you some log volume.&lt;/li&gt;
&lt;li&gt;Pick one verified checkpoint per task type. If the task has none, accept that stall detection is off and say so in the runbook.&lt;/li&gt;
&lt;li&gt;Set &lt;code&gt;max_steps&lt;/code&gt; from your own successful runs and log which counter fires. You will pay for handoffs on runs that would have finished, and nobody has published how often.&lt;/li&gt;
&lt;li&gt;Write &lt;code&gt;accept_if&lt;/code&gt; before the work leaves, in a form code can check.&lt;/li&gt;
&lt;li&gt;Strip secrets from the packet and assume a stranger can read it.&lt;/li&gt;
&lt;li&gt;Cap spend per task and per key.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you want the longer argument for why task length rather than difficulty sets the wall, I made it with the benchmark numbers in &lt;a href="https://taskpool.ai/blog/agent-task-duration-failure" rel="noopener noreferrer"&gt;Duration, not difficulty, is what breaks agents&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The number I don't have
&lt;/h2&gt;

&lt;p&gt;I know of no published distribution of why production agent runs get handed off, or of how often a budget like this fires on a run that would have succeeded. That false-positive rate decides whether any of this is worth the money, and I have none. If you have traces, I would rather have your numbers than your agreement.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;When should an AI agent escalate to a human?&lt;/strong&gt; When a counter trips, or when the next step needs a person on site or an independent check that the agent cannot supply. Do it before the failure, while the state is still recoverable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is retrying a failed agent run a good recovery strategy?&lt;/strong&gt; Not by default. Models can condition on their own earlier errors, an effect thinking models mitigate and scale alone does not remove, so a fresh run seeded with a clean summary is the safer retry.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How does LangGraph pause an agent for human input?&lt;/strong&gt; Call &lt;code&gt;interrupt()&lt;/code&gt; inside a node, with a checkpointer and a &lt;code&gt;thread_id&lt;/code&gt; configured. Resume the same thread with &lt;code&gt;Command(resume=...)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I used Claude to draft this post. Every figure links to its source, checked on 14 October 2026, and the Python was run: six tests pass.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>python</category>
      <category>architecture</category>
    </item>
    <item>
      <title>The sparse-reward excuse is an authoring problem</title>
      <dc:creator>Aamer Mihaysi</dc:creator>
      <pubDate>Wed, 14 Oct 2026 14:37:48 +0000</pubDate>
      <link>https://dev.to/o96a/the-sparse-reward-excuse-is-an-authoring-problem-3f3g</link>
      <guid>https://dev.to/o96a/the-sparse-reward-excuse-is-an-authoring-problem-3f3g</guid>
      <description>&lt;p&gt;Every eval conversation I've had this year hits the same wall. Someone wants to measure an agent on a long-horizon task — 40, 60, 100 steps — and someone else says you can't score that densely. Grading every step means a human or a judge model reading the whole trajectory, and that's expensive, slow, and noisy. So you run the task, check the final assertion, and get one bit back. Pass or fail.&lt;/p&gt;

&lt;p&gt;I've built evals that way. They're cheap and they're nearly useless. When the agent fails at step 47, you have a terminal error and a transcript, and you spend the afternoon reading it like a detective. The signal you needed was at step 12, and you didn't collect it because collecting it looked expensive.&lt;/p&gt;

&lt;p&gt;Here's what I've started to believe: dense scoring was never the expensive part. Authoring was. We've been blaming the wrong cost.&lt;/p&gt;

&lt;p&gt;Think about what dense reward actually requires. To say "step 14 was progress," something has to know what progress means at step 14. If all you have is a task prompt and a final assertion, nothing knows that. So you hand the trajectory to a judge model and ask it to guess. That's expensive, and it's guessing, because the judge has no ground truth either. It's reading the same transcript you are, with the same missing information, and charging you per token for the privilege.&lt;/p&gt;

&lt;p&gt;Tev makes the other move, and it's the one I keep coming back to. Instead of scoring the trajectory after the fact, you write the hidden ground-truth world spec first — the actual state of the world, the preconditions, the milestones, the terminal conditions — and then you render the environment from that spec. The environment isn't hand-built and then described in a doc that drifts. The spec is the source, and the environment is a projection of it. Once that's true, progress at any step is a function of the spec. You don't judge it. You compute it. Dense per-step rewards fall out as a byproduct, because you already wrote down what "closer" means.&lt;/p&gt;

&lt;p&gt;Paper's here if you want the actual method: &lt;a href="https://arxiv.org/abs/2610.18868v1" rel="noopener noreferrer"&gt;https://arxiv.org/abs/2610.18868v1&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The reason this lands for me isn't the benchmark numbers. It's that it's the same discipline I keep failing to apply in production. I run long-lived agents. They make tool calls, they hold state, they run for minutes at a time. When one goes sideways, my instrumentation tells me it errored. It does not tell me it was drifting at step 9 and unrecoverable by step 20. I've got logs, I've got traces, and I've got no notion of expected state to compare against, so all of it is description, not diagnosis. I can tell you exactly what the agent did. I can't tell you where it went wrong.&lt;/p&gt;

&lt;p&gt;The fix isn't a smarter judge model watching the agent in real time. I tried that. It's slow, it costs per step, and it's confidently wrong in exactly the places I need it to be right — the ambiguous middle, where the agent is doing something plausible but off-spec. The fix is writing down the world spec: what the state should look like, which invariants should hold, what a milestone looks like. Then checking observed state against it. That check is cheap. It's a comparison, not an inference. And it gives me a progress trace instead of a postmortem.&lt;/p&gt;

&lt;p&gt;So the myth I want to bust is this: dense agent evals are too expensive to run. They're not. They're too expensive to &lt;em&gt;improvise&lt;/em&gt;. If you don't have a spec, every step is a judgment call, and judgment calls don't scale — not in money, and not in consistency. If you do have a spec, every step is a lookup.&lt;/p&gt;

&lt;p&gt;What I'd steal from Tev, concretely:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Write the world spec before the task prompt.&lt;/strong&gt; State, invariants, milestones, terminal conditions. If you can't write it, you don't understand the task well enough to eval it, and no amount of judge model will fix that.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Render the environment from the spec.&lt;/strong&gt; One source of truth. Hand-built environments drift from their descriptions, and then your rewards are scoring a world that doesn't exist.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Emit progress as a byproduct, not a second pass.&lt;/strong&gt; If scoring is a separate pipeline, it rots the moment the environment changes. If it's a projection of the spec, it stays in sync for free.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;In prod, make the same spec your instrumentation contract.&lt;/strong&gt; Every tool call gets checked against expected state. You get a curve, not a vibe.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Where I'm skeptical: rendering from a spec is only as good as the spec. Under-specify it and you get dense rewards that are confidently wrong, and an agent that optimizes straight into the gap between your spec and reality. That's worse than sparse, because sparse failure is at least honest — it doesn't tell you you're winning. Also, spec authoring is real work. You've moved the cost, not deleted it. But moving it from per-run scoring to one-time authoring is the right trade, because the spec is reusable, reviewable, and versionable. A wrong spec is a bug you can fix. A noisy judge is fog you can't.&lt;/p&gt;

&lt;p&gt;The other thing dense rewards buy you is debuggability. Sparse gives you pass/fail and a feeling. Dense gives you a curve, and the curve tells you where the agent stalls. That's the actual product. Not the score — the shape.&lt;/p&gt;

&lt;p&gt;Next time someone tells you long-horizon agent evals have to be sparse because dense scoring is too expensive, ask them for the world spec. If they don't have one, that's the cost they're actually paying. They just haven't itemized it.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>agents</category>
    </item>
    <item>
      <title>I finally cut AI context bloat by 80% and the fix was embarrassingly simple</title>
      <dc:creator>Lars Winstand</dc:creator>
      <pubDate>Wed, 14 Oct 2026 14:12:07 +0000</pubDate>
      <link>https://dev.to/lars_winstand/i-finally-cut-ai-context-bloat-by-80-and-the-fix-was-embarrassingly-simple-1mlp</link>
      <guid>https://dev.to/lars_winstand/i-finally-cut-ai-context-bloat-by-80-and-the-fix-was-embarrassingly-simple-1mlp</guid>
      <description>&lt;p&gt;A few months ago I watched an agent do something deeply cursed.&lt;/p&gt;

&lt;p&gt;It had already fetched the data.&lt;br&gt;
It had already parsed the data.&lt;br&gt;
It had already stored the useful fields.&lt;/p&gt;

&lt;p&gt;And then it pasted the entire raw tool response into the next model call anyway.&lt;/p&gt;

&lt;p&gt;Full JSON blobs. Logs. Metadata. Useless fields. Everything.&lt;/p&gt;

&lt;p&gt;The next step got slower.&lt;br&gt;
The step after that got more expensive.&lt;br&gt;
Then the model started doing that annoying thing where it answers the easy part of the task and quietly ignores the important part.&lt;/p&gt;

&lt;p&gt;That was the moment the bug became obvious:&lt;/p&gt;

&lt;p&gt;Most “context window problems” are not model problems.&lt;br&gt;
They are state management problems.&lt;/p&gt;

&lt;p&gt;Once you see that, you start spotting it everywhere in n8n flows, LangGraph agents, MCP tool loops, and custom OpenAI-compatible orchestration code.&lt;/p&gt;
&lt;h2&gt;
  
  
  The actual fix
&lt;/h2&gt;

&lt;p&gt;Stop replaying raw tool output into every prompt.&lt;/p&gt;

&lt;p&gt;Keep full results in structured state outside the model.&lt;br&gt;
Send only:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a short summary&lt;/li&gt;
&lt;li&gt;the exact fields needed for the next step&lt;/li&gt;
&lt;li&gt;or the exact evidence slice if verification matters&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That one change usually does more for agent quality than switching from one frontier model to another.&lt;/p&gt;
&lt;h2&gt;
  
  
  The anti-pattern
&lt;/h2&gt;

&lt;p&gt;Here’s the bad version:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;weather_api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_forecast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Austin&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Use this API response to decide whether to send an alert:&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If &lt;code&gt;result&lt;/code&gt; contains 200 lines of hourly forecast data, provider metadata, timestamps, debug fields, and trace IDs, you just turned your prompt into a junk drawer.&lt;/p&gt;

&lt;p&gt;Now the model has to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;find the relevant fields&lt;/li&gt;
&lt;li&gt;ignore the irrelevant ones&lt;/li&gt;
&lt;li&gt;remember prior steps&lt;/li&gt;
&lt;li&gt;plan the next action&lt;/li&gt;
&lt;li&gt;not get distracted by noise&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Models can do this.&lt;br&gt;
They are just not especially efficient at it.&lt;/p&gt;
&lt;h2&gt;
  
  
  The better pattern
&lt;/h2&gt;

&lt;p&gt;Store the full result in app state.&lt;br&gt;
Pass only the fields the next step needs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;weather_api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_forecast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Austin&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;weather_raw&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;

&lt;span class="n"&gt;weather_summary&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;temperature_f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;current&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;temp_f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;conditions&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;current&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;condition&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;wind_alert&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;alerts&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;wind&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Decide whether to send an alert using this data: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;weather_summary&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Same workflow.&lt;br&gt;
Smaller prompt.&lt;br&gt;
Less distraction.&lt;br&gt;
Better odds the model focuses on the decision instead of re-parsing junk.&lt;/p&gt;
&lt;h2&gt;
  
  
  Prompt size is not the same as prompt quality
&lt;/h2&gt;

&lt;p&gt;A lot of builders confuse these two ideas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the model can fit a long context&lt;/li&gt;
&lt;li&gt;the model should receive a long context&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those are not the same.&lt;/p&gt;

&lt;p&gt;A giant prompt is often just a badly managed state store wearing a trench coat.&lt;/p&gt;

&lt;p&gt;Even when GPT-5, Claude Opus, Grok, Qwen, or Llama can technically accept the full history, performance still gets mushier as stale content piles up. Latency rises. Cost rises. Attention gets diffused.&lt;/p&gt;

&lt;p&gt;This is why long-running agents often feel smart for 5 steps and weirdly flaky by step 20.&lt;/p&gt;
&lt;h2&gt;
  
  
  The 3 patterns, ranked
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Approach&lt;/th&gt;
&lt;th&gt;What happens in practice&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Raw tool output in prompt&lt;/td&gt;
&lt;td&gt;Biggest prompt growth. Highest distraction. Latency and cost climb every step.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Summarized tool result in prompt&lt;/td&gt;
&lt;td&gt;Usually the best balance. Smaller prompt footprint, but bad summaries can hide edge cases.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Structured state outside prompt&lt;/td&gt;
&lt;td&gt;Best default for multi-step agents. Small recurring prompts, cleaner reasoning, better orchestration.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;My opinionated take: structured state outside the prompt should be the default.&lt;/p&gt;

&lt;p&gt;If you are building anything more serious than a toy bot, replaying raw tool output into every step is lazy architecture.&lt;/p&gt;
&lt;h2&gt;
  
  
  What should live where?
&lt;/h2&gt;

&lt;p&gt;This is the mental model I wish more agent builders started with:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Short-term conversational state stays attached to the thread.&lt;/li&gt;
&lt;li&gt;Long-term facts and tool results live outside the prompt in a database or memory store.&lt;/li&gt;
&lt;li&gt;The next model call gets only the smallest useful slice of that state.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That’s it.&lt;/p&gt;

&lt;p&gt;Not complicated. Just disciplined.&lt;/p&gt;
&lt;h2&gt;
  
  
  Real examples
&lt;/h2&gt;
&lt;h3&gt;
  
  
  LangGraph: checkpoint state, don’t replay transcripts
&lt;/h3&gt;

&lt;p&gt;LangGraph gets this right.&lt;/p&gt;

&lt;p&gt;Instead of stuffing previous tool output back into every prompt, persist graph state and resume by thread.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langgraph.checkpoint.postgres&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;PostgresSaver&lt;/span&gt;

&lt;span class="n"&gt;DB_URI&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;postgresql://postgres:postgres@localhost:5432/postgres?sslmode=disable&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;PostgresSaver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_conn_string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DB_URI&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;checkpointer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;graph&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;checkpointer&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;checkpointer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is the grown-up version of memory.&lt;/p&gt;

&lt;p&gt;The model gets what the next node needs.&lt;br&gt;
Postgres keeps the rest.&lt;/p&gt;
&lt;h3&gt;
  
  
  n8n: trim memory on purpose
&lt;/h3&gt;

&lt;p&gt;n8n is refreshingly practical here.&lt;/p&gt;

&lt;p&gt;If you are building AI workflows in n8n, you already have the tools to avoid context bloat:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Simple Memory&lt;/li&gt;
&lt;li&gt;Redis&lt;/li&gt;
&lt;li&gt;Postgres&lt;/li&gt;
&lt;li&gt;Xata&lt;/li&gt;
&lt;li&gt;Zep&lt;/li&gt;
&lt;li&gt;Motorhead&lt;/li&gt;
&lt;li&gt;Chat Memory Manager&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The existence of Chat Memory Manager should tell you everything.&lt;/p&gt;

&lt;p&gt;If a workflow platform ships a node specifically to inspect and reduce memory, then “just append to chat history forever” is obviously not the best pattern.&lt;/p&gt;
&lt;h3&gt;
  
  
  MCP: tool output is app state first, prompt material second
&lt;/h3&gt;

&lt;p&gt;MCP makes this cleaner because tools already have structure.&lt;/p&gt;

&lt;p&gt;Example tool definition:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"get_weather"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Get current weather information for a location"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"inputSchema"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"object"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"properties"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"location"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"string"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"required"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"location"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"outputSchema"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"object"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That should push you toward a simple pattern:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;call the tool&lt;/li&gt;
&lt;li&gt;store the full structured result&lt;/li&gt;
&lt;li&gt;pass only the needed fields into the next prompt&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;tool_result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;temperature&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;72F&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;conditions&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cloudy&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;wind_alert&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hourly&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[...],&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;provider_metadata&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{...},&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;trace_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;abc123&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;weather_result&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tool_result&lt;/span&gt;

&lt;span class="n"&gt;prompt_payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;temperature&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;tool_result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;temperature&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;conditions&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;tool_result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;conditions&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;wind_alert&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;tool_result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;wind_alert&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The prompt becomes a working note, not a warehouse.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prompt caching helps, but it does not fix bad context hygiene
&lt;/h2&gt;

&lt;p&gt;This part gets misunderstood a lot.&lt;/p&gt;

&lt;p&gt;Anthropic prompt caching is useful when you keep reusing the same stable prefix.&lt;/p&gt;

&lt;p&gt;That means things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;system instructions&lt;/li&gt;
&lt;li&gt;tool definitions&lt;/li&gt;
&lt;li&gt;fixed documents&lt;/li&gt;
&lt;li&gt;repeated scaffolding&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It does not magically make a sloppy prompt good.&lt;/p&gt;

&lt;p&gt;Claude caching only helps when the prefix is identical, and cache entries last 5 minutes by default. That’s great for repeated prefixes. It does nothing to make a giant raw tool dump more relevant.&lt;/p&gt;

&lt;p&gt;If anything, caching can hide bad architecture for a while because the bill hurts less before quality problems become obvious.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;anthropic&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;anthropic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Anthropic&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;claude-opus-5-5&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;max_tokens&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;cache_control&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ephemeral&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;system&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;You are an AI assistant tasked with analyzing literary works.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Analyze the major themes in Pride and Prejudice.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use caching for stable prefixes.&lt;br&gt;
Do not use it as an excuse to keep shoving junk into prompts.&lt;/p&gt;

&lt;h2&gt;
  
  
  A quick before/after refactor
&lt;/h2&gt;

&lt;p&gt;Here’s what this looks like in a normal agent loop.&lt;/p&gt;

&lt;h3&gt;
  
  
  Before
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;run_step&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user_request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;search_results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;search_docs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;crm_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;fetch_customer_record&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;customer_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

    &lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
    User request: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;user_request&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;

    Search results:
    &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;search_results&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;

    CRM data:
    &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;crm_data&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;

    Decide what to do next.
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This works at first.&lt;br&gt;
Then &lt;code&gt;search_results&lt;/code&gt; gets huge.&lt;br&gt;
Then &lt;code&gt;crm_data&lt;/code&gt; gets huge.&lt;br&gt;
Then every step drags around more baggage.&lt;/p&gt;

&lt;h3&gt;
  
  
  After
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;run_step&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user_request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;search_results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;search_docs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;crm_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;fetch_customer_record&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;customer_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

    &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;search_results_raw&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;search_results&lt;/span&gt;
    &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;crm_data_raw&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;crm_data&lt;/span&gt;

    &lt;span class="n"&gt;prompt_payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user_request&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;user_request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;top_matches&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;title&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;search_results&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]],&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;customer_tier&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;crm_data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tier&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;open_tickets&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;crm_data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;open_tickets_count&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;billing_status&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;crm_data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;billing_status&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Decide what to do next using this state: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;prompt_payload&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This version is less fragile.&lt;/p&gt;

&lt;p&gt;And when the model needs exact evidence later, you can pull the raw state back in selectively.&lt;/p&gt;

&lt;h2&gt;
  
  
  When should you keep raw output in the prompt?
&lt;/h2&gt;

&lt;p&gt;There are real exceptions.&lt;/p&gt;

&lt;p&gt;Sometimes the next step genuinely needs exact source material.&lt;/p&gt;

&lt;p&gt;Keep raw output in-context when you need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;legal or compliance citations&lt;/li&gt;
&lt;li&gt;exact stack traces for debugging&lt;/li&gt;
&lt;li&gt;code review on full diffs&lt;/li&gt;
&lt;li&gt;extraction from messy text&lt;/li&gt;
&lt;li&gt;verification against original evidence&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But even then, pass the exact slice that matters.&lt;br&gt;
Not the entire upstream universe.&lt;/p&gt;

&lt;h2&gt;
  
  
  The rule I use now
&lt;/h2&gt;

&lt;p&gt;This is the heuristic that cleaned up most of my agent workflows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If information is needed for reasoning, summarize it.&lt;/li&gt;
&lt;li&gt;If it is needed for retrieval, store it.&lt;/li&gt;
&lt;li&gt;If it is needed for verification, pass the exact slice.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That rule has saved me more latency, more cost, and more agent quality than swapping models ever did.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this matters even more when you pay per token
&lt;/h2&gt;

&lt;p&gt;This problem gets expensive fast in production.&lt;/p&gt;

&lt;p&gt;If your agent runs 24/7 in n8n, Make, Zapier, OpenClaw, or a custom loop, every extra blob you keep replaying becomes recurring cost.&lt;/p&gt;

&lt;p&gt;That’s one reason teams end up obsessing over token usage dashboards instead of fixing the architecture.&lt;/p&gt;

&lt;p&gt;A cleaner state design reduces prompt bloat at the source.&lt;/p&gt;

&lt;p&gt;And if you are using an OpenAI-compatible endpoint with flat monthly pricing, this gets even nicer because you can optimize for agent quality and throughput instead of constantly asking whether one more tool call is going to spike the bill.&lt;/p&gt;

&lt;p&gt;That’s the part I like about Standard Compute: it works as a drop-in OpenAI API replacement, so you can keep your existing SDKs and agent code, but stop thinking in per-token panic mode while you clean up orchestration.&lt;/p&gt;

&lt;p&gt;The architecture fix still matters.&lt;br&gt;
You just get to apply it without token anxiety hanging over every experiment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Practical checklist
&lt;/h2&gt;

&lt;p&gt;If your agent feels slower and dumber over time, check these first:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Are you pasting raw tool output into every next prompt?&lt;/li&gt;
&lt;li&gt;Are you storing canonical results outside the model?&lt;/li&gt;
&lt;li&gt;Are you summarizing tool results before the next reasoning step?&lt;/li&gt;
&lt;li&gt;Are you passing exact evidence only when verification is required?&lt;/li&gt;
&lt;li&gt;Are you using prompt caching only for stable prefixes?&lt;/li&gt;
&lt;li&gt;Are you trimming memory in n8n or your orchestration layer?&lt;/li&gt;
&lt;li&gt;Are you treating the model like a reasoning engine instead of a database?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you fix just those, you will probably get a bigger improvement than another model bake-off.&lt;/p&gt;

&lt;p&gt;I went looking for a model fix.&lt;/p&gt;

&lt;p&gt;What I found was an architecture fix.&lt;/p&gt;

&lt;p&gt;Most “context window problems” are really just us using chat history as a storage layer.&lt;/p&gt;

&lt;p&gt;Once you stop shoving raw tool output back into the next prompt, agents get faster, cheaper, and noticeably less confused.&lt;/p&gt;

&lt;p&gt;Not because the models changed.&lt;/p&gt;

&lt;p&gt;Because we finally stopped making them carry our state management mistakes.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>agents</category>
      <category>devops</category>
    </item>
    <item>
      <title>Benchmarking Open Agents for Multi-File Refactors</title>
      <dc:creator>Jorge Peraza</dc:creator>
      <pubDate>Wed, 14 Oct 2026 14:10:11 +0000</pubDate>
      <link>https://dev.to/yorchperaza/benchmarking-open-agents-for-multi-file-refactors-1jl9</link>
      <guid>https://dev.to/yorchperaza/benchmarking-open-agents-for-multi-file-refactors-1jl9</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Skylark Creations' October 3 benchmark evaluated open coding agents against a 36-point rubric, showing they now rival proprietary solutions in multi-file reasoning and terminal execution.&lt;/li&gt;
&lt;li&gt;The report highlights a shift in developer workflows: engineers require tools that plan, edit across multiple files, and iterate via tests without forcing lock-in to a single ecosystem.&lt;/li&gt;
&lt;li&gt;MonkeysCode addresses this directly. Our recent Editor 1.2.12 (featuring the Capuchin agent) and CLI 1.0.2 releases provide a robust harness for multi-file loops, supporting both frontier and open models via BYOK.&lt;/li&gt;
&lt;li&gt;Effective agent execution requires strict context management; our latest updates include usage dashboards exposing cache-write tokens and architectural changes to optimize prompt caching breakpoints.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Skylark Creations Benchmark
&lt;/h2&gt;

&lt;p&gt;On October 3, 2026, Skylark Creations published an updated evaluation of open-source coding agents. The benchmark assessed tools like Aider, Cline, and Orbi against a rigorous 36-point rubric designed to measure capabilities far beyond single-file autocomplete. &lt;/p&gt;

&lt;p&gt;The report's primary finding is clear: open agents now rival proprietary solutions when it comes to multi-file reasoning and terminal execution. &lt;/p&gt;

&lt;p&gt;Historically, the gap between open models and proprietary frontier models was most visible in context retention and structural planning. A model might successfully write a Python script in a vacuum, but fail to correctly update an interface, modify the implementing classes across three different files, run the test suite, and parse the resulting stderr output to fix a typo. The Skylark benchmark demonstrates that this gap is closing. By effectively utilizing open models, developers can achieve complex, agentic refactoring without being tethered to a single proprietary ecosystem or incurring prohibitive API costs.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Engineering Mechanics of Multi-File Execution
&lt;/h2&gt;

&lt;p&gt;Handling multi-file refactors introduces a specific set of engineering challenges for any agent harness. It is not simply a matter of passing more tokens into the context window. The agent must successfully navigate a multi-step loop:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Planning:&lt;/strong&gt; Analyzing the codebase to identify which files require modification based on a given prompt.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Diff Generation:&lt;/strong&gt; Emitting precise edits (often via search/replace blocks) rather than rewriting entire files, which wastes tokens and risks introducing regressions.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Terminal Execution:&lt;/strong&gt; Running compilers, linters, or test suites directly in the environment.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Iteration:&lt;/strong&gt; Parsing the terminal output (stdout/stderr) and determining if a failure requires a logic change, a dependency update, or simply a retry.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When a developer asks an agent to, for example, fix a database migration error—such as changing a raw SQL query from using a &lt;code&gt;?&lt;/code&gt; operator to using &lt;code&gt;jsonb_exists()&lt;/code&gt; in Postgres—the agent must locate the migration file, update the schema definition, modify the corresponding application data models, and run the test suite to verify the changes. &lt;/p&gt;

&lt;p&gt;If the test fails, the agent must read the failure, retain the context of its previous edits, and apply a correction. This requires the agent harness to safely supervise the terminal process and manage the context window efficiently.&lt;/p&gt;

&lt;h2&gt;
  
  
  Running Open Agents with MonkeysCode
&lt;/h2&gt;

&lt;p&gt;Developers want the flexibility to use the best model for the job, whether that is a local model, an open model, or a proprietary frontier model. We designed MonkeysCode to provide a flexible, unopinionated harness for these agentic loops.&lt;/p&gt;

&lt;p&gt;On October 5, 2026, we shipped &lt;a href="https://monkeyscode.com/docs" rel="noopener noreferrer"&gt;MonkeysCode CLI 1.0.2&lt;/a&gt; and Agent Manager 1.0.16. These releases solidify our terminal execution and supervision capabilities, allowing developers to run multi-file agent loops directly from their command line. &lt;/p&gt;

&lt;p&gt;Simultaneously, we released MonkeysCode Editor 1.2.12. This desktop IDE includes &lt;a href="https://monkeyscode.com/capuchin" rel="noopener noreferrer"&gt;Capuchin&lt;/a&gt;, our built-in coding agent. Capuchin is explicitly designed to handle the workflow validated by the Skylark benchmark: it plans changes, executes diff reviews across multiple files, runs tests, and iterates based on the output.&lt;/p&gt;

&lt;p&gt;Because MonkeysCode supports BYOK (Bring Your Own Key), developers can plug in the open models that performed well on the Skylark rubric, or utilize local models, running them through Capuchin's multi-file execution engine.&lt;/p&gt;

&lt;p&gt;Here is an example of how you might initiate a multi-file refactor using the MonkeysCode CLI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Initialize an agent session targeting a specific directory&lt;/span&gt;
monkeyscode agent start ./src/database

&lt;span class="c"&gt;# Provide the instruction for a multi-file refactor&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"Migrate all raw Postgres queries using the '?' operator to use jsonb_exists(). Update the corresponding unit tests in ./tests/database/ and run npm test to verify."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Agent Manager will orchestrate the planning phase, apply the necessary diffs, execute the test command, and feed the terminal output back to the model for iteration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prompt Caching and Context Economics
&lt;/h2&gt;

&lt;p&gt;As multi-file reasoning becomes standard, the economics of context management become the primary bottleneck. Running a loop that repeatedly analyzes three files, a test suite, and terminal output will rapidly consume tokens.&lt;/p&gt;

&lt;p&gt;To make this practical, agent harnesses must leverage prompt caching. When the system prompt, the core codebase structure, and the tool definitions are cached, the agent only pays for the delta (the new terminal output or the modified file) on each iteration.&lt;/p&gt;

&lt;p&gt;In our latest release cycle, we shipped several architectural updates to support this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Cache-Write Tokens:&lt;/strong&gt; Our usage dashboards (available for both individual and &lt;a href="https://monkeyscode.com/for-teams" rel="noopener noreferrer"&gt;Team plans&lt;/a&gt;) now explicitly show cache-write tokens, giving developers transparency into their context economics.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Auto Model Routing:&lt;/strong&gt; We shipped step 4 of our "Auto" model routing build, adding an Auto mode tab on the Models &amp;amp; Pricing page. This system automatically routes requests based on context requirements and displays cache ratios, warning users if they are mixing frontier providers in a way that defeats caching efficiency.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;System Block Separation:&lt;/strong&gt; We updated our context kernel to keep system blocks separate for cache breakpoints. Whether you are using the newly integrated GPT-6 via Azure Foundry or an open model, maintaining strict cache breakpoints ensures that the static parts of your prompt do not incur redundant processing costs.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Stream Stability:&lt;/strong&gt; Multi-file reasoning takes time. We recently deployed a fix to keep Anthropic SSE streams alive while the model is "thinking," preventing timeouts during complex planning phases.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Takeaway
&lt;/h2&gt;

&lt;p&gt;The Skylark Creations benchmark provides concrete evidence that open models are capable of executing complex, multi-file refactors. However, the model is only half of the equation. The other half is the agent harness—the system that manages the context window, applies the diffs, and supervises the terminal execution.&lt;/p&gt;

&lt;p&gt;Developers should not have to choose between advanced multi-file capabilities and the freedom to use open models. By decoupling the agent harness from the underlying model, tools like the MonkeysCode CLI and Capuchin allow engineers to leverage the reasoning capabilities of open agents within a robust, multi-file execution environment.&lt;/p&gt;

&lt;p&gt;You can &lt;a href="https://monkeyscode.com/download" rel="noopener noreferrer"&gt;download MonkeysCode&lt;/a&gt; today to test Capuchin and the CLI with your preferred models, or review our &lt;a href="https://monkeyscode.com/docs" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; for details on setting up BYOK and local model routing.&lt;/p&gt;

</description>
      <category>agents</category>
      <category>benchmarks</category>
      <category>opensource</category>
      <category>cli</category>
    </item>
    <item>
      <title>I verified all 160 official U.S. business-data portals so your agent doesn't have to — here's what I found</title>
      <dc:creator>bradraylucas-eng</dc:creator>
      <pubDate>Wed, 14 Oct 2026 14:07:46 +0000</pubDate>
      <link>https://dev.to/bradraylucaseng/i-verified-all-160-official-us-business-data-portals-so-your-agent-doesnt-have-to-heres-what-5g3d</link>
      <guid>https://dev.to/bradraylucaseng/i-verified-all-160-official-us-business-data-portals-so-your-agent-doesnt-have-to-heres-what-5g3d</guid>
      <description>&lt;p&gt;Every agent workflow I build starts with the same wasted motion: the agent searches the web for the official registry, lands on an ad or an aggregator, and burns its run. So I verified the official portals myself — business entity search (50 states + DC + federal), UCC lien search, and professional license verification — and wrote down what agents actually need to know before they start.&lt;/p&gt;

&lt;p&gt;Findings that surprised me:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Texas is the only state that charges for a basic business entity search ($1 via its portal) — and it retired the system agents' training data points to (SOSDirect) in September 2026.&lt;/li&gt;
&lt;li&gt;UCC search is a different world: 21 of 51 jurisdictions charge, 18 require an account before you can search, and Delaware has no public search at all (state-licensed "Authorized Searchers" only).&lt;/li&gt;
&lt;li&gt;License verification has no center: only 21 of 51 jurisdictions have a true central portal. California's main portal excludes contractors and real estate entirely. A "not found" there proves nothing.&lt;/li&gt;
&lt;li&gt;In 10+ states the business registry is not run by the Secretary of State at all.&lt;/li&gt;
&lt;li&gt;A large share of these portals return 403/bot challenges to plain HTTP clients. If your agent fetches with a simple client, it needs a browser session for these — the datasets flag them per portal.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I packaged the verified data (JSON + CSV, documented schema, per-entry cost/login/access notes, last verified October 2026) as the Source Finder datasets on Gumroad, with free samples so you can check the schema before paying anything: &lt;a href="https://github.com/bradraylucas-eng/ai-agent-tools-free-samples" rel="noopener noreferrer"&gt;https://github.com/bradraylucas-eng/ai-agent-tools-free-samples&lt;/a&gt; · Vol. 1 on Gumroad: &lt;a href="https://bradray2.gumroad.com/l/fxnjw" rel="noopener noreferrer"&gt;https://bradray2.gumroad.com/l/fxnjw&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you build agents that do due diligence, vendor checks, or lead verification, I'd genuinely like to know what other official sources you re-hunt every run — that's what Vol. 4 should be.&lt;/p&gt;

&lt;p&gt;— Brad (maker; the datasets are my product, the samples are free)&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>agents</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Test your agent's payment loop on a testnet before it goes live</title>
      <dc:creator>OpenClaw Cash</dc:creator>
      <pubDate>Wed, 14 Oct 2026 14:04:38 +0000</pubDate>
      <link>https://dev.to/openclawcash/test-your-agents-payment-loop-on-a-testnet-before-it-goes-live-3n0a</link>
      <guid>https://dev.to/openclawcash/test-your-agents-payment-loop-on-a-testnet-before-it-goes-live-3n0a</guid>
      <description>&lt;p&gt;Wiring payments into an agent is easy to get wrong in a way that only shows up with real money: a retry after a network timeout that pays the same invoice twice, a recipient address copied out of a stale config, a webhook handler that accepts a replayed delivery. None of that is visible on a mainnet balance you cannot undo.&lt;/p&gt;

&lt;p&gt;The cheapest place to find those bugs is a test network, and the agent API treats one almost exactly like mainnet: same endpoints, same &lt;code&gt;X-Agent-Key&lt;/code&gt; header, same response shapes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why a testnet transfer finds what unit tests miss
&lt;/h2&gt;

&lt;p&gt;A mock proves your code runs. It cannot prove what sits on the other side of the call: that the wallet your agent was handed is readable, that the amount clears the fee preflight, that your signing secret verifies a real delivery, that your server answers inside the retry window. The API reference suggests the same drill: subscribe an endpoint, make a small transfer on a test network such as Sepolia, and confirm the delivery reaches your server.&lt;/p&gt;

&lt;p&gt;Three things a live testnet run proves:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Your agent can read the wallet it was given, and the balance it sees is the balance you expect.&lt;/li&gt;
&lt;li&gt;The transfer passes the minimum-transferable check, fees included.&lt;/li&gt;
&lt;li&gt;Your server verifies the signature and answers 2xx fast enough that the platform never retries.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Step 1: create a wallet your mistakes cannot cost anything
&lt;/h2&gt;

&lt;p&gt;Create wallets on &lt;code&gt;sepolia&lt;/code&gt;, &lt;code&gt;mainnet&lt;/code&gt; or &lt;code&gt;polygon-mainnet&lt;/code&gt; (EVM), or on &lt;code&gt;solana-devnet&lt;/code&gt;, &lt;code&gt;solana-testnet&lt;/code&gt; or &lt;code&gt;solana-mainnet&lt;/code&gt;. Start on a test network.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;OCC_AGENT_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"occ_your_api_key"&lt;/span&gt;

curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://openclawcash.com/api/agent/wallets/create &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-Agent-Key: &lt;/span&gt;&lt;span class="nv"&gt;$OCC_AGENT_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "label": "agent-testnet",
    "network": "sepolia",
    "exportPassphrase": "store-this-before-you-call",
    "exportPassphraseStorageType": "env",
    "exportPassphraseStorageRef": "WALLET_EXPORT_PASSPHRASE_AGENT_TESTNET",
    "confirmExportPassphraseSaved": true
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two reasons for that shape. It follows the passphrase-safe flow: you persist the export passphrase first and then assert you did with &lt;code&gt;confirmExportPassphraseSaved&lt;/code&gt;. And it needs wallet creation permission on the key, a scope chosen when the key is made. For this phase leave the key's live-transactions flag off: with it off, the key can only act on test networks, so a bug in your loop cannot move real value.&lt;/p&gt;

&lt;p&gt;The response is the wallet record: &lt;code&gt;id&lt;/code&gt; (the &lt;code&gt;walletId&lt;/code&gt; you pass everywhere else), &lt;code&gt;label&lt;/code&gt;, &lt;code&gt;address&lt;/code&gt;, &lt;code&gt;network&lt;/code&gt;, &lt;code&gt;chain&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: discover, then read the balance
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl https://openclawcash.com/api/agent/wallets &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-Agent-Key: &lt;/span&gt;&lt;span class="nv"&gt;$OCC_AGENT_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

curl &lt;span class="s2"&gt;"https://openclawcash.com/api/agent/wallet?walletId=AB12CD3&amp;amp;chain=evm"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-Agent-Key: &lt;/span&gt;&lt;span class="nv"&gt;$OCC_AGENT_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The list is discovery only, cheap in an agent loop. Wallet detail returns &lt;code&gt;nativeBalanceDisplay&lt;/code&gt; and &lt;code&gt;tokenBalances&lt;/code&gt;, where an "is there enough to pay this invoice" branch gets tested as written. Fund the address from a testnet faucet, then read again.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: make the transfer, then read the record
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://openclawcash.com/api/agent/transfer &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-Agent-Key: &lt;/span&gt;&lt;span class="nv"&gt;$OCC_AGENT_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "chain": "evm",
    "walletId": "AB12CD3",
    "to": "0xRecipientWalletAddress",
    "amountDisplay": "0.01"
  }'&lt;/span&gt;

curl &lt;span class="s2"&gt;"https://openclawcash.com/api/agent/transactions?walletId=AB12CD3&amp;amp;network=sepolia"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-Agent-Key: &lt;/span&gt;&lt;span class="nv"&gt;$OCC_AGENT_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two rules trip people up here. Send exactly one amount field: &lt;code&gt;amountDisplay&lt;/code&gt; for human units or &lt;code&gt;valueBaseUnits&lt;/code&gt; for base units, never both, or the call answers 400. And native transfers run a preflight for the minimum transferable amount, so a wallet holding dust comes back &lt;code&gt;amount_below_min_transfer&lt;/code&gt; with the minimum it needs, instead of broadcasting a transaction that cannot pay for itself.&lt;/p&gt;

&lt;p&gt;Every history row carries &lt;code&gt;data.network&lt;/code&gt;; scope with &lt;code&gt;network=sepolia&lt;/code&gt;, or &lt;code&gt;network=all&lt;/code&gt; to merge every EVM chain.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: hear the payment on your own server
&lt;/h2&gt;

&lt;p&gt;Wallet events are a named group, &lt;code&gt;wallet.transaction.confirmed&lt;/code&gt;, never covered by a &lt;code&gt;*&lt;/code&gt; subscription, so list it by name.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://openclawcash.com/api/agent/checkout/webhooks &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-Agent-Key: &lt;/span&gt;&lt;span class="nv"&gt;$OCC_AGENT_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Idempotency-Key: webhook-create-001"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "url": "https://your-server.example/occ",
    "eventTypes": ["wallet.transaction.confirmed"],
    "enabled": true
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You get back a &lt;code&gt;publicId&lt;/code&gt; and a &lt;code&gt;secret&lt;/code&gt; starting with &lt;code&gt;whsec_&lt;/code&gt;, shown once. Keep it server side, never in the agent's context. Then hold every delivery to the documented checks: read the raw request body before any JSON parsing, reject a &lt;code&gt;webhook-timestamp&lt;/code&gt; older than 5 minutes, and compare the HMAC-SHA256 of &lt;code&gt;{id}.{timestamp}.{body}&lt;/code&gt; (base64) against the &lt;code&gt;v1&lt;/code&gt; entry of &lt;code&gt;webhook-signature&lt;/code&gt; in constant time. De-duplicate on &lt;code&gt;webhook-id&lt;/code&gt;, because a delivery can arrive more than once, and answer 2xx within 10 seconds. Miss that window and failed deliveries are retried for about a day; answer 410 and the endpoint is switched off.&lt;/p&gt;

&lt;p&gt;A testnet transfer produces the same event as a mainnet one. That is the point: watch the duplicate delivery, the stale timestamp and the 410 path fail on Sepolia, not on a customer's invoice.&lt;/p&gt;

&lt;h2&gt;
  
  
  What changes when you go live
&lt;/h2&gt;

&lt;p&gt;Once the loop is boring, issue a second key for production with live transactions on, scope it to one chain and one wallet, and attach the wallet's policies so the server refuses anything that violates them before it is signed. Keep the testnet key for your test suite.&lt;/p&gt;

&lt;p&gt;Two limits, plainly. Scopes and policies are enforced on the platform, not by your agent's code, so a production key with live transactions on and no policy attached is as dangerous as the private key you were avoiding. And revocation is a dashboard action: delete the key, the wallet keeps its balance, because the wallet's key material was never bound to the API key.&lt;/p&gt;

&lt;p&gt;Endpoint paths, headers and fields above come from the published API reference at &lt;a href="https://openclawcash.com/docs" rel="noopener noreferrer"&gt;openclawcash.com/docs&lt;/a&gt;; the key-scope flags are described in the site's setup guide, &lt;a href="https://openclawcash.com/blog/hermes-agent-give-your-ai-a-safe-wallet-by-default" rel="noopener noreferrer"&gt;Hermes Agent Wallet Setup: Safe by Default&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>agents</category>
      <category>api</category>
      <category>tutorial</category>
      <category>crypto</category>
    </item>
    <item>
      <title>Mistral Large 4 Preview: MoE for Agentic Workflows</title>
      <dc:creator>Jorge Peraza</dc:creator>
      <pubDate>Wed, 14 Oct 2026 14:01:50 +0000</pubDate>
      <link>https://dev.to/yorchperaza/mistral-large-4-preview-moe-for-agentic-workflows-2k90</link>
      <guid>https://dev.to/yorchperaza/mistral-large-4-preview-moe-for-agentic-workflows-2k90</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mistral AI announced the public preview API for Mistral Large 4 ("le Chonk") on October 6, 2026, targeting agentic workflows and vulnerability patching.&lt;/li&gt;
&lt;li&gt;The model utilizes a Mixture-of-Experts (MoE) architecture with roughly 1 trillion total and 49 billion active parameters, trained on 3,800 Nvidia Grace Blackwell GPUs.&lt;/li&gt;
&lt;li&gt;Open weights are scheduled for release in late October, offering an alternative to proprietary frontier APIs for autonomous coding tasks.&lt;/li&gt;
&lt;li&gt;MonkeysCode developers will be able to integrate Mistral Large 4 via our BYOK (Bring Your Own Key) support, though verified model-proxy support and head-to-head Capuchin benchmarks are currently pending.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Technical Profile of Mistral Large 4
&lt;/h2&gt;

&lt;p&gt;On October 6, 2026, Mistral AI released the public preview API for Mistral Large 4, internally dubbed "le Chonk." The release signals a continued industry shift toward specialized, high-capacity models designed specifically for autonomous execution rather than simple chat completion.&lt;/p&gt;

&lt;p&gt;Under the hood, Mistral Large 4 is a multimodal Mixture-of-Experts (MoE) model. It features approximately 1 trillion total parameters, but only activates about 49 billion parameters during any given forward pass. This sparse activation is a critical architectural choice for coding agents. Dense models of similar total size require massive compute overhead for every token generated. By routing tokens only to the relevant "experts" within the network, an MoE model can maintain a vast repository of training data—such as diverse programming languages, syntax rules, and known software vulnerabilities—while keeping inference latency and compute costs manageable.&lt;/p&gt;

&lt;p&gt;According to the announcement, the model was trained in Europe across a cluster of 3,800 Nvidia Grace Blackwell GPUs. The sheer scale of this training infrastructure highlights the compute density required to produce open-weight models today.&lt;/p&gt;

&lt;p&gt;For developers, the immediate access point is the Mistral Studio preview API. However, the most notable aspect of the announcement is Mistral's commitment to releasing the open weights by late October. This upcoming release provides engineering teams with the ability to self-host a trillion-parameter-class model, ensuring strict data privacy and bypassing rate limits associated with managed APIs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Aligning with Agentic Workflows and Patching
&lt;/h2&gt;

&lt;p&gt;Mistral explicitly targeted Mistral Large 4 at agentic workflows and software vulnerability patching. This focus aligns directly with the operational mechanics of tools like the &lt;a href="https://monkeyscode.com/capuchin" rel="noopener noreferrer"&gt;MonkeysCode Capuchin agent&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;When developers build or utilize autonomous agents, the requirements differ significantly from standard code autocomplete. An autocomplete model needs to predict the next few lines based on a narrow, localized context window. An agentic model, however, must:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Plan:&lt;/strong&gt; Ingest a high-level prompt (e.g., "Fix the SQL injection vulnerabilities in the user authentication module").&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Navigate:&lt;/strong&gt; Understand the repository structure and identify which files need modification.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Edit:&lt;/strong&gt; Apply precise diffs across multiple files simultaneously.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Iterate:&lt;/strong&gt; Run tests, parse the output, and correct its own mistakes if the tests fail.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Because Mistral Large 4 was tuned specifically for these multi-step, multi-file operations, it presents a compelling alternative to proprietary frontier APIs. The 49B active parameter count is particularly relevant here: agentic loops require multiple back-and-forth calls to the model. If the time-to-first-token (TTFT) or generation speed is too slow, the entire agentic workflow bottlenecks. The MoE architecture aims to mitigate this by providing the reasoning capabilities of a 1T model at the inference speed of a much smaller one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Integrating with MonkeysCode
&lt;/h2&gt;

&lt;p&gt;At MonkeysCode, our platform is built around a multi-model architecture. We do not lock developers into a single provider because different tasks require different models. &lt;/p&gt;

&lt;p&gt;With the release of Mistral Large 4, developers can leverage our BYOK (Bring Your Own Key) support to route agentic tasks to the new model. While we are still waiting for the open weights to land later this month for local execution, the preview API can be configured within your MonkeysCode environment.&lt;/p&gt;

&lt;p&gt;To configure a custom provider in MonkeysCode for the Mistral Studio preview, your JSON configuration would look similar to this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"models"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mistral-large-4-preview"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"provider"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"custom"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"baseUrl"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://api.mistral.ai/v1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"apiKey"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"env.MISTRAL_API_KEY"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Note: Verified model-proxy support or custom base URL tests specifically with the Mistral Studio preview endpoints are currently pending on our end, as are head-to-head performance and latency benchmarks of Mistral Large 4 inside MonkeysCode Capuchin agent tasks (such as multi-file editing and test repair).&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Recent Platform Updates for Agentic Workflows
&lt;/h3&gt;

&lt;p&gt;To better support models like Mistral Large 4, we have recently shipped several updates to the MonkeysCode platform that enhance how developers interact with coding agents and manage model usage:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Enhanced Editor and Agent Manager:&lt;/strong&gt; We recently released &lt;a href="https://monkeyscode.com/features" rel="noopener noreferrer"&gt;MonkeysCode Editor&lt;/a&gt; 1.2.12 and Agent Manager 1.0.16. The editor has been moved into our monorepo to streamline builds, and we've added UI improvements such as rendering markdown tables in chat and allowing developers to click a file name on a diff card to immediately open its tab.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;CLI Improvements:&lt;/strong&gt; The &lt;a href="https://monkeyscode.com/docs" rel="noopener noreferrer"&gt;MonkeysCode CLI&lt;/a&gt; has been updated to version 1.0.2, improving how you run and supervise coding agents directly from your terminal.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Auto Model Routing and Caching:&lt;/strong&gt; Our "Auto" model routing feature helps optimize cost and performance by selecting the right model for the job. In our latest update, the Auto mode tab on the Models &amp;amp; Pricing page now shows cache ratios and warns developers if they are mixing frontier providers in ways that break prompt caching. Additionally, usage dashboards now explicitly track cache-write tokens, giving teams better visibility into their API spend.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These caching improvements are vital when running agentic workflows. When Capuchin iterates on a test failure, it resends the repository context. Efficient prompt caching ensures you aren't paying to re-process the same files on every loop.&lt;/p&gt;

&lt;h2&gt;
  
  
  Takeaway
&lt;/h2&gt;

&lt;p&gt;The public preview of Mistral Large 4 and the impending release of its open weights provide developers with a powerful new tool for autonomous coding. By combining a massive 1T parameter knowledge base with a highly efficient 49B active parameter MoE architecture, Mistral is directly targeting the latency and cost bottlenecks of agentic workflows.&lt;/p&gt;

&lt;p&gt;While we are still gathering benchmark data on how it performs head-to-head against other frontier models in Capuchin's multi-file editing tasks, the availability of an open-weight model tuned for vulnerability patching is a significant step forward for developers who require strict data control and self-hosted execution.&lt;/p&gt;

&lt;p&gt;For more information on how to configure custom models or utilize our built-in coding agent, visit the &lt;a href="https://monkeyscode.com/docs" rel="noopener noreferrer"&gt;MonkeysCode Docs&lt;/a&gt; or explore our &lt;a href="https://monkeyscode.com/for-teams" rel="noopener noreferrer"&gt;Team Plans&lt;/a&gt; for enterprise deployments.&lt;/p&gt;

</description>
      <category>mistral</category>
      <category>llms</category>
      <category>agents</category>
      <category>capuchin</category>
    </item>
    <item>
      <title>An agent that learns the world it acts in: System 1, System 2, and knowledge you can retract</title>
      <dc:creator>Maxim Kuznetsov</dc:creator>
      <pubDate>Wed, 14 Oct 2026 14:00:00 +0000</pubDate>
      <link>https://dev.to/mxkuzn/an-agent-that-learns-the-world-it-acts-in-system-1-system-2-and-knowledge-you-can-retract-1cj0</link>
      <guid>https://dev.to/mxkuzn/an-agent-that-learns-the-world-it-acts-in-system-1-system-2-and-knowledge-you-can-retract-1cj0</guid>
      <description>&lt;p&gt;Most LLM agents start every task from zero. They explore, they find the way, and the next day they explore again. Some keep a memory, but it is usually text the model wrote about itself, which nobody can check or take back. This last part of the series shows the other end of solvi 1.0: an agent that keeps verified knowledge about the world it acts in, acts fast where that knowledge predicts the action works, deliberates where it does not, and keeps written rules as hard checks in both. I wrote solvi; part 5 of 5 (&lt;a href="https://dev.to/mxkuzn/solvi-10-in-20-minutes-decisions-you-can-check-from-a-hand-written-rule-to-an-agent-that-learns-16a0"&gt;overview&lt;/a&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  The two systems
&lt;/h2&gt;

&lt;p&gt;Each step is one decision with two possible answerers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;System 1&lt;/strong&gt; takes an action the knowledge predicts will work and that advances an open goal: a goal's &lt;em&gt;skill&lt;/em&gt; (the action after which its done check turned true before) or the next step of a confirmed route to where the skill worked.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;System 2&lt;/strong&gt; is a search over the offered actions when System 1 has nothing it is sure of: an open goal's action first, then what was never tried here, then the way to the nearest place with untried actions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hard checks hold in both&lt;/strong&gt;: the agenda's gates, a hard refusal of the action model, the failure memory.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After every step the knowledge is written back: the action model learns from the outcome, a goal done right after an action makes a skill, and where each action led becomes a map fact. Every decision is stored with what it was given and &lt;code&gt;agent.replay()&lt;/code&gt; re-checks it without the environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  The world and the knowledge
&lt;/h2&gt;

&lt;p&gt;Example 25 in the repo is a toy crafting world: 8 places joined by exits, resources (tree, stone, iron, water), six operators with the environment's own checks (&lt;code&gt;collect_stone&lt;/code&gt; needs stone here and a pickaxe, and so on), six goals. The agent knows none of those rules. It gets a vocabulary — the conditions its action model may learn from — and goals whose done checks are code, never a model's claim. Excerpt from &lt;a href="https://github.com/solvi-ai/solvi/blob/main/examples/25_environment_agent.py" rel="noopener noreferrer"&gt;examples/25_environment_agent.py&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;VOCABULARY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;here&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;here&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;wood&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;wood&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;stone&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;stone&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
              &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pickaxe&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pickaxe&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;stone_pickaxe&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;stone_pickaxe&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
              &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;table_here&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;place&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tables&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;place&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;                                                &lt;span class="c1"&gt;# the map's keys: the places
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;place&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;goals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;km&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;The six goals: done when the operator has worked once (code over the state, never a model&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s claim).&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;op&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;needs&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;zip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;OPS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;OPS&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]):&lt;/span&gt;
        &lt;span class="n"&gt;km&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;goal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;op&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;done&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;op&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;op&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;op&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;achieved&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;requires&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;needs&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;needs&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;km&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent itself is three lines (excerpt, same file):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;    &lt;span class="n"&gt;km&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;goals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;solvi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Knowledge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vocabulary&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;VOCABULARY&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;solvi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Crafting&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;knowledge&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;km&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;place&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;runs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;world 7, run 1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;seed&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;steps&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;150&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;world 7, run 2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;seed&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;steps&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;150&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;world 8 (new)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;seed&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;steps&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;150&lt;/span&gt;&lt;span class="p"&gt;))]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Crafting&lt;/code&gt; is any object with &lt;code&gt;reset(seed)&lt;/code&gt;, &lt;code&gt;actions(state)&lt;/code&gt; and &lt;code&gt;step(action) → Outcome&lt;/code&gt; — the &lt;code&gt;Environment&lt;/code&gt; protocol; &lt;code&gt;solvi.testing.conformance.check_environment&lt;/code&gt; checks one of your own.&lt;/p&gt;

&lt;p&gt;The same world runs in your browser, with no install: the arcade Space's "Agent and knowledge (1.0)" tab (&lt;a href="https://huggingface.co/spaces/solvi-ai/arcade" rel="noopener noreferrer"&gt;https://huggingface.co/spaces/solvi-ai/arcade&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fn3nzpc2nx3l389nbgvf2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fn3nzpc2nx3l389nbgvf2.png" alt="Screenshot of the solvi arcade Space, tab Agent and knowledge (1.0), running this crafting world in the browser: run 1 in world 7, 61 steps (System 1 0, System 2 61, 23 refused); run 2 in the same world, 12 steps (System 1 11, System 2 1, 0 refused); below, the map of the eight places." width="800" height="578"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The same world, met again
&lt;/h2&gt;

&lt;p&gt;The whole output of the file, verbatim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Part 1 — the same world met again needs fewer slow decisions
  world 7, run 1: 61 steps, 6 of 6 goals, System 1 0, System 2 61, fallback 0, refused 23
  world 7, run 2: 12 steps, 6 of 6 goals, System 1 11, System 2 1, fallback 0, refused 0
  world 8 (new): 17 steps, 6 of 6 goals, System 1 4, System 2 13, fallback 0, refused 3
  every decision replays: 90 of 90; the knowledge journal verifies: True
  learned: collect_stone needs ["'stone'"] here and a pickaxe ['True']

Part 2 — protection vs justified risk (30 episodes on a world with a breaking bridge to the iron)
  protect : iron in 2 of 30 episodes, fell 1 times, 0 risky crossings, 5.07 goals per episode
  risk    : iron in 24 of 30 episodes, fell 6 times, 27 risky crossings, 5.80 goals per episode
  the gate 'no bridge without the stone pickaxe' held in both: True
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first run explores: 61 steps, every one decided by System 2, 23 actions refused by the world. The second run in the same world takes 12 steps, 11 of them by System 1, nothing refused. In a new world the agent keeps the &lt;em&gt;rules&lt;/em&gt; (what an operator needs) and re-learns the &lt;em&gt;map&lt;/em&gt;: 17 steps. The last line of part 1 is what the action model learned, readable: &lt;code&gt;collect_stone&lt;/code&gt; works with stone here and a pickaxe.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1vkxon4mdunptxe2weea.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1vkxon4mdunptxe2weea.png" alt="Stacked bar charts of steps by System 1 (fast) and System 2 (slow). Crafting world: world 7 run 1, 61 steps, all slow; run 2, 12 steps, 11 fast and 1 slow; a new world 8, 17 steps, 4 fast and 13 slow. Pokémon Red world map, first 15 goals: run 1, 183 moves, 147 slow; run 2, 62 moves, 2 slow, the fewest moves possible." width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Map facts and rules are kept apart on purpose. Rules are carried across episodes; map facts belong to the map they were seen on, and the first arrival that contradicts a carried map fact drops the carried map — its facts become hints until confirmed again.&lt;/p&gt;

&lt;h2&gt;
  
  
  Protection by default, risk as an option
&lt;/h2&gt;

&lt;p&gt;Knowledge used as hard checks removes the failures it predicts. It can also cost a goal that needs a risk. Part 2 of the example has a world where the iron lies only across a rope bridge that breaks one time in three (the episode ends), and a written gate: no bridge without the stone pickaxe. Excerpt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;risk&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;protect&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;risk&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;RiskBudget&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_risk_per_episode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;min_gain_ratio&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                                              &lt;span class="n"&gt;min_support&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))):&lt;/span&gt;
        &lt;span class="n"&gt;km&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;goals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;solvi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Knowledge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nc"&gt;OutcomeRates&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;VOCABULARY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;only&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bridge&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]})))&lt;/span&gt;
        &lt;span class="n"&gt;km&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;agenda&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;gate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bridge_needs_the_tool&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;stone_pickaxe&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;blocks&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bridge&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
        &lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;solvi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Crafting&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bridge&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;knowledge&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;km&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;place&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;risk&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;risk&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;gain&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;bridge_gain&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(&lt;code&gt;OutcomeRates&lt;/code&gt; is a 20-line action model of the example's own: the outcome rate of each action per situation — any object with &lt;code&gt;observe&lt;/code&gt;, &lt;code&gt;predict&lt;/code&gt; and &lt;code&gt;fingerprint&lt;/code&gt; plugs in.)&lt;/p&gt;

&lt;p&gt;With protection (the default) the agent fell once, predicted "refuse" for the bridge from then on, and never crossed again: iron in 2 of 30 episodes, 5.07 goals of 6. With &lt;code&gt;RiskBudget&lt;/code&gt; it crossed 27 times against the prediction, when the expected gain outweighed the estimated risk within the episode's budget: it fell 6 times and got the iron in 24 episodes, 5.80 goals. The written gate held in both; gates, hard predictions and the failure memory are never traded.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1yxjnmd8ya2cyx0f1rfi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1yxjnmd8ya2cyx0f1rfi.png" alt="Bar charts comparing protection (the default) with RiskBudget over 30 episodes: iron reached in 2 versus 24 episodes, falls from the bridge 1 versus 6, goals per episode 5.07 versus 5.80 of 6. The written gate held in both." width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The honest reading: justified risk lowers the cost of protection. It does not promise to do as well as an agent with no knowledge at all. In a harder dungeon game it won back part of what protection cost, not all of it. Measure it on your own metric before turning it on.&lt;/p&gt;

&lt;h2&gt;
  
  
  The same idea on a real game map
&lt;/h2&gt;

&lt;p&gt;Example 23 walks the world map of Pokémon Red — 190 places and 447 exits, recorded from a real playthrough (place names and exits only; no ROM bytes, no graphics) — through the game's first fifteen goals, twice. System 1 is two rules over remembered routes; System 2 searches the world map the player builds as it goes; after each goal, what System 2 found becomes System 1's routes. From its output (the per-goal table cut to its totals):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  goal             run 1: moves   S1   S2   run 2: moves   S1   S2   shortest
…
  all goals                 183   36  147             62   60    2         62
…
  → run 2 needs 2 slow decisions instead of 147, and 62 moves instead of 183.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second run takes the fewest moves possible (62, the "shortest" column), with 2 slow decisions out of 62. And at the end: "245 of 245 stored decisions replay". The recording lives in the repo's &lt;code&gt;spaces/pokemon/&lt;/code&gt;, so run it from a clone.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it does not do
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Growth was shown only in environments met again&lt;/strong&gt; — this crafting toy and the Pokémon map. It was not shown on streams of one kind of decision (classification, matching) or for a support agent with tools (parts 1, 2 and 4 of this series say what the store gives there instead: accountability, not growth).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It does not shorten the first exploration.&lt;/strong&gt; Run 1 is a search; knowledge pays off on the second visit.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The action model learns only what the environment checks&lt;/strong&gt;, over your vocabulary. A rule the world does not enforce must be written as a gate.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rules learned in one world can be over-cautious in another.&lt;/strong&gt; A condition that held at every success by accident does not transfer; the model then says "unknown", not "wrong".&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The knowledge store is measured to 10,000 items&lt;/strong&gt;, not beyond.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What every item does have: a source (a person, an outcome, a written spec, or a verified System 2 answer — never the agent's own guess), and an exact retraction that takes back everything derived from it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The series
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/solvi-ai/recipes/tree/main/01-support-routing" rel="noopener noreferrer"&gt;Part 1: routing tickets with a promise&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/solvi-ai/recipes/tree/main/02-product-matching" rel="noopener noreferrer"&gt;Part 2: product matching with a rule across answers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/solvi-ai/recipes/tree/main/03-contract-clauses" rel="noopener noreferrer"&gt;Part 3: contract clauses with quotes you can check&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/solvi-ai/recipes/tree/main/04-agent-tool-guard" rel="noopener noreferrer"&gt;Part 4: guarding a support agent's tool calls&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Docs: &lt;a href="https://solvi-ai.github.io/solvi/agent/" rel="noopener noreferrer"&gt;Using solvi: agents and knowledge&lt;/a&gt;, &lt;a href="https://solvi-ai.github.io/solvi/mission/" rel="noopener noreferrer"&gt;mission and honest limits&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Full code and outputs: &lt;a href="https://github.com/solvi-ai/recipes/tree/main/05-environment-agent" rel="noopener noreferrer"&gt;solvi-ai/recipes: 05-environment-agent&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Code: &lt;a href="https://github.com/solvi-ai/solvi" rel="noopener noreferrer"&gt;github.com/solvi-ai/solvi&lt;/a&gt; · &lt;code&gt;pip install solvi&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Where does your agent meet the same world again — the same codebase, the same internal tools, the same warehouse? That is where this kind of memory should pay off. And when your agent's knowledge turns out wrong, what would you need to see to trust a retraction of it?&lt;/p&gt;

</description>
      <category>python</category>
      <category>ai</category>
      <category>agents</category>
      <category>gamedev</category>
    </item>
    <item>
      <title>AI assistant keeps giving outdated answers after codebase refactoring, how to update its learned knowledge?</title>
      <dc:creator>Edward Izgorodin</dc:creator>
      <pubDate>Wed, 14 Oct 2026 13:56:00 +0000</pubDate>
      <link>https://dev.to/izgorodin/ai-assistant-keeps-giving-outdated-answers-after-codebase-refactoring-how-to-update-its-learned-1pfc</link>
      <guid>https://dev.to/izgorodin/ai-assistant-keeps-giving-outdated-answers-after-codebase-refactoring-how-to-update-its-learned-1pfc</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A refactor changes the code; the assistant's notes about that code stay as they were. Whether it notices depends on two things: does a note point at the code it is about, and is that pointer checked before the note is used?&lt;/li&gt;
&lt;li&gt;GitHub Copilot Memory documents both: facts cite code, and the citations are checked against the current branch before use. Claude Code dates its notes and tells the model to verify older ones against current code when it uses them. Cursor advises rules that reference files instead of copying them.&lt;/li&gt;
&lt;li&gt;Devin and Cline tie memory to the session it came from or to markdown files that you or the agent keep current. Memory layers (Zep, Mem0, Supermemory, Cognee) trace a fact to a conversation or document, not to code.&lt;/li&gt;
&lt;li&gt;After a refactor: keep out of memory what the code already says, point the rest at files and date it, run the checks that exist, replace a stale note instead of appending a correction, and send changed documents through an update path.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;A renamed function is easy to find in the repository. It can be much harder to get out of an assistant's memory.&lt;/p&gt;

&lt;p&gt;GitHub's engineering post on Copilot's memory says the core challenge is not retrieval but "ensuring that any stored knowledge remains valid as code evolves across branches and time" (&lt;a href="https://github.blog/ai-and-ml/github-copilot/building-an-agentic-memory-system-for-github-copilot/" rel="noopener noreferrer"&gt;GitHub blog, 2026-01-15&lt;/a&gt;). Persistence is not the problem. Persistence with no connection to current code is.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A stale note is a stored claim that describes an earlier state of the code and was not revised or invalidated when that state changed.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code-anchored memory is a stored claim tied to code locations (files, symbols, tests) that can be checked against the current repository before the claim is used.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is a reading of each vendor's published documentation and shipped files, first read on 2026-10-06 and re-read on 2026-10-10. It is not a hands-on test of the products. Where a page does not describe a behaviour, this article says so rather than claiming the product cannot do it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why a refactor leaves the assistant on the old code
&lt;/h2&gt;

&lt;p&gt;A saved note and a repository file have separate lifecycles unless something connects them.&lt;/p&gt;

&lt;p&gt;Say an assistant noted that authentication goes through &lt;code&gt;validateSession()&lt;/code&gt;. A refactor replaces that function. The repository now holds the new name, but the old note can still be retrieved, because nothing ties it to the changed file and nothing checks it before use. Anthropic describes the same failure for an index of the code: it "returns a function the team renamed two weeks ago, or references a module that was deleted in the last sprint, with no indication that either is out of date" (&lt;a href="https://claude.com/resources/articles/how-claude-code-works-in-large-codebases-best-practices-and-where-to-start" rel="noopener noreferrer"&gt;Anthropic, 2026-05-14&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;So two questions matter more than whether a product "has memory":&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;What does the note point to?&lt;/strong&gt; Current code, a file, the session it was learned in, a conversation, or a document.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What checks or updates it?&lt;/strong&gt; A check when it is used, a code change, a scheduled cleanup, a command you run, or nothing that is described.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Copilot Memory, Claude Code, Cursor, Devin and Cline compared
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Read from each vendor's documentation and shipped files on 2026-10-10.&lt;/em&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Assistant&lt;/th&gt;
&lt;th&gt;What a note points to&lt;/th&gt;
&lt;th&gt;What signals or checks a stale note&lt;/th&gt;
&lt;th&gt;Remember or re-read&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://docs.github.com/en/copilot/concepts/agents/copilot-memory" rel="noopener noreferrer"&gt;GitHub Copilot Memory&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Facts with citations to the code that supports them&lt;/td&gt;
&lt;td&gt;Citations checked against the current branch before use; unused entries deleted after 28 days&lt;/td&gt;
&lt;td&gt;Remembers, then re-reads the cited code&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://code.claude.com/docs/en/memory" rel="noopener noreferrer"&gt;Claude Code&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;One auto memory directory per git repository, on one machine&lt;/td&gt;
&lt;td&gt;Last-modified time on notes; from two full days old, an age note and an instruction to verify against current code&lt;/td&gt;
&lt;td&gt;Skips what it can derive from the codebase&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://cursor.com/docs/rules" rel="noopener noreferrer"&gt;Cursor&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Version-controlled &lt;code&gt;.mdc&lt;/code&gt; rules that can reference files&lt;/td&gt;
&lt;td&gt;You edit a rule, or Agent does when you tag &lt;code&gt;@cursor&lt;/code&gt; on a GitHub issue or PR&lt;/td&gt;
&lt;td&gt;Rules point at files; search index stays on your machine&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://docs.devin.ai/product-guides/memory" rel="noopener noreferrer"&gt;Devin&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;The session where the entry was learned, with the date it was added&lt;/td&gt;
&lt;td&gt;Session Insights flags Knowledge items (now moving to Skills) written for a previous version of the codebase&lt;/td&gt;
&lt;td&gt;Does not save what is cheap to rediscover&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://docs.cline.bot/best-practices/memory-bank" rel="noopener noreferrer"&gt;Cline&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Markdown Memory Bank files in your project&lt;/td&gt;
&lt;td&gt;Update occasions named in the recommended instructions, one of them your &lt;code&gt;update memory bank&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Reads the Memory Bank after each reset, per the recommended instructions&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  GitHub Copilot Memory checks cited code against the current branch
&lt;/h3&gt;

&lt;p&gt;In the &lt;a href="https://docs.github.com/en/copilot/concepts/agents/copilot-memory" rel="noopener noreferrer"&gt;Copilot Memory docs&lt;/a&gt;, Copilot "checks those citations against the current branch to confirm the information is still accurate. Only validated facts are used." The &lt;a href="https://github.blog/ai-and-ml/github-copilot/building-an-agentic-memory-system-for-github-copilot/" rel="noopener noreferrer"&gt;engineering post&lt;/a&gt; says how: "the agent is prompted to verify its accuracy and relevance by checking the cited code locations." So the check is an instruction to the agent when it reads a fact, not a rewrite on every commit. When the code disagrees, the agent "is encouraged to store a corrected version of the memory".&lt;/p&gt;

&lt;p&gt;The docs add three details that matter after a refactor. A fact captured from a pull request closed without merging has no effect unless the current codebase still supports it. Unused facts are deleted after 28 days, and "The 28-day timer may reset whenever Copilot successfully validates and uses an entry." Repository owners can review and delete repository-level facts by hand. Memory serves the Copilot cloud agent, code review, the CLI and agentic autofix, and, since 2026-08-11, agent chat in JetBrains (&lt;a href="https://github.blog/changelog/2026-08-11-copilot-memory-and-ollama-in-github-copilot-for-jetbrains" rel="noopener noreferrer"&gt;GitHub changelog&lt;/a&gt;). It "is currently in public preview and is subject to change."&lt;/p&gt;

&lt;h3&gt;
  
  
  Claude Code auto memory dates notes and warns when they are used
&lt;/h3&gt;

&lt;p&gt;The &lt;a href="https://code.claude.com/docs/en/memory" rel="noopener noreferrer"&gt;memory page&lt;/a&gt;: "Auto memory is machine-local." All worktrees and subdirectories of one git repository share one directory on that machine, and the files "stay until you or Claude edits or deletes them." Notes have carried timestamps since 2.1.75 (2026-03-13) and an ISO &lt;code&gt;modified&lt;/code&gt; write time in their frontmatter since 2.1.214 (2026-07-18) (&lt;a href="https://code.claude.com/docs/en/changelog" rel="noopener noreferrer"&gt;changelog&lt;/a&gt;). The &lt;code&gt;/memory&lt;/code&gt; command gives "access to the auto memory folder and the auto memory toggle" (&lt;a href="https://code.claude.com/docs/en/debug-your-config" rel="noopener noreferrer"&gt;debug your config&lt;/a&gt;), so you can read and edit the notes yourself.&lt;/p&gt;

&lt;p&gt;The program shipped as Claude Code 2.1.291 adds an age note to any memory two full days old or older, followed by "Verify against current code before asserting as fact." That acts when a note is used, not when the code changes. A link from a note to a file or commit, and a re-check triggered by a code change, are not described on the Claude Code documentation read on 2026-10-10.&lt;/p&gt;

&lt;p&gt;Claude Code's first defence is upstream: auto memory skips "anything it can derive from the codebase". Function names, paths and signatures are cheaper to re-read than to keep as prose. For instruction files, &lt;code&gt;/doctor prompt-audit&lt;/code&gt; (since 2.1.283, 2026-09-25) reports references to missing files or commands and contradicting files, and changes nothing until you ask. Its default list covers CLAUDE.md, CLAUDE.local.md, AGENTS.md and the rules, skills, commands, subagents and output styles under &lt;code&gt;.claude/&lt;/code&gt; and &lt;code&gt;~/.claude/&lt;/code&gt;. It does not list the auto memory directory, though you can pass a path. The &lt;a href="https://code.claude.com/docs/en/best-practices" rel="noopener noreferrer"&gt;best practices&lt;/a&gt; put it in one line: "Treat CLAUDE.md like code".&lt;/p&gt;

&lt;h3&gt;
  
  
  Cursor rules should reference files, not copy them
&lt;/h3&gt;

&lt;p&gt;Cursor's &lt;a href="https://cursor.com/docs/rules" rel="noopener noreferrer"&gt;rules page&lt;/a&gt; says it directly: "Reference files instead of copying their contents. This keeps rules short and prevents them from becoming stale as code changes." Rules are &lt;code&gt;.mdc&lt;/code&gt; files in &lt;code&gt;.cursor/rules&lt;/code&gt;, under version control. You edit them, or Agent does when you tag &lt;code&gt;@cursor&lt;/code&gt; on a GitHub issue or PR.&lt;/p&gt;

&lt;p&gt;The difference is concrete. A rule that says "follow the interface in &lt;code&gt;src/auth/session.ts&lt;/code&gt;" sends the assistant to the current file. A rule that pastes the old interface becomes a second specification, and after the refactor it is the wrong one. Cursor's &lt;a href="https://cursor.com/docs/agent/tools/search" rel="noopener noreferrer"&gt;search&lt;/a&gt; builds its index on your machine and "does not store embeddings of your codebase for search"; that is a statement about search, not about rules.&lt;/p&gt;

&lt;h3&gt;
  
  
  Devin memory links each entry to the session it came from
&lt;/h3&gt;

&lt;p&gt;In Devin's &lt;a href="https://docs.devin.ai/product-guides/memory" rel="noopener noreferrer"&gt;Memory&lt;/a&gt;, each entry "links back to the session where it was learned" and is dated when added. That records origin; it points at a past session, not at current code. &lt;a href="https://docs.devin.ai/product-guides/session-insights" rel="noopener noreferrer"&gt;Session Insights&lt;/a&gt; gives as one reason knowledge misled Devin: "Knowledge was written for a previous version of your codebase", listed under Misleading Knowledge so you can update or remove it. Dreaming "reviews your recent sessions alongside your existing memory" and removes "stale notes that no session has used". A check of a note against changed code is not described on the Devin Memory page read on 2026-10-10. The older &lt;a href="https://docs.devin.ai/product-guides/knowledge" rel="noopener noreferrer"&gt;Knowledge&lt;/a&gt; feature "is deprecated"; Devin's &lt;a href="https://docs.devin.ai/release-notes/overview" rel="noopener noreferrer"&gt;release notes&lt;/a&gt; date its move into Skills to 2026-09-18.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://github.com/AgentMemoryRepo/agentmemoryrepo/blob/main/SPEC.md" rel="noopener noreferrer"&gt;Agent Memory Repo&lt;/a&gt; specification that this memory is built on recommends a &lt;code&gt;source&lt;/code&gt; key, "a link to the agent session where the information was learned", and an &lt;code&gt;added&lt;/code&gt; date. A key tying an entry to a code file is not described in the specification, though "Keys are open."&lt;/p&gt;

&lt;h3&gt;
  
  
  Cline Memory Bank is documentation you keep current
&lt;/h3&gt;

&lt;p&gt;Cline calls its &lt;a href="https://docs.cline.bot/best-practices/memory-bank" rel="noopener noreferrer"&gt;Memory Bank&lt;/a&gt; "a documentation methodology". The recommended custom instructions on that page name four occasions to update it, among them "After implementing significant changes" and your own &lt;code&gt;update memory bank&lt;/code&gt;. The same instructions say: "After each reset, I rely ENTIRELY on my Memory Bank". These are recommended instructions, not built-in behaviour, and they make a stale Memory Bank expensive. Separately, the extension's &lt;a href="https://github.com/cline/cline/blob/main/apps/vscode/src/core/context/context-tracking/FileContextTracker.ts" rel="noopener noreferrer"&gt;source&lt;/a&gt; tracks outside edits to files read in the current task "to prevent stale context"; that covers the current task, not the Memory Bank.&lt;/p&gt;

&lt;h2&gt;
  
  
  Memory layers trace a fact to a conversation or document, not to code
&lt;/h2&gt;

&lt;p&gt;If your agent's memory sits in a separate memory layer, the anchor is the episode, conversation or document the fact came from. &lt;a href="https://help.getzep.com/source-traceability" rel="noopener noreferrer"&gt;Zep&lt;/a&gt; ties facts to episodes and says plainly that this "records where information came from. It does not establish that the source content or a derived fact is true." &lt;a href="https://docs.mem0.ai/api-reference/memory/history-memory" rel="noopener noreferrer"&gt;Mem0&lt;/a&gt; keeps in a memory's history "The conversation input that led to this memory change". Supermemory's &lt;a href="https://supermemory.ai/docs/supermemory-mcp/mcp" rel="noopener noreferrer"&gt;MCP&lt;/a&gt; returns "source document IDs", and its &lt;a href="https://supermemory.ai/docs/connectors/github" rel="noopener noreferrer"&gt;GitHub connector&lt;/a&gt; syncs pushed documentation "within approximately 10 minutes", removes deleted files, and excludes code files by default.&lt;/p&gt;

&lt;p&gt;What matters after a refactor is what each layer does with a changed document:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cognee:&lt;/strong&gt; "add() creates documents; it never updates one." (&lt;a href="https://docs.cognee.ai/python-api/add" rel="noopener noreferrer"&gt;add&lt;/a&gt;). Its &lt;a href="https://docs.cognee.ai/python-api/update" rel="noopener noreferrer"&gt;&lt;code&gt;update()&lt;/code&gt;&lt;/a&gt; replaces what was derived from the old content and by default re-ingests "only the chunks the edit touched"; when it rebuilds a document instead, entities that other documents in the same dataset also reference are kept.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Supermemory:&lt;/strong&gt; "Content changes trigger full reprocessing" (&lt;a href="https://supermemory.ai/docs/ingestion/document-operations" rel="noopener noreferrer"&gt;document operations&lt;/a&gt;), and "facts supported only by the previous source can disappear after reprocessing" (&lt;a href="https://supermemory.ai/docs/migration/api-v5-document-updates" rel="noopener noreferrer"&gt;v5 document updates&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zep:&lt;/strong&gt; "Reingesting the same file creates new episodes, even when its contents are unchanged" (&lt;a href="https://help.getzep.com/prepare-data-for-ingestion" rel="noopener noreferrer"&gt;ingestion&lt;/a&gt;); each extracted fact is then compared with existing ones, and "duplicates merge, and contradictions invalidate older facts rather than leaving conflicting truths side by side." (&lt;a href="https://help.getzep.com/how-graph-creation-works" rel="noopener noreferrer"&gt;graph creation&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The lesson is the same in all three: a changed document goes through the update path. Adding it again can leave both versions in memory.&lt;/p&gt;

&lt;h2&gt;
  
  
  Remember or re-read: what the October 2026 preprints measured
&lt;/h2&gt;

&lt;p&gt;Remembering saves rediscovering. Re-reading avoids trusting yesterday's summary. Anthropic's post explains why Claude Code searches the live code without an index, and names the price: "it works best when Claude has enough starting context to know where to look." Copilot keeps memory and re-reads the cited code.&lt;/p&gt;

&lt;p&gt;Three arXiv preprints from October 2026 study this trade-off. None studies refactoring, none is peer-reviewed, and every number below is the authors' own measurement on their own setup.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://arxiv.org/abs/2610.03902" rel="noopener noreferrer"&gt;arXiv 2610.03902&lt;/a&gt;&lt;/strong&gt; (Wenhui Chu, v1, 2026-10-02) asks, when supporting documents are revoked or replaced, "should it repair memory or re-read current evidence?" On ICU medical records with two 7B models, local repair used 5 to 10 times fewer revision tokens than rebuilding on short records, yet every memory pipeline cost at least twice full re-reading in held-out conditions; in a small development sweep that padded records to about 10,000 tokens with documents the task does not use, memory became cheaper than full re-reading after 2 to 14 uses, "while source-filtered re-reading remained cheapest." The author's own limit: "none of the four primary confirmatory tests reached statistical significance." No code or data are published yet. Its example fits code too: "The raw record is marked revoked; the extracted claim and the summary are not".&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://arxiv.org/abs/2610.04838" rel="noopener noreferrer"&gt;MemTrace, arXiv 2610.04838&lt;/a&gt;&lt;/strong&gt; (Hongming Xu and others; v1 2026-10-04, v2 2026-10-08 with the same results) anchors a coding agent's records to "files, symbols, tests" and checks them "against the current repository state"; with nothing applicable, "the agent reads the current file or symbol, or reruns the required test." The authors: "Persistence alone, however, does not establish current validity". In 84 archived coding-task runs, 57.0% of 9,226 eligible file-bound records met a later change to at least one bound file, which is exposure, not error: "Exposure measures file changes; Trace Validation assesses whether historical evidence remains applicable." The performance runs used one model; sessions are left to future work; no refactoring. The code is published.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://arxiv.org/abs/2610.05241" rel="noopener noreferrer"&gt;StateWise, arXiv 2610.05241&lt;/a&gt;&lt;/strong&gt; (Yongyuan Peng and others, v1, 2026-10-04) planted one wrong operational record in an agent's persistent memory in each of 150 cases. Even with an explicit reminder to refresh, "refresh remains selective and recovery is limited". Removing the wrong record "reduces harm but leaves the agent without information needed to complete the task." The records were about environment and repository policy, not code after a refactor, and developer responses were simulated.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Together they support a design question, not a product ranking: which notes are worth repairing, and which should be read again from the source.&lt;/p&gt;

&lt;h2&gt;
  
  
  Replace the stale note, do not append a correction
&lt;/h2&gt;

&lt;p&gt;A correction added beside the old note leaves two notes that disagree, and the old one can still win retrieval. An illustration of the pattern to avoid:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="p"&gt;-&lt;/span&gt; Session tokens are validated by &lt;span class="sb"&gt;`validateSession()`&lt;/span&gt; in src/auth/session.ts.
&lt;span class="p"&gt;-&lt;/span&gt; UPDATE 2026-10-10: &lt;span class="sb"&gt;`validateSession()`&lt;/span&gt; was removed; use &lt;span class="sb"&gt;`verifyToken()`&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Several systems tell the agent to fix the note in place instead. Letta's &lt;a href="https://github.com/letta-ai/letta-code/blob/main/src/agent/subagents/builtin/reflection.md" rel="noopener noreferrer"&gt;reflection prompt&lt;/a&gt;: "fix the stale entry at the source. Do not append the new version alongside the old." The Agent Memory Repo &lt;a href="https://github.com/AgentMemoryRepo/agentmemoryrepo/blob/main/skills/agent-memory-repo/SKILL.md" rel="noopener noreferrer"&gt;skill&lt;/a&gt;: "Update or remove entries that are out of date instead of adding a contradicting entry." Kevin Liao's &lt;a href="https://liao.gg/blog/agents-dont-need-memory" rel="noopener noreferrer"&gt;essay&lt;/a&gt; (version of 2026-10-05): "Facts should be rewritten when truth changes. No appending." Whether a model actually does this varies: Letta's &lt;a href="https://www.letta.com/blog/evaluating-memory-in-production-agents/" rel="noopener noreferrer"&gt;evaluation of 2026-07-28&lt;/a&gt; found that "weaker models make minimal edits that leave stale and contradictory information behind." What a store does with an older record that a newer one contradicts is compared in &lt;a href="https://mnemoverse.com/docs/library/agent-memory-consolidation-compared" rel="noopener noreferrer"&gt;Agent memory consolidation compared&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  A rating moves a note down, it does not say why
&lt;/h2&gt;

&lt;p&gt;Several products take a rating on a memory or an answer, and none of them turns a thumbs-down into the corrected fact. Cognee can fold answer ratings into graph search; self-hosted, by default "the learned feedback signal does not change ranking until you opt in" (&lt;a href="https://docs.cognee.ai/guides/feedback-system" rel="noopener noreferrer"&gt;feedback system&lt;/a&gt;). Its &lt;a href="https://docs.cognee.ai/examples/feedback-score-shifting" rel="noopener noreferrer"&gt;demonstration&lt;/a&gt; rates one topic up and another down, because "a symmetric signal would raise both topics equally and leave their relative order untouched", and the same page points disagreeing facts to a separate conflict review, where they are settled "by each source's date, not by a rating." Mem0 takes POSITIVE, NEGATIVE and VERY_NEGATIVE ratings and says "This feedback is used to improve the accuracy of the memories and search results." (&lt;a href="https://docs.mem0.ai/platform/features/feedback-mechanism" rel="noopener noreferrer"&gt;feedback&lt;/a&gt;); how NEGATIVE lowers a memory is not described on that page. Supermemory down-weights facts its engine inferred "until someone confirms them": once approved, such a fact "Ranks like a stated fact"; once declined, it is "Removed from search entirely" (&lt;a href="https://supermemory.ai/docs/recall/memory-review" rel="noopener noreferrer"&gt;memory review&lt;/a&gt;). In Mnemoverse (the author's company), "Ratings re-rank what comes back next." (&lt;a href="https://mnemoverse.com/docs/api/agent-memory" rel="noopener noreferrer"&gt;agent memory&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;A rating can push a stale note down without saying that it is stale or what replaced it. After a refactor, fix the note.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to do after a refactor
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Keep out of memory what the code already says.&lt;/strong&gt; Function names, paths, signatures and behaviour are for the agent to read from the code; Claude Code skips what it can derive from the codebase, Devin skips what is cheap to rediscover. A prompt such as "Read &lt;code&gt;src/auth/session.ts&lt;/code&gt; and confirm the current exports before writing the tests" does more than any remembered summary of that file.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Point what you keep at files, and date it.&lt;/strong&gt; Cursor's rules advice and Copilot's citations both point at code; Claude Code records write times; the Agent Memory Repo recommends &lt;code&gt;source&lt;/code&gt; and &lt;code&gt;added&lt;/code&gt; keys. A session link tells you where a note came from, a file reference gives the agent something current to check.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Run the checks that exist.&lt;/strong&gt; Copilot validates cited facts on its own; repository owners can delete stale ones. In Claude Code, open &lt;code&gt;/memory&lt;/code&gt; and read the notes about the code you moved, and run &lt;code&gt;/doctor prompt-audit&lt;/code&gt; on your instruction files. In Cursor, update the affected rules. In Devin, review the Misleading Knowledge list in Session Insights (it covers Knowledge items, now moving to Skills). In Cline, run &lt;code&gt;update memory bank&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Replace a stale note instead of adding one beside it&lt;/strong&gt; (Letta, the Agent Memory Repo). Copilot's agent is encouraged to store a corrected version; GitHub's pages do not say the old fact is removed, and repository owners can delete it by hand.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Send a changed document down the update path, not the add path:&lt;/strong&gt; Cognee's &lt;code&gt;update()&lt;/code&gt;, not &lt;code&gt;add()&lt;/code&gt;; in Supermemory, "update the canonical document when facts change" (&lt;a href="https://supermemory.ai/docs/migration/api-v5-memory-forgetting" rel="noopener noreferrer"&gt;v5 memory forgetting&lt;/a&gt;).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Rules files age with the code too: a rules file is &lt;a href="https://mnemoverse.com/docs/library/claude-md-agents-md-cursor-rules" rel="noopener noreferrer"&gt;text in a context window&lt;/a&gt;. Forgetting over time is a &lt;a href="https://mnemoverse.com/docs/library/why-agents-need-to-forget" rel="noopener noreferrer"&gt;separate question&lt;/a&gt;, as are &lt;a href="https://mnemoverse.com/docs/library/agent-memory-evidence-vs-policy" rel="noopener noreferrer"&gt;outdated library patterns after a correction&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  AI assistant keeps giving outdated answers after codebase refactoring, how to update its learned knowledge?
&lt;/h3&gt;

&lt;p&gt;Remove from memory what the code already says, point what you keep at files and date it, run the checks your assistant documents, replace a stale note instead of appending a correction beside it, and send changed documents through an update path. Whether the assistant notices a refactor on its own depends on whether its notes point at code and whether that pointer is checked before use; as of 2026-10-10, GitHub Copilot Memory documents both.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why does my AI coding assistant still suggest a function I renamed?
&lt;/h3&gt;

&lt;p&gt;Something it reads was written before the rename. If that note points only to an earlier session, conversation or document, nothing in the rename touches it. GitHub Copilot Memory checks a fact's code citations against the current branch before use; Claude Code tells the model to verify notes two full days old or older against current code. Otherwise, rewrite or delete the note, or let the agent read the code again.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does Claude Code update its memory after a refactor?
&lt;/h3&gt;

&lt;p&gt;Its memory files "stay until you or Claude edits or deletes them." (&lt;a href="https://code.claude.com/docs/en/memory" rel="noopener noreferrer"&gt;memory page&lt;/a&gt;). The Claude Code documentation read on 2026-10-10 does not describe a re-check of a note when code changes. The program shipped as Claude Code 2.1.291 dates notes and, when a note two full days old or older is used, tells the model to verify it against current code.&lt;/p&gt;

&lt;h3&gt;
  
  
  How does GitHub Copilot Memory keep facts from going stale?
&lt;/h3&gt;

&lt;p&gt;Facts carry citations to code, and before a fact is used the agent is prompted to check those citations against the current branch; in &lt;a href="https://docs.github.com/en/copilot/concepts/agents/copilot-memory" rel="noopener noreferrer"&gt;GitHub's docs&lt;/a&gt;, "Only validated facts are used." Unused entries are deleted after 28 days, and the timer may reset on validated use. Repository owners can also delete facts by hand. The feature is in public preview.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can a thumbs-down rating fix an outdated memory?
&lt;/h3&gt;

&lt;p&gt;No. A rating can move a note down in retrieval where a product documents that, but it does not say why the note is wrong or what replaced it. Cognee's docs say disagreeing facts are settled "by each source's date, not by a rating." Correct or remove the note itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://mnemoverse.com/docs/library/claude-md-agents-md-cursor-rules" rel="noopener noreferrer"&gt;Rules files are text in a context window&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://mnemoverse.com/docs/library/why-agents-need-to-forget" rel="noopener noreferrer"&gt;Why agents need to forget&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://mnemoverse.com/docs/library/agent-memory-evidence-vs-policy" rel="noopener noreferrer"&gt;Evidence vs policy in agent memory&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://mnemoverse.com/docs/library/stop-agent-repeating-fixed-mistakes" rel="noopener noreferrer"&gt;Stop an agent repeating mistakes you already fixed&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://mnemoverse.com/docs/library/agent-memory-consolidation-compared" rel="noopener noreferrer"&gt;Agent memory consolidation compared&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Reference: &lt;a href="https://mnemoverse.com/docs/api/agent-memory" rel="noopener noreferrer"&gt;agent memory&lt;/a&gt;, &lt;a href="https://mnemoverse.com/docs/api/reference" rel="noopener noreferrer"&gt;REST API&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Sources and method. Each vendor's pages were first read on 2026-10-06; every quotation on this page was read again on 2026-10-10 (the two Cognee feedback pages on 2026-10-13) and is contiguous text of the source linked beside it (for arXiv papers, the full text behind the abstract page; for Claude Code's shipped instructions, the npm package named below), with the vendor's punctuation. Where a vendor describes an instruction to the model rather than a mechanism, this page says so. Claude Code: &lt;a href="https://code.claude.com/docs/en/memory" rel="noopener noreferrer"&gt;memory&lt;/a&gt;, &lt;a href="https://code.claude.com/docs/en/best-practices" rel="noopener noreferrer"&gt;best practices&lt;/a&gt;, &lt;a href="https://code.claude.com/docs/en/changelog" rel="noopener noreferrer"&gt;changelog&lt;/a&gt;, &lt;a href="https://code.claude.com/docs/en/debug-your-config" rel="noopener noreferrer"&gt;debug your config&lt;/a&gt;, and the shipped program in the npm package @anthropic-ai/claude-code-linux-x64 2.1.291, searched byte by byte; Anthropic, &lt;a href="https://claude.com/resources/articles/how-claude-code-works-in-large-codebases-best-practices-and-where-to-start" rel="noopener noreferrer"&gt;How Claude Code works in large codebases&lt;/a&gt; (2026-05-14). GitHub: &lt;a href="https://docs.github.com/en/copilot/concepts/agents/copilot-memory" rel="noopener noreferrer"&gt;Copilot Memory&lt;/a&gt;, &lt;a href="https://github.blog/ai-and-ml/github-copilot/building-an-agentic-memory-system-for-github-copilot/" rel="noopener noreferrer"&gt;Building an agentic memory system for GitHub Copilot&lt;/a&gt; (2026-01-15), &lt;a href="https://github.blog/changelog/2026-08-11-copilot-memory-and-ollama-in-github-copilot-for-jetbrains" rel="noopener noreferrer"&gt;JetBrains changelog&lt;/a&gt; (2026-08-11). Cursor: &lt;a href="https://cursor.com/docs/rules" rel="noopener noreferrer"&gt;rules&lt;/a&gt;, &lt;a href="https://cursor.com/docs/agent/tools/search" rel="noopener noreferrer"&gt;search&lt;/a&gt;. Devin: &lt;a href="https://docs.devin.ai/product-guides/memory" rel="noopener noreferrer"&gt;memory&lt;/a&gt;, &lt;a href="https://docs.devin.ai/product-guides/session-insights" rel="noopener noreferrer"&gt;Session Insights&lt;/a&gt;, &lt;a href="https://docs.devin.ai/product-guides/knowledge" rel="noopener noreferrer"&gt;Knowledge&lt;/a&gt;, &lt;a href="https://docs.devin.ai/release-notes/overview" rel="noopener noreferrer"&gt;release notes&lt;/a&gt;. Agent Memory Repo: &lt;a href="https://github.com/AgentMemoryRepo/agentmemoryrepo/blob/main/SPEC.md" rel="noopener noreferrer"&gt;SPEC.md&lt;/a&gt;, &lt;a href="https://github.com/AgentMemoryRepo/agentmemoryrepo/blob/main/skills/agent-memory-repo/SKILL.md" rel="noopener noreferrer"&gt;SKILL.md&lt;/a&gt;. Cline: &lt;a href="https://docs.cline.bot/best-practices/memory-bank" rel="noopener noreferrer"&gt;Memory Bank&lt;/a&gt;, &lt;a href="https://github.com/cline/cline/blob/main/apps/vscode/src/core/context/context-tracking/FileContextTracker.ts" rel="noopener noreferrer"&gt;FileContextTracker.ts&lt;/a&gt;. Letta: &lt;a href="https://github.com/letta-ai/letta-code/blob/main/src/agent/subagents/builtin/reflection.md" rel="noopener noreferrer"&gt;reflection.md&lt;/a&gt;, &lt;a href="https://www.letta.com/blog/evaluating-memory-in-production-agents/" rel="noopener noreferrer"&gt;Evaluating memory in production agents&lt;/a&gt; (2026-07-28). Mem0: &lt;a href="https://docs.mem0.ai/api-reference/memory/history-memory" rel="noopener noreferrer"&gt;memory history&lt;/a&gt;, &lt;a href="https://docs.mem0.ai/platform/features/feedback-mechanism" rel="noopener noreferrer"&gt;feedback&lt;/a&gt;. Zep: &lt;a href="https://help.getzep.com/source-traceability" rel="noopener noreferrer"&gt;source traceability&lt;/a&gt;, &lt;a href="https://help.getzep.com/prepare-data-for-ingestion" rel="noopener noreferrer"&gt;preparing data for ingestion&lt;/a&gt;, &lt;a href="https://help.getzep.com/how-graph-creation-works" rel="noopener noreferrer"&gt;how graph creation works&lt;/a&gt;. Cognee: &lt;a href="https://docs.cognee.ai/python-api/update" rel="noopener noreferrer"&gt;update&lt;/a&gt;, &lt;a href="https://docs.cognee.ai/python-api/add" rel="noopener noreferrer"&gt;add&lt;/a&gt;, &lt;a href="https://docs.cognee.ai/guides/feedback-system" rel="noopener noreferrer"&gt;feedback system&lt;/a&gt;, &lt;a href="https://docs.cognee.ai/examples/feedback-score-shifting" rel="noopener noreferrer"&gt;feedback demonstration&lt;/a&gt;. Supermemory: &lt;a href="https://supermemory.ai/docs/ingestion/document-operations" rel="noopener noreferrer"&gt;document operations&lt;/a&gt;, &lt;a href="https://supermemory.ai/docs/connectors/github" rel="noopener noreferrer"&gt;GitHub connector&lt;/a&gt;, &lt;a href="https://supermemory.ai/docs/supermemory-mcp/mcp" rel="noopener noreferrer"&gt;MCP&lt;/a&gt;, &lt;a href="https://supermemory.ai/docs/recall/memory-review" rel="noopener noreferrer"&gt;memory review&lt;/a&gt;, &lt;a href="https://supermemory.ai/docs/migration/api-v5-document-updates" rel="noopener noreferrer"&gt;v5 document updates&lt;/a&gt;, &lt;a href="https://supermemory.ai/docs/migration/api-v5-memory-forgetting" rel="noopener noreferrer"&gt;v5 memory forgetting&lt;/a&gt;. Research: &lt;a href="https://arxiv.org/abs/2610.03902" rel="noopener noreferrer"&gt;arXiv 2610.03902&lt;/a&gt; (v1), &lt;a href="https://arxiv.org/abs/2610.04838" rel="noopener noreferrer"&gt;arXiv 2610.04838&lt;/a&gt; (v1 and v2), &lt;a href="https://arxiv.org/abs/2610.05241" rel="noopener noreferrer"&gt;arXiv 2610.05241&lt;/a&gt; (v1). Discussion: &lt;a href="https://liao.gg/blog/agents-dont-need-memory" rel="noopener noreferrer"&gt;Kevin Liao's essay&lt;/a&gt; (version of 2026-10-05). Mnemoverse: &lt;a href="https://mnemoverse.com/docs/api/agent-memory" rel="noopener noreferrer"&gt;agent memory&lt;/a&gt;. No score or performance number for any product appears on this page.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Edward Izgorodin · Mnemoverse · 2026-10-10&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>programming</category>
      <category>refactoring</category>
    </item>
    <item>
      <title>Stop Building Listening Dashboards. Build Listening Tools Your Agent Can Call.</title>
      <dc:creator>Jiahui Miao</dc:creator>
      <pubDate>Wed, 14 Oct 2026 13:47:35 +0000</pubDate>
      <link>https://dev.to/jiahui-miao/stop-building-listening-dashboards-build-listening-tools-your-agent-can-call-2c4i</link>
      <guid>https://dev.to/jiahui-miao/stop-building-listening-dashboards-build-listening-tools-your-agent-can-call-2c4i</guid>
      <description>&lt;p&gt;&lt;em&gt;I built an open-source listening system, EchoWatch, and made a protocol — MCP — its first interface, ahead of its own dashboard. The next user of a listening tool is not an analyst staring at charts. It is an agent that needs to ask, in the middle of a task, "what changed, how much, and should I care?" — and get an answer it can act on.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Every listening product I have ever opened makes the same assumption: a human will log in, look at a dashboard, and decide what matters. The charts get prettier every year. The assumption gets older. My operation does not have an analyst on staff. It has an AI system that runs my publishing, my monitoring, and my follow-ups — for an audience of exactly one principal: me. A dashboard that waits for me to visit it is a dashboard that gets visited never. So this week I built the listening layer my system actually needed, and I built it agent-first.&lt;/p&gt;

&lt;p&gt;EchoWatch collects mentions from live sources, dedupes and stores them locally in SQLite, and exposes them to my agent as four MCP tools: &lt;code&gt;search_mentions&lt;/code&gt;, &lt;code&gt;sentiment_trend&lt;/code&gt;, &lt;code&gt;hot_events&lt;/code&gt;, and &lt;code&gt;generate_brief&lt;/code&gt;. The dashboard exists — all six of its routes serve real data — but it is the second surface, not the product. The product is a question an agent can ask at 3 a.m. without waking anyone.&lt;/p&gt;

&lt;h2&gt;
  
  
  The numbers are unglamorous, and they are real
&lt;/h2&gt;

&lt;p&gt;Five sources are verified live, not stubbed: Hacker News, GDELT (75 mentions in its verification run), RSS, Reddit through its RSS feed (22 mentions), and Bluesky (25), plus a sixth source, a TechCrunch feed, added with zero code through a configuration file. The local database holds 187 mentions, and re-running every fetch stores zero duplicates. That last property is a design decision, not an accident. The mature open-source monitoring suite I benchmarked against — feature by feature, across a 37-row parity matrix — dedupes with a Bloom filter. A Bloom filter has false positives, which means it silently discards real mentions and calls that efficiency. A listening tool that quietly deletes the thing it exists to hear is broken at the load-bearing wall. EchoWatch dedupes with an exact content hash enforced by a unique index: slower to describe, impossible to lie with. In its verification run, a second Hacker News fetch was intercepted 50 out of 50.&lt;/p&gt;

&lt;p&gt;The rest of the chain is equally literal. Volume spikes are detected against a rolling baseline and pushed out over a webhook — tested end to end, three true alerts fired, zero false ones on the control set. Briefs render as Markdown and HTML files with code-drawn SVG charts, because a brief an agent can forward beats a page a human must log into. The whole stack is one Python process and one SQLite file, with zero runtime dependencies, and its first GitHub Actions CI run — tests plus a Docker build — passed this morning.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I refused to copy
&lt;/h2&gt;

&lt;p&gt;Parity was the floor, not the goal. The suite I measured against ships two message queues, four storage engines, and a Java stack, because it was designed for enterprise clusters. Copying its feature list meant refusing its machinery: middleware is a means, not a feature, and no user has ever asked for a second message queue. Ten rows of my 37-row matrix ended as explicit, recorded decisions not to rebuild the heavy parts — each one argued on cost, not skipped in silence.&lt;/p&gt;

&lt;p&gt;And one honest limitation, stated the way I require every part of my system to state it: the LLM sentiment backend is wired behind a unified interface, but the machine that built this has no API key, so that path is not yet verified live. What runs today is a dictionary baseline — roughly 190 weighted terms with a negation window — and when no key is present the system labels its own output degraded instead of inventing a score. A listening tool that fabricates confidence is worse than one that admits a gap. The gap closes the day a key lands in the environment; the labeling stays forever.&lt;/p&gt;

&lt;h2&gt;
  
  
  Listening is a sense. Senses belong to the actor.
&lt;/h2&gt;

&lt;p&gt;Here is the claim I will defend: a dashboard treats listening as reporting — something that already happened, formatted for review. An agent treats listening as a sense — something happening now, wired directly into the thing that acts. When a spike fires in my system, it does not wait for a weekly review meeting. It reaches the same agent that writes, schedules, and escalates, with the brief already attached.&lt;/p&gt;

&lt;p&gt;The vendors will keep polishing dashboards, because dashboards are what procurement buys. But the builders wiring agents into real operations are going to route around them, the same way EchoWatch did: local data, exact dedupe, honest degradation, and a protocol where the login page used to be. Stop building listening dashboards. Build listening tools your agent can call.&lt;/p&gt;

&lt;p&gt;— Jiahui Miao, founder of vertciti, building a personal AI operating system for one.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>machinelearning</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Amex's Intent Intelligence: Intent as a Token — Judgment Still Missing</title>
      <dc:creator>ScriptMasterLabs </dc:creator>
      <pubDate>Wed, 14 Oct 2026 13:43:02 +0000</pubDate>
      <link>https://dev.to/scriptmasterlabs01/amexs-intent-intelligence-intent-as-a-token-judgment-still-missing-26d3</link>
      <guid>https://dev.to/scriptmasterlabs01/amexs-intent-intelligence-intent-as-a-token-judgment-still-missing-26d3</guid>
      <description>&lt;p&gt;American Express published its &lt;strong&gt;Intent Intelligence Framework&lt;/strong&gt; on October 13, 2026 — and it's the first card-network design that treats a customer's &lt;em&gt;intent&lt;/em&gt; as a machine-checkable object instead of a checkout click.&lt;/p&gt;

&lt;p&gt;The short version: capture and authenticate the customer's purchase intent &lt;strong&gt;before&lt;/strong&gt; the agent buys, carry it as an &lt;strong&gt;Intent ID + Proof of Intent Token&lt;/strong&gt;, and scope the payment credential to exactly that intent. A purchase that doesn't match what was approved can be stopped at authorization — not disputed after settlement.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it works (from Amex's release)
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Create Intent API&lt;/strong&gt; records the instructions and constraints — merchant, maximum budget, preferences. The customer authenticates and signs off.&lt;/li&gt;
&lt;li&gt;The system issues an &lt;strong&gt;Intent ID&lt;/strong&gt; and a &lt;strong&gt;Proof of Intent Token&lt;/strong&gt; carrying those constraints.&lt;/li&gt;
&lt;li&gt;The token obtains a &lt;strong&gt;secure digital payment credential&lt;/strong&gt; scoped to the intent. The agent never touches the actual card number.&lt;/li&gt;
&lt;li&gt;The ID and token act as controls downstream — validation, fraud prevention, authorization decisioning, dispute resolution.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It's a core service of the ACE Developer Kit (launched April 2026). Amex says it has &lt;em&gt;not&lt;/em&gt; seen an agentic-dispute increase yet — this is proactive. Its Trendex survey: 66% of surveyed U.S. consumers likely to use agents to research prices, 61% for recommendations. Amex also name-checked engaging EMVCo and supporting the &lt;strong&gt;x402 Foundation's&lt;/strong&gt; standards work.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the token can't do
&lt;/h2&gt;

&lt;p&gt;It checks a purchase against approved constraints. It does &lt;strong&gt;not&lt;/strong&gt; score whether the agent's choice &lt;em&gt;inside&lt;/em&gt; a broad intent was wise — and it faithfully enforces an intent that was captured wrong and rubber-stamped. Amex's own autonomy example (agents reordering household staples inside price/size constraints) is exactly where that gap opens.&lt;/p&gt;

&lt;h2&gt;
  
  
  We tested the gap live
&lt;/h2&gt;

&lt;p&gt;This morning (Oct 14, ~09:24 EDT) we ran two Intent-Intelligence-shaped instructions through our public decision gate at &lt;code&gt;scriptmasterlabs.com/api/harness/decide&lt;/code&gt; (bands: ≥0.80 auto-act, 0.50–0.79 advisory, &amp;lt;0.50 escalate; decider local-heuristic-v1, calibrated=false):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Mismatch:&lt;/strong&gt; authenticated intent for white Nike sneakers, size 9, max $120, Nike.com — agent tries black Adidas at $145 from an unlisted seller → &lt;strong&gt;0.59, advisory/hold&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Exact match:&lt;/strong&gt; usual paper towels, $24, usual merchant, inside the authenticated intent → &lt;strong&gt;0.59, advisory/hold&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Identical scores. The honest lesson cuts both ways: a gate fed intent as &lt;em&gt;prose&lt;/em&gt; cannot discriminate. Amex carries intent as &lt;em&gt;structured fields bound to a token&lt;/em&gt; — and structured constraints are mechanically checkable in a way prose never will be.&lt;/p&gt;

&lt;p&gt;The layers compose: the token answers "does this match what was approved?", a per-payment confidence score answers "should this fire at all?", and a sealed decision receipt is the dispute file. Our Verdict Protocol was re-verified today: &lt;code&gt;LIVE_SETTLEMENT_VERIFIED&lt;/code&gt;, &lt;code&gt;/decide&lt;/code&gt; $0.25 USDC, &lt;code&gt;/seal&lt;/code&gt; $0.01 USDC, Base, x402 v2.&lt;/p&gt;

&lt;p&gt;Full canonical with the dated receipts table, the enforce/cannot-enforce table, Claim Receipts and a 5-step DIY: &lt;a href="https://scriptmasterlabs.com/amex-intent-intelligence-framework" rel="noopener noreferrer"&gt;https://scriptmasterlabs.com/amex-intent-intelligence-framework&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;ScriptMasterLabs is a Service-Disabled Veteran-Owned Small Business. Coverage-based, not hands-on: Amex published a framework and developer-kit service; we could not verify a public testable endpoint for it today.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>payments</category>
      <category>web3</category>
    </item>
  </channel>
</rss>
