SpamSieve 3.3.1 is an update of my Mac e-mail spam filter that improves the filtering accuracy and includes various optimizations, fixes, and updates for macOS 27. Some interesting engineering issues were:
I’m still supporting macOS 10.13, but the app can now build with the macOS 12 deployment target in preparation for Xcode 27. The way Swift handles calling deprecated APIs remains annoying. You need workarounds like protocols to suppress a warning in a particular region of code. Often, I am updating to a newer API, but I want to continue using the old one on earlier versions of macOS. Right now I am heavily testing on macOS 26, so I would like to only deploy the new code there. Sometimes the initial versions of APIs are buggy, and I don’t want to have to retest every feature on every version. But Swift doesn’t like me to gate the calls to macOS 26 and later if the new API was actually introduced in, say, macOS 11.
The most risky update was probably switching to the Swift API for Scanner. This is tricky because the current scan position changes from being based on UTF-16 indexes to String.Index. And in some cases my code was intentionally scanning into the middle of a combining character. I was really glad to have extensive tests here.
Recent versions of Tahoe introduced a Core Data bug that broke save recovery (when invalid Unicode can’t be written to the database and we have to fix it up first). When the error comes in, SpamSieve looks under the NSDetailedErrorsKey key, but the value of this key is "NSDetailedErrorsKey" while the actual error info is under the key "NSDetailedErrors".
Database corruption combined with a Core Data bug and two Swift behaviors were causing crashes. The root problem, I think, is that in this situation Core Data neglects to set the error pointer for -[NSManagedObjectContext countForFetchRequest:error:]. Normally, Swift would detect this and throw a generic nilError. However, this method signals errors by returning NSNotFound instead of nil. It’s annotated as swift_error(nonnull_error), which I think means that Swift doesn’t even look at the return value, only the (unset) error. So my code was receiving NSNotFound on the non-error path, treating it as a real count, and doing some math with it, which (by default in Swift) leads to a crash if there’s overflow. Now my code checks for NSNotFound and uses Int.addingReportingOverflow().
I reimplemented Core Data batch fetching because of two problems with the fetchBatchSize option. First, it logs spurious errors when fetching from multiple stores at once. Second, it leads to high memory use. It will load objects in batches, but it never releases the earlier batches. You can manually refault objects that you no longer need, but it will still hold onto the full object shells, which can add up. My implementation only holds onto IDs, and it can fetch the IDs using a different context than the objects to push more work to background threads.
I’m now using String.makeContiguousUTF8() in various places to avoid slow iteration of bridged strings.
There was a regression where some menu code could crash on macOS 10.13. -[NSMenu setItemArray:] is only available on macOS 10.14 and later, whereas the getter is always available. With old Objective-C, the two methods could be annotated with separate availabilities. The Objective-C property syntax doesn’t allow this, so there’s no way for the compiler to flag calls where the setter is missing.
The AppleScript support works much better with large data sets. The key, I think, is to never return an array to Cocoa for a scripting property/element. First, if you give it a lazy array it will sometimes try to access all the elements even if it only needs a few. And, second, AppleScript will run out of memory if the array is too large. By using indexed accessors, you can maintain laziness and only convert one object to a descriptor at a time. By caching a batch-fetching collection, you can limit the number of fetches and respond quickly when AppleScript requests individual objects.
Bringing Swift Package Index to Apple allows us to build on its strong foundations while preserving its vision and expertise. Together, we’re building a comprehensive package registry to serve the Swift community’s evolving needs.
[…]
Swift Package Index will continue to operate as it does today. You can continue to rely on it to discover packages, check compatibility, and explore documentation. As we embark on this new phase, our goal is to accelerate development and introduce new features that make discovering and evaluating packages even better.
Discover the latest language advancements, including updates for everyday ergonomics, improved concurrency, and safer high-performance code. Explore workflow and language interoperability improvements and updates in embedded Swift.
Build engaging live experiences with gRPC in your Swift app and backend. gRPC is an open-source RPC framework designed for high-performance, bidirectional streaming APIs. Explore how the gRPC Swift package provides a modern, safe runtime built with Swift concurrency.
Bring NumPy-style computing natively to Swift with MLX Swift. Discover how to eliminate cross-language friction in your machine learning workflows by handling image processing, tensor operations, and neural network training in a single, type-safe environment. Explore the APIs that let you leverage GPU acceleration while enjoying the compiler, tooling, and debugging experience you already know.
Join us online for a deep dive into WWDC26 with Apple engineers and designers to ask questions, get advice, and follow the discussion about the week’s biggest Swift announcements.
There’s a voting system. And that means a number of questions weren’t selected. This time I copied those down and I thought it could be fun to take a shot at answering the ones that are more in my area.
The Swift dependency scanner has been optimized to avoid redundant setup work and header searches when looking up Clang modules during a single dependency-scan action, substantially improving scanning performance.
As a consequence of this change, every Clang module reachable from a single Swift dependency-scan action must have a unique module name. If two module maps visible to the same scan declare a Clang module with the same name, the scan may report an error.
[…]
System now provides Swift APIs for the C stat, lstat, fstat, and fstatat system calls. This includes a new Stat type with initializers from FilePath, FileDescriptor, or a C string; FilePath.stat() and FileDescriptor.stat() instance methods; and supporting types (FileType, FileMode, FileFlags, UserID, GroupID, DeviceID, and Inode).
The new isTriviallyIdentical(to:) method offers a guaranteed-fast way to check two objects for equality. It is essentially an optimised version of the existing equality condition provided by Equatable and the == operator. It’s useful because it guarantees O(1) time complexity, whereas == makes no formal guarantees at all (and for many types is O(N) or worse). But unlike the existing identity comparison operator === – also O(1) – it promises to do more than just tell if two objects are the exact same pointer, and it works on value types (not just reference types).
[…]
These new types generalise the existing patterns of borrowed and mutable references, that have previously existed in Swift in much more restricted forms (e.g. inout parameters are essentially MutableRef parameters, and Span & MutableSpan are array equivalents).
There’s now a built-in function for demangling Swift symbol names, in the Runtime module (that’s bundled with the Swift toolchain, alongside the stdlib etc).
As Apple has aligned OS version numbers across platforms, Swift 6.4 takes the next step by letting you collapse repetitive availability attributes into a single anyAppleOS token.
[…]
There are situations where you need to call a deprecated API while you plan a migration, or audit a critical function for unsafe usage, without letting those concerns bleed into the rest of the project. The new @diagnose attribute handles both cases.
[…]
Some work should complete even after a task is cancelled, like flushing a file to avoid corruption. withTaskCancellationShield wraps a region where Task.isCancelled always returns false.
Swift 6.4 improves error handling for unstructured tasks through SE-0520: Discardable result use in Task initializers. The change helps you catch a subtle bug: creating a throwing task and then ignoring its returned task handle.
I thought it would be a good time to detail some of the type checker performance improvements we worked on since I shared the type checker performance roadmap last year. I’m also going to outline a couple of things we plan on looking at next.
Update (2026-07-09): I was optimistic about improvements to the type checker making compilation faster, but I found that compiling my predominantly Swift project with Xcode 27 Beta 3 was only 0.3% faster than with Xcode 26.6. I wonder if there’s some extra setting I’m supposed to enable.
Swift 6.3 introduces the @c attribute, which lets you expose Swift functions and enums to C code in your project. […] @c also works together with @implementation. This lets you provide a Swift implementation for a function declared in a C header[…]
[…]
Swift 6.3 introduces module selectors to specify which imported module Swift should look in for an API used in your code. If you import more than one module that provides API with the same name, module selectors let you disambiguate which API to use[…]
[…]
Provide pre-specialized implementations of a generic API for common concrete types using @specialize.
[…]
Guarantee inlining — a compiler optimization that expands the body of a function at the call-site — for direct calls to a function with @inline(always).
[…]
Expose the implementation of a function in an ABI-stable library to clients with @export(implementation). This allows the function to participate in more compiler optimizations.
Discover the latest enhancements to SwiftData. We’ll show you how to persist custom and third-party types using Codable, and group fetched data into sections in your SwiftUI app. We’ll also explore how to observe data store changes anywhere else using ResultsObserver and HistoryObserver, giving you the flexibility to drive powerful state objects and react precisely to model updates.
Again, there seems to be nothing new in Core Data this year, nor any communication about it. There’s still no interoperability for object IDs. The SwiftData changes seem fine but don’t really address the new framework’s deficiencies relative to Core Data. It seems like there are still basic problems with threading. I just don’t understand how Apple is deciding what to prioritize with this framework.
With SwiftUI, the bones seem questionable, but at least we can see that Apple is full steam ahead, with substantial progress to address limitations and pain points. SwiftData seemed to have better bones and is much less ambitious. Getting it right seemed like just a matter of follow through. But, for some inexplicable reason, it seems to lack the resources and/or urgency to reach its potential. And even though SwiftUI is clearly the chosen one, AppKit remains in development. Meanwhile, Core Data seems to be abandoned, even though SwiftData feels more like a side quest than a genuine attempt to supplant it.
The implicit message, for those who have build the core of their app on top of Apple’s old persistence framework, seems to be that Apple is not looking out for their needs. Core Data will surely get maintenance to the extent that Apple’s own apps need it, but there’s no evidence of a future or even a migration plan. The answer, I guess, is third-party frameworks, but that’s not an easy migration, either, since none is even as close a match as SwiftData.
Experience SwiftData in action as we add persistence to an existing app. We’ll show you how to define your data models and seamlessly integrate persistent data with SwiftUI. You’ll also learn foundational skills for managing your app’s state using this expressive, declarative API.
Join us online for a deep dive into WWDC26 with Apple engineers and designers to ask questions, get advice, and follow the discussion about the week’s biggest SwiftData announcements.
SwiftData predicates can now work directly with enum values, resulting in cleaner models and simpler query code.
[…]
In iOS 27, Apple introduced support for compound predicates through the Predicate(all:) and Predicate(any:) initializers, making it easier to build queries dynamically based on user input.
I’m not sure why that took so long.
The framework is gradually moving beyond simple demos and becoming easier to use in larger, more sophisticated projects.
[…]
iOS 27 is the first release where many of the framework’s early rough edges have started to disappear.
Compared with @Query gaining support for section fetches, and ResultsObserver enabling observation of query result changes outside views, I am more interested in @Attribute(.codable). It provides a clearer storage intent and gives developers a way to avoid falling into the black box of composition.
Of course, @Attribute(.codable) is not a silver bullet. It is more like a clearly defined escape hatch SwiftData provides for opaque Codable types: suitable for storing external types that you cannot model yourself, but still genuinely need to persist. The cost is that this content cannot participate in SwiftData’s predicate, sort, or migration awareness. Precisely for this reason, its value lies not in being “more powerful,” but in being “more explicit.”
However, SwiftData still does not provide cloud syncing for public / shared data, nor have I seen a clearer signal of performance improvements. These issues will continue to limit its adoption. For many developers, SwiftData this year feels more like it is filling key gaps rather than making a leap significant enough to fundamentally change confidence in it.
Codable types in SwiftData seem pretty lame given that SQLite absolutely does have JSON support and does support queries on it?
But the funnier thing in the MKMapItem.Identifier example is that MKMapItem.Identifier is a RawRepresentable==String, so it could actually be stored as a String in the store.
AsyncImage now automatically caches downloaded images using HTTP caching protocols, allowing servers to control caching behavior via standard headers.
[…]
Xcode 27 introduces a new @State implementation that avoids this repeated evaluation. This new behavior back-deploys to iOS 17 aligned OSes. The new @State is implemented with a Swift macro. It is largely source compatible with the property wrapper version, with a few exceptions.
[…]
Text views now support TextRenderer.
[…]
In apps built with the 27.0 SDKs, the new ReadableDocument and WritableDocument protocols support asynchronous reading and writing, progress reporting, and direct access to document URLs. New DocumentGroup initializers that adopt these protocols let you disable document creation for editing-only apps and present custom UI before any document is opened.
[…]
TextField respects custom font and color styling applied to its prompt.
[…]
List accepts drops in two cases that previously didn’t work: drags with compatible transfer representations are accepted into reorderable content even when the .reorderableItem transfer type isn’t present, and a .dropDestination(…) modifier declared on a list item now performs the drop.
Build your project in Xcode 27 or later to construct type-agnostic content from closures that you mark with ContentBuilder, which serves as the unified replacement for type-specific builders like ToolbarContentBuilder and CommandsBuilder.
Use the visibilityPriority(_:) modifier to prioritize important toolbar actions so SwiftUI keeps them visible as space shrinks, moving lower-priority items to the overflow menu first.
[…]
Present an alert or confirmation dialog from an optional data item or error object, and use that data to produce the content and title[…]
Explore the latest additions to SwiftUI and discover how they can improve your apps. We’ll introduce a new Document protocol with direct disk access and snapshot-based diffing for building high-performance apps; new APIs for reordering content in lists, grids, and sections; and toolbar enhancements including visibility priority and auto-minimizing behavior. We’ll also cover expanded presentation APIs — including swipe actions on any view — plus AsyncImage caching improvements and lazy state initialization for Observable types.
Discover how to incrementally adopt SwiftUI in your existing AppKit or UIKit app. We’ll show you how to use the Observation framework to automatically update your views, integrate SwiftUI components into an existing view hierarchy, and bring gesture recognizers into SwiftUI. We’ll also explore how to add complete SwiftUI scenes to your app without changing your overall architecture.
Discover the inner workings of lazy stacks in SwiftUI. We’ll explore how LazyVStack and LazyHStack estimate sizes, lazily load subviews, and prefetch content to deliver smooth scrolling experiences. We’ll also cover advanced performance optimizations, state management best practices, and tips for precise programmatic scrolling. To get the most out of this session, we recommend basic familiarity with SwiftUI layout using stacks.
Discover how to craft rich, custom experiences by creatively composing SwiftUI layout and graphics APIs. We’ll show you how to break down complex designs and use a creative pipeline to chain simple building blocks together. Learn how to draw with layer shaders, animate with timelines, and anchor views with alignment guides.
Follow along as we build a game of Solitaire to explore the latest drag-and-drop capabilities in SwiftUI. We’ll show you how to use the new reordering API to let people arrange content, implement drag containers to move multiple items at once, and customize the drag-and-drop lifecycle to fit your app’s rules.
Up until now it was a property wrapper conforming to the DynamicProperty protocol, but in Xcode 27 it becomes a Swift macro. In this post we will look at what the change means for @Observable models stored in @State.
SwiftUI also introduces a new prominent tab role. You can use the prominent role for trailing-separated tabs, similar to search.
[…]
Document-based apps get a refreshed look and feel, along with a performance boost. It looks like Xcode has started using these improvements, which might explain why we see so much work around document-based apps this year. And finally, Xcode introduces SwiftUI Specialist and What’s New in SwiftUI skills for agentic coding in Xcode.
For me, the biggest change in SwiftUI comes from its comprehensive support for document-based apps. It not only adds a large number of new APIs, but also shifts the mental model toward “observable document objects + asynchronous snapshots + dedicated readers / writers.” This is clearly better suited to complex document apps, and it also aligns more closely with the overall evolution of modern Swift around Observation and Concurrency.
The sessions also mentioned that SwiftUI continues to optimize layout- and container-related implementations, bringing noticeable performance improvements in some scenarios. This is an improvement developers have urgently needed. However, SwiftUI still does not provide the ability to create custom Lazy containers, which remains a clear disappointment.
iOS 27 introduces new reordering APIs that work with any container. We can mark dynamic content with reorderable() and define the scope of the interaction with reorderContainer(for:). SwiftUI handles the drag preview, insertion placeholder, and drop animation, while our code applies the resulting change to the model.
SwiftUI’s drag container APIs are also now available on iPhone and iPad, after previously being limited to macOS. They let us make items in a collection draggable without making the collection reorderable, and include multiple selected items in the same drag. The APIs also support lazy generation of transferable values and drag-session observation.
I love the new #SwiftUI Text selection but without a way to make selection span multiple Texts in a group, it doesn’t really address our needs at Linear – here’s hoping we see an update in a later seed 🤞
The NavigationTransition protocol has been available in SwiftUI since iOS 18, letting us control how views animate when pushed onto a NavigationStack and when presenting sheets and full-screen covers. We specify the transition using the navigationTransition(_:) modifier on the destination or presented view, and SwiftUI uses it instead of the default animation for that context. Before iOS 27, SwiftUI provided two built-in conforming types: AutomaticNavigationTransition, used via the automatic static value, which defers to the system default for the current context, and ZoomNavigationTransition, used via zoom(sourceID:in:), which animates the presented view expanding from a source view marked with matchedTransitionSource(). iOS 27 introduces CrossFadeNavigationTransition, a new built-in transition that cross-fades between views without requiring a source, and adds AnyNavigationTransition, a type eraser that lets us select a transition at runtime.
The last few years watching WWDC has been a mixed experience for me, because I honestly believe Swift and SwiftUI are actively either bad or being made worst.
Yet every year, the problems I have with them are doubled down on, not improved.
The FB21333309 cache bug I submitted is now confirmed to be fixed on iOS 27.
Instead of introducing a new CacheKey like I suggested, SwiftUI team choose to move the intensity payload out of the FeedbackType enum to a new Payload enum and add a new payload var to SensoryFeedback storage.
A few weeks ago I realised that most iOS jobs require knowledge of SwiftUI. So I started to rebuild my Mastodon client in SwiftUI. Then I got an offer for a new job and accepted it.
This means I can get back to working on the ObjC version. Feels good. :)
iOS 27 adds new AsyncImage initializers that accept a URLRequest instead of a URL. We can now configure request headers, cache policy, and timeout interval while continuing to use the built-in loading and phase handling provided by AsyncImage. A new asyncImageURLSession(_:) modifier also lets us provide the URL session used by asynchronous images in a view hierarchy.
Seven years after its blockbuster 2019 announcement, SwiftUI was supposed to be the mature, production-grade future of cross-platform UI development on all Apple platforms. Instead, SwiftUI feels like a perpetual beta, even in 2026. In this deep dive, I break down why the initial excitement has given way to deep professional frustration for senior engineers. I analyze the systemic issues with performance and layout predictability, the chaotic state of SwiftUI’s ever-changing data flow, and the frustrating lack of backward compatibility that forces developers into a nightmare of shims and workarounds.
Through real-world examples—including Apple’s own SwiftUI tutorial (which is broken) and a head-to-head performance comparison with UIKit (guess who wins)—I demonstrate how SwiftUI trades precise engineering for an illusion of convenience.
Beyond the code, this video explores a broader, more concerning shift in Cupertino: a transition away from the uncompromising craftsmanship of the original era of Cocoa, Aqua, and Auto Layout toward a modern corporate culture of “good enough” products.
At the heart of this architecture is our third generation of Apple Foundation Models (AFM), a family of five foundation models custom-built in collaboration with Google. These span from on-device models to server-based models running on Private Cloud Compute.
Apple Foundation Models are built to unlock a wide range of helpful experiences for our users, like an entirely new Siri and intelligent tools that make everyday apps smarter and more useful.
“The amount of the Google Assistant we use is none,” Federighi said, explaining that Apple uses none of the Gemini models deployed to Google’s customers, none of Google’s client-side code, and no Google Search infrastructure as the knowledge backbone.
The cloud models hosted on Private Cloud Compute are interesting: they’re not “Gemini” models; they’re Apple Foundation Models trained using proprietary data via RL, which were then “refined” with data from Google’s “frontier” models.
[…]
I’ve been covering the AFM family of models for a while now, and AFM Core Advanced is one of the most interesting on-device models I’ve read about in a while, especially in the context of model size for mobile devices and built-in multimodality with support for text, images, and audio. I’m very keen to play around with this model and understand how it holds up in practice. I wonder if the new CLI (!) for AFM will let you test this one.
It’s very cool that Apple shipped a 20B parameter on-device.
You can’t put 20B parameters in RAM at any reasonable precision. To make it work they are using pretty exotic architecture by today’s standards.
A small model predicts from the query (or prompt) which experts to load from Nand into RAM. The key distinction from a typical MoE is that you do this once per query and then generate all the tokens with the same experts (instead of switching the experts for every token).
FoundationModels is one of the highlights of this WWDC; I think it’s now finally what we hoped we were getting two years ago, and thought we were getting last year (just the models themselves were barely up for it then). I finally feel like I can build features with it, though I really don’t like the Sword of Damocles Apple is holding above Private Cloud Compute and how it can permanently lock you out of using the models forever across all your apps if you hit a download threshold. Poison pill
These strict limits don’t seem to be getting as much attention as they should. It’s nice that for small developers who meet the above criteria, access to PCC has no cost. But there’s no way (yet?) to buy your way out of these limits.
[…]
The “fewer than 2 million first-time app downloads from any of their apps” restriction is particularly notable. It’s not 2 million installations for apps that are using PCC, but 2 million downloads for any app the developer has ever released.
Is there a real time count somewhere of total lifetime downloads for a developer account, so one can plan if they at risk of the switch tripping? Reminds me of the small business qualifications. I had to try to figure out if an employers developer account was going to exceed the revenue threshold for the year. I was left trying to determine it from sales reports, not to mention sales date versus pay out date confusion. I think I botched the calculation in the end.
Claude for Foundation Models is a Swift package that makes Claude available as a server-side language model in Apple’s Foundation Models framework. The package conforms Claude to the framework’s LanguageModel protocol, so you drive it with the same LanguageModelSession API you use for Apple’s on-device model: respond(to:), streaming, guided generation, and tool calling all work the same way.
Requests go directly from your app to the Claude API; Apple is not in the request path and does not see prompts or responses. Usage is billed to your Anthropic account at standard API pricing.
Apple is literally stopping me from building a brand new app using Private Cloud Compute because I made a successful app a few years ago.
The new app might be a success, or it might be a complete flop. Nobody knows yet.
I would understand it if Apple were to limit developers once an app reaches a certain number of downloads or active users, but that’s not what’s happening here.
Instead, they’re blocking developers before they’ve even had a chance to build and ship the app.
My team rewrote Apple’s TrueType hinting interpreter in Swift, ask me anything.
[…]
I feel like naming just one would be a disservices to all of the features that made this effort possible (C interop, generics, noncopyable/nonescapable types) but at the end of the day I think the star of the show was the optimizer; despite being faster than the code it replaced, the new code is super readable and that was only possible because the optimizer was able to completely eliminate all of our abstractions.
The new version is faster, but the main motivation was security concerns.
Is hinting useful/being used in the days of hi-dpi displays? I was under impression that Apple switched to grayscale anti-aliasing and ditched hinting.
For the most part hinting isn’t really necessary anymore, but thanks to being Turing-complete it has been Hyrum’s law-ed by at least one CJK font that uses hinting to lay out strokes in its characters.
One of the axioms for this project was that I wanted my team to write the most boring code possible—nearly identical structurally to the code it was replacing, because to do otherwise would introduce binary compatibility risk. The other axiom was 100% test coverage for all new code as it landed, with the same units testing both interpreters.
Font parsers process data from untrusted sources, making the TrueType hinting interpreter a security-critical attack surface. To make the format more resilient on Apple platforms, we rewrote its hinting interpreter from C to memory-safe Swift for the Fall 2025 releases. In addition to memory safety, we also improved performance: on average, our Swift interpreter runs 13% faster than the C interpreter it replaced.
[…]
Binary compatibility was crucial for this project to succeed: existing programs had to continue to function the same as they did before, effectively unaware that a new implementation was in place. This means not just interface compatibility but pixel-identical glyph rendering as well, relative to the C implementation.
[…]
To ensure correctness, we developed two test suites. The first was a unit test suite that can target both implementations, providing exhaustive (99.7%) code coverage for both. This suite is included with the open source release of the Swift interpreter.
Then, to represent real-world workloads, we used a fuzzer to minimize a corpus of 10 million PDF files down to 4,200 without any loss of code coverage.
[…]
Following WebKit’s Safer Swift Guidelines, the example below demonstrates how to wrap a bridged structure from C in a projection type that uses Ref for lifetime safety, brokers bounds-safe access to the underlying data, and returns idiomatic Swift types to its callers.
Apple this week confirmed that Notion is migrating its user interface to SwiftUI, citing the app’s desire for greater performance and UI consistency than its existing web-based stack can deliver.
[…]
The callout was clearly deliberate; Notion is one of the most widely used productivity apps on the Mac, and has long been criticized for the sluggishness that comes with its Electron-based architecture.
Siri Wolfram helped define the original promise of Apple’s voice assistant. When Siri debuted on the iPhone 4S in 2011, it could answer factual and computational questions without sending users through a list of search results. Ask about a mathematical calculation, scientific quantity, historical statistic or unit conversion, and Wolfram Alpha could provide a structured answer.
That partnership gave early Siri something many modern AI assistants still struggle to guarantee: a source designed to compute answers rather than produce plausible sentences. Wolfram Alpha was not a chatbot. It was a computational knowledge engine built around curated data, symbolic mathematics and algorithms.
Siri AI enters a far more ambitious era. Apple now wants its assistant to hold natural conversations, understand personal context, interpret images, find information across apps and complete actions. Yet the old Siri Wolfram relationship remains useful for understanding what Apple gained, what was lost as assistants became more conversational and why verified computation may become even more valuable in the generative AI age.
Siri Wolfram Was Built Around Answers
The original Siri Wolfram integration reflected a straightforward idea: users wanted direct answers without manually searching, opening websites and comparing sources.
Wolfram Alpha was particularly effective for questions with a computable result. It could solve equations, compare financial data, convert measurements, retrieve astronomical information, calculate dates and present structured scientific facts. Siri provided the voice interface, while Wolfram supplied the knowledge engine behind selected responses.
A user could ask how many days remained until a date, calculate a percentage, compare populations or request information about a mathematical concept. Siri translated the spoken request and delivered the result in a format suitable for the iPhone.
The experience was narrow compared with modern generative AI, but it had a valuable discipline. Wolfram Alpha attempted to determine an answer from structured information. It did not need to improvise an explanation every time.
That made Siri Wolfram especially useful for mathematics, science, education and quick factual calculations. The assistant could sound intelligent because it was connected to a system built to compute.
Image Source: Google
What Siri Wolfram Alpha Could Do Well
Siri Wolfram Alpha worked best when the request had a definable structure. Arithmetic, percentages, conversions, equations and statistics were natural categories. The system could also retrieve information about weather history, geography, nutrition, astronomy, transportation and other data-rich subjects.
The integration helped make Siri feel different from ordinary web search. Instead of showing several links, the assistant could present one answer with supporting figures or charts.
That approach had limitations. Wolfram Alpha could only respond effectively when it understood the request and had the relevant data or computational method. It was not designed for open-ended conversation, personal writing, emotional nuance or the countless informal questions users ask assistants.
Siri also relied on several external services, with Wolfram Alpha handling only certain knowledge categories. The experience could therefore feel inconsistent. One request produced a polished computational response, while another returned a web search or a limited canned answer.
Still, the partnership demonstrated a principle Apple has never fully abandoned: the best assistant does not need to create every answer itself. It needs to route each request to the system most qualified to handle it.
Generative AI Changed the Definition of an Assistant
Modern AI assistants are expected to do far more than retrieve facts. Users want them to explain ideas, write messages, summarize documents, analyze images, brainstorm projects and remember the direction of a conversation.
Siri AI is Apple’s response to that expanded expectation. Powered by Apple Intelligence and Apple Foundation Models, the new assistant can handle open-ended requests and continue natural conversations. It can use personal context from supported apps, understand onscreen content and connect requests with app actions.
This is a dramatic expansion from the Siri Wolfram era. The old model was largely transactional: ask a question, receive an answer. Siri AI is intended to interpret intent, understand relationships between information and help complete a larger task.
A user may ask Siri AI to find a restaurant recommendation buried in Messages, locate a hotel confirmation in Mail and add the details to a travel note. That request involves personal context and several system services rather than one public factual answer.
The assistant becomes less like a talking search box and more like an operating-system layer.
Image Credit: Apple Inc.
Conversation Creates a Reliability Problem
Generative AI makes assistants more flexible, but it also introduces uncertainty. A language model can produce an elegant response even when the underlying information is incomplete or wrong. The same fluency that makes the assistant enjoyable can make an inaccurate answer sound convincing.
The old Siri Wolfram model avoided much of that risk within its strongest categories. A mathematical calculation came from a computational engine. A unit conversion followed a defined relationship. A data query could be tied to structured information.
Siri AI needs both capabilities. It needs conversational intelligence for requests that cannot be reduced to a formula, while retaining access to reliable tools for tasks that demand precision.
Apple can use specialized systems for calculations, calendars, maps, weather, app actions and personal information rather than asking one generative model to invent every result. Foundation models can understand the request, then direct the work to an appropriate source.
That structure would preserve the strongest lesson from Siri Wolfram: intelligence also means knowing when not to guess.
Personal Context Is the New Knowledge Engine
Wolfram Alpha gave Siri access to public computational knowledge. Siri AI adds a second knowledge source: the user’s own information.
Apple says Siri AI can understand personal context across messages, emails, photos, notes and other supported content. It can help retrieve a detail without requiring the user to remember which app contains it.
This changes the assistant’s value. Wolfram Alpha could explain the distance between two cities. Siri AI could find the hotel reservation, identify the arrival time and retrieve the message where a friend recommended a nearby restaurant.
That personal layer also requires stricter privacy. Apple uses on-device processing for many requests and Private Cloud Compute when more processing power is required. The company has designed the system so personal data does not become part of an ordinary cloud AI profile.
Siri Wolfram answered questions about the world. Siri AI is being designed to answer questions about the user’s place within it.
Image Credit: Apple Inc.
Apps Complete the Transition
Siri AI also moves beyond knowledge by connecting directly with apps through App Intents. Developers can expose content and actions so the assistant can help users complete tasks instead of only describing how to do them.
That could include editing a photo, retrieving a document, starting a workout, updating a task or sending information through a supported app. Onscreen awareness adds another route, allowing users to ask about content already visible without explaining every detail again.
Wolfram Alpha remains valuable because some questions require specialized computation. App Intents extend the same routing philosophy into actions. Siri does not need to contain every capability internally. It needs to understand the request and connect it with the correct tool.
This may become the defining structure of Siri AI: one conversational interface backed by models, apps, services, personal context and specialized knowledge engines.
The Old Siri Still Has a Lesson for the New One
Siri Wolfram belonged to a more limited assistant era, but its underlying approach was disciplined. The system used a specialized source for questions that demanded structured knowledge and computation.
Siri AI has a wider assignment. It must converse naturally, interpret images, understand personal information and complete actions across Apple devices. That breadth can make Siri far more useful, but only if Apple preserves dependable pathways for calculations and factual tasks.
The future assistant should not choose between Wolfram-style precision and generative flexibility. It should combine them. A conversational model can understand what the user wants. A computational engine can provide the numerical answer. Personal context can supply relevant details. App Intents can complete the task.
The old Siri Wolfram integration showed that a voice assistant could make expert knowledge accessible through one spoken request. Siri AI now aims to place conversation, personal context and action around that foundation.
The assistant has become larger, more personal and more capable. Its credibility will still depend on something the 2011 version understood well: when a question has a correct answer, intelligence should calculate before it speaks
Neuroscientists have long believed that language processing was only found in regions of the brain’s left hemisphere, including the well-known Broca’s area. However, new evidence suggests the brain’s language network is far more widespread than previously thought.
Researchers at the Massachusetts Institute of Technology (MIT) analyzed functional magnetic resonance imaging (fMRI) scans from 772 participants and identified 17 additional brain regions involved in language comprehension. These newly discovered areas are distributed across the brain, including the cerebellum, hippocampus, amygdala, and several regions of the cerebral cortex. In total, this accounts for five percent of the adult brain volume (roughly the size of a large strawberry).
“Even though there are all these distant components, it’s pretty restricted in terms of volume. You don’t need that much of the brain to do language,” says senior author Evelina Fedorenko, an MIT associate professor of brain and cognitive sciences and a member of MIT’s McGovern Institute for Brain Research, in a statement.
Locating the Brain’s Hidden Language Centers
To find these hidden language-related regions in the brain, the researchers revisited years of brain imaging data collected since 2013. Additionally, participants completed a standard “language localizer” task, during which they read or listened to meaningful sentences and sequences of meaningless nonwords. By comparing brain activity between these two conditions, the research team identified regions that responded more strongly to language.
“When we initially started looking at language, in the first couple of papers, I tried to be comprehensive and include anything that seemed consistent across participants, and there was a huge amount of resistance,” said Fedorenko. “People would say things like, ‘Well, we know those are not language areas, so please focus on the language areas.’”
The team decided to adopt a more flexible statistical approach to detect weaker signals and identify previously overlooked language-sensitive regions beyond the classical language areas. They then compared these regions’ responses during a spatial working memory task to distinguish language-specific areas from those involved in what would be considered general cognitive functions.
Cerebellum Discoveries
Interestingly, five of the newly identified language regions are located in the cerebellum, a structure traditionally associated with movement and coordination. Some of these cerebellar regions were also active during non-language tasks, suggesting they may help integrate information across different brain systems rather than process language alone.
“It’s a very simple paradigm that lets you identify this core language system in individual brains,” says MIT postdoc Agata Wolna, the lead author of the paper.
Additional language-sensitive regions were identified in the hippocampus and amygdala, areas better known for their roles in memory and emotion. Their involvement suggests that understanding language may rely more on integrating memory, emotional context, and higher-order cognitive functions than previously understood in science.
“We always see this frontal temporal network, but there’s quite a lot of evidence that there are other regions that are also critical for language processing,” said Wolna. “By using a laxer threshold and zooming in on areas with weak MRI signal, we tried to maximize the chances of finding small and weakly responsive regions outside of this left frontal temporal system.”
The findings challenge long-held assumptions about the brain’s organization and can open new avenues for research into how language processing is understood in neuroscience.
Chrissy Newton is a PR professional and the founder of VOCAB Communications. She currently appears on The Discovery Channel and Max and hosts the Rebelliously Curious podcast, which can be found on YouTube and on all audio podcast streaming platforms. Follow her on X: @ChrissyNewton, Instagram: @BeingChrissyNewton, and chrissynewton.com. To contact Chrissy with a story, please email chrissy @ thedebrief.org.
“Our findings show that the brain is far more active and capable during unconsciousness than previously thought,” said Dr. Sameer Sheth, professor and Cullen Foundation Endowed Chair of neurosurgery and a McNair Scholar at Baylor. “Even when patients are fully anesthetized, their brains continue to analyze the world around them.”
a Rare Look Inside the Anesthetized Hippocampus
Sheth’s team recorded from hundreds of individual neurons in the hippocampus, a region of the brain essential for memory formation. Researchers collected data during epilepsy surgeries, specifically anterior temporal lobectomies, when patients were under general anesthesia and the hippocampus was temporarily accessible. This rare opportunity allowed researchers to directly record hippocampal activity, something scalp EEG cannot.
The researchers used Neuropixels probes, high-density recording devices that can monitor hundreds of neurons simultaneously. This study represents the first use of this technology in the human hippocampus during anesthesia. Seven patients participated, all under propofol anesthesia with consistent sedation levels maintained throughout the recordings.
The Unconscious Brain Still Learns
In the initial test, researchers played patients a repeating tone with occasional unexpected pitches. Hippocampal neurons consistently detected these outlier tones, and their sensitivity increased over approximately ten minutes. Researchers usually observe this kind of adaptive neural response during wakefulness.
To dig deeper, the researchers built a computer model of a recurrent neural network, trained to perform the same tone discrimination task. The model showed the same pattern as the human brain recordings, suggesting that this increased sensitivity to outlier tones can arise from local brain circuits alone, without the need for higher-level conscious processing.
Predicting Words Before They’re Spoken
The researchers also played short stories to anesthetized patients while recording from the same neurons. Hippocampal activity tracked language in real time, distinguishing between nouns, verbs, and adjectives. Neural activity reflected both the current word and prediction of the upcoming word in the sequence. “The brain appears to anticipate what comes next in a story, even without conscious awareness,” Sheth said.
“This kind of predictive coding is something we associate with being awake and attentive, yet it’s happening here in an unconscious state,” added Baylor neurosurgery professor Benjamin Hayden.
What This Means for the Science of Consciousness
The results show that the hippocampus can support neural computations associated with complex cognition even during unconsciousness. This suggests that at least some components of language processing and prediction may not require conscious awareness. Sheth’s team proposes that consciousness does not arise from a single brain region but rather emerges from interactions among multiple brain regions. The hippocampus may process information that later becomes part of awareness.
The researchers noted a parallel with artificial intelligence. Large language models generate text by predicting the next word in a sequence; the anesthetized hippocampus showed a similar pattern of prediction. This similarity may provide neuroscientists and AI researchers with a shared framework for studying language prediction based on biological circuitry.
“Can we use these signals to deploy and run a speech prosthetic for some of the parts of the brain that are damaged by stroke or injury? These are questions that we can now consider in relation to this part of the brain,” said study author and Baylor neurosurgery resident Kalman Katlowitz.
While these results are promising, the team acknowledged the study’s limitations. The research focused only on propofol-based general anesthesia, so the results may not apply to other unconscious states such as natural sleep or coma. Additionally, the researchers examined only the hippocampus, so they cannot yet determine how broadly this type of unconscious processing occurs in other brain regions.
“This work pushes us to rethink what it means to be conscious,” Sheth concluded. “The brain is doing much more behind the scenes than we fully understand.”
Austin Burgess is a writer and researcher with a background in sales, marketing, and data analytics. He holds an MBA, a Bachelor of Science in Business Administration, and a data analytics certification. His work focuses on breaking scientific developments, with an emphasis on emerging biology, cognitive neuroscience, and archaeological discoveries.
In a groundbreaking study that redefines our understanding of how language is encoded in the human brain, researchers have mapped the diverse landscape of neurons distributed across frontal and temporal cortical regions, revealing a complex yet lateralized neural architecture for human language processing. By leveraging advanced single-neuron recording techniques alongside sophisticated language models, the team has identified not just the locations but the nuanced encoding properties of neurons implicated in various linguistic computations. This work illuminates how language, a uniquely human faculty, is instantiated at the neuronal level with precision and regional specificity.
The study’s comprehensive neuronal recordings spanned key brain areas historically associated with language, including the frontal cortex, anterior temporal cortex, and posterior temporal cortex. These regions were chosen given their established roles in speech production and linguistic comprehension, as well as their demonstrated selective responses in prior localized brain imaging studies. Importantly, the neurons examined were broadly distributed across both hemispheres and these cortical regions, showcasing the widespread neural substrate involved in language tasks.
One of the seminal findings was that roughly half of the neurons, 289 out of 579, exhibited selective responsiveness to one or more linguistic features. Intriguingly, this selectivity was evenly distributed across the three cortical sites — frontal, anterior temporal, and posterior temporal — and did not significantly differ between the left and right hemispheres. This suggests a foundational neural scaffold where language-related computations recruit a multitude of neurons across large-scale networks rather than isolated hotspots, emphasizing distributed processing over modular localization.
However, beyond this broad distribution, the study uncovered striking lateralization and regional differentiation in the strength and informational content of neural modulation. Neurons within the left hemisphere exhibited significantly stronger modulation—quantified by their z-scored activity changes—in response to linguistic features compared to their right hemisphere counterparts. This enhanced sensitivity encompassed a range of linguistic elements, including lower-order features like pitch, underscoring the superior role of the left hemisphere in detailed linguistic encoding.
Further dissecting these lateralized effects across cortical regions revealed that the posterior temporal cortex showed the most pronounced difference in left-right modulation strength, significantly outperforming other areas. This aligns well with the notion that posterior temporal areas are central to decoding complex linguistic dependencies and syntactic structures, functions critical for fluent language comprehension and production.
Conversely, the prefrontal cortex displayed the strongest overall neuronal modulation to these language features, both in the left and right hemispheres, compared to temporal regions. This finding suggests a hierarchical and possibly integrative role for the frontal cortex in orchestrating language processing, perhaps linked to higher-order syntactic planning, working memory, or executive control mechanisms required for natural speech.
The neural predictivity analysis, leveraging embeddings from cutting-edge contextual language models, further corroborated the lateralized and regionalized pattern. Neural activity in the left anterior temporal cortex was most accurately predicted by these language model features, highlighting this region’s role in abstract linguistic representation and semantic integration during language tasks.
Methodologically, the study capitalized on the precise temporal resolution of single-neuron recording combined with sophisticated statistical analyses, including permutation and rank-sum tests, to quantify neuronal response selectivity and modulation. This rigorous approach afforded a fine-grained characterization of how individual neurons adapt their firing patterns to various syntactic and prosodic elements of language in real-time.
Collectively, these data challenge conventional notions that neural language processing is confined to narrowly defined “language centers.” Instead, the findings advocate for a model of language representation as a widely distributed but regionally specialized system with marked hemispheric dominance. This has profound implications for understanding the neural basis of language disorders, suggesting that therapeutic interventions might need to consider both distributed network integrity and hemispheric targeting.
Moreover, the study’s integration of naturalistic language models with neurophysiological data marks a pioneering step in computational neuroscience, bridging theoretical frameworks of language with tangible neural mechanisms. By showing how models trained solely on linguistic input can approximate neuronal responses, this research points toward a future where artificial intelligence and neuroscience synergistically unravel human cognition.
Importantly, the results underscore the unique neural architecture supporting language that has evolved in humans, outstripping earlier simplistic models focused on gross anatomical mapping. These advances set the stage for future investigations that might explore how these neuronal populations interact dynamically during complex language tasks such as conversation, narrative comprehension, or bilingual processing.
In conclusion, this landmark research paints a detailed, high-resolution portrait of the neuronal building blocks underpinning human language. It reveals an exquisitely lateralized and regionally differentiated system whereby distributed neurons collectively encode the multifaceted features of speech. Such insights not only deepen fundamental neuroscience but also hold promise for novel clinical interventions and computational linguistic advancements.
Subject of Research: Neuronal encoding of human language features across frontal and temporal cortical regions; lateralization and regional differentiation of linguistic processing in the brain.
Article Title: Mapping the neuronal building blocks of human language with language models.
Article References:
Cai, J., Kfir, Y., Jamali, M. et al. Mapping the neuronal building blocks of human language with language models. Nature (2026). https://doi.org/10.1038/s41586-026-10691-5
Most generative AI tools know less about R than languages like JavaScript and Python, thanks to how much training data is available for each. However, with a little extra setup, you can give a large language model (LLM) the knowledge it needs to improve its R skills.
Here are 10 ways to help generative AI write R code like a pro.
Use a coding agent
AI coding agents have more power, flexibility, and coding-focused tools than general-purpose chatbots.
Anthropic’s Claude Code and OpenAI’s Codex agents have versions that run in a terminal, IDE extensions, desktop and mobile apps, and other integrations.
R users may also be interested in Posit’s Posit Assistant, which is designed for data analysis in both R and Python. It needs less setup for R than general-purpose coding agents, and it has more built-in knowledge about data science, R package development, and Shiny apps. Plus, it can read objects in your R and Python environments by default, which can be useful in some situations (although perhaps not if you’re working with sensitive data). There are versions of Posit Assistant for RStudio, the Positron IDE, and the terminal. Setup info is here.
Note: Posit Assistant is not the same as the older Positron Assistant that was demo’d at last year’s posit::conf(). The older assistant will eventually be superceded by Posit Assistant. Posit Assistant comes pre-installed with RStudio but not pre-activated, so you don’t need to use it unless you want to.
Google’s original entry in this space, Gemini CLI, is being retired in favor of a new “Antigravity CLI” starting June 18.
There are other IDE platforms with built-in agents, including Cursor and Windsurf, and terminal + subscription coding agents such as Warp, which was open-sourced in April. However, I won’t be covering those here.
You may be limited at work by what your employer allows you to use, but you can still experiment on your own with public data — and then lobby for a new agent if a different one better meets your needs. Whatever you choose, though, moving to one of these from a web-based chatbot should produce better code.
“The shift from chatbot to agent is the most important change in how people use AI since ChatGPT launched,” says Ethan Mollick, co-director of the Wharton School’s Generative AI Labs at the University of Pennsylvania.
Set up CLAUDE.md, AGENTS.md, or GEMINI.md knowledge files
All the major coding agents look for knowledge files to load each time you start a session, and you can easily edit those files. The files can include things like your proficiency in various languages and how you like to document projects. For example, I tell my LLMs that I’d like a README.md in every project with info on how to use the project and technical info on how the project was coded.
Most coding tools let you have both an overarching main file that’s loaded into every session, and an additional file per project.
If you’re adding Claude or Codex to an existing code base, the /init slash command will create one of those .md project files after scanning and analyzing the code. You can also ask an LLM to interview you to create or add to one of those files.
Claude Code looks for a user-level main CLAUDE.md file at ~/.claude/CLAUDE.md and then a project-level file at ./CLAUDE.md or ./.claude/CLAUDE.md. The /memory slash command shows where those files are located. Codex uses AGENTS.md files. Antigravity docs say it looks for a main GEMINI.md file plus GEMINI.md and/or AGENTS.md files in your working directory.
Positron Assistant is set up to read AGENT.md, AGENTS.md, POSITRON.md, CLAUDE.md, GEMINI.md, and LLMS.txt in a workspace root directory, according to the docs. See the Positron docs for more on custom instructions.
Use agent skills
Agent skills can turn an LLM with questionable R knowledge into an expert that understand how you want it to write code. You can develop your own skills, work with your LLM to create skills, or download skills written by others. Claude even has a skill to help you build skills. This is one of the best ways to stop having to repeat the same instructions over and over. Instead, the LLM will “remember” what’s in your skills files by loading them when they’re needed.
What’s the difference between the knowledge .md files mentioned above and a skill? I like to think of CLAUDE.md or AGENTS.md files as important background info that’s always available, while skills are more specific instructions that are useful at certain times. Or, as Claude Opus 4.7 put it: “Skills are for triggered workflows (‘when user asks X, do Y’). A standing rule that applies to every project isn’t trigger-based; it’s a directive I should always follow.” Standing rules should go in CLAUDE.md.
“Create a skill when you keep pasting the same instructions, checklist, or multi-step procedure into chat, or when a section of CLAUDE.md has grown into a procedure rather than a fact,” according to Anthropic’s Claude Code docs. “Unlike CLAUDE.md content, a skill’s body loads only when it’s used, so long reference material costs almost nothing until you need it.” Only skill descriptions are loaded at the start of each session, so the LLM knows what skills are available.
Anthropic originally created skills for Claude in October 2025 and then published the concept as an open standard a couple of months later. Most coding agents now use them.
Anthropic has an easy-to-folllow guide to creating custom skills here if you want to try your hand at building your own.
Posit Assistant comes with several R-related skills built in and allows users to add more. You’ll find them here.
If you’re not using Posit Assistant, you can add Posit-developed skills to another coding agent. Posit published a GitHub repository with skills for creating R packages, Shiny apps, and Quarto documents; for creating and resolving GitHub pull requests; for open-source R and Python package releases; for code reviews (R, Python, JavaScript/TypeScript, SQL); and for creating architectural documentation for a codebase. Browse them all here.
Read and edit the skills you download
Skills are just a folder with one or more markdown text files that have a structured YAML header. That folder can include optional resources and scripts, too. Skill instruction files are easy to read and edit, so you can make sure they do what you want. Tweak them as desired.
For example, Claude helped me write my own customized R skill. Claude leans toward tidyverse packages, but there are other packages I like a lot, too, such data.table. I made sure the R skill knows my package preferences, and under what circumstances I prefer each.
If one of your preferred procedures changes, remember to update the associated skills. Or, ask an LLM to update it for you. Keeping skills up to date will make your coding agent more useful.
Keep your CLAUDE.md or AGENTS.md files updated, too. Maybe you started off with a CLAUDE.md file that said you’re an experienced Python programmer who is just learning R. Three months from now, you might want to update your R skill level. Or, perhaps you told an AGENTS.md file that you like thoroughly documented code, but now you’d prefer a lighter touch. You may want to have your coding agent go over those files with you from time to time and ask you about the main points and whether they need updating.
Use the btw R package and its MCP server
It’s frustrating when an LLM writes code based on an ancient R package version in its training data, or when it doesn’t know about a relatively recent package at all. btw solves this problem by letting your coding agent access info about all the R packages installed on your system. That means it can write code based on your specific R environment. Plus, btw lets an LLM access variables in your current R environment via a Model Context Protocol (MCP) server.
MCP servers are a standardized way for LLMs to access external data — in this case, your running R session (external doesn’t have to mean cloud). Like skills, MCP was created by Anthropic as an open standard and has since been adopted by most major AI platforms. The btw R package includes an MCP server, which you can install for Claude Code by running the following code in a terminal window (not R console).
claude mcp add -s "user" r-btw -- Rscript -e "btw::btw_mcp_server()"
btw comes with a lot of tools. It’s not a great idea to overload your LLM with tools it may never use. If you just want to register btw tools for accessing your R session and looking up package documentation, you can run a command like this instead:
To connect Claude Code to your open R session, you also need to run btw::btw_mcp_session()in every new R session. (I sometimes forget this part until I’m puzzled why Claude can’t read my R variables or even see what packages I have installed.)
You can see a demo of btw in this Posit video that compares Claude Code and Posit Assistant.
The btw R package lets Claude Code and other agents read objects in your R session.
Foundry
You don’t need to do this setup for Posit Assistant, since tools for accessing your R session and variables are built in.
Use plan mode for your projects
I cannot stress this enough. Just as humans benefit from having a plan before starting to implement a project, LLMs benefit from working through a plan before beginning to generate code. Plus, it can be useful at times to “brainstorm” with an LLM about structures and features, ask it for alternatives, or even have another LLM review a plan before implementing it.
Anthropic advises starting with plan mode. “Letting Claude jump straight to coding can produce code that solves the wrong problem. Use plan mode to separate exploration from execution,” they wrote in a best practices doc.
Claude, Codex, Gemini, and Posit Assistant all have a plan mode in their CLI versions that can be activated with the /plan slash command.
Foundry
When in plan mode activated with /plan, Claude will often ask questions before coming up with its plan.
Foundry
Make sure your coding agent learns from its mistakes
This is one of the best tips I read first from Joe Amditis, associate director of operations at the Center for Cooperative Media at Montclair State University: If your coding agent makes a mistake and you work together to fix it, make sure to save that memory so it doesn’t make the same error again.
Your agent may have an auto memory system that’s supposed to do some of this (I’ve used Claude Code’s), but you can instruct any coding agent to keep a separate lessons learned file for each project, too, or ask it what’s the best way to ensure it doesn’t make the same error again. This isn’t a guarantee, any more than you can be assured an LLM will follow all the rules in a CLAUDE.md or AGENTS.md file or all the steps in a skill. But it has definitely cut down on my agents making the same errors over and over.
Have your agent write tests and do code reviews
Tests and code reviews done by a coding agent aren’t a substitute for a human checking that software works. Review an LLM’s results yourself any time a task is important! However, agent-generated tests are still a good way to head off some problems and cut down the time you spend as your LLM’s debugging partner. If you don’t know where to start to help your agent know how to test and review code, see Posit’s testing-r-packages and critical-code-reviewer skills. Your agent may also have built-in code review skills, such as Claude Code’s /code-review slash command.
Code review skills are available from many sources. For example, Sentry has a code review skill in its repository. Aimed specifically at its project’s needs, it can be a useful sample for similar skills. And superpowers is a popular set of general-purpose programming skills that’s billed as “a complete software development methodology for your coding agents, built on top of a set of composable skills and some initial instructions that make sure your agent uses them.” I don’t use superpowers, but a lot of other people clearly do given its more than 227,000 GitHub stars and 20,000 forks.
Another tip: Several experts suggest using a different LLM — maybe even from a different provider — to conduct a code review, since each model has its own strengths and weaknesses.
Don’t forget general prompting good habits
Whatever programming language you’re using, being clear will improve your outputs. Keep your requests targeted, and don’t expect the LLM to read your mind.
“Codex handles complex work better when you break it into smaller, focused steps,” OpenAI says in its developer docs. “Smaller tasks are easier for Codex to test and for you to review. If you’re not sure how to split a task up, ask Codex to propose a plan.”
“Take time to make your prompts as relevant as possible, just as you would when helping a new teammate scope a task,” Google advises in its Five Best Practices for Using AI Coding Assistants. “Consider what details you need to share for a person to succeed, and provide all those details to your AI tool.”
And, don’t load up your context window to the LLM’s published limit. Performance often degrades as you get close to the maximum token limit.
Take advantage of open LLMs, particularly if you have budget and token limits
Open-weight models — especially ones small enough to run on a desktop computer — may never rival frontier LLMs like Claude, GPT, or Gemini. But for a lot of R coding, they don’t need to.
To see how well an LLM can write R code, it should have the same kind of harness that Claude Code, Codex, or Posit Assistant gives larger LLMs. “The harness is the product,” argues Mallory Mejias at Sidecar, an AI education company. “The model is the engine inside it — important, but increasingly interchangeable.” I wouldn’t go that far, since I still find the LLM to be a critical piece of this equation, and models differ. But the same LLM will perform differently depending on the tools and context it has.
Posit recently added Google’s open-source Gemma 4 26B to Assistant’s existing options of larger, closed-source LLMs. “Up until this point, models of this size — small enough to run comfortably on high-end consumer laptops — were on our radar but not yet capable enough to drive an agent harness like Posit Assistant,” Posit senior software engineer Simon Couch wrote on the Posit blog. “This has changed in the last few months with releases like Gemma 4.” However, to use it in Posit Assistant in RStudio, you still need to run it through a Posit AI subscription, not locally. It uses 1/10 the budget that the same session with Claude Sonnet would consume.
Several projects can use Claude Code to run local LLMs. Ollama, open-source software for running LLMs locally, does this with the terminal command ollama launch claude --model , such as:
ollama launch claude --model gemma4:26b
The makers of Unsloth, an open-source framework for running and training models, say running local LLMs inside Claude Code can be very slow due to a cache invalidation issue. They say this can be fixed by adding "CLAUDE_CODE_ATTRIBUTION_HEADER" : "0" to ~/.claude/settings.json under “env”.
Unsloth can also use Claude Code to run local models, but it’s somewhat more involved to install and set up than Ollama. See this Unsloth tutorial.
Open-source coding agent Open Code runs LLMs from OpenAI, Anthropic, Google, Kimi, Alibaba’s Qwen, and others. I haven’t warmed up to it yet compared with commercially backed CLI tools I’ve tried, but it has 174,000 GitHub stars so clearly a lot of fans.
AI consultant Thomas Wiegold, who switched from Claude to Open Code, said “OpenCode covers everything I need for my daily workflow. It’s fast, the provider flexibility is genuinely useful rather than theoretical, and the TUI is better for extended sessions…. That said, I’m not going to pretend it’s all smooth sailing.” He noted some stability issues and a remote code execution vulnerability earlier this year.
Large language models remain imperfect and unpredictable tools, but they’re improving rapidly — as are the harnesses around them. Even frontier LLMs in commercial coding agents can ignore instructions at times and otherwise behave in unpleasantly surprising ways. However, you’ll vastly improve your chances of generating quality code if you use coding agents, take time to set them up with quality instructions, and remember good prompting techniques. Good luck!
—
Coding agent info
Claude Code – Anthropic’s coding agent is available in the terminal and as an IDE extension, a desktop app, mobile apps, Slack app, and a cloud version that can work directly in your repos on GitHub. Arguably the first breakthrough coding agent, it now includes an elegant remote-control option where you can start a session on your desktop and then continue it on a phone or tablet. While designed for Claude LLMs, you can use it to run local LLMs via tools like Ollama or Unsloth Studio. When using Claude models, it tends to offer less usage than other vendors’ options. Anthropic has posted the terminal version’s code on GitHub, with usage governed by Anthropic’s commercial terms of service. You can use Claude Code via API pay per use or as part of a Claude subscription.
Codex – OpenAI’s answer to Claude Code is available via terminal, app, IDE extension, or cloud, with integrations for GitHub, Slack, and Linear. The CLI tool is open source under an Apache license, available on GitHub, and works via API pay per use or as part of a ChatGPT subscription.
Posit Assistant – The Posit (formerly RStudio) coding agent is designed for data work in R and Python, although Posit senior software engineer Simon Couch told me it would do fine for programming work for other uses and in other languages. It is available for the RStudio IDE (via a Posit AI subscription in RStudio), Positron IDE, and as a stand-alone CLI terminal app, although the CLI tool currently doesn’t feel as full-featured as the IDE integrations (that may change). As of this writing, you can also use API keys from Anthropic, OpenAI, and Snowflake Cortex and a GitHub Copilot account in Positron. Posit Assistant is being updated quite frequenty, Couch told me. If you tested it a month or two ago, it has more capabilities now.
Antigravity CLI – Google’s terminal-based tool will be replacing the Gemini CLI for unpaid and Google One users this month. There’s also an Antigravity IDE, SDK, and platform for orchestrating multiple agents. One advantage of Antigravity: Google offers a free plan with access to Gemini 3.5 Flash, Gemini 3.1 Pro, Gemini 3 Flash, Claude Sonnet 4.6, Claude Opus 4.6, and gpt-oss-120b, and what it describes as “generous” but undefined weekly rate limits based on “the degree we have capacity.”
A new study challenges the widely accepted idea that word meanings are organized around emotion. After analyzing billions of words, scientists found that language may be shaped by something more basic: the need for safety. Researchers at the University of Vermont have found a new way to understand language, challenging a major assumption in psychology, [...]
Scientists have discovered that the brain’s sensory systems play a much larger role in speech learning than previously believed. New research suggests that learning to speak a new language, or recovering speech after injury, relies more heavily on the brain’s sensory systems than on regions responsible for controlling movement. The findings, from researchers at McGill [...]