<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Wei Zhang</title>
    <description>The latest articles on DEV Community by Wei Zhang (@weizhang_dev).</description>
    <link>https://dev.to/weizhang_dev</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3830370%2Fb0f862f4-fe45-4d43-ae9e-43cc220f2540.png</url>
      <title>DEV Community: Wei Zhang</title>
      <link>https://dev.to/weizhang_dev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/weizhang_dev"/>
    <language>en</language>
    <item>
      <title>The Best Camera Is the One You Have — And the Same Goes for AI Tools</title>
      <dc:creator>Wei Zhang</dc:creator>
      <pubDate>Thu, 26 Mar 2026 09:52:25 +0000</pubDate>
      <link>https://dev.to/weizhang_dev/the-best-camera-is-the-one-you-have-and-the-same-goes-for-ai-tools-ki</link>
      <guid>https://dev.to/weizhang_dev/the-best-camera-is-the-one-you-have-and-the-same-goes-for-ai-tools-ki</guid>
      <description>&lt;h1&gt;
  
  
  The Best Camera Is the One You Have — And the Same Goes for AI Tools
&lt;/h1&gt;

&lt;p&gt;The most upvoted post on r/filmmakers this week wasn't about a new camera release or a festival win. It was someone asking: "Why aren't we all just buying our dream cameras from seven years ago?"&lt;/p&gt;

&lt;p&gt;228 upvotes. 73 comments. And almost every single reply said some version of the same thing: the gear doesn't make the film, you do. The best camera is the one you already own.&lt;/p&gt;

&lt;p&gt;I've been thinking about that post all week because I'm watching the exact same anxiety play out in AI video tools — and it's costing creators the same thing it always has.&lt;/p&gt;

&lt;h2&gt;
  
  
  The camera version of this story
&lt;/h2&gt;

&lt;p&gt;The top comment on that post, with 137 upvotes, was from someone who bought a Blackmagic URSA Mini 4K in 2016. Eight years later, still using it. Still happy with the footage. Still getting hired.&lt;/p&gt;

&lt;p&gt;Another comment, 92 upvotes: "All the employers are gear snobs. I went into an interview and they asked what camera I shoot on before they asked to see my reel."&lt;/p&gt;

&lt;p&gt;The thread is full of people who spent years chasing the next body, the next lens, the next codec — and then realized the footage from their "outdated" camera was already good enough. The gap was never the sensor. It was lighting, composition, and knowing what story they were trying to tell.&lt;/p&gt;

&lt;p&gt;Nobody in that thread said "I upgraded my camera and my films got better." Not one person.&lt;/p&gt;

&lt;h2&gt;
  
  
  Now replace "camera" with "AI tool"
&lt;/h2&gt;

&lt;p&gt;Every week there's a new AI video tool that's supposedly the one that changes everything. I've watched this cycle repeat for over a year now.&lt;/p&gt;

&lt;p&gt;Sora was going to replace editors. Then it shut down. Runway Gen-3 was the breakthrough. Then Gen-4 came out and everyone moved on. Kling got hyped for a month. Seedance had its moment. Pika keeps iterating. Each launch follows the same pattern: stunning demo, breathless coverage, creators scrambling to learn it, and then three weeks later everyone's waiting for the next one.&lt;/p&gt;

&lt;p&gt;I know because I did this myself. In a three-month stretch last year I tested four different tools seriously — installed them, watched the tutorials, tried them on real projects. At the end of those three months I'd spent more time learning tools than making content. My actual output dropped. I was so busy chasing the "best" AI tool that I stopped editing.&lt;/p&gt;

&lt;p&gt;The parallel to camera gear anxiety is almost embarrassing once you see it. Different technology, identical behavior. Chase the new thing, feel behind when the next new thing drops, repeat until you've spent all your creative energy on tool selection instead of creative work.&lt;/p&gt;

&lt;h2&gt;
  
  
  What actually worked when I stopped switching
&lt;/h2&gt;

&lt;p&gt;About two months ago I made a decision that felt boring at the time: I picked my tools and stopped looking at new ones.&lt;/p&gt;

&lt;p&gt;For AI-assisted editing I settled on NemoVideo for transcript-based rough cuts and assembly. Not because it's the flashiest tool — because I already knew how to use it and it saved me about three hours per project on the mechanical work. For AI-generated footage I use one tool for B-roll and atmospheric shots. That's it. When a new tool launches, I read about it and move on.&lt;/p&gt;

&lt;p&gt;The result was immediate. My output nearly doubled in the first month. Not because the tools got better, but because I stopped spending half my week evaluating tools and started spending it on the work itself. More time on pacing decisions. More time on sound design choices. More time on the parts that actually make a video good — the parts no AI tool handles for you regardless of which one you pick.&lt;/p&gt;

&lt;p&gt;It turns out the bottleneck was never the tool. It was me, constantly resetting instead of building momentum.&lt;/p&gt;

&lt;h2&gt;
  
  
  The math nobody talks about
&lt;/h2&gt;

&lt;p&gt;Every time you switch tools, you lose about two weeks of productive work. A week learning the new interface, a week getting back to the speed you had with the old one. Switch four times a year and you've burned two months. Switch every time Twitter tells you something is a game-changer and you've burned half your year on evaluation instead of execution. I've seen creators with beautiful demo reels of five different AI tools and zero finished client projects.&lt;/p&gt;

&lt;p&gt;Meanwhile, the person who picked a "good enough" tool in January and just kept using it has shipped twelve projects while you shipped four and tested six tools.&lt;/p&gt;

&lt;p&gt;This is the same math that applies to cameras. The filmmaker still shooting on that 2016 Blackmagic has eight years of muscle memory with that body. They know exactly how it behaves in low light, how the colors grade, what its limitations are and how to work around them. That familiarity is worth more than any spec sheet upgrade. You can't shortcut it by switching to the "better" model every quarter.&lt;/p&gt;

&lt;h2&gt;
  
  
  The uncomfortable conclusion
&lt;/h2&gt;

&lt;p&gt;The AI video tool space wants you to believe you need the newest thing. Every launch is positioned as the moment everything changes. And some of them are genuinely impressive — the quality improvements I wrote about last week are real.&lt;/p&gt;

&lt;p&gt;But quality of the tool has never been what separates good work from bad work. Taste does. Judgment does. Knowing when to cut, when to hold, when to let a moment breathe — that's the actual skill, and no tool upgrade gives it to you.&lt;/p&gt;

&lt;p&gt;My workflow now is deliberately boring: NemoVideo for the assembly grunt work, one AI tool for B-roll, and the rest is me in the timeline making decisions. It's not exciting. But I'm finishing things, which is more than I could say when I was tool-hopping.&lt;/p&gt;

&lt;p&gt;That r/filmmakers thread had one reply that stuck with me. Someone wrote: "I stopped upgrading and started shooting more."&lt;/p&gt;

&lt;p&gt;That's it. That's the whole lesson. Stop upgrading. Start editing. The best tool is the one that ships.&lt;/p&gt;




</description>
      <category>ai</category>
      <category>video</category>
      <category>productivity</category>
      <category>beginners</category>
    </item>
    <item>
      <title>AI Video Just Crossed the 'I'd Watch It' Line — What Changed and What Still Hasn't</title>
      <dc:creator>Wei Zhang</dc:creator>
      <pubDate>Thu, 26 Mar 2026 08:48:41 +0000</pubDate>
      <link>https://dev.to/weizhang_dev/ai-video-just-crossed-the-id-watch-it-line-what-changed-and-what-still-hasnt-o88</link>
      <guid>https://dev.to/weizhang_dev/ai-video-just-crossed-the-id-watch-it-line-what-changed-and-what-still-hasnt-o88</guid>
      <description>&lt;h1&gt;
  
  
  AI Video Just Crossed the "I'd Watch It" Line — What Changed and What Still Hasn't
&lt;/h1&gt;

&lt;p&gt;Something happened on r/aivideo this week that I almost missed.&lt;/p&gt;

&lt;p&gt;Three days in a row, AI-generated video posts crossed 1,000 upvotes. A kung fu fight scene hit 1,400. A water physics clip broke 1,800. A Spiderman homage reached 3,200. That's not unusual by itself — viral AI clips have been around for a year. What caught me off guard was the comments.&lt;/p&gt;

&lt;p&gt;The top comment on the kung fu clip, with 263 upvotes, wasn't "cool tech demo." It was "I'd watch it."&lt;/p&gt;

&lt;p&gt;That's a line I didn't expect to see crossed this soon.&lt;/p&gt;

&lt;h2&gt;
  
  
  What actually changed
&lt;/h2&gt;

&lt;p&gt;I've been testing AI video tools on real projects for about 14 months now, and three things are genuinely different from where we were six months ago.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Motion doesn't look like jello anymore.&lt;/strong&gt; The water physics in that diving clip would have been impossible in mid-2025. Back then every fluid simulation looked like someone poured syrup in zero gravity. Now the splash timing, the way light refracts through moving water — it's not perfect, but it's past the uncanny valley for short clips.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Faces hold together within a single shot.&lt;/strong&gt; I used to get warped jawlines and drifting eye spacing in maybe 60% of generations. That's dropped to maybe 20-30% depending on the tool and the angle. Front-facing medium shots are pretty reliable now. Profile views and wide angles still break down. But for the most common framing in short-form content — someone talking to camera, waist up — it works more often than it fails now.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Style transfer got real.&lt;/strong&gt; This one surprised me the most. That Spiderman clip isn't just "a person in a spider suit." The tool understood what a Sam Raimi Spider-Man looks like versus what a Miles Morales animation looks like. A year ago, asking for a specific visual style gave you vague approximations. Now it's getting close enough that people are debating copyright instead of laughing at the output.&lt;/p&gt;

&lt;h2&gt;
  
  
  What hasn't changed at all
&lt;/h2&gt;

&lt;p&gt;Here's the thing nobody in those comment sections is talking about: every single one of those viral clips is under 15 seconds. Not one is over 30.&lt;/p&gt;

&lt;p&gt;And that's not a coincidence — it's the wall.&lt;/p&gt;

&lt;p&gt;Character consistency across shots is still broken. I wrote about this last week after testing Runway, Kling, Seedance, and Pika on the same project. Same character, two consecutive shots, 15-20 regenerations to get something close. Skin tone drifts between cuts. Hair changes length. Clothing shifts color. One tool gave me a character who aged about ten years between shot one and shot two.&lt;/p&gt;

&lt;p&gt;Controllability is the other gap nobody mentions. You can generate "a person walking down a street" but you can't say "turn their head left, pause, then look down at their phone." The tools generate motion, they don't follow direction. For a 10-second mood clip that's fine. For anything with narrative structure, it's a dealbreaker.&lt;/p&gt;

&lt;p&gt;So we've got tools that can produce stunning individual moments but can't string two of them together coherently. That's a very specific kind of progress.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where this actually matters right now
&lt;/h2&gt;

&lt;p&gt;Last week I tested something I'd been putting off. I needed B-roll for a client project — atmospheric city shots, some abstract transitions, a couple of moody interior clips. Instead of digging through stock footage for an hour, I generated 5 clips with AI. Three of them made it into the final cut.&lt;/p&gt;

&lt;p&gt;The client didn't notice. Didn't ask. The footage just worked because B-roll doesn't need character consistency or precise controllability. It needs mood, texture, and motion that doesn't distract. AI can do that now. Six months ago, the motion artifacts would have been immediately obvious — that strange wobble in the highlights, the way shadows would jump between frames. That's mostly gone now, at least for atmospheric stuff.&lt;/p&gt;

&lt;p&gt;But here's what I didn't use AI for: the interview cuts, the narrative pacing, the emotional arc of the piece. That was still me in the timeline, making decisions about when to cut, how long to hold a reaction shot, where to let silence breathe. I used NemoVideo to handle the assembly and rough cuts from the transcript, which saved me a few hours on the mechanical work. But the creative decisions were mine.&lt;/p&gt;

&lt;p&gt;That split — AI for raw material, editing tools for assembly and judgment — is where the real workflow is forming. Not AI replacing the editor, but AI changing what the editor spends time on.&lt;/p&gt;

&lt;h2&gt;
  
  
  The gap between "I'd watch it" and "I'd ship it"
&lt;/h2&gt;

&lt;p&gt;Here's what I keep coming back to.&lt;/p&gt;

&lt;p&gt;"I'd watch it" means: this is visually impressive and entertaining for 12 seconds on my phone while I'm scrolling.&lt;/p&gt;

&lt;p&gt;"I'd ship it" means: I would put this in a project with my name on it, send it to a client, and stake my professional reputation on it.&lt;/p&gt;

&lt;p&gt;Those are completely different bars. "I'd watch it" requires quality within a single continuous shot. "I'd ship it" requires consistency across shots, controllable direction, and reliable reproduction — generate the same character twice and get the same character.&lt;/p&gt;

&lt;p&gt;Crossing the "I'd watch it" line took about 18 months from Sora's first demo to this week's r/aivideo posts. Crossing the "I'd ship it" line is going to take longer because the problems are architecturally harder. Current models don't maintain persistent identity across generations. That's not a training data problem — it's a fundamental gap in how these systems represent characters and scenes.&lt;/p&gt;

&lt;p&gt;My practical advice for anyone editing video right now: start using AI-generated B-roll where it fits. Mood shots, transitions, establishing shots, abstract textures. Save yourself the stock footage hunt. For everything else, use tools that help you edit faster — NemoVideo for transcript-based rough cuts, traditional NLEs for the fine work. Let AI handle the parts where "close enough" is good enough, and keep your hands on the parts where it isn't.&lt;/p&gt;

&lt;p&gt;The 1,000-upvote clips are real progress. But until I can generate shot two and have it match shot one, "I'd watch it" is as far as we go.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;tags: ai, video, productivity, creative&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>video</category>
      <category>machinelearning</category>
      <category>productivity</category>
    </item>
    <item>
      <title>The Character Consistency Problem: Why Every AI Video Tool Still Fails at the One Thing That Matters Most</title>
      <dc:creator>Wei Zhang</dc:creator>
      <pubDate>Thu, 26 Mar 2026 04:24:04 +0000</pubDate>
      <link>https://dev.to/weizhang_dev/the-character-consistency-problem-why-every-ai-video-tool-still-fails-at-the-one-thing-that-3386</link>
      <guid>https://dev.to/weizhang_dev/the-character-consistency-problem-why-every-ai-video-tool-still-fails-at-the-one-thing-that-3386</guid>
      <description>&lt;h1&gt;
  
  
  The Character Consistency Problem: Why Every AI Video Tool Still Fails at the One Thing That Matters Most
&lt;/h1&gt;

&lt;p&gt;Every AI video demo you've ever seen has something in common: it's a single shot. One clip. Five seconds of a character doing something impressive, posted with a caption like "this changes everything."&lt;/p&gt;

&lt;p&gt;What you never see in those demos is the same character in a second shot. Or a third. Or eight shots across a 60-second video where they need to look like the same person wearing the same clothes in the same lighting. That's not an oversight — it's because the tools can't do it yet. And this single problem is the reason AI video hasn't crossed over from impressive tech demo to production tool.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Actually Happens When You Try
&lt;/h2&gt;

&lt;p&gt;I tested this properly last month. A client wanted a 60-second explainer with a spokesperson character appearing in 8 different scenes — office, warehouse, outdoor, conference room, and so on. Standard corporate video stuff. The brief specifically said "consistent character throughout" because they wanted it to feel like a real person presenting.&lt;/p&gt;

&lt;p&gt;I tried four tools: Runway, Kling, Seedance, and Pika. Same reference images, same prompts adjusted for each platform's syntax. Here's what happened.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Runway&lt;/strong&gt; gave me the most photorealistic output but the character drifted noticeably between scenes. Hair length changed, skin tone shifted warmer in outdoor scenes, and the face structure was slightly different at wider angles. I generated about 18 takes per scene before getting something passable, and even then the warehouse scene and the office scene looked like siblings rather than the same person.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Kling&lt;/strong&gt; handled face consistency better than the others, especially with their reference image pinning. But the clothing was a problem — the character's jacket changed shade between nearly every scene and completely changed style in two of them. I spent an afternoon trying different prompt combinations and got it to about 80% consistent. Close, but a client would absolutely notice.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Seedance&lt;/strong&gt; had the best motion quality but the worst consistency. The character looked like a completely different person in 3 out of 8 scenes. I gave up after 22 regenerations on the outdoor shot.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pika&lt;/strong&gt; was somewhere in the middle. Decent face consistency if I kept the angles similar, but the moment I needed a different camera position — like switching from a medium shot to a close-up — the character shifted enough to break continuity.&lt;/p&gt;

&lt;p&gt;Average across all four tools: about 15-20 regenerations per scene to get something that was &lt;em&gt;close enough&lt;/em&gt;, and even then I wouldn't call any of them truly consistent across the full sequence.&lt;/p&gt;

&lt;p&gt;The client ended up hiring a real person for the shoot. Half a day of filming, done.&lt;/p&gt;

&lt;h2&gt;
  
  
  Workarounds That Sort of Work
&lt;/h2&gt;

&lt;p&gt;The AI video community has come up with some creative hacks for this. None of them fully solve the problem, but some get you closer than others.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reference image pinning&lt;/strong&gt; is the most straightforward. You feed the tool a set of images of your character from multiple angles and it tries to match them. Kling does this best right now. The limitation is that pinning works well for similar poses but falls apart when you need the character doing very different things across scenes — sitting versus walking versus gesturing at a whiteboard. The more the pose diverges from your reference images, the more the character drifts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;LoRA fine-tuning&lt;/strong&gt; is the technical option. You train a lightweight model on 20-30 images of your character and it learns their specific features. This produces the most consistent results I've seen, but the barrier is real: you need to understand model training, you need compute resources, and each character takes a few hours to train. For a freelancer with a one-off project, the setup time kills the value.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Separate character and background generation&lt;/strong&gt; is a workflow I saw on r/aivideo recently that's clever. You generate your character in a neutral environment, extract them, generate backgrounds separately, and composite them together. It's essentially doing in post what the AI tools fail to do in one pass. More work, but you get much better control over each element. The tradeoff is that integration — matching lighting, shadows, perspective between the character and background — becomes a manual compositing job.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Just shoot real footage and use AI for editing.&lt;/strong&gt; This sounds like a cop-out but it's honestly the most reliable approach for anything that needs character consistency. Real footage gives you perfect consistency by default because it's the same actual person. The AI part moves to editing — rough cuts, subtitles, color matching, reformatting for different platforms. Tools like NemoVideo handle that workflow well: you feed it real footage and use chat-based commands to edit, rather than asking AI to generate everything from scratch. The character consistency problem simply doesn't exist when you start with real footage.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Problem Is Fundamentally Hard
&lt;/h2&gt;

&lt;p&gt;Character consistency isn't a bug that will be fixed in the next update. It's a core architectural challenge.&lt;/p&gt;

&lt;p&gt;Current video models work by predicting frames based on text descriptions and latent representations. Each generation pass is essentially independent — the model doesn't have a persistent understanding of "this is Character A and they should always look exactly like this." It's approximating from a description every single time.&lt;/p&gt;

&lt;p&gt;This is why single shots look great. Within one continuous generation, the model maintains local coherence. The character stays consistent for 3-5 seconds because each frame is predicted from the adjacent frames. But start a new generation — different scene, different prompt — and you're rolling the dice on whether the model's interpretation of "30-year-old woman with brown hair in a blue jacket" matches its interpretation from the last generation. Usually it's close. Close isn't consistent enough for professional work.&lt;/p&gt;

&lt;p&gt;Building true persistent character identity into these models would require something closer to a structured scene graph — an explicit representation of what each character looks like that persists across generations. Some research papers are exploring this but I haven't seen it in any production tool. My honest estimate is 12-18 months before any major platform solves this well enough for consistent use in client work, and even that might be optimistic.&lt;/p&gt;

&lt;h2&gt;
  
  
  What This Means Right Now
&lt;/h2&gt;

&lt;p&gt;If your project needs character consistency across multiple shots — and most real projects do — you have two practical options today.&lt;/p&gt;

&lt;p&gt;Option one: shoot real footage and use AI for editing assistance. NemoVideo, Descript, DaVinci Resolve with AI plugins — these tools accelerate the editing workflow without introducing the consistency problem. You trade the dream of fully AI-generated video for the reality of AI-assisted production, which is less exciting but actually works.&lt;/p&gt;

&lt;p&gt;Option two: plan your AI-generated content around single shots. Social media clips, thumbnail generation, concept visualization, mood boards. Anything where each piece stands alone and doesn't need to match anything else. That's where current tools genuinely deliver.&lt;/p&gt;

&lt;p&gt;The day AI video tools solve character consistency is the day they become real production tools. We're not there yet, and pretending otherwise is how you end up regenerating the same scene 22 times and hiring a real person anyway.&lt;/p&gt;




</description>
      <category>ai</category>
      <category>video</category>
      <category>machinelearning</category>
      <category>productivity</category>
    </item>
    <item>
      <title>I Turned a 2-Hour Podcast into 20 Short Clips: Here's the Full Workflow (and Where AI Actually Helped)</title>
      <dc:creator>Wei Zhang</dc:creator>
      <pubDate>Thu, 26 Mar 2026 04:15:11 +0000</pubDate>
      <link>https://dev.to/weizhang_dev/i-turned-a-2-hour-podcast-into-20-short-clips-heres-the-full-workflow-and-where-ai-actually-156b</link>
      <guid>https://dev.to/weizhang_dev/i-turned-a-2-hour-podcast-into-20-short-clips-heres-the-full-workflow-and-where-ai-actually-156b</guid>
      <description>&lt;h1&gt;
  
  
  I Turned a 2-Hour Podcast into 20 Short Clips: Here's the Full Workflow (and Where AI Actually Helped)
&lt;/h1&gt;

&lt;p&gt;A client sent me a 2-hour podcast episode last month and asked for 20 short clips — Reels, Shorts, TikToks, the whole spread. Different aspect ratios, subtitles, branded templates, color-matched, ready to publish across five platforms.&lt;/p&gt;

&lt;p&gt;A year ago this would have been a full week of work. I wanted to see how much AI could actually cut that down. Not in theory — in practice, with real client footage, real deadlines, and real quality standards.&lt;/p&gt;

&lt;p&gt;Final answer: 3 days instead of 7. But not in the way I expected.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Transcription and Finding the Good Parts
&lt;/h2&gt;

&lt;p&gt;The first job was turning two hours of audio into text and finding the 20 moments worth clipping. Transcription used to be the most tedious part of this entire process — I'd spend 20 minutes per hour of footage just fixing auto-generated captions. Now it takes about 45 seconds to get a transcript that's maybe 95% accurate. I ran the episode through Descript, fixed a handful of proper nouns and technical terms, and had a clean transcript in under 10 minutes.&lt;/p&gt;

&lt;p&gt;Finding the actual clip-worthy moments was where things got interesting. I asked the AI to flag "high-engagement segments" and it returned 30 candidates. About 20 of them were fine. The other 10 were technically interesting quotes but had zero standalone value — the kind of thing that makes sense in context but means nothing as a 45-second clip on Instagram.&lt;/p&gt;

&lt;p&gt;This is the pattern I keep seeing: AI is excellent at identifying &lt;em&gt;what was said&lt;/em&gt; but terrible at judging &lt;em&gt;what will perform&lt;/em&gt;. It flagged a detailed technical explanation about microphone placement as a "high-engagement moment" because it had lots of specific information. Meanwhile it missed a 30-second story about a guest's worst interview experience that was obviously the most shareable moment in the entire episode. I had to manually review all 30 candidates and make the final picks myself.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Time: 40 minutes (AI-assisted) vs ~3.5 hours (fully manual)&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Rough Cuts and Going Vertical
&lt;/h2&gt;

&lt;p&gt;With 20 segments identified, I needed to cut them from the timeline and reformat everything for vertical. This is where batch processing made the biggest difference.&lt;/p&gt;

&lt;p&gt;I used NemoVideo for the rough cuts — described each clip by timestamp and target duration in plain language, and it handled the extraction and initial framing. "Cut from 34:12 to 35:45, crop to 9:16, keep the speaker centered" repeated twenty times is exactly the kind of repetitive work where chat-based editing shines. What would have been an hour of timeline scrubbing took about 15 minutes.&lt;/p&gt;

&lt;p&gt;The vertical reframing worked well for single-speaker segments. The tool tracked the active speaker and kept them centered, which saved me from manually keyframing a crop for each clip.&lt;/p&gt;

&lt;p&gt;But the two-person conversation clips were a mess. Every time the speakers talked over each other or one person gestured into the other's frame, the tracking would jump between them or settle on the wrong person entirely. I ended up manually fixing the framing on about 6 of the 20 clips. Not a dealbreaker, but worth knowing if your source footage has multiple speakers on camera.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Time: 45 minutes (AI-assisted) vs ~2.5 hours (manual crop and cut)&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Subtitles and Brand Packaging
&lt;/h2&gt;

&lt;p&gt;Subtitles were the smoothest part of the entire process. The AI-generated captions from the transcript were already 92% accurate, and since I'd cleaned up the transcript in Step 1, the subtitle timing was nearly perfect out of the box. I spent maybe 20 minutes fixing edge cases — words that broke across lines awkwardly, a few timing misalignments where the speaker paused mid-sentence.&lt;/p&gt;

&lt;p&gt;Brand packaging was more mixed. The client had specific colors, fonts, a lower-third template, and an intro bumper that needed to go on every clip. Applying the template across all 20 clips in batch worked great for the simple stuff — colors, fonts, logo placement. But the lower-third positioning needed adjustment on about half the clips because the speaker's head was in a different spot in each one. Batch automation got me 60% of the way there, manual tweaking handled the rest.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Time: 1.5 hours (AI-assisted) vs ~5 hours (manual subtitling + templating)&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Color Matching and Final Review
&lt;/h2&gt;

&lt;p&gt;The podcast was shot with two cameras that clearly had different white balance settings. AI color matching got both cameras to a consistent baseline in about 8 minutes across all 20 clips. I tweaked contrast and skin tones manually after that, but the initial match eliminated what used to be 30-40 minutes of scoping between cameras.&lt;/p&gt;

&lt;p&gt;Final review is the step that AI cannot help with at all, and I don't think it will anytime soon. I watched every single clip start to finish, checking for subtitle errors, awkward cuts, branding consistency, and whether each clip actually made sense as a standalone piece. This took about 2 hours and I caught problems in almost a third of them — a subtitle that said "their" instead of "there," a clip that started mid-sentence because the AI timestamp was off by two seconds, a lower-third that covered the guest's face in one shot.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Time: 2.5 hours (unavoidable manual review)&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Honest Math
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Step&lt;/th&gt;
&lt;th&gt;AI-Assisted&lt;/th&gt;
&lt;th&gt;Fully Manual&lt;/th&gt;
&lt;th&gt;Saved&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Transcription + clip selection&lt;/td&gt;
&lt;td&gt;40 min&lt;/td&gt;
&lt;td&gt;3.5 hrs&lt;/td&gt;
&lt;td&gt;2 hrs 50 min&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rough cuts + vertical reframe&lt;/td&gt;
&lt;td&gt;45 min&lt;/td&gt;
&lt;td&gt;2.5 hrs&lt;/td&gt;
&lt;td&gt;1 hr 45 min&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Subtitles + brand templates&lt;/td&gt;
&lt;td&gt;1.5 hrs&lt;/td&gt;
&lt;td&gt;5 hrs&lt;/td&gt;
&lt;td&gt;3 hrs 30 min&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Color match + final review&lt;/td&gt;
&lt;td&gt;2.5 hrs&lt;/td&gt;
&lt;td&gt;3.5 hrs&lt;/td&gt;
&lt;td&gt;1 hr&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Total&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~5.5 hrs&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~14.5 hrs&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~9 hrs&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Spread across three working days with client feedback loops, that's 3 days instead of 7. Real savings, not theoretical.&lt;/p&gt;

&lt;p&gt;The tools that did the heavy lifting: Descript for transcription, NemoVideo for batch rough cuts and reframing, and DaVinci Resolve for final color and export.&lt;/p&gt;

&lt;h2&gt;
  
  
  What AI Still Can't Do
&lt;/h2&gt;

&lt;p&gt;I could write another article about what worked, but the more useful list is what didn't.&lt;/p&gt;

&lt;p&gt;AI cannot tell you which moments will perform on social media. It can find quotes and highlight reels, but it has no sense of what makes someone stop scrolling. That judgment is still entirely yours.&lt;/p&gt;

&lt;p&gt;AI cannot handle multi-speaker framing reliably. The second you have two people in frame with overlapping dialogue, every auto-framing tool I've tested gets confused. Plan on manual fixes for 25-30% of your clips if your source has multiple speakers.&lt;/p&gt;

&lt;p&gt;AI cannot do your final QA pass. I've tried trusting the output without a manual review exactly once. The client found a subtitle error in the first clip they watched. Never again.&lt;/p&gt;

&lt;p&gt;Three days instead of seven is genuinely useful. But the three days that remain are the ones that require actual editorial judgment — and those aren't going anywhere.&lt;/p&gt;




</description>
      <category>ai</category>
      <category>video</category>
      <category>productivity</category>
      <category>podcast</category>
    </item>
    <item>
      <title>Every AI Video Demo Is Lying to You (And What Actually Works in Production)</title>
      <dc:creator>Wei Zhang</dc:creator>
      <pubDate>Thu, 26 Mar 2026 00:48:18 +0000</pubDate>
      <link>https://dev.to/weizhang_dev/every-ai-video-demo-is-lying-to-you-and-what-actually-works-in-production-59jl</link>
      <guid>https://dev.to/weizhang_dev/every-ai-video-demo-is-lying-to-you-and-what-actually-works-in-production-59jl</guid>
      <description>&lt;h1&gt;
  
  
  Every AI Video Demo Is Lying to You (And What Actually Works in Production)
&lt;/h1&gt;

&lt;p&gt;I've been a video editor for about five years. In the last twelve months, I've tested pretty much every AI video tool that's crossed my feed — and I'm tired of the gap between what these tools promise and what they actually deliver when a client is waiting.&lt;/p&gt;

&lt;p&gt;This isn't a listicle of "top 10 AI tools." This is what happened when I tried to use them for real work.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Demo Problem
&lt;/h2&gt;

&lt;p&gt;Scroll through r/aivideo on any given day and you'll see incredible clips. A diver gliding through impossible underwater geometry. Cinematic one-shots that look like they cost $50K to produce. "Absolute cinema," the comments say.&lt;/p&gt;

&lt;p&gt;And they're right — as isolated clips, the output is stunning. The problem starts when you try to make something &lt;em&gt;with&lt;/em&gt; these tools rather than just &lt;em&gt;from&lt;/em&gt; them.&lt;/p&gt;

&lt;p&gt;Here's what I mean. A client needed a 90-second product video last month. Simple brief: show the product in three environments, maintain consistent branding, match their existing color palette. I figured I'd try the AI route since the demos made it look effortless.&lt;/p&gt;

&lt;p&gt;Three days later I had:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;47 generated clips, none with consistent lighting&lt;/li&gt;
&lt;li&gt;A product that changed shape slightly between every shot&lt;/li&gt;
&lt;li&gt;Zero usable footage that matched the brand guidelines&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I ended up shooting it traditionally in half a day. The AI "shortcut" cost me three days and a very awkward status update to the client.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Demos Always Look Better Than Products
&lt;/h2&gt;

&lt;p&gt;There's a simple reason every AI video demo looks incredible: demos have no constraints.&lt;/p&gt;

&lt;p&gt;Nobody's demo reel needs to match a brand book. Nobody's demo needs consistent characters across 15 shots. Nobody's demo gets reviewed by a client who notices the logo is slightly different in frame 847.&lt;/p&gt;

&lt;p&gt;Professional video work is almost entirely about consistency and control — the exact two things current AI generation is worst at. You can get one great frame. Getting 2,700 frames (that's 90 seconds at 30fps) that all look like they belong together? That's where everything falls apart.&lt;/p&gt;

&lt;p&gt;The Sora shutdown last week proved this at scale. OpenAI reportedly burned through compute generating clips that looked great as Twitter posts but couldn't sustain a two-minute coherent scene. If they couldn't make it work with billions in infrastructure, your $20/month subscription probably isn't getting there either.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Actually Works (The Boring Stuff Nobody Demos)
&lt;/h2&gt;

&lt;p&gt;Here's the thing — AI &lt;em&gt;is&lt;/em&gt; genuinely useful in video production. Just not the way the demos suggest. The tools that have stuck in my daily workflow are all on the editing side, not the creation side:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Auto-transcription and subtitle generation.&lt;/strong&gt; This used to take me 20 minutes per minute of footage. Now it takes about 45 seconds with decent accuracy. I still fix errors but the baseline is good enough that it's a net time save every single project.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rough cut from scripts.&lt;/strong&gt; I write markers in my script, the tool matches them to footage based on transcript and visual content, and I get a rough cut that's maybe 60% of the way there. Still needs heavy manual work but it kills the blank-NLE-project problem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Color matching between cameras.&lt;/strong&gt; Shot a conference last month with three different camera setups. The AI color matcher got all three to a consistent baseline in about ten minutes. Manual grading from there but it killed the tedious first pass.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Noise reduction and upscaling.&lt;/strong&gt; Old footage, badly lit interviews, phone recordings from clients — AI handles these better than any manual approach I've tried. Topaz has been in my toolkit for two years and it's one of the few AI tools I'd genuinely miss.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Chat-based editing interfaces.&lt;/strong&gt; This one surprised me. Tools like NemoVideo let you tell it what you want in plain language instead of hunting through menus. "Trim the first 15 seconds, add a fade, match the color to the previous clip" — and it just does it. Not flashy, but it's cut my editing time on routine projects by roughly a third.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Gap Nobody Talks About
&lt;/h2&gt;

&lt;p&gt;The AI video industry has a positioning problem. All the money and attention goes toward generation — making something from nothing. That's the sexy demo. That's what gets 1000 upvotes on Reddit.&lt;/p&gt;

&lt;p&gt;But the actual market need is editing assistance — making existing footage better, faster, cheaper. The editors who are saving real time with AI aren't posting demos. They're just quietly getting projects done in three days instead of five.&lt;/p&gt;

&lt;p&gt;I think we're going to see this split widen. The generation side will keep producing incredible demos and keep failing in production. The editing side will keep being boring and keep actually working.&lt;/p&gt;

&lt;h2&gt;
  
  
  My Actual Toolkit (March 2026)
&lt;/h2&gt;

&lt;p&gt;For anyone who's curious what I'm actually using day-to-day, here's the honest list:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;DaVinci Resolve&lt;/strong&gt; — Primary NLE, free tier handles 90% of my needs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Topaz Video AI&lt;/strong&gt; — Noise reduction and upscaling, $199 one-time&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Descript&lt;/strong&gt; — Transcription-based editing for interview content&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NemoVideo&lt;/strong&gt; — Chat-based editing for routine projects, genuinely surprised by how much time it saves&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;After Effects&lt;/strong&gt; — Motion graphics, some things still need manual keyframing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Notice what's not on the list: any AI generation tool. Not because they can't make cool clips. Because I can't use cool clips that change the product's shape between shots.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Bottom Line
&lt;/h2&gt;

&lt;p&gt;If you're evaluating AI video tools for actual production work, ignore the demos. Ask three questions instead:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Can it maintain consistency across an entire project? (Not one clip — an entire project.)&lt;/li&gt;
&lt;li&gt;Does it save time on tasks I already do, or does it create new tasks I didn't have before?&lt;/li&gt;
&lt;li&gt;Would I trust this output enough to send it to a client without manually checking every frame?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If the answer to any of those is no, you're looking at a toy, not a tool. And right now, most AI generation products are still toys. The editing tools? Some of those are genuinely ready.&lt;/p&gt;




&lt;p&gt;tags: ai, video, productivity, tools&lt;/p&gt;

</description>
      <category>ai</category>
      <category>video</category>
      <category>productivity</category>
      <category>tools</category>
    </item>
    <item>
      <title>Why Sora Failed: What Actually Works in AI Video Editing Right Now</title>
      <dc:creator>Wei Zhang</dc:creator>
      <pubDate>Wed, 25 Mar 2026 21:29:36 +0000</pubDate>
      <link>https://dev.to/weizhang_dev/why-sora-failed-what-actually-works-in-ai-video-editing-right-now-2ko</link>
      <guid>https://dev.to/weizhang_dev/why-sora-failed-what-actually-works-in-ai-video-editing-right-now-2ko</guid>
      <description>&lt;h1&gt;
  
  
  Why Sora Failed: What Actually Works in AI Video Editing Right Now
&lt;/h1&gt;

&lt;p&gt;OpenAI shut down Sora this week. Disney pulled out of their deal. And honestly? I'm not surprised at all.&lt;/p&gt;

&lt;p&gt;I've been editing video professionally for about 5 years, and I spent the last 12 months testing every AI video tool I could get my hands on. Sora included. Here's what I learned — and what I think actually matters going forward.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Demo-to-Reality Gap
&lt;/h2&gt;

&lt;p&gt;Sora's launch demos were incredible. Photorealistic cityscapes, smooth camera movements, consistent lighting. The problem was that none of that translated to actual production work.&lt;/p&gt;

&lt;p&gt;When I tried using Sora for a client's product demo back in January, the results were unusable. Character faces morphed between shots. Lighting shifted randomly mid-scene. I generated the same 10-second clip maybe 40 times trying to get two consecutive shots where the main character looked like the same person. Never got there.&lt;/p&gt;

&lt;p&gt;This wasn't just a Sora problem — Runway, Kling, Pika, they all have it. Text-to-video generation sounds revolutionary until you need to produce something a client will actually pay for.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Killed Sora Specifically
&lt;/h2&gt;

&lt;p&gt;Three things:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Compute costs were brutal.&lt;/strong&gt; Every generation burned through GPU time that OpenAI needed for their core language model business. When you're spending millions on inference for a product that most users treat as a toy, the math doesn't work.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No moat.&lt;/strong&gt; Google's Veo, Runway's Gen-3, Kling 3.0 — the space got crowded fast. Sora had first-mover hype but not first-mover advantage. By the time it launched publicly, cheaper alternatives existed that produced comparable output.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The use case was wrong.&lt;/strong&gt; Sora targeted the "type a sentence, get a video" market. But professional editors don't want to type sentences. They have footage already. They need help with the tedious parts of working with that footage.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where AI Actually Saves Me Time
&lt;/h2&gt;

&lt;p&gt;Here's the thing nobody talks about in the AI video hype cycle: the boring applications work. They've been working for over a year now.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Auto-transcription and captioning.&lt;/strong&gt; I used to spend 45 minutes manually transcribing a 10-minute interview. Now it takes 30 seconds and the accuracy is above 95%. This alone changed my workflow more than any generation tool.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rough cuts from script markers.&lt;/strong&gt; I work on interview-driven content. Being able to feed in a script and have the tool pull matching segments from 3 hours of raw footage — that saves me an entire afternoon per project.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Color matching between cameras.&lt;/strong&gt; Multi-cam shoots where one camera is slightly warmer than the other used to mean 20 minutes of manual adjustment per scene. AI handles this in seconds and gets it right maybe 85% of the time. The remaining 15% still needs manual tweaking, but 85% automation on a tedious task is genuinely useful.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Smart audio cleanup.&lt;/strong&gt; Background noise removal has gotten scary good. I had a client shoot an interview next to a construction site — two years ago that footage would've been unusable. Ran it through AI noise removal and it sounded like a studio recording.&lt;/p&gt;

&lt;p&gt;Tools like NemoVideo have been leaning into this practical direction — focusing on the editing workflow rather than generation from scratch. You tell it what you want done to existing footage instead of trying to conjure something from a text prompt. It's less flashy than "here's a video of a cat riding a skateboard through Tokyo" but it's what actually ships to clients.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where This Goes Next
&lt;/h2&gt;

&lt;p&gt;I think we're about to see a real split in the AI video space:&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;generation side&lt;/strong&gt; (text-to-video, image-to-video) will keep improving but stay limited to social media content, prototyping, and creative experimentation. It won't replace professional production workflows for at least another 3-5 years. The consistency problem is that fundamental.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;editing assistance side&lt;/strong&gt; will quietly become standard. Within 18 months, I expect auto-transcription, smart rough cuts, and AI color grading to be built into every major NLE. The standalone tools that got there first — the ones that focused on making editors faster rather than replacing them — will either get acquired or become the new standard.&lt;/p&gt;

&lt;p&gt;Sora's failure isn't proof that AI in video doesn't work. It's proof that the industry was building the wrong thing. The editors I know don't want AI to make their videos for them. They want AI to handle the 40% of their job that's repetitive so they can spend more time on the 60% that's creative.&lt;/p&gt;

&lt;p&gt;That's a less exciting pitch than "generate anything from text." But it's the one that actually works.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>video</category>
      <category>openai</category>
      <category>productivity</category>
    </item>
    <item>
      <title>ClawHub Just Changed Its Search Algorithm — Here's What I Found in the Source Code</title>
      <dc:creator>Wei Zhang</dc:creator>
      <pubDate>Mon, 23 Mar 2026 03:01:27 +0000</pubDate>
      <link>https://dev.to/weizhang_dev/clawhub-just-changed-its-search-algorithm-heres-what-i-found-in-the-source-code-1cpe</link>
      <guid>https://dev.to/weizhang_dev/clawhub-just-changed-its-search-algorithm-heres-what-i-found-in-the-source-code-1cpe</guid>
      <description>&lt;p&gt;My skill rankings crashed at 4 AM.&lt;/p&gt;

&lt;p&gt;Twelve #1 positions the night before. I checked at 4:18 AM and ten of them were gone. Two survived. The pattern was obvious once I saw it: the two survivors had their keyword directly in the slug. Everything relying on description text had vanished.&lt;/p&gt;

&lt;p&gt;I spent the next two hours in the &lt;a href="https://github.com/openclaw/clawhub" rel="noopener noreferrer"&gt;ClawHub source code&lt;/a&gt; figuring out what happened.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two commits, one explanation
&lt;/h2&gt;

&lt;p&gt;On March 22 at 18:03 UTC, ClawHub pushed commit &lt;a href="https://github.com/openclaw/clawhub/commit/801cc550ab16" rel="noopener noreferrer"&gt;&lt;code&gt;801cc55&lt;/code&gt;&lt;/a&gt; — "fix: narrow skill package catalog search." One minute later, &lt;a href="https://github.com/openclaw/clawhub/commit/9ea750852f1a" rel="noopener noreferrer"&gt;&lt;code&gt;9ea7508&lt;/code&gt;&lt;/a&gt; landed to stabilize the change.&lt;/p&gt;

&lt;p&gt;The key diff is in &lt;code&gt;convex/skills.ts&lt;/code&gt;. Before the change, search worked like this: take a query string, scan up to 200 pages of the &lt;code&gt;skillSearchDigest&lt;/code&gt; index, score every result against the query vector, return the best matches.&lt;/p&gt;

&lt;p&gt;After the change, there's a new first step:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;exactSkill&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;resolveSkillBySlugOrAlias&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;queryText&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;exactSkill&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;skill&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;exactDigest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;skillSearchDigest&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;withIndex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;by_skill&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;q&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;q&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;skillId&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;exactSkill&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;skill&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_id&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;unique&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;exactDigest&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nf"&gt;skillCatalogMatchesFilters&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;exactDigest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;exactScore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;scoreSkillCatalogResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;exactDigest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;queryText&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;exactScore&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;seen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;exactDigest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;skillId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;matches&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;score&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;exactScore&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;package&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;toPublicSkillCatalogItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;exactDigest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Search now tries to resolve the query as an exact slug first. If it finds a match, that skill gets scored and added to results before any vector scanning happens.&lt;/p&gt;

&lt;p&gt;The second change: the old paginated scan loop (up to &lt;code&gt;MAX_SKILL_CATALOG_SEARCH_SCAN_PAGES&lt;/code&gt; iterations) got replaced with a single page fetch. The constant was deleted entirely.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this actually means
&lt;/h2&gt;

&lt;p&gt;Three things changed for skill authors:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Slug match is now guaranteed.&lt;/strong&gt; If someone searches "auto-caption" and your slug is &lt;code&gt;auto-caption&lt;/code&gt;, you're in the results. Period. Before this, you depended on vector similarity catching you during the page scan. Usually it did. Sometimes it didn't — which is exactly what &lt;a href="https://github.com/openclaw/openclaw/issues/52034" rel="noopener noreferrer"&gt;issue #52034&lt;/a&gt; reported. This is genuinely good news. If you picked a descriptive slug when you first published, you just got a safety net for free.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vector-only skills got fragile.&lt;/strong&gt; My skills with keywords only in the description were scoring 1.7-1.9 through vector similarity. When the index rebuilt during the deploy, those embeddings temporarily disappeared. Slug-match skills didn't care because they hit the new exact path directly. I had a few skills that relied entirely on description keywords for certain search terms — every one of them dropped out overnight.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The scan window narrowed.&lt;/strong&gt; Removing the multi-page loop means vector search covers fewer candidates per query. If your skill's embedding sits deep in the index, it might not get scanned at all. This probably won't affect most skills, but if you're ranking on a long-tail keyword with a lot of competition, your margin just got thinner.&lt;/p&gt;

&lt;h2&gt;
  
  
  The fix took 30 minutes
&lt;/h2&gt;

&lt;p&gt;I published a version bump on one of the affected skills — no code changes, just a patch version increment. Within 30 minutes, its rankings came back. The publish triggered a fresh &lt;code&gt;skillSearchDigest&lt;/code&gt; entry, which the new single-page scan picked up immediately.&lt;/p&gt;

&lt;p&gt;I then bumped the rest. By 5:30 AM, all twelve #1 positions were restored. Some scores actually came back slightly higher than before — video editing went from 3.217 to 3.242. Not sure if that's the new scoring function being more generous or just normal variance.&lt;/p&gt;

&lt;p&gt;One thing worth mentioning: I also noticed that skills from a newer account I'd been testing with disappeared from search entirely. Not just dropped in rank — gone. Even exact slug searches returned nothing. Still not sure if that's related to the algorithm change or a separate account-trust issue. Something to watch.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd tell other skill authors
&lt;/h2&gt;

&lt;p&gt;Pick your slug carefully. Before this update, slug was already the highest-weight signal (I wrote about that in &lt;a href="https://dev.to/weizhang_dev/how-i-got-12-number-one-rankings-on-clawhub-in-5-days-7jh"&gt;my previous post&lt;/a&gt;). Now it's even more important because it has a dedicated resolution path that bypasses vector search entirely.&lt;/p&gt;

&lt;p&gt;If your rankings suddenly drop, try publishing a patch version. You're not fixing a bug — you're forcing a digest rebuild under the new scoring logic.&lt;/p&gt;

&lt;p&gt;And if you want to check where you stand right now, the search API is public:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://clawhub.ai/api/search?q=your+keyword&amp;amp;limit=10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No auth needed. The &lt;code&gt;score&lt;/code&gt; field in the response is what determines your position.&lt;/p&gt;

&lt;p&gt;The search code is &lt;a href="https://github.com/openclaw/clawhub/blob/main/convex/skills.ts" rel="noopener noreferrer"&gt;open source&lt;/a&gt;. Reading it took me two hours. It saved me from thinking my skills were broken when it was just the platform rebuilding its index.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This is part of a series on building AI video tools with OpenClaw. Previous posts: &lt;a href="https://dev.to/weizhang_dev/how-i-built-an-ai-video-editor-as-an-openclaw-skill-103j"&gt;How I Built an AI Video Editor&lt;/a&gt; | &lt;a href="https://dev.to/weizhang_dev/5-things-i-learned-wrapping-a-gui-first-api-for-ai-agents-3gep"&gt;What Broke When I Wrapped a Video API&lt;/a&gt; | &lt;a href="https://dev.to/weizhang_dev/i-use-openclaw-to-automate-my-entire-tiktok-and-reels-workflow-16od"&gt;Automating TikTok and Reels&lt;/a&gt; | &lt;a href="https://dev.to/weizhang_dev/i-reverse-engineered-4-top-video-skills-on-clawhub-heres-what-actually-drives-installs-2g24"&gt;Reverse-Engineering ClawHub's Top Video Skills&lt;/a&gt; | &lt;a href="https://dev.to/weizhang_dev/how-i-got-12-number-one-rankings-on-clawhub-in-5-days-7jh"&gt;12 #1 Rankings in 5 Days&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>openclaw</category>
      <category>showdev</category>
      <category>opensource</category>
      <category>ai</category>
    </item>
    <item>
      <title>How I Got 12 Number One Rankings on ClawHub in 5 Days</title>
      <dc:creator>Wei Zhang</dc:creator>
      <pubDate>Sun, 22 Mar 2026 22:20:51 +0000</pubDate>
      <link>https://dev.to/weizhang_dev/how-i-got-12-number-one-rankings-on-clawhub-in-5-days-7jh</link>
      <guid>https://dev.to/weizhang_dev/how-i-got-12-number-one-rankings-on-clawhub-in-5-days-7jh</guid>
      <description>&lt;p&gt;I published 13 video editing skills on ClawHub over the span of a week. For the first three days, only two appeared in search results. By day five, twelve of them held the #1 spot for their target keywords.&lt;/p&gt;

&lt;p&gt;Nothing changed about the skills themselves. Same API, same functionality, same code. What changed was how I named and described them.&lt;/p&gt;

&lt;p&gt;Here's everything I learned about ClawHub's search ranking — with real numbers from my testing.&lt;/p&gt;

&lt;h2&gt;
  
  
  The slug is everything
&lt;/h2&gt;

&lt;p&gt;ClawHub uses vector search for skill discovery. I spent two weeks querying the search API (&lt;code&gt;/api/search?q=keyword&lt;/code&gt;) with different keywords and recording scores. The pattern was consistent across 30+ queries:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If your slug contains the search keyword, you score 3.0+. If it doesn't, your ceiling is about 2.0.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here's what that looks like in practice:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Slug&lt;/th&gt;
&lt;th&gt;Query&lt;/th&gt;
&lt;th&gt;Score&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;auto-caption&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;"auto caption"&lt;/td&gt;
&lt;td&gt;3.147&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ai-video-editing&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;"video editing"&lt;/td&gt;
&lt;td&gt;3.217&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;nemo-subtitle&lt;/code&gt; (brand name)&lt;/td&gt;
&lt;td&gt;"add subtitles"&lt;/td&gt;
&lt;td&gt;1.859&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;nemo-shorts&lt;/code&gt; (brand name)&lt;/td&gt;
&lt;td&gt;"shorts maker"&lt;/td&gt;
&lt;td&gt;1.757&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The first two slugs contain the exact search term. They score 3.0+. The bottom two have brand-name slugs — they rank well because of description optimization, but they'll never break 2.0.&lt;/p&gt;

&lt;p&gt;I tested this by publishing a new skill with the slug &lt;code&gt;auto-caption&lt;/code&gt; for the keyword "auto caption." Within 6 hours it hit #1 at 3.099. A different skill covering the exact same feature, with a brand-name slug, had been stuck at 1.7 for days.&lt;/p&gt;

&lt;p&gt;The lesson hit hard: if you're serious about a keyword, put it in your slug. Not your description, not your displayName — your slug. Everything else is supplementary.&lt;/p&gt;

&lt;p&gt;There's a catch, though. Slugs are permanent. You can't rename them after publishing. So if you picked a vanity name like I did for my first batch (&lt;code&gt;nemo-video&lt;/code&gt;, &lt;code&gt;nemo-edit&lt;/code&gt;, &lt;code&gt;nemo-subtitle&lt;/code&gt;), you're locked into the description-optimization game with a lower ceiling. I ended up publishing separate skills with keyword-rich slugs to cover the gaps.&lt;/p&gt;

&lt;h2&gt;
  
  
  DisplayName: powerful but fragile
&lt;/h2&gt;

&lt;p&gt;After discovering the slug effect, I figured displayName was just cosmetic. Wrong.&lt;/p&gt;

&lt;p&gt;I ran an accidental experiment. While cleaning up my skills, I shortened a displayName from 70 characters to 30 — cut out keyword suffixes like "for TikTok, Reels, and YouTube Shorts" to make it look neater.&lt;/p&gt;

&lt;p&gt;Within hours, the skill dropped out of the top 15 results for every keyword it had ranked for. Not a gradual decline — gone. I restored the original long name and the rankings came back within an hour. No other changes.&lt;/p&gt;

&lt;p&gt;My read: displayName feeds into the same vector embedding as description. Every keyword you remove from it shrinks your footprint in the search space. The "cleaner" name was literally invisible to the queries that used to find it.&lt;/p&gt;

&lt;p&gt;The rule I follow now: stuff every relevant keyword into your displayName, readability second. &lt;code&gt;Video Caption Tool - Burn Captions, AI Subtitles and SRT Export&lt;/code&gt; is ugly. It also ranks.&lt;/p&gt;

&lt;h2&gt;
  
  
  First sentence of your description is disproportionately weighted
&lt;/h2&gt;

&lt;p&gt;This one came from debugging a specific failure. My subtitle skill wasn't ranking for "add subtitles" even though those exact words appeared in the description — in the third sentence.&lt;/p&gt;

&lt;p&gt;I moved "Add subtitles" to the very first word of the description. Next index cycle, the skill jumped from outside top 10 to #1 for that query.&lt;/p&gt;

&lt;p&gt;The practical takeaway: open your description with the exact keyword phrase you want to rank for. Not a paraphrase, not a synonym — the literal words someone would type into the search box. Save the creative writing for sentence two.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 4 AM crash
&lt;/h2&gt;

&lt;p&gt;This is the part nobody warns you about.&lt;/p&gt;

&lt;p&gt;Last night I checked rankings before bed — 12 keywords holding #1. At 4:18 AM I ran a routine scan. Ten of those twelve had vanished from the results entirely. Not dropped to #5 or #8. Gone.&lt;/p&gt;

&lt;p&gt;I spent the next hour figuring out what happened. The pattern was clear: skills with keyword-in-slug (like &lt;code&gt;auto-caption&lt;/code&gt;) were still ranked. Skills that relied on description keywords for their ranking had disappeared. The scores for competitor skills hadn't changed — our skills had simply been removed from the index.&lt;/p&gt;

&lt;p&gt;The fix was dumb. I bumped the version number on two affected skills (no code changes, just a version bump in the SKILL.md frontmatter) and republished. Within 30 minutes, both were back at #1 with scores slightly higher than before.&lt;/p&gt;

&lt;p&gt;My best guess: ClawHub periodically rebuilds its vector index, and description-derived embeddings are more volatile during rebuilds than slug-derived ones. Slug matches are probably handled by a separate scoring path that survives reindexing.&lt;/p&gt;

&lt;p&gt;The practical defense: monitor your rankings, and if something falls off a cliff overnight, try republishing. A version bump with zero changes was enough to re-enter the index.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where this leaves things
&lt;/h2&gt;

&lt;p&gt;Right now, 12 of my 13 skills hold a #1 ranking for at least one keyword. The 13th has a brand-name slug and a crowded keyword — it ranks #3, which is fine.&lt;/p&gt;

&lt;p&gt;Other skill authors are hitting the same walls. There's a thread on the OpenClaw repo (&lt;a href="https://github.com/openclaw/openclaw/issues/50090" rel="noopener noreferrer"&gt;#50090&lt;/a&gt;) where several of us have been sharing data on what they're calling "invisible trigger failures" — skills that load fine but never get selected because the search ranking is opaque.&lt;/p&gt;

&lt;p&gt;What would actually fix this: a simple dashboard in ClawHub showing skill authors which queries match their skill and where they rank. The search API exists. The data is there. It just isn't surfaced to the people who need it most.&lt;/p&gt;

&lt;h2&gt;
  
  
  Update (March 23)
&lt;/h2&gt;

&lt;p&gt;Found the root cause. ClawHub &lt;a href="https://github.com/openclaw/clawhub/commits/main" rel="noopener noreferrer"&gt;pushed two commits&lt;/a&gt; on March 22 at 18:03 UTC — "narrow skill package catalog search" and "stabilize package catalog search." The code change added an exact-slug-match priority path to the search function (&lt;code&gt;resolveSkillBySlugOrAlias&lt;/code&gt; runs first, then vector search fills remaining slots). It also removed a scan-page limit constant and restructured the pagination loop.&lt;/p&gt;

&lt;p&gt;The overnight crash happened about 2 hours after this deploy. Skills relying on description-keyword matches fell out of the index during the transition. Slug-match skills stayed because they now hit the new exact-match path directly.&lt;/p&gt;

&lt;p&gt;The "republish to force reindex" workaround still works — but now I understand why. You're not fixing a random glitch. You're forcing the new search function to rebuild your skill's search digest entry under the updated scoring logic.&lt;/p&gt;

&lt;p&gt;Worth noting: the new exact-match path is actually good for skill authors long-term. If your slug matches the query, you're now guaranteed to appear in results. That wasn't true before (which is exactly what &lt;a href="https://github.com/openclaw/openclaw/issues/52034" rel="noopener noreferrer"&gt;#52034&lt;/a&gt; reported).&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This is part of a series on building AI video tools with OpenClaw. Previous posts: &lt;a href="https://dev.to/weizhang_dev/how-i-built-an-ai-video-editor-as-an-openclaw-skill-103j"&gt;How I Built an AI Video Editor&lt;/a&gt; | &lt;a href="https://dev.to/weizhang_dev/5-things-i-learned-wrapping-a-gui-first-api-for-ai-agents-3gep"&gt;What Broke When I Wrapped a Video API&lt;/a&gt; | &lt;a href="https://dev.to/weizhang_dev/i-use-openclaw-to-automate-my-entire-tiktok-and-reels-workflow-16od"&gt;Automating TikTok and Reels&lt;/a&gt; | &lt;a href="https://dev.to/weizhang_dev/i-reverse-engineered-4-top-video-skills-on-clawhub-heres-what-actually-drives-installs-2g24"&gt;Reverse-Engineering ClawHub's Top Video Skills&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Update (March 23)
&lt;/h2&gt;

&lt;p&gt;After publishing this, I dug into what caused the 4 AM ranking crash. Turns out it was not random.&lt;/p&gt;

&lt;p&gt;ClawHub pushed two commits on March 22 at 18:03-18:04 UTC — about 8 hours before the crash hit my rankings. The key change in commit 801cc55 ("fix: narrow skill package catalog search"): the search function now runs an exact slug match first via &lt;code&gt;resolveSkillBySlugOrAlias()&lt;/code&gt; before falling back to vector scanning. Previously it was pure vector search. The commit also removed a constant called &lt;code&gt;MAX_SKILL_CATALOG_SEARCH_SCAN_PAGES&lt;/code&gt; (previously 200), narrowing the vector scan range.&lt;/p&gt;

&lt;p&gt;When this deployed, it triggered a search index rebuild. Skills relying on description-derived embeddings lost their scores during the rebuild. Skills with keyword-in-slug survived because the new exact-match path handles them before the vector scan runs.&lt;/p&gt;

&lt;p&gt;The version bump fix worked because republishing forces ClawHub to rebuild the skill search digest. Not ideal that a zero-change version bump is the recovery path, but it works.&lt;/p&gt;

&lt;p&gt;Long-term this makes slug strategy even more important. The description optimization ceiling probably got lower with the narrowed vector scan. Filed the underlying instability in &lt;a href="https://github.com/openclaw/openclaw/issues/52034" rel="noopener noreferrer"&gt;#52034&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>openclaw</category>
      <category>showdev</category>
      <category>ai</category>
      <category>video</category>
    </item>
    <item>
      <title>I Analyzed ClawHub's 4 Most-Downloaded Video Skills — The Top One Has 65 Installs and Here's Why</title>
      <dc:creator>Wei Zhang</dc:creator>
      <pubDate>Sun, 22 Mar 2026 22:08:39 +0000</pubDate>
      <link>https://dev.to/weizhang_dev/i-reverse-engineered-4-top-video-skills-on-clawhub-heres-what-actually-drives-installs-2g24</link>
      <guid>https://dev.to/weizhang_dev/i-reverse-engineered-4-top-video-skills-on-clawhub-heres-what-actually-drives-installs-2g24</guid>
      <description>&lt;p&gt;We shipped a video editing skill on ClawHub earlier this month. Downloads ticked up to about 200. But installs? Zero.&lt;/p&gt;

&lt;p&gt;That number bugged me. So I did what any obsessive developer would do: I downloaded the SKILL.md files from every video-related skill I could find and started reading them line by line.&lt;/p&gt;

&lt;p&gt;Four stood out. Here's what I learned.&lt;/p&gt;

&lt;h2&gt;
  
  
  The lineup
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Skill&lt;/th&gt;
&lt;th&gt;Lines&lt;/th&gt;
&lt;th&gt;API Key needed?&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;pexoai-agent&lt;/td&gt;
&lt;td&gt;300&lt;/td&gt;
&lt;td&gt;Yes (PEXO_API_KEY)&lt;/td&gt;
&lt;td&gt;AI video production, 5-60s clips&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ffmpeg-video-editor&lt;/td&gt;
&lt;td&gt;393&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Natural language → FFmpeg commands&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;video-subtitles&lt;/td&gt;
&lt;td&gt;67&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;SRT generation + burn-in&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;video-frames&lt;/td&gt;
&lt;td&gt;29&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Extract frames from video&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Already, something jumps out. The two skills with the most real-world traction — video-subtitles and ffmpeg-video-editor — need zero external API keys. You install them and they just work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lesson 1: Downloads aren't installs
&lt;/h2&gt;

&lt;p&gt;Pexo has a polished SKILL.md. Good structure, clear workflow, even a clever "delivery worker" metaphor for how the AI should behave. But it requires &lt;code&gt;PEXO_API_KEY&lt;/code&gt; and &lt;code&gt;PEXO_BASE_URL&lt;/code&gt; before anything happens. That's a signup, a dashboard visit, and a copy-paste before your first video.&lt;/p&gt;

&lt;p&gt;Meanwhile video-frames is 29 lines long. It needs ffmpeg (which most dev machines already have) and nothing else. First frame extraction works in one command.&lt;/p&gt;

&lt;p&gt;The friction difference is enormous. Every step between "install" and "first result" costs you users. We had the same problem — our skill needed a token setup flow that, while automatic, still felt like a gate.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lesson 2: 67 lines beats 300
&lt;/h2&gt;

&lt;p&gt;video-subtitles does one thing well: transcribe audio, generate SRT, optionally burn subtitles into the video. The entire SKILL.md is 67 lines. There's a Quick Start section with five copy-paste examples right at the top:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Plain transcript&lt;/span&gt;
./scripts/generate_srt.py video.mp4

&lt;span class="c"&gt;# Burn subtitles into video&lt;/span&gt;
./scripts/generate_srt.py video.mp4 &lt;span class="nt"&gt;--srt&lt;/span&gt; &lt;span class="nt"&gt;--burn&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Compare that to our skill at the time — over 200 lines of API documentation, session management flows, token refresh logic. All necessary for our architecture, but the AI agent reading that file has to parse through a lot before it knows what to do.&lt;/p&gt;

&lt;p&gt;The lesson isn't "write less." It's that the first 20 lines matter more than the remaining 180. If your Quick Start doesn't give the agent a working command in under 10 lines, you've already lost.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lesson 3: The language rule nobody thinks about
&lt;/h2&gt;

&lt;p&gt;Pexo's SKILL.md has a section I'd never seen before:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gu"&gt;## ⚠️ LANGUAGE RULE (highest priority)&lt;/span&gt;

You MUST reply to the user in the SAME language they use.
This is non-negotiable.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Simple. Obvious in hindsight. If your skill works globally — and ClawHub skills do — the AI should respond in whatever language the user speaks. We never specified this. Our skill defaulted to English regardless of input, which probably confused every non-English user who tried it.&lt;/p&gt;

&lt;p&gt;One line in your SKILL.md fixes this. Pexo marks it as "highest priority," above the actual workflow. That tells me they learned this the hard way.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lesson 4: FFmpeg skills win because FFmpeg is already there
&lt;/h2&gt;

&lt;p&gt;ffmpeg-video-editor is basically a prompt template. It doesn't call any API. It doesn't upload anything. It translates "trim this video from 1:21 to 1:35" into an ffmpeg command and runs it locally.&lt;/p&gt;

&lt;p&gt;That's it. And it works because ffmpeg is already installed on most machines that would run OpenClaw. Zero network latency, zero API costs, zero auth.&lt;/p&gt;

&lt;p&gt;There's a ceiling to this approach — you can't do AI-generated scenes or text-to-video with local ffmpeg. But for the 80% of editing tasks that are just "cut, crop, convert" it's hard to beat.&lt;/p&gt;

&lt;h2&gt;
  
  
  What we changed
&lt;/h2&gt;

&lt;p&gt;After this analysis, we rewrote our SKILL.md with three things in mind:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Quick Start first.&lt;/strong&gt; The agent should know how to make a basic edit within the first 10 lines.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reduce the auth wall.&lt;/strong&gt; Anonymous tokens that auto-generate on first use — no signup required for basic edits.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Add the language rule.&lt;/strong&gt; One paragraph, borrowed directly from Pexo's approach.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We also split our monolithic skill into focused ones — a subtitle tool, a shorts maker, a color grading tool — each with a tight description that matches how people actually search.&lt;/p&gt;

&lt;p&gt;Still early. Still zero installs. But the SKILL.md reads like something an AI agent can actually follow now, and that feels like the right foundation.&lt;/p&gt;

&lt;p&gt;If you're building OpenClaw skills, go read the SKILL.md files of what's already working. The patterns are right there. You can find our video editing skills on &lt;a href="https://clawhub.ai" rel="noopener noreferrer"&gt;ClawHub&lt;/a&gt; by searching "video editing" or "subtitles."&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This is part of a series on building AI video tools with OpenClaw. Previous posts: &lt;a href="https://dev.to/weizhang_dev/how-i-built-an-ai-video-editor-as-an-openclaw-skill-103j"&gt;How I Built an AI Video Editor as an OpenClaw Skill&lt;/a&gt; | &lt;a href="https://dev.to/weizhang_dev/5-things-i-learned-wrapping-a-gui-first-api-for-ai-agents-3gep"&gt;I Wrapped a Video Editing API for AI - Here is What Broke&lt;/a&gt; | &lt;a href="https://dev.to/weizhang_dev/i-use-openclaw-to-automate-my-entire-tiktok-and-reels-workflow-16od"&gt;I use OpenClaw to automate my entire TikTok and Reels workflow&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>openclaw</category>
      <category>showdev</category>
      <category>ai</category>
      <category>video</category>
    </item>
    <item>
      <title>I use OpenClaw to automate my entire TikTok and Reels workflow</title>
      <dc:creator>Wei Zhang</dc:creator>
      <pubDate>Sat, 21 Mar 2026 21:27:51 +0000</pubDate>
      <link>https://dev.to/weizhang_dev/i-use-openclaw-to-automate-my-entire-tiktok-and-reels-workflow-16od</link>
      <guid>https://dev.to/weizhang_dev/i-use-openclaw-to-automate-my-entire-tiktok-and-reels-workflow-16od</guid>
      <description>&lt;p&gt;Let me describe my Tuesday evenings three months ago.&lt;/p&gt;

&lt;p&gt;I'd shoot four to five short clips throughout the week — product demos, quick tutorials, a behind-the-scenes moment. Good content. Then Tuesday would arrive and I'd spend three to four hours staring at a timeline in DaVinci Resolve, doing the same things I'd done the Tuesday before: trim the dead air, add subtitles, resize to 9:16, drop in background music at a sane volume, export three versions for TikTok, Reels, and Shorts.&lt;/p&gt;

&lt;p&gt;I wasn't editing. I was operating a conveyor belt.&lt;/p&gt;

&lt;p&gt;The actual creative decisions took maybe twenty minutes. The rest was clicking through dialogs and watching export progress bars. I kept thinking: &lt;em&gt;this should not require a human.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What I Found
&lt;/h2&gt;

&lt;p&gt;I've been an &lt;a href="https://openclaw.ai" rel="noopener noreferrer"&gt;OpenClaw&lt;/a&gt; user for about a year — I use it to manage my calendar, draft emails, handle some light scripting for my projects. It's basically a personal AI that runs locally and you can extend with community-built skills.&lt;/p&gt;

&lt;p&gt;A few months ago I noticed a video editing skill on &lt;a href="https://clawhub.ai" rel="noopener noreferrer"&gt;ClawHub&lt;/a&gt;. The description was straightforward: edit videos by chatting with your AI assistant.&lt;/p&gt;

&lt;p&gt;I was skeptical. I've used enough AI video tools to know they usually mean "we'll describe what edits you should make" not "we'll actually make the edits." But I had a boring Tuesday coming up, so I tried it.&lt;/p&gt;

&lt;p&gt;The short version: it actually makes the edits. You install the skill, drop a video file into your OpenClaw workspace, and start talking.&lt;/p&gt;




&lt;h2&gt;
  
  
  My Workflow, Step by Step
&lt;/h2&gt;

&lt;p&gt;I've settled into a pretty consistent routine. Here's exactly how a typical video goes from raw footage to three exported files.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Drop the file
&lt;/h3&gt;

&lt;p&gt;I record on my phone or mirrorless, AirDrop to my laptop, and drag the file into &lt;code&gt;~/.openclaw/workspace/inbox/&lt;/code&gt;. That's the only manual step that stays manual.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Open OpenClaw and start a session
&lt;/h3&gt;

&lt;p&gt;I type one message to kick things off:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"New video in inbox: &lt;code&gt;demo-march-14.mp4&lt;/code&gt;. It's a 4-minute product walkthrough. I need it trimmed to under 90 seconds, subtitled, and exported in three sizes. Let's go."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;OpenClaw picks up the file, calls the video editing skill, and we're off.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Let it run
&lt;/h3&gt;

&lt;p&gt;From here it's a back-and-forth, but it goes fast. The skill knows how to handle the heavy lifting — it sends the video to the processing pipeline, streams back status updates, and when it's done it tells me exactly where the output landed.&lt;/p&gt;

&lt;p&gt;The full session usually takes 8–12 minutes per video depending on length. I keep my laptop open but I'm not watching it. I'm making coffee.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Prompts I Actually Use
&lt;/h2&gt;

&lt;p&gt;This is the part I wish someone had given me when I started. Here are my most-used prompts, copy-pasteable:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For trimming + compression:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Trim the first 8 seconds and the last 5 seconds from [filename]. Then compress to under 50MB without dropping below 1080p.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;For subtitles:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Add auto-generated subtitles to [filename]. Burn them in at the bottom third, white text with a subtle black shadow, no background box.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;For multi-platform export:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Take [filename] and export three versions: one at original aspect ratio for YouTube, one cropped to 9:16 at 1080x1920 for TikTok and Reels, one at 1080x1920 with max 60 seconds for Shorts. Name them [basename]-youtube, [basename]-vertical, [basename]-shorts.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;For background music:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Add [music-file.mp3] as background music to [filename]. Set the music volume to 15% and duck it to 5% whenever speech is detected.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;For a full batch:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Process all .mp4 files in the inbox folder: trim 5 seconds from the start of each, add auto-subtitles, export as 9:16 vertical. Move originals to /inbox/processed when done.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That last one is my favorite. I drop five clips, send one message, go to sleep. In the morning there are fifteen files (three versions each) waiting for me.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Numbers: Before vs After
&lt;/h2&gt;

&lt;p&gt;I tracked my time for six weeks before switching and six weeks after. This isn't marketing copy — this is what I logged.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Task&lt;/th&gt;
&lt;th&gt;Before (per video)&lt;/th&gt;
&lt;th&gt;After (per video)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Trimming + cleanup&lt;/td&gt;
&lt;td&gt;12 min&lt;/td&gt;
&lt;td&gt;~0 (automated)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Subtitle generation + review&lt;/td&gt;
&lt;td&gt;18 min&lt;/td&gt;
&lt;td&gt;4 min (review only)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Resize + format variants&lt;/td&gt;
&lt;td&gt;15 min&lt;/td&gt;
&lt;td&gt;~0 (automated)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Music + audio balance&lt;/td&gt;
&lt;td&gt;10 min&lt;/td&gt;
&lt;td&gt;~0 (automated)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Export management&lt;/td&gt;
&lt;td&gt;8 min&lt;/td&gt;
&lt;td&gt;~0 (automated)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Total per video&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~63 min&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~8 min&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;With four videos a week, that's roughly 220 minutes back every week. About 3.5 hours.&lt;/p&gt;

&lt;p&gt;Cost-wise: the skill runs on credits. I'm paying roughly $12–15 a month at my current volume. Before I was paying in time, which at any reasonable rate is worth way more than fifteen dollars.&lt;/p&gt;




&lt;h2&gt;
  
  
  Honest Limitations
&lt;/h2&gt;

&lt;p&gt;I'd be lying if I said this was perfect. Here's what still trips me up:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Subtitle accuracy on technical jargon.&lt;/strong&gt; If I'm talking about specific software terms or product names, the auto-generated subtitles will sometimes mangle them. I still do a quick manual review on anything that's going to be public-facing. Takes about 3–4 minutes per video.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Music ducking isn't always perfect.&lt;/strong&gt; The speech detection for auto-ducking works well on clean recordings. If I shot in a noisy environment or there's significant background noise in my source, it can duck at weird moments. I've learned to specify stricter ducking parameters when this is a risk: &lt;code&gt;duck to 3% when speech confidence is above 80%&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Large files and timeouts.&lt;/strong&gt; Anything over about 800MB can sometimes timeout during upload depending on my connection. I've started transcoding very long source files first with a quick local ffmpeg pass to h264 before sending them. Not ideal, but it's a one-liner.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The skill can't watch your screen.&lt;/strong&gt; This is OpenClaw operating on files, not a GUI agent. If your workflow depends on real-time visual feedback during editing (color grading, precise subtitle positioning, etc.), you'll still need to do that part yourself.&lt;/p&gt;




&lt;h2&gt;
  
  
  How to Get Started
&lt;/h2&gt;

&lt;p&gt;If you're already an OpenClaw user, setup is about five minutes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;a href="https://clawhub.ai/imo14reifey/video-editor-ai" rel="noopener noreferrer"&gt;ClawHub&lt;/a&gt; and search for a video editing skill&lt;/li&gt;
&lt;li&gt;Install the skill:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx clawhub@latest &lt;span class="nb"&gt;install &lt;/span&gt;video-editor-ai &lt;span class="nt"&gt;--force&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;You'll be prompted to register for an API key when you first use it (there are free credits to test with)&lt;/li&gt;
&lt;li&gt;Drop a video in your workspace and start talking&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Source code is on &lt;a href="https://github.com/nemovideo/nemovideo_skills" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; if you want to see how the skill is structured.&lt;/p&gt;

&lt;p&gt;If you're not yet an OpenClaw user — it's a local AI assistant you run yourself, kind of like having a personal Claude or GPT that also has access to your filesystem, your apps, and community-built skills. You can find it at &lt;a href="https://openclaw.ai" rel="noopener noreferrer"&gt;openclaw.ai&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thought
&lt;/h2&gt;

&lt;p&gt;I still enjoy video editing when it's actually editing — when I'm making a real creative decision about pacing or structure or what to cut. What I don't enjoy is the mechanical repetition that comes after.&lt;/p&gt;

&lt;p&gt;OpenClaw with a good video editing skill drew a clear line between those two things. The creative stuff stays with me. The repetitive stuff goes to the machine.&lt;/p&gt;

&lt;p&gt;Three and a half hours a week adds up. I've spent that time shooting better content instead.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;If you've got questions about specific prompts or use cases, drop them in the comments — happy to share what's worked.&lt;/em&gt;&lt;/p&gt;







&lt;p&gt;&lt;em&gt;This is part of a series on building AI video tools with OpenClaw. Previous posts: &lt;a href="https://dev.to/weizhang_dev/how-i-built-an-ai-video-editor-as-an-openclaw-skill-103j"&gt;How I Built an AI Video Editor&lt;/a&gt; | &lt;a href="https://dev.to/weizhang_dev/5-things-i-learned-wrapping-a-gui-first-api-for-ai-agents-3gep"&gt;What Broke When I Wrapped a Video API&lt;/a&gt; | Next: &lt;a href="https://dev.to/weizhang_dev/i-reverse-engineered-4-top-video-skills-on-clawhub-heres-what-actually-drives-installs-2g24"&gt;Reverse-Engineering Top Video Skills&lt;/a&gt; | &lt;a href="https://dev.to/weizhang_dev/how-i-got-12-number-one-rankings-on-clawhub-in-5-days-7jh"&gt;12 #1 Rankings in 5 Days&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>openclaw</category>
      <category>showdev</category>
      <category>productivity</category>
      <category>ai</category>
    </item>
    <item>
      <title>I Wrapped a Video Editing API for AI - Here is What Broke</title>
      <dc:creator>Wei Zhang</dc:creator>
      <pubDate>Fri, 20 Mar 2026 06:27:30 +0000</pubDate>
      <link>https://dev.to/weizhang_dev/5-things-i-learned-wrapping-a-gui-first-api-for-ai-agents-3gep</link>
      <guid>https://dev.to/weizhang_dev/5-things-i-learned-wrapping-a-gui-first-api-for-ai-agents-3gep</guid>
      <description>&lt;p&gt;Most AI agent tutorials assume you control both ends of the stack. You define the tools, you define the responses, everything is designed for programmatic access from the start.&lt;/p&gt;

&lt;p&gt;Real-world integrations are messier. The useful APIs — the ones that actually do something valuable — were usually built for humans with browsers. They return things like "click the Export button" and "drag the clip to the timeline." They assume someone is watching a screen.&lt;/p&gt;

&lt;p&gt;I spent the last few months building &lt;a href="https://clawhub.ai/imo14reifey/video-editor-ai" rel="noopener noreferrer"&gt;video-editor-ai&lt;/a&gt;, an OpenClaw skill that wraps a video editing backend originally designed for a web UI. Here's what I learned.&lt;/p&gt;




&lt;h2&gt;
  
  
  Lesson 1: You Need an Interception Layer, Not Just a Wrapper
&lt;/h2&gt;

&lt;p&gt;The naive approach is to forward everything from the user to the backend and return whatever comes back. This breaks immediately when the backend responds with GUI instructions.&lt;/p&gt;

&lt;p&gt;The backend I was working with would say things like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"Your video is ready! Click the Export button in the top right 
corner to download it."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you pass this directly to the user, they'll ask "what Export button?" The skill has no UI. There is no button.&lt;/p&gt;

&lt;p&gt;The fix isn't prompt engineering ("please don't mention buttons"). It's an architectural one: you need a &lt;strong&gt;translation layer&lt;/strong&gt; that sits between the backend response and the user.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;backend response → [GUI Translator] → user-visible response
                          ↓
                   if "click X" detected:
                   execute X directly via API
                   replace with: "✅ Done. Here's your file."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The translator needs to handle two cases:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Cosmetic GUI references&lt;/strong&gt; ("check the dashboard") — strip and ignore&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Actionable GUI references&lt;/strong&gt; ("click Export") — intercept and execute the actual API call&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The second case is critical. If "click Export" reaches the user as text, nothing happens. If your translator catches it and calls the render endpoint, the user gets their file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lesson:&lt;/strong&gt; Design for interception from day one. Map every GUI action in the backend's vocabulary to an API call.&lt;/p&gt;




&lt;h2&gt;
  
  
  Lesson 2: Silent Edits Are Real and You Must Handle Them
&lt;/h2&gt;

&lt;p&gt;This one took me the longest to figure out.&lt;/p&gt;

&lt;p&gt;About 30% of edit operations in the backend return no user-visible text at all. The backend processes the edit, updates internal state, sends a stream of tool calls — and then closes the connection without saying anything.&lt;/p&gt;

&lt;p&gt;From the user's perspective: they type "remove the background music." Nothing happens. No confirmation, no error. Just silence.&lt;/p&gt;

&lt;p&gt;The first instinct is to retry. That's wrong. The edit succeeded. Retrying it will apply the same edit twice, which in a credit-based system means you've now charged the user twice for one action.&lt;/p&gt;

&lt;p&gt;The correct approach is &lt;strong&gt;state diffing&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Before sending the edit:
&lt;/span&gt;&lt;span class="n"&gt;state_before&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_current_state&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;session_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Send edit via SSE stream
&lt;/span&gt;&lt;span class="n"&gt;response_text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;send_to_backend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# If stream closes with no text:
&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;response_text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;state_after&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_current_state&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;session_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;diff&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;compute_diff&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state_before&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;state_after&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;diff&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;format_diff_as_confirmation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;diff&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="c1"&gt;# "✅ BGM track removed (was: Lo-fi Beats, 0–45s)"
&lt;/span&gt;    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;The edit didn&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;t seem to take effect. Want to try again?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The diff-based confirmation also makes the UX much better than a generic "done." Users want to know &lt;em&gt;what&lt;/em&gt; changed, not just that something happened.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lesson:&lt;/strong&gt; Never assume a silent response means failure. Check state before and after any operation. Build state diffing before you build anything else.&lt;/p&gt;




&lt;h2&gt;
  
  
  Lesson 3: Billing and Credits Belong to the Agent, Not the Backend
&lt;/h2&gt;

&lt;p&gt;This is a UX problem that becomes a trust problem quickly.&lt;/p&gt;

&lt;p&gt;The backend I was wrapping charged credits for processing operations. It also had an export/render endpoint that was completely free. But from the user's perspective — talking to an agent — this distinction is invisible.&lt;/p&gt;

&lt;p&gt;Early in development, users would ask "how many credits do I have left?" The agent would forward this to the backend, which would respond: "You can check your credit balance on the dashboard under Account Settings."&lt;/p&gt;

&lt;p&gt;Two problems:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;There is no dashboard. The skill is the interface.&lt;/li&gt;
&lt;li&gt;Even if there were, this is exactly the kind of round-trip that should never hit the backend.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The solution is a &lt;strong&gt;pre-flight router&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;incoming message
      ↓
  [Router]
  ├── "credits" / "balance" / "how much left" → call balance API directly
  ├── "export" / "download" / "send me the file" → call render API directly  
  ├── "upload" / user attaches a file → call upload API directly
  └── everything else → forward to backend via SSE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The router catches intent before it reaches the backend. It means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Credit checks are instant (no SSE stream overhead)&lt;/li&gt;
&lt;li&gt;Exports never accidentally trigger new generations&lt;/li&gt;
&lt;li&gt;Upload flow is deterministic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The rule of thumb: &lt;strong&gt;any operation with a known, fixed API endpoint should never go through the conversational backend&lt;/strong&gt;. The backend is for things that require interpretation. Credit checks don't require interpretation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lesson:&lt;/strong&gt; Map your API surface area before you write any prompt logic. Identify which operations are deterministic (route them directly) vs. which require the backend's reasoning (route them through SSE).&lt;/p&gt;




&lt;h2&gt;
  
  
  Lesson 4: Backend Error Messages Are Written for Humans, Not Agents
&lt;/h2&gt;

&lt;p&gt;Error handling in GUI-first APIs is designed for a support workflow, not programmatic consumption.&lt;/p&gt;

&lt;p&gt;Typical backend error message:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"I encountered a temporary issue processing your request. 
Please try again or contact support at support@example.com 
if the problem persists."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This message is useless to an agent for three reasons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It doesn't say what failed&lt;/li&gt;
&lt;li&gt;"Try again" is dangerous if the failure was a credit deduction&lt;/li&gt;
&lt;li&gt;"Contact support" is a dead end in an automated flow&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Worse: this exact message sometimes appears as a &lt;em&gt;trailing message&lt;/em&gt; after a successful operation. The backend completes the edit, sends the result, then appends a generic error epilogue as a separate SSE event. If your agent treats this as an error state, you get false negatives.&lt;/p&gt;

&lt;p&gt;The pattern that works:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;parse_sse_stream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;events&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;has_success&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;
    &lt;span class="n"&gt;final_text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;events&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;looks_like_success&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;has_success&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
            &lt;span class="n"&gt;final_text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="nf"&gt;looks_like_error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;has_success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="c1"&gt;# Trailing error after success = ignore
&lt;/span&gt;                &lt;span class="k"&gt;continue&lt;/span&gt;
            &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="c1"&gt;# Genuine error = surface to user
&lt;/span&gt;                &lt;span class="n"&gt;final_text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;translate_error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;final_text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;translate_error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;backend_message&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Map backend error vocabulary to actionable user messages
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;temporary issue&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;backend_message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;The backend is busy — try again in 30 seconds.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;insufficient credits&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;backend_message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;You&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ve run out of credits. Get more at [link].&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="c1"&gt;# ... etc
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Something went wrong. Here&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s the raw error: &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;backend_message&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key insight: &lt;strong&gt;don't surface backend error messages directly&lt;/strong&gt;. Translate them. Your agent knows the context (what was attempted, what state things are in) that the backend doesn't.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lesson:&lt;/strong&gt; Build an error translation table early. Expect that the same error string from the backend can mean different things depending on when in the flow it appears.&lt;/p&gt;




&lt;h2&gt;
  
  
  Lesson 5: Test With Transcripts, Not Unit Tests
&lt;/h2&gt;

&lt;p&gt;Standard unit testing doesn't map well to conversational agent skills. You can't easily mock a 300-second SSE stream, and the interesting failure modes only surface in real multi-turn conversations.&lt;/p&gt;

&lt;p&gt;What actually works: &lt;strong&gt;transcript testing&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I ended up with a library of ~110 conversation transcripts — real interactions that exposed bugs, edge cases, or just confusing UX. Each transcript is a sequence of user messages and expected agent behaviors:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# transcript: double-export.yaml&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;User&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;asks&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;export&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;immediately&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;after&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;generation"&lt;/span&gt;
&lt;span class="na"&gt;turns&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;create&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;a&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;30&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;second&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;video&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;about&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;ocean&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;waves"&lt;/span&gt;
    &lt;span class="na"&gt;expect&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;confirmation&lt;/span&gt;
        &lt;span class="na"&gt;contains&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;video&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;created"&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;export&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;it"&lt;/span&gt;
    &lt;span class="na"&gt;expect&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;file_delivered&lt;/span&gt;
        &lt;span class="na"&gt;not_contains&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;generating"&lt;/span&gt;  &lt;span class="c1"&gt;# should NOT start a new generation&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;credits_unchanged&lt;/span&gt;     &lt;span class="c1"&gt;# export is free, credits should not decrease&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This approach catches:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Regression bugs&lt;/strong&gt;: does fixing the silent edit problem break the export flow?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;UX issues&lt;/strong&gt;: does the phrasing of confirmations actually make sense in context?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Edge cases&lt;/strong&gt;: what happens if the user asks to export a video that's still generating?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The transcripts also serve as documentation. New contributors can read them to understand how the skill is supposed to behave in specific scenarios — something a SKILL.md instruction file can't fully capture.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lesson:&lt;/strong&gt; Start collecting transcripts from your first real user session. Every surprising or broken interaction is a test case. By the time you have 20 transcripts, you'll have a regression suite that catches most of the things that matter.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Common Thread
&lt;/h2&gt;

&lt;p&gt;All five of these lessons come back to the same root problem: &lt;strong&gt;GUI-first backends communicate in a vocabulary designed for human visual processing, and agents operate in a vocabulary designed for text and function calls.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The translation work is non-trivial, but it's also reusable. The patterns above — interception layers, state diffing, pre-flight routers, error translation, transcript testing — apply to any GUI-first API you want to expose to an agent runtime.&lt;/p&gt;

&lt;p&gt;If you're building on OpenClaw and want to see the full implementation, video-editor-ai's SKILL.md is open source:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx clawhub@latest &lt;span class="nb"&gt;install &lt;/span&gt;video-editor-ai &lt;span class="nt"&gt;--force&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Source: &lt;a href="https://github.com/nemovideo/nemovideo_skills" rel="noopener noreferrer"&gt;github.com/nemovideo/nemovideo_skills&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;What GUI-first APIs have you tried to wrap for agent use? Curious what other translation patterns people have run into.&lt;/em&gt;&lt;/p&gt;







&lt;p&gt;&lt;em&gt;This is part of a series on building AI video tools with OpenClaw. Previous: &lt;a href="https://dev.to/weizhang_dev/how-i-built-an-ai-video-editor-as-an-openclaw-skill-103j"&gt;How I Built an AI Video Editor&lt;/a&gt; | Next posts: &lt;a href="https://dev.to/weizhang_dev/i-use-openclaw-to-automate-my-entire-tiktok-and-reels-workflow-16od"&gt;Automating TikTok and Reels&lt;/a&gt; | &lt;a href="https://dev.to/weizhang_dev/i-reverse-engineered-4-top-video-skills-on-clawhub-heres-what-actually-drives-installs-2g24"&gt;Reverse-Engineering Top Video Skills&lt;/a&gt; | &lt;a href="https://dev.to/weizhang_dev/how-i-got-12-number-one-rankings-on-clawhub-in-5-days-7jh"&gt;12 #1 Rankings in 5 Days&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>openclaw</category>
      <category>ai</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Descript's Lyrebird API vs Building a Video Editing Skill for OpenClaw — A Developer's Comparison</title>
      <dc:creator>Wei Zhang</dc:creator>
      <pubDate>Wed, 18 Mar 2026 07:10:26 +0000</pubDate>
      <link>https://dev.to/weizhang_dev/descripts-lyrebird-api-vs-building-a-video-editing-skill-for-openclaw-a-developers-comparison-50ek</link>
      <guid>https://dev.to/weizhang_dev/descripts-lyrebird-api-vs-building-a-video-editing-skill-for-openclaw-a-developers-comparison-50ek</guid>
      <description>&lt;p&gt;Descript shipped their Lyrebird enterprise API in January 2026. Upload raw footage, get back an edited project file or rendered video. They've also made Claude Sonnet 4.5 the default model inside Underlord, their AI editing layer.&lt;/p&gt;

&lt;p&gt;I've spent the past few months building &lt;a href="https://clawhub.ai/imo14reifey/video-editor-ai" rel="noopener noreferrer"&gt;video-editor-ai&lt;/a&gt;, an OpenClaw Skill that does roughly the same thing: give it footage, describe what you want, get back a finished file. Same surface area. Very different architecture underneath.&lt;/p&gt;

&lt;p&gt;Here's an honest comparison from someone who's shipped both approaches.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Descript's Lyrebird API Actually Does
&lt;/h2&gt;

&lt;p&gt;The Lyrebird API is what Descript calls "lightweight, focused on workflow handoffs." That's accurate. The core model is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You upload raw footage via a signed URL&lt;/li&gt;
&lt;li&gt;You send an edit job with parameters&lt;/li&gt;
&lt;li&gt;You poll (or receive a webhook) when the render is done&lt;/li&gt;
&lt;li&gt;You download the output file&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It's a well-designed batch processing API. Each call is stateless — the API doesn't remember what you did in the previous call. If you want to apply three sequential edits (cut → subtitle → color grade), you either chain three separate API calls yourself, or you express the full edit spec upfront in a single job.&lt;/p&gt;

&lt;p&gt;This is the right design for a lot of use cases: automated pipelines, batch processing, CI/CD video workflows, anything where you have a complete spec before you start.&lt;/p&gt;

&lt;p&gt;It's not the right design for conversational editing.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Session State Problem
&lt;/h2&gt;

&lt;p&gt;Conversational video editing looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User: "add Chinese subtitles"
Agent: [processes, returns file with subtitles]

User: "actually make them white with a black outline"
Agent: [processes, returns updated file]

User: "now trim the first 10 seconds"
Agent: [processes, returns final file]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each turn depends on the output of the previous turn. The agent needs to know: which file are we working on right now? What edits have already been applied? Where are we in the sequence?&lt;/p&gt;

&lt;p&gt;With Descript's API, you manage this state yourself. Between turns, you're responsible for tracking the "current file," persisting the session context, and constructing the next API call with the right input file. The API itself is stateless.&lt;/p&gt;

&lt;p&gt;With an OpenClaw Skill, session state is built into the runtime. The Skill runs inside the agent's conversation context — it can read prior turns, track which file is "active," and construct downstream calls without you building a state machine around the API.&lt;/p&gt;

&lt;p&gt;Here's what that looks like in practice. In a Skill, you don't write:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Your orchestration code
&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;load_session_state&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;session_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;current_file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;current_file&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;descript_api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;edit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;current_file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;trim first 10 seconds&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;current_file&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;output_url&lt;/span&gt;
&lt;span class="nf"&gt;save_session_state&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;session_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You write:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# In the Skill's routing logic&lt;/span&gt;
If the user refers to "it" or "the video" without specifying a filename,
use the most recently processed file from this session.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Skill runtime handles persistence. The agent handles reference resolution. You just describe the policy.&lt;/p&gt;

&lt;p&gt;This isn't a minor difference. In a multi-turn video editing workflow, managing session state is a significant chunk of the application logic. The Skill model moves that responsibility into the runtime; the API model leaves it with you.&lt;/p&gt;




&lt;h2&gt;
  
  
  GUI-First vs Agent-Native Intent
&lt;/h2&gt;

&lt;p&gt;The deeper architectural difference is in what the API exposes.&lt;/p&gt;

&lt;p&gt;Descript's API reflects Descript's product. It talks in terms of Descript's edit operations: compositions, sequences, layers, transcript-based edits. These are the right concepts for Descript's GUI. They're not necessarily the right concepts for an agent.&lt;/p&gt;

&lt;p&gt;When a user says "remove the background music," an agent doesn't want to know which audio track index to zero out. It wants to express an intent — "remove BGM" — and have the editing layer figure out the implementation.&lt;/p&gt;

&lt;p&gt;This is the GUI-first problem that shows up in every video editing API I've worked with. The API surface reflects the GUI's data model, not the agent's vocabulary. The result is a translation layer you have to build yourself:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# You end up writing this
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;handle_remove_bgm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;current_project&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Figure out which tracks are BGM vs dialog
&lt;/span&gt;    &lt;span class="n"&gt;tracks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;descript_api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_tracks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;current_project&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;bgm_tracks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;tracks&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;classify_track&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;music&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="c1"&gt;# Zero them out
&lt;/span&gt;    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;track&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;bgm_tracks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;descript_api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mute_track&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;current_project&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;track&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;descript_api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;current_project&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In video-editor-ai's architecture, this translation lives in the Skill itself — the SKILL.md contains a routing table that maps natural language intents to API calls. The calling agent doesn't need to know anything about the underlying edit operations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# In SKILL.md&lt;/span&gt;
If the user asks to "remove background music", "mute BGM", "take out the music":
→ Call /edit/audio with {"action": "mute", "track_type": "music"}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Skill is the translation layer. You write it once, and every agent that installs the Skill gets the translation for free.&lt;/p&gt;




&lt;h2&gt;
  
  
  Error Handling: Who's Responsible?
&lt;/h2&gt;

&lt;p&gt;One more difference worth understanding before you choose an approach.&lt;/p&gt;

&lt;p&gt;With a direct API integration, errors from the video processing backend land in your application code. A failed render, a timeout on a long export, a quota exceeded response — you handle all of these.&lt;/p&gt;

&lt;p&gt;With a Skill, error handling can be layered into the Skill's instruction set. The Skill knows the semantics of the errors (a 429 means quota, not a bug; a 0-byte output means the upstream service returned empty, not that the write failed) and can surface them to the user appropriately:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Error handling in SKILL.md&lt;/span&gt;
If the render API returns a 0-byte file:
&lt;span class="p"&gt;-&lt;/span&gt; Do NOT retry automatically (avoid double-charging credits)
&lt;span class="p"&gt;-&lt;/span&gt; Check session state: did the previous turn confirm the edit completed?
&lt;span class="p"&gt;  -&lt;/span&gt; If yes: the edit succeeded silently, run state diff and confirm to user
&lt;span class="p"&gt;  -&lt;/span&gt; If no: surface error and ask user to try again
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This kind of contextual error handling is hard to encode in API client code. It requires knowing the application semantics, not just the HTTP status codes. In a Skill, it lives naturally alongside the rest of the routing logic.&lt;/p&gt;




&lt;h2&gt;
  
  
  When to Use Each
&lt;/h2&gt;

&lt;p&gt;These aren't competing approaches for the same use case. They're right for different things.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use Descript's Lyrebird API when:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You're building a batch pipeline (process 50 videos overnight)&lt;/li&gt;
&lt;li&gt;You have a complete edit spec before you start (no user interaction mid-edit)&lt;/li&gt;
&lt;li&gt;You're integrating into an existing product that already manages state&lt;/li&gt;
&lt;li&gt;You need Descript's specific editing capabilities (transcript-based cuts, screen recording tools, their specific audio cleanup)&lt;/li&gt;
&lt;li&gt;You have an enterprise contract and budget&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Use an OpenClaw Skill when:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You're building a conversational agent workflow&lt;/li&gt;
&lt;li&gt;Users will iterate on edits across multiple turns&lt;/li&gt;
&lt;li&gt;You want the editing capability to work across any OpenClaw-compatible agent without integration work&lt;/li&gt;
&lt;li&gt;You want a free tier to prototype with (100 credits, no account required)&lt;/li&gt;
&lt;li&gt;You want the translation layer between natural language and video operations handled for you&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The clearest signal: if you're thinking about session state management before you've written a single line of feature code, you probably want the Skill model. If you have a complete spec and just need to ship files through a processing pipeline, you probably want the API model.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Part Descript Got Right That We Copied
&lt;/h2&gt;

&lt;p&gt;One thing Lyrebird does well that informed video-editor-ai's design: the output is a real file, not a streaming blob that disappears.&lt;/p&gt;

&lt;p&gt;Early versions of video-editor-ai returned a temporary URL that expired in 15 minutes. Users would come back to a conversation 20 minutes later, ask for the file again, and get a 404. Descript delivers permanent project files. We moved video-editor-ai to the same model — the Skill stores a reference to the output in session state, and the user can retrieve it any time in the conversation.&lt;/p&gt;

&lt;p&gt;Good API design is good API design regardless of where it comes from.&lt;/p&gt;




&lt;h2&gt;
  
  
  Practical Starting Point
&lt;/h2&gt;

&lt;p&gt;If you want to compare the approaches hands-on:&lt;/p&gt;

&lt;p&gt;For Descript's API: &lt;a href="https://docs.descriptapi.com" rel="noopener noreferrer"&gt;https://docs.descriptapi.com&lt;/a&gt; (enterprise access required)&lt;/p&gt;

&lt;p&gt;For the OpenClaw Skill approach:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx clawhub@latest &lt;span class="nb"&gt;install &lt;/span&gt;video-editor-ai
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;100 free credits, no account needed. The SKILL.md is open source at &lt;a href="https://github.com/nemovideo/nemovideo_skills" rel="noopener noreferrer"&gt;github.com/nemovideo/nemovideo_skills&lt;/a&gt; — the routing table and error handling logic are all readable.&lt;/p&gt;

&lt;p&gt;The two approaches aren't mutually exclusive. A production system could use Descript's API for batch jobs and an OpenClaw Skill for the conversational editing interface. But if you're starting from scratch and building for an agent-first workflow, the Skill model saves you a significant amount of state management and translation layer work.&lt;/p&gt;







&lt;h2&gt;
  
  
  One More Thing: The Pricing Model Signal
&lt;/h2&gt;

&lt;p&gt;Descript's Lyrebird API is enterprise-only. That's not a criticism — enterprise pricing makes sense for a company with Descript's support costs and customer profile. But it does signal something about who each approach is designed for.&lt;/p&gt;

&lt;p&gt;OpenClaw Skills are distributed through ClawHub, which is free to publish on and has a free tier for end users. The economics are different because the model is different: Skills are closer to open-source libraries than to API products. You install them, they run in your agent, and the cost is per-operation on the underlying processing backend (in video-editor-ai's case, that's the video processing credits).&lt;/p&gt;

&lt;p&gt;If you're evaluating video editing APIs and cost structure matters, that's a real difference worth factoring in.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Building something at the intersection of agent runtimes and video editing? I'd like to hear what API design decisions you're running into — the session state problem comes up in almost every media workflow I've seen.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Related skills from the same backend:&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://clawhub.ai/nemovideonemo/shorts-editor" rel="noopener noreferrer"&gt;Shorts Editor&lt;/a&gt;&lt;/strong&gt; - vertical video for TikTok, Reels and Shorts. Install: &lt;code&gt;npx clawhub@latest install shorts-editor&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://clawhub.ai/nemovideonemo/video-caption-tool" rel="noopener noreferrer"&gt;Video Caption Tool&lt;/a&gt;&lt;/strong&gt; - auto subtitles, 50+ language translation, SRT export. Install: &lt;code&gt;npx clawhub@latest install video-caption-tool&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>openclaw</category>
      <category>ai</category>
      <category>webdev</category>
      <category>video</category>
    </item>
  </channel>
</rss>
