Loading episodes…
0:00 0:00

Websites in the AI Age: When Your AI Becomes a Real Coworker

00:00
BACK TO HOME

Websites in the AI Age: When Your AI Becomes a Real Coworker

10xTeam May 14, 2026 12 min read

There’s a version of AI collaboration most developers are familiar with: you paste your code into a chat window, ask a question, and copy the answer back. The AI is a smart search engine. A sophisticated autocomplete. A rubber duck that talks back.

Then there’s the other version — the one that’s actually coming.

In that version, the AI doesn’t just answer questions about your codebase. It acts on it. It runs commands. It reads a discovery file, understands your tools, and makes changes that appear in production. You review its work the same way you’d review a pull request from a junior developer.

I’ve been building toward that second version. This is what I learned.


The Problem with “AI-Assisted” Development

Most codebases are not designed to be used by AI agents. They’re designed to be read by humans, modified by humans, and deployed by humans. The AI is an afterthought — a tool you use before you touch the code, not one that touches it for you.

This creates a subtle but significant inefficiency. Every time you want the AI to help with something — update a social media link, swap out a banner headline, add a new promotional CTA — you have to do the translation yourself. You describe what you want. The AI generates code. You review it, decide if it’s right, and apply it manually.

That’s not collaboration. That’s dictation.

The alternative is designing your project so that an AI agent can discover what tools are available, understand what they do without reading the underlying implementation, and act — running the right command to produce the right result, without touching a single HTML file.


AGENTS.md: The Discovery Contract

The first piece of this puzzle is visibility. An AI agent arriving at your project for the first time needs to answer one question immediately: “What can I do here without breaking anything?”

For humans, the answer lives in documentation, READMEs, and institutional knowledge. For AI agents, the answer needs to be machine-readable and explicit.

I created a file called AGENTS.md at the root of the project. It’s modeled after the same instinct behind robots.txt, sitemap.xml, and OpenAI’s tool manifest format — a convention that any automated system can look for first.

Here’s what it contains:

  • A project overview (type, CSS framework, build commands)
  • A command registry — every available CLI command, what it does, and an example
  • Architecture diagrams — how CTAs flow from data files to templates to layouts
  • Known gotchas — the “don’t do this” list that saves an AI (or a new human developer) from common mistakes

The key insight: AGENTS.md is not documentation about the project. It’s an operational contract — a set of instructions for any automated system that needs to act on the project without human supervision.

When I start a new conversation with an AI assistant about this codebase, the first thing I ask it to do is read AGENTS.md. Within seconds, it knows that updating a CTA title means running node cli/features.js update-data --key bio.title --value "...", not opening _layouts/post.html and searching for the right <h3> tag.


NLP Contracts: Teaching AI to Read Templates

The second piece is introspection. My project uses a template system for its Call-To-Action components — reusable HTML blocks for bio cards, social buttons, book promos, and platform banners. Each template lives in cli/templates/ctas/.

The problem: if an AI agent wants to create a new CTA, how does it know what variables a template requires? It could read the raw HTML. But that’s fragile — a change in formatting or structure could break the AI’s ability to parse it.

The solution: embed an NLP Contract at the top of every template. This is a hidden JSON block that describes the template in structured, machine-readable terms.

<!-- NLP_CONTRACT_START
{
  "type": "cta",
  "name": "link_button",
  "description": "A CTA block with a headline, paragraph, and a primary action button.",
  "variables": [
    { "name": "cta_id",   "type": "string", "required": true,  "description": "Unique ID" },
    { "name": "title",    "type": "string", "required": true,  "description": "Headline" },
    { "name": "btn_url",  "type": "url",    "required": true,  "description": "Button URL" },
    { "name": "btn_text", "type": "string", "required": true,  "description": "Button label" },
    { "name": "icon",     "type": "string", "required": false, "default": "fa-bolt" }
  ]
}
NLP_CONTRACT_END -->

An AI agent (or the CLI tool itself) reads this contract first. It validates required variables, fills in defaults, and only then processes the HTML. The template’s visual implementation can change completely without breaking the contract.

This is the same principle behind function calling in modern LLMs, JSON Schema in APIs, and OpenAPI specs in REST services. The schema comes first. The implementation is an internal detail.

Running node cli/features.js list-templates prints every available template’s contract in human-readable form:

📄 promo_banner.html
   A styled Arabic announcement/promo banner strip.
   Variables:
     --var:cta_id     — Unique identifier [required]
     --var:message    — Banner text [required]
     --var:color      — Background theme [default: blue]
     --var:link_url   — Optional link URL

The AI doesn’t need to open the file. The file announces itself.


Separation of Data and Presentation

The third piece is where content lives. In most web projects, content is scattered everywhere — in HTML templates, in layout files, in hardcoded strings inside JavaScript. When you want to change a headline or update a URL, you go hunting through files.

This is manageable for humans. For AI agents operating at scale, it’s a reliability problem. Changing a URL in the wrong file, or missing one of three places where the same string appears, produces subtle bugs that are hard to catch and harder to roll back.

The solution is radical separation: all content and URLs live in one place, and nothing else touches them directly.

In this project, that’s _data/post_ctas.yml:

bio:
  title: "Learn Programming, AI, and Cybersecurity"
  desc: "Discover the wonders of the tech world with Ahmed Bouchefra."
  btn_text: "Read More About the Author"
  btn_url: "/about.html"

socials:
  title: "Join Our Communities"
  facebook_url: "https://facebook.com/yourpage"
  telegram_url: "https://t.me/yourchannel"

The HTML templates read from this file via Liquid tags. The CLI tool writes to it via update-data. An AI agent only ever needs to know one command to change any piece of copy across the entire site:

node cli/features.js update-data --key socials.facebook_url --value "https://facebook.com/new"

It doesn’t matter how many templates use that URL. The data file is the single source of truth.

The same pattern governs announcements. _data/announcements.yml holds every banner — active, inactive, and historical. The CLI manages them:

# Add a new banner
node cli/features.js add-announcement \
  --message "📚 Subscribe free and get all our books!" \
  --color blue \
  --link "/library.html" \
  --dismiss days:7

# Bring back an old one for an event
node cli/features.js activate-announcement --id announce_ramadan_2026

No code was touched. No HTML was opened. The AI ran a command, and the site changed.


Feature Flags: The Agentic Safety Net

Agents make mistakes. The safest AI-driven systems are the ones that make mistakes reversibly.

Feature flags are the canonical tool for this. Every UI component in this project — CTAs, banners, PDF export options, social buttons, the AI summary widget — has a corresponding boolean flag in _data/features.json. Setting any flag to false removes that component from the live site immediately after rebuild.

{
  "post": {
    "cta_bio": true,
    "cta_socials": true,
    "print_cta_books": false,
    "lib_topbar": false
  }
}

An AI agent can disable any feature with one command:

node cli/features.js disable cta_books --ctx post

This is structurally similar to how feature flags work at scale in production systems (LaunchDarkly, Unleash, Statsig). The principle scales from a personal blog to a multi-million-user platform: the ability to turn things on and off without a code deploy is the foundation of safe agentic action.


The PDF Export Problem: Thinking in Print

One unexpected challenge in building this system was PDF export. The site uses the browser’s native window.print() to generate PDFs. The print stylesheet captures everything inside the main <article> element.

Early in the design, the CTAs lived outside the article — which meant they were clean on the live page but invisible in PDFs. Moving them inside the article solved that. But then we needed a way to exclude specific CTAs from print without removing them from the live page.

The solution: a print_cta_* flag for every component. When set to false, the Liquid template injects a no-print CSS class. The component renders normally on screen, but disappears when the browser generates a PDF.




<div class="post-cta-bio ">
    ...
</div>

This is a small example of a larger principle: in systems designed for AI action, every behavior should be controllable through data, not code changes. The agent shouldn’t need to modify HTML to change what appears in a PDF.


The post_ctas_group.html Pattern: Single Injection, Multiple Layouts

The final architectural piece worth discussing is composition.

The project has multiple post layouts: post.html, roadmappost.html, bookpost.html. Initially, CTAs were hardcoded into each layout separately — which meant updating a CTA required opening three files and making the same change in each.

The solution: a single grouping include, post_ctas_group.html, that contains all the CTA inclusion logic. Every layout includes it in exactly one place:



Adding a new CTA to the entire site now requires exactly two actions: creating the CTA’s include file (via the CLI’s add-cta command), and updating post_ctas_group.html. No layout files need to be touched.

This is the single point of injection principle — a direct application of Don’t Repeat Yourself that happens to make AI-driven management dramatically safer. When an AI agent adds a new CTA using node cli/features.js add-cta, it knows with certainty that the CTA will appear in every layout. There’s no room for the “I added it to post.html but forgot roadmappost.html” failure mode.


What This Looks Like in Practice

Here’s what an AI agent session looks like with this architecture in place:

Me: Add a Ramadan promotional banner that auto-dismisses in 30 days.

Agent:

node cli/features.js add-announcement \
  --id "announce_ramadan_2026" \
  --message "🌙 Special Ramadan offers available now" \
  --color purple \
  --link "https://webtutpro.com/ramadan" \
  --link-text "Explore" \
  --dismiss days:30

Done. No code was shown. No files were opened. No HTML was generated. The agent read the tool contract from AGENTS.md, ran the correct command, and the banner appeared on the live site after the next build.

The same workflow applies to updating the bio headline, disabling the books CTA from the PDF export, or scaffolding an entirely new type of CTA from a template.

This is what “AI as a coworker” actually looks like — not a model that generates code for you to copy and paste, but an agent that uses real tools to make real changes, with a clear audit trail and a predictable rollback path.


The Bigger Picture: Toward Agentic Infrastructure

What I’ve described here maps directly onto patterns that are becoming standard in enterprise AI systems:

This project The bigger world
AGENTS.md MCP (Model Context Protocol) server manifests, OpenAI tool definitions
NLP Contracts JSON Schema, OpenAPI, function calling signatures
_data/post_ctas.yml Content management APIs, headless CMS content layers
Feature flags in features.json LaunchDarkly, Unleash, runtime configuration systems
post_ctas_group.html Dependency injection, single-responsibility modules

The difference is scale. Enterprise teams spend millions building infrastructure for AI agents to act on their systems safely. The same principles — discoverability, schema-first design, data/presentation separation, reversible flags, single injection points — apply at any scale, including a personal Jekyll blog.

If you’re building anything today — a website, a CLI tool, a backend service — and you think AI agents might ever interact with it, the question worth asking is: “Could an AI agent read my project and know exactly what to do without asking me first?”

If the answer is no, the gap between your current architecture and an AI-ready one is probably smaller than you think.


Conclusion

The shift from “AI as autocomplete” to “AI as agent” requires more than smarter models. It requires infrastructure — projects designed to receive agentic action, not just answer questions about it.

AGENTS.md gives agents a map. NLP Contracts give them a vocabulary. Data/presentation separation gives them a safe place to act. Feature flags give them a safety net. Single injection points give them predictable surfaces.

None of these patterns are new. They’re principles from software engineering applied deliberately with AI agency in mind. The models are already capable enough. The bottleneck is the architecture they’re acting on.

Build AI-ready projects, and the coworker you get is considerably more useful than the one everyone’s currently describing.


Join the 10xdev Community

Subscribe and get 8+ free PDFs that contain detailed roadmaps with recommended learning periods for each programming language or field, along with links to free resources such as books, YouTube tutorials, and courses with certificates.

Audio Interrupted

We lost the audio stream. Retry with shorter sentences?