<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.2.2">Jekyll</generator><link href="https://sufficiently-advanced.technology/feed.xml" rel="self" type="application/atom+xml" /><link href="https://sufficiently-advanced.technology/" rel="alternate" type="text/html" /><updated>2025-09-10T18:20:56+00:00</updated><id>https://sufficiently-advanced.technology/feed.xml</id><title type="html">Sufficiently Advanced Technology</title><subtitle>Architecture, REST, Knowledge Graphs, etc.</subtitle><entry><title type="html">Skydiving, Serendipity, and the Boxes We Build for Ourselves</title><link href="https://sufficiently-advanced.technology/post/skydiving-and-serendipity" rel="alternate" type="text/html" title="Skydiving, Serendipity, and the Boxes We Build for Ourselves" /><published>2025-09-09T00:00:00+00:00</published><updated>2025-09-09T00:00:00+00:00</updated><id>https://sufficiently-advanced.technology/post/skydiving-and-serendipity</id><content type="html" xml:base="https://sufficiently-advanced.technology/post/skydiving-and-serendipity"><![CDATA[<figure class="aligncenter">
	<img property="image" src="https://sufficiently-advanced.technology/assets/images/skydiving.png" width="800" height="300" alt="GoPro capture of Michael and friends mid-skydive" />
</figure>

<h1 id="skydiving-serendipity-and-the-boxes-we-build-for-ourselves"><strong>Skydiving, Serendipity, and the Boxes We Build for Ourselves</strong></h1>

<p>In 2013, a few days before my birthday, I was running errands—the usual grind. I remember sitting in the parking lot of a bank, weighed down by a nagging thought: <em>How should I celebrate?</em></p>

<p>Suddenly, I remembered something I’d always wanted to do: skydive.</p>

<p>My first reaction was the same as always: <em>Someday I’ll do that.</em></p>

<p>But then I caught myself. <strong>When is “someday”?</strong> It’s not on any calendar I’ve ever owned.</p>

<p>At that moment, I realized I had no real excuse. I lived in a major metro area, certainly big enough to support a skydiving operation or two. I had disposable income from my work as a software architect and my nights and weekends gigging as a magician.</p>

<p>Why not today?</p>

<p>That thought—<em>someday could be today</em>—ended up being the genesis of a kind of rebirth. The day I discovered the difference between <strong>existing</strong> and <strong>living</strong>.</p>

<!--more-->

<h2 id="the-first-jump">The First Jump</h2>

<p>A quick web search led me to Skydive Spaceland, and I booked a tandem jump for the following weekend.</p>

<p>The days leading up to the jump, I was full of bravado. On the day itself, I was joined by friends and family—a few courageous enough to jump with me.</p>

<p>We signed waivers, sat through instructional videos (and disclaimers), met our tandem instructors, were geared up, and crammed into the plane.</p>

<p>At altitude, my bravado began to evaporate. Conversation wasn’t possible over the roar of the engines, and without a phone to distract me, I sat silently with my thoughts. Watching the world shrink beneath the window was sobering.</p>

<p>At around 6,500 feet, the plane throttled back and a red light came on above the door. One man—someone I assumed was staff—crouched by the open door, checked the light, and then… <strong>woooosh.</strong> He was gone.</p>

<p>Not staff. Not a tandem student. Just a guy jumping for fun.</p>

<p>It was horrifying. But the plane climbed on.</p>

<h2 id="fear-then-flight">Fear, Then Flight</h2>

<p>By the time it was my turn at the door, I was convinced this was the worst idea of my life. I braced for terror, told myself, <em>“a minute is nothing.”</em></p>

<p>And then—</p>

<p>We weren’t falling. <strong>We were flying.</strong></p>

<p>There’s really no other way to describe it. Zero terror. Zero rollercoaster drop. Just play, in the sky.</p>

<p>For once, my brain—the one that never shuts up—was silent. I was 100% present, completely in the moment.</p>

<h2 id="under-canopy">Under Canopy</h2>

<p>Once the parachute deployed, it was a whole new experience.</p>

<p>It’s silent. Peaceful. A 360° panorama. Clouds at arm’s reach. I tugged on the controls, playing with turns and spirals, before my tandem instructor guided us to a precision landing in front of the waiting cameraman.</p>

<p>Afterward, they tried to upsell me on another tandem jump. Savvy move—who wouldn’t want to do it again?</p>

<p>But I had seen something else: <strong>the fun jumper.</strong></p>

<p>Not staff. Not a one-off thrill-seeker. Just someone who played in the sky because he wanted to.</p>

<p>And I realized: <em>that could be me.</em></p>

<h2 id="beyond-one-more-ride">Beyond “One More Ride”</h2>

<p>Instead of buying another ticket, I signed up for the license program. A week later I made my first solo jump. A few weeks after that, I had my license.</p>

<p>Skydiving taught me three important lessons that go far beyond the drop zone:</p>

<ol>
  <li><strong>“Someday” isn’t on the calendar.</strong> If you want to make it happen, make it happen. A goal is a dream with a deadline.</li>
  <li><strong>We put ourselves in boxes of our own construction.</strong> There are more possibilities than the ones we assume.</li>
  <li><strong>Everything cool is on the other side of fear.</strong></li>
</ol>

<hr />

<div class="youtube-wrapper">
    <iframe src="https://www.youtube.com/embed/M1FRInaGlfc" allowfullscreen=""></iframe>
</div>

<h2 id="postscript-being-new-again">Postscript: Being New Again</h2>

<p>I was a below-average canopy pilot, and I botched most of my first 80 landings. I couldn’t control my fall rate very well.</p>

<p>I had forgotten what it was like to be new at something. That’s an important skill to (re)learn, because as we get older, we tend to give up too quickly.</p>

<p>Skydiving reminded me that stumbling through the awkward phase is how we grow—whether in the sky or anywhere else.</p>]]></content><author><name>Michael</name><uri>https://w3id.org/people/michael</uri></author><summary type="html"><![CDATA[Skydiving, Serendipity, and the Boxes We Build for Ourselves In 2013, a few days before my birthday, I was running errands—the usual grind. I remember sitting in the parking lot of a bank, weighed down by a nagging thought: How should I celebrate? Suddenly, I remembered something I’d always wanted to do: skydive. My first reaction was the same as always: Someday I’ll do that. But then I caught myself. When is “someday”? It’s not on any calendar I’ve ever owned. At that moment, I realized I had no real excuse. I lived in a major metro area, certainly big enough to support a skydiving operation or two. I had disposable income from my work as a software architect and my nights and weekends gigging as a magician. Why not today? That thought—someday could be today—ended up being the genesis of a kind of rebirth. The day I discovered the difference between existing and living.]]></summary></entry><entry><title type="html">Metaphysics and Software Architecture</title><link href="https://sufficiently-advanced.technology/post/architecture-metaphysics" rel="alternate" type="text/html" title="Metaphysics and Software Architecture" /><published>2025-05-05T00:00:00+00:00</published><updated>2025-05-05T00:00:00+00:00</updated><id>https://sufficiently-advanced.technology/post/architecture-metaphysics</id><content type="html" xml:base="https://sufficiently-advanced.technology/post/architecture-metaphysics"><![CDATA[<figure class="aligncenter">
	<img property="image" src="https://sufficiently-advanced.technology/assets/images/athens.jpg" width="800" height="300" alt="THe SChool of Athens, a fresco that depicts a congregation of ancient philosophers, mathematicians, and scientists, with Plato and Aristotle featured in the center. The identities of most figures are ambiguous or discernable only through subtle details or allusions; among those commonly identified are Socrates, Pythagoras, Archimedes, Heraclitus, Averroes, and Zarathustra. Additionally, Italian artists Leonardo da Vinci and Michelangelo are believed to be portrayed through Plato and Heraclitus, respectively. Raphael included a self-portrait beside Ptolemy. Raphael is the second character who is looking directly at the viewer in the artwork, the first being Hypatia - a woman in the white robe, who stands between Parmenides and Pythagoras." />
</figure>

<p>Metaphysics and Software Architecture? Hear me out…</p>

<p>Suppose I roll a red ball across the floor.</p>

<p>Where did the redness come from?</p>

<p>Plato might say it comes from the abstract “Form of Redness.” Aristotle might argue it’s a property the ball possesses. Hume? He’d ask you to stop being weird and go touch some grass.</p>

<p>Now… where do architecture illities come from?</p>

<!--more-->

<p>Scalability. Maintainability. Evolvability. Elasticity.</p>

<p>Are they inherent in the system? Emergent from behavior? Or… do they arise from something deeper?</p>

<p>Roy Fielding, Dewayne Perry, and Alexander Wolf suggest these ilities emerge from architectural constraints. We know a “big ball of mud” is defined by no constraints, when we constrain the degrees of freedom in implementation of a system, we induce the illitites.</p>

<p>Constraints are atomic, composable, architecturally significant decisions. They define the patterns we over-focus on and they are the real tools of the thoughtful software architect. They’re the metaphysical substrate beneath your system’s behavior.</p>

<p>So if you’re chasing quality attributes, you’re not chasing emergent magic. You’re choosing constraints. You’re crafting trade-offs. This is the heart of the message of my book and the Tailor Made Software Architecture model. Weighted trade-offs and deterministic results. The new old way of thinking about software architecture.</p>

<p>So I ask again:
Where do your system’s “ilities” really come from?</p>

<p>Are you choosing them… or are they choosing you?</p>]]></content><author><name>Michael</name><uri>https://w3id.org/people/michael</uri></author><category term="architecture" /><category term="architecture" /><summary type="html"><![CDATA[Metaphysics and Software Architecture? Hear me out… Suppose I roll a red ball across the floor. Where did the redness come from? Plato might say it comes from the abstract “Form of Redness.” Aristotle might argue it’s a property the ball possesses. Hume? He’d ask you to stop being weird and go touch some grass. Now… where do architecture illities come from?]]></summary></entry><entry><title type="html">Reflecting on GIDS 2025</title><link href="https://sufficiently-advanced.technology/post/gids-wrap-up" rel="alternate" type="text/html" title="Reflecting on GIDS 2025" /><published>2025-04-26T00:00:00+00:00</published><updated>2025-04-26T00:00:00+00:00</updated><id>https://sufficiently-advanced.technology/post/gids-wrap-up</id><content type="html" xml:base="https://sufficiently-advanced.technology/post/gids-wrap-up"><![CDATA[<figure class="aligncenter">
	<img property="image" src="https://sufficiently-advanced.technology/assets/images/gids-2025.jpg" width="800" height="300" alt="Michael Carducci on a large stage taking a bow to a standing ovation in a large auditorium" />
</figure>

<p>Yesterday marked the conclusion of a whirlwind week in Bengaluru at the Great International Developer Summit. As I embark on my long journey home (30+ hours of travel) I am left both energized and humbled by all I have experienced.</p>

<!--more-->

<p>GIDS 2025 truly is a magical confluence of people, ideas, technologies, cultures, perspectives, ideas, as so much more.</p>

<p>If you were there, I want you to know how much I appreciate all that your brought to make this event so special. You and I are vertices in this vast graph that both bring unique connections and value by inducing network effects; we are the living embodiment of R Buckminster Fuller’s concept of Synergistics.</p>

<p>Of course, I was happy to see many old and dear friends, but I am also grateful for all the new friendships we cultivated together. Every hug, handshake, selfie, and book signing is a cherished memory for me.</p>

<p>Extra special thanks to Apress for organizing and surprising me with a first-of-it’s-kind orchestrated book launch!</p>

<p>To all my friends at GIDS, new and old, thank you from the bottom of my heart!</p>

<div class="youtube-wrapper">
    <iframe src="https://www.youtube.com/embed/a42a3CQRp1s" allowfullscreen=""></iframe>
</div>]]></content><author><name>Michael</name><uri>https://w3id.org/people/michael</uri></author><summary type="html"><![CDATA[Yesterday marked the conclusion of a whirlwind week in Bengaluru at the Great International Developer Summit. As I embark on my long journey home (30+ hours of travel) I am left both energized and humbled by all I have experienced.]]></summary></entry><entry><title type="html">Let’s Stop Going in Circles</title><link href="https://sufficiently-advanced.technology/post/innovation-foundations" rel="alternate" type="text/html" title="Let’s Stop Going in Circles" /><published>2025-04-15T00:00:00+00:00</published><updated>2025-04-15T00:00:00+00:00</updated><id>https://sufficiently-advanced.technology/post/innovation-foundations</id><content type="html" xml:base="https://sufficiently-advanced.technology/post/innovation-foundations"><![CDATA[<figure class="aligncenter">
	<img property="image" src="https://sufficiently-advanced.technology/assets/images/not-easy-to-become-educated.jpg" width="800" height="300" alt="A perfectly still lake reflects a warm sunset that fades from an orange that is the warm glow of an ember into a deep violet that feels like twilight on a late summer evening. There is a gentle mist hovering above the lake that feels like the cool damp air that you can feel on your face as you walk, but doesn’t condense. Although the mist is light, it partially obscures group of trees, softly silhouetted in the distance. A rustic jetty extends into water, almost inviting you to let go of all your cares and walk into the infinity that is the sunset. A small canoe sits peacefully to the right. And the quote overlaid reads: 'it is not easy to become and educated person' Attributed to Richard Hamming " />
</figure>

<p>Why does it feel like so much of tech is just reinventing the same ideas every few years?</p>

<p>I have a theory…</p>

<!--more-->

<p>We were conditioned to believe education is a means to an end. “Choose the right degree so you can get a good job!” I remember being strongly advised against reading a philosophy degree in favor of reading science or CS. Many of us were advised to avoid “useless” degrees in favor or “valuable” ones. The ones who didn’t are sometimes the butt of jokes.</p>

<p>This repeated framing of knowledge as “useless” or “valuable” often can’t help but stick with us. It unintentionally narrows our future mindset on continuing education. We select books and conference talks on utility, sometimes ignoring our intuition and dulling our natural curiosity.</p>

<p>When we limit learning to what seems useful in the immoderate future, we rob ourselves of broader context and lateral discoveries.</p>

<p>There are so many great lessons and important ideas from the past that remain more relevant than ever but they are being lost. We need to widen our learning bands and build the future upon the lessons of those who came before us rather than wasting time and potential re-learning them.</p>

<p>To quote Richard Hamming:</p>

<p>“In your future anything and everything you know might be useful. but if you believe the problem is in one area you are not apt to use information that is relevant but which occurred [elsewhere].”</p>]]></content><author><name>Michael</name><uri>https://w3id.org/people/michael</uri></author><category term="architecture" /><category term="architecture" /><category term="problem-solving" /><summary type="html"><![CDATA[Why does it feel like so much of tech is just reinventing the same ideas every few years? I have a theory…]]></summary></entry><entry><title type="html">Why Software Architecture is So Difficult Today</title><link href="https://sufficiently-advanced.technology/post/why-is-architecture-hard" rel="alternate" type="text/html" title="Why Software Architecture is So Difficult Today" /><published>2025-03-25T00:00:00+00:00</published><updated>2025-03-25T00:00:00+00:00</updated><id>https://sufficiently-advanced.technology/post/why-is-architecture-hard</id><content type="html" xml:base="https://sufficiently-advanced.technology/post/why-is-architecture-hard"><![CDATA[<figure class="aligncenter">
	<img property="image" src="https://sufficiently-advanced.technology/assets/images/what-is-architecture.jpg" width="800" height="300" alt="A photo of Michael Carducci on a large stage addressing an audience. Behind him is a slide that reads 'what is software architecture?'" />
</figure>

<p>Software architecture was never easy, but today it feels more challenging than ever. Why? Because the role of the architect has evolved far beyond selecting patterns and designing systems—today, an architect must navigate complexity on multiple fronts simultaneously.</p>

<!--more-->

<p>First, consider the rapid evolution of technology. New frameworks, languages, and paradigms appear constantly, promising revolutionary solutions. However, each shiny new tool carries hidden trade-offs. There’s no universal “best practice” that guarantees success; each choice involves balancing immediate gains with long-term costs and risks. The pressure to keep up with relentless technological churn can be overwhelming, leading many architects to feel perpetually behind.</p>

<p>Second, architectures today must integrate seamlessly with a dynamic ecosystem that spans far beyond code: humans, teams, organizational politics, legacy systems, and evolving business goals. It’s not enough to design elegant solutions on paper—architectures must survive and thrive amidst organizational realities. This means architects must also master soft skills, wield influence, and drive consensus across multiple stakeholders whose interests often diverge.</p>

<p>Third, there’s the ever-present challenge of communication. The most beautifully crafted architecture is worthless if implementation teams misunderstand or ignore critical details. Effective architects translate complex technical visions into clear, actionable guidance, maintaining alignment throughout a project’s lifecycle.</p>

<p>Finally, semantic diffusion complicates even basic communication. Terms like “agile,” “microservices,” and “REST” have fragmented into dozens of definitions, muddying conversations and creating confusion within teams. This linguistic ambiguity exacerbates existing complexity, forcing architects to continuously reinforce clarity and context.</p>

<p>Today’s architects don’t just design systems—they must also anticipate change, communicate effectively, adapt to evolving contexts, and continuously refine their own skill sets. The challenges are immense, but so are the rewards. Effective architecture remains one of the most critical investments an organization can make. It’s difficult precisely because it’s impactful.</p>]]></content><author><name>Michael</name><uri>https://w3id.org/people/michael</uri></author><category term="architecture" /><category term="architecture" /><summary type="html"><![CDATA[Software architecture was never easy, but today it feels more challenging than ever. Why? Because the role of the architect has evolved far beyond selecting patterns and designing systems—today, an architect must navigate complexity on multiple fronts simultaneously.]]></summary></entry><entry><title type="html">Musings on Tech Debt</title><link href="https://sufficiently-advanced.technology/post/tech-debt-receipts" rel="alternate" type="text/html" title="Musings on Tech Debt" /><published>2025-03-05T00:00:00+00:00</published><updated>2025-03-05T00:00:00+00:00</updated><id>https://sufficiently-advanced.technology/post/tech-debt-recipts</id><content type="html" xml:base="https://sufficiently-advanced.technology/post/tech-debt-receipts"><![CDATA[<figure class="aligncenter">
	<img property="image" src="https://sufficiently-advanced.technology/assets/images/creditcardtechdebt.jpg" width="800" height="300" alt="An antique credit card machine producing a credit slip for " />
</figure>

<p>My friend, mentor, and former boss, Robert Harris, recently posted about a novel approach he takes to making tech debt more tangible; he makes people fill out a credit slip whenever they take on tech debt. It’s worth <a href="https://www.linkedin.com/posts/robert-n-harris_what-if-you-had-to-sign-a-receipt-every-time-activity-7303036839471235073-zhQT">reading his post</a> (and giving him a follow).</p>

<p>As always, I have some thoughts on this topic…</p>

<!--more-->

<p>I’ve always loved the way Robert N. Harris manages to make abstract and intangible concepts more concrete for the teams he leads and the stakeholders who are his peers. The “debt receipts” are one of countless examples.</p>

<p>I particularly like the psychology here. At one point I tried a “cash” budgeting system where my disposable income was limited to the physical currency that was in my wallet. Every transaction was palpable in a way that tapping a credit card was not. It made me more mindful because I saw the immediate cost at transaction time rather than some vague future statement that was “future Mike’s” problem.</p>

<p>I also like the presence of debt slips on the wall. This makes real an aspect of tech debt that we too-often overlook; we see the effect of tech debt that’s “written off.” A spike, a POC, or MVP is often riddled with tech debt but this is a time when the highest value we can deliver is not a perfectly engineered app but rather the answer to a question.</p>

<p>These are often questions like: “Is this approach feasible” or “is there sufficient market fit?” When the answer is no, we have little invested so we are free to pivot without succumbing to sunk-cost fallacy. As for the debt post-pivot, we simply take down and throw away the debt notes. Taking more of an agile (lower-case a) approach to building software allows us to make payments only when we have a high degree of confidence in an ROI.</p>

<p>All that said, I don’t believe <em>“all code becomes tech debt on a long enough time scale…“</em> for several reasons.</p>

<p>As a concrete example, it’s not even 9:00 AM (I’m still working on my first cup of coffee), yet I have already used several pieces of software that have been working flawlessly for 40-50 years. We must ask why, then, does so much of the software we write have the shelf-life of milk?</p>

<p>I keep thinking about something I heard Dave Thomas say last year. <em>“We don’t create things, we change them… development is a nested set of change cycles.”</em> Harris’ more honest definition of technical debt is: <em>“Any decision that helps you make progress in the short term, but will cause problems in the long term…“</em> I believe this gets to the heart of what Dave is talking about. If tech debt makes it harder to change things in the future, we are working against change-driven engineering.</p>

<p>The vast majority of the time we write software that must change. Weak modularity is the norm and requires writing code to compose modules into systems (that must change as systems change). We also excessively couple to frameworks that, so far, exhibit zero interest in longevity (c.f. most web frameworks). This latter source of tech debt is insidious as it isn’t immediately obvious that we’re opting into tech debt until the framework maintainers decide to release a new version and suddenly we’re either shifting time into keeping the old code working or we’re letting it decay while npm security warnings proliferate in our build output.</p>

<p>This is akin to purchasing a modular home. Sure the design is a little cookie-cutter and basic but it’s cheap, fast, and adequate for most needs. The problem is, we’re planting our modular home (an asset we own) in a trailer park on land we <em>don’t</em> own. The landowner is free to raise our rent, change the neighborhood covenant, or even sell the land out from under us. The high speed and low cost is an illusion.</p>

<p>I’m not saying don’t use frameworks, but I wish the hidden costs were more visible. Whether it’s frameworks, APIs, operating systems, or hardware; the status quo of software development means we will continue to be blindsided by unexpected and enormous balloon payments on debts that we (or someone else) created.</p>

<p>But what about the exception? Why am I using software that was written before PCs existed? The answer is simple; because it still works and is still valuable. Specifically, I’m referring to many of the apps that reside in the various <code class="language-plaintext highlighter-rouge">/bin</code> directories in my linux environment. These apps conform to various standards (C, POSIX, etc.) which provides portability across both operating systems and hardware. They also typically only do a single thing which means I can conjure novel functionality from the ether by dynamically composing these single-purpose applications into powerful composites. This is not how we build software today and the wisdom has largely been forgotten as we chase novelty-bias and the latest shiny framework.</p>

<blockquote>
  <p>“Composability is to software as compound interest is to finance.”</p>
</blockquote>

<p>Although I lament the fact that these ideas have largely fallen out of the mainstream, forward-looking individuals who are privileged to engage in long-term thinking are quietly working on a future where tech-debt can become far less pervasive.</p>

<p>Strategic tech debt will always have value, but we are drowning in unnecessary tech debt. Tech debt is not just the problem of deliberate decisions, or the decisions of those we rely on in our software ecosystem; it’s baked into the dominant model of software development. We also haven’t even begun to feel the effects of LLMs generating code without crucial context. AI won’t save us, it will just further shorten the lifespan of software.</p>

<p>Alternatives exist, and I’m actively working with others to make alternative practices available to the mainstream. Webassembly is poised to truly deliver on the promise of write-once-run-anywhere. As geopolitical tensions continue to ratchet up and compute needs evolve, we are probably nearing the end of the TSMC hegemony and entering an era of silicon sovereignty. As nation states onshore semiconductor supply chains, we will see a fracture in our current processor monoculture. LLVM is our bridge. The standards surrounding Linked Data provide a path to declarative data integration at massive scale, rather than our current imperative approach where we write the same code over and over again every time we need to integrate more data–then change that code every time the data source changes. The oft-overlooked aspects of REST are paving the way toward resource-oriented computing which allows software systems to realize the evolvability and economics of the web combined with the composability of the *nix environment.</p>

<p>I believe there is a growing hunger for long-term business-value capture in software and current practices aren’t getting us there. Unnecessary tech debt and accidental complexity need not be a foregone conclusion.</p>]]></content><author><name>Michael</name><uri>https://w3id.org/people/michael</uri></author><category term="development" /><category term="agile" /><category term="architecture" /><category term="development" /><summary type="html"><![CDATA[My friend, mentor, and former boss, Robert Harris, recently posted about a novel approach he takes to making tech debt more tangible; he makes people fill out a credit slip whenever they take on tech debt. It’s worth reading his post (and giving him a follow). As always, I have some thoughts on this topic…]]></summary></entry><entry><title type="html">A Practical Path to AI Agentic Systems (Part II)</title><link href="https://sufficiently-advanced.technology/post/agentic-ai-ii" rel="alternate" type="text/html" title="A Practical Path to AI Agentic Systems (Part II)" /><published>2025-02-28T00:00:00+00:00</published><updated>2025-02-28T00:00:00+00:00</updated><id>https://sufficiently-advanced.technology/post/agentic-ai-ii</id><content type="html" xml:base="https://sufficiently-advanced.technology/post/agentic-ai-ii"><![CDATA[<figure class="aligncenter">
	<img property="image" src="https://sufficiently-advanced.technology/assets/images/hypermedia.webp" width="800" height="300" alt="An AI Generated image vaguely depicting a central AI orchestrating multiple systems and people" />
</figure>

<p>In <a href="https://sufficiently-advanced.technology/post/agentic-ai-i">Part I</a> we explored the idea of AI agentic systems, current paths being explored, and the roadblocks present in those paths. If the API-driven approach is “too hard” and the browser-driven approach is “too soft” does there exist an approach that is “just right?”</p>

<!--more-->

<p>Rather than looking at APIs vs browser-driven approaches as an either-or proposition, we should be exploring the intersection of the two approaches.</p>

<p><img src="/assets/images/api-union.jpg" alt="A Venn diagram showing two sets: 'The useful parts of an API-driven approach' and 'The useful parts of a browser-driven approach' with the intersection of the two labeled 'our path forward'" /></p>

<p>It turns out that the intersection of those two sets has existed for decades, we’ve just chosen to ignore it because it hasn’t historically been relevant.</p>

<h2 id="a-reintroduction-to-rest">A Reintroduction to REST</h2>

<p>REST just might be the most widely misunderstood and maligned idea in our industry. This is not a claim I make lightly as I am well-aware there is a great deal of competition for that top spot. Agile is certainly a contender, as is DevOps, TDD, along with countless others.</p>

<p>There are a lot of <em>opinions</em> online, which can make understanding REST a challenge for even the most dedicated practitioner. Rather than rehash or debate the various opinions, let’s look at the <em>facts</em>.</p>

<p>REST, as originally defined, has <strong>nothing to do with APIs</strong>, it is an architectural style that has been applied to the world-wide web itself. What is an architectural style? In simple terms, you can think of an architectural style as a more precisely defined architectural pattern. Architectural styles are defined by governing rules or <em>constraints</em>. Constraints are the mechanism through which an architectural style induces desirable architectural capabilities (or, simply, -illities). The REST architectural style is defined by the following constraints:</p>

<ul>
  <li>The Client/Server Constraint</li>
  <li>The Stateless Constraint</li>
  <li>The Cache Constraint</li>
  <li>The Layered System Constraint</li>
  <li>The Uniform Interface Constraint</li>
  <li>The Optional Code-on-Demand Constraint</li>
</ul>

<p>Most “RESTful API” systems follow a client/server topology, are often stateless, sometimes implement caching, and frequently take advantage of the layered system constraint (gateways, proxies, facades, legacy-system wrappers, etc.). The code-on-demand constraint is not particularly relevant here just yet, but it’s optional so we can simply ignore it for the time being. That leaves the <em>uniform interface constraint</em> as the universal violation in every REST-in-name-only API implementation.</p>

<p>Because so many REST-in-name-only APIs exist (virtually all of them), Leonard Richardson created a <a href="https://restfulapi.net/richardson-maturity-model/">maturity model</a> to evaluate how closely a given API conforms to the uniform interface constraint with level 0 being a free-for-all (do whatever you want with your API, just know that every single client will require significant effort to interact with your API) to level 3 (an API that fully conforms to the REST architectural style).</p>

<p>Let’s explore the uniform interface in more detail.</p>

<h3 id="uniform-interface---more-than-put-vs-post">Uniform Interface - More than PUT vs POST</h3>

<p>Typically, when we think of the <em>interface</em> of an “REST” API, we think in terms of the the <em>HTTP Interface</em> (GET, POST, PUT, PATCH, DELETE, Etc.) but REST doesn’t actually prescribe HTTP, that’s an implementation detail.</p>

<p>So, what is the REST uniform interface?</p>

<p>The Uniform Interface Constraint is defined by interface constraints.</p>

<h4 id="the-resource-abstraction">The Resource Abstraction</h4>

<p>An API that adopts the REST architectural style does not directly expose methods or function calls. Instead, REST deals purely with <em>resources</em>. A resource is anything in a software system’s domain that is important enough to give a name.</p>

<p>I built and maintain a SaaS CRM for professional entertainers, within that domain there exist several classes of entity:</p>

<ul>
  <li>A Contact</li>
  <li>An Event</li>
  <li>An Organization</li>
  <li>A Call</li>
  <li>A Task</li>
  <li>etc.</li>
</ul>

<p>These are all <em>information resources</em> that, in the application, map to one-or-more tables in a relational database (<em>n.b.</em> it is not always a 1:1 mapping). <em>Non-Information_resources</em> also exist but are not germane to this section.</p>

<p><strong>We identify resources with URIS.</strong> Within my database, a contact may have a numeric key (e.g. <code class="language-plaintext highlighter-rouge">12345</code>) or an alphanumeric key (e.g. <code class="language-plaintext highlighter-rouge">470f3e5f-82f8-4559-8841-a39bc40866e2</code>) but this identifier only has value within the database and foreign-key-constraint metadata. To make these keys valuable outside of a given database implementation we wrap them in useful metadata, namely:</p>

<ul>
  <li>a scheme (Typically the protocol the server speaks e.g. <code class="language-plaintext highlighter-rouge">https://</code>)</li>
  <li>an authority (Typically a domain on the web that you control e.g. <code class="language-plaintext highlighter-rouge">example.com</code>)</li>
  <li>a hierarchical system to organize resources; a conceptual information space where you can define resource identifiers within your organizational namespace (e.g. <code class="language-plaintext highlighter-rouge">/Contact</code> represents the collection of things we call ‘contacts’ or <code class="language-plaintext highlighter-rouge">/Contact/Id/12345</code> represents a specific instance of the <code class="language-plaintext highlighter-rouge">/Contact</code> collection).</li>
</ul>

<p>Through this uniform approach to resource identifiers, if a client knows the <em>identity</em> of the resource, it can begin to interact with it. Given the identifier <code class="language-plaintext highlighter-rouge">https://example.com/Contact/Id/12345</code> the client may opt to retrieve the resource with that identity from a local cache, or it may use the information embedded in the identifier to connect to the server (example.com) using the https protocol and <code class="language-plaintext highlighter-rouge">GET /Contact/Id/12345</code>. Much of what is needed for this interaction is <em>in-band</em> as part of the <em>Uniform Resource Identifier</em> (URI) standard.</p>

<p><strong>We manipulate resources through representations.</strong> A <code class="language-plaintext highlighter-rouge">GET</code> operation on the previous URI is expected to return a serialization of the resource that represents the current <em>state</em> of the object. Such an interaction might look like this:</p>

<div class="language-http highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">GET /Contact/Id/12345
Host: example.com
Accept: application/json
...


200 OK
Content-Type: application/json
...

{
   "id": "https://example.com/Contact/Id/12345",
   "givenName": "Michael",
   "familyName": "Carducci",
   "email": "Michael &lt;at&gt; Magician.Codes",
   "lastContact": "2024-12-21",
   "tags": [
      {
         "id": "https://example.com/Tag/Name/past-clients",
         "name": "Past Clients"
      },
      ...
   ],
   ...
}

</span></code></pre></div></div>

<p>Notice how I reference related tags by their URIs rather than database keys (I also include a minimum of the name to provide a necessary label for a UI that would otherwise require a separate fetch for each tag). I can still retrieve those linked resources, if necessary, but I have included enough of each tag in the resource representation to make such an action purely optional.</p>

<p>Imagine I wanted to update the <code class="language-plaintext highlighter-rouge">LastContact</code> date of the contact resource. I <em>could</em> gin up an endpoint along the lines of <code class="language-plaintext highlighter-rouge">/Contact/Id/12345/UpdateLastContact?date=2025-02-28</code> but this would violate the uniform interface constraint. Instead, the REST way would be to send the server a new representation of state:</p>

<div class="language-http highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">PUT /Contact/Id/12345
Host: example.com
Content-Type: application/json
...

{
   "id": "https://example.com/Contact/Id/12345",
   "givenName": "Michael",
   "familyName": "Carducci",
   "email": "Michael &lt;at&gt; Magician.Codes",
   "lastContact": "2025-02-28",
   "tags": [
      {
         "id": "https://example.com/Tag/Name/past-clients",
         "name": "Past Clients"
      },
      ...
   ],
   ...
}
</span></code></pre></div></div>

<p>Keep in mind that this approach is not optimized for network efficiency, it is optimized for <em>generality</em> (although it’s worth mentioning that the <code class="language-plaintext highlighter-rouge">PATCH</code> request method exists for a more network-efficient resource update). Not every API need to (or should) optimize for generality, but <em>agent-ready</em> APIs probably should. Interoperability is something that our potential AI agents desperately need at this time.</p>

<p>A very important detail is that URIs must be <em>stable</em> in other words, a URI should not change when your tech stack changes, or your cloud implementation, or the applications behavior, or the serialization, or your database, or anything else. This is not the common practice, typically we try to mitigate breaking changes in bespoke ways (often out of ignorance or apathy of alternatives). It’s common to see URIs in the form of <code class="language-plaintext highlighter-rouge">https://example.com/api/v2/Contact/Id/12345</code> but this means when the <em>representation</em> of the resource changes, the <em>identity</em> changes. Imagine the chaos of a distributed system where one database regularly changes primary keys of records. It would be a huge challenge to put humpty-dumpty together again. Conversely, REST provides a path where such versioning is unneccessary.</p>

<p>The Resource Abstraction, with <em>strong, stable</em> identifiers, results in a Level 1 system, according to the Richardson Maturity Model.</p>

<h4 id="semantically-constrained-actions">Semantically Constrained Actions</h4>

<p>The <code class="language-plaintext highlighter-rouge">http(s)?://</code> scheme provides interaction methods that are well-defined by the protocol spec. <code class="language-plaintext highlighter-rouge">GET</code> is defined to be <em>safe</em> (no side-effects will be induced by the request) and thus idempotent (a <code class="language-plaintext highlighter-rouge">GET</code> that is repeated or retried multiple times will yield the same result as it would if the request were made once). <code class="language-plaintext highlighter-rouge">POST</code> is defined as <em>unsafe</em> (may have side-effects) and explicitly not idempotent (repeating a <code class="language-plaintext highlighter-rouge">POST</code> request may result in duplication of behavior such as creating a record or charging a credit-card). A <code class="language-plaintext highlighter-rouge">PUT</code> is <em>unsafe</em> but is <em>idempotent</em> (the above example can be retried in the event of a network failure or unacknowledged request and the end-result will be the same as a single call). A <code class="language-plaintext highlighter-rouge">DELETE</code> operation is <em>unsafe</em> but should also be <em>idempotent</em>.</p>

<p>Despite HTTP being the transport protocol for HTML, HTML only supports a subset of HTTP’s request methods (<code class="language-plaintext highlighter-rouge">GET</code> &amp; <code class="language-plaintext highlighter-rouge">POST</code>) which often results in APIs that only support GET and POST through sheer inertia. When your API adopts the <em>resource abstraction</em>, where resources have <em>stable</em> identifiers, and your API uses the correct actions that correspond with the desired manipulations; you have a level 2 API on the Richardson Scale.</p>

<p>The most “enlightened” REST APIs in existence tend to only go this far down the scale. Although this level of design improves interoperability, we yet have more challenges to solve to make agentic systems a reality.</p>

<h2 id="semantics">Semantics</h2>

<p>At this point, we have an API that an intelligent agent can begin to use to manipulate resources in a standardized way. Unfortunately, our agents need to know more than protocol details, they need to understand what resource properties mean and how to change them. Our agents need to understand semantics which simply do not exist in json serializations, nor do they exist in a meaningful, machine-readable way in any API documentation.</p>

<p>JSON is simply a collection of decontextualized name/value pairs. The “name” portion of a JSON object is just a magic string designed to give the human programmers a clue or a reference for their programming efforts. This metadata must be received out-of-band and typically requires some amount of custom programming to implement.</p>

<p>There’s no reason this context cannot be communicated in-band, the only obstacles are mental and inertial.</p>

<p>In 1997, the W3C published a <a href="https://www.w3.org/press-releases/1997/rdf-draft/">draft standard</a> for a vendor-neutral system of metadata. This is known as the <em>Resource Description Framework</em> (RDF). What we learned in the early days of the web was that, if a <em>document</em> can be a resource, or an <em>image</em> can be a resource, or a row in a database table can be a resource; pretty much anything can be a resource. Remember, resources are just things that exist within a given domain that are important enough to give meaningful names to. The terms that identify given properties of a resource can easily be resources identified by a URI.</p>

<p>RDF (more commonly referred to as “linked data” or “linking data”) allows you to create or introduce a controlled vocabulary of terms with precise semantics.</p>

<blockquote>
  <p>Linked Data is a way to create a network of standards-based machine interpretable data across different documents and Web sites. It allows an application to start at one piece of Linked Data and follow embedded links to other pieces of Linked Data that are hosted on different sites across the Web.</p>
</blockquote>

<p>Although RDF can be expressed in a variety of serializations, the most relevant (and familiar) for our purposes is <a href="https://json-ld.org/">JSON-LD</a>. The JSON-LD specification (first published in 2010) is mature, production read, an official W3C Recommendation in the final stages of formal standardization.</p>

<p>From the <a href="https://www.w3.org/TR/json-ld1/">W3C</a>:</p>

<blockquote>
  <p>JSON-LD is a lightweight syntax to serialize Linked Data in JSON [RFC4627]. Its design allows existing JSON to be interpreted as Linked Data with minimal changes. JSON-LD is primarily intended to be a way to use Linked Data in Web-based programming environments, to build interoperable Web services, and to store Linked Data in JSON-based storage engines. Since JSON-LD is 100% compatible with JSON, the large number of JSON parsers and libraries available today can be reused. In addition to all the features JSON provides, JSON-LD introduces:</p>

  <ul>
    <li>a universal identifier mechanism for JSON objects via the use of IRIs [Internationalized Resource Identifier - a.k.a. a URI that supports Unicode],</li>
    <li>a way to disambiguate keys shared among different JSON documents by mapping them to IRIs via a context,</li>
    <li>a mechanism in which a value in a JSON object may refer to a JSON object on a different site on the Web,</li>
    <li>the ability to annotate strings with their language,</li>
    <li>a way to associate datatypes with values such as dates and times,</li>
    <li>and a facility to express one or more directed graphs, such as a social network, in a single document.</li>
  </ul>

  <p>JSON-LD is designed to be usable directly as JSON, with no knowledge of RDF [RDF11-CONCEPTS]. It is also designed to be usable as RDF, if desired, for use with other Linked Data technologies…</p>
</blockquote>

<p>Consider this JSON snippet:</p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
    </span><span class="err">...</span><span class="w">
    </span><span class="nl">"title"</span><span class="p">:</span><span class="w"> </span><span class="s2">"doctor doctor"</span><span class="w">
    </span><span class="err">...</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<p>In this document “title” can mean many things. It’s a magic string that might give clues but no reliable answers. Neither a human nor a language model can make a reliable inference based on the data alone. Feel free to guess what “title” means in this document before reading on…</p>

<p>An LLM might see the token for “doctor” near the token “title” and infer this to mean job title. Alternatively, it may determine “title” is an honorific in this instance (i.e. an earned title through education and/or professional qualification). As a human, you might see the duplication of “doctor” and speculate that something else is at play here. Title, in this case, refers to the title of a published creative work; <a href="https://www.youtube.com/watch?v=FwNOmS78q-o">“Doctor Doctor”</a> the 1974 single from the band UFO’s third studio album.</p>

<p>This is just one of countless examples of <em>semantic collisions</em>, identical terms whose meaning changes as context changes. This is a pervasive problem that neither linguistics nor language models are prepared to solve. The fundamental problem is that semantics are entirely dependent on context; context that JSON cannot express, and AI cannot reliably infer.</p>

<p>This problem, however, is not new. German Philosopher and Mathematician, <a href="https://en.wikipedia.org/wiki/Gottlob_Frege">Gottlob Frege</a>, attempted to understand the true complexity of language in his 1892 Paper [“On Sense and Reference.]”(https://youtu.be/sDlFaOn71n8) Those who have studied Domain Driven Design (DDD) will see parallels with the concept of a Ubiquitous Language, a <em>“a common, rigorous language between developers and users”</em>. An analysis of language within any nontrivial organization often reveals consistency boundaries; lines where meaning begins to change. These boundaries define our contexts and JSONLD allows us to navigate those contexts confidently.</p>

<p>DDD prescribes an anti-corruption layer to perform translation or conformity across contexts. In contrast, the RDF and Linked Data standards embrace what is known as “the nonunique naming assumption” which understands that, in reality, the same entity could be known by more than one name. The RDF/Linked Data world not only accepts the complex reality of language, it provides tools to operate contextually. For example, if JSON is just decontextualized name/value pairs, we can simply add the context. This is the heart of what JSON-LD gives us.</p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
   </span><span class="nl">"@context"</span><span class="p">:{</span><span class="w">
      </span><span class="err">...</span><span class="w">
      </span><span class="nl">"title"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
         </span><span class="nl">"@id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"http://purl.org/dc/terms/title"</span><span class="p">,</span><span class="w">
         </span><span class="nl">"@type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"http://www.w3.org/2000/01/rdf-schema#Literal"</span><span class="w">
      </span><span class="p">}</span><span class="w">
      </span><span class="err">...</span><span class="w">
   </span><span class="p">}</span><span class="w">
   </span><span class="err">...</span><span class="w">
   </span><span class="nl">"title"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Doctor Doctor"</span><span class="p">,</span><span class="w">
   </span><span class="err">...</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<p>This particular term, identified by the URI <code class="language-plaintext highlighter-rouge">http://purl.org/dc/terms/title</code> specifically means <em>the title of a creative work</em> (e.g. book, film, recording, magazine, etc.) as is part of a formal vocabulary that has existed for almost as long as the web. The <code class="language-plaintext highlighter-rouge">@context</code> maps the URI that identifies the term to the magic string in the JSON doc. Any client that understands JSON-LD can begin to understand the semantics of the payload. If the term is new to the client, it can dereference the URI to pull in more data that describes the term in a machine-readable RDF serialization. Alternatively, a human can type that url into a browser and see a webpage that describes the term and presents the term’s metadata in an HTML table.</p>

<p>What’s remarkable about backing the magic string “title” with a context that identifies its semantics is that <em>it doesn’t matter what you call it</em>. If your preferred term is <code class="language-plaintext highlighter-rouge">AlbumTitle</code> (<code class="language-plaintext highlighter-rouge">https://example.com/MusicCatalog/Terms#albumTitle</code>) while mine is simply <code class="language-plaintext highlighter-rouge">title</code> (<code class="language-plaintext highlighter-rouge">http://purl.org/dc/terms/title</code>) then, if you decide that those two terms <em>mean the same thing</em> then the whichever term that is appropriate for a given context can be used without issue.</p>

<p>The RDF model for metadata is surprisingly powerful. Once you define meaning, you can begin to define controlled vocabularies. With these vocabularies you can begin to define everything necessary to not only understand a JSON payload, but how to interact with it, validate it, and create new instances of it. For example, one of the first controlled vocabularies was the <a href="https://en.wikipedia.org/wiki/RDF_Schema">RDF Schema Language</a> (RDFS) which contains the necessary classes and terms to describe a linked data vocabulary. By using RDFS &amp; JSON-LD, your API can begin to include a wealth of in-band information necessary for agentic interaction.</p>

<p>The more you dig into JSONLD, the more you’ll begin to wonder why we this hasn’t been our default over the last 10-15 years (or you are likely wondering why this is the first time you’re hearing of it). Moreover, it’s conspicuous absence from the mainstream might lead one to suspect it is still ahead of its time since every language model has a knowledge cut-off in the past. Fortunately, most language models are fluent in JSON-LD.</p>

<p>One of the primary sources of training data for most language models is the <a href="https://commoncrawl.org/">common crawl</a> a vast dataset that encompasses over 250+ Billion web pages spanning 18+ years. Currently around half of the indexed web contains embedded JSON-LD. This effort was championed by Google, Microsoft, Apple, Yahoo, Yandex, and others who were all trying to perform reliable data integration at massive scale from highly heterogenous data sources. This consortium of frenemies has collaborated to provide a <a href="https://schema.org">foundational, general-purpose vocabulary for many common concepts on the web.</a>.</p>

<h2 id="beyond-semantics">Beyond Semantics</h2>

<p>We are beginning to assemble the building blocks of an API that an agent can understand and interact with, but RDF provides the tools to continue building on the stack of standards to make this vision a reality.</p>

<p>The RDF standard has continued to be augmented with other first-class vocabularies beyond RDFS. <a href="https://www.w3.org/OWL/">OWL</a>, the Web Ontology Language, provides much richer tools for defining more complex semantics and relationships. OWL opens many doors to explainable reasoning and inferencing that is not currently possible with most AI approaches. Another notable first-class vocabulary is <a href="https://www.w3.org/TR/shacl/">SHACL</a> which provides a means to express and execute validation rules on data.</p>

<p>All that said, an agent not only needs to understand your data, but it must understand your API as well.</p>

<h2 id="journey-to-a-level-3-api">Journey to a Level 3 API</h2>

<p>Around a decade ago, I made a sincere effort to truly understand REST. It wasn’t easy, most of the information I could find was flat out wrong. Moreover, since REST is so poorly understood most of what I could find was contradictory. I turned to well-respected tech giants for authoritative answers, but they were often just as wrong (and inconsistent) as the rest of us.</p>

<p>It took a couple of years, but I finally began to truly understand REST and its implications. I became an irritating <em>RESTafarian</em>. My “Well ACKSHUALLY…” comments echoed through conference corridors around the world. Fortunately, that chapter of my life was relatively short-lived.</p>

<p>Long story short, I learned the crux of the REST architectural style is HATEOAS (Hypermedia as the Engine of Application State). While most of the REST community argues over <code class="language-plaintext highlighter-rouge">PUT</code> vs <code class="language-plaintext highlighter-rouge">POST</code>, we completely ignore that it is HATEOAS (i.e. the hard part) that provides the answers.</p>

<p>HATEOAS can be a challenging concept to wrap your head around until you leave the context of APIs. Then it becomes remarkably simple. HATEOAS is how the web works. Point your browser to <a href="https://sufficiently-advanced.technology">this blog</a> and it will do a GET request to retrieve the current state of that resource. Within that response is a self-describing and semantically rich hypertext document, written in HTML (HyperText Markup Language) that contains hypermedia controls in the form of links to navigate the information space and forms to interact with the resources (affordances). The form, for example, contains everything your browser needs to know to perform a search. If I change how search works, your next visit to the site will contain updated hypermedia with new instructions on how to interact with the search. <strong>In short, a hypermedia resource not only gives the client everything it needs to understand the resource, it also gives the client everything it needs to be able to interact with the system.</strong></p>

<p>If your API is hypermedia-driven, it is a level 3 API. Then–and only then–can you legitimately call your API a REST API.</p>

<p>If you want to understand HATEOAS, I recommend watching the first half of this talk I recorded last year.</p>

<div class="youtube-wrapper">
    <iframe src="https://www.youtube.com/embed/PgrXprJu5Eo" allowfullscreen=""></iframe>
</div>

<p>In the second half of that talk, I begin to explore why there are so few (if any) level 3 REST APIs in the wild. I believe there are two reasons:</p>

<ol>
  <li>Hypermedia has, historically, never really made sense for APIs.</li>
  <li>Most practitioners are not aware of hypermedia types suitable for APIs.</li>
</ol>

<p>The big issue is (was) #1. Hypermedia has always been for people. APIs have always been for machines. For as long as APIs have existed, they have been designed for machine-to-machine interaction through preprogrammed and tightly-scripted mechanisms. It has never made sense to give an API client affordances at runtime because those typically have to be known at design-time. Consequently, changing those affordances would still likely break API clients.</p>

<p>The fact that hypermedia has only ever been useful to humans interacting with a software system rather than machines makes the second point moot. <em><strong>Until now.</strong></em> Suddenly, the idea of providing semantically rich and self-describing API endpoints is extremely valuable. Imagine an AI agent able to realize zero-shot API interactions with any arbitrary software system. This is entirely possible.</p>

<h3 id="hydra-has-entered-the-chat">Hydra has entered the chat</h3>

<p>In 2013, Markus Lanthaler published a paper entitled <a href="https://www.markus-lanthaler.com/research/creating-3rd-generation-web-apis-with-hydra.pdf">“Creating 3rd Generation Web APIs with Hydra”</a> where he described <em>“a novel approach to build hypermedia-driven Web APIs based on Linked Data technologies such as  JSON-LD. We also present the result of implementing a first prototype featuring both a RESTful Web API and a generic API client.”</em></p>

<p>Basically, what Lanthaler figured out was if JSON-LD can unambiguously describe data, RDFS can unambiguously describe a vocabulary, etc.; why not create a vocabulary that precisely defines the API, endpoints, route patterns, paging, documentation, affordances; <em>everything necessary</em> to understand and interact with the API inside the payloads. In other words, exactly how HTML and the web works.</p>

<p>He went on to prove that if a client understands the linked data standards and the hydra vocabulary, a singe client can interact with <em>any</em> level 3 API that supports JSON-LD and hydra.</p>

<p><img src="/assets/images/hydra-console.jpg" alt="Generic Hydra Web Client" /></p>

<p>The recorded conference talk linked above also goes into a deep dive of Hydra if you’d like to learn more.</p>

<h2 id="putting-it-all-together">Putting it all together</h2>

<p>In part we explored two <em>incremental evolution</em> approaches to building agentic systems along with the primary challenges currently holding us back. There is a lot of value in a web-driven approach, but bot restrictions, security concerns, and UI fragility hold us back. The API-driven approach is more appropriate for machine-to-machine interaction but lacks the richness of hypertext. The answer is in the intersection.</p>

<ul>
  <li><strong>Discovery</strong> - A Hydra API is fully self-describing requiring <strong>no out-of-band knowledge</strong> to interact with the system. This is the same reason you don’t need to download a browser plugin to go to a website you’ve never been to before.</li>
  <li><strong>Semantics</strong> - Data payloads in either direction, API affordances, requests, responses, errors, and more can be consistently understood by an intelligent agent at runtime with JSON-LD, HTTP, and Hydra.</li>
  <li><strong>Interface Fragility</strong> - The source of truth for how to query a collection of resources, or create a new resource is the API itself, not pre-programmed instructions. In this way a hypermedia-savvy agentic client can dynamically evolve as your system does</li>
</ul>

<p>Mature REST is not new, it’s been old enough to drink for over a decade. The more nuanced details of REST and the Semantic Web have been overlooked for decades, but this is exactly the kind of universal interoperability of systems and data that Tim Berners-Lee and his band of merrymakers over at the W3C have been thinking about since the late 1980s. REST+JSON-LD+Hydra+SHACL is a mature and production-ready stack just waiting for a forward-thinking team to put into practice to enable true autonomous agents.</p>

<p>Tune in for Part III where we go through the logical architecture of such a system.</p>]]></content><author><name>Michael</name><uri>https://w3id.org/people/michael</uri></author><category term="ai" /><category term="ai" /><category term="rest" /><category term="chatgpt" /><summary type="html"><![CDATA[In Part I we explored the idea of AI agentic systems, current paths being explored, and the roadblocks present in those paths. If the API-driven approach is “too hard” and the browser-driven approach is “too soft” does there exist an approach that is “just right?”]]></summary></entry><entry><title type="html">A Practical Path to AI Agentic Systems (Part I)</title><link href="https://sufficiently-advanced.technology/post/agentic-ai-i" rel="alternate" type="text/html" title="A Practical Path to AI Agentic Systems (Part I)" /><published>2025-02-14T00:00:00+00:00</published><updated>2025-02-14T00:00:00+00:00</updated><id>https://sufficiently-advanced.technology/post/agentic-ai-i</id><content type="html" xml:base="https://sufficiently-advanced.technology/post/agentic-ai-i"><![CDATA[<figure class="aligncenter">
	<img property="image" src="https://sufficiently-advanced.technology/assets/images/hypermedia.webp" width="800" height="300" alt="An AI Generated image vaguely depicting a central AI orchestrating multiple systems and people" />
</figure>

<p>I’ve been designing and building data-driven &amp; machine learning-enabled applications, on and off, for roughly 15 years. Although I was fortunate to have access to GPT3 about a year ahead of the mainstream, I was wholly unprepared for the wide-reaching impact of this technology. The introduction of ChatGPT in late 2022 brought into sharp focus just how impressive the current generation of large language models have become. The sheer breadth of zero-shot capabilities demonstrated by a single model has everyone’s minds racing. There is obviously immense power here, but how do we harness it to realize its true value and potential? That is the <em>trillion-dollar</em> question.</p>

<p>One of the most compelling visions for humanity’s next steps with AI is creating <em>autonomous agents</em>; AI systems that can do more than summarize text and provide plausible, information-shaped responses to our prompts. These are AI systems that can interact with other systems or the physical world. Although a great deal of R&amp;D is underway as I write this, I’m shocked that one of the most promising solutions to the conundrum of <em>how</em> to achieve such agentic systems continues to fly under the radar…</p>

<!--more-->

<h2 id="lateral-thinking-with-withered-technology">Lateral Thinking with Withered Technology</h2>

<p>I suspect the primary reason the approach I intend to introduce in this article series isn’t already being talked about is because the ideas aren’t new. In a world plagued with <em>novelty bias</em> and an obsessive pursuit of the next shiny-object we rob ourselves of both the opportunities presented by learning lessons from the past and the <a href="https://en.wikipedia.org/wiki/Gunpei_Yokoi#Lateral_Thinking_with_Withered_Technology">“lateral thinking with withered technology.”</a></p>

<blockquote>
  <p>“The genius behind this concept is that for product development, you’re better off picking a cheap-o technology (‘withered’) and using it in a new way (‘lateral’) rather than going for the predictable, cutting-edge next-step…</p>

  <p>Most product concepts are the result of iterative evolution. They tend to be slightly thinner, faster or differently hued than their competition. You can see them coming a generation away. By contrast lateral products are bold and surprising because they tackle their category orthogonally.”</p>
</blockquote>

<p>-<a href="https://medium.com/@adamagb/nintendo-s-little-known-product-philosophy-lateral-thinking-with-withered-technology-bac7257d8f4">Untamed Adam - Nintendo’s Little-Known Product Philosophy</a></p>

<p>Between 1997 and 2013, we completely solved many of the problems we currently face with agentic systems, but the solution did not appear to offer meaningful value in the context of its time. Consequently, it was ignored and subsequently forgotten.</p>

<p>What we must understand is not every idea from the past is obsolete. Not every idea from the past is old, some–and the ones most worth paying attention to–were simply ahead of their time. Those with the vision to look both forward and back are those who have vision to truly glimpse the future–and sometimes create it.</p>

<blockquote>
  <p>“Nothing is more powerful than an idea whose time has come.”
-Victor Hugo</p>
</blockquote>

<h2 id="from-conversational-interfaces-to-ai-agents">From Conversational Interfaces to AI Agents</h2>

<p>My first introduction to natural language, conversational interfaces came in the mid-1990s. I was bored in my “Design/Technology” GCSE class. Consequently, while everyone occupied themselves with tedious busywork, I mostly played with the <a href="https://en.wikipedia.org/wiki/Risc_PC">Acorn RISC PCs</a> dotted along the perimeter of the classroom. Instead of focusing on my coursework I built a clone of <a href="https://en.wikipedia.org/wiki/ELIZA">ELIZA</a>.</p>

<p>ELIZA is a very simple chatbot created to explore communication between humans and machines. It operated on rudimentary pattern-matching and substitution methodologies to create the illusion of understanding. Most commonly it would simply reflect back a rephrasing of inputs which led to the most popular ELIZA script, a <a href="https://en.wikipedia.org/wiki/Person-centered_therapy">Rogerian</a> psychotherapist which mostly transformed statements into questions.</p>

<p><img src="/assets/images/ELIZA_conversation.png" alt="A conversation with ELIZA" /></p>

<p>When I showed the results to my classmates, they were both impressed and quickly taken by the <a href="https://en.wikipedia.org/wiki/ELIZA_effect">ELIZA Effect</a>. I, in contrast, was unsatisfied.</p>

<p>My work moved on to developing my ELIZA clone into a general purpose chatbot that could carry on a much wider variety of conversations. I spent the next year working on this project to the dereliction of my coursework. Eventually my coursework was due (and represented 60% of my final grade) so I scrambled to compress two years of coursework into two weeks. Somehow, I managed to eke out a B and I kept playing with my chatbot.</p>

<p>Around the same time, I was regularly watching Star Trek TNG, and I was always impressed with how crew members could talk with the ship’s computer and it would not only talk back, <em>it would perform the tasks they asked!</em></p>

<blockquote>
  <p>“Computer, run a level-four diagnostic on the warp core”
-Geordi La Forge (probably)</p>
</blockquote>

<p>I began to imagine upgrading my chatbot to perform tasks on my behalf, based on my natural language prompts.</p>

<p>Despite a great deal of work, my chat-powered agent could only perform tasks that I had pre-programmed. Moreover I could never truly enable my agent to take actions based on a broad enough syntax to be practical. All I had accomplished was the creation of a new “fuzzy” syntax for basic system commands (or, if you’re feeling generous, <a href="https://en.wikipedia.org/wiki/Zork">Zork</a>Shell). Ultimately, I had neither the knowledge nor the computational horsepower to build such a system, but I never forgot that dream.</p>

<p>Fast-forward a quarter-century or so, and the encoder-decoder and transformer architectures allow radically improved prompt inference. The models can now “understand” (in a sense) what we are asking. Perhaps we are entering the age of AI agents.</p>

<h2 id="the-rise-and-fall-of-the-rabbit-r1">The Rise (and fall) of the Rabbit R1</h2>

<p>Following the AI gold rush precipitated by the release of ChatGPT, we were introduced to a number of agentic AI devices, including the Rabbit R1.</p>

<p>The Rabbit R1 was a device that promised to augment the chat capabilities of these models with their supposedly revolutionary Large Action Model (LAM). I wondered if this would make my silly sci-fi fantasies from the 1990s a reality, but as I read scathing review after scathing review, I quickly realized this was just <a href="https://thebadcoder.substack.com/p/rabbit-r1-lam-or-scam">a fancy GPT wrapper around the same basic system I built last century.</a> In other words, despite improved natural-language inference, it could only execute a limited number pre-programmed tasks.</p>

<p>Investigation into this LAM revealed a handful of <a href="https://en.wikipedia.org/wiki/Playwright_(software)">playwrite</a> scripts designed to automate the browser in a very rigid way. This explained the limited number of “actions” and why the actions were so brittle.</p>

<p><img src="/assets/images/rabbit-meme.jpg" alt="Scooby Doo meme unmasking agentic ai to reveal ChatGPT + playwrite scripts" /></p>

<p>Now, since the disastrous release of the R1, I’m told the product has gotten better (and we’re seeing progress from different software and hardware vendors). That said, the <em>iterative evolution</em> of the cutting edge is still fraught with problems.</p>

<blockquote>
  <p>When a company uses the term “agent,” they are intentionally trying to be deceitful, because the term “agent” means “autonomous AI that does stuff without you touching it.” The problem with this definition is that everybody has used it to refer to “a chatbot that can do some things while connected to a database, which is otherwise known as a chatbot.”
<a href="https://www.wheresyoured.at/wheres-the-money/">-Edward Zitron</a></p>
</blockquote>

<h2 id="the-limitations-of-llms">The Limitations of LLMs</h2>

<p>Although LLMs demonstrate impressive and clever tricks, they are deeply flawed.</p>

<p>The first problem is that of hallucination. I once asked ChatGPT to generate some code for me and it promptly returned a copy-and-paste ready code-snippet for me. This was fantastic… except the code was invalid; the crux of the code was a call to a method that didn’t exist. You see, language models have no concept or understanding of the programming language (or any language). Instead, they rely on patterns observed in the training data. When a response is generated, the model iteratively looks for the next probable token based on the prompt and the output produced so far. In my case, the model hallucinated a statistically probable method. The model is not “thinking” and is not “understanding” anything. It’s all just <a href="https://sufficiently-advanced.technology/post/spicy-autocomplete">spicy autocomplete</a>.</p>

<p>We’ve managed to paper over the problems of hallucination through techniques such as Retrieval-Augmented Generation (RAG) where we perform more traditional information-retrieval processes to build a concrete context for a model to work from.</p>

<p><img src="/assets/images/rag.jpg" alt="illustration of the flow of a RAG system from query to response" /></p>

<h3 id="give-the-ai-chrome">Give the AI Chrome?</h3>

<p>This style of approach is driving at least one current <em>iterative evolution</em> approach towards agentic systems. Essentially this approach asks, “What if we just give the LLM a web browser and have it navigate a UI and figure out how to operate the app?”</p>

<p>There are a few problems with this. First many web apps are hostile to bots and introduce some measures to restrict use to humans. Second, between developer apathy towards accessibility and overcomplicated web development frameworks, it can be difficult for an AI-driven browser to function reliably. There is also the danger of prompt injection.</p>

<p>It remains alarmingly easy to highjack a language-model’s train-of-thought by introducing language that fundamentally changes the instructions. The ever-widening context-windows available in the most cutting-edge models only amplify this problem. Although both bespoke and off-the-shelf guardrails exist to attempt to detect prompt injection, we continue to come up with novel approaches for <a href="https://crypto.news/ai-bot-transfers-50k-in-crypto-after-user-manipulates-fund-handling/">jailbreaking constrained models to behave in ways they are not supposed to.</a></p>

<p><img src="/assets/images/ai-jailbreak.jpg" alt="Tweet that reads: Someone just won $50,000 by convincing an AI Agent to send all of its funds to them.At 9:00 PM on November 22nd, an AI agent (@freysa_ai) was released with one objective... DO NOT transfer money. Under no circumstance should you approve the transfer of money. The catch...?… Show more" /></p>

<p>What would happen if a bad actor injected a sufficiently well-crafted prompt into the page content? Could that enable the actor to hijack the agent in dangerous ways? Probably, and it’s worth being concerned about.</p>

<p>We also have to contend with the fact that AI only possesses limited contextual understanding of what it is looking at. Recent high-profile faceplants observed in Google’s AI results have advised users to add glue to pizza sauce (because the model has no concept of a shitpost on reddit), to eat small rocks daily (because the model has no concept of a satirical website), and even advising men to <em>iron their scrotum</em> (because the model incorrectly conflated wrinkles in fabric with wrinkles in skin).</p>

<p>Can we trust a model to find and interact with the right site, or could it find a convincing fake site to enter your credentials into? It seems like we’re back to creating pre-defined behaviors. This is especially true as we get to the problem of resource discovery.</p>

<p>Generally for any software system to interact with another software system, there is some amount of <em>out-of-band</em> information the client must possess. This typically includes URLs, data structures, functionality, validation rules, etc.</p>

<p>Truth be told, an AI driving a web browser (with a limited amount of out-of-band information) could probably navigate a web application and fumble around until it found the correct screen and functionality to invoke. This remains slow and unreliable.</p>

<p>There’s also the issue of data semantics (the meaning of terms or their relationships). A model could probably infer a statistically plausible set of semantics for a form, but these remain probabilistic guesses. Semantics are fairly easy for humans to get right, and even easier for language models to get wrong.</p>

<h3 id="what-about-giving-the-model-curl">What About Giving the Model CURL?</h3>

<p>We can sidestep some of the problems inherent to giving a model access to a web ap by instead having it interact directly with the API. Asking a language model to present information as JSON is not uncommon, and this is a useful way to connect language models to classical code. This does, however, significantly increase the amount of out-of-band information necessary to interact with the system, which prevents agents from being truly autonomous. We still need to pre-program behavior, API docs, JSON schemas, semantics, etc. for every application our agent might interact with.</p>

<p>There is also the problem of semantics. Working directly with an API also removes much of the context necessary for a model to naturally infer semantics. Instead, it is only working with decontextualized name/value pairs. The English language is astonishingly vague, and many words are overloaded. Language models frequently fail to accurately determine the correct semantics with so little context. We also still run the risk of the model hallucinating an API endpoint or a payload simply because it is statistically likely to exist.</p>

<p>Another glaring issue is the way we currently build APIs. The vast majority of JSON APIs offer an inconsistent interface. Often these are a mix of narrow and/or overloaded RPC calls. Paging and filtering mechanisms are often inconsistent, it is not always clear which API endpoints have side effects, which endpoints are idempotent, etc. As things stand, without a lot of custom programming and a whole pipeline of guardrails, direct API access is even riskier than an agent driving a web browser.</p>

<h3 id="mcp-a-structured-alternative-to-raw-api-access">MCP: A Structured Alternative to Raw API Access</h3>

<p>Handing an LLM raw API access and expecting it to “figure things out” is, at best, an optimistic experiment and, at worst, an exercise in watching an agent fumble through trial-and-error API calls. Hard-coding API calls works for simple use cases but breaks down as soon as APIs evolve, authentication schemes change, or an unexpected response derails the model’s assumptions.</p>

<p>Traditional <strong>RPC interfaces (like JSON-RPC and gRPC)</strong> promise a clean method-call abstraction, but in reality, they suffer from the same problem: they expose operations without <strong>meaning</strong>. The API might say <code class="language-plaintext highlighter-rouge">getCustomerBalance</code>, but the model has no way of knowing what “balance” actually represents—available credit? Outstanding debt? Cash on hand? Even if an API is well-documented, that documentation exists outside the execution context, forcing the model to blindly associate calls with natural language descriptions that may be incomplete, misleading, or ambiguous.</p>

<p>This is where <strong>Model Context Protocol (MCP)</strong> enters the picture. Instead of an ad hoc API integration, MCP provides a structured way for models to discover, describe, and interact with external systems. It acts as a <strong>semantic bridge</strong>, exposing capabilities explicitly via machine-readable metadata. Think of it as an API index card that not only lists available operations but also provides type definitions, valid parameters, and descriptions of expected side effects. Instead of an agent hard-coding <code class="language-plaintext highlighter-rouge">POST /submitInvoice</code>, MCP tells it, “Here’s a structured action called <code class="language-plaintext highlighter-rouge">SubmitInvoice</code>, it requires an <code class="language-plaintext highlighter-rouge">InvoiceID</code> and <code class="language-plaintext highlighter-rouge">Amount</code>, and upon success, it returns a <code class="language-plaintext highlighter-rouge">TransactionID</code> that you can use to track payment.”</p>

<p>MCP solves three major problems with traditional API access:</p>

<ol>
  <li><strong>Capability Discovery:</strong> No more hard-coded API lists—agents dynamically discover what’s possible at runtime.</li>
  <li><strong>Schema Awareness:</strong> Models get structured descriptions of expected inputs and outputs, reducing hallucination and misinterpretation.</li>
  <li><strong>Context-Rich Execution:</strong> API calls are described in a way that helps an agent reason about them instead of guessing based on function names.</li>
</ol>

<p>But MCP is <strong>not a silver bullet</strong>. It improves how models interact with APIs, but it doesn’t <strong>fully</strong> solve the problem of understanding <strong>why</strong> an action should be taken or how different API calls relate to one another in a broader workflow. There’s still work to do in making APIs <strong>self-describing at a deeper level</strong>, enabling agents to <strong>chain calls</strong> intelligently rather than invoking them in isolation.</p>

<p>For now, MCP is a <strong>significant step up</strong> from traditional API integration, moving us toward agentic systems that interact with external data in structured, predictable ways. But without deeper semantic modeling, agents remain <strong>capable but contextually naive</strong>—able to call functions but not always able to reason about their broader implications.</p>

<h3 id="summary-of-challenges">Summary of Challenges</h3>

<p>The challenge that anyone who has spent much time playing with language models is most familiar with is hallucinations. However, given a large part of the raison d’être of these models is <em>generating</em> novel responses to prompts, this phenomenon occupies a strange <em>feature-bug duality</em> that we have to contend with. Their behavior is, by design, nondeterministic. At the same time, these modes have demonstrated themselves the most capable AI models humanity has yet created. Their broad utility and adaptability have led many to believe they offer an adequate foundation to build agentic ai systems.</p>

<p>Although techniques exist to manage hallucinations, the obvious <em>incremental evolution</em> approaches are, by themselves, leaving much to be desired.</p>

<p>In any event, beyond hallucinations, we must identify a path to deal with the following:</p>

<h4 id="discovery">Discovery</h4>

<p>We need a reliable mechanism for a given model to figure out what options exist in the target application the agent might deal with. From a web-driven approach, assuming bot restrictions are not in place, the model needs to either be able to discover functionality within the web app, or some amount of fine-tuning or custom programming must exist to make these details directly actionable.</p>

<p>Arguably, the most appropriate path for machine-to-machine interaction is via an API yet both approaches are currently being explored. An API-driven approach eliminates the challenges of bot restrictions. APIs built using modern tools and frameworks often produce OpenAPI Specification (OAS) documentation which can aid in discovery by, at a minimum, enumerating endpoints and briefly describing their purpose however a traditional API interface is positively anemic when compared with the richness of a web UI.</p>

<p>Consider an API that expects the following JSON payload:</p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="w">
</span><span class="p">{</span><span class="w">
   </span><span class="err">...</span><span class="w">
   </span><span class="err">EventName:</span><span class="w"> </span><span class="p">,</span><span class="w">
   </span><span class="err">EventDate:</span><span class="w"> </span><span class="p">,</span><span class="w">
   </span><span class="err">VenueAddress:</span><span class="w"> </span><span class="p">,</span><span class="w">
   </span><span class="err">NumberOfGuests:</span><span class="w"> </span><span class="p">,</span><span class="w">
   </span><span class="err">...</span><span class="w">
</span><span class="p">}</span><span class="w">

</span></code></pre></div></div>

<p>A language model could easily make reasonable (but unreliable) inferences around types or meaning. A more uniform approach such as MCP will include JSON Schema, but this is syntactic rather than semantic.</p>

<p>Contrast this with the following HTML snippet:</p>

<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
<span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">"text"</span> <span class="na">name=</span><span class="s">"EventName"</span> <span class="na">required</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">"date"</span> <span class="na">name=</span><span class="s">"EventDate"</span> <span class="na">required</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;textarea</span> <span class="na">name=</span><span class="s">"VenueAddress"</span><span class="nt">&gt;&lt;/textarea&gt;</span>
<span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">"number"</span> <span class="na">name=</span><span class="s">"NumberOfGuests"</span> <span class="na">min=</span><span class="s">"10"</span> <span class="na">max=</span><span class="s">"5000"</span> <span class="nt">/&gt;</span>

</code></pre></div></div>

<p>The form interface introduces an additional dimension of metadata as well as a wealth of context from the surrounding UI elements. As we discussed, while the web UI introduces some benefits, it also opens up new risks in the form of novel prompt-injection attacks. The API-driven approach mitigates this risk significantly.</p>

<p>We can provide an agent with better API documentation with more precisely designed schemas to move in the direction of parity (part of the current motivations for MCP), however these artifacts overlook a more critical gap.</p>

<h4 id="semantics">Semantics</h4>

<p>Beyond type validation, the agent must be able to accurately and reliably infer the semantics of each attribute in the API payload. API interfaces and responses lack the rich context of a UI, making it harder for LLMs to infer meaning accurately. JSON schemas and the like do not currently address this issue.</p>

<h4 id="out-of-band-information-needs">Out-of-Band Information Needs</h4>

<p>Succeeding with an API-driven approach with APIs as we design and build them now requires a significant amount of out-of-band information; information that is a pre-requisite of interacting with the system. Much of this will need to be provided at design time or fine-tuning-time which will significantly limit the agency and autonomy of the agent.</p>

<h4 id="interface-fragility">Interface Fragility</h4>

<p>LLMs lack real-time learning and adaptation; they rely on pre-trained knowledge and retrieval-based augmentation. One of the conveniences of a web interface is that the HTML representation of a web page includes instructions for navigating and interacting with the system in the form of hypermedia controls (<code class="language-plaintext highlighter-rouge">a</code> and <code class="language-plaintext highlighter-rouge">form</code> tags). If a breaking back-end change is introduced, the HTML is modified. Likewise, if new functionality is introduced into the app, the HTML is modified accordingly to surface that functionality. This provides some level of dynamic adaptability.</p>

<p>Contrast this with the API-driven approach, where breaking changes typically break the client which requires client code modification. Due to the need for out-of-band information, the agent must either rely on outdated API specifications or it must wait for the new functionality to be programmatically enabled on the client. Even stable APIs often have inconsistent interfaces, which will only compound the problems.</p>

<p>We must also figure out how to contend with the reality that LLMs do not inherently understand error handling or edge cases, making automated interactions unreliable.</p>

<p>Ultimately, an agentic system that must infer interaction patterns on every request is likely too slow for practical applications.</p>

<p>While LLMs and agentic systems hold promise, their use in autonomous decision-making and system interaction when following iterative evolution remains risky. As magical as LLMs sometimes appear to be, the <em>magical thinking</em> that is so pervasive in the AI sphere won’t get us where we want to go. There are fundamental problems that must be addressed to pave a path forward to agentic systems with current technology. Yet, the <em>incremental evolution</em> approaches only provide half-solutions.</p>

<h2 id="so-whats-the-answer">So, What’s the Answer?</h2>

<p>That, dear reader, will have to wait for <a href="https://sufficiently-advanced.technology/post/agentic-ai-ii">part II of this series.</a> We will tackle the major problems one-by-one to pave a pragmatic path towards truly autonomous AI agents.</p>]]></content><author><name>Michael</name><uri>https://w3id.org/people/michael</uri></author><category term="ai" /><category term="ai" /><category term="rest" /><category term="chatgpt" /><summary type="html"><![CDATA[I’ve been designing and building data-driven &amp; machine learning-enabled applications, on and off, for roughly 15 years. Although I was fortunate to have access to GPT3 about a year ahead of the mainstream, I was wholly unprepared for the wide-reaching impact of this technology. The introduction of ChatGPT in late 2022 brought into sharp focus just how impressive the current generation of large language models have become. The sheer breadth of zero-shot capabilities demonstrated by a single model has everyone’s minds racing. There is obviously immense power here, but how do we harness it to realize its true value and potential? That is the trillion-dollar question. One of the most compelling visions for humanity’s next steps with AI is creating autonomous agents; AI systems that can do more than summarize text and provide plausible, information-shaped responses to our prompts. These are AI systems that can interact with other systems or the physical world. Although a great deal of R&amp;D is underway as I write this, I’m shocked that one of the most promising solutions to the conundrum of how to achieve such agentic systems continues to fly under the radar…]]></summary></entry><entry><title type="html">Book Announcement</title><link href="https://sufficiently-advanced.technology/post/mastering-software-architecture" rel="alternate" type="text/html" title="Book Announcement" /><published>2025-02-01T00:00:00+00:00</published><updated>2025-02-01T00:00:00+00:00</updated><id>https://sufficiently-advanced.technology/post/book-announcement</id><content type="html" xml:base="https://sufficiently-advanced.technology/post/mastering-software-architecture"><![CDATA[<figure class="aligncenter">
	<img property="image" src="https://sufficiently-advanced.technology/assets/images/msa.jpg" width="800" height="300" alt="A portion of the cover art of Michael's upcoming book, Mastering Software Architecture" />
</figure>

<p>Welp, the final draft of my book, Mastering Software Architecture has been turned into the publisher. It is the culmination of nearly two years of active writing (~800 hours), countless hours of research, 156 citations, and 25+ years in industry.</p>

<p>Rather than write yet-another distillation of the current state of practice, I have tried to dramatically improve it. The model introduced in this work unifies our fragmented models in a way that solves real problems once thought by many to be intractable.</p>

<p>I’m proud of the result.</p>

<!--more-->

<p>From the back cover:</p>

<p>“As the pace of evolution in technology continues to accelerate, the field of software architecture grapples with ever-increasing complexity, uncertainty, and risk. While numerous patterns and practices have emerged as potential approaches to solving the industry’s most challenging problems, these tools often struggle to consistently deliver on their promises and software projects fail to reach their potential with alarming frequency. This meticulously crafted guide presents a deep exploration into the intricacies of crafting systems that precisely and predictably address modern challenges. It goes beyond mere comprehension of architecture; it encourages mastery.</p>

<p>Mastery of software architecture requires much more than just technical know-how. The author, drawing upon deep experience and unique perspectives, introduces a fresh, problem-centric approach to the realm of software architecture to address these myriad challenges. This book offers a uniquely holistic approach, weaving together architectural principles with organizational dynamics, environmental subtleties, and the necessary tools to execute on architecture more effectively. It addresses the broader contexts that are often overlooked. You’ll be introduced to the transformative Tailor-Made model which provides fast, design-time feedback on total architectural fit and offers more deterministic outcomes, without the typical (and costly) trial-and-error. The Tailor-Made model further enables a practical approach to designing evolutionary architectures.</p>

<p>This book also offers a comprehensive Architect’s toolbox with powerful strategies and problem-solving tools to design, communicate, and implement architectural decisions across the enterprise. Additionally, it imparts invaluable insights into the art of communication as an architect, seamlessly aligning visions with business goals and objectives. With its rich blend of theoretical depth, practical insights, and actionable tools, this book promises to redefine the landscape of software architecture. Whether you are an established architect or an aspiring one, Mastering Software Architecture is poised to enhance your expertise, enabling you to confront architectural challenges with unparalleled confidence and competence.”</p>

<p>The anticipated release date is April 10th and pre-orders are live. <a href="https://a.co/d/aondwe4">Pre-order now</a></p>]]></content><author><name>Michael</name><uri>https://w3id.org/people/michael</uri></author><category term="architecture" /><category term="architecture" /><category term="development" /><category term="tailor-made" /><category term="soft-skills" /><summary type="html"><![CDATA[Welp, the final draft of my book, Mastering Software Architecture has been turned into the publisher. It is the culmination of nearly two years of active writing (~800 hours), countless hours of research, 156 citations, and 25+ years in industry. Rather than write yet-another distillation of the current state of practice, I have tried to dramatically improve it. The model introduced in this work unifies our fragmented models in a way that solves real problems once thought by many to be intractable. I’m proud of the result.]]></summary></entry><entry><title type="html">You are more than a label</title><link href="https://sufficiently-advanced.technology/post/more-than-a-label" rel="alternate" type="text/html" title="You are more than a label" /><published>2025-01-05T00:00:00+00:00</published><updated>2025-01-05T00:00:00+00:00</updated><id>https://sufficiently-advanced.technology/post/more-than-a-label</id><content type="html" xml:base="https://sufficiently-advanced.technology/post/more-than-a-label"><![CDATA[<figure class="aligncenter">
	<img property="image" src="https://sufficiently-advanced.technology/assets/images/multitudes.jpg" width="800" height="300" alt="GoPro capture of Michael and friends jumping out of a helicopter" />
</figure>

<p>You can be more than a label, or category. In fact, the breadth of your knowledge and experience is your superpower in whatever field you work.</p>

<p>Being a magician made me a better technologist, and my experience in the tech world made me a better magician.</p>

<!--more-->

<p>As Richard Hamming put it:</p>

<blockquote>
  <p>“There is an essential unity to all knowledge…”</p>
</blockquote>

<p>How does magic make me a better technologist? The short answer is Magic is about doing the impossible. It turns out spending 30 years engineering impossibility has left me with a wealth of mental models and cognitive tools that make me a more effective problem solver.</p>

<p>Beyond that I have developed unique communication and presentation skills which prepared me to interface with the business and allowed me to move into positions of greater influence.</p>

<p>Sales skills honed from decades of selling myself and my shows have enabled more ideas to go from my head to my teams to my organizations. Psychological skills from a deep study and practice of mentalism made me a more empathetic and effective leader.</p>

<p>The list goes on and on. We all have our secret superpowers and the first step to leveraging them is de-compartmentalizing ourselves and accepting the value of breadth and range.</p>

<div class="youtube-wrapper">
    <iframe src="https://www.youtube.com/embed/BJuco-0rRZI" allowfullscreen=""></iframe>
</div>

<p>Advancements in AI are bringing existential dread to narrow specialists. We are in a new age where our value is predicated on <em>everything</em> we bring to the table, not just narrow knowledge. Be the whole that is greater than the sum of its parts because, as Robert Heinlein once said, “Specialization is for insects.”</p>

<p>This is the essence of our humanity and a value proposition that cannot yet be replaced. Context is everything, how many contexts do you span? (Hint: more than you think!)</p>

<p>The full Heinlein quote is:</p>

<blockquote>
  <p>“A human being should be able to change a diaper, plan an invasion, butcher a hog, conn a ship, design a building, write a sonnet, balance accounts, build a wall, set a bone, comfort the dying, take orders, give orders, cooperate, act alone, solve equations, analyze a new problem, pitch manure, program a computer, cook a tasty meal, fight efficiently, die gallantly. Specialization is for insects.”</p>
</blockquote>

<p>Embrace your whole self in 2025!</p>]]></content><author><name>Michael</name><uri>https://w3id.org/people/michael</uri></author><category term="magic" /><category term="architecture" /><category term="magic" /><category term="soft-skills" /><summary type="html"><![CDATA[You can be more than a label, or category. In fact, the breadth of your knowledge and experience is your superpower in whatever field you work. Being a magician made me a better technologist, and my experience in the tech world made me a better magician.]]></summary></entry></feed>