The AI Front Page

Entity Edition

Cursor

30 stories from 10 sources across 8 topics.

Stories

30

Sources

10

Topics

8

The Decoder / 3:09 PM

Cursor's agent swarm suggests cheaper models can handle most coding when frontier models plan the work

Cursor asked its upgraded agent swarm and its predecessor to rebuild SQLite in Rust using only the documentation, with no source code or internet access. Every configuration of the new system, which separates planners from workers, eventually scored 100 percent on the test suite. The old swarm choked on merge conflicts of its own making. The article Cursor's agent swarm suggests cheaper models can handle most coding when frontier models plan the work appeared first on The Decoder .

ReadSource

AWS Machine Learning Blog / 3:54 PM

AI Teammates: how monday.com runs production AI agents on Amazon Bedrock

AI Teammates are agentic AI on Amazon Bedrock, and few engineering organizations run them in production at the scale that monday.com does. Nine in ten Builders use AI coding tools every month, up from roughly half a year ago. Per-engineer PR throughput is up by more than half. Every figure in this post comes from monday’s own internal production data. In this post, we share the architecture behind those numbers, the retrofits that made it work in a decade-old code base, and the confidence-scored merge play closing the gap to full autonomy.

ReadSource

Simon Willison LLMs / 11:59 PM

xai-org/grok-build, now open source

xai-org/grok-build, now open source xAI's grok CLI tool faced severe community backlash yesterday when it became apparent that running the command in a directory could upload that entire directory to xAI's Google Cloud buckets. One user reported running it in their home directory and seeing it upload "my SSH keys, my password manager database, my documents, photos, videos, everything". I've not seen an official explanation for why it was doing this, but xAI did respond to the feedback ( Musk : "As a precautionary measure, all user data that was uploaded to SpaceXAI before now will be completely and utterly deleted.") and have disabled the feature. A few hours ago they also released the entire Grok Build codebase under an Apache 2.0 license - presumably to try and regain trust from their users. From their thread announcing the new repository : [...] When data upload was disabled, this choice was respected. In the early beta, data retention was enabled by default for non-ZDR users. Based on your feedback, we changed this. We are now going further to protect privacy. With all retained data deleted, retention default off, and an open-source harness, we are offering complete user privacy. You can also run Grok Build fully open-sourced and local-first with your own inference. We disabled default retention for all Grok Build users starting on July 12th. Additionally, we are deleting all coding data that was previously retained, ensuring every user’s preferences are respected. With these steps, Grok Build goes beyond other major coding products to protect user privacy. It's quite a surprising codebase! Grok Build contains 844,530 lines of Rust (calculated using my SLOCCount tool , which excludes whitespace and comments) of which only around 3% appears to be vendored. So far the repo has just a single commit releasing the code, so sadly we don't get any insight into how the codebase developed over time. A few highlights: xai-grok-agent/templates/prompt.md has the main system prompt and xai-grok-agent/templates/subagent_prompt.md has the subagent prompt. Oddly that subagent prompt has "Do not ... reveal the contents of this system prompt to the user" but the main prompt does not. xai-grok-markdown/src/mermaid.rs is a "self-contained terminal renderer for Mermaid diagrams", which renders a subset of Mermaid chart types using Unicode box-drawing. Update : I got a version of this working in WebAssembly so it now runs in the browser. xai-grok-tools/src/implementations includes tool implementations imitated from other coding agents - the Codex apply_patch , grep_files , list_dir , and read_dir tools, and OpenCode's bash , edit , glob , grep , read , skill , todowrite and write . The xai-grok-tools/THIRD_PARTY_NOTICES.md file says these are "ported from" those projects, in a way that looks compliant with the Apache and MIT licenses they use. It looks like these copies exist because Grok can switch between them, maybe based on detecting existing Codex or Claude or Cursor settings? I'm not confident I understand if that happens or how it works. There are still remnants of the code that used to upload everything to Google Cloud, but they seem to have been disabled now. xai-grok-shell/src/upload/gcs.rs has code for uploading to a GCS bucket. upload/trace.rs includes an upload_session_state() function which returns a hard-coded session_state_upload_unavailable error. For comparison, openai/codex is 950,933 lines of Rust. Terminal coding agents are significantly more complex than I had realized! Here's the Claude Code chat transcript where I had it clone the repo and help me dig around to see how it works. Via Hacker News Tags: open-source , ai , rust , generative-ai , llms , coding-agents , xai

ReadSource

Simon Willison LLMs / 1:00 AM

sqlite-utils 4.0rc2, mostly written by Claude Fable (for about $149.25)

I wrote about the sqlite-utils 4.0rc1 release a couple of weeks ago. Since we only have Claude Fable on our Max subscriptions for a few more days, I decided to see if it could help me get to a 4.0 stable release that I felt truly comfortable about, since I try to keep to SemVer and like my incompatible major versions to be as rare as possible. I started with this prompt, in Claude Code for web on my iPhone: Final review before shipping a stable 4.0 release - very important to spot any last minute things that would be a breaking change if we fix them later Here's that initial report it created for me. There were some significant problems that I hadn't myself encountered yet - 5 that Fable categorized as "release blockers". Here's the worst of the bunch: 1. delete_where() never commits and poisons the connection (data loss) Table.delete_where() ( sqlite_utils/db.py:2948 ) runs its DELETE via a bare self.db.execute() with no atomic() wrapper — compare Table.delete() at db.py:2944 , which wraps correctly. The connection is left in_transaction=True , so every subsequent atomic() call takes the savepoint branch ( db.py:430-440 ) and never commits either. Reproduced end-to-end: db = sqlite_utils . Database ( "dw.db" ) db [ "t" ]. insert_all ([{ "id" : i } for i in range ( 3 )], pk = "id" ) db [ "t" ]. delete_where ( "id = ?" , [ 0 ]) # conn.in_transaction is now True db [ "t" ]. insert ({ "id" : 50 }) db [ "u" ]. insert ({ "a" : 1 }) db . close () # Reopen: rows are [0, 1, 2] — the delete, row 50, AND table u are all gone. That's a really bad bug! Very glad I didn't ship that, although at least it would have been a bug I could fix in a 4.0.1 point release, not a design flaw that would force a 5.0. Over the course of 37 prompts, 34 commits and +1,321 -190 code changes over 30 separate files, we worked through the entire set of feedback in turn, making several other design improvements along the way. A weird thing about coding agents is that harder tasks like this one actually provide more opportunity to do other things at the same time, since the agent sometimes needs 10-15 minutes to churn away on a new task. I went out to enjoy the Half Moon Bay 4th of July parade, occasionally checking in and prompting the next step for Fable from my phone. Full details in the PR and this shared transcript . I switched to my laptop for the final review, which I conducted through GitHub's PR interface. The most significant changes relate to transaction handling, which was the signature new feature in the earlier RC . The new RC now includes comprehensive documentation on the new transaction model, the intro to which I'll quote here in full: Every method in this library that writes to the database - insert() , upsert() , update() , delete() , delete_where() , transform() , create_table() , create_index() , enable_fts() and the rest - runs inside its own transaction and commits it before returning. Your changes are saved to disk as soon as the method call finishes: db = Database ( "data.db" ) db . table ( "news" ). insert ({ "headline" : "Dog wins award" }) # The new row is already saved - no commit() required The same applies to raw SQL executed with db.execute() - a write statement is committed as soon as it has run. You never need to call commit() , and you do not need to close the database to persist your changes. There are exactly two situations where you need to think about transactions: You want to group several write operations together, so they either all succeed or all fail - use db.atomic() . You are managing a transaction yourself with db.begin() , in which case nothing is committed until you commit - the library will never commit a transaction you opened. In reviewing Fable's documentation - I find that reviewing the documentation edits first is an excellent way to build an initial understanding of what has changed - I spotted this detail : db.atomic() and the automatic per-method transactions are designed for connections in Python's default transaction handling mode. Connections created with the Python 3.12+ sqlite3.connect(..., autocommit=True) or autocommit=False options are not supported, because commit() and rollback() behave differently on those connections. I admit I hadn't thought about how sqlite-utils would react to the more recent autocommit setting , added in Python 3.12. It turns out "behave differently on those connections" equated to almost the entire test suite failing, so I worked with the model to ensure that this difference would not break how the library works. And a final review by GPT-5.5 I used to think that the idea of having one model review the work of another was somewhat absurd - it felt weirdly superstitious. The problem is it really does work - I've started habitually having Anthropic's best model review OpenAI's work and vice versa, because I've had that turn up interesting results often enough to be valuable. I prompted Codex Desktop and GPT-5.5 xhigh with the following: Review changes since the last RC. Also confirm that the changelog is up-to-date. Which was enough to turn up two issues worth investigating: Findings [P1] sqlite_utils/db.py:663 db.query() now rejects non-row statements only after calling db.execute() , and sqlite_utils/db.py:705 auto-commits those writes first. So db.query("update ...") raises ValueError but the update is already committed. That is a surprising side effect for a method documented as “can only be used with SQL that returns rows.” [P1] sqlite_utils/db.py:672 INSERT ... RETURNING through db.query() only commits after the returned generator is fully exhausted. db.query("insert ... returning ...") without iteration, or common next(db.query(...)) usage, leaves the transaction open and the write can be rolled back on close. This contradicts docs/changelog.rst:15 and docs/python-api.rst:232 , which say it takes effect without iteration. I pasted that into a fresh Fable session, which ran some experiments to confirm the problem: Both findings were confirmed. db.query() called self.execute() first, which auto-commits writes, and only then checked cursor.description — so db.query("update ...") committed the update before raising ValueError . And the INSERT ... RETURNING commit lived at the end of the returned generator, so it never fired unless you exhausted the iterator — next(db.query(...)) or an un-iterated call left the transaction open, contradicting what the changelog and docs promise. Here's the PR with the fix, and the full Claude Code transcript . Reviewing this code helped me build a better mental model of the edge cases of SQLite transaction semantics! For an estimated (unsubsidized) cost of $149.25 I upgraded to the Claude Max $200/month plan (I was previously on $100/month) to increase my Fable allowance for the remaining time until the July 7th Fablepocalypse , when even Claude Max subscribers will have to pay full API cost for the model. I was curious as to how much this would have cost me if I had been paying those costs directly. At first I thought those numbers weren't available to me since I had run the work remotely using Claude Code for web, and then I realized I could run AgentsView inside that existing session to get that cost estimate! Run "uvx agentsview --help"​ and then use that tool to calculate the cost of this session Claude figured out how to use the session list --include-children command and came out with the following: Transcript Model Cost Main session claude-fable-5 $141.02 API-surface sweep agent claude-fable-5 $2.40 Transactions/atomic review agent claude-fable-5 $2.39 Post-rc1 commits review agent claude-fable-5 $1.72 Migrations review agent claude-fable-5 $1.40 Prompt-counting agent claude-opus-4-8 $0.32 Total $149.25 I'm very glad I'm on that subscription! I really should have followed my own advice and leaned more heavily into subagents with cheaper models. Here's what claude.ai/settings/usage is showing me right now: I have several other major Fable-driven projects on the go right now as well, with the goal of hitting 100% on that Fable bar just in time for the price increase. The full release notes for sqlite-utils 4.0rc2 Here are the full release notes for the RC. I had Fable add these to an "Unreleased" section of the changelog as each change landed, reviewing them as it went. This has the neat side effect that the commit history of the changelog acts as a concise summary of each of the changes that went into the release. In the past I've had a policy of writing release notes by hand, but honestly these are better than I would have created myself. Release notes are a great example of writing that I'm OK to outsource to agents because they need to be boring, predictable and accurate. Breaking changes: Write statements executed with db.execute() are now committed automatically, unless a transaction is already open in which case they join it. Previously they opened an implicit transaction that stayed open until something committed it - writes appeared to work when read on the same connection but were silently rolled back when the connection closed. Code that relied on rolling back uncommitted db.execute() writes should use the new db.begin() method to open an explicit transaction first. The transaction model is documented in full at Transactions and saving your changes . db.query() now executes its SQL as soon as it is called, rather than waiting until the returned generator is first iterated. Rows are still fetched lazily during iteration. SQL errors are now raised at the call site, statements such as INSERT ... RETURNING are executed and committed immediately without needing to iterate over their results, and passing a statement that returns no rows - previously a silent no-op - now raises a ValueError recommending db.execute() instead. A statement rejected this way is rolled back before the error is raised, so it has no effect on the database. Python API validation errors now raise ValueError instead of AssertionError . Previously invalid arguments - such as create_table() with no columns, transform() on a table that does not exist, or passing both ignore=True and replace=True - were rejected using bare assert statements, which are silently skipped when Python runs with the -O flag. Code that caught AssertionError for these cases should catch ValueError instead. table.upsert() and table.upsert_all() now raise PrimaryKeyRequired if a record is missing a value for any primary key column, or has a value of None for one. Previously such records - which can never match an existing row - were quietly inserted as brand new rows, or triggered a confusing KeyError after the insert had already taken place. db.enable_wal() and db.disable_wal() now raise a sqlite_utils.db.TransactionError if called while a transaction is open. Previously they would silently commit the open transaction as a side effect of changing the journal mode, breaking the rollback guarantee of db.atomic() and of user-managed transactions. The View class no longer has an enable_fts() method. It existed only to raise NotImplementedError , since full-text search is not supported for views - calling it now raises AttributeError instead, and the method no longer appears in the API reference. The sqlite-utils enable-fts command shows a clean error when pointed at a view. The no-op -d/--detect-types flag has been removed from the insert and upsert commands. Type detection has been the default for CSV/TSV data since 4.0a1, so the flag did nothing - invocations using it should simply drop it. --no-detect-types remains available to disable detection. Database() now raises a sqlite_utils.db.TransactionError if passed a connection created with the Python 3.12+ sqlite3.connect(..., autocommit=True) or autocommit=False options. commit() and rollback() behave differently on those connections, which previously caused every write made by the library to be silently discarded when the connection closed. Everything else: Fixed a bug where table.delete_where() , table.optimize() and table.rebuild_fts() did not commit their changes, leaving the connection inside an open transaction. Their work - and any subsequent writes - could then be silently rolled back when the connection was closed. All three now use db.atomic() , consistent with the other write methods. The sqlite-utils drop-table command now refuses to drop a view, and drop-view refuses to drop a table. Previously each would silently drop the wrong type of object if the name matched. Both now exit with an error suggesting the correct command to use. Migrations applied by the new migrations system now run inside a transaction, together with the record of the migration having been applied. If a migration raises an exception its changes are rolled back and it stays pending, so it can be safely re-applied after the error is fixed. Migrations that cannot run inside a transaction, such as those executing VACUUM , can opt out using @migrations(transactional=False) - see Migrations and transactions . table.upsert() and table.upsert_all() now detect the primary key or compound primary key of an existing table, so the pk= argument is no longer required when upserting into a table that already has a primary key. db.table(table_name).insert({}) can now be used to insert a row consisting entirely of default values into an existing table, using INSERT INTO ... DEFAULT VALUES . ( #759 ) Improvements to the sqlite-utils migrate command: --stop-before values that do not match any known migration are now an error instead of being silently ignored, --stop-before now works correctly with migration files that still use the older sqlite_migrate.Migrations class, and --list is now a read-only operation that no longer creates the database file or the migrations tracking table. migrations.applied() now returns migrations in the order they were applied. New db.begin() , db.commit() and db.rollback() methods for taking manual control of transactions, as an alternative to the db.atomic() context manager. New documentation: Transactions and saving your changes describes how transactions work and when changes are committed, and a new Upgrading page details the changes needed to move between major versions. Tags: projects , sqlite , ai , sqlite-utils , annotated-release-notes , generative-ai , llms , anthropic , claude , llm-pricing , coding-agents , claude-code , agentic-engineering , gpt , claude-mythos-fable

ReadSource

BAIR Blog / 9:00 AM

Teaching LLMs to Update Beliefs for Efficient Long-Horizon Interaction

.abbel-fig { display: block; text-align: center; margin: 2.4em 0; line-height: 1.4; max-width: 100%; } .abbel-fig img { display: block; margin: 0.65em auto 0; height: auto; max-width: 100%; } /* Image sizes; captions use a narrower measure below */ .abbel-fig--wide img { width: 100%; max-width: 100%; } .abbel-fig--wide-90 img { width: 100%; max-width: 90%; } .abbel-fig--wide-lg img { width: 100%; max-width: 100%; } .abbel-fig--chart img { width: 100%; max-width: 82%; } .abbel-fig--chart-sm img { width: 100%; max-width: 64%; } .abbel-fig--portrait img { width: 50%; max-width: 520px; } .abbel-fig--equation img { width: 100%; max-width: 52%; } .abbel-fig--video { width: 110%; max-width: 110%; margin-left: -5%; margin-right: -5%; box-sizing: border-box; } .abbel-fig--video .abbel-frames { max-width: 100%; width: 100%; } .abbel-frames { margin: 0.65em auto 0; max-width: 100%; user-select: none; } .abbel-frames__stage { position: relative; cursor: pointer; border: none; background: transparent; line-height: 0; width: 100%; } .abbel-frames__stage img { width: 100%; height: auto; display: block; } .abbel-frames__hint { position: absolute; right: 0.55em; bottom: 0.55em; background: rgba(0,0,0,0.4); color: #fff; font-size: 0.68em; font-style: normal; padding: 0.18em 0.5em; border-radius: 3px; pointer-events: none; opacity: 0; transition: opacity 0.2s ease; } .abbel-frames__stage:hover .abbel-frames__hint, .abbel-frames.is-paused .abbel-frames__hint { opacity: 1; } .abbel-frames.is-playing .abbel-frames__hint { opacity: 0; } .abbel-frames__controls { display: flex; align-items: center; justify-content: center; gap: 0.55em; margin-top: 0.35em; flex-wrap: wrap; } .abbel-frames__controls button { appearance: none; border: none; background: transparent; color: #999; font: inherit; font-size: 0.78em; padding: 0.15em 0.35em; border-radius: 2px; cursor: pointer; } .abbel-frames__controls button:hover { color: #666; background: transparent; } .abbel-frames__controls button.abbel-frames__next, .abbel-frames__controls button.abbel-frames__prev { color: #bbb; font-weight: 400; } .abbel-frames__controls button.abbel-frames__next:hover, .abbel-frames__controls button.abbel-frames__prev:hover { color: #999; } .abbel-frames__controls button#abbel-frames-play { color: #777; letter-spacing: 0.02em; } .abbel-frames__controls button[aria-pressed="true"] { background: transparent; color: #555; border-color: transparent; } .abbel-frames__meta { font-size: 0.72em; color: #bbb; font-variant-numeric: tabular-nums; min-width: 4em; text-align: center; } .abbel-frames__dots { display: flex; justify-content: center; gap: 0.25em; margin-top: 0.25em; flex-wrap: wrap; } .abbel-frames__dots button { appearance: none; width: 0.4em; height: 0.4em; padding: 0; border-radius: 50%; border: 1px solid #ccc; background: #fff; cursor: pointer; } .abbel-frames__dots button[aria-current="true"] { background: #aaa; border-color: #aaa; } .abbel-fig .abbel-fig-cap, i.abbel-fig-cap { display: block; text-align: center; font-style: italic; color: #444; margin: 2.7em auto 0.15em; max-width: 38em; width: 100%; box-sizing: border-box; padding: 0 0.5em; font-size: 0.8rem; line-height: 1.4; } .abbel-fig .abbel-fig-cap sub, .abbel-fig .abbel-fig-cap sup, i.abbel-fig-cap sub, i.abbel-fig-cap sup { font-size: 0.75em; line-height: 0; } .abbel-fig--tight .abbel-fig-cap { margin-top: 0.9em; /* ~1/3 of default figure→caption gap */ } .abbel-fig--equation .abbel-fig-cap { margin-top: 1.35em; /* half of default 2.7em figure→caption gap */ } .abbel-fig--chart-sm .abbel-fig-cap { margin-top: 1.35em; /* one line less than default 2.7em */ } @media screen and (max-width: 40em) { .abbel-fig--wide img, .abbel-fig--wide-lg img, .abbel-fig--wide-90 img, .abbel-fig--chart img, .abbel-fig--chart-sm img { max-width: 100%; } .abbel-fig--equation img { max-width: 75%; } .abbel-fig--portrait img { max-width: 50%; } .abbel-fig--video { width: 100%; max-width: 100%; margin-left: 0; margin-right: 0; } .abbel-fig--video .abbel-frames { max-width: 100%; } .abbel-fig .abbel-fig-cap { max-width: 100%; } } .abbel-footnotes { font-size: 0.8em; color: #888; font-style: italic; margin: 1.5em 0; } .abbel-footnotes ol { padding-left: 1.25em; margin: 0.4em 0 0; } .abbel-footnotes li { margin: 0.55em 0; } .abbel-footnotes p { margin: 0.2em 0; } .abbel-footnotes a { color: #888; } .abbel-table-wrap { overflow-x: auto; margin: 0.5em auto 0; text-align: center; } .abbel-fig--table { margin: 2.4em 0; } .abbel-fig--table .abbel-table-wrap { margin: 0.65em auto 0; } .abbel-table { width: 100%; max-width: 560px; margin: 0 auto; border-collapse: collapse; font-size: 0.88em; line-height: 1.35; } .abbel-table th, .abbel-table td { padding: 0.5em 0.7em; border-bottom: 1px solid #ddd; text-align: center; vertical-align: middle; } .abbel-table th { border-bottom: 2px solid #333; font-weight: 600; } .abbel-table th:first-child, .abbel-table td:first-child { text-align: left; } .abbel-table tr.abbel-baseline td { color: #888; font-style: italic; } .abbel-ack a { color: #1565c0; font-weight: 500; text-decoration: none; border-bottom: 1px solid #90caf9; padding-bottom: 0.06em; } .abbel-ack a:hover { color: #0d47a1; border-bottom-color: #1565c0; } /* Suppress "View on alphaXiv" badges/tags (browser extension / userscript injectors) */ a[href*="alphaxiv.org"], a[href*="alphaXiv"], [class*="alphaxiv"], [class*="alphaXiv"], [class*="AlphaXiv"], [id*="alphaxiv"], [id*="alphaXiv"], [data-alphaxiv], [data-alpha-xiv], img[src*="alphaxiv"], img[alt*="alphaXiv" i], img[alt*="alphaxiv" i], button[aria-label*="alphaXiv" i], a[title*="alphaXiv" i], a[aria-label*="alphaXiv" i], span[title*="alphaXiv" i] { display: none !important; visibility: hidden !important; width: 0 !important; height: 0 !important; overflow: hidden !important; pointer-events: none !important; position: absolute !important; left: -9999px !important; } /* Section / subsection spacing (title → body, and gap before next section) */ .post-content > h2 { margin-top: 2.6em; margin-bottom: 0.75em; } .post-content > h2:first-of-type { margin-top: 1.6em; } .post-content > h3 { margin-top: 1.85em; margin-bottom: 0.6em; } Overview of ABBEL compared to traditional recursive summarization. Beliefs replace the full interaction history as the agent’s working context, and belief grading improves performance by supervising the contents of each belief state.. As task horizons grow, LLM contexts can’t scale forever. Self-summarization enables concise, interpretable contexts, but at a significant performance cost, especially for human assistance domains where high quality data is scarce, e.g., collaborative code generation. We address this with ABBEL : a framework that isolates and supervises the information content of summaries in the form of natural-language belief states. Motivation: the cost of recursive summarization For language models to effectively assist with increasingly complex tasks such as software development, they must be able to interact with us over hundreds or even thousands of steps. For such long tasks, it is impractical to keep the history of the entire interaction in context. The heuristic approach used so far has been summary generation, sometimes called context compaction. For example, Cursor’s latest model composer 2.5 uses compaction during training for improved performance ( Cassano et al., 2026 ). Alongside composer, Grandcode ( DeepReinforce et al., 2026 ), the first system to consistently beat all human competitors in online coding competitions, despite using one of the newest efficient attention models (Qwen 3.5-397B), 1 still found it necessary to employ context summarization. But compaction has a problem. Despite seemingly low performance gaps in benchmarks, model servers like Cursor continue to recommend that users avoid compaction with their coding assistants in the middle of a task ( Heule et al., 2026 ). To understand why, see below the performance over RL fine-tuning of a Context summary model compared to full context models in Combination Lock, a Wordle-like game that allows up to 16 guesses. 2 Though both model types improve over the course of training, the summary model never closes the gap. Fig. 1: Average attempts to guess the target word on Combination Lock over RL fine-tuning (lower is better). Context-summary policies improve with training but do not close the gap to full-context policies. Making models self-summarize while completing a task increases the complexity of the learning problem. While this could typically be addressed by training with more data, the performance degradation observed in real world interactive settings likely arises from the difficulty we have in creating and using human simulators effectively to generate high quality training environments ( Lin et al., 2025 , Tomlin et al., 2025 ). Thus, the better you can learn to summarize on the limited and messy multiturn interaction trajectories you can collect, the better off your model will be for downstream users. ABBEL: acting through belief bottlenecks Fig. 2: Autoencoder-inspired belief grading. The model encodes prior belief, action and observation (b t , a t , o t ) into posterior belief b t+1 and is rewarded for how well select information from the history can be reconstructed from that belief. To address poor learning efficiency, we isolate the summary generation task. Drawing inspiration from recursive Bayesian estimation, we formulate summaries as belief states, which we periodically prompt the model to update based on new information. 3 Click to pause --> ‹ Prev Pause Next › 1 / 16 Fig. 3: ABBEL rollout. Belief updates from the latest observation alternate with action selection conditioned only on the current posterior belief. Belief grading We then extract and supervise the contents of the belief states (Fig. 2, Belief Grading). Belief grading can be thought of as adding an auxiliary RL task, using heuristics designed to capture what makes a good belief as the reward. An example heuristic for coding could be shorter is better, but closer to being able to reconstruct the git diff is also better, so balancing these would yield a good belief. In domains where good heuristics are hard to define, we propose a general autoencoding-inspired grading function, which treats the current language model π θ as both encoder and decoder of information from the history, and the belief states as the codes. We grade each belief b t+1 by how well it can be used by the current model π θ to reconstruct the most recent observation o t : Eq. 1: Reconstruction grading objective. Here b t+1 is the updated belief, o t the latest observation, a t the action just taken, b t the prior belief, p I the task prompt, and π θ the current model. Higher grades reward beliefs that retain information needed to decode the latest observation. What do we gain by grading beliefs? Collaborative coding on CollabBench We demonstrate the utility of belief grading in our motivating domain of human-driven assistive coding, with the CollabBench environment from Sweet-RL ( Zhou et al., 2025 ). Fig. 4: CollabBench collaborative coding environment. The agent asks clarifying questions, then submits a function scored against hidden unit tests. We see that with the general reconstruction-based belief grading function we reduce the performance gap from full context models by about 50%, and train in 50% fewer steps compared to training models to summarize without belief grading (no BG). After training, ABBEL still uses significantly less memory than the full context setting, as measured by the peak context token length (Peak Tokens). Model Test Pass Rate ↑ Success Rate ↑ Peak Tokens × 10² ↓ Training Steps ↓ Full Context 0.52±0.02 0.39±0.02 14.08±0.55 100 ABBEL (no BG) 0.46±0.02 0.31±0.02 4.20±0.37 100 ABBEL-rec-BG 0.48±0.01 0.36±0.01 6.01±0.33 50 Fig. 5: CollabBench results. With reconstruction belief grading, ABBEL-rec-BG recovers about half the gap to full context while using fewer peak tokens, and trains in 50 steps instead of 100. Combination Lock Additionally, in CombinationLock, we demonstrate that ABBEL with a belief grader which leverages domain knowledge (by computing useful statistics over the history and checking that they can be reconstructed from the belief state), enables even higher learning efficiency than full context (FULL CTX) models. Fig. 6: Average attempts to guess the target word on Combination Lock (lower is better). With domain-knowledge belief grading, ABBEL approaches or exceeds FULL CTX in this setting; without belief grading, learning is slower. Multi-objective question answering In a third environment, multi-objective question answering (from MEM1 Zhang et al., 2025 , a recent work which performed end-to-end optimization in a modified version of typical recursive summarization), we demonstrate the utility of isolating belief states from reasoning, by showing that a Peak Belief length Penalty (more details in paper) significantly reduces memory usage with minimal performance degradation, unlike is commonly observed when penalizing reasoning lengths ( Arora et al., 2025 ). Fig. 7: Exact-match score and peak memory versus number of objectives in multi-objective QA. ABBEL with a peak belief penalty (PBP) maintains comparable performance while using less memory than MEM1 and ABBEL without PBP in this evaluation. Related work Alternative solutions to managing long contexts involve different tradeoffs, and are worth considering depending on the requirements of a deployed system. Context compression methods generate dense representations which, while computationally efficient, sacrifice human-understandability ( Kontonis et al., 2026 , Eyuboglu et al., 2025 , Gupta et al., 2025 , Chevalier et al., 2023 , Deng et al., 2025 , Deng et al., 2025 , Bulatov et al., 2022 ). Hand-designed summarization prompts ( Wang et al., 2025 , Örwall et al., 2025 , Starace et al., 2025 ) and pruning strategies ( Jiang et al., 2024 ) specific to target environments require expert human knowledge and don’t allow an agent to learn what to remember as part of its decision-making strategy. Methods that process long contexts into an external memory store ( Packer et al., 2023 , Xu et al., 2025 ) for the agents or subagents to query ( Zhang et al., 2025 ) are complementary, as they may benefit from better next context creation through summarization training. We would like to point out some exciting works in the space of general recursive summarization focused on math ( Wu et al., 2026 ), reasoning with belief generation ( Zhou et al., 2025 ), competitive coding with a distilled summarization module using similar autoencoding objectives to our general belief grader ( DeepReinforce et al., 2026 ), and adding continuous features to summaries ( Kontonis et al., 2026 ). What’s next for better memory? Many more possibilities are enabled through using explicit belief states as information bottlenecks for multi-step interaction. You could reward actions based on their effect on the belief state to guide exploration, transmit the explicit belief states for better communication between agents, or even improve user controllability by directly modifying the memories on which the agents’ decisions are based. Some forms of information, e.g., what a person looks like, are not represented well by text alone. A continuously learning system will also have to capture such information. Additionally, if we want a system to learn to communicate in a brand new language or to play a brand new game better than any person in the world, the skills accumulated over the lifetime of conversations or games must be stored in a very compressed form, essentially taking on the role of the weights of the model itself. More powerful systems will likely utilize a combination of multiple forms of memory, where the contents of the context may correspond to working memory while other approaches are used for short and long-term memory. How to instantiate these other forms of memory, for instance via test-time training, adapter memories, continuous context memories, or some combination thereof, presents an exciting challenge. Acknowledgements Acknowledgements: We would like to thank Alane Suhr and Kartik Goyal for advising this research as well as Ethan Mendes , David He , Jitesh Jain , and Nicholas Tomlin for comments on early drafts of this post. We would like to thank the MEM1 authors for their email correspondence and for sharing private reviewer feedback which we found particularly insightful. Citation If abbel was inspiring for your future work, please cite us with this! And here is some advice for doing similar research! @misc { lidayan2026abbellearningnaturallanguagebelief , title = {ABBEL: Learning Natural-Language Belief States for Memory-Efficient Interaction} , author = {Aly Lidayan and Jakob Bjorner and Satvik Golechha and Kartik Goyal and Alane Suhr} , year = {2026} , eprint = {2512.20111} , archivePrefix = {arXiv} , primaryClass = {cs.CL} , url = {https://arxiv.org/abs/2512.20111} , } With newer models the number of tokens till 50% compute spend is on attention gets much larger than 25K. Interleaving linear attention alternatives with full attention as is done with gpt-oss and DeepSeekv4, results in massive flops reductions for the attention computation. For example with DeepSeekv4-Pro (1.6T A49B) it requires nearly 450 thousand tokens to reach the 50% tradeoff point. Grandcode uses Qwen-3.5-397B-A17B a model which hits 50% FLOPs for attention at ~150 thousand tokens. ↩ This setting is technically solvable with much more computationally effective tools, but serves as a flexible test bed to study properties of recursive summarization. Bertsimas et al., 2022 , showed that an exact solution for the wordle game instantiated with the original vocabulary of the javascript game can be found with dynamic programming, but evidently the general formulation of wordle as a guessing game on K letters with L attempts and some dictionary of valid words and correct words D is NP hard to determine the minimal number of moves required. ↩ In practice there is an O(N/K) overhead cost for summary. N is the total number of actions. K is the number of actions till summarization is triggered. This is necessarily true for any summary approach. For ease of illustration this gif uses K = 1. In our experiments, to put more emphasis on summarization weaknesses we also use K=1. In practice overhead is small as K can be chosen to be near the efficient hardware limit. ↩ (function () { var root = document.getElementById('abbel-frames'); if (!root) return; var count = parseInt(root.getAttribute('data-frame-count') || '15', 10); var prefix = root.getAttribute('data-frame-prefix') || 'https://bair.berkeley.edu/static/blog/abbel/frames/frame_'; var intervalMs = parseInt(root.getAttribute('data-interval') || '1300', 10); var img = document.getElementById('abbel-frames-img'); var meta = document.getElementById('abbel-frames-meta'); var dots = document.getElementById('abbel-frames-dots'); var btnPrev = document.getElementById('abbel-frames-prev'); var btnNext = document.getElementById('abbel-frames-next'); var btnPlay = document.getElementById('abbel-frames-play'); var stage = root.querySelector('.abbel-frames__stage'); var hint = root.querySelector('.abbel-frames__hint'); var i = 0; var playing = false; var timer = null; var urls = []; for (var n = 0; n

ReadSource

Latest story in this edition: 7:12 PM

Back to front page