DEV Community

Marcc Atayde
Marcc Atayde

Posted on

How AI Is Actually Changing Web Agency Workflows: The Honest Developer's Breakdown

There's a version of this article that opens with "AI is revolutionizing everything" and then lists ChatGPT prompts for writing alt text. You've read that article. This isn't it.

What's actually happening in web agencies right now is messier, more interesting, and more consequential than the hype suggests. AI isn't replacing developers — but it is fundamentally reshaping where developer time goes, which skills compound in value, and how agencies structure their delivery pipelines. If you're shipping client work professionally, the changes are already affecting you whether you've intentionally adopted AI tooling or not.

Let me walk through where AI integration is producing real workflow gains, where it's creating new categories of technical debt, and what the code actually looks like when you wire this stuff into production.

Where AI Is Genuinely Useful in Agency Work

Content Intelligence Pipelines

The most durable AI integration I've seen in agency workflows isn't code generation — it's content processing. Specifically, taking unstructured client content and transforming it into structured, SEO-aware output at scale.

A typical pattern: a client dumps a folder of Word documents, product specs, and old blog posts. Previously, a developer manually parsed this into CMS-ready content. Now you can pipe it through an LLM with a structured extraction prompt and get JSON back that maps directly to your content model.

// Laravel job that processes raw client documents through OpenAI
class ProcessClientContentJob implements ShouldQueue
{
    public function __construct(
        private string $rawText,
        private int $pageId
    ) {}

    public function handle(OpenAI\Client $openai): void
    {
        $response = $openai->chat()->create([
            'model' => 'gpt-4o',
            'messages' => [
                [
                    'role' => 'system',
                    'content' => 'You are a content structuring assistant. Extract structured page content from raw text. Return valid JSON only.'
                ],
                [
                    'role' => 'user',
                    'content' => $this->buildExtractionPrompt($this->rawText)
                ]
            ],
            'response_format' => ['type' => 'json_object'],
            'temperature' => 0.2,
        ]);

        $structured = json_decode(
            $response->choices[0]->message->content,
            true
        );

        Page::find($this->pageId)->update([
            'title'        => $structured['title'] ?? null,
            'meta_desc'    => $structured['meta_description'] ?? null,
            'body_blocks'  => $structured['content_blocks'] ?? [],
            'focus_keyword'=> $structured['primary_keyword'] ?? null,
            'ai_processed' => true,
        ]);
    }

    private function buildExtractionPrompt(string $text): string
    {
        return <<<PROMPT
        Extract the following from this content and return as JSON:
        - title (SEO-optimised, max 60 chars)
        - meta_description (max 155 chars)
        - primary_keyword
        - content_blocks (array of {type, content} where type is heading|paragraph|list)

        Raw content:
        {$text}
        PROMPT;
    }
}
Enter fullscreen mode Exit fullscreen mode

The response_format: json_object constraint is critical — without it you're parsing freeform text and that breaks in production constantly.

Automated Code Review as a CI Step

Another pattern gaining traction: running AI code review as part of your PR pipeline, not as a replacement for human review but as a first-pass filter that catches the obvious stuff before it reaches a senior developer's attention.

# .github/workflows/ai-review.yml
name: AI Code Review
on:
  pull_request:
    types: [opened, synchronize]

jobs:
  review:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Get diff
        id: diff
        run: |
          git diff origin/${{ github.base_ref }}...HEAD -- '*.php' > diff.txt
          echo "diff_exists=$([ -s diff.txt ] && echo true || echo false)" >> $GITHUB_OUTPUT

      - name: AI Review
        if: steps.diff.outputs.diff_exists == 'true'
        env:
          OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          DIFF=$(cat diff.txt)
          REVIEW=$(curl -s https://api.openai.com/v1/chat/completions \
            -H "Authorization: Bearer $OPENAI_API_KEY" \
            -H "Content-Type: application/json" \
            -d "$(jq -n \
              --arg diff "$DIFF" \
              '{model:"gpt-4o-mini",messages:[{role:"system",content:"Review this PHP diff for security issues, N+1 queries, and missing validation. Be terse and specific. Flag only real problems."},{role:"user",content:$diff}],max_tokens:800}'\
            )" | jq -r '.choices[0].message.content')

          gh pr comment ${{ github.event.pull_request.number }} --body "**AI Review:**
          $REVIEW"
Enter fullscreen mode Exit fullscreen mode

The gpt-4o-mini choice here is deliberate — it runs on every PR, so cost matters. Save the expensive model for the high-stakes operations.

The Problems Nobody Talks About

Context Window Debt

LLMs are stateless. Every request is a clean slate. This is obvious but the implications sneak up on you. When you're building AI-assisted features that span multiple user interactions — think a multi-step onboarding wizard with an AI advisor — you're responsible for reconstructing context on every call. That means serializing conversation history, truncating it intelligently when it exceeds limits, and deciding what's safe to drop.

class ConversationContextManager
{
    private const MAX_TOKENS = 6000; // conservative limit for gpt-4o-mini

    public function buildMessages(Conversation $conversation): array
    {
        $messages = [['role' => 'system', 'content' => $this->systemPrompt()]];
        $history  = $conversation->messages()
                        ->latest()
                        ->take(20) // grab recent 20
                        ->get()
                        ->reverse();

        $tokenCount = $this->estimateTokens($this->systemPrompt());

        foreach ($history as $message) {
            $msgTokens = $this->estimateTokens($message->content);

            if ($tokenCount + $msgTokens > self::MAX_TOKENS) {
                break; // drop oldest first
            }

            $messages[]  = ['role' => $message->role, 'content' => $message->content];
            $tokenCount += $msgTokens;
        }

        return $messages;
    }

    private function estimateTokens(string $text): int
    {
        // rough approximation: 1 token ≈ 4 chars
        return (int) ceil(mb_strlen($text) / 4);
    }
}
Enter fullscreen mode Exit fullscreen mode

This is boring infrastructure work. It's also the difference between a chatbot that works and one that loses its mind after five messages.

Over-Reliance on Generation for Client-Facing Content

This one is more of an agency operations concern. AI-generated content, shipped without domain review, creates SEO problems downstream. Thin content, homogenized phrasing, and factual errors in technical niches are common failure modes. At https://hanzweb.ae, the approach that's held up best is using AI for structure and first-draft scaffolding, then routing output through a human review step before anything touches a production CMS. It's slower than fully automated pipelines, but the quality delta in search performance is measurable.

What Skills Actually Compound Here

If you're thinking about where to invest learning time, the highest-leverage areas in an AI-augmented agency workflow are:

  • Prompt engineering for structured output — JSON mode, function calling, and schema enforcement are more reliable than free-text parsing.
  • Retrieval-augmented generation (RAG) — Knowing how to chunk, embed, and retrieve client-specific knowledge makes generic LLM outputs actually relevant to a client's business context.
  • Observability for AI calls — Logging latency, token usage, and output quality metrics. When an AI feature degrades silently, you need the data to diagnose it.
  • Cost modeling — A feature that costs $0.002 per trigger is fine. One that costs $0.40 per trigger needs a budget conversation before it ships.

Conclusion

AI in agency workflows isn't a switch you flip — it's a surface you instrument carefully. The wins are real: content processing, code review augmentation, client-facing conversational interfaces. But the failure modes are equally real: context mismanagement, cost blowouts, and content quality regressions that don't show up until months later in analytics.

The developers getting the most out of these tools aren't the ones using AI to write all their code. They're the ones who understand where deterministic systems end and probabilistic ones begin — and who build the guardrails accordingly.

Ship AI features the same way you'd ship any infrastructure: with logging, with fallbacks, and with a healthy skepticism toward anything that looks too easy.

Top comments (0)