Imagine trying to solve a puzzle but with only half the pieces. Your puzzle will always fall short, missing key elements that reveal the whole picture. This is the challenge you can face when applying AI to your code. Without access to the right kind of data, even the most advanced AI models face limitations in their ability to transform, analyze or understand software at scale.
Code isn’t just text — it’s a living, interconnected system of logic, dependencies and relationships. Code representations such as abstract syntax trees (ASTs) offer a step forward from raw text, providing structure and syntax awareness. But it can still leave handfuls of additional puzzle pieces in the box.
When it comes to modernizing and maintaining codebases at scale — working across hundreds, if not thousands, of repositories at once — completeness and accuracy are keys. Let’s take a Java 21 upgrade as an example of the challenge.
A single repository might contain obvious migration challenges, including deprecated methods or API changes, but if you’re only looking at one repo at a time, you’re missing the broader picture. The reality is that most organizations operate multiple interdependent repositories, with shared libraries, transitive dependencies and legacy integrations that must all evolve in sync. One of our customers had over 15,000 codebases to upgrade to Java 21, which they estimated would take 50,000 hours to complete manually (that’s 687 days for 10 engineers working 8-hour days!). Where do they even start!?
You might upgrade one repo to Java 21 only to realize that another repo, on which it depends, still relies on Java 11 conventions, causing unexpected runtime failures. Even worse is the scenario where a shared internal library gets updated, breaking dozens of services downstream that weren’t even aware they were relying on an outdated method. Without a multi-repo view, you are upgrading in the dark, reacting to failures instead of proactively ensuring a smooth transition. You need to have all the puzzle pieces interlocked to have a clear picture.
Generative AI models, even those trained on vast amounts of code, are passive assistants — they generate suggestions based on patterns but lack deep understanding of a unique codebase’s structure, dependencies and execution context.
Let’s talk about the code data problem and what’s needed to enable agentic experiences that can drive code analysis and refactoring at scale.
AI is Only as Smart as Your Code Data
To move beyond code suggestions and into meaningful action at scale, AI needs more than surface-level structure — it needs deep, contextual understanding of your source code. This structured data is vital for handling code transformations at scale, but not all structured data is created equal. Various tools and AI models rely on ASTs, which provide a syntax-aware view of code. However, ASTs lack the deep context required for accurate, meaningful transformations.
An AST represents the structure of code but omits key details such as formatting, type information and environmental context. This ‘abstract’ view is useful for basic analysis but results in a lossy representation for more complex tasks. For example, a scanner searching for vulnerabilities like Log4Shell might flag any ‘Logger’ reference — unable to distinguish between Log4J and other logging libraries — leading to false positives and extra work for developers. Differentiating between a logger.info call in SLF4J and Log4J might seem trivial, but without metadata, an AST-based approach lacks the context to handle such cases accurately.
While your integrated development environment (IDE) has a more complete picture, its scope is limited to active repositories. For AI to truly understand and refactor code at scale, it needs a better real-time data source.
We’ve found that the lossless semantic tree (LST) — a rich, machine-readable representation of code that’s part of the open-source OpenRewrite project — offers the most comprehensive view of a codebase. An LST is not just a syntactic representation; it is enriched with metadata about the code’s environment. It includes information such as types in use, transitive dependencies, build tools and configuration files. Unlike other code data formats, LST ensures transformations are not only syntactically correct but also semantically meaningful.
Finally, you can see all the puzzle pieces laid out in front of you, organized by color and shape and ready for assembly. The focused and accurate data from LST gives AI a solid foundation for acting on code, grounding its reasoning, reducing hallucinations and opening the door to scalable modernization. But unlocking that potential requires more than just good data. Tool calling is the next critical step — giving AI structured, reliable access to that data and the means to act on it.
The Counterbalance of Determinism and AI
To truly scale code modernization, AI needs structured execution paths, access to high-quality code data and the ability to take reliable action. That’s where agentic AI comes in, moving beyond passive code suggestions into autonomous planning, execution and adaptation. But for these agents to operate effectively, they must be equipped with tools they can trust to perform consistent, accurate work.
That capability came into focus in 2024 with the advent of tool-function calling through tool-calling paradigms such as Model Context Protocol (MCP) and OpenAI agent framework. This breakthrough enabled AI agents to combine the predictive reasoning of LLMs with the precision of deterministic tools. Practically overnight, thousands of existing OpenRewrite recipes — each one a deterministic program capable of safely and predictably operating on the LST code representation — became callable tools for AI agents.
Tool calling works by providing the AI agent with a ‘toolbox’ of capabilities it can invoke based on the task at hand. These tools might include recipes to upgrade logging frameworks, replace deprecated APIs, or scan for security vulnerabilities across an organization’s codebase. Through APIs, these recipes become executable actions the AI can request, rather than having to generate or guess the implementation logic itself. It’s like being able to find just the right puzzle piece more quickly to bring the full picture into view — accelerating transformation while reducing risk.
Here’s how it works in practice: An AI agent receives a prompt — say, ’Upgrade all services to Java 21 and ensure compatibility with internal libraries.’ It assesses the request, determines which tools (i.e., recipes) are relevant, and calls those tools via APIs to execute specific transformations across the codebase. The agent can then incorporate the returned results into its reasoning, adjusting its plan, verifying success or triggering additional actions as needed. This closed-loop process — analyze, act, evaluate — enables scalable, autonomous code modernization with human-level oversight.
By invoking OpenRewrite recipes through tool calling, AI agents gain the execution power they need, backed by the full-fidelity LST data. Every code change becomes traceable, predictable and consistent, eliminating the variability and risk associated with purely generative approaches. AI no longer just suggests solutions — it becomes an orchestrator of real-world impact, able to coordinate massive transformations across thousands of repositories with precision.
Scalable Modernization With AI and Better Code Data
There’s a world where your codebase modernization efforts have all the pieces assembled to execute efficiently. This is the next evolution of software engineering — where AI agents, deterministic tools and rich code data work together to drive continuous modernization at scale. By delivering the richest representation of code data, LSTs enable deterministic recipes to act with precision, while AI interprets complex results and provides actionable insights.
Organizations that embrace LST-based approaches gain the ability to manage massive codebases with confidence, whether refactoring legacy systems, enforcing security or optimizing dependencies. Scalable transformation happens when AI meets the right code data — together, they unlock what’s next.