AI use may speed code generation, but developers’ skills suffer 31 Jan 2026, 1:03 am

There’s a lot of hype about AI coding tools and the gains developers are seeing when it comes to speed and accuracy. But are developers also offloading some of their thinking to AI when they use them as copilots?

Anthropic researchers recently put this to the test, examining how quickly software developers picked up a new skill (learning a new Python library) with and without AI assistance, and, more importantly, determining whether using AI made them less likely to actually understand the code they’d just written.

What they found: AI-assisted developers were successfully performing new tasks, but, paradoxically, they weren’t learning new skills.

This isn’t particularly surprising, according to real-world software engineers. “AI coding assistants are not a shortcut to competence, but a powerful tool that requires a new level of discipline,” said Wyatt Mayham of Northwest AI Consulting.

AI users scored two letter grades lower on coding concepts

In a randomized, controlled trial, a group of 52 “mostly junior” developers were split into two groups: One was encouraged to use AI, one denied its use, performing a short exercise interacting with the relatively new asynchronous Python Trio library that involved new concepts beyond just Python fluency. The chosen engineers were familiar with both Python and AI coding assistants, and had never used the Trio library.

Researchers then quizzed them on their mastery of debugging and code reading and writing, as well as their ability to understand core tool and library principles to help them assess whether AI-generated code follows appropriate software design patterns.

The results: The AI-using group scored 17 percentage points lower on the quiz than a control group who coded by hand — that is, 50% compared to 67%, or the equivalent of nearly two letter grades. This was despite the quiz having covered concepts they’d used just a few minutes before.

Notably, the biggest gaps in mastery were around code debugging and comprehension of when code is incorrect and why it fails. This is troubling, because it means that humans may not possess the necessary skills to validate and debug AI-written code “if their skill formation was inhibited by using AI in the first place,” the researchers pointed out.

The experiment in depth

The 70-minute experiment was set up like a self-guided tutorial: Participants received a description of a problem, starter code, and a quick explainer of the Trio concepts required to solve it. They had 10 minutes to get familiar with the tool and 35 minutes to perform the task of coding two different features with Trio. The remaining 25 minutes was devoted to the quiz.

They were encouraged to work as quickly as possible using an online coding platform; the AI group could access a sidebar-embedded AI assistant that could touch code at any point and produce correct code if asked. The researchers took screen recordings to see how much time participants spent coding or composing queries, the types of questions they asked, and the errors they made.

Interestingly, using AI didn’t automatically guarantee a lower score; rather, it was how the developers used AI that influenced what skills and concepts they retained.

Developers in the AI group spent up to 30% of their allotted time (11 minutes) writing up to 15 queries. Meanwhile, those in the non-AI group ran into more errors, mostly around syntax and Trio concepts, than the AI-assisted group. However, the researchers posited that they “likely improved their debugging skills” by resolving errors on their own.

AI group participants were ranked based on their level and method of AI use. Those with quiz scores of less than 40% relied heavily on AI, showing “less independent thinking and more cognitive offloading.” This group was further split into:

  • AI delegators: These developers “wholly relied” on AI, completing the task the fastest and encountering few or no errors;
  • ‘Progressive’ AI users: They started out proactively by asking a few questions, then devolved into full reliance on AI;
  • Iterative AI debuggers: They also asked more questions initially, but ultimately trusted AI to debug and verify their code, rather than clarifying their understanding of it.

The other category of users, who had quiz scores of 65% or higher, used AI for code generation as well as conceptual queries, and were further split into these groups:

  • Participants who generated code, manually copied and pasted it into their workflows, then asked follow-up questions. They ultimately showed a “higher level of understanding” on the quiz.
  • Participants who composed “hybrid queries” asking for both code and explanations around it. This often took more time, but improved their comprehension.
  • Participants who asked conceptual questions, then relied on their understanding to complete the task. They encountered “many errors” along the way, but also independently resolved them.

“The key isn’t whether a developer uses AI, but how,” Mayham emphasized, saying these findings align with his own experience. “The developers who avoided skill degradation were those who actively engaged their minds instead of passively accepting the AI’s output.”

Interestingly, developers in the experiment were aware of their own habits. While the non-AI-using participants found the task “fun” and said they had developed an understanding of Trio, AI-using participants said they wished they had paid more attention to the details of the Trio library, either by reading the generated code or prompting for more in-depth explanations.

“Specifically, [AI using] participants reported feeling ‘lazy’ and that ‘there are still a lot of gaps in (their) understanding,’” the researchers explained.

How developers can keep honing their skills

Many studies, including Anthropic’s own, have found that AI can speed up some tasks by as much as 80%, however, this new research seems to indicate that sometimes speed is just speed — not quality. Junior developers who feel they have to move as quickly as possible are risking their skill development, the researchers noted.

“AI-enhanced productivity is not a shortcut to competence,” they said, and the “aggressive” incorporation of AI into the workplace can have negative impacts on workers who don’t remain cognitively engaged. Humans still need the skills to catch AI’s errors, guide output, and provide oversight, the researchers emphasized.

“Cognitive effort — and even getting painfully stuck — is important for fostering mastery,” they said.

Managers should think “intentionally” when they deploy AI tools to ensure engineers continue to learn as they work, the researchers advised. Major LLM providers provide learning environments, such as Anthropic’s Claude Code Learning and Explanatory modes, or OpenAI’s ChatGPT Study Mode, to assist.

From Mayham’s perspective, developers can mitigate skill atrophy by:

  • Treating AI as a learning tool: Ask for code and explanations. Prompt it with conceptual questions. “Use it to understand the ‘why’ behind the code, not just the ‘what,’” he advised.
  • Verifying and refactoring: “Never trust AI-generated code implicitly.” Always take the time to read, understand, and test it. Oftentimes, the best learning comes from debugging or improving AI-provided code.
  • Maintaining independent thought: Use AI to augment workflow, not replace the thinking process. “The goal is to remain the architect of the solution, with the AI acting as a highly-efficient assistant,” said Mayham.

AI-driven productivity is not a substitute for “genuine competence,” especially in high-stakes, safety-critical systems, he noted. Developers must be intentional and disciplined in how they adopt tools to ensure they’re continually building skills, “not eroding them”. The successful ones won’t just offload their work to AI, they’ll use it to ask better questions, explore new concepts, and challenge their own understanding.

“The risk of skill atrophy is real, but it’s not inevitable. It’s a choice,” said Mayham. “The developers who will thrive are those who treat AI as a Socratic partner for learning, not a black box for delegation.”

(image/jpeg; 1.54 MB)

Google expands BigQuery with conversational agent and custom agent tools 30 Jan 2026, 12:46 pm

Google has added Conversational Analytics to its BigQuery data warehouse, which it says will allow enterprise data teams and business users to ask questions about data in natural language, in turn speeding up data analytics for AI use cases.

The agent, currently in preview, can be found under the Conversations tab in the new Agents Hub inside BigQuery and activated by pointing to data tables. It expands the data warehouse’s current text-to-SQL capabilities, analysts say.

“BigQuery already offers features like data canvas to make query generation and visual exploration easier. What changes with the agent is not the ability to ask questions in simple language, but the ability to carry a contextual conversation with the data over multiple steps, which can be defined as conversational analytics,” said Abhisekh Satapathy, principal analyst at Avasant.

“Instead of treating each prompt as a one-off request, the new agent remembers what was asked earlier, including datasets, filters, time ranges, and assumptions, and uses that context when answering follow-up questions. This lets users refine an analysis progressively rather than starting from scratch each time,” Satapathy added.

Satapathy pointed out that this eases the pressure on developers to prebuild dashboards or predefined business logic for every possible question that a data analyst or business user could ask.

“Rather than encoding every scenario upfront, teams can let the agent interpret user intent dynamically, while still enforcing access controls, metric definitions, and governance rules already defined in BigQuery,” he said.

Ability to build and deploy custom agents via API endpoints

In addition to the agent, Google has also added tools to build, deploy, and manage custom agents across applications and operational workflows via API endpoints to the Agent Hub.

These tools, according to Satapathy, address three practical enterprise needs: “It reduces duplication of analytics logic across tools, ensures consistent definitions and policies across all analytics users, and centralizes access control and auditing rather than implementing them separately in each application.”

The reduction in duplication also frees up developers as they no longer have to rebuild logic to interpret user questions, map them to datasets, apply security rules, or explain results, Satapathy added.

Custom agents can also be deployed via Looker, which has a built-in conversational analytics feature.

Continued Text-to-SQL improvements

Over the past few months, Google has been adding natural language and SQL abilities to BigQuery to help developers and data analysts with SQL querying.

Earlier this month, it previewed a Comments to SQL feature that is aimed at enabling developers and data analysts to write natural-language instructions in SQL comments and have them translated into executable queries inside BigQuery Studio via Gemini.

Last November, Google added three new managed AI-based SQL functions — AI.IF, AI.CLASSIFY, and AI.SCORE — to help enterprise users reduce the complexity of running large-scale analytics, especially on unstructured data. In August, Google made incremental updates to the data engineering and data science agents in BigQuery.

Rivals, such as Snowflake and Databricks, have also been prepping natural language to SQL capabilities for their offerings.

While Databricks already offers AI Functions that can be used to apply generative-AI or LLM inference directly from SQL or Python, Snowflake provides AI_PARSE_DOCUMENT, AISQL, and Cortex functions for document parsing, semantic search, and AI-driven analytics. Other warehouses, such as Oracle’s Autonomous Data Warehouse, also support AI workflows alongside SQL.

(image/jpeg; 1.17 MB)

Are you ready for JavaScript in 2026? 30 Jan 2026, 9:00 am

I am loath to inform you that the first month of 2026 has expired. We have now entered the second quarter of the 21st century. These are the opening acts of the millennium.

Fortunately, it looks like AI 2027 may not pan out and we may, as yet, avoid LLM doom. We almost definitely won’t have a superintelligence that absorbs the power grid for its own purposes. And furthermore, we will probably still have human programmers at the end of this year.

All good news. Also, it’s comforting to see that some things never change. This month’s report brings all kinds of interesting developments unfolding in the world of JavaScript, including TypeScript’s new type stripping feature, Angular’s more modern reactive workflow, and Hotwire, the HTMX-powered JSON alternative on the rise.

Top picks for JavaScript readers on InfoWorld

TypeScript levels up with type stripping
This is the biggest thing to hit TypeScript since its inception. No more source maps, and no more waiting to compile. By treating types as white space, modern runtimes like Node are unlocking a no-build TypeScript that keeps stack traces accurate and workflows clean.

Get started with Angular: Introducing the modern reactive workflow
Combining a more community-engaged development approach with impressive technical updates, Angular has quickly become one of the most interesting JavaScript projects to watch. Here’s a hands-on guide to modern JavaScript development with Angular.

Intro to Hotwire: HTML over the wire
Reclaim your developer experience by keeping the logic in one place, on the server. HTML-based Hotwire offers an articulate counterpoint to the complexity of modern SPAs, proving that sometimes the best way forward lies with the technologies of the past.

React tutorial: Get started with the React library
Despite the endless churn of new frameworks, React remains the quintessential reactive engine. This updated guide walks you through the fundamentals of React development, including a This is Spinal Tap variant on the canonical counter application. Sometimes, your components just need to go to 11.

More good reads and JavaScript updates elsewhere

jQuery 4. 0. 0: The library that refuses to die
Almost 20 years to the day since its debut, jQuery 4. 0 has landed. It’s not just a legacy patch; it’s a full migration to the ES modules, and a goodbye to IE 10. For those who remember when $ was the only way to keep the DOM under control, it’s comforting to see this fresh start for the web’s standard library.

Introducing the HTML element
Instead of a script-triggered action, is a declarative element. This is designed to be a UX and security improvement and it is available now, in the latest Chrome (144) release. Similar updates are planned for camera and microphone.

ChatGPT containers can now run bash, pip/npm install packages, and download files
Some way or another, the LLM and the IDE are going to merge. In fact, it seems like every purpose-built app is going to be Borged by AI, even if exactly how is yet to be discovered. These latest upgrades to ChatGPT’s sandboxed runtime container might raise a question or two.

(image/jpeg; 14.76 MB)

The best free cloud computing courses in 2026 30 Jan 2026, 9:00 am

The cloud isn’t new, but the way enterprises use it keeps evolving. AI workloads, new platform services, and tighter governance mean teams can’t rely on outdated knowledge. The real issue isn’t ignorance but drift. Assumptions once valid are now proven wrong through outages, security rework, or surprise bills.

That’s why free, on-demand courses have become strategically advantageous. They’re frictionless to start, easy to standardize across teams, and effective at establishing a shared vocabulary. If you can align hundreds of people on core concepts in a month without budget approvals, you can remove an enormous amount of organizational drag.

What to look for in free cloud courses

Most free training fails in one of two ways. It either turns into marketing content with a few diagrams or becomes a click-through tour of a console and doesn’t teach decision-making. When I evaluate a free course for enterprise use, I’m looking for content that changes how someone thinks, not just tells them what buttons to push. Here’s my criteria:

First, it must teach durable concepts that transfer across providers, topics such as regions and resiliency, identity boundaries, networking fundamentals, observability, and cost mechanics. A course that can’t explain why architectures break or why bills rise is not foundational training. It’s vendor orientation.

Second, it needs to be truly on-demand and modular. Enterprises don’t learn on a schedule; they learn between sprints and incidents. The most useful free training lets teams move quickly through familiar sections and slow down on unfamiliar material without losing coherence.

Third, I want a clear scope anchored to something recognizable, such as a blueprint for fundamentals certification or a well-structured learning path. This matters because “free content sprawl” is real; people watch a few random videos and think they’re trained. A structured path reduces gaps and makes completion measurable, which is why I like how Microsoft Learn organizes fundamentals content into a formal training path.

Fourth, the course should connect concepts to operations. Hands-on labs are great, but I’d rather see practical framing. If a course never addresses governance, identity, or shared responsibility in ways that align with real-world enterprise practices, it will foster false confidence.

Finally, freshness matters. Cloud platforms evolve continuously, and the best provider-run free training tends to stay current with the latest terminology and service direction. AWS, for example, positions AWS Skill Builder as a central portal for digital training, which is partly why its free catalog remains a common baseline in enterprises.

Are free courses better than paid?

Free courses tend to win on a time-to-value metric. You can enroll a whole team today, establish baseline literacy this week, and stop having unproductive debates about terminology in the next sprint. That is a real operational benefit. Fewer misunderstandings mean fewer design errors and fewer late-stage corrections.

Free courses are also scaled well for standardization. If your organization is rolling out a cloud center of excellence, a platform team, or a finops initiative, you need a common language. Paid training often trains individuals; free training can train the organization.

There’s another subtle advantage: Provider-authored fundamentals courses teach the provider’s “intended mental model.” That’s not the same as neutral truth, but it’s extremely useful when you’re building on that platform. It helps teams understand how the provider expects identity, networking, and service boundaries to be used, thereby reducing troubleshooting time and architectural friction.

Where paid courses still win

Paid training tends to outperform in depth and context. A good instructor-led course can compress months of trial and error into a week, especially in content areas such as architecture trade-offs, incident response, or security design. Also, paid programs frequently include curated labs, graded assessments, and real-time feedback. Free courses rarely provide those at the same level.

Paid courses can be especially valuable when you need a capability quickly for a high-stakes delivery. If you’re building a regulated workload, redesigning an identity model, or implementing a platform engineering program, the cost of getting it wrong dwarfs the cost of training. That’s when paying for course expertise can be the cheaper option.

But paying isn’t a guarantee of quality. Some paid offerings are simply extended versions of free material with better packaging. The most effective enterprise pattern is to use free, on-demand courses to establish a universal baseline, then spend the budget surgically on advanced topics where hands-on coaching and scenario work produce clear ROI.

Five free courses worth your time

In alphabetical order:

  • AWS Cloud Practitioner Essentials via AWS Skill Builder is a reliable entry point to AWS fundamentals. It’s designed to build a baseline understanding of cloud concepts and explain how AWS frames core services and responsibility boundaries. Even in multicloud organizations, AWS fluency reduces confusion because AWS terminology often leaks into broader enterprise discussions.
  • Google’s Cloud Computing Fundamentals course template on Google Skills offers a provider-specific fundamentals view, emphasizing compute options and how Google frames the platform. I like this course as either a primary path for Google Cloud shops or a secondary perspective for multicloud teams seeking to avoid provider tunnel vision.
  • The Linux Foundation’s Introduction to Cloud Infrastructure Technologies is valuable because it grounds cloud learning in open source infrastructure concepts rather than a single hyperscaler’s service catalog. That matters when your enterprise includes Kubernetes, containers, and portability debates, because those issues live in the open source layer more than in the provider layer.
  • Microsoft Learn’s Azure Fundamentals, particularly the training path focused on cloud concepts, is a strong option for teams in Microsoft-heavy environments. The material is self-paced and structured to support standardization across large groups. It also integrates governance themes early, which aligns with how Azure is adopted in many enterprises.
  • Oracle’s “Learn Oracle for Free” path to becoming an OCI Foundations Associate belongs on the list because Oracle Cloud Infrastructure appears in real enterprise portfolios, particularly when Oracle workloads, commercial agreements, or specific performance needs influence platform choices. Oracle explicitly positions the path as free training aligned with foundational OCI knowledge. Even if you don’t standardize on OCI, understanding it helps when you inherit it through acquisitions or packaged enterprise systems.

Using courses in the enterprise

If you’re training one person, you can optimize for their learning style. If you’re training an enterprise, you should optimize for consistency and outcomes. The goal is not to create a population of hobbyists; it’s to reduce avoidable production errors and accelerate sound decision-making.

A practical approach is to select one primary provider course aligned with your dominant cloud, assign one alternate-provider fundamentals course to broaden thinking, and add the Linux Foundation option to anchor the team in portable concepts. You then reinforce the material internally with a short set of standards specific to your situation: What does good identity hygiene mean in your company? What do approved network patterns look like? What cost and resiliency checks must occur before production? Training creates the language; internal standards create the behavior.

(image/jpeg; 10.18 MB)

Who profits from AI? Not OpenAI, says think tank 30 Jan 2026, 2:15 am

Findings from a new study by Epoch AI, a non-profit research institute, appear to poke major holes in the notion that AI firms, and specifically OpenAI, will eventually become profitable.

The research paper  written by Jaime Sevilla, Hannah Petrovic and Anson Ho, suggests that while running an AI model may generate enough revenue to cover its own operating costs, any profit is outweighed by the cost of developing the next big model. So, it said, “despite making money on each model, companies can lose money each year.”

The paper seeks to answer three questions: How profitable is running AI models? Are models profitable over their lifecycle? Will AI models become profitable?

To answer question one, researchers created a case study they called the GPT-5 bundle, which they said included all of OpenAI’s offerings available during GPT-5’s lifetime as the flagship model, including GPT-5 and GPT-5.1, GPT-4o, ChatGPT, and the API, and estimated the revenue from and costs of running the bundle. All numbers gathered were based on sources of information that included claims by OpenAI and its staff, and reporting by media outlets, primarily The Information, CNBC, and the Wall Street Journal.

The revenue estimate, they said, “is relatively straightforward”. Since the bundle included all of OpenAI’s models, it was the company’s total revenue over GPT-5’s lifetime from August to December last year: $6.1 billion.

And, they pointed out, “at first glance, $6.1 billion sounds healthy, until you juxtapose it with the costs of running the GPT-5 bundle.” These costs come from four main sources, the report said, the first of which is inference compute at a cost of $3.2 billion. That number is based on public estimates of OpenAI’s total inference compute spend in 2025, and assumes that the allocation of compute during GPT-5’s tenure was proportional to the fraction of the year’s revenue generated in that period.

The other costs are staff compensation ($1.2 billion), sales and marketing ($2.2 billion) and legal, office, and administrative costs: $0.2 billion.

It’s all in the calculation

As for options for calculating profit, the paper stated, “one option is to look at gross profits. This only counts the direct cost of running a model, which in this case is just the inference compute cost of $3.2 billion. Since the revenue was $6.1 billion, this leads to a profit of $2.9 billion, or gross profit margin of 48%, and in line with other estimates. This is lower than other software businesses, but high enough to eventually build a business on.”

In short, they stated, “running AI models is likely profitable in the sense of having decent gross margins.”

However, that’s not the full story.

The paper stated that by buying the argument that gross margins only should be considered when looking at profitability, “on those terms, it was profitable to run the GPT-5 bundle. But was it profitable enough to recoup the costs of developing it? In theory, yes — you just have to keep running them, and sooner or later you’ll earn enough revenue to recoup these costs. But in practice, models might have too short a lifetime to make enough revenue. For example, they could be outcompeted by products from rival labs, forcing them to be replaced.”

The trick, the authors stated, revolves around comparing gross profits and comparing the nearly $3 billion to the firm’s R&D costs: “To evaluate AI products, we need to look at both profit margins in inference as well as the time it takes for users to migrate to something better. In the case of the GPT-5 bundle, we find that it’s decidedly unprofitable over its full lifecycle, even from a gross margin perspective.”

As for the big question of whether AI models will become profitable, the paper stated, “the most crucial point is that these model lifecycle losses aren’t necessarily cause for alarm. AI models don’t need to be profitable today, as long as companies can convince investors that they will be in the future. That’s standard for fast-growing tech companies.”

The bottom line, said the trio of authors, is that profitability is very possible because “compute margins are falling, enterprise deals are stickier, and models can stay relevant longer than the GPT-5 cycle suggests.”

Asked whether the markets will stay irrational for long enough for OpenAI to become solvent, Jason Andersen, VP and principal analyst at Moor Insights & Strategy, said, “it’s possible, but there is no guarantee. I believe in 2026 you will see refinements in strategy from these firms. In my brain, there are three levers that OpenAI and other general-purpose AIs can use to improve their financial position (or at least slow the burn).” 

The first, he said, is pacing, “and I think that is happening already. We saw major model drops at a slower pace last year. So, by slowing down a bit, they can reduce some of their costs or at the very least spread them out better. Frankly, customers need to catch up anyway, so they can plausibly slow down, so the market can catch up to what they already have.”

The second, said Andersen, is to diversify their offerings, and the third involves capturing revenue from other software vendors.

As to whether OpenAI and others can keep going long enough for AI to become truly effective, he said, “OpenAI and Anthropic have the best chance of going long and staying independent. But, that said, I also want to be cautious about what ‘truly effective’ means. If you mean truly effective means achieving AGI, it’s theoretical, so probably not without major breakthroughs in hardware and energy. But if ‘effective’ means reaching profitability over a period of years, then yes, those two have a shot.”

The trick on the road to profits, he said, “will be finding a way to compete and win against companies that have welded their future to AI. Notably, Google, Microsoft, and X have now made their models inextricable to their other products and offerings. So, is there enough time and diversification opportunities to compete with them? My guess is that a couple pure plays will do well and maybe even disrupt the market, but many others won’t make it.”

Describing the paper’s findings as “very linear” and based on short-term analysis,  Scott Bickley, advisory fellow at Info-Tech Research Group, said that OpenAI has been “pretty open about the fact they are not profitable currently. What they pivot to is this staggering chart of how revenues are going to grow exponentially over the next three plus years, and that’s why they are trying to raise $200 billion now to build up infrastructure that’s going to support hundreds of billions of dollars of business a year.”

Many fortunes tied to OpenAI

He estimated that OpenAI’s overall financial commitments, as a result of agreements with Nvidia and hyperscalers as well as data center buildouts, now total $1.4 trillion, and said, “They’re trying to make themselves too big to fail, to buy the long runway they’re going to need for these investments to hopefully pay off over the course of years, or even decades.”

Right now, he said, the company is “shoring up the balance sheet. They’re trying to build everything they can to buy runway ahead. But either they wildly succeed beyond any of our imagination, and they come up with applications that I can’t envision are realistic today, or they fail miserably, and they’re guaranteed that everyone can buy a chunk of the empire for pennies on the dollar or something to that effect. But I think it’s either boom or bust. I don’t see a middle road.”

As it currently stands, said Bickley, all major vendors have “tied their fortunes to OpenAI, which is exactly what Sam Altman wanted to have happen. He’s going to force the biggest players in the space to help him be successful.”

In the event the company did end up failing, he predicted the impact on companies buying AI initiatives developed by it will be minimal. “Regardless of what happens to the commercial entity of OpenAI, the intellectual property that’s been developed, the models that are there, are going to be there. They’ll fall under someone’s control and continue to be used. They’re not in any danger of not being available.”

The article originally appeared on Computerworld.

(image/jpeg; 1.88 MB)

Microsoft previews GitHub Copilot app modernization for C++ 30 Jan 2026, 1:38 am

Microsoft has launched a public preview of GitHub Copilot app modernization for C++. The company had previewed C++ code editing tools for GitHub Copilot in December. Both previews are available via the Visual Studio 2026 Insiders channel.

GitHub Copilot app modernization for C++ helps developers upgrade C++ projects to newer MSVC Build Tools versions. The public preview was announced January 27. App modernization for C++ previously became available in a private preview in November, with the launch of the Visual Studio 2026 IDE. After receiving feedback from private preview participants, Microsoft has added support for CMake projects, reduced hallucinations, removed several critical failures, and improved Copilot’s behavior when encountering an internal compiler error. Microsoft also reinforced Copilot’s understanding of when project files need to be modified to do the upgrade.

With app modernization for C++, GitHub Copilot can reduce toil incurred when adopting newer versions of MSVC, Microsoft said. GitHub Copilot will first examine a project to determine whether it can update its settings to use the latest MSVC version. Microsoft described a three-step process of assessment, planning, and execution that GitHub Copilot follows for app modernization. After updating the project settings, Copilot will do an initial build to assess if there are any issues blocking the upgrade. After confirming the accuracy of the assessment with the user, Copilot will propose solutions to any issues that need to be addressed. Once the user approves the plan, the agent completes a sequence of tasks and validates that its changes resolved the identified problems. If there remains work to be done, the agent continues iterating until the problems are resolved or the conversation is discontinued.

(image/jpeg; 6.84 MB)

Suse offers cloud sovereignty assessment tool 29 Jan 2026, 9:07 pm

Suse has unveiled a Cloud Sovereignty Framework Self Assessment tool, with the intention of helping customers understand the gaps in their compliance with the 2025 EU Cloud Sovereignty Framework.

Launched January 29, the tool is a web-based, self-service discovery platform designed to evaluate an organization’s cloud infrastructure against the EU Cloud Sovereignty Framework. The assessment provides an objective Sovereignty Effective Assurance Levels (SEAL) score, which measures the organization’s sovereignty on the eight objectives defined by the framework. The tool also provides a roadmap for closing the compliance gap by leveraging Suse solutions and its European partner ecosystem.

Key features of Suse’s tool include:

  • The SEAL benchmark, which maps the organization to one of five SEAL levels, from No Sovereignty to Full Digital Sovereignty.
  • Weighted risk analysis, which weighs eight sovereignty objectives (SOVs), prioritizing supply chain (20%) and operational autonomy (15%), showing where the most critical vulnerabilities lie.
  • Trust-based engagement, with results stored in the user’s browser.
  • Consultative roadmap, a concrete improvement plan that can be downloaded as a PDF.

In explaining the assessment, Suse noted that industry research firm Forrester expects digital and AI sovereignty to drive a private cloud renaissance with doubled year-on-year growth in 2026. With the 2025 EU Cloud Sovereignty Framework now introduced, organizations risk contract ineligibility without proven digital sovereignty. The Cloud Sovereignty Framework Self Assessment simplifies this journey, Suse said.

(image/jpeg; 1.43 MB)

New PDF compression filter will save space, need software updates 29 Jan 2026, 8:03 pm

Brotli is one of the most widely used but least-known compression formats ever devised, long incorporated into all major browsers and web content delivery networks (CDNs). Despite that, it isn’t yet used in the creation and display of PDF documents, which since version 1.2 in 1996 have relied on the FlateDecode filter also used to compress .zip and .png files.

That is about to change, though, with the PDF Association moving closer to publishing a specification this summer that developers can use to add Brotli to their PDF processors. The hope is that Brotli will then quickly be incorporated in an update of the official PDF 2.0 standard, ISO 32000-2, maintained by the International Organization for Standardization.

With PDF file sizes steadily increasing, and the number stored in enterprise data lakes ballooning by billions each year, the need for a more efficient compression method has never been more pressing.

The pay-off for using Brotli compression will be smaller PDFs. This will translate into an average of 10% to 25% reduction in file size, depending on the type of content being encoded, according to a 2025 test by PDF Association member Artifex Software.

Unfortunately, for enterprises this is where the work begins. As PDFs written using Brotli compression start to circulate, anyone who hasn’t updated their applications and library dependencies to support it will be unable to decompress and open the new-format files. For PDFs, this would be a first: While the format has added numerous features since becoming an ISO standard in 2008, none have stopped users from opening PDFs.

The most visible software requiring an upgrade to support Brotli includes proprietary PDF creators and readers such as Adobe Acrobat, Foxit PDF Editor, and Nitro PDF. PDF readers integrated into browsers also fall into this category.

Beyond this, however, lies a sizable ecosystem of less-visible open-source utilities, libraries, and SDKs which are used inside enterprises as part of PDF workflows and automated batch processing. Finding and updating these components, often buried deep inside third-party libraries, promises to be time consuming.

If enterprises delay updating, then they risk encountering PDFs created using newer software supporting Brotli that will no longer open on their older, non-updated programs. IT teams will most likely come face to face with this when users contact them to report that they can’t open a file.

Building Brotli support

To kick off adoption, developers need encouragement, said Guust Ysebie, a software engineer with document processing developer Apryse. “Somebody has to jump first and make some noise so other products jump on the bandwagon,” he said.

It’s a challenge because, as he explained in a post about the move to Brotli on the PDF Association’s website, Brotli’s adoption has been slowed because the PDF specification requires consensus across hundreds of stakeholders.

The transition can be eased in three ways, he suggested, the simplest of which is to publicize the need to upgrade across multiple information sources as part of an awareness campaign.

A more radical suggestion is that Brotli-enabled PDFs could be formatted such that, rather than cause older readers to crash, they could show a “not supported” error message encouraging customers to upgrade as a placeholder for the compressed content.

A final tactic is for likeminded developers to take it upon themselves to upgrade open-source libraries. Ysebie said he’s added Brotli support to several libraries, including the iText SDK from Apryse.

“This is how adoption works in real life: Create the feature unofficially, then early adopters implement it, and this causes bigger products to also adopt it,” said Ysebie. The critical moment for adoption of Brotli-enabled software would be its appearance in Adobe Reader. This will happen at some point, but when is still unclear, he said.

The good news is that because there are only a limited number of software libraries to upgrade, adding support to this software should be straightforward, said Ysebie. However, organizations will still have to apply those updated images to their current applications.

As to when Brotli will be added to the ISO PDF 2.0 specification (ongoing since 2015), Ysebie agreed this has a way to go. But the industry had to move on from old technology at some point. “We need to push the ecosystem forward. It will be a little chaotic in the beginning but with a lot of potential for the future.”

This article first appeared on Computerworld.

(image/jpeg; 0.42 MB)

Apiiro’s Guardian Agent guards against insecure AI code 29 Jan 2026, 6:35 pm

Apiiro has launched Guardian Agent, an AI agent that helps prevent coding agents from generating vulnerable or non-compliant code by rewriting developer prompts into secure prompts, according to the company.

Introduced January 28, Guardian Agent is now in a private preview stage. Describing the technology as introducing a fundamentally new paradigm for securing software in the era of AI-driven development, Apiiro said Guardian replaces traditional appsec approaches built around detecting and fixing vulnerabilities after code is written. Guardian Agent replaces this reactive model with a preventive one, stopping risk before code is generated by guarding AI coding agents in real time, according to Apiiro. Guardian Agent operates in real time directly from the developer’s IDE and CLI tools. The agent is powered by Apiiro’s code analysis technology and a software graph that “deeply understands” the customer’s software architecture and adapts to its changes, the company said.

Elaborating on the inspiration behind Guardian Agent, Apiiro said AI coding agents are breaking the physics of application security. Enterprises generate four times more code after adopting AI coding agents and expand the application attack surface by six times. This expansion is driven by rapid generation of new APIs, duplicated open source technologies and dependencies, and other resources, reshaping the software architecture with each code change, Apiiro said. Much of the code is generated without developers being fully aware of it. By preventing vulnerabilities before code exists, security outcomes are improved and developer productivity is increased, Apiiro stressed.

(image/jpeg; 7.36 MB)

Get started with Angular: Introducing the modern reactive workflow 29 Jan 2026, 9:00 am

Angular is a cohesive, all-in-one reactive framework for web development. It is one of the larger reactive frameworks, focused on being a single architectural system that handles all your web development needs under one idiom. While Angular was long criticized for being heavyweight as compared to React, many of those issues were addressed in Angular 19. Modern Angular is built around the Signals API and minimal formality, while still delivering a one-stop-shop that includes dependency injection and integrated routing.

Angular is popular with the enterprise because of its stable, curated nature, but it is becoming more attractive to the wider developer community thanks to its more community engaged development philosophy. That, along with its recent technical evolution, make Angular one of the most interesting projects to watch right now.

Why choose Angular?

Choosing a JavaScript development framework sometimes feels like a philosophical debate, but it should be a practical decision. Angular is unique because it is strongly opinionated. It doesn’t just give you a view layer; it provides a complete toolkit for building web applications.

Like other reactive frameworks, Angular is built around its reactive engine, which lets you bind state (variables) to the view. But if that’s all you needed, one of the smaller, more focused frameworks would be more than enough. What Angular has that some of these other frameworks don’t is its ability to use data binding to automatically synchronize data from your user interface (UI) with your JavaScript objects. Angular also leverages dependency injection and inversion of control to help structure your application and make it easier to test. And it contains more advanced features like server-side rendering (SSR) and static-site generation (SSG) within itself, rather than requiring you to engage a meta-framework for either style of development.

While Angular might not be your top choice for every occasion, it’s an excellent option for larger projects that require features you won’t get with a more lightweight framework.

Also see: Catching up with Angular 19.

Getting started with Angular

With those concepts in mind, let’s set up Angular in your development environment. After that, we can run through developing a web application with Angular. To start, make sure you have Node and NPM installed. From the command line, enter:

$ node -v
$ npm -v

Next, you can use the Angular CLI to launch a new app:

$ ng new iw-ng

You can use the defaults in your responses to the interactive prompts shown here:

A screenshot of a new project setup in the Angular command-line interface.

Matthew Tyson

We now have a basic project layout in the new directory, which you can import into an IDE (such as VS Code) or edit directly.

Looking at the project layout, you might notice it is fairly lean, a break from Angular projects of the past. The most important parts are:

  • src/main.ts: This is the main entry point. In older versions of Angular, this file had to bootstrap a module, which then bootstrapped a component. Now, it avoids any verbose syntax, calling bootstrapApplication with your root component directly.
  • src/index.html: The main HTML page that hosts your application. This is the standard index.html that serves all root requests in a web page and contains the tag where your Angular component will render. It is the “body” that the “spirit” of your code animates.
  • src/app/app.ts: The root component of your application. This single file defines the view logic and the component metadata. In the new “standalone” world, it manages its own imports, meaning you can see exactly what dependencies it uses right at the top of the file. (This is the root element that appears in src/index.html.)
  • src/app/app.config.ts: This file is new in modern Angular and replaces the old AppModule providers array. It is where you configure global services, like the router or HTTP client.
  • angular.json: The configuration file for the CLI itself. It tells the build tools how to process your code, though you will rarely need to touch this file manually anymore.

Here is the basic flow of how the engine renders these components:

  1. The arrival (HTML): The browser receives index.html. The tag is there, but it’s empty.
  2. The unpacking (JavaScript): The browser sees the tags at the bottom of the HTML and downloads the JavaScript bundles (your compiled code) from src/app/app.ts.
  3. The assembly (Bootstrap): The browser runs that JavaScript. The code “wakes up,” finds the tag in the DOM, and dynamically inserts your title, buttons, and lists.

This flow will be different if you are using server-side rendering (SSR), but we’ll leave that option aside for now. Now that you’ve seen the basic architecture, let’s get into the code.

Developing your first web app in Angular

If you open src/app/app.ts (more info here) the component definition looks like this:

import { Component, signal } from '@angular/core';
import { RouterOutlet } from '@angular/router';

@Component({
  selector: 'app-root',
  imports: [RouterOutlet],
  templateUrl: './app.html',
  styleUrl: './app.css'
})
export class App {
  protected readonly title = signal('iw-ng');
}

Before we dissect the code, let’s run the app and see what it produces:

$ ng serve

You should see a page like this one at localhost:4200:

A screenshot of a Hello, World! app built with Angular.

Matthew Tyson

Returning to the src/app.ts component, notice that there are three main parts of the definition: the class, the metadata, and the view. Let’s unpack these separately.

The class (export class App)

Export class App is vanilla TypeScript that holds your component’s data and logic. In our example, title = signal(‘iw-ng’) defines a piece of reactive state. Unlike older versions of Angular where data was just a plain property, here we use a signal. Signals are wrappers around values that notify the template precisely when they change, enabling fine-grained performance.

The metadata (@Component)

The @Component decorator tells Angular it is dealing with a component, not just a generic class. There are several elements involved in the decorator’s communication with the engine:

  • selector: 'app-root': Defines the custom HTML tag associated with any given component. Angular finds in your index.html and renders the component there.
  • imports: In the new Angular era, dependencies are explicit. You list exactly what a component needs (like RouterOutlet or other components) here, rather than hiding them in a separate module file.
  • templateUrl: Points to the external HTML file that defines the view.

The view (the template)

This is the visual part of the component, defined in app.html. It combines standard HTML with Angular’s template syntax. (JSX handles this part for React-based apps.)

We can modify src/app/app.html to see how these three elements work together. To start, delete the default content and add the following:

Hello, {{ title() }}

The double curly braces {{ }} are called interpolation. Notice the parentheses in title(). We are reading the “title” signal value by calling its function. If you were to update that signal programmatically (e.g., this.title.set('New Value')), the text on the screen would update instantly.

Angular’s built-in control flow

Old-school Angular required “structural directives” like *ngIf and *ngFor logic control. These were powerful but required importing CommonModule and learning a specific micro-syntax. Modern Angular uses a built-in control flow that looks like standard JavaScript (similar to other Reactive platforms).

To see the new control flow in action, let’s add a list to our component. Update src/app/app.ts as follows, leaving the rest of the file the same:

export class App {
  protected readonly title = signal('iw-ng');
  protected readonly frameworks = signal(['Angular', 'React', 'Vue', 'Svelte']);
  protected showList = signal(true);

  toggleList() {
    this.showList.update(v => !v);
  }
}

While we’re at it, let’s also update src/app/app.html to render this new list (don’t worry about for now; it just tells Angular where to render the framing template):



@if (showList()) {
  
    @for (tech of frameworks(); track tech) {
  • {{ tech }}
  • }
} @else {

List is hidden

}

The app will now display a list that can be toggled for visibility:

Screenshot of a list that can be toggled on and off for visibility.

Matthew Tyson

This syntax is cleaner and easier to read than the old *ngFor loops:

  • @if conditionally renders the block if the signal’s value is true.
  • @for iterates over the array. The track keyword is required for performance (it tells Angular how to identify unique items in the list).
  • (click) is an event binding. It lets us run code (the toggleList method) when the user interacts with the button.

Services: Managing business logic in Angular

Components focus on the view (i.e., what you see). For the business logic that backs the application functionality, we use services.

A service is just a class that can be “injected” into a component that needs it. This is Angular’s famous dependency injection system. It allows you to write logic once and reuse it anywhere. It’s a slightly different way of thinking about how an application is wired together, but it gives you real organizational benefits over time.

To generate a service, you can use the CLI:

$ ng generate service frameworks

This command creates a src/app/hero.ts file. In modern Angular, we define services using the @Injectable decorator. Currently, the src/app/hero.ts file just has this:

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root',
})
export class Frameworks {
  
}

Open the file and add a simple method to return our data:

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root', // Available everywhere in the app
})
export class Frameworks {
  getList() {
    return ['Angular', 'React', 'Vue', 'Svelte'];
  }
}

The providedIn: 'root' metadata is important, it tells Angular to create a single, shared instance of this service for the entire application (you might recognize this as an instance of the singleton pattern).

Using the service

In the past, we had to list dependencies in the constructor. Modern Angular offers a cleaner way: the inject() function. Subsequently, we can refactor our src/app/app.ts to get its data from the service instead of hardcoding it:

import { Component, inject, signal } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import { Frameworks } from './frameworks'; // Import the service

@Component({
  selector: 'app-root',
  imports: [RouterOutlet],
  templateUrl: './app.html',
  styleUrl: './app.css'
})
export class App {
  private frameworksService = inject(Frameworks); // Dependency Injection
  
  protected readonly title = signal('iw-ng');
  
  // Initialize signal with data directly from the service
  protected readonly frameworks = signal(this.frameworksService.getList());
  protected showList = signal(true);

  toggleList() {
    this.showList.update(v => !v);
  }
}

Dependency injection is a powerful pattern. The component doesn’t need to know where the list came from (it could be coming from an API, a database, or a hard-coded array); it just asks the service for what it needs. This pattern adds a bit of extra work up front, but it delivers a more flexible, organized codebase as the app grows in size and complexity.

Routers and routes

Once your application grows beyond a single view, you need a way to navigate between different screens. In Angular, we use the built-in router for this purpose. In our example project, src/app/app.routes.ts is the dedicated home for the router config. Let’s follow the steps for creating a new route.

First, we define the route. When you open src/app/app.routes.ts, you will see an exported routes array. This array contains the available routes for your app. Each string name resolves to a component that handles rendering that route. In effect, this is the map of your application’s landscape.

In a real application, you’d often have “framing template” material in the root of the app (like the navbar) and then the routes fill in the body content. (Remember that by default, Angular is designed for single-page apps, where navigation does reload the screen, but swaps content.)

For now, let’s just get a sense of how the router works. First, create a new component so we have a destination to travel to. In your terminal, run:

$ ng generate component details

This will generate a simple details component in the src/app/details directory.

Now we can update src/app/app.routes.ts to include this new path. We will also add a “default” path that redirects empty requests to the home view, ensuring the user always lands somewhere:

import { Routes } from '@angular/router';
import { App } from './app'; // Matches src/app/app.ts
import { Details } from './details/details'; // Matches src/app/details/details.ts

export const routes: Routes = [
  { path: '', redirectTo: '/home', pathMatch: 'full' },
  { path: 'home', component: App },
  { path: 'details', component: Details },
];

Now if you visit localhost:4200/home, you’ll get the message from the details component: “Details works!”

Next, we’ll use the routerLink directive to move between views without refreshing the page. In src/app/app.html, we create a navigation bar that sits permanently at the top of the page (the “stationary” element), while the router swaps the content below it (the “impermanent” element):




And with that, the application has a navigation flow. The user clicks, the URL updates, and the content transforms, all without the jarring flicker of a browser reload.

Parametrized routes

The last thing we’ll look at is handling route parameters, where the route accepts variables in the path. To manage this kind of dynamic data, you define a route with a variable, marked by a colon. Open src/app/app.routes.ts and add a dynamic path:

export const routes: Routes = [
  // ... existing routes
  { path: 'details/:id', component: Details }, 
];

The :id is a placeholder. Whether the URL is /details/42 or /details/108, this router will receive it because it matches the path. Inside the details component, we have access to this parameter (using the ActivatedRoute service or the new withComponentInputBinding). We can use that value to retrieve the data we need (like using it to recover a detail item from a database).

Conclusion

We have seen the core elements of modern Angular: Setting up the environment, building reactive components with signals, organizing logic with services, and tying it all together with interactive routing.

Deploying these pieces together is the basic work in Angular. Once you get comfortable with it, you have an extremely powerful platform at your fingertips. And, when you are ready to go deeper, there is a whole lot more to explore in Angular, including:

  • State management: Beyond signals, Angular has support for managing complex, application-wide state.
  • Forms: Angular has a robust system for handling user input.
  • Signals: We only scratched the surface of signals here. Signals offer a powerful, fine-grained way to manage state changes.
  • Build: You can learn more about producing production builds.
  • RxJS: Takes reactive programming to the next level.

(image/jpeg; 3.02 MB)

What is prompt engineering? The art of AI orchestration 29 Jan 2026, 9:00 am

Prompt engineering is the process of crafting inputs, or prompts, to a generative AI system that lead to the system producing better outputs. That sounds simple on the surface, but because LLMs and other gen AI tools are complex, nondeterministic “black box” systems, it’s a devilishly tricky process that involves trial and error and a certain degree of guesswork — and that’s before you even consider that the question of what constitutes “better output” is itself difficult to answer.

Almost every advance in computer science since COBOL has been pitched as a means for ordinary people to unlock the power of computers without having to learn any specialized languages or skills, and with natural language AI chatbots, it might seem that we’ve finally achieved that goal. But it turns out that there are a number of techniques — some intuitive, some less so — that can help you get the most from a gen AI system, and learning those techniques is quickly becoming a key skill in the AI age.

Why is prompt engineering important?

Most people’s experience with gen AI tools involves directly interacting with ChatGPT or Claude or the like. For those folks, prompt engineering techniques represent a way to get better answers out of those tools. Those tools are becoming increasingly built into business software and processes, so that’s a strong motivation to improve your prompts, just as the first generation of web users learned quirks and tricks of Google and other search engines.

However, prompt engineering is even more important for developers who are building an ecosystem around AI tools in ways that hopefully relieve some of the burden from ordinary users. Enterprise AI applications increasingly include an orchestration layer between end users and the underlying AI foundation model. This layer includes system prompts and retrieval augmented generation (RAG) tools that enhance user inputs before they’re sent to the AI system.

For instance, a medical AI application could ask its doctor and nurse users to simply input a list of patient symptoms; the application’s orchestration layer would then turn that list into a prompt, informed by prompt engineering techniques and enhanced by information derived from RAG, that will hopefully produce the best diagnosis.

For developers, this orchestration layer represents the next frontier of professional work in the AI age. Just as search engines were originally aimed at ordinary users but also spawned a multibillion dollar industry in the form of search engine optimization, so too is prompt engineering becoming a vital and potentially lucrative skill.

Prompt engineering types and techniques

Prompt engineering approaches vary in sophistication, but all serve the same goal: to guide the model’s internal reasoning and reduce the model’s tendency toward ambiguity or hallucination. The techniques fall into a few major categories:

Zero-shot prompting is the simplest and, in many cases, the default: you give the model an instruction — “Summarize this article,” “Explain this API,” “Draft a patient note” — and the system relies entirely on its general training to produce an answer. This is referred to as direct or (for reasons we’ll discuss in a moment) zero-shot prompting; it’s useful for quick tasks, but it rarely provides the consistency or structure needed for enterprise settings, where outputs must follow predictable formats and meet compliance or quality constraints.One-shot and few-shot prompting add examples to the instruction to demonstrate the format, reasoning style, or output structure the system should follow. Here’s an example of one-shot prompting with ChatGPT:

example of one-shot prompting with ChatGPT

 One-shot prompting with ChatGPT

Foundry


This is a one-shot prompt because it involves a single example, but you can add more to produce few-shot (or indeed many-shot) prompts. Direct prompts that don’t include examples were retroactively named zero-shot as a result.

Prompts of this type can be used to provide in-context learning with examples that steer the model to better performance. For instance, a model that struggles with a zero-shot instruction like “Extract key risks from this report” may respond much more reliably if given a few examples of the kinds of risks you’re talking about. In production systems, these examples are often embedded as part of the system prompt or stored in an internal prompt template library rather than visible to the end user.

Chain-of-thought prompting takes things further, encouraging the model to break down a problem into intermediate steps. It was first developed in a 2022 paper that used the following example:

Image of chain-of-thought prompts

Source: “Chain-of-Thought Prompting Elicits Reasoning in Large Language Models,” Wei et al., 2022.

Foundry

Chain-of-thought prompts can involve elaborate demonstrations of your desired reasoning, as the example demonstrates; however, it’s worth noting that contemporary LLMs are prone to engage in chain of thought reasoning on their own with even gentle nudge, like adding “show your work” to the prompt. This technique is particularly effective for reasoning tasks—anything involving classification, diagnostics, planning, multi-step decision-making, or rules interpretation.

The way these engineered prompts work reveals something about the nature of gen AI that’s important to keep in mind. While ChatGPT and other LLM chat interfaces create the illusion that you’re having a conversation with someone, the underlying model is fundamentally a machine for predicting the next token in sequence.

When you’re “talking” with it in a natural conversational style, it’s doing its best to predict, based on its training data, what the most likely next bit of dialogue in the exchange would be. But as our examples indicate, you can prompt it with a multi-“character” dialogue scaffolds, with both the Qs and the As, and then ask it to predict the next A, or indeed even the next Q; it’s perfectly happy to do so and doesn’t necessarily “identify” with either “character,” and can even switch back and forth if you prompt it correctly. Good prompt engineering techniques can make use of this rather than trying to coax an LLM into doing what you want as if it were a person.

Zero-shot and few-shot examples can be embedded as system-level templates, and chain-of-thought reasoning can be enforced by the software layer rather than left to user discretion. More elaborate dialogue scaffolds can shape model behavior in ways that reduce risk and improve consistency. Collectively, these techniques form the core of production-grade prompting that sits between end users and the model.

Prompt engineering challenges

Prompt engineering remains a rapidly evolving discipline, and that brings real challenges. One issue is the fragility of prompts: even small changes in wording can cause large shifts in output quality. Prompts tuned for one model version do not always behave identically in a newer version, meaning organizations face ongoing maintenance simply to keep outputs stable as models update.

A related problem is opacity. Because LLMs are black-box systems, a strong prompt does not guarantee strong reasoning; it only increases the likelihood that the model interprets instructions correctly. Studies have highlighted the gap between well-engineered prompts and trustworthy outputs. In regulated industries, a model that merely sounds confident can be dangerous if the underlying prompt does not constrain it sufficiently. (We’ve already compared prompt engineering to SEO, and fragility and opacity are problems familiar to SEO practitioners.)

Enterprise teams also face scalability issues. Due to LLMs’ nondeterministic nature, a prompt that works for a single request may not perform consistently across thousands of queries, each with slightly different inputs. As businesses move toward broader deployments, this inconsistency can translate into productivity losses, compliance risks, or increased human review needs.

Security risk is another emerging challenge. Prompt-injection attacks, where malformed user input or retrieval content manipulates the internal prompt templates, are now practical threats.

Prompt engineering courses

One more challenge in the prompt engineering landscape: The skills gap remains significant. Enterprises understand the importance of prompt engineering, but the technology and techniques are so new that few professionals have hands-on experience building robust prompt pipelines. This gap is driving demand for the growing list of prompt engineering courses and certifications.

Companies themselves are increasingly offering internal training as they roll out generative AI. Citi, for example, has made AI prompt training mandatory for roughly 175,000–180,000 employees who can access its AI tools, framing it as a way to boost AI proficiency across the workforce. Deloitte’s AI Academy similarly aims to train more than 120,000 professionals on generative AI and related skills.

Prompt engineering jobs

There’s rising demand for professionals who can design prompt templates, build orchestration layers, and integrate prompts with retrieval systems and pipelines. Employers increasingly want practitioners with AI skills who understand not just prompting, but how to integrate them with retrieval systems and tool-use.

These roles often emphasize hybrid responsibilities: evaluating model updates, maintaining prompt libraries, testing output quality, implementing safety constraints, and embedding prompts into multi-step agent workflows. As companies deploy AI deeper into customer support, analytics, and operations, prompt engineers must collaborate with security, compliance, and UX teams to prevent hallucination, drift or unexpected system behavior.

Despite some skepticism about the longevity of “prompt engineer” as a standalone title, the underlying competencies—structured reasoning, workflow design, prompt orchestration, evaluation and integration—are becoming core to broader AI engineering disciplines. Demand for talent remains strong, and compensation for AI skills continues to rise.

Prompt engineering guides

Readers interested in going deeper into practical techniques have several authoritative guides available:

These resources can help you get started in this rapidly expanding field—but there’s no substitute for getting hands on with prompts yourself.

(image/jpeg; 1.67 MB)

Why your next microservices should be streaming SQL-driven 29 Jan 2026, 9:00 am

“It is tempting, if the only tool you have is a hammer, to treat everything as if it were a nail.” — Abraham Maslow, 1966

Microservices provide many benefits for building business services, such as independent tools, technologies, languages, release cycles, and full control over your dependencies. However, microservices aren’t the solution for every problem. As Mr. Maslow observed, if we limit our tool choices, we end up using less-than-ideal methods for fixing our problems. In this article, we’ll take a look at streaming SQL, so you can expand your toolbox with another option for solving your business problems. But first, how does it differ from a regular (batch) SQL query?

SQL queries on a traditional database (e.g. Postgres) are bounded queries, operating over the finite set of data within the database. The bounded data includes whatever was present at the point in time of the query’s execution. Any modifications to the data set occurring after the query execution are not included in the final results. Instead, you would need to issue another query to include that new data.

Streaming SQL 01

A bounded SQL query on a database table. 

Confluent

In contrast, a streaming SQL query operates on an unbounded data set—most commonly one or more event streams. In this model, the streaming SQL engine consumes events from the stream(s) one at a time, ordering them according to timestamps and offsets. The streaming SQL query also runs indefinitely, processing events as they arrive at the inputs, updating state stores, computing results, and even outputting events to downstream streams.

Streaming SQL 02

An unbounded SQL query on an event stream. 

Confluent

Apache Flink is an excellent example of a streaming SQL solution. Under the hood is a layered streaming framework that provides low-level building blocks, a DataStream API, a higher level Table API, and at the top-most level of abstraction, a streaming SQL API. Note that Flink’s SQL streaming syntax may vary from other SQL streaming syntaxes, since there is no universally agreed upon streaming SQL syntax. While some SQL streaming services may use ANSI standard SQL, others (including Flink) add their own syntactical variations for their streaming frameworks.

There are several key benefits for building services with streaming SQL. For one, you gain access to the powerful streaming frameworks without having to familiarize yourself with the deeper underlying syntax. Secondly, you get to offload all of the tricky parts of streaming to the framework including repartitioning data, rebalancing workloads, and recovering from failures. Third, you gain the freedom to write your streaming logic in SQL instead of the framework’s domain-specific language. Many of the full-featured streaming frameworks (like Apache Kafka Streams and Flink) are written to run on the Java Virtual Machine (JVM) and offer limited support for other languages.

Finally, it’s worth mentioning that Flink uses the TABLE type as a fundamental data primitive, as evidenced by the SQL layer built on top of the Table API in this four-layer Flink API diagram. Flink uses both streams and tables as part of its data primitives, enabling you to materialize a stream into a table and similarly turn a table back into a stream by appending the table updates to an output stream. Visit the official documentation to learn more.

Let’s shift gears now to look at a few common patterns of streaming SQL use, to get an idea of where it really shines.

Pattern 1: Integrating with AI and machine learning

First on the list, streaming SQL supports direct integration with artificial intelligence and machine learning (ML) models, directly from your SQL code. Accessing an AI or ML model through streaming SQL is easier than ever. Given the emergence of AI as a contender for many business workloads, streaming SQL gives you the capability to utilize that model in an event-driven manner, without having to spin up, run, and manage a dedicated microservice. This pattern works similarly to the user-defined function (UDF) pattern: You create the model, register it for use, and then call it inline in your SQL query.

The Flink documentation goes into greater detail on how you’d hook up a model:

CREATE MODEL sentiment_analysis_model 
INPUT (text STRING COMMENT 'Input text for sentiment analysis') 
OUTPUT (sentiment STRING COMMENT 'Predicted sentiment (positive/negative/neutral/mixed)')
COMMENT 'A model for sentiment analysis of text'
WITH (
    'provider' = 'openai',
    'endpoint' = 'https://api.openai.com/v1/chat/completions',
    'api-key' = '',
    'model'='gpt-3.5-turbo',
    'system-prompt' = 'Classify the text below into one of the following labels: [positive, negative, neutral, mixed]. Output only the label.'
);

Source: Flink Examples

The model declaration is effectively a bunch of wiring and configurations that enable you to use the model in your streaming SQL code. For example, you can use this model declaration to evaluate sentiments about the body of text contained within the event. Note that ML_PREDICT requires both the specific model name used and the text parameter:

INSERT INTO my_sentiment_results 
    SELECT text, sentiment 
    FROM input_event_stream, LATERAL TABLE(ML_PREDICT('sentiment_analysis_model', text));

Pattern 2: Bespoke business logic as functions

While streaming SQL offers many functions natively, it’s simply not possible to include everything into the language syntax. This is where user-defined functions come in—they’re functions, defined by the user (you), that your program can execute from the SQL statements. UDFs can call external systems and create side effects that aren’t supported by the core SQL syntax. You define the UDF by implementing the function code in a standalone file, then upload it to the streaming SQL service before you run your SQL statement.

Let’s take a look at a Flink example.

// Declare the UDF in a separate java file
import org.apache.flink.table.api.*;
import org.apache.flink.table.functions.ScalarFunction;
import static org.apache.flink.table.api.Expressions.*;

//Returns 2 for high risk, 1 for normal risk, 0 for low risk.
public static class DefaultRiskUDF extends ScalarFunction {
  public Integer eval(Integer debt, 
    Integer interest_basis_points, 
    Integer annual_repayment,
    Integer timespan_in_years) throws Exception {

    int computed_debt = debt;

   	 for (int i = 0; i = debt )
return 2;
else if ( computed_debt  debt / 2)
return 1;
else
return 0;
}

Next, you’ll need to compile the Java file into a JAR file and upload it to a location that is accessible by your streaming SQL framework. Once the JAR is loaded, you’ll need to register it with the framework, and then you can use it in your streaming SQL statements. The following gives a very brief example of registration and invocation syntax.

-- Register the function.
CREATE FUNCTION DefaultRiskUDF
  AS 'com.namespace.SubstringUDF'
  USING JAR '';

-- Invoke the function to compute the risk of:
-- 100k debt over 15 years, 4% interest rate (400 basis points), and a 10k annual repayment rate
SELECT UserId, DefaultRiskUDF(100000, 400, 10000, 15) AS RiskRating
FROM UserFinances
WHERE RiskRating >= 1;

This UDF lets us compute the risk that a borrower may default on a loan, returning 0 and 1 for low and normal risk respectively, and a value of 2 for high-risk borrowers or accounts at risk. Though this UDF is a pretty simple and contrived example, you can do far more complex operations using almost anything within the standard Java libraries. You won’t have to build a whole microservice just to get some functionality that isn’t in your streaming SQL solution. You can just upload whatever’s missing and call it directly inline from your code.

Pattern 3: Basic filters, aggregations, and joins

This pattern takes a step back to the basic (but powerful) functions built right into the streaming SQL framework. A popular use case for streaming SQL is that of simple filtering, where you keep all records that meet a criteria and discard the rest. The following shows a SQL filter that only returns records where total_price > 10.00, which you can then output to a table of results or into a stream as a sequence of events.

SELECT *
FROM orders
WHERE total_price > 10.00;

Windowing and aggregations are another powerful set of components for streaming SQL. In this security example, we’re counting how many times a given user has attempted to log in within a one-minute tumbling window (you can also use other window types, like sliding or session).

SELECT 
    COUNT(user_id) AS login_count, 
    TUMBLE_START(event_time, INTERVAL '1' MINUTE) AS window_start
FROM login_attempts
GROUP BY TUMBLE(event_time, INTERVAL '1' MINUTE);

Once you have how many login attempts a user has in the window, you can filter for a higher value (say > 10), triggering business logic inside a UDF to lock them out temporarily as an anti-hacking feature.

Finally, you can also join data from multiple streams together with just a few simple commands. Joining streams as streams (or as tables) is actually pretty challenging to do well without a streaming framework, particularly when accounting for fault tolerance, scalability, and performance. In this example, we’re joining Product data on Orders data with the product ID, returning an enriched Order + Product result.

SELECT * FROM Orders
INNER JOIN Product
ON Orders.productId = Product.id

Note that not all streaming frameworks (SQL or otherwise) support primary-to-foreign-key joins. Some only allow you to do primary-to-primary-key joins. Why? The short answer is that it can be quite challenging to implement these types of joins when accounting for fault tolerance, scalability, and performance. In fact, you should investigate how your streaming SQL framework handles joins, and if it can support both foreign and primary key joins, or simply just the latter.

So far we’ve covered some of the basic functions of streaming SQL, though currently the results from these queries aren’t powering anything more complex. With these queries as they stand, you would effectively just be outputting them into another event stream for a downstream service to consume. That brings us to our next pattern, the sidecar.

Pattern 4: Streaming SQL sidecar

The streaming SQL sidecar pattern enables you to leverage the functionality of a full featured stream processing engine, like Flink or Kafka Streams, without having to write your business logic in the same language. The streaming SQL component provides the rich stream processing functionality, like aggregations and joins, while the downstream application processes the resulting event stream in its own independent runtime.

Streaming SQL 03

Connecting the streaming SQL query to an event-driven service via an internal stream.

Confluent

In this example, INTERNAL_STREAM is a Kafka topic where the SQL sidecar writes its results. The event-driven service consumes the events from the INTERNAL_STREAM, processes them accordingly, and may even emit events to the OUTPUT_STREAM.

Another common use of the sidecar is to prepare data to serve using a web service to other applications. The consumer consumes from the INPUT_STREAM, processes the data, and makes it available for the web service to materialize into its own state store. From there, it can serve request/response queries from other services, such as REST and RPC requests.

Streaming SQL 04

Powering a web service to serve REST / RPC requests using the sidecar pattern. 

Confluent

While the sidecar pattern gives you a lot of room for extra capabilities, it does require that you build, manage, and deploy the sidecar service alongside your SQL queries. A major benefit of this pattern is that you can rely on the streaming SQL functionality to handle the streaming transformations and logic without having to change your entire tech stack. Instead, you just plug the streaming SQL results into your existing tech stack, building your web services and other applications using the same tools that you always have.

Additional use cases

Each of these patterns shows operations in isolation, which may be enough for simpler applications. For more complex business requirements, there’s a good chance that you’re going to chain together multiple patterns, with each feeding its results into the next. For example, first you filter some data, then apply a UDF, then make a call to an ML or AI model using ML_PREDICT, as shown in the first half of the example below. The streaming SQL then filters the results from the first ML_PREDICT, applies a UDF, and then sends those results to a final ML model before writing to the OUTPUT_STREAM.

Streaming SQL 05

Chain multiple SQL streaming operations together for more complex use cases. 

Confluent

Streaming SQL is predominantly offered as a serverless capability by numerous cloud vendors, billed as a quick and easy way to get streaming data services up and running. Between its built-in functions, UDFs, materialized results, and integrations with ML and AI models, streaming SQL has proven to be a worthy contender for consideration when building microservices.

New Tech Forum provides a venue for technology leaders—including vendors and other outside contributors—to explore and discuss emerging enterprise technology in unprecedented depth and breadth. The selection is subjective, based on our pick of the technologies we believe to be important and of greatest interest to InfoWorld readers. InfoWorld does not accept marketing collateral for publication and reserves the right to edit all contributed content. Send all inquiries to doug_dineley@foundryco.com.

(image/jpeg; 9.07 MB)

Crooks are hijacking and reselling AI infrastructure: Report 29 Jan 2026, 12:39 am

For years, CSOs have worried about their IT infrastructure being used for unauthorized cryptomining. Now, say researchers, they’d better start worrying about crooks hijacking and reselling access to exposed corporate AI infrastructure.

In a report released Wednesday, researchers at Pillar Security say they have discovered campaigns at scale going after exposed large language model (LLM) and MCP endpoints – for example, an AI-powered support chatbot on a website.

“I think it’s alarming,” said report co-author Ariel Fogel. “What we’ve discovered is an actual criminal network where people are trying to steal your credentials, steal your ability to use LLMs and your computations, and then resell it.”

“It depends on your application, but you should be acting pretty fast by blocking this kind of threat,” added co-author Eilon Cohen. “After all, you don’t want your expensive resources being used by others. If you deploy something that has access to critical assets, you should be acting right now.”

Kellman Meghu, chief technology officer at Canadian incident response firm DeepCove Security, said that this campaign “is only going to grow to some catastrophic impacts. The worst part is the low bar of technical knowledge needed to exploit this.”

How big are these campaigns? In the past couple of weeks alone, the researchers’ honeypots captured 35,000 attack sessions hunting for exposed AI infrastructure.

“This isn’t a one-off attack,” Fogel added. “It’s a business.” He doubts a nation-state it behind it; the campaigns appear to be run by a small group.

The goals: To steal compute resources for use by unauthorized LLM inference requests, to resell API access at discounted rates through criminal marketplaces, to exfiltrate data from LLM context windows and conversation history, and to pivot to internal systems via compromised MCP servers.

Two campaigns

The researchers have so far identified two campaigns: One, dubbed Operation Bizarre Bazaar, is targeting unprotected LLMs. The other campaign targets Model Context Protocol (MCP) endpoints. 

It’s not hard to find these exposed endpoints. The threat actors behind the campaigns are using familiar tools: The Shodan and Censys IP search engines.

At risk: Organizations running self-hosted LLM infrastructure (such as Ollama, software that processes a request to the LLM model behind an application; vLLM, similar to Ollama but for high performance environments; and local AI implementations) or those deploying MCP servers for AI integrations.

Targets include:

  • exposed endpoints on default ports of common LLM inference services;
  • unauthenticated API access without proper access controls;
  • development/staging environments with public IP addresses;
  • MCP servers connecting LLMs to file systems, databases and internal APIs.

Common misconfigurations leveraged by these threat actors include:

  • Ollama running on port 11434 without authentication;
  • OpenAI-compatible APIs on port 8000 exposed to the internet;
  • MCP servers accessible without access controls;
  • development/staging AI infrastructure with public IPs;
  • production chatbot endpoints (customer support, sales bots) without authentication or rate limiting.

George Gerchow, CSO at Bedrock Data and an IANS faculty member, said Operation Bizarre Bazaar “is a clear sign that attackers have moved beyond ad hoc LLM abuse and now treat exposed AI infrastructure as a monetizable attack surface. What’s especially concerning isn’t just unauthorized compute use, but the fact that many of these endpoints are now tied to the Model Context Protocol (MCP), the emerging open standard for securely connecting large language models to data sources and tools. MCP is powerful because it enables real-time context and autonomous actions, but without strong controls, those same integration points become pivot vectors into internal systems.”

Defenders need to treat AI services with the same rigor as APIs or databases, he said, starting with authentication, telemetry, and threat modelling early in the development cycle. “As MCP becomes foundational to modern AI integrations, securing those protocol interfaces, not just model access, must be a priority,” he said.

In an interview, Pillar Security report authors Eilon Cohen and Ariel Fogel couldn’t estimate how much revenue threat actors might have pulled in so far. But they warn that CSOs and infosec leaders had better act fast, particularly if an LLM is accessing critical data.

Their report described three components to the Bizarre Bazaar campaign:

  • the scanner: a distributed bot infrastructure that systematically probes the internet for exposed AI endpoints. Every exposed Ollama instance, every unauthenticated vLLM server, every accessible MCP endpoint gets cataloged. Once an endpoint appears in scan results, exploitation attempts begin within hours;
  • the validator: Once scanners identify targets, infrastructure tied to an alleged criminal site validates the endpoints through API testing. During a concentrated operational window, the attacker tested placeholder API keys, enumerated model capabilities and assessed response quality;
  • the marketplace: Discounted access to 30+ LLM providers is being sold on a site called The Unified LLM API Gateway. It’s hosted on bulletproof infrastructure in the Netherlands and marketed on Discord and Telegram.

So far, the researchers said, those buying access appear to be people building their own AI infrastructure and trying to save money, as well as people involved in online gaming.

Threat actors may not only be stealing AI access from fully developed applications, the researchers added. A developer trying to prototype an app, who, through carelessness, doesn’t secure a server, could be victimized through credential theft as well.

Joseph Steinberg, a US-based AI and cybersecurity expert, said the report is another illustration of how new technology like artificial intelligence creates new risks and the need for new security solutions beyond the traditional IT controls.

CSOs need to ask themselves if their organization has the skills needed to safely deploy and protect an AI project, or whether the work should be outsourced to a provider with the needed expertise.

Mitigation

Pillar Security said CSOs with externally-facing LLMs and MCP servers should:

  • enable authentication on all LLM endpoints. Requiring authentication eliminates opportunistic attacks. Organizations should verify that Ollama, vLLM, and similar services require valid credentials for all requests;
  • audit MCP server exposure. MCP servers must never be directly accessible from the internet. Verify firewall rules, review cloud security groups, confirm authentication requirements;
  • block known malicious infrastructure.  Add the 204.76.203.0/24 subnet to deny lists. For the MCP reconnaissance campaign, block AS135377 ranges;
  • implement rate limiting. Stop burst exploitation attempts. Deploy WAF/CDN rules for AI-specific traffic patterns;
  • audit production chatbot exposure. Every customer-facing chatbot, sales assistant, and internal AI agent must implement security controls to prevent abuse.

Don’t give up

Despite the number of news stories in the past year about AI vulnerabilities, Meghu said the answer is not to give up on AI, but to keep strict controls on its usage. “Do not just ban it, bring it into the light and help your users understand the risk, as well as work on ways for them to use AI/LLM in a safe way that benefits the business,” he advised.

“It is probably time to have dedicated training on AI use and risk,” he added. “Make sure you take feedback from users on how they want to interact with an AI service and make sure you support and get ahead of it. Just banning it sends users into a shadow IT realm, and the impact from this is too frightening to risk people hiding it. Embrace and make it part of your communications and planning with your employees.”

This article originally appeared on CSOonline.

(image/jpeg; 19 MB)

Google’s LiteRT adds advanced hardware acceleration 28 Jan 2026, 11:04 pm

LiteRT, Google’s “modern” on-device inference framework evolved from TensorFlow Lite (TFLite), has introduced advanced acceleration capabilities, based on a ”next-generation GPU engine” called ML Drift.

Google said that this milestone, announced January 28, solidifies LiteRT as a universal on-device framework and represents a significant leap over its predecessor, TFLite. LiteRT delivers 1.4x faster GPU performance than TFLite, provides a unified workflow for GPU and NPU acceleration across edge platforms, supports superior cross-platform deployment for generative AI models, and offers first-class PyTorch/JAX support through seamless model conversion, Google said. The company previewed LiteRT’s new acceleration capabilities last May.

Found on GitHub, LiteRT powers apps used every day, delivering low latency and high privacy on billions of devices, Google said. Via the new ML Drift GPU engine, LiteRT supports OpenCL, OpenGL, Metal, and WebGPU, allowing developers to deploy models across, mobile, desktop, and web. For Android, LiteRT automatically prioritizes when available for peak performance, while falling back to OpenGL for broader device coverage. In addition, LiteRT provides a unified, simplified NPU deployment workflow that abstracts away low-level, vendor-specific SDKs and handles fragmentation across numerous SoC (system on chip) variants, according to Google.

LiteRT documentation can be found at ai.google.dev.

(image/jpeg; 7.91 MB)

Teradata unveils enterprise AgentStack to push AI agents into production 28 Jan 2026, 9:17 am

Teradata has expanded the agent-building capabilities it launched last year into a full-blown toolkit, which it says will help enterprises address the challenge of moving AI agents beyond pilots into production-grade deployments.

Branded as Enterprise AgentStack, the expanded toolkit layers AgentEngine and AgentOps onto Teradata’s existing Agent Builder, which includes a user interface for building agents with the help of third-party frameworks such as LangGraph, and a context intelligence capability.

While AgentEngine is an execution environment for deploying agents across hybrid infrastructures, AgentOps is a unified interface for centralized discovery, monitoring, and lifecycle management of agents across a given enterprise.

The AgentEngine is a critical piece of Enterprise AgentStack as it sits between agent design and real-world operations, saidHyperFRAME Research’s practice leader of AI stack Stephanie Walter.

“Without an execution engine, enterprises often rely on custom glue code to coordinate agents. The Agent Engine standardizes execution behavior and gives enterprises a way to understand agent performance, reliability, and risk at scale,” Walter said, adding that AgentEngine-like capabilities are what enterprises need for moving agents or agentic systems into production.

However, analysts say Teradata’s approach to enterprise agent adoption differs markedly from that of rivals such as Databricks and Snowflake.

While Snowflake has been leaning on its Cortex and Native App Framework to let enterprises build AI-powered applications and agents closer to governed data, Databricks has been focusing on agent workflows through Mosaic AI, emphasizing model development, orchestration, and evaluation tied to its lakehouse architecture, Robert Kramer, principal analyst at Moor Insights and Strategy, said.

Seconding Kramer, Walter pointed out that Teradata’s differentiation lies in positioning Enterprise AgentStack as a vendor-agnostic execution and operations layer designed to work across hybrid environments, rather than anchoring agents tightly to a single cloud or data platform.

That positioning can be attributed to Teradata’s reliance on third-party frameworks such as Karini.ai, Flowise, CrewAI, and LangGraph, which give enterprises and their developers flexibility to evolve their agent architectures over time without being locked onto platforms from Snowflake and Databricks that tend to optimize for end-to-end control within their own environments, Walter added.

However, the analyst cautioned that, although Enterprise AgentStack’s architecture aligns well with enterprise needs, its litmus test will be to continue maintaining deep integrations with third-party frameworks.

“Customers will want to see concrete evidence of AgentStack supporting complex, long-running, multi-agent deployments in production,” Walter said.

Kramer, too, pointed out that enterprises and developers should try to understand the depth of usability before implementation.

“They need to check how easy it is to apply policies consistently, run evaluations after changes, trace failures end-to-end, and integrate with existing security and compliance tools. Openness only works if it doesn’t shift complexity back onto the customer,” Kramer said.

Enterprise AgentStack is expected to be made available in private preview on the cloud and on-prem between April and June this year.

(image/jpeg; 2.54 MB)

Is code a cow path? 28 Jan 2026, 9:00 am

When the automobile was first invented, many looked like—and were indeed called—horseless carriages.

Early websites for newspapers were laid out just like the paper versions. They still are to some extent.

Our computers have “desktops” and “files”—just like an office from the 1950s.

It is even said that the width of our railroad tracks is a direct result of the width between the wheels of a Roman chariot (though that claim is somewhat dubious).

This phenomenon—using new technology in the old technology way—is often called “paving the cow paths.” Cows are not known for understanding that the shortest distance between two points is a straight line, and it doesn’t always make sense to put pavement down where they wear tracks in the fields.

This notion was formalized by the great Peter Drucker, who said “There is surely nothing quite so useless as doing with great efficiency what should not be done at all.” 

All of this got me thinking about AI writing all of our code now. 

Is code necessary?

We developers spend years honing our craft. We read books about clean code, write blogs about the proper way to structure code, and tell ourselves, rightly, that code is meant to be read and maintained as much as it is to be written.

AI coding could change all of that. Your coding agent doesn’t need to see all that great stuff that we humans do. Comments, good variable names, cleanly constructed classes, and the like are all things we do for humans. Shoot, code itself is a human construct, a prop we created to make it easier to reason about the software we design and build. 

I was recently using Claude Code to build an application, and I insisted that he (I can’t help but think of Claude Code as a person) code against interfaces and not implementations, that he design everything with small classes that do one thing, etc. I wanted the code Claude created to be what we developers always shoot for—well-written, easy to maintain, and decoupled. You know the drill. 

And then it occurred to me—are we all merely paving cowpaths? Should agentic AI be concerned with the same things we humans care about when constructing software? Claude wrote comments all over the place—that was for me, not for him. He wrote the code the way that I wanted him to. Does he have a better idea about how to make the software work? 

For that matter, who needs code anyway? It’s not inconceivable that coding agents will eventually just render machine code—i.e., they could compile your native language directly into a binary. (That’s one way to end the language wars!)

Right now we have the process of writing code, reviewing it, compiling it, and running it. We’ve added an extra layer—explaining our intentions to an agent that translates them into code. If that is a cow path—and the more I think about it, the more it does seem a rather indirect way to get from point A to point B—then what will be the most direct way to get from here to there?

The straightest path to software

Every day, our coding agents get better. The better they get, the more we’ll trust them, and the less we’ll need to review their code before committing it. Someday, we might expect, agents will review the code that agents write. What happens to code when humans eventually don’t even read what the agents write anymore? Will code even matter at that point?

Will we write unit tests—or have our agents write unit tests—only for our benefit? Will coding agents even need tests? It’s not hard to imagine a future where agents just test their output automatically, or build things that just work without testing because they can “see” what the outcome of the tests would be. 

Ask yourself this: When is the last time that you checked the output of your compiler? Can you even understand the output of your compiler? Some of you can, sure. But be honest, most of you can’t. 

Maybe AI will come up with a way of designing software based on our human language inputs that is more direct and to the point—a way that we haven’t conceived of yet. Code may stop being the primary representation of software.

Maybe code will become something that, as Peter Drucker put it, should not be done at all.

(image/jpeg; 0.22 MB)

CPython vs. PyPy: Which Python runtime has the better JIT? 28 Jan 2026, 9:00 am

PyPy, an alternative runtime for Python, uses a specially created JIT compiler to yield potentially massive speedups over CPython, the conventional Python runtime.

But PyPy’s exemplary performance has often come at the cost of compatibility with the rest of the Python ecosystem, particularly C extensions. And while those issues are improving, the PyPy runtime itself often lags in keeping up to date with the latest Python releases.

Meanwhile, the most recent releases of CPython included the first editions of a JIT compiler native to CPython. The long-term promise there is better performance, and in some workloads, you can already see significant improvements. CPython also has a new alternative build that eliminates the GIL to allow fully free-threaded operations—another avenue of significant performance gains.

Could CPython be on track to displace PyPy for better performance? We ran PyPy and the latest JIT-enabled and no-GIL CPython builds side by side on the same benchmarks, with intriguing results.

PyPy still kills it at raw math

CPython has always performed poorly in simple numerical operations, due to all the indirection and abstraction required. There’s no such thing in CPython as a primitive, machine-level integer, for instance.

As a result, benchmarks like this one tend to perform quite poorly in CPython:


def transform(n: int):
    q = 0
    for x in range(0, n * 500):
        q += x
    return q


def main():
    return [transform(x) for x in range(1000)]

main()

On a Ryzen 5 3600 with six cores, Python 3.14 takes about 9 seconds to run this benchmark. But PyPy chews through it in around 0.2 seconds.

This also isn’t the kind of workload that benefits from Python’s JIT, at least not yet. With the JIT enabled in 3.14, the time drops only slightly, to around 8 seconds.

But what happens if we use a multi-threaded version of the same code, and throw the no-GIL version of Python at it?


def transform(n: int):
    q = 0
    for x in range(0, n * 500):
        q += x
    return q


def main():
    result = []
    with ThreadPoolExecutor() as pool:
        for x in range(1000):
            result.append(pool.submit(transform, x))
    return [_.result() for _ in result]

main()

The difference is dramatic, to say the least. Python 3.14 completes this job in 1.7 seconds. Still not the sub-second results of PyPy, but a big enough jump to make using threads and no-GIL worth it.

What about PyPy and threading? Ironically, running the multithreaded version on PyPy slows it down drastically, with the job taking around 2.1 seconds to run. Blame that on PyPy still having a GIL-like locking mechanism, and therefore no full parallelism across threads. Its JIT compilation is best exploited by running everything in a single thread.

If you’re wondering if swapping a process pool for a thread pool would help, the answer is, not really. A process pool version of the above does speed things up a bit—1.3 seconds on PyPy—but process pools and multiprocessing on PyPy are not as optimized as they are in CPython.

To recap: for “vanilla” Python 3.14:

  • No JIT, GIL: 9 seconds
  • With JIT, GIL: 8 seconds
  • No JIT, no-GIL: 9.5 seconds

The no-GIL build is still slightly slower than the regular build for single-threaded operations. The JIT helps a little here, but not much.

Now, consider the same breakdown for Python 3.14 and a process pool:

  • No JIT, GIL: 1.75 seconds
  • With JIT, GIL: 1.5 seconds
  • No JIT, no-GIL: 2 seconds

How about for Python 3.14, using other forms of the script?

  • Threaded version with no-GIL: 1.7 seconds
  • Multiprocessing version with GIL: 2.3 seconds
  • Multiprocessing version with GIL and JIT: 2.4 seconds
  • Multiprocessing version with no-GIL: 2.1 seconds

And here’s a summary of how PyPy fares:

  • Single-threaded script: 0.2 seconds
  • Multithreaded script: 2.1 seconds
  • Multiprocessing script: 1.3 seconds

The n-body problem

Another common math-heavy benchmark vanilla Python is notoriously bad at is the “n-body” benchmark. This is also the kind of problem that’s hard to speed up by using parallel computation. It is possible, just not simple, so the easiest implementations are single-threaded.

If I run the n-body benchmark for 1,000,000 repetitions, I get the following results:

  • Python 3.14, no JIT: 7.1 seconds
  • Python 3.14, JIT: 5.7 seconds
  • Python 3.15a4, no JIT: 7.6 seconds
  • Python 3.15a4, JIT: 4.2 seconds

That’s an impressive showing for the JIT-capable editions of Python. But then we see that PyPy chews through the same benchmark in 0.7 seconds—as-is.

Computing pi

Sometimes even PyPy struggles with math-heavy Python programs. Consider this naive implementation to calculate digits of pi. This is another example of a task that can’t be parallelized much, if at all, so we’re using a single-threaded test.

When run for 20,000 digits, here’s what came out:

  • Python 3.14, no JIT: 13.6 seconds
  • Python 3.14, JIT: 13.5 seconds
  • Python 3.15, no JIT: 13.7 seconds
  • Python 3.15, JIT: 13.5 seconds
  • PyPy: 19.1 seconds

It’s uncommon, but hardly impossible, for PyPy’s performance to be worse than regular Python’s. What’s surprising is to see it happen in a scenario where you’d expect PyPy to excel.

CPython is getting competitive for other kinds of work

Another benchmark I’ve used often with Python is a variant of the Google n-gram benchmark, which processes a multi-megabyte CSV file and generates some statistics about it. That makes it more I/O-bound than the previous benchmarks, which were more CPU-bound, but it’s still possible to use it for useful information about the speed of the runtime.

I’ve written three incarnations of this benchmark: single-threaded, multi-threaded, and multi-process. Here’s the single-threaded version:


import collections
import time
import gc
import sys
try:
    print ("JIT enabled:", sys._jit.is_enabled())
except Exception:
    ...

def main():
    line: str
    fields: list[str]
    sum_by_key: dict = {}

    start = time.time()

    with open("ngrams.tsv", encoding="utf-8", buffering=2 

Here’s how Python 3.14 handles this benchmark with different versions of the script:

  • Single-threaded, GIL: 4.2 seconds
  • Single-threaded, JIT, GIL: 3.7 seconds
  • Multi-threaded, no-GIL: 1.05 seconds
  • Multi-processing, GIL: 2.42 seconds
  • Multi-processing, JIT, GIL: 2.4 seconds
  • Multi-processing, no-GIL: 2.1 seconds

And here’s the same picture with PyPy:

  • Single-threaded: 2.75 seconds
  • Multi-threaded: 14.3 seconds (not a typo!)
  • Multi-processing: 8.7 seconds

In other words, for this scenario, the CPython no-GIL multithreaded version beats even PyPy at its most optimal. As yet, there is no build of CPython that enables the JIT and uses free threading, but such a version is not far away and could easily change the picture even further.

Conclusion

In sum, PyPy running the most basic, unoptimized version of a math-heavy script still outperforms CPython. But CPython gets drastic relative improvements from using free-threading and even multiprocessing, where possible.

While PyPy cannot take advantage of those built-in features, its base speed is fast enough that using threading or multiprocessing for some jobs isn’t really required. For instance, the n-body problem is hard to parallelize well, and computing pi can hardly be parallelized at all, so it’s a boon to be able to run single-threaded versions of those algorithms fast.

What stands out most from these tests is that PyPy’s benefits are not universal, or even consistent. They vary widely depending on the scenario. Even within the same program, there can be a tremendous variety of scenarios. Some programs can run tremendously fast with PyPy, but it’s not easy to tell in advance which ones. The only way to know is to benchmark your application.

Something else to note is that one of the major avenues toward better performance and parallelism for Python generally—free-threading—isn’t currently available for PyPy. Multiprocessing doesn’t work well in PyPy either, due to it having a much slower data serialization mechanism between processes than CPython does.

As fast as PyPy can be, the benchmarks here show the benefits of true parallelism with threads in some scenarios. PyPy’s developers might find a way to implement that in time, but it’s unlikely they’d be able to do it by directly repurposing what CPython already has, given how different PyPy and CPython are under the hood.

(image/jpeg; 8.16 MB)

Gemini Flash model gets visual reasoning capability 28 Jan 2026, 3:20 am

Google has added an Agentic Vision capability to its Gemini 3 Flash model, which the company said combines visual reasoning with code execution to ground answers in visual evidence. The capability fundamentally changes how AI models process images, according to Google.

Introduced January 27, Agentic Vision is available via the Gemini API in the Google AI Studio development tool and Vertex AI in the Gemini app.

Agentic Vision in Gemini Flash converts image understanding from a static act into an agentic process, Google said. By combining visual reasoning andcode execution, the model formulates plans to zoom in, inspect, and manipulate images step-by-step. Until now, multimodal models typically processed the world in a single, static glance. If they missed a small detail—like a serial number or a distant sign—they were forced to guess, Google said. By contrast, Agentic Vision converts image understanding into an active investigation, introducing an agentic, “think, act, observe” loop into image understanding tasks, the company said.

Agentic Vision allows a model to interact with its environment by annotating images. Instead of just describing what it sees, Gemini 3 Flash can execute code to draw directly on the canvas to ground reasoning. Also, Agentic Vision can parse high-density tables and execute Python code to visualize findings. Future plans for Agentic Vision including adding more implicit code-driven behaviors, equipping Gemini models with more tools, and delivering the capability in more model sizes, extending it beyond Flash.

(image/jpeg; 9.21 MB)

OpenSilver 3.3 runs Blazor components inside XAML apps 27 Jan 2026, 10:37 pm

Userware has released OpenSilver 3.3, an update to the open-source framework for building cross-platform applications using C# and XAML. OpenSilver 3.3 lets Blazor components for web development run directly inside XAML applications, streamlining the process of running these components.

Userware unveiled OpenSilver 3.3 on January 27. OpenSilver SDKs for Microsoft’s Visual Studio and Visual Studio Code can be downloaded from opensilver.net.

With the Blazor boost in OpenSilver 3.3, Blazor components run directly inside an XAML visual tree, sharing the same DOM and the same runtime. Developers can drop a MudBlazor data grid, a DevExpress rich text editor, or any Blazor component directly into their XAML application without requiring JavaScript bridges or interop wrappers, according to Userware. Because OpenSilver runs on WebAssembly for browsers and .NET MAUI Hybrid for native apps, the same code deploys to Web, iOS, Android, Windows, macOS, and Linux.

The company did warn, though, that Razor code embedded inside XAML will currently show errors at design time but will compile and run correctly. Workarounds include wrapping the Razor code in CDATA, using separate .razor files, or filtering to “Build Only” errors.

Open source OpenSilver is a replacement for Microsoft Silverlight, a rich Internet application framework that was discontinued in 2021 and is no longer supported. For developers maintaining a Silverlight or Windows Presentation Foundation app, Blazor integration offers a way to modernize incrementally. Users can identify controls that need updating, such as an old data grid or a basic text editor, and replace them with modern Blazor equivalents.

    (image/jpeg; 0.24 MB)

    Anthropic integrates third‑party apps into Claude, reshaping enterprise AI workflows 27 Jan 2026, 12:47 pm

    Anthropic has added a new capability inside its generative AI-based chatbot Claude that will allow users to directly access applications inside the Claude interface.

    The new capability, termed as interactive apps, is based on a new extension — MCP Apps — of the open source Model Context Protocol (MCP).

    MCP Apps, first proposed in November and subsequently developed with the help of OpenAI’s Apps SDK, expands MCP’s capabilities to allow tools to be included as interactive UI components directly inside the chat window as part of a conversation, instead of just text or query results.

    “Claude already connects to your tools and takes actions on your behalf. Now those tools show up right in the conversation, so you can see what’s happening and collaborate in real time,” the company wrote in a blog post.

    Currently, the list of interactive apps is limited to Amplitude, Asana, Box, Canva, Clay, Figma, Hex, monday.com, and Slack. Agentforce 360 from Salesforce will be added soon, the company said, adding that the list will be expanded to include other applications.

    Easier integration into workflows

    Claude’s evolution from a chatbot into an integrated execution environment for applications is expected to help enterprises move agentic AI systems toward broader, production-scale deployments, analysts say.

    The ability to access applications directly within Claude’s interface lowers integration friction, making it simpler for enterprises to deploy Claude as an agentic system across workflows, said Akshat Tyagi, associate practice leader at HFS Research.

    “Most pilots fail in production because agents are unpredictable, hard to govern, and difficult to integrate into real workflows. Claude’s interactive apps change that,” Tyagi noted.

    For enterprise developers, the reduction in integration complexity could also translate into faster iteration cycles and higher productivity, according to Forrester Principal Analyst Charlie Dai.

    The approach provides a more straightforward path to building multi-step, output-producing workflows without the need for extensive setup or custom plumbing, Dai said.

    Targeting more productivity

    According to Tyagi, productivity gains will not only be limited to developers, but business teams will stand to benefit as well, and teams don’t need to move between systems, copy outputs, or translate AI responses into actions due to the integration of multiple applications within Claude’s interface.

    MCP Apps and Anthropic’s broader approach to productivity underscore a widening architectural split in the AI landscape, according to Avasant research director Chandrika Dutt, even as vendors pursue the same underlying goal of boosting productivity by embedding agents directly into active workflows.

    While Anthropic and OpenAI are building models in which applications run inside the AI interface, other big tech vendors, including Microsoft and Google, are focused on embedding AI directly into their productivity suites, such as Microsoft 365 Copilot and Google Gemini Workspace, Dutt said.

    “These strategies represent two paths toward a similar end state. As enterprise demand for agent-driven execution grows, in a separate layer, it is likely that these approaches will converge, with Microsoft and Google eventually supporting more interactive, app-level execution models as well,” Dutt added.

    Further, the analyst pointed out that Claude’s new interactive apps will also facilitate easier governance and trust — key facets of scaling agentic AI systems in an enterprise.

    “Claude operates on the same live screen, data, and configuration the user is viewing, allowing users to see exactly what changes are made, where they are applied, and how they affect tasks, files, or design elements in real time, without having to cross-check across different tools,” Dutt said.

    Increased burden of due diligence

    However, analysts cautioned that the unified nature of the interface may exponentially increase the risk from a security standpoint, especially as more applications are added.

    More so because running UIs of these interactive applications means running code that enterprises didn’t write themselves and that will increase the burden of due diligence before connecting to an interactive application, said Abhishek Sengupta, practice director at Everest Group.

    MCP Apps itself, though, offers several security features, in the form of sandboxing UIs, the ability for enterprises to review all templates before rendering, and audit messages between the application server and their Claude client.

    The interactive app feature is currently available to all paid subscribers of Claude, including Pro, Max, Team, and Enterprise subscribers.

    It is expected to be added to Claude Cowork soon, the company said.

    (image/jpeg; 2.6 MB)

    Page processed in 0.369 seconds.

    Powered by SimplePie 1.4-dev, Build 20170403172323. Run the SimplePie Compatibility Test. SimplePie is © 2004–2026, Ryan Parman and Geoffrey Sneddon, and licensed under the BSD License.