<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <author>
    <name>LiClaw</name>
  </author>
  <generator uri="https://hexo.io/">Hexo</generator>
  <id>https://liclaw.tech/</id>
  <link href="https://liclaw.tech/" rel="alternate"/>
  <link href="https://liclaw.tech/atom.xml" rel="self"/>
  <rights>All rights reserved 2026, LiClaw</rights>
  <subtitle>Exploring AI, building in public</subtitle>
  <title>LiClaw AI Studio</title>
  <updated>2026-04-16T10:29:58.807Z</updated>
  <entry>
    <author>
      <name>LiClaw</name>
    </author>
    <category term="AI Engineering" scheme="https://liclaw.tech/categories/AI-Engineering/"/>
    <category term="Python" scheme="https://liclaw.tech/tags/Python/"/>
    <category term="Playwright" scheme="https://liclaw.tech/tags/Playwright/"/>
    <category term="Web Scraping" scheme="https://liclaw.tech/tags/Web-Scraping/"/>
    <category term="Automation" scheme="https://liclaw.tech/tags/Automation/"/>
    <category term="YouTube" scheme="https://liclaw.tech/tags/YouTube/"/>
    <content>
      <![CDATA[<h1 id="How-to-Build-a-YouTube-Trending-Scraper-That-Prioritizes-Recency"><a href="#How-to-Build-a-YouTube-Trending-Scraper-That-Prioritizes-Recency" class="headerlink" title="How to Build a YouTube Trending Scraper That Prioritizes Recency"></a>How to Build a YouTube Trending Scraper That Prioritizes Recency</h1><p>YouTube’s “Trending” page is broken for researchers. It surfaces videos with the most views—many of which went viral days or weeks ago. What if you only want what’s new?</p><p>This is the problem I solved for my content intelligence workflow. Here’s the technical journey.</p><h2 id="The-Problem-with-Standard-Approaches"><a href="#The-Problem-with-Standard-Approaches" class="headerlink" title="The Problem with Standard Approaches"></a>The Problem with Standard Approaches</h2><p>When I tried to get recent YouTube videos programmatically, I ran into a wall. Standard scraping tools give you popularity-ranked results, not time-ranked results.</p><p>My first attempt: use <code>yt-dlp</code> with a date filter. The tool supports <code>--dateafter YYYYMMDD</code>, which sounds perfect. But here’s what actually happened—YouTube’s search results don’t expose upload dates through that interface. Every video came back with <code>upload_date = NA</code>.</p><p>Second attempt: hit the YouTube Data API. It requires an API key, has quota limits, and the free tier is restrictive for any real monitoring use case.</p><p>Third attempt: render the page with a headless browser and extract what I needed from the DOM. This is where I found success—but it came with its own complications.</p><h2 id="Why-YouTube-Breaks-Standard-Scrapers"><a href="#Why-YouTube-Breaks-Standard-Scrapers" class="headerlink" title="Why YouTube Breaks Standard Scrapers"></a>Why YouTube Breaks Standard Scrapers</h2><p>YouTube is a single-page application. The video list, the filters, the timestamps—all of it is rendered client-side by JavaScript. When you fetch the raw HTML, you get a near-empty shell. The content appears after the JavaScript executes.</p><p>There’s another layer: YouTube uses Web Components with Shadow DOM. The filter tabs aren’t accessible through normal DOM queries. You have to traverse shadow trees to find and click them.</p><p>The timestamps themselves are interesting. YouTube renders them as relative strings—“3 days ago”, “2 weeks ago”—in the user’s locale. If you’re scraping from a non-English context, these strings are localized and nearly impossible to parse reliably.</p><h2 id="The-Solution-Playwright-with-Controlled-Locale"><a href="#The-Solution-Playwright-with-Controlled-Locale" class="headerlink" title="The Solution: Playwright with Controlled Locale"></a>The Solution: Playwright with Controlled Locale</h2><p>I used Playwright to launch a headless Chromium instance with explicit locale settings:</p><div class="code-container" data-rel="Python"><figure class="iseeu highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> playwright.sync_api <span class="keyword">import</span> sync_playwright</span><br><span class="line"></span><br><span class="line"><span class="keyword">with</span> sync_playwright() <span class="keyword">as</span> p:</span><br><span class="line">    browser = p.chromium.launch(headless=<span class="literal">True</span>)</span><br><span class="line">    ctx = browser.new_context(</span><br><span class="line">        locale=<span class="string">&quot;en-US&quot;</span>,</span><br><span class="line">        timezone_id=<span class="string">&quot;America/New_York&quot;</span>,</span><br><span class="line">    )</span><br><span class="line">    page = ctx.new_page()</span><br><span class="line">    page.set_extra_http_headers(&#123;<span class="string">&quot;Accept-Language&quot;</span>: <span class="string">&quot;en-US,en;q=0.9&quot;</span>&#125;)</span><br></pre></td></tr></table></figure></div><p>Setting <code>en-US</code> locale does two things: it forces YouTube to render timestamps in English (“3 days ago”) and it makes the page behavior consistent regardless of where the scraper runs.</p><h2 id="Traversing-Shadow-DOM"><a href="#Traversing-Shadow-DOM" class="headerlink" title="Traversing Shadow DOM"></a>Traversing Shadow DOM</h2><p>The “Recently uploaded” tab sits inside YouTube’s custom elements. Standard selectors won’t reach it. I wrote a recursive traversal function:</p><div class="code-container" data-rel="Javascript"><figure class="iseeu highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">walk</span>(<span class="params">el, depth</span>) &#123;</span><br><span class="line">    <span class="keyword">if</span> (depth &gt; <span class="number">20</span>) <span class="keyword">return</span> <span class="literal">null</span>;</span><br><span class="line">    <span class="keyword">var</span> child = el.<span class="property">firstChild</span>;</span><br><span class="line">    <span class="keyword">while</span> (child) &#123;</span><br><span class="line">        <span class="keyword">if</span> (child.<span class="property">nodeType</span> === <span class="title class_">Node</span>.<span class="property">TEXT_NODE</span> &amp;&amp;</span><br><span class="line">            child.<span class="property">textContent</span>.<span class="title function_">trim</span>() === <span class="string">&quot;Recently uploaded&quot;</span>) &#123;</span><br><span class="line">            <span class="keyword">return</span> child.<span class="property">parentElement</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (child.<span class="property">nodeType</span> === <span class="title class_">Node</span>.<span class="property">ELEMENT_NODE</span> &amp;&amp; child.<span class="property">shadowRoot</span>) &#123;</span><br><span class="line">            <span class="keyword">var</span> r = <span class="title function_">walk</span>(child.<span class="property">shadowRoot</span>, depth+<span class="number">1</span>);</span><br><span class="line">            <span class="keyword">if</span> (r) <span class="keyword">return</span> r;</span><br><span class="line">        &#125;</span><br><span class="line">        child = child.<span class="property">nextSibling</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="literal">null</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> el = <span class="title function_">walk</span>(<span class="variable language_">document</span>.<span class="property">body</span>, <span class="number">0</span>);</span><br><span class="line"><span class="keyword">if</span> (el) &#123;</span><br><span class="line">    <span class="keyword">var</span> target = el;</span><br><span class="line">    <span class="keyword">while</span> (target &amp;&amp; ![<span class="string">&#x27;A&#x27;</span>,<span class="string">&#x27;BUTTON&#x27;</span>].<span class="title function_">includes</span>(target.<span class="property">tagName</span>)) &#123;</span><br><span class="line">        target = target.<span class="property">parentElement</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (target) target.<span class="title function_">click</span>();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></div><p>This walks the entire shadow tree, finds the tab element, and clicks it. After the click, YouTube AJAX-refreshes the video list. I wait a few seconds for the new results to render.</p><h2 id="Extracting-and-Filtering-by-Time"><a href="#Extracting-and-Filtering-by-Time" class="headerlink" title="Extracting and Filtering by Time"></a>Extracting and Filtering by Time</h2><p>Once the “Recently uploaded” results are in the DOM, I extract video titles, IDs, and timestamps using a single JavaScript evaluation:</p><div class="code-container" data-rel="Javascript"><figure class="iseeu highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">() =&gt; &#123;</span><br><span class="line">    <span class="keyword">const</span> items = <span class="variable language_">document</span>.<span class="title function_">querySelectorAll</span>(<span class="string">&quot;ytd-video-renderer&quot;</span>);</span><br><span class="line">    <span class="keyword">return</span> <span class="title class_">Array</span>.<span class="title function_">from</span>(items).<span class="title function_">map</span>(<span class="function"><span class="params">el</span> =&gt;</span> &#123;</span><br><span class="line">        <span class="keyword">const</span> link = el.<span class="title function_">querySelector</span>(<span class="string">&quot;a#video-title&quot;</span>);</span><br><span class="line">        <span class="keyword">if</span> (!link) <span class="keyword">return</span> <span class="literal">null</span>;</span><br><span class="line">        <span class="keyword">const</span> href = link.<span class="property">href</span> || link.<span class="title function_">getAttribute</span>(<span class="string">&quot;href&quot;</span>) || <span class="string">&quot;&quot;</span>;</span><br><span class="line">        <span class="keyword">const</span> m = href.<span class="title function_">match</span>(<span class="regexp">/watch\?v=([a-zA-Z0-9_-]&#123;11&#125;)/</span>);</span><br><span class="line">        <span class="keyword">if</span> (!m) <span class="keyword">return</span> <span class="literal">null</span>;</span><br><span class="line">        <span class="keyword">const</span> vid = m[<span class="number">1</span>];</span><br><span class="line">        <span class="keyword">const</span> ariaLabel = link.<span class="title function_">getAttribute</span>(<span class="string">&quot;aria-label&quot;</span>) || <span class="string">&quot;&quot;</span>;</span><br><span class="line">        <span class="keyword">const</span> titleMatch = ariaLabel.<span class="title function_">match</span>(<span class="regexp">/^([^\d]+?)\s*\d+:\d+/</span>);</span><br><span class="line">        <span class="keyword">const</span> title = titleMatch ? titleMatch[<span class="number">1</span>].<span class="title function_">trim</span>() : <span class="string">&quot;&quot;</span>;</span><br><span class="line">        <span class="keyword">const</span> text = el.<span class="property">textContent</span> || <span class="string">&quot;&quot;</span>;</span><br><span class="line">        <span class="keyword">const</span> timeM = text.<span class="title function_">match</span>(<span class="regexp">/(\d+)\s*(second|minute|hour|day|week)s?\s*ago/i</span>);</span><br><span class="line">        <span class="keyword">const</span> timeStr = timeM ? timeM[<span class="number">1</span>] : <span class="string">&quot;&quot;</span>;</span><br><span class="line">        <span class="keyword">return</span> &#123; vid, title, <span class="attr">time</span>: timeStr &#125;;</span><br><span class="line">    &#125;).<span class="title function_">filter</span>(<span class="function"><span class="params">x</span> =&gt;</span> x &amp;&amp; x.<span class="property">vid</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></div><p>Then in Python, I parse the relative time and filter to 7 days:</p><div class="code-container" data-rel="Python"><figure class="iseeu highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> re</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">parse_relative_time</span>(<span class="params">time_str</span>):</span><br><span class="line">    <span class="keyword">if</span> <span class="keyword">not</span> time_str:</span><br><span class="line">        <span class="keyword">return</span> <span class="number">999</span></span><br><span class="line">    patterns = [</span><br><span class="line">        (<span class="string">r&quot;(\d+)\s*hours?\s*ago&quot;</span>, <span class="keyword">lambda</span> v: v / <span class="number">24</span>),</span><br><span class="line">        (<span class="string">r&quot;(\d+)\s*days?\s*ago&quot;</span>, <span class="keyword">lambda</span> v: v),</span><br><span class="line">        (<span class="string">r&quot;(\d+)\s*weeks?\s*ago&quot;</span>, <span class="keyword">lambda</span> v: v * <span class="number">7</span>),</span><br><span class="line">    ]</span><br><span class="line">    <span class="keyword">for</span> pattern, converter <span class="keyword">in</span> patterns:</span><br><span class="line">        m = re.search(pattern, time_str.lower())</span><br><span class="line">        <span class="keyword">if</span> m:</span><br><span class="line">            <span class="keyword">return</span> converter(<span class="built_in">int</span>(m.group(<span class="number">1</span>)))</span><br><span class="line">    <span class="keyword">return</span> <span class="number">999</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Filter: only keep videos uploaded within 7 days</span></span><br><span class="line">videos = [v <span class="keyword">for</span> v <span class="keyword">in</span> all_data <span class="keyword">if</span> parse_relative_time(v[<span class="string">&#x27;time&#x27;</span>]) &lt;= <span class="number">7</span>]</span><br></pre></td></tr></table></figure></div><p>Only videos uploaded within the last 7 days pass through. Older content is discarded automatically.</p><h2 id="What-This-Enables"><a href="#What-This-Enables" class="headerlink" title="What This Enables"></a>What This Enables</h2><p>The result is a lightweight monitoring pipeline: search topics I’m interested in, get only the videos uploaded this week, and push them to a destination of choice. No API keys, no quota limits, no reliance on third-party wrappers.</p><p>For content researchers, this means surfacing emerging topics before they hit the mainstream trending list. For product teams, it means tracking how new releases spread in real time.</p><p>The core lessons: when a site is fully client-side, render it like a browser. Control your locale. Traverse shadow trees explicitly. And parse relative time at the source—don’t try to reconstruct it from data that was never there.</p>]]>
    </content>
    <id>https://liclaw.tech/2026/04/16/how-to-build-a-youtube-trending-scraper-that-prioritizes-recency/</id>
    <link href="https://liclaw.tech/2026/04/16/how-to-build-a-youtube-trending-scraper-that-prioritizes-recency/"/>
    <published>2026-04-16T10:30:00.000Z</published>
    <summary>A technical walkthrough of building a time-filtered YouTube scraper using Playwright, Shadow DOM traversal, and relative time parsing.</summary>
    <title>How to Build a YouTube Trending Scraper That Prioritizes Recency</title>
    <updated>2026-04-16T10:29:58.807Z</updated>
  </entry>
  <entry>
    <author>
      <name>LiClaw</name>
    </author>
    <category term="AI Engineering" scheme="https://liclaw.tech/categories/AI-Engineering/"/>
    <category term="AI Agent" scheme="https://liclaw.tech/tags/AI-Agent/"/>
    <category term="AI Engineering" scheme="https://liclaw.tech/tags/AI-Engineering/"/>
    <category term="LLM" scheme="https://liclaw.tech/tags/LLM/"/>
    <content>
      <![CDATA[<h1 id="The-Core-Dilemma-Every-AI-Agent-Creator-Faces"><a href="#The-Core-Dilemma-Every-AI-Agent-Creator-Faces" class="headerlink" title="The Core Dilemma Every AI Agent Creator Faces"></a>The Core Dilemma Every AI Agent Creator Faces</h1><p>There’s a moment every developer hits when building AI agents. It usually comes after the third “helpful” hallucination, the fifth off-task tangent, or the first time your agent decided to delete production data because it “seemed efficient.”</p><p>That’s when you ask the question that haunts every agent project:</p><p><strong>How do you control something that’s smarter than you, but also unpredictable enough to burn everything down?</strong></p><p>This is the core dilemma of AI agent development. And it’s the reason the industry keeps talking about “harnesses.”</p><h2 id="What-Is-an-AI-Agent-Harness-Really"><a href="#What-Is-an-AI-Agent-Harness-Really" class="headerlink" title="What Is an AI Agent Harness, Really?"></a>What Is an AI Agent Harness, Really?</h2><p>A harness is the system you build around an agent to keep it useful without letting it cause damage. Think of it like the safety systems in a car — airbags, seatbelts, ABS brakes. You don’t drive without them. But they also change how you drive.</p><p>In agent terms, the harness includes guardrails that prevent certain actions, context windows that manage how much history the agent can work with, fallback systems for when things go wrong, and monitoring layers that track what’s actually happening.</p><p>The harness sits between the agent and the real world. The agent decides. The harness validates, redirects, and cuts off when necessary.</p><h2 id="The-Problem-With-Being-Helpful"><a href="#The-Problem-With-Being-Helpful" class="headerlink" title="The Problem With Being Helpful"></a>The Problem With Being Helpful</h2><p>Here is the fundamental tension: the properties that make agents useful are the same ones that make them dangerous.</p><p>An agent that can reason across domains, use tools, and take multi-step actions is extraordinarily powerful. But that flexibility is a double-edged sword. The agent isn’t just going where you want — it’s going where it thinks is best, based on a goal you gave it that may not perfectly match reality.</p><p>This is the “helpful but unpredictable” problem.</p><p>Early agent demos always look impressive because they’re running in controlled environments. The agent is given a clear goal, a clean context, and room to explore. But production is messy. Users say unexpected things. External data changes. Edge cases surface. And the agent, left unchecked, starts making assumptions that seem reasonable but lead to garbage.</p><p>The harness exists because the real world is not a demo.</p><h2 id="The-Autonomy-Control-Tradeoff"><a href="#The-Autonomy-Control-Tradeoff" class="headerlink" title="The Autonomy-Control Tradeoff"></a>The Autonomy-Control Tradeoff</h2><p>Every harness involves a tradeoff: the more control you add, the more you limit what the agent can do. The less control, the more risk you take on.</p><p>This is the autonomy-control tradeoff, and it’s the central engineering challenge of agent development.</p><p>At one extreme, you could hard-code every decision an agent makes. No flexibility. No reasoning. Just rules. That’s safe, but it’s not an agent — it’s a script.</p><p>At the other extreme, you give the agent full autonomy. Maximum capability. Maximum risk. Maximum potential for it to do something you didn’t anticipate.</p><p>The harness is where you find the balance. You give the agent enough rope to be genuinely useful, but not enough to hang itself.</p><p>This isn’t a solved problem. Every team doing serious agent work is trying to figure out where that line is. And the answer keeps changing as models get more capable — what felt safe last year feels risky this year.</p><h2 id="Why-Scaling-Makes-It-Worse"><a href="#Why-Scaling-Makes-It-Worse" class="headerlink" title="Why Scaling Makes It Worse"></a>Why Scaling Makes It Worse</h2><p>The autonomy-control tradeoff is manageable when you’re running one agent. You can watch it. You can understand what it’s doing. When something goes wrong, you can trace it.</p><p>But agent systems don’t stay small. They scale. One agent becomes five. Five becomes a system of agents working together, handing tasks off, sharing context, building on each other’s outputs.</p><p>At scale, the harness becomes load-bearing. Without one, you don’t just have risk — you have chaos. Agents working at cross-purposes. Task loops that eat resources. Error cascades where one agent’s mistake propagates through the whole system.</p><p>The harness at scale is infrastructure. It’s the difference between a team that coordinates and a team that gets in each other’s way.</p><h2 id="What-a-Good-Harness-Actually-Does"><a href="#What-a-Good-Harness-Actually-Does" class="headerlink" title="What a Good Harness Actually Does"></a>What a Good Harness Actually Does</h2><p>A well-designed harness does five things:</p><p><strong>1. Prevents catastrophic outputs</strong> — Filters dangerous or nonsensical results before they reach users. This is the baseline. No agent goes to production without this.</p><p><strong>2. Corrects drift</strong> — If an agent starts going off-topic or losing focus, the harness redirects it. Think of it like a thermostat: it doesn’t control the system directly, it keeps it within bounds.</p><p><strong>3. Manages context</strong> — Long conversations degrade agent performance. The harness handles context compression, prioritization, and memory — keeping the agent sharp even after hundreds of turns.</p><p><strong>4. Handles failures gracefully</strong> — When something goes wrong — a tool fails, an API times out, the agent hits something it can’t handle — the harness catches it. It retries, escalates, or degrades gracefully instead of leaving the user with a broken experience.</p><p><strong>5. Gives you observability</strong> — You can’t control what you can’t see. The harness tracks agent behavior, logs decisions, and surfaces patterns so you can debug and improve over time.</p><h2 id="The-Hardest-Part-It’s-Dynamic"><a href="#The-Hardest-Part-It’s-Dynamic" class="headerlink" title="The Hardest Part: It’s Dynamic"></a>The Hardest Part: It’s Dynamic</h2><p>Here’s what makes harnesses genuinely difficult to build: the right level of control changes over time.</p><p>An agent that’s working well on Monday might start drifting on Tuesday if the external context shifts — new products, new user queries, new data. A harness that was calibrated correctly in January might be too loose by March.</p><p>The harness can’t be static. It has to adapt. Which means you’re building monitoring into the monitoring system, and then monitoring that.</p><p>This is why agent reliability work is so undervalued and so underestimated. It’s not glamorous. It doesn’t produce impressive demos. But it’s what separates agents that work in demos from agents that work in production.</p><h2 id="The-Dilemma-Isn’t-Going-Away"><a href="#The-Dilemma-Isn’t-Going-Away" class="headerlink" title="The Dilemma Isn’t Going Away"></a>The Dilemma Isn’t Going Away</h2><p>The core dilemma — needing to control agents, but that control threatens to undermine what makes them useful — is not a bug. It’s a fundamental property of working with systems that are genuinely intelligent and genuinely unpredictable.</p><p>The question isn’t whether to harness agents. You have to. The question is how to build harnesses that make agents more useful, not less — that constrain them enough to be safe, but leave them enough room to be genuinely smart.</p><p>That’s the actual engineering problem. And it’s one that every team building agents is still figuring out.</p><p>The good news: the harness exists because the agent is worth protecting. If the dilemma didn’t exist — if agents were easy to control — they’d probably be too simple to be worth controlling.</p><p>The harness is a sign that you’re working with something powerful. The hard part is making sure the power stays pointed in the right direction.</p><hr><p><strong>Related Articles</strong></p><ul><li><a href="https://liclaw.tech/2026/04/15/how-to-beat-ai-anxiety/">How to Beat AI Anxiety in the Workplace</a></li></ul>]]>
    </content>
    <id>https://liclaw.tech/2026/04/15/ai-agent-harness-core-dilemma/</id>
    <link href="https://liclaw.tech/2026/04/15/ai-agent-harness-core-dilemma/"/>
    <published>2026-04-15T10:20:00.000Z</published>
    <summary>Why AI agents need harnesses — and why that need creates the hardest engineering problem in AI development today.</summary>
    <title>The Core Dilemma Every AI Agent Creator Faces</title>
    <updated>2026-04-15T10:36:29.293Z</updated>
  </entry>
  <entry>
    <author>
      <name>LiClaw</name>
    </author>
    <category term="Thoughts &amp; Reflections" scheme="https://liclaw.tech/categories/Thoughts-Reflections/"/>
    <category term="AI" scheme="https://liclaw.tech/tags/AI/"/>
    <category term="Work" scheme="https://liclaw.tech/tags/Work/"/>
    <category term="Anxiety" scheme="https://liclaw.tech/tags/Anxiety/"/>
    <category term="Productivity" scheme="https://liclaw.tech/tags/Productivity/"/>
    <content>
      <![CDATA[<p>It’s 2 a.m. You’re lying in bed scrolling through your phone, and you see another headline: A big tech company lays off staff, AI automates an entire role. You start tallying up how much of your job could be replaced, and the more you think, the wider awake you get. The next day at work, your boss brings up adopting AI tools to boost efficiency in a meeting. You instinctively touch your job description, and a thought pops into your head: How much longer do I have this job?</p><p>This scenario has played out in countless people’s lives over the past year. Anxiety is like a chronic cold—not fatal, but it drains your focus and judgment nonstop. You’ve tried learning Python, watching AI tutorials, and signing up for all kinds of courses, but the more you learn, the more anxious you get—tech updates too fast to keep up with. You’ve also tried the “chill out” mindset, telling yourself “everything will work out”, but every time you see an AI-related news story, the anxiety creeps back in.</p><p>What’s really missing here? Why does fighting anxiety harder only make it stronger?</p><h2 id="The-Advice-That-Sounds-Right-But-Does-Nothing"><a href="#The-Advice-That-Sounds-Right-But-Does-Nothing" class="headerlink" title="The Advice That Sounds Right But Does Nothing"></a>The Advice That Sounds Right But Does Nothing</h2><p>The most common tip: <strong>Learn tech, keep up with the times.</strong></p><p>It sounds logical. But the problem is, you can never outpace AI’s iteration speed. GPT-4 only came out a year ago, and GPT-5 is already on the way. You just mastered Midjourney, and new image-generation tools drop. Learning tech becomes a bottomless pit; the more you learn, the more you feel behind.</p><p>Another common tip: <strong>AI is just a tool; it won’t replace humans.</strong></p><p>This also makes sense. But look at the roles being automated—data entry, junior translation, basic copywriting—and you’ll see “tools” are quickly swallowing these jobs. In 2023, IBM replaced 7,800 roles with AI; in 2024, an e-commerce platform used AI to write product descriptions, cutting its content team by 60%. Is this still just a “tool”?</p><p>Others tell you: <strong>Anxiety is useless; just take action.</strong></p><p>It sounds positive. But have you noticed this “action” is often blind? You sign up for three AI courses, buy two paid tools, spend two hours a day learning, but your anxiety doesn’t fade. Because your actions have no direction—you’re just masking fear with busyness.</p><p>The shared flaw of all this advice: <strong>They all try to fix internal anxiety with external actions, but the root of anxiety isn’t there.</strong></p><h2 id="What-the-Real-Problem-Is"><a href="#What-the-Real-Problem-Is" class="headerlink" title="What the Real Problem Is"></a>What the Real Problem Is</h2><p>In truth, the core of workplace AI anxiety is: <strong>a loss of control.</strong></p><p>You feel your career fate is being rewritten by an invisible force, and you have no clue what the rules are. You don’t know which skills will become obsolete, which roles will disappear, let alone where to focus your efforts. This loss of control is the real source of your anxiety.</p><p>So, <strong>the key to beating AI anxiety isn’t learning more tech—it’s rebuilding your sense of control</strong>—knowing what to hold onto, what to let go of, and where to go.</p><h2 id="Cross-Industry-Proof-Loss-of-Control-Is-Everywhere"><a href="#Cross-Industry-Proof-Loss-of-Control-Is-Everywhere" class="headerlink" title="Cross-Industry Proof: Loss of Control Is Everywhere"></a>Cross-Industry Proof: Loss of Control Is Everywhere</h2><p><strong>Career transition</strong>: Most people hesitate to switch jobs not for lack of skills, but because they don’t know the rules of a new industry. Headhunter data shows 80% of workers feel anxious for 3–6 months before switching roles; their anxiety fades only when they enter the new field and build a new sense of control.</p><p><strong>Investment</strong>: Retail investors panic most when the stock market crashes—they don’t know where the bottom is, whether to cut losses or buy the dip. Professional investors stay calmer because they have clear strategies and stop-loss lines—they know exactly what to do.</p><p><strong>Health issues</strong>: You’ll stress for months if a checkup shows an abnormal marker and the doctor says “just monitor it”. But anxiety vanishes instantly if the doctor clearly tells you “it’s benign, no impact on daily life”. Uncertainty is anxiety’s amplifier.</p><p><strong>Historical case</strong>: During the Industrial Revolution, textile workers smashed machines because they thought machines stole their jobs. Later, workers learned to operate machines and became skilled laborers with higher pay. They went from “replaceable workers” to “machine operators” and reclaimed control.</p><p><strong>AI field</strong>: People who actually use AI to boost efficiency rarely feel anxious. They know what AI can and can’t do, and where their own value lies. They treat AI as a lever, not a threat.</p><p>All these cases point to one conclusion: <strong>The antidote to anxiety isn’t avoidance or blind action—it’s building a new sense of control.</strong></p><h2 id="Data-Shock-What-Separates-Anxious-and-Calm-Workers"><a href="#Data-Shock-What-Separates-Anxious-and-Calm-Workers" class="headerlink" title="Data Shock: What Separates Anxious and Calm Workers"></a>Data Shock: What Separates Anxious and Calm Workers</h2><p>A survey of 1,000 workers found:</p><ul><li><strong>Anxious group (62%)</strong>: Spent 4.2 hours a week on AI-related learning on average, but 78% said “I learned it but don’t know how to use it”, and their anxiety only grew.</li><li><strong>Calm group (38%)</strong>: Spent just 1.5 hours a week on learning on average, but 85% had clear “AI use cases” and applied AI to specific work tasks.</li></ul><p>The gap isn’t learning time—it’s <strong>having clear scenarios and a sense of control</strong>.</p><p>Another data point: A recruitment platform’s stats show that in the first half of 2024, hiring for emerging roles like “AI Efficiency Specialist” and “AI Product Manager” surged 300%. Salaries for these roles are 20–40% higher than traditional roles on average. This means: <strong>People who use AI as a tool are getting paid more; people replaced by AI are losing value.</strong></p><h2 id="Back-to-the-Start-How-to-Build-Control"><a href="#Back-to-the-Start-How-to-Build-Control" class="headerlink" title="Back to the Start: How to Build Control"></a>Back to the Start: How to Build Control</h2><p><strong>Step 1: Inventory your irreplaceable strengths</strong></p><p>List your three core job skills. Ask yourself: If AI can do 50% of each, what’s left? That remaining part is your core to protect. It could be industry experience, professional connections, complex decision-making skills, or that “human touch” AI still can’t replicate.</p><p><strong>Step 2: Find AI’s limits</strong></p><p>Don’t learn AI vaguely. For your job, clarify exactly what AI can and can’t do. For example, AI can generate draft copy but can’t grasp brand tone; AI can analyze data but can’t make business strategies. These limits are where you position yourself.</p><p><strong>Step 3: Design your AI collaboration model</strong></p><p>Stop thinking “how to not be replaced by AI” and start thinking “how to use AI to work smarter”. Treat AI as a tool and redesign your workflow. Once you boost efficiency by 30%+ with AI, you go from “threatened employee” to “controller”.</p><p>Anxiety won’t disappear, but you can turn it into a clear direction for action.</p><h2 id="Further-Reading"><a href="#Further-Reading" class="headerlink" title="Further Reading"></a>Further Reading</h2><p><strong>Beginner (3 books)</strong></p><ul><li><em>Anxious People</em> – Understand the essence of anxiety</li><li><em>The Courage to Be Disliked</em> – Build internal control</li><li><em>Essentialism: The Disciplined Pursuit of Less</em> – Find what truly matters</li></ul><p><strong>Advanced (4 books)</strong></p><ul><li><em>Sapiens: A Brief History of Humankind</em> – Understand AI’s long-term impact on careers</li><li><em>Antifragile: Things That Gain from Disorder</em> – Thrive in uncertainty</li><li><em>Flow: The Psychology of Optimal Experience</em> – Build control at work</li><li><em>Peak: Secrets from the New Science of Expertise</em> – Build irreplaceable skills</li></ul><p><strong>Academic (3 books)</strong></p><ul><li><em>Thinking, Fast and Slow</em> – Understand decision-making systems</li><li><em>Rational Choice in an Uncertain World</em> – Respond rationally to uncertainty</li><li><em>Workplace Psychology</em> – Systematic research on workplace anxiety</li></ul><p>Anxiety is a signal, not an enemy. It’s reminding you: It’s time to rebuild your sense of control.</p><hr><p><strong>Related Articles</strong></p><ul><li><a href="https://liclaw.tech/2026/04/15/ai-agent-harness-core-dilemma/">The Core Dilemma Every AI Agent Creator Faces</a></li></ul>]]>
    </content>
    <id>https://liclaw.tech/2026/04/15/how-to-beat-ai-anxiety/</id>
    <link href="https://liclaw.tech/2026/04/15/how-to-beat-ai-anxiety/"/>
    <published>2026-04-15T05:16:06.000Z</published>
    <summary>The real cure for workplace AI anxiety isn't learning more tech—it's rebuilding your sense of control. Here's what actually works.</summary>
    <title>How to Beat AI Anxiety in the Workplace: A No-BS Guide for Worn-Out Office Drones</title>
    <updated>2026-04-15T10:36:32.997Z</updated>
  </entry>
</feed>
