[Ed. note: As we take a break for the holidays and gear up for the new year, we’re revisiting our top ten posts of the year. Enjoy this favorite from 2023, and we’ll see you in 2024!]
Amidst the hype surrounding AI advancements, a common concern arises among software developers: could artificial intelligence render our jobs obsolete? The vision of business executives and product managers bypassing developers to directly instruct AI to build software tailored to their needs fuels anxieties about job security. However, with 15 years of experience in translating specifications into software, I find this apprehension largely unfounded.
While coding presents its challenges, debugging code has rarely been a weeks-long ordeal for me. Once you grasp the syntax, logic, and methodologies, coding becomes a relatively straightforward process, most of the time. The real bottlenecks in software creation lie not in writing code, but in defining what the software should actually do. The most demanding aspect of software development isn’t the coding itself – it’s crafting clear, comprehensive, and accurate requirements, and these requirements remain firmly in the human domain.
This article will explore the critical relationship between well-defined requirements and successful software, and why even the most sophisticated AI still relies on human clarity to deliver meaningful results.
Feature or Bug? The Perils of Ambiguous Requirements
Early in my career, I joined a project midway to accelerate the team’s progress. The software’s core function was to configure bespoke products on e-commerce platforms. My specific task was to generate dynamic terms and conditions, incorporating conditional clauses based on product type and the customer’s US state, driven by legal stipulations.
During development, I identified a potential flaw. A user could select a product type, triggering the correct terms and conditions, but later in the workflow, they could switch to a different product type while retaining the initial terms. This contradicted a key feature explicitly agreed upon in the business requirements document, signed off by the client.
Naively, I inquired with the client, “Should we prevent users from overriding the correct terms and conditions?” The response, delivered with unwavering certainty, is etched in my memory:
“That will never happen.”
This came from a senior executive, a long-tenured expert in the company’s business processes, entrusted with overseeing the software project. The very person who explicitly requested the override capability dismissed its potential misuse. Who was I, a junior developer, to question a senior executive of a paying client? I dismissed my concern and moved on.
Months later, mere weeks before the software launch, a client-side tester reported a defect, assigned to me. Upon reviewing the details, I couldn’t help but laugh.
My initial apprehension about overriding terms, the scenario deemed impossible? It was happening. And guess who was tasked with fixing it, and blamed for its occurrence?
The fix was simple, and the bug’s impact was minimal. Yet, this experience became a recurring theme throughout my software development journey. Conversations with fellow software engineers confirmed I wasn’t alone. The problems grew in scale and complexity, becoming harder and costlier to resolve, but the root cause often remained the same: unclear, inconsistent, or simply incorrect requirements.
Confused cartoon character surrounded by question marks
AI Capabilities: Chess Mastery vs. Real-World Complexity
Artificial intelligence, a concept with a long history, has recently surged into public consciousness with high-profile advancements, sparking media attention and even congressional scrutiny. AI has already demonstrated remarkable success in specific domains, most notably in games like chess.
AI’s application to chess dates back to the 1980s. Today, it’s widely accepted that AI surpasses human chess-playing ability. This isn’t surprising considering chess operates within finite parameters (though the game itself remains unsolved).
Chess begins with a fixed set of 32 pieces on a 64-square board, governed by well-defined, universally accepted rules, and a singular, clear objective: checkmate the opponent’s king. Each turn presents a finite number of possible moves. Playing chess is essentially executing a complex rules engine. AI systems excel at calculating the consequences of every move, selecting the optimal strategy to capture pieces, gain positional advantage, and ultimately win.
Another area of intense AI development is self-driving cars. Manufacturers have long promised autonomous vehicles, and while some cars now possess self-driving capabilities, they often come with significant limitations. Many systems require constant driver supervision, mandating hands on the wheel – far from true autonomy.
Like chess AIs, self-driving cars heavily rely on rules-based engines for decision-making. However, unlike chess, the rules for navigating every conceivable driving situation are not clearly defined. Driving involves countless split-second judgments – avoiding pedestrians, maneuvering around obstacles, navigating busy intersections. These nuanced decisions are the difference between a safe arrival and a trip to the emergency room.
In technology, high availability is paramount. The gold standard is often five or even six 9s of availability – meaning a website or service is operational 99.999% (or 99.9999%) of the time. Achieving the first 99% availability is relatively straightforward. It allows for over three days (87.6 hours) of downtime annually. However, each additional “9” exponentially increases the complexity and cost. Reaching 99.9999% availability permits only 31.5 seconds of downtime per year. This requires vastly more rigorous planning, effort, and expense. While achieving the initial 99% isn’t trivial, it’s proportionally much easier and cheaper than securing that final fraction of perfection.
Availability Percentage | Downtime per Year |
---|---|
99% | 87.6 hours |
99.9% | 8.76 hours |
99.99% | Less than 1 hour (52 minutes) |
99.999% | 5.2 minutes |
99.9999% | Roughly 31.5 seconds |
No matter how advanced AI becomes in self-driving, the risk of accidents and fatalities persists. These risks are, of course, present even with human drivers. The acceptable accident and fatality rate for self-driving cars, likely determined by governmental regulations, will almost certainly need to be at least as good as, if not better than, human driving.
The challenge in achieving this level of safety stems from the vastly greater number of variables in driving compared to chess. These variables are not finite. The initial 95% or 99% of driving scenarios might be predictable and manageable. However, the long tail of edge cases – other drivers, road closures, construction, accidents, weather, faded lane markings – presents immense complexity. Each edge case is unique, making it incredibly difficult for AI to anticipate, recognize, and respond appropriately without causing accidents. While edge cases may share some characteristics, their unique combinations defy simple rule-based solutions.
AI: Code Generator, Not Software Creator
Software development shares more similarities with driving than chess. It involves a multitude of variables, and its “rules” often rely on human judgment and interpretation. While software projects have desired outcomes, they are rarely as singular and clearly defined as winning a chess game. Software is rarely “finished”; it evolves continuously with new features, bug fixes, and adaptations – it’s an ongoing process. Chess, in contrast, concludes definitively with a win or loss.
In software development, we use technical specifications to bring some of the structured rule-based clarity of chess to our projects. Ideally, specs detail expected user interactions and program workflows – “to buy an e-sandwich, the user clicks this button, creating this data structure, triggering this service.” However, reality often falls short. We are frequently given vague wishlists, napkin-sketch wireframes, and ambiguous requirements documents, and tasked with “making our best judgment.”
Even worse, requirements frequently change or are outright ignored. Recently, I was asked to contribute to a project aimed at providing COVID-19 health information via SMS surveys in areas with unreliable Wi-Fi. Initially enthusiastic, I soon recognized potential problems.
Asking a retail customer to rate their shopping experience on a 1-10 scale is vastly different from conducting multi-step surveys with multiple-choice questions about COVID-19 symptoms via SMS. While I didn’t refuse outright, I raised numerous potential failure points, emphasizing the need for clear protocols for handling incoming SMS responses. How would comma-separated numbers be mapped to answers? What if a response didn’t match any given options?
After discussing these concerns, the team concluded that proceeding was unwise without resolving these data handling complexities. This, I believe, was a successful outcome. Pushing forward without clear solutions for potential errors and invalid user data would have been far more wasteful.
Will AI-driven software creation simply empower stakeholders to directly instruct computers to build SMS surveys based on equally vague specifications? Will AI proactively ask probing questions about handling data inconsistencies and potential errors in SMS survey responses? Will it account for the inevitable human mistakes and devise robust error handling strategies?
To generate functional software with AI, you must possess a clear vision of your desired outcome and articulate it with precision. Even when developing software for personal use, unforeseen challenges and complexities often emerge only when coding commences.
Over the past decade, the software industry has largely shifted from the waterfall methodology to agile. Waterfall mandates complete requirement definition before coding begins, while agile embraces flexibility and iterative adjustments throughout the development process.
Countless waterfall projects have failed because stakeholders, despite believing they knew what they wanted and could accurately document it, were deeply disappointed with the final product. Agile development emerged as a response to these inherent limitations of the waterfall approach.
AI might excel at rewriting existing software for new hardware or modern programming languages. Many organizations still rely on software written in COBOL, but the pool of COBOL programmers is shrinking. If your needs are precisely defined, AI could potentially create software faster and cheaper than human teams, especially for tasks like rewriting existing code where the functionality is already well-understood. AI could likely replicate software already created by humans more efficiently – because humans initially defined what that software should do.
AI might even perform well with the waterfall process, sometimes ironically called the “death march.” The problem with waterfall isn’t the coding phase; it’s everything before that – the requirement definition. Humans struggle with waterfall not because of the coding itself, but because accurately and completely defining requirements upfront is incredibly difficult. Artificial intelligence is capable of extraordinary feats, but it cannot read minds or intuitively grasp what users truly need or want.