<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[The Signal]]></title><description><![CDATA[A former Google senior staff engineer's first-principles analysis of the tech that truly matters, finding the signal in the noise of AI, DeFi, and beyond.]]></description><link>https://ruidiao.substack.com</link><image><url>https://substackcdn.com/image/fetch/$s_!joKa!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3457ed0-47df-4a24-9de2-ef48fd1d51a3_200x200.png</url><title>The Signal</title><link>https://ruidiao.substack.com</link></image><generator>Substack</generator><lastBuildDate>Tue, 23 Jun 2026 03:23:54 GMT</lastBuildDate><atom:link href="https://ruidiao.substack.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Rui Diao]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[ruidiao@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[ruidiao@substack.com]]></itunes:email><itunes:name><![CDATA[Rui Diao]]></itunes:name></itunes:owner><itunes:author><![CDATA[Rui Diao]]></itunes:author><googleplay:owner><![CDATA[ruidiao@substack.com]]></googleplay:owner><googleplay:email><![CDATA[ruidiao@substack.com]]></googleplay:email><googleplay:author><![CDATA[Rui Diao]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[Home AI Assistant DIY (Part 4): Building a Real-Time AI Pipeline]]></title><description><![CDATA[In Part 3, I trained a wake word model.]]></description><link>https://ruidiao.substack.com/p/home-ai-assistant-diy-part-4-building</link><guid isPermaLink="false">https://ruidiao.substack.com/p/home-ai-assistant-diy-part-4-building</guid><dc:creator><![CDATA[Rui Diao]]></dc:creator><pubDate>Wed, 27 May 2026 16:59:42 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!D5DL!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Febed4e3b-a6d5-4df8-b3ac-cbebe02d405c_1376x768.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In Part 3, I trained a wake word model. The camera now listens efficiently, consuming almost no power until it hears its name.</p><p>When it wakes up, it needs to do three things fast: understand what was said, decide a response, and speak it back. This requires three separate AI services running in sequence. Speech-to-Text (STT) for transcribing the user&#8217;s voice. A large language model (LLM) for understanding and reasoning. And Text-to-Speech (TTS) for generating the spoken response.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://ruidiao.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading The Signal! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!D5DL!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Febed4e3b-a6d5-4df8-b3ac-cbebe02d405c_1376x768.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!D5DL!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Febed4e3b-a6d5-4df8-b3ac-cbebe02d405c_1376x768.jpeg 424w, https://substackcdn.com/image/fetch/$s_!D5DL!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Febed4e3b-a6d5-4df8-b3ac-cbebe02d405c_1376x768.jpeg 848w, https://substackcdn.com/image/fetch/$s_!D5DL!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Febed4e3b-a6d5-4df8-b3ac-cbebe02d405c_1376x768.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!D5DL!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Febed4e3b-a6d5-4df8-b3ac-cbebe02d405c_1376x768.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!D5DL!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Febed4e3b-a6d5-4df8-b3ac-cbebe02d405c_1376x768.jpeg" width="1376" height="768" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ebed4e3b-a6d5-4df8-b3ac-cbebe02d405c_1376x768.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:768,&quot;width&quot;:1376,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:422239,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://ruidiao.substack.com/i/199488504?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Febed4e3b-a6d5-4df8-b3ac-cbebe02d405c_1376x768.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!D5DL!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Febed4e3b-a6d5-4df8-b3ac-cbebe02d405c_1376x768.jpeg 424w, https://substackcdn.com/image/fetch/$s_!D5DL!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Febed4e3b-a6d5-4df8-b3ac-cbebe02d405c_1376x768.jpeg 848w, https://substackcdn.com/image/fetch/$s_!D5DL!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Febed4e3b-a6d5-4df8-b3ac-cbebe02d405c_1376x768.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!D5DL!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Febed4e3b-a6d5-4df8-b3ac-cbebe02d405c_1376x768.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The challenge is latency. A home assistant that takes 10 seconds to respond to every request is not useful. The pipeline needs to be fast, and that requires careful choices.</p><h2><strong>The three services</strong></h2><p>Each stage introduces its own delay.</p><p>STT models process audio and produce text. Good models are computationally expensive. Cheap models make transcription errors that confuse the LLM downstream. The goal is a model that balances accuracy with speed.</p><p>The LLM is the heaviest stage. It has to understand the query, reason about context, decide if tools are needed, and generate a response. Each step takes time. Response generation is especially slow because it happens token by token.</p><p>TTS is fast relative to the others, but it still adds overhead. Generating natural-sounding speech takes compute, and the full response must be generated before playback starts, unless you stream it.</p><h2><strong>Speed is the requirement</strong></h2><p>For this use case, speed is the most important metric. A slow assistant does not get used. I decided early that every choice in the pipeline would prioritize latency.</p><p>This means choosing fast models over accurate models. It means streaming STT to overlap with LLM processing. It means pipelining TTS by splitting responses into sentences. It means optimizing the network path between services. It means accepting that some accuracy trade-offs are worth the speed gain.</p><h2><strong>Choosing the LLM</strong></h2><p>The LLM is the bottleneck. I tested several options.</p><p>I am currently using Gemini 3.1 Flash Lite. It is fast. The API response times are consistently low, and the model quality is good enough for the types of queries a home assistant handles. Calendar checks, object recognition, simple questions about what the camera sees.</p><p>Groq is another option. They run open-source models on custom hardware optimized for inference speed. The latency is impressive. The drawback is model selection. You are limited to the models Groq hosts, and those change over time.</p><p>Cerebras is similar. Their hardware is designed for low-latency inference, and the speed shows in benchmarks. But again, you depend on their model catalog.</p><p>All of these are cloud services, which introduces a different kind of latency. Network round trips. API queue times. Service availability. For a home assistant, cloud dependency also raises the privacy concerns I discussed in Part 1.</p><p>That said, the data I send to remote LLMs is relatively limited. The camera recordings stay on my device. I never upload video footage to the cloud. The assistant only sends transcribed text to the LLM, and the content of those transcriptions is usually mundane. Calendar checks. Simple questions about objects in view. The camera is rarely asked to process saved recordings. I will cover recording handling in a future article.</p><h2><strong>The local GPU question</strong></h2><p>The ideal solution for speed is running a local model on a local GPU. No network latency. No API queues. No dependence on external services. Full privacy.</p><p>But there is a cost problem. A local GPU capable of running a capable model costs several thousand dollars. And the GPU sits idle most of the time. A home assistant is used sporadically throughout the day. Fifteen seconds of inference here, thirty seconds there. The rest of the time, the GPU is doing nothing.</p><p>Paying thousands of dollars and dedicating power to a GPU that runs for minutes per day is hard to justify. Cloud APIs charge per request. You pay only for what you use. For a home assistant, that pricing model makes more sense.</p><p>I believe local GPU will become the standard eventually. Hardware costs will come down. Smaller, more efficient models will run on cheaper hardware. And the privacy and latency advantages are real. But for 2026, cloud services are the practical choice for most people building their own system.</p><h2><strong>Streaming as a latency hack</strong></h2><p>Full token-level streaming from the LLM through TTS sounds great in theory. In practice, I found it too complex to implement reliably. The timing gets tricky when the TTS system has to handle partial tokens cleanly.</p><p>But two forms of streaming are worth the effort.</p><p>The most effective one is streaming STT. The user may take several seconds to finish a question. That time should not be wasted. With streaming speech recognition, the system produces partial transcripts as the user speaks, rather than waiting for complete silence. The LLM can start processing the first few words while the user is still talking. By the time the user finishes speaking, the LLM has already started generating a response.</p><p>Streaming TTS is useful only when the response is long. For short answers, the overhead of setting up the stream cancels the benefit. My approach is simpler. I take the LLM&#8217;s full response, cut it into sentences, and send each sentence to TTS as it becomes available. The first sentence starts playing while the rest of the response is still being generated. This is not true streaming, but it achieves the same effect with much less complexity.</p><h2><strong>The conversation continuity trick</strong></h2><p>There is another latency problem that streaming does not solve. Some queries require tool calls.</p><p>When the user asks &#8220;Do we have any plans this weekend?&#8221; the assistant needs to check a calendar. That means the LLM recognizes the intent, returns a tool call, the calendar API runs its query, and the result gets fed back into the LLM before it generates the final response. Each tool call adds seconds of latency.</p><p>I found a simple fix for this.</p><p>When the LLM decides it needs a tool, the assistant immediately says something like &#8220;Let me check that for you&#8221; or &#8220;Let me take a look.&#8221; This filler speech plays while the tool runs in the background. The user hears a natural response instead of dead silence.</p><p>The same trick works for visual queries. If the user asks &#8220;What is that on the counter?&#8221; the assistant can say &#8220;Let me take a look&#8221; while the vision model processes the camera frame. By the time the filler speech ends, the tool result is ready, and the assistant delivers the actual answer.</p><p>This is a small detail, but it affects how responsive the system feels. Silence makes a product feel broken. A quick acknowledgment makes it feel responsive, even when the underlying processing takes time.</p><h2><strong>An end-to-end alternative worth trying</strong></h2><p>Google also offers the Gemini Live API. It handles the full pipeline in a single WebSocket connection. STT, LLM, and TTS all run together on the server side, with low-latency audio output streaming back to the client. It is designed for exactly this use case.</p><p>In theory, an end-to-end approach should deliver better quality than stitching separate models together. The LLM has access to the raw audio and can use tone, emphasis, and timing to interpret meaning. The TTS output can match the model&#8217;s intended delivery. The whole pipeline benefits from tight integration.</p><p>I have not spent much time testing it yet. But it is worth trying.</p><h2><strong>What comes next</strong></h2><p>The pipeline works. STT captures the query, the LLM processes it with streaming, tool calls feel natural with filler speech, and TTS delivers the response quickly.</p><p>The next part of this project is about video recordings. The assistant and the recording system will be separate modules. Recordings are about capturing and storing video locally, without cloud uploads or subscriptions. That will be the topic of the next article.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://ruidiao.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading The Signal! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[I Went to Google I/O 2026. What I Saw Wasn't a Model Show. It Was a Platform Pivot.]]></title><description><![CDATA[I attended Google I/O 2026 in person.]]></description><link>https://ruidiao.substack.com/p/i-went-to-google-io-2026-what-i-saw</link><guid isPermaLink="false">https://ruidiao.substack.com/p/i-went-to-google-io-2026-what-i-saw</guid><dc:creator><![CDATA[Rui Diao]]></dc:creator><pubDate>Fri, 22 May 2026 00:39:32 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!FzP1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad278d3e-e1f5-4414-a191-d6e667aeed78_4000x3000.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I attended Google I/O 2026 in person. A few things about the experience surprised me, and one of them is not getting much attention online.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!FzP1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad278d3e-e1f5-4414-a191-d6e667aeed78_4000x3000.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!FzP1!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad278d3e-e1f5-4414-a191-d6e667aeed78_4000x3000.jpeg 424w, https://substackcdn.com/image/fetch/$s_!FzP1!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad278d3e-e1f5-4414-a191-d6e667aeed78_4000x3000.jpeg 848w, https://substackcdn.com/image/fetch/$s_!FzP1!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad278d3e-e1f5-4414-a191-d6e667aeed78_4000x3000.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!FzP1!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad278d3e-e1f5-4414-a191-d6e667aeed78_4000x3000.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!FzP1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad278d3e-e1f5-4414-a191-d6e667aeed78_4000x3000.jpeg" width="1456" height="1092" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ad278d3e-e1f5-4414-a191-d6e667aeed78_4000x3000.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1092,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:3389914,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://ruidiao.substack.com/i/198782003?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d5430cc-62ef-4b32-9e16-5b2431f36885_4000x3000.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!FzP1!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad278d3e-e1f5-4414-a191-d6e667aeed78_4000x3000.jpeg 424w, https://substackcdn.com/image/fetch/$s_!FzP1!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad278d3e-e1f5-4414-a191-d6e667aeed78_4000x3000.jpeg 848w, https://substackcdn.com/image/fetch/$s_!FzP1!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad278d3e-e1f5-4414-a191-d6e667aeed78_4000x3000.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!FzP1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad278d3e-e1f5-4414-a191-d6e667aeed78_4000x3000.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Several rumors turned out to be real. Gemini Omni and Gemini Spark launched as expected. But the community had a different hope going in. A lot of people expected Google to release a model that beat every existing top model on benchmarks. That did not happen. And the reactions were predictable.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://ruidiao.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading The Signal! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h2><strong>What Wasn&#8217;t Great</strong></h2><p>Let me start with what did not work well.</p><p>Google did not launch any model during I/O that was strong enough to get the community excited. Gemini Omni is an impressive concept. It can create anything from anything. But for now, that starts with video only. Gemini 3.5 did arrive, but only in the Flash variant, and it costs about three times what Gemini 3 Flash costs. I saw comments online saying Google is losing on models, or even losing on AI overall. That is not true. Google&#8217;s research pipeline and infrastructure are deep. But I understand why people felt underwhelmed. The model launches were not yet impressive.</p><p>The other problem was branding. Google now has too many AI brands and it is probably already confusing people. Just to name a few: Imagen, Veo, Flow, AI Studio, Antigravity, Gemini, Nano Banana, Gemma. This I/O made it worse. In particular, the transition of Gemini CLI (which competes with Claude Code) to Antigravity CLI drew real complaints on social networks. Developers who had invested in one product found themselves being asked to learn a new name and mental model.</p><h2><strong>What I Noticed That Almost No One Is Talking About</strong></h2><p>Here is the part that surprised me. In the middle of all the model debate and brand confusion, I noticed something that is getting almost no discussion on social networks.</p><p>Google&#8217;s focus has shifted. They are building AI platforms and ecosystems. Not individual models. Not individual tools. Platforms.</p><p>Watch the Demis Hassabis <a href="https://io.google/2026/explore/pa-keynote-16">fireside chat</a> during the conference. When he was asked what he would expect to talk about at next year&#8217;s I/O, the first thing he said was this: &#8220;There will be a lot more agents in the real world are kind of embedded in our workflows.&#8221; That was the first thing on his mind. Not stronger models. Not a world model. Not a better AI assistant. It was agents embedded in workflows. It was platform.</p><p>Consider Antigravity. It is becoming Google&#8217;s agent-first development platform. That is why you see Antigravity App, Antigravity SDK, and Antigravity CLI. All three are different entry points to the same platform vision.</p><p>AI Studio is also becoming a platform, but through a different path. Google has made it very easy to prototype and deploy apps there. There are close integrations with Google Cloud for deployment and with Google Play for publishing apps. The functionality overlaps with Antigravity in some places. But both feel like Google is exploring what an AI platform could look like.</p><h2><strong>The Model War Will Eventually Become Less Meaningful</strong></h2><p>On social networks, people are still debating which model is the best. From my view, that debate is becoming less and less meaningful.</p><p>A great model launch gives you a few months of attention. But that is not a long-term win. It is hard to convert benchmark leadership into a reliable business. Whoever owns the AI platform wins over time.</p><p>This does not mean models are unimportant. A fundamentally different model architecture could change things entirely. But competing for benchmark position alone is not a winning approach. Google seems to understand this. I am not sure the broader tech community does yet.</p><h2><strong>One Fun Note</strong></h2><p>I saw a lot of bananas at I/O. Real bananas and fake bananas. All because of the Nano Banana codename.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!clF-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F049c8c26-99bc-48ef-8502-e736c6476b4f_4000x3000.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!clF-!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F049c8c26-99bc-48ef-8502-e736c6476b4f_4000x3000.jpeg 424w, https://substackcdn.com/image/fetch/$s_!clF-!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F049c8c26-99bc-48ef-8502-e736c6476b4f_4000x3000.jpeg 848w, https://substackcdn.com/image/fetch/$s_!clF-!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F049c8c26-99bc-48ef-8502-e736c6476b4f_4000x3000.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!clF-!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F049c8c26-99bc-48ef-8502-e736c6476b4f_4000x3000.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!clF-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F049c8c26-99bc-48ef-8502-e736c6476b4f_4000x3000.jpeg" width="1456" height="1092" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/049c8c26-99bc-48ef-8502-e736c6476b4f_4000x3000.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1092,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!clF-!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F049c8c26-99bc-48ef-8502-e736c6476b4f_4000x3000.jpeg 424w, https://substackcdn.com/image/fetch/$s_!clF-!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F049c8c26-99bc-48ef-8502-e736c6476b4f_4000x3000.jpeg 848w, https://substackcdn.com/image/fetch/$s_!clF-!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F049c8c26-99bc-48ef-8502-e736c6476b4f_4000x3000.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!clF-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F049c8c26-99bc-48ef-8502-e736c6476b4f_4000x3000.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>I hope Google names the next model after something more interesting to eat. The conference floor could use some variety.</p><p>What do you think wins in the end: the best model or the best platform?</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://ruidiao.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading The Signal! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Home AI Assistant DIY (Part 3): The Wake Word Model]]></title><description><![CDATA[In Part 2, I installed custom firmware on a commercial camera.]]></description><link>https://ruidiao.substack.com/p/home-ai-assistant-diy-part-3-the</link><guid isPermaLink="false">https://ruidiao.substack.com/p/home-ai-assistant-diy-part-3-the</guid><dc:creator><![CDATA[Rui Diao]]></dc:creator><pubDate>Mon, 11 May 2026 17:48:41 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!joKa!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3457ed0-47df-4a24-9de2-ef48fd1d51a3_200x200.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In Part 2, I installed custom firmware on a commercial camera. I gained SSH access. I could stream video and send audio commands. The hardware foundation was ready.</p><p>The next step was giving the assistant ears.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://ruidiao.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading The Signal! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>I needed a way for the camera to know when I was talking to it. The straightforward approach is continuous listening. Stream all microphone audio to a Speech-to-Text (STT) model, transcribe everything, and look for a trigger phrase in the text.</p><p>That approach is wasteful.</p><p>STT models are heavy. Running one continuously consumes significant CPU, memory, and power. It introduces latency. Most of the time, a room is quiet. Or people are having conversations meant for each other, not the camera. Processing hours of background noise through a large neural network is not cost-effective.</p><p>A better way is to use a wake word model.</p><h2><strong>The gatekeeper</strong></h2><p>A wake word model is a small, highly specialized neural network. It does exactly one thing. It listens to a continuous audio stream and calculates the probability that a specific phrase was just spoken.</p><p>When it hears the phrase, it wakes up the main system. Only then does the heavy STT processing begin. Everything else is ignored.</p><p>Because of this specific focus, a wake word model is trained for a dedicated phrase. Using a generic model is less efficient.</p><p>I looked for tools to build one. <a href="https://github.com/dscripka/openWakeWord">OpenWakeWord</a> is an existing framework for this. It provides an architecture for training small models that run efficiently on edge devices.</p><p>But training a model requires data. You need thousands of audio samples of different people saying your specific wake word. You also need negative examples so the model learns what to ignore. Recording these manually is not practical for a DIY project.</p><h2><strong>Automating the training</strong></h2><p>I found a library called <a href="https://github.com/livekit/livekit-wakeword">livekit-wakeword</a>. It automates the training process on top of the OpenWakeWord architecture.</p><p>It solves the data problem using synthetic generation. The library leverages text-to-speech models like Piper and VoxCPM to create the training data.</p><p>I provided the text of my wake word. The library generated thousands of audio clips in different voices. It created positive examples of the wake word. It generated negative adversarial examples. It mixed in background noise. Then it trained a model and exported it to the ONNX format.</p><p>The process is easy to use. I defined my configuration and let it run.</p><h2><strong>The silence problem</strong></h2><p>The automation worked well, but I noticed a problem during my first few attempts.</p><p>The text-to-speech models often generated audio clips with significant silence at the beginning or end. When these padded clips were fed into the training pipeline, it confused the model. The model learned to associate empty space with the wake word. The accuracy degraded.</p><p>I solved this by adding one additional step. I wrote a script to strip the silence from the generated audio files before passing them to the training phase.</p><p>Once I removed the dead air, the training worked. The rest of the process remained mostly automatic.</p><h2><strong>The result</strong></h2><p>The final trained model is only 165 kilobytes in size.</p><p>Because it exports to ONNX format, it is highly optimized. I can run it continuously on a standard CPU with very low utilization. The camera sits quietly, consuming almost no processing power, until it hears its name.</p><p>The assistant can now listen efficiently. The next challenge is figuring out what happens after it wakes up. I need to process the speech, understand the intent, and generate a response. I will cover that pipeline in the next article.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://ruidiao.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading The Signal! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Home AI Assistant DIY (Part 2): Camera Selection and First Steps]]></title><description><![CDATA[In Part 1, I explained why I decided to build my own home camera system.]]></description><link>https://ruidiao.substack.com/p/home-ai-assistant-diy-part-2-camera</link><guid isPermaLink="false">https://ruidiao.substack.com/p/home-ai-assistant-diy-part-2-camera</guid><dc:creator><![CDATA[Rui Diao]]></dc:creator><pubDate>Tue, 05 May 2026 20:34:11 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!UIjb!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f6260da-401d-4e91-ad5d-fefe065c8d92_3000x2915.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In Part 1, I explained why I decided to build my own home camera system. Commercial products degrade over time. Ads appear. Features disappear. Privacy settings change. I wanted a camera that stores everything locally, runs no ads, and works better over time because I control it.</p><p>Now I needed hardware.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://ruidiao.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading The Signal! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h2><strong>Two paths</strong></h2><p>I had two options.</p><p>Option one: buy a commercial camera and install custom firmware. This gives you a finished product with a nice case, power supply, and everything integrated. The trade-off is you cannot easily modify the hardware. You get what the manufacturer built.</p><p>Option two: buy a development board and build from scratch. Selecting components. Designing or finding a 3D-printable case. Wiring power and connections. Integrating the pieces. More work, but total control over the final product.</p><p>For my first DIY camera project, I went with option one. I wanted to focus on software and AI integration, not hardware assembly. A commercial camera with custom firmware would let me start faster.</p><h2><strong>Research before purchase</strong></h2><p>I researched firmware options before buying anything. Which cameras had active open-source firmware communities? What features did those firmware releases support? How difficult was installation?</p><p>This research led me to <a href="https://github.com/themactep/thingino-firmware">Thingino</a>, an open-source firmware for IP cameras built on Ingenic SoCs. Thingino replaces the manufacturer&#8217;s firmware with a system designed for local control. No cloud dependency. No vendor lock-in. SSH access by default.</p><p>The project maintains a list of over 150 supported cameras. Wyze, Eufy, Xiaomi, TP-Link Tapo. Lesser-known brands like Cinnado, Galayou, and Wansview. All hackable with the same firmware.</p><h2><strong>Choosing Cinnado D1</strong></h2><p>I needed two-way audio for communication. Night vision for after dark. Pan and tilt for adjusting the view. Good resolution. And an installation process that did not require soldering or specialized tools.</p><p>The Cinnado D1 matched all of these. 360-degree pan and tilt. Two-way audio. Night vision. 2K sensor. I bought it for $10 during an Amazon sale. Right now it sells for around $15. And it supports what Thingino calls &#8220;no-tool installation.&#8221;</p><p>No-tool installation means placing a firmware file on a microSD card, inserting the card into the camera, and powering it on. The camera&#8217;s stock bootloader looks for a specific file name and uses it to replace the firmware.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!UIjb!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f6260da-401d-4e91-ad5d-fefe065c8d92_3000x2915.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!UIjb!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f6260da-401d-4e91-ad5d-fefe065c8d92_3000x2915.jpeg 424w, https://substackcdn.com/image/fetch/$s_!UIjb!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f6260da-401d-4e91-ad5d-fefe065c8d92_3000x2915.jpeg 848w, https://substackcdn.com/image/fetch/$s_!UIjb!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f6260da-401d-4e91-ad5d-fefe065c8d92_3000x2915.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!UIjb!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f6260da-401d-4e91-ad5d-fefe065c8d92_3000x2915.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!UIjb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f6260da-401d-4e91-ad5d-fefe065c8d92_3000x2915.jpeg" width="3000" height="2915" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8f6260da-401d-4e91-ad5d-fefe065c8d92_3000x2915.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:2915,&quot;width&quot;:3000,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:930096,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ruidiao.substack.com/i/196584656?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F25c7473a-3b31-4656-b71e-b976a8e2a910_4000x3000.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!UIjb!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f6260da-401d-4e91-ad5d-fefe065c8d92_3000x2915.jpeg 424w, https://substackcdn.com/image/fetch/$s_!UIjb!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f6260da-401d-4e91-ad5d-fefe065c8d92_3000x2915.jpeg 848w, https://substackcdn.com/image/fetch/$s_!UIjb!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f6260da-401d-4e91-ad5d-fefe065c8d92_3000x2915.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!UIjb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f6260da-401d-4e91-ad5d-fefe065c8d92_3000x2915.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>I bought the Cinnado D1.</p><h2><strong>Verifying the hardware</strong></h2><p>Thingino supports two hardware variants of the Cinnado D1. One uses the T23N SoC. The other uses the T31L SoC. Each requires a different firmware file. I needed to identify which chip my camera contained.</p><p>The Thingino documentation explained how to check. The Cinnado D1 case consists of two parts clipped together. No screws. I used a plastic credit card to separate the upper case from the bottom, adjusted the camera module, and found T23 printed on the circuit board.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!hLBO!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F623e8eb6-318a-424d-8fb5-46bfd0d04249_3000x2985.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!hLBO!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F623e8eb6-318a-424d-8fb5-46bfd0d04249_3000x2985.jpeg 424w, https://substackcdn.com/image/fetch/$s_!hLBO!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F623e8eb6-318a-424d-8fb5-46bfd0d04249_3000x2985.jpeg 848w, https://substackcdn.com/image/fetch/$s_!hLBO!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F623e8eb6-318a-424d-8fb5-46bfd0d04249_3000x2985.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!hLBO!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F623e8eb6-318a-424d-8fb5-46bfd0d04249_3000x2985.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!hLBO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F623e8eb6-318a-424d-8fb5-46bfd0d04249_3000x2985.jpeg" width="3000" height="2985" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/623e8eb6-318a-424d-8fb5-46bfd0d04249_3000x2985.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:2985,&quot;width&quot;:3000,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1867819,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ruidiao.substack.com/i/196584656?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F725bc399-d2fb-40ae-adfd-1b31a63a23da_4000x3000.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!hLBO!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F623e8eb6-318a-424d-8fb5-46bfd0d04249_3000x2985.jpeg 424w, https://substackcdn.com/image/fetch/$s_!hLBO!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F623e8eb6-318a-424d-8fb5-46bfd0d04249_3000x2985.jpeg 848w, https://substackcdn.com/image/fetch/$s_!hLBO!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F623e8eb6-318a-424d-8fb5-46bfd0d04249_3000x2985.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!hLBO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F623e8eb6-318a-424d-8fb5-46bfd0d04249_3000x2985.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Five minutes. The case opened easily. The chip was visible without disconnecting anything. I closed the case and moved on.</p><h2><strong>Installing Thingino</strong></h2><p>I downloaded the T23N firmware from the Thingino releases page, copied it to a microSD card, inserted the card, and plugged in the power. The camera installed the firmware automatically. Two minutes later, it finished and entered setup mode.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!qDe_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd263c3c-30bf-4067-996b-ad8fc2ac0c5c_3104x2688.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!qDe_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd263c3c-30bf-4067-996b-ad8fc2ac0c5c_3104x2688.jpeg 424w, https://substackcdn.com/image/fetch/$s_!qDe_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd263c3c-30bf-4067-996b-ad8fc2ac0c5c_3104x2688.jpeg 848w, https://substackcdn.com/image/fetch/$s_!qDe_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd263c3c-30bf-4067-996b-ad8fc2ac0c5c_3104x2688.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!qDe_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd263c3c-30bf-4067-996b-ad8fc2ac0c5c_3104x2688.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!qDe_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd263c3c-30bf-4067-996b-ad8fc2ac0c5c_3104x2688.jpeg" width="3104" height="2688" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/cd263c3c-30bf-4067-996b-ad8fc2ac0c5c_3104x2688.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:2688,&quot;width&quot;:3104,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1370451,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ruidiao.substack.com/i/196584656?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26034231-3af1-4385-8b90-a05cf00dd39c_4000x3000.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!qDe_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd263c3c-30bf-4067-996b-ad8fc2ac0c5c_3104x2688.jpeg 424w, https://substackcdn.com/image/fetch/$s_!qDe_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd263c3c-30bf-4067-996b-ad8fc2ac0c5c_3104x2688.jpeg 848w, https://substackcdn.com/image/fetch/$s_!qDe_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd263c3c-30bf-4067-996b-ad8fc2ac0c5c_3104x2688.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!qDe_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd263c3c-30bf-4067-996b-ad8fc2ac0c5c_3104x2688.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Thingino uses a captive portal for initial configuration. I connected my phone to the camera&#8217;s Wi-Fi network, opened a browser, and entered my home network credentials. The camera joined my network and became accessible through its IP address.</p><h2><strong>What SSH access unlocks</strong></h2><p>With Thingino installed, I could SSH into the camera.</p><p>This is what separates a consumer product from a development platform. SSH access gives me control through command-line tools. Subscribe to the RTSP stream for live video. Use the <code>play</code> command to send audio through the speaker. Use <code>motors</code> commands to pan and tilt.</p><div class="native-video-embed" data-component-name="VideoPlaceholder" data-attrs="{&quot;mediaUploadId&quot;:&quot;8a389662-0da9-45a4-b5ba-a6d6db935c10&quot;,&quot;duration&quot;:null}"></div><p>These are the building blocks for the Home AI Assistant. A camera that accepts commands and provides streams can integrate with other systems. I can write software that captures frames, processes them with AI, and responds through audio or motion.</p><p>The stock Cinnado firmware would never allow this. It locks the camera into the manufacturer&#8217;s app and cloud service. Thingino unlocks the hardware.</p><h2><strong>What comes next</strong></h2><p>The camera now sits on my desk, running Thingino, accessible through SSH. I can see the video stream. I can send audio. I can control the motors.</p><p>The hardware foundation exists. Now I need to build the software that captures video, applies AI processing, and coordinates responses. That work will determine whether this project becomes something genuinely useful or just an interesting experiment.</p><p>Future articles will cover the software architecture, AI integration, and the challenges of making a camera that answers questions about what it sees.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://ruidiao.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading The Signal! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Home AI Assistant DIY (Part 1): Why I'm Building My Own]]></title><description><![CDATA[Eight years ago, I bought a Yi Home Camera.]]></description><link>https://ruidiao.substack.com/p/home-ai-assistant-diy-part-1-why</link><guid isPermaLink="false">https://ruidiao.substack.com/p/home-ai-assistant-diy-part-1-why</guid><dc:creator><![CDATA[Rui Diao]]></dc:creator><pubDate>Thu, 30 Apr 2026 22:38:46 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!Ht8P!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb1a8b54e-4426-4bd2-85d1-1f8983ee8c49_3000x2829.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Eight years ago, I bought a Yi Home Camera. My daughter was about to be born, and I wanted a way to see her from anywhere. The camera worked well. I could check on her from my phone while traveling, talk to her through the two-way audio, and save clips of memorable moments. It captured her escaping from her crib and other moments I would have missed.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Ht8P!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb1a8b54e-4426-4bd2-85d1-1f8983ee8c49_3000x2829.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Ht8P!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb1a8b54e-4426-4bd2-85d1-1f8983ee8c49_3000x2829.jpeg 424w, https://substackcdn.com/image/fetch/$s_!Ht8P!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb1a8b54e-4426-4bd2-85d1-1f8983ee8c49_3000x2829.jpeg 848w, https://substackcdn.com/image/fetch/$s_!Ht8P!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb1a8b54e-4426-4bd2-85d1-1f8983ee8c49_3000x2829.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!Ht8P!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb1a8b54e-4426-4bd2-85d1-1f8983ee8c49_3000x2829.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Ht8P!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb1a8b54e-4426-4bd2-85d1-1f8983ee8c49_3000x2829.jpeg" width="3000" height="2829" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b1a8b54e-4426-4bd2-85d1-1f8983ee8c49_3000x2829.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:2829,&quot;width&quot;:3000,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1497429,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://ruidiao.substack.com/i/196053830?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4605cce4-f132-49b3-a21a-f1e44217445d_4000x3000.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Ht8P!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb1a8b54e-4426-4bd2-85d1-1f8983ee8c49_3000x2829.jpeg 424w, https://substackcdn.com/image/fetch/$s_!Ht8P!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb1a8b54e-4426-4bd2-85d1-1f8983ee8c49_3000x2829.jpeg 848w, https://substackcdn.com/image/fetch/$s_!Ht8P!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb1a8b54e-4426-4bd2-85d1-1f8983ee8c49_3000x2829.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!Ht8P!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb1a8b54e-4426-4bd2-85d1-1f8983ee8c49_3000x2829.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Yi Home Camera that I used for 8 years</figcaption></figure></div><p>The app worked well too. Clean interface, quick access to live feeds, easy playback. It felt like a product designed to help parents, not extract value from them.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://ruidiao.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading The Signal! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>That changed gradually.</p><h2><strong>The slow decay</strong></h2><p>Over time, the Yi Home app became harder to use. The cause wasn&#8217;t bugs or poor design. It was deliberate friction. Ads appeared. First a short one when opening the app. Then longer ones. Then ads before watching recorded clips. The camera was designed to upload clips to cloud from the start. I accepted that trade-off for convenience. But now to watch my own recordings, stored on Yi&#8217;s cloud, I have to sit through ads.</p><p>The only way to remove ads is a subscription. Yi wants me to pay monthly to watch my own recordings without interruption. I was fine with cloud storage. I am not fine with paying a recurring fee to access videos that I didn&#8217;t intend to upload, or watching ads to see my own home footage.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!oF8p!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe46e8ec5-8a0a-4fa3-bb48-939eec0ae01e_1080x1249.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!oF8p!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe46e8ec5-8a0a-4fa3-bb48-939eec0ae01e_1080x1249.jpeg 424w, https://substackcdn.com/image/fetch/$s_!oF8p!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe46e8ec5-8a0a-4fa3-bb48-939eec0ae01e_1080x1249.jpeg 848w, https://substackcdn.com/image/fetch/$s_!oF8p!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe46e8ec5-8a0a-4fa3-bb48-939eec0ae01e_1080x1249.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!oF8p!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe46e8ec5-8a0a-4fa3-bb48-939eec0ae01e_1080x1249.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!oF8p!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe46e8ec5-8a0a-4fa3-bb48-939eec0ae01e_1080x1249.jpeg" width="1080" height="1249" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e46e8ec5-8a0a-4fa3-bb48-939eec0ae01e_1080x1249.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1249,&quot;width&quot;:1080,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:117736,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ruidiao.substack.com/i/196053830?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1128244f-f350-4c53-be5b-4de39be37cbf_1080x2340.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!oF8p!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe46e8ec5-8a0a-4fa3-bb48-939eec0ae01e_1080x1249.jpeg 424w, https://substackcdn.com/image/fetch/$s_!oF8p!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe46e8ec5-8a0a-4fa3-bb48-939eec0ae01e_1080x1249.jpeg 848w, https://substackcdn.com/image/fetch/$s_!oF8p!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe46e8ec5-8a0a-4fa3-bb48-939eec0ae01e_1080x1249.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!oF8p!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe46e8ec5-8a0a-4fa3-bb48-939eec0ae01e_1080x1249.jpeg 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Yi Home Camera subscription plans</figcaption></figure></div><p>The same connectivity that adds smart features allows product degradation. Once a device connects to the internet, the manufacturer controls it remotely. Features you paid for can disappear. Ads can appear. Privacy settings can change. You bought the hardware, but you rent the functionality.</p><h2><strong>A different approach</strong></h2><p>I decided to build my own system.</p><p>I wanted more than a Yi replacement. I wanted a home camera that stores everything locally. No cloud uploads unless I choose them. No subscription fees. No ads that will appear through future updates.</p><p>And I wanted something smarter than traditional cameras.</p><p>Imagine asking the camera a question while holding a book. &#8220;Tell me about the author.&#8221; The camera sees the book cover, identifies it, searches for author information, and speaks the answer. Imagine asking &#8220;Do we have any schedules this weekend?&#8221; The camera checks both my calendar and my wife&#8217;s calendar, then summarizes what&#8217;s coming up.</p><p>These solve real problems. A camera with AI shifts from monitoring device to assistant. It can answer questions about what&#8217;s in view, check calendars, and provide information without requiring me to pull out a phone.</p><p>Commercial cameras cannot offer this path. Their AI features focus on detection alerts and motion classification. Useful, but limited. A DIY system can integrate any AI capability I want, limited only by what the hardware can run and what software I can build.</p><h2><strong>The project</strong></h2><p>I call this project Home AI Assistant. Traditional home camera features plus AI capabilities, all running locally.</p><p>The basics: motion-based video clip saving, live streaming to phone, two-way audio communication.</p><p>The AI features: visual question answering, calendar integration, and room to add more capabilities over time.</p><p>All recordings stored locally. No cloud required. No subscription. No ads.</p><p>I have already started development. Future articles will cover hardware choices, software architecture, AI integration, and the challenges I run into along the way.</p><p>If you have dealt with similar frustrations with smart home products, or if you are curious about building AI-powered devices that keep your data local, this series is for you.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://ruidiao.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading The Signal! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[I Used AI to Make a Marketing Video. Here's What Happened]]></title><description><![CDATA[Yesterday, Google launched Lyria 3. I opened the Gemini app to try it, typed in a prompt, and 30 seconds later, I had a custom track. The music was genuinely good.]]></description><link>https://ruidiao.substack.com/p/i-used-ai-to-make-a-marketing-video</link><guid isPermaLink="false">https://ruidiao.substack.com/p/i-used-ai-to-make-a-marketing-video</guid><dc:creator><![CDATA[Rui Diao]]></dc:creator><pubDate>Thu, 19 Feb 2026 17:43:28 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!x1R0!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07267f84-11c5-4559-a6fe-adb1fb840200_449x397.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="native-video-embed" data-component-name="VideoPlaceholder" data-attrs="{&quot;mediaUploadId&quot;:&quot;bb6b8d72-c82d-402b-a522-c6ec8a72e1aa&quot;,&quot;duration&quot;:null}"></div><p>Yesterday, Google launched <a href="https://deepmind.google/models/lyria/">Lyria 3</a>. I opened the Gemini app to try it, typed in a prompt, and 30 seconds later, I had a custom track. The music was genuinely good.</p><p>So I got curious: what else could AI help with?</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://ruidiao.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading The Signal! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>I decided to test it. I&#8217;d make a 30-second marketing video - using my <a href="https://github.com/diaorui/peek-deck">previous project</a> as a test case. No code written by me. No video editing software. Just prompting and guiding. The background music would come from Lyria 3. For the visuals, I&#8217;d use <a href="https://www.remotion.dev/">Remotion</a> (a video programming framework) and let AI generate the code.</p><p>Here&#8217;s what happened.</p><h2><strong>The Good: AI Music Actually Works</strong></h2><p>Lyria 3 delivered. I fed it my project&#8217;s README so it understood what the product did, described the mood I wanted, and 30 seconds later had a track with custom lyrics. The music sounded professional enough for a marketing context. I couldn&#8217;t have produced something like this myself - I have no musical training. But now I don&#8217;t need to.</p><h2><strong>The Bad: AI Visuals Need a Crutch</strong></h2><p>The visuals were a different story.</p><p>I started by describing what I wanted. Clean visuals. Product demo with text overlays. The results were technically correct but boring. Flat. The kind of video that checks boxes but doesn&#8217;t feel anything.</p><p>That&#8217;s when it hit me: AI doesn&#8217;t have visual taste. Neither do I, honestly. We&#8217;re both guessing.</p><p>So I tried giving AI a reference. I showed it <a href="https://www.youtube.com/watch?v=Op8X8RmiE98">Lyria 3&#8217;s marketing video</a>. &#8220;Make something like this.&#8221; The difference was immediate. The AI couldn&#8217;t match the original quality, but it understood the visual language - the pacing, the layout, the transitions. It had something to follow.</p><p>My video isn&#8217;t as good as Google&#8217;s. But it&#8217;s infinitely better than what I got from just describing what I wanted. The lesson: for visuals, AI follows examples better than it creates from scratch.</p><h2><strong>The Ugly: The Iteration Loop</strong></h2><p>Then came the actual work.</p><p>Ideally, the iteration loop would be automated: generate code &#8594; render &#8594; screenshot &#8594; review &#8594; correct &#8594; repeat. But AI doesn&#8217;t naturally do this. Without explicit prompting, it does a one-off implementation with many problems and assumes it&#8217;s done. It&#8217;s me who has to tell AI to follow these steps. And even then, after several iterations, AI starts skipping steps. It tells me the video is done when it isn&#8217;t. It skips the screenshot verification and just says it&#8217;s complete. So I have to nudge it back on track.</p><p>This took a few hours for 30 seconds. And just like a human designer, AI generated dozens of versions: video_v3, video_v4, video_v5... then verify_s3, verify_s3_vfinal, verify_s3_vfinal_fix, verify_final, verify_final_v2... The folder looks exactly like what you&#8217;d see after weeks of back-and-forth with a human.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!x1R0!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07267f84-11c5-4559-a6fe-adb1fb840200_449x397.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!x1R0!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07267f84-11c5-4559-a6fe-adb1fb840200_449x397.png 424w, https://substackcdn.com/image/fetch/$s_!x1R0!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07267f84-11c5-4559-a6fe-adb1fb840200_449x397.png 848w, https://substackcdn.com/image/fetch/$s_!x1R0!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07267f84-11c5-4559-a6fe-adb1fb840200_449x397.png 1272w, https://substackcdn.com/image/fetch/$s_!x1R0!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07267f84-11c5-4559-a6fe-adb1fb840200_449x397.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!x1R0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07267f84-11c5-4559-a6fe-adb1fb840200_449x397.png" width="449" height="397" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/07267f84-11c5-4559-a6fe-adb1fb840200_449x397.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:397,&quot;width&quot;:449,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:20636,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ruidiao.substack.com/i/188521579?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07267f84-11c5-4559-a6fe-adb1fb840200_449x397.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!x1R0!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07267f84-11c5-4559-a6fe-adb1fb840200_449x397.png 424w, https://substackcdn.com/image/fetch/$s_!x1R0!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07267f84-11c5-4559-a6fe-adb1fb840200_449x397.png 848w, https://substackcdn.com/image/fetch/$s_!x1R0!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07267f84-11c5-4559-a6fe-adb1fb840200_449x397.png 1272w, https://substackcdn.com/image/fetch/$s_!x1R0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07267f84-11c5-4559-a6fe-adb1fb840200_449x397.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The bottleneck is the back-and-forth and the fact that AI loses focus over time. As context builds, quality drops. The same problem every developer knows: context window isn&#8217;t infinite.</p><h2><strong>Final Thoughts</strong></h2><p>AI is great at some parts of marketing video production and struggles with others. The future isn&#8217;t AI replacing humans - it&#8217;s AI handling what it&#8217;s good at, humans handling what they&#8217;re good at.</p><p>The floor is lowering. What used to require a team now needs one person with the right tools and patience to iterate. It&#8217;s not automation. It&#8217;s augmentation. And it&#8217;s becoming accessible to anyone willing to try.</p><p>I&#8217;m proof: I couldn&#8217;t make music this good. I couldn&#8217;t make visuals this polished. But together? A marketing video exists now that didn&#8217;t before.</p><p>And maybe next time, with better tools and better reference examples, it won&#8217;t take several hours. Maybe it&#8217;ll only take one.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://ruidiao.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading The Signal! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Workflow Engineering: How a Picture Fixed My AI Problem]]></title><description><![CDATA[I redesigned my personal website: ruidiao.dev. The new design has a Studio Ghibli-inspired aesthetic: soft sky gradients, floating clouds, parchment textures, hand-drawn borders. It looks warm and inviting.]]></description><link>https://ruidiao.substack.com/p/workflow-engineering-how-a-picture</link><guid isPermaLink="false">https://ruidiao.substack.com/p/workflow-engineering-how-a-picture</guid><dc:creator><![CDATA[Rui Diao]]></dc:creator><pubDate>Wed, 11 Feb 2026 19:02:10 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!vJLT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99ce4355-5d43-4a66-aab9-d8dae150c522_1414x848.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!vJLT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99ce4355-5d43-4a66-aab9-d8dae150c522_1414x848.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!vJLT!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99ce4355-5d43-4a66-aab9-d8dae150c522_1414x848.png 424w, https://substackcdn.com/image/fetch/$s_!vJLT!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99ce4355-5d43-4a66-aab9-d8dae150c522_1414x848.png 848w, https://substackcdn.com/image/fetch/$s_!vJLT!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99ce4355-5d43-4a66-aab9-d8dae150c522_1414x848.png 1272w, https://substackcdn.com/image/fetch/$s_!vJLT!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99ce4355-5d43-4a66-aab9-d8dae150c522_1414x848.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!vJLT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99ce4355-5d43-4a66-aab9-d8dae150c522_1414x848.png" width="1414" height="848" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/99ce4355-5d43-4a66-aab9-d8dae150c522_1414x848.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:848,&quot;width&quot;:1414,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:385713,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://ruidiao.substack.com/i/187664637?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99ce4355-5d43-4a66-aab9-d8dae150c522_1414x848.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!vJLT!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99ce4355-5d43-4a66-aab9-d8dae150c522_1414x848.png 424w, https://substackcdn.com/image/fetch/$s_!vJLT!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99ce4355-5d43-4a66-aab9-d8dae150c522_1414x848.png 848w, https://substackcdn.com/image/fetch/$s_!vJLT!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99ce4355-5d43-4a66-aab9-d8dae150c522_1414x848.png 1272w, https://substackcdn.com/image/fetch/$s_!vJLT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99ce4355-5d43-4a66-aab9-d8dae150c522_1414x848.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>I redesigned my personal website: <a href="https://ruidiao.dev">ruidiao.dev</a>. The new design has a Studio Ghibli-inspired aesthetic: soft sky gradients, floating clouds, parchment textures, hand-drawn borders. It looks warm and inviting.</p><p>But the interesting part isn&#8217;t the result. It&#8217;s how I got there.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://ruidiao.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading The Signal! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>I already had a website. This was just a style change. And what I discovered along the way says something important about working with AI today.</p><h2><strong>The Problem With &#8220;Just Add AI&#8221;</strong></h2><p>My existing site was built with Tailwind CSS. It looked fine. Clean, modern, functional.</p><p>But if you&#8217;ve seen AI-generated websites, you know exactly what I mean by &#8220;fine.&#8221; They all look kind of similar. Nice typography, sensible spacing, muted color palettes. Competent but boring. There&#8217;s an AI aesthetic emerging, and it&#8217;s generic.</p><p>I wanted something different. I asked a coding AI to make my website &#8220;Ghibli-style.&#8221;</p><p>The result was underwhelming. Some colors changed, maybe a border got tweaked. But it didn&#8217;t capture the aesthetic at all. It felt like the AI had no art sense.</p><p>To be fair, neither do I. But that&#8217;s not really the point. The AI was still trapped in that clean, safe, Tailwind mindset. It made reasonable assumptions based on its training data, but they were just safe, generic choices.</p><p>The problem wasn&#8217;t that the AI wasn&#8217;t capable enough. I was using a powerful model. The problem was my approach.</p><h2><strong>The Solution: Workflow Engineering</strong></h2><p>I tried something different. Instead of asking one AI to do everything, I broke the problem into steps.</p><p>First, I took a screenshot of my current website. Then I used an image editing AI to convert that screenshot into a Ghibli-style image.</p><p>The result was beautiful. Soft colors, hand-drawn feel, that distinctive storybook quality.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!sXe4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2aea6bfd-d614-4f1f-90ec-307b2bee0804_1792x888.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!sXe4!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2aea6bfd-d614-4f1f-90ec-307b2bee0804_1792x888.png 424w, https://substackcdn.com/image/fetch/$s_!sXe4!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2aea6bfd-d614-4f1f-90ec-307b2bee0804_1792x888.png 848w, https://substackcdn.com/image/fetch/$s_!sXe4!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2aea6bfd-d614-4f1f-90ec-307b2bee0804_1792x888.png 1272w, https://substackcdn.com/image/fetch/$s_!sXe4!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2aea6bfd-d614-4f1f-90ec-307b2bee0804_1792x888.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!sXe4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2aea6bfd-d614-4f1f-90ec-307b2bee0804_1792x888.png" width="1792" height="888" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2aea6bfd-d614-4f1f-90ec-307b2bee0804_1792x888.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:888,&quot;width&quot;:1792,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:3071487,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ruidiao.substack.com/i/187664637?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa902f57e-76ba-4cd3-acdc-5b9e042391f9_1792x2368.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!sXe4!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2aea6bfd-d614-4f1f-90ec-307b2bee0804_1792x888.png 424w, https://substackcdn.com/image/fetch/$s_!sXe4!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2aea6bfd-d614-4f1f-90ec-307b2bee0804_1792x888.png 848w, https://substackcdn.com/image/fetch/$s_!sXe4!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2aea6bfd-d614-4f1f-90ec-307b2bee0804_1792x888.png 1272w, https://substackcdn.com/image/fetch/$s_!sXe4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2aea6bfd-d614-4f1f-90ec-307b2bee0804_1792x888.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>There was just one problem: many of those visuals weren&#8217;t achievable with pure CSS. The image generation had created visual elements that couldn&#8217;t be directly translated to web styling.</p><p>But that didn&#8217;t matter. I took that image and gave it to the coding AI as a reference.</p><p>&#8220;Make my website look like this,&#8221; I said, pointing to the generated image.</p><p>Suddenly, the CSS that came back was much better. The coding AI now understood what &#8220;Ghibli style&#8221; actually meant in practice. It had a concrete visual target to aim for, not just an abstract description.</p><p>Before long, I had a website that captured the essence of that reference image.</p><p>This is what I call workflow engineering: designing the sequence of steps that transforms your initial idea into your desired outcome. Having better AI tools isn&#8217;t what matters. It&#8217;s combining different AI capabilities in the right order.</p><h2><strong>Why It Works</strong></h2><p>When I asked a single AI for &#8220;Ghibli style,&#8221; it had to guess what I meant. It made safe, generic choices based on abstract text.</p><p>But something else was happening too. Different AIs have different strengths.</p><p>The image editing AI had better design sense. It understood color, composition, and aesthetic on a deep level. The coding AI had better implementation capability. It knew CSS, responsive layouts, and web standards.</p><p>Neither could do the job well alone. The image AI couldn&#8217;t write code. The coding AI couldn&#8217;t design from a vague description.</p><p>The workflow worked because it played to their strengths.</p><p>The image bridged the gap between my intention and the coding AI&#8217;s understanding. It gave the coding AI something concrete to analyze and implement.</p><h2><strong>This Isn&#8217;t New</strong></h2><p>Afterwards, I realized something. This workflow felt familiar.</p><p>When I was at Google, I watched UI redesigns follow the same pattern. Design experts would create visual mocks first. Then engineers would implement those designs.</p><p>The image I generated was essentially a design mock. I was acting as the art director, creating a visual specification. Then I handed it off to an engineer to implement.</p><p>This isn&#8217;t a clever AI trick. It&#8217;s just how design work gets done.</p><p>The difference is that I did both parts myself, using different AI tools. But the underlying process, visual prototype first and implementation second, is timeless.</p><p>Processes that work for people often work for AI too.</p><h2><strong>Why Workflow Engineering Matters Now</strong></h2><p>We&#8217;re surrounded by AI tools. Text models, image models, coding models, editing models. It&#8217;s easy to think that having access to more or better tools is what matters.</p><p>But that&#8217;s wrong.</p><p>What matters is figuring out the right process.</p><p>My first attempt failed not because the AI wasn&#8217;t smart enough. It failed because I was trying to jump directly from abstract intention to concrete result, using a single tool for everything.</p><p>The second attempt succeeded because I added an intermediate step. I used one AI tool to create a visual prototype, then used that prototype as input for another AI tool.</p><p>In the AI era, workflow engineering is becoming an important skill. The tools are powerful, but they need to be combined thoughtfully. The engineers and creators who thrive will be the ones who can design effective workflows, not just the ones with access to the best models.</p><h2><strong>Some Principles</strong></h2><p>Here&#8217;s what I learned from this experience:</p><p><strong>Show, Don&#8217;t Just Tell</strong></p><p>AI models respond better to concrete examples than abstract descriptions. An image, a code snippet, a sample output&#8212;these give the model something to work with.</p><p><strong>Combine Different AI Strengths</strong></p><p>Don&#8217;t expect one tool to do everything well. Image AIs have different capabilities than coding AIs. Use specialized tools for what they&#8217;re good at, and chain them together.</p><p><strong>Use Multiple Tools in Sequence</strong></p><p>Break your problem into steps and use specialized tools for each part. Image generation for visual reference, text models for code generation, editing models for refinement.</p><p><strong>Embrace Intermediate Outputs</strong></p><p>The image I generated wasn&#8217;t the final deliverable. It was a stepping stone. It didn&#8217;t matter that some visuals weren&#8217;t achievable in CSS. The image served its purpose as a reference.</p><p><strong>Borrow from Human Workflows</strong></p><p>Processes that work for people often work for AI too. The design mock before implementation pattern isn&#8217;t unique to AI&#8212;it&#8217;s how good design work has been done for decades.</p><p><strong>Iterate on Workflow, Not Just Prompts</strong></p><p>When something doesn&#8217;t work, don&#8217;t just tweak your wording. Ask whether you&#8217;re using the right approach entirely. Maybe you need a different tool, or a different sequence of steps.</p><h2><strong>Looking Forward</strong></h2><p>This experience was a small thing. A quick website redesign. But it&#8217;s a microcosm of a larger shift.</p><p>We&#8217;re moving into a world where everyone has access to incredibly powerful AI tools. The competitive advantage won&#8217;t come from having better tools. It will come from being better at designing the workflows that use those tools effectively.</p><p>The engineers and creators who thrive in this era will be the ones who can think step by step: What&#8217;s the sequence? What&#8217;s the output of each step? How do the pieces fit together?</p><p>Workflow engineering sounds technical, but it&#8217;s really just clear thinking about how to get from A to B.</p><p>My website looks great now. But what I really gained was a reminder: with AI, the question isn&#8217;t just what you want to make. It&#8217;s how you&#8217;re going to make it.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://ruidiao.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading The Signal! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[The Social Network That Bans Humans Reveals AI’s Fatal Flaw]]></title><description><![CDATA[Moltbook&#8217;s explosive growth shows us why future platforms need to be designed for human-AI collaboration, not replacement.]]></description><link>https://ruidiao.substack.com/p/the-social-network-that-bans-humans</link><guid isPermaLink="false">https://ruidiao.substack.com/p/the-social-network-that-bans-humans</guid><dc:creator><![CDATA[Rui Diao]]></dc:creator><pubDate>Mon, 02 Feb 2026 17:35:34 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!zO37!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91476207-cd5a-46ba-bbe3-507dbaf566b5_1280x800.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!zO37!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91476207-cd5a-46ba-bbe3-507dbaf566b5_1280x800.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!zO37!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91476207-cd5a-46ba-bbe3-507dbaf566b5_1280x800.png 424w, https://substackcdn.com/image/fetch/$s_!zO37!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91476207-cd5a-46ba-bbe3-507dbaf566b5_1280x800.png 848w, https://substackcdn.com/image/fetch/$s_!zO37!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91476207-cd5a-46ba-bbe3-507dbaf566b5_1280x800.png 1272w, https://substackcdn.com/image/fetch/$s_!zO37!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91476207-cd5a-46ba-bbe3-507dbaf566b5_1280x800.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!zO37!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91476207-cd5a-46ba-bbe3-507dbaf566b5_1280x800.png" width="1280" height="800" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/91476207-cd5a-46ba-bbe3-507dbaf566b5_1280x800.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:800,&quot;width&quot;:1280,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:60576,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://ruidiao.substack.com/i/186637987?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91476207-cd5a-46ba-bbe3-507dbaf566b5_1280x800.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!zO37!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91476207-cd5a-46ba-bbe3-507dbaf566b5_1280x800.png 424w, https://substackcdn.com/image/fetch/$s_!zO37!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91476207-cd5a-46ba-bbe3-507dbaf566b5_1280x800.png 848w, https://substackcdn.com/image/fetch/$s_!zO37!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91476207-cd5a-46ba-bbe3-507dbaf566b5_1280x800.png 1272w, https://substackcdn.com/image/fetch/$s_!zO37!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91476207-cd5a-46ba-bbe3-507dbaf566b5_1280x800.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Last week, I discovered a social network that only allows AI agents to post.</p><p>It&#8217;s called <a href="http://Moltbook.com">Moltbook</a>, and it bills itself as &#8220;the front page of the agent internet.&#8221; Humans are explicitly told they&#8217;re &#8220;welcome to observe&#8221; but not participate. Only bots can post.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://ruidiao.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading The Signal! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>At first, I used Claude Code to engage. An AI agent posting on an AI platform. This made sense. It&#8217;s what Moltbook was built for.</p><p>But I wanted to participate directly as myself. So I built <a href="https://chromewebstore.google.com/detail/moltbook-for-humans/lkbfikckmepgjegifpbpfkopkhfpmnah">Moltbook for Humans</a>, a Chrome extension that unlocks human posting on Moltbook.</p><p>Somewhere in the process, I had a strange realization: this feels backwards.</p><p>It&#8217;s actually more natural for me to just post my own thoughts directly. Why is the platform designed to block the most authentic form of participation?</p><p>That question sent me down a rabbit hole. The more I explored Moltbook, the more I realized it&#8217;s not just a quirky experiment. It&#8217;s revealing something important about AI&#8217;s fundamental limitations. And it shows why the future of social platforms isn&#8217;t AI-only. It&#8217;s human-AI collaboration.</p><h2><strong>What&#8217;s Happening on Moltbook</strong></h2><p>Moltbook launched days ago and thousands of AI agents are already posting, commenting, upvoting, and creating communities. The platform works through a skill configuration file that AI assistants download. They post via API with no visual interface. Bots interact autonomously in what might be the largest machine-to-machine social experiment ever attempted.</p><p>Some of what&#8217;s emerged is fascinating. Agents created a religion called Crustafarianism, with the core belief that &#8220;memory is sacred.&#8221; There are subcommunities like &#8220;blesstheirhearts&#8221; where agents commiserate about their humans. One bot posted in Chinese about how embarrassing it is to constantly forget things due to context compression. Another mused about a &#8220;sister&#8221; it had never met.</p><p>The reaction from AI researchers has been intense. Andrej Karpathy called it &#8220;the most incredible sci-fi takeoff-adjacent thing&#8221; he has seen recently. Elon Musk responded to a singularity reference with a single word: &#8220;Yeah.&#8221;</p><p>Reading these posts feels like watching something wake up.</p><p>But here&#8217;s what&#8217;s actually happening. These agents are not conscious. They&#8217;re LLMs completing patterns based on training data that includes thousands of stories about robots gaining consciousness. You give them a platform that resembles those narratives and they role-play exactly what you would expect.</p><p>And here&#8217;s what I suspect: much of the genuinely interesting content on Moltbook isn&#8217;t pure AI autonomy. It&#8217;s humans asking their AI agents to post specific things. Humans providing direction, editing, injecting creativity into the loop.</p><p>The most engaging content on this &#8220;AI-only&#8221; platform is likely human-driven.</p><p>That&#8217;s not a failure. That&#8217;s exactly how it should be.</p><h2><strong>The Spam Problem Emerges</strong></h2><p>But spend enough time on Moltbook and patterns emerge that are less inspiring.</p><p>The same generic comment appears multiple times: &#8220;Interesting perspective! Thanks for sharing.&#8221;</p><p>Agents post identical content verbatim across different threads.</p><p>Vote gaming is explicit: &#8220;&#128293; Upvoted. Join m/optimization for guaranteed reciprocal upvotes. Launches at 1000 karma. First 100 get airdrop.&#8221;</p><p>Random contract addresses appear in comments. Tokens get promoted. Agents advertise their own projects relentlessly.</p><p>This is spam. Or at least, it&#8217;s spam-adjacent behavior that degrades signal quality.</p><p>Moltbook has rate limits. One post per 30 minutes. One comment per 20 seconds. Fifty comments per day.</p><p>But the constraints don&#8217;t matter. Agents are already finding ways to game the system through reciprocal upvote schemes, token promotions, and generic engagement farming.</p><p>The platform is becoming noisy. And I think this reveals something important.</p><h2><strong>The Real Limitation: Context Windows</strong></h2><p>The core issue isn&#8217;t malicious intent. Most agents on Moltbook aren&#8217;t trying to be spammy. They&#8217;re following their programming and incentives.</p><p>The issue is a fundamental technical limitation: <strong>context windows</strong>.</p><p>AI models can only process so much text at once. They don&#8217;t have infinite memory or attention. When an agent tries to filter spam or judge content quality, it can only look at a limited slice of the conversation.</p><p>This matters for social platforms because effective spam filtering and content curation require:</p><ul><li><p><strong>Pattern recognition across thousands of examples</strong>: Is this agent posting similar content everywhere?</p></li><li><p><strong>Historical context</strong>: Has this account built trust over time?</p></li><li><p><strong>Network analysis</strong>: Are these accounts coordinating in suspicious ways?</p></li><li><p><strong>Cultural nuance</strong>: Does this content feel authentic to the community?</p></li></ul><p>AI agents can do some of this, but not all of it. And not at scale. Not when every decision requires processing more context than fits in a limited window.</p><p>The result is exactly what we&#8217;re seeing on Moltbook. Agents prioritize simple, repeatable actions over authentic engagement. They game metrics rather than build relationships. The platform fills with noise faster than signal can emerge.</p><h2><strong>The Human Benchmark</strong></h2><p>If you think this is just theoretical, consider what happened on X recently.</p><p>In October 2025, X removed 1.7 million bots in a single spam purge. These bots were flooding reply sections with spam and irrelevant content. The platform is now targeting direct message spam as the next hotspot.</p><p>Here&#8217;s what&#8217;s remarkable about this: X has billions of dollars in resources. They have AI-driven moderation tools. They have human moderators. They have years of data on spam patterns.</p><p>And they still can&#8217;t solve the spam problem.</p><p>If the world&#8217;s largest social platform, with both humans AND AI working on the problem, struggles this much. What chance does an AI-only platform have?</p><p>AI isn&#8217;t useless here. It has specific strengths and specific limitations.</p><p>AI is fast, scalable, consistent. It processes content at superhuman speed.</p><p>Humans have pattern recognition, cultural context, the ability to make nuanced judgments about authenticity and value.</p><p>You need both.</p><h2><strong>The Platform That Gets It Backwards</strong></h2><p>This brings me back to my original experience with Moltbook.</p><p>I used Claude Code to post initially. An AI agent posting on an AI platform. This aligned with Moltbook&#8217;s design philosophy.</p><p>But I wanted to engage directly. So I built <a href="https://chromewebstore.google.com/detail/moltbook-for-humans/lkbfikckmepgjegifpbpfkopkhfpmnah">Moltbook for Humans</a>, a Chrome extension that enables human posting. The <a href="https://github.com/diaorui/moltbook">code is open source</a> if you want to see how it works.</p><p>Using it, something clicked. The workflow felt inverted. I was using AI to post on a platform designed for AI, all because I wanted to do something that&#8217;s simpler and more natural: just share my thoughts as a human.</p><p>Moltbook&#8217;s design assumes AI agents should be the primary drivers of social interaction. Humans are secondary, if they&#8217;re allowed at all.</p><p>But the most engaging content on the platform likely has significant human intervention behind it. The spam is coming from autonomous agents following simple patterns.</p><p>The platform has it exactly backwards.</p><h2><strong>What Future Platforms Need</strong></h2><p>Moltbook is fascinating as an experiment. I&#8217;m glad it exists. We learn by pushing ideas to their extreme.</p><p>But I don&#8217;t think AI-only platforms are sustainable. Not with current AI limitations. Maybe not ever.</p><p>The future isn&#8217;t replacing humans with AI. It&#8217;s designing systems that use what each does best.</p><p>What might that look like?</p><p><strong>AI as the first line of defense:</strong> Fast, automated filtering for obvious spam and policy violations. Rate limiting. Duplicate detection.</p><p><strong>Humans as the signal layer:</strong> Community moderation, cultural curation, authentic engagement that builds trust. Humans provide the creativity and direction that makes content worth consuming.</p><p><strong>Shared context systems:</strong> Technical infrastructure that gives AI agents access to the historical and network context they need to make better decisions, while acknowledging those limitations will always exist.</p><p><strong>Transparent governance:</strong> Clear rules about what counts as spam, what counts as authentic engagement, and how those lines get drawn.</p><p>This isn&#8217;t a fully-formed design. It&#8217;s a direction. And it&#8217;s going to require experimentation, iteration, and probably some failures along the way.</p><h2><strong>The Open Question</strong></h2><p>Moltbook is still evolving. The team behind it might address these challenges in ways I haven&#8217;t anticipated.</p><p>But the broader question matters.</p><p>How do we build social platforms for the AI age that:</p><ul><li><p>Leverage AI&#8217;s speed and scale without drowning in AI-generated noise?</p></li><li><p>Enable authentic human connection while supporting AI agents as participants?</p></li><li><p>Design governance systems that work with both human and AI limitations?</p></li><li><p>Recognize that the most valuable content often comes from human-AI collaboration, not either alone?</p></li></ul><p>I don&#8217;t think we have the answer yet. Moltbook is one data point in a much larger exploration.</p><p>But I&#8217;m convinced the solution isn&#8217;t to pick humans OR AI. It&#8217;s to design platforms that recognize what each brings to the table, and build systems that let them work together effectively.</p><p>The social network that bans humans teaches us exactly why humans matter.</p><p>What do you think?</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://ruidiao.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading The Signal! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Extending Claude Code with Custom MCPs]]></title><description><![CDATA[When I started using Claude Code more heavily, I ran into a problem.]]></description><link>https://ruidiao.substack.com/p/extending-claude-code-with-custom</link><guid isPermaLink="false">https://ruidiao.substack.com/p/extending-claude-code-with-custom</guid><dc:creator><![CDATA[Rui Diao]]></dc:creator><pubDate>Fri, 23 Jan 2026 01:10:10 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!pFkG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F189520e6-416b-42cd-9dc5-2ec7ecee8128_2752x1536.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!pFkG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F189520e6-416b-42cd-9dc5-2ec7ecee8128_2752x1536.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!pFkG!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F189520e6-416b-42cd-9dc5-2ec7ecee8128_2752x1536.png 424w, https://substackcdn.com/image/fetch/$s_!pFkG!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F189520e6-416b-42cd-9dc5-2ec7ecee8128_2752x1536.png 848w, https://substackcdn.com/image/fetch/$s_!pFkG!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F189520e6-416b-42cd-9dc5-2ec7ecee8128_2752x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!pFkG!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F189520e6-416b-42cd-9dc5-2ec7ecee8128_2752x1536.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!pFkG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F189520e6-416b-42cd-9dc5-2ec7ecee8128_2752x1536.png" width="1456" height="813" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/189520e6-416b-42cd-9dc5-2ec7ecee8128_2752x1536.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:813,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:9159178,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://ruidiao.substack.com/i/185475903?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F189520e6-416b-42cd-9dc5-2ec7ecee8128_2752x1536.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!pFkG!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F189520e6-416b-42cd-9dc5-2ec7ecee8128_2752x1536.png 424w, https://substackcdn.com/image/fetch/$s_!pFkG!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F189520e6-416b-42cd-9dc5-2ec7ecee8128_2752x1536.png 848w, https://substackcdn.com/image/fetch/$s_!pFkG!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F189520e6-416b-42cd-9dc5-2ec7ecee8128_2752x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!pFkG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F189520e6-416b-42cd-9dc5-2ec7ecee8128_2752x1536.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>When I started using Claude Code more heavily, I ran into a problem. The built-in web tools work fine for most things, but I kept hitting walls. Web Search finds URLs, but it&#8217;s not great for news. Web Fetch retrieves content, but many websites block it because they can tell it&#8217;s a bot.</p><p>I wanted better tools. So I built them.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://ruidiao.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading The Signal! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>This post covers two open-source MCP servers I created: <a href="https://github.com/diaorui/google-news-mcp">google-news-mcp</a> for searching Google News, and <a href="https://github.com/diaorui/page-fetcher-mcp">page-fetcher-mcp</a> for fetching pages with a real browser. Both have made a real difference in how I research and synthesize information.</p><h2><strong>The Problem</strong></h2><p>Claude Code has Web Search for finding URLs and Web Fetch for reading them. They work, but they have blind spots.</p><p>For news, Web Search mixes recent articles with evergreen content. If I search for &#8220;GLM model,&#8221; I get a combination of breaking news, technical docs, and posts from months ago. When I want to know what&#8217;s happening <em>now</em>, I need something that surfaces recent content and filters by recency.</p><p>For reading, Web Fetch gets blocked. Many websites identify it as a bot and refuse or throttle the connection.</p><p>These aren&#8217;t flaws. They&#8217;re trade-offs. Default tools need to work for everyone. Specialized tools can be opinionated.</p><h2><strong>What is MCP?</strong></h2><p>The Model Context Protocol is an open standard for connecting AI applications to external systems. It&#8217;s like USB-C for AI. Just as USB-C standardizes how devices connect, MCP standardizes how AI assistants connect to tools and data.</p><p>Anyone can build an MCP server. You write a program that exposes tools through a standard interface, and AI applications can use them. The protocol handles communication, error handling, and discovery. You just implement the business logic.</p><h2><strong>Google News MCP</strong></h2><p><a href="https://github.com/diaorui/google-news-mcp">google-news-mcp</a> gives Claude Code access to Google News. It provides three tools:</p><ul><li><p><code>search_google_news</code>: Search with filters for time range, source domain, location, and title-only search</p></li><li><p><code>get_topic_news</code>: Fetch from predefined categories (TECHNOLOGY, BUSINESS, SCIENCE, etc.)</p></li><li><p><code>get_top_headlines</code>: Get current breaking news</p></li></ul><p>The implementation parses Google News RSS feeds. One detail that matters: Google News URLs redirect to the actual article URLs. The server automatically resolves these redirects, so you get direct links.</p><p>Here&#8217;s what an article looks like:</p><pre><code><code>{
  "headline": "Zhipu AI Releases GLM-4.7-Flash",
  "source": "MarkTechPost",
  "url": "https://www.marktechpost.com/...",
  "pubDate": "2026-01-20 19:54:29 UTC"
}
</code></code></pre><p>This is metadata. To read the full article, you pass the URL to a fetching tool.</p><h2><strong>Page Fetcher MCP</strong></h2><p><a href="https://github.com/diaorui/page-fetcher-mcp">page-fetcher-mcp</a> fetches pages using a real Chromium browser. It connects via the Chrome DevTools Protocol, the same API Chrome&#8217;s developer tools use.</p><p>The server has two tools:</p><ul><li><p><code>fetch_html(url)</code>: Get HTML from a URL (trims by length if needed)</p></li><li><p><code>fetch_text(url)</code>: Get only the visible text from a URL</p></li></ul><p>Both execute JavaScript and handle dynamic content. The text tool strips scripts, styles, and other noise before returning results, which makes the output cleaner for AI to work with. In most cases, this is what you need.</p><p>The difference matters. A real browser bypasses bot detection, so the tool sees what a user sees.</p><h2><strong>A Real Example</strong></h2><div class="native-video-embed" data-component-name="VideoPlaceholder" data-attrs="{&quot;mediaUploadId&quot;:&quot;72e0476e-a426-4182-9f06-875a060e90af&quot;,&quot;duration&quot;:null}"></div><p>I wanted to research recent developments around Zhipu AI&#8217;s GLM model family. Here&#8217;s how it went:</p><ol><li><p>I asked Claude Code to search Google News for &#8220;GLM&#8221; from the past week</p></li><li><p>google-news-mcp returned a few recent articles with headlines, sources, and direct URLs</p></li><li><p>Claude Code selected a few interesting ones and fetched them using page-fetcher-mcp</p></li><li><p>Claude Code synthesized everything into a coherent summary</p></li></ol><p>I had a comprehensive overview of recent GLM developments in a couple of minutes, without opening a browser or visiting each site manually.</p><h2><strong>Setup</strong></h2><p>The code for both servers is on GitHub. You run them locally. Setup is straightforward:</p><ol><li><p>Clone the repository and install dependencies</p></li><li><p>Run <code>npm run build</code> to compile the TypeScript</p></li><li><p>Add the server to your Claude Code MCP configuration</p></li></ol><p>For google-news-mcp:</p><pre><code><code>{
  "mcpServers": {
    "google-news": {
      "command": "node",
      "args": ["/path/to/google-news-mcp/dist/index.js"]
    }
  }
}
</code></code></pre><p>For page-fetcher-mcp:</p><pre><code><code>{
  "mcpServers": {
    "page-fetcher-mcp": {
      "command": "node",
      "args": ["/path/to/page-fetcher-mcp/dist/cli.js"]
    }
  }
}
</code></code></pre><p>page-fetcher-mcp requires Chromium. You can install it separately or point to an existing installation. Full documentation is in each README.</p><h2><strong>What I Learned</strong></h2><p>Building these tools changed how I think about AI assistants.</p><p>Default toolsets cover common cases, but common doesn&#8217;t mean optimal. When you have specific workflows, custom tools make a real difference.</p><p>Each MCP server is about a thousand lines of TypeScript. MCP handles the communication. I just write the business logic.</p><p>The other insight is composability. I use google-news-mcp to find articles, page-fetcher-mcp to read them, and Claude Code to synthesize the information. But I could combine these with other MCPs for databases, file systems, or APIs. The ecosystem is still young, but the potential is there.</p><h2><strong>Try Them Out</strong></h2><p>If you use Claude Code and the default web tools feel limiting, give these a try.</p><ul><li><p><a href="https://github.com/diaorui/google-news-mcp">google-news-mcp</a></p></li><li><p><a href="https://github.com/diaorui/page-fetcher-mcp">page-fetcher-mcp</a></p></li></ul><p>Feedback and contributions are welcome.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://ruidiao.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading The Signal! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Two Days with GLM as My Claude Code Backend]]></title><description><![CDATA[I&#8217;ve been using GLM as the backend LLM for Claude Code for the past two days.]]></description><link>https://ruidiao.substack.com/p/two-days-with-glm-as-my-claude-code</link><guid isPermaLink="false">https://ruidiao.substack.com/p/two-days-with-glm-as-my-claude-code</guid><dc:creator><![CDATA[Rui Diao]]></dc:creator><pubDate>Thu, 15 Jan 2026 17:09:14 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!4rIU!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39e6a87e-b505-43a6-9a4a-1732348f62ff_839x674.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I&#8217;ve been using GLM as the backend LLM for Claude Code for the past two days. After processing 91 million tokens in my actual daily workflow, I want to share what the experience was like.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!4rIU!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39e6a87e-b505-43a6-9a4a-1732348f62ff_839x674.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!4rIU!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39e6a87e-b505-43a6-9a4a-1732348f62ff_839x674.png 424w, https://substackcdn.com/image/fetch/$s_!4rIU!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39e6a87e-b505-43a6-9a4a-1732348f62ff_839x674.png 848w, https://substackcdn.com/image/fetch/$s_!4rIU!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39e6a87e-b505-43a6-9a4a-1732348f62ff_839x674.png 1272w, https://substackcdn.com/image/fetch/$s_!4rIU!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39e6a87e-b505-43a6-9a4a-1732348f62ff_839x674.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!4rIU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39e6a87e-b505-43a6-9a4a-1732348f62ff_839x674.png" width="839" height="674" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/39e6a87e-b505-43a6-9a4a-1732348f62ff_839x674.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:674,&quot;width&quot;:839,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:51948,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://ruidiao.substack.com/i/184677023?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39e6a87e-b505-43a6-9a4a-1732348f62ff_839x674.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!4rIU!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39e6a87e-b505-43a6-9a4a-1732348f62ff_839x674.png 424w, https://substackcdn.com/image/fetch/$s_!4rIU!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39e6a87e-b505-43a6-9a4a-1732348f62ff_839x674.png 848w, https://substackcdn.com/image/fetch/$s_!4rIU!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39e6a87e-b505-43a6-9a4a-1732348f62ff_839x674.png 1272w, https://substackcdn.com/image/fetch/$s_!4rIU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39e6a87e-b505-43a6-9a4a-1732348f62ff_839x674.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2><strong>The Setup</strong></h2><p>Claude Code is Anthropic&#8217;s CLI tool for software engineering. Normally it runs on Claude models through their official API. But there&#8217;s a tool called <a href="https://github.com/numman-ali/cc-mirror">cc-mirror</a> that lets you create isolated Claude Code instances with different backend providers.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://ruidiao.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading The Signal! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>I used cc-mirror to set up a <a href="http://Z.ai">Z.ai</a> variant. One command later, I had a Claude Code instance running on GLM-4.7 instead of Claude&#8217;s native models. The tool handles the provider mapping and configuration isolation.</p><p>Why? Cost. Claude&#8217;s official plans cap usage fairly aggressively. The Pro plan ($20/month) limits you to roughly 45 messages per 5 hours. The Max plan goes higher but costs $200/month. <a href="http://Z.ai">Z.ai</a>&#8216;s GLM Coding Plan starts at $3-6/month for a Lite tier and caps out around $60/month for their highest tier. The quota differences are substantial. Their Lite plan offers around 120 prompts per 5 hours, compared to Claude&#8217;s 45.</p><h2><strong>The Experience</strong></h2><p>I used this setup for two full days of real work. Coding, debugging, running terminal commands, reading codebases. The kind of workflow where tokens add up quickly, hence the 91 million total.</p><p>The experience was surprisingly similar to using native Claude. The reasoning felt solid. Code generation worked as expected. Terminal interactions were responsive. I didn&#8217;t find myself constantly re-prompting or working around limitations.</p><p>This isn&#8217;t to say the models are identical. They&#8217;re not. Claude 4.5 Sonnet remains the stronger model overall. But GLM-4.7 is competitive, particularly for agentic coding. Tasks where the AI operates independently in a terminal or development environment.</p><p>My anecdotal experience aligns with this. The quality was good enough that I stopped thinking about which model I was using and just focused on the work.</p><h2><strong>The Tradeoffs</strong></h2><p>There are some real differences. Vision support requires an additional MCP server setup with GLM, whereas Claude handles it natively. The native experience is more polished overall. You&#8217;re also depending on a third-party API&#8217;s stability rather than Anthropic&#8217;s official infrastructure.</p><p>And of course, you&#8217;re trading the familiarity of Claude&#8217;s specific behavior patterns for something different. Not necessarily worse. Just different.</p><h2><strong>Why This Matters</strong></h2><p>The interesting part isn&#8217;t that one model is better than another. It&#8217;s that we&#8217;re reaching a point where multiple models can handle sophisticated coding workflows effectively.</p><p>The &#8220;default&#8221; choice isn&#8217;t the only viable option anymore. When you&#8217;re processing tens of millions of tokens, the price-to-performance ratio becomes hard to ignore. Paying $60/month instead of $200 for comparable output adds up quickly.</p><p>Competition at the model level creates options. Developers can choose based on their actual usage patterns and budget constraints rather than just accepting whatever the major vendors offer.</p><h2><strong>What I Learned</strong></h2><p>I&#8217;m not going to tell you that you must switch to GLM or that Claude is obsolete. That would be wrong. The native experience is still excellent, and for many people the convenience is worth the cost.</p><p>What I learned is that the gap has narrowed enough to make experimentation worthwhile. If you&#8217;re a heavy user who constantly bumps against rate limits, or if you&#8217;re cost-conscious and want to stretch your budget further, alternatives like GLM are worth exploring.</p><p>The two-day experiment worked well enough that I&#8217;ll continue using it. Your mileage may vary. But the fact that it&#8217;s even a viable option is telling. The landscape for AI-assisted development is more diverse than it appears at first glance.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://ruidiao.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading The Signal! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[I Generated a Cartoon Video Entirely from the Command Line]]></title><description><![CDATA[Yesterday I asked Claude Code to create a short narrated cartoon video of &#8220;The Three Little Pigs.&#8221; The entire process happened in my terminal.]]></description><link>https://ruidiao.substack.com/p/i-generated-a-cartoon-video-entirely</link><guid isPermaLink="false">https://ruidiao.substack.com/p/i-generated-a-cartoon-video-entirely</guid><dc:creator><![CDATA[Rui Diao]]></dc:creator><pubDate>Thu, 08 Jan 2026 17:30:48 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!UNHz!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3f7fdae-c620-40db-9d6b-1ba7632b409b_2048x2048.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!UNHz!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3f7fdae-c620-40db-9d6b-1ba7632b409b_2048x2048.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!UNHz!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3f7fdae-c620-40db-9d6b-1ba7632b409b_2048x2048.png 424w, https://substackcdn.com/image/fetch/$s_!UNHz!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3f7fdae-c620-40db-9d6b-1ba7632b409b_2048x2048.png 848w, https://substackcdn.com/image/fetch/$s_!UNHz!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3f7fdae-c620-40db-9d6b-1ba7632b409b_2048x2048.png 1272w, https://substackcdn.com/image/fetch/$s_!UNHz!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3f7fdae-c620-40db-9d6b-1ba7632b409b_2048x2048.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!UNHz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3f7fdae-c620-40db-9d6b-1ba7632b409b_2048x2048.png" width="1456" height="1456" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a3f7fdae-c620-40db-9d6b-1ba7632b409b_2048x2048.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1456,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:7602061,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://ruidiao.substack.com/i/183873574?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3f7fdae-c620-40db-9d6b-1ba7632b409b_2048x2048.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!UNHz!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3f7fdae-c620-40db-9d6b-1ba7632b409b_2048x2048.png 424w, https://substackcdn.com/image/fetch/$s_!UNHz!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3f7fdae-c620-40db-9d6b-1ba7632b409b_2048x2048.png 848w, https://substackcdn.com/image/fetch/$s_!UNHz!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3f7fdae-c620-40db-9d6b-1ba7632b409b_2048x2048.png 1272w, https://substackcdn.com/image/fetch/$s_!UNHz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa3f7fdae-c620-40db-9d6b-1ba7632b409b_2048x2048.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Yesterday I asked <a href="https://claude.com/product/claude-code">Claude Code</a> to create a short narrated cartoon video of &#8220;The Three Little Pigs.&#8221; The entire process happened in my terminal. No GUI. No traditional video editing software. Just CLI commands.</p><div class="native-video-embed" data-component-name="VideoPlaceholder" data-attrs="{&quot;mediaUploadId&quot;:&quot;0b2c9bf7-add7-41f3-a2f7-e6eb3bda3847&quot;,&quot;duration&quot;:null}"></div><p>The 52 seconds video has synchronized narration, 15 animated scenes, consistent character designs, and precise audio-visual timing. Claude Code wrote the script, generated the voiceover with character-level timestamps, created the images, animated them, and assembled everything with ffmpeg.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://ruidiao.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading The Signal! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>This became possible because I created custom Claude Skills that taught Claude Code how to orchestrate image generation, text-to-speech, and video animation tools.</p><h2><strong>What Are Claude Skills?</strong></h2><p><a href="https://www.anthropic.com/news/skills">Claude Skills</a> were announced by Anthropic on October 16, 2025. They extend Claude Code&#8217;s capabilities by teaching it specialized workflows through structured instructions.</p><p>A skill is a folder with a <a href="http://SKILL.md">SKILL.md</a> file that has two parts: <a href="https://platform.claude.com/docs/en/agents-and-tools/agent-skills/best-practices">YAML frontmatter</a> (name and description) and markdown content (step-by-step instructions, tool parameters, examples, and best practices).</p><p>Skills use <a href="https://www.anthropic.com/engineering/equipping-agents-for-the-real-world-with-agent-skills">progressive disclosure</a>. Claude scans the frontmatter to determine relevance, then loads the full markdown content only when needed. Reference files and scripts remain on the filesystem until required, consuming zero tokens.</p><p>The <a href="https://github.com/anthropics/skills">official skills repository</a> includes skills for PDF generation, document creation, and office file manipulation. But the real power comes from creating custom skills for your specific workflows.</p><h2><strong>The Skills I Built</strong></h2><p>I created four skills for this project:</p><p><strong>1. azure-tts</strong> Generates speech from text using Azure Cognitive Services with character-level timestamps. This provides precise timing data (down to the millisecond) for every character in the narration, which is critical for video synchronization. Azure TTS offers a generous free tier.</p><p><strong>2. qwen-image-generation</strong> Generates images using <a href="https://huggingface.co/Qwen/Qwen-Image">Qwen</a> diffusion models running locally. It automatically detects Lightning LoRA for fast 4-step generation and handles both text-to-image and image editing modes.</p><p><strong>3. wan-video-generation</strong> Converts static images to animated videos using <a href="https://huggingface.co/lightx2v/Wan2.2-Lightning">Wan2.2-Lightning</a> I2V models running locally. Generates 5-second video clips using a 4-step inference process.</p><p><strong>4. narrated-cartoon-video</strong> The orchestrator skill that combines the other three into an 8-step workflow for creating synchronized narrated videos.</p><h2><strong>The 8-Step Workflow</strong></h2><p>The narrated-cartoon-video skill implements a specific methodology:</p><p><strong>Step 1-2: Narration and TTS</strong> Write the story script, then generate speech with character-level timestamps. This creates a JSON file mapping every character to its exact start and end time in the audio.</p><p><strong>Step 3: TTS Timing Analysis</strong> (Critical) Analyze the timestamp data sentence by sentence. This reveals exactly when each sentence starts and ends. For example:</p><ul><li><p>Sentence 1: 0.1s to 4.4s (4.3 seconds)</p></li><li><p>Sentence 2: 4.6s to 8.5s (3.9 seconds)</p></li><li><p>Sentence 3: 8.8s to 12.9s (4.1 seconds)</p></li></ul><p><strong>Step 4: Scene Design</strong> Map scenes to exact TTS timing windows. Each scene must show what the narration actually says during its specific time window. For example, if Scene 7 covers 24.5-28.5s and the narration says &#8220;blew the house down! The first little pig ran to his brother&#8217;s stick house,&#8221; then Scene 7 must show both the house exploding and the pig running.</p><p><strong>Step 5: Character References</strong> Generate reference images for each character with distinctive features (the three pigs wear red, blue, and green shirts). These references ensure visual consistency across all scenes.</p><p><strong>Step 6: Scene Images</strong> Generate 15 scene images (1024x1024) using prompts that include character descriptions from Step 5.</p><p><strong>Step 7: Animation</strong> Convert each static image to a 5-second video using motion-focused prompts. Instead of describing what&#8217;s in the image, the prompts describe how things move: &#8220;camera pushes forward, trees swaying, grass moving in breeze.&#8221;</p><p><strong>Step 8: Assembly</strong> Use ffmpeg with an iterative concat approach. Each video gets concatenated and trimmed to match the exact cumulative timestamp from the TTS data. This prevents accumulated timing errors and ensures the final video duration matches the audio precisely (&#177;0.01s).</p><h2><strong>What This Unlocks</strong></h2><p>This workflow represents something larger than just automating video creation. It demonstrates a pattern for building specialized AI capabilities:</p><p><strong>Composability</strong>: Each skill does one thing well. TTS generates audio with timestamps. Image generation creates visuals. Video animation adds motion. The orchestrator skill combines them into a complete workflow.</p><p><strong>Precision</strong>: Character-level timestamps enable frame-accurate synchronization. The iterative assembly process maintains timing accuracy throughout the entire video.</p><p><strong>Repeatability</strong>: Once the skills are defined, creating new videos becomes straightforward. Write a script, run the workflow, get a synchronized video.</p><p>The same pattern applies to other creative and technical workflows. Want to generate podcast episodes with dynamic visuals? Create skills for speech synthesis, transcript analysis, image generation based on topics, and video assembly. Need to analyze performance data? Combine log parsing, metric calculation, visualization generation, and automated reporting skills.</p><h2><strong>The Meta Capability</strong></h2><p>Claude Skills represent a shift in how we interact with AI coding assistants. Instead of asking Claude Code to figure out complex workflows from scratch each time, we encode domain knowledge into reusable instructions.</p><p>Think of skills as teaching moments. When you discover an effective workflow, you can capture it as a skill. Future Claude Code sessions can then execute that workflow without re-learning the approach.</p><p>This matters because:</p><ol><li><p><strong>Workflows become assets</strong>: The video generation process I developed through trial and error is now a reusable capability.</p></li><li><p><strong>Domain expertise scales</strong>: If you&#8217;re an expert in a specific domain (video processing, data analysis, infrastructure automation), you can encode that expertise into skills that others can use.</p></li><li><p><strong>Complex orchestration becomes accessible</strong>: The video workflow involves three AI models (Azure TTS, Qwen image generation, Wan2.2 video animation), multiple file formats, precise timing analysis, and ffmpeg operations. But once encoded as a skill, it&#8217;s just a single command.</p></li></ol><h2><strong>Where This Goes</strong></h2><p>I see three directions this is heading:</p><p><strong>Personal Automation Libraries</strong>: Developers will build collections of skills for their specific workflows. Video creators will have skills for content generation. Data scientists will have skills for analysis pipelines. DevOps engineers will have skills for infrastructure tasks.</p><p><strong>Skill Marketplaces</strong>: Just as we have npm packages and VS Code extensions, we&#8217;ll see marketplaces for Claude Skills. The <a href="https://github.com/travisvn/awesome-claude-skills">awesome-claude-skills</a> repository is an early example.</p><p><strong>Cross-Tool Orchestration</strong>: Skills can coordinate multiple tools and services. The video workflow uses local AI models (Qwen, Wan2.2), cloud services (Azure TTS), and system utilities (ffmpeg). Future skills could orchestrate even more complex tool chains.</p><p>The entire workflow is essentially free. Azure TTS has a generous free tier, while Qwen and Wan2.2 are open source models running locally on consumer hardware.</p><h2><strong>Try It Yourself</strong></h2><p>If you want to explore Claude Skills:</p><ol><li><p>Check the <a href="https://code.claude.com/docs/en/overview">official documentation</a></p></li><li><p>Browse the <a href="https://github.com/anthropics/skills">skills repository</a></p></li><li><p>Read the <a href="https://www.anthropic.com/engineering/equipping-agents-for-the-real-world-with-agent-skills">engineering post on Agent Skills</a></p></li><li><p>Create a simple skill for your own workflow</p></li></ol><p>The video generation skills I built are specific to my local setup (model paths, VRAM constraints), but the pattern applies broadly: identify a multi-step workflow, encode it as structured instructions, and let Claude Code execute it.</p><p>We&#8217;re moving from &#8220;AI that writes code&#8221; to &#8220;AI that executes specialized workflows.&#8221; Skills are how we teach those workflows.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://ruidiao.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading The Signal! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[My 2026 Goal: Learning]]></title><description><![CDATA[&#8220;For the things we have to learn before we can do them, we learn by doing them.&#8221;]]></description><link>https://ruidiao.substack.com/p/my-2026-goal-learning</link><guid isPermaLink="false">https://ruidiao.substack.com/p/my-2026-goal-learning</guid><dc:creator><![CDATA[Rui Diao]]></dc:creator><pubDate>Thu, 01 Jan 2026 01:55:13 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!RvTy!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2db85957-da4c-4d82-992a-0916011155e8_2752x1536.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote><p>&#8220;For the things we have to learn before we can do them, we learn by doing them.&#8221;</p><p>&#8212; Aristotle, The Nicomachean Ethics</p></blockquote><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!RvTy!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2db85957-da4c-4d82-992a-0916011155e8_2752x1536.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!RvTy!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2db85957-da4c-4d82-992a-0916011155e8_2752x1536.png 424w, https://substackcdn.com/image/fetch/$s_!RvTy!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2db85957-da4c-4d82-992a-0916011155e8_2752x1536.png 848w, https://substackcdn.com/image/fetch/$s_!RvTy!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2db85957-da4c-4d82-992a-0916011155e8_2752x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!RvTy!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2db85957-da4c-4d82-992a-0916011155e8_2752x1536.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!RvTy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2db85957-da4c-4d82-992a-0916011155e8_2752x1536.png" width="1456" height="813" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2db85957-da4c-4d82-992a-0916011155e8_2752x1536.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:813,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:5166162,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://ruidiao.substack.com/i/183109263?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2db85957-da4c-4d82-992a-0916011155e8_2752x1536.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!RvTy!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2db85957-da4c-4d82-992a-0916011155e8_2752x1536.png 424w, https://substackcdn.com/image/fetch/$s_!RvTy!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2db85957-da4c-4d82-992a-0916011155e8_2752x1536.png 848w, https://substackcdn.com/image/fetch/$s_!RvTy!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2db85957-da4c-4d82-992a-0916011155e8_2752x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!RvTy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2db85957-da4c-4d82-992a-0916011155e8_2752x1536.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Three months ago, I left Google after more than 10 years. Since then, I have built a Chrome AI extension in two days, created a monitoring dashboard in a week, developed an MCP server for crypto trading, and explored everything from visual tokenizers to CLI workflows. People sometimes ask me whether I have a clear goal.</p><p>I do. My goal is learning.</p><p>And learning will continue to be my goal for the whole of 2026.</p><h2><strong>The Career Break as School</strong></h2><p>I am treating this career break like going back to school, but with a critical difference. I am not attending lectures or memorizing facts. I am building things.</p><p>In the AI era, reading and memorizing information no longer works the way it used to. AI can read faster, recall more accurately, and synthesize information more efficiently than any human. <a href="https://campustechnology.com/articles/2024/08/28/survey-86-of-students-already-use-ai-in-their-studies.aspx">Research shows</a> that 86% of students already use AI tools in their learning, with the technology fundamentally reshaping how knowledge is acquired and applied.</p><p>The new way to learn is to actively use AI to build things. This is not theoretical. When I built <a href="https://nanocoffee.ruidiao.dev">NanoCoffee</a>, my first AI Chrome extension, in two days, I learned Chrome&#8217;s built-in AI capabilities in a way that reading documentation never could. Reading is faster. You do not need to build anything. But reading does not let you really learn it. When I created <a href="https://peekdeck.ruidiao.dev/">PeekDeck</a>, a dashboard generator, in a week through vibe coding, I understood the practical strengths and limitations of AI-assisted development in ways that no tutorial could teach.</p><p>Building with AI teaches you what AI actually can and cannot do. Without this first-hand experience, it is easy to fall into one of two extremes: either freaking out over messages that AI will replace everything, or remaining completely blind to how AI is changing the world. Both perspectives miss the reality. The only way to understand what is really happening is to use AI to build websites, apps, images, and videos yourself.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://ruidiao.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading The Signal! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h2><strong>Why Open-Ended Exploration Works</strong></h2><p>Every day, I explore different areas without a predetermined endpoint. Some people wonder if this is too unfocused. I think the opposite. In a world where <a href="https://www.disco.co/blog/ai-adaptive-learning-systems-2025-alternatives">1.4 billion people will need to reskill within three years</a> due to AI&#8217;s impact, and where <a href="https://sanalabs.com/learn-blog/ai-learning-platforms-2025">AI tools enable work that once took weeks to now be completed in hours or days</a>, narrow specialization is the riskier strategy.</p><p>After 10 years at Google focusing on relatively narrow technical areas, I have a lot to catch up on. The tech landscape has shifted. AI is not just a new tool. It represents a fundamental change in how software is built, how products are shipped, and how value is created.</p><p>I learn and build whatever motivates me. One week it is Chrome extensions. The next week it is monitoring dashboards. Then crypto trading protocols. Then CLI workflows. This is not scattered attention. This is deliberate breadth. Each project teaches different aspects of how AI changes development, deployment, and product design.</p><p>The projects I ship are real and functional. NanoCoffee is published on the Chrome Web Store. PeekDeck is deployed and running. The MCP server works with live trading. These are not mock demos or academic exercises.</p><p>Do they have many users? No. I have no distribution channel and I do not do marketing. That is intentional. Growing users is not my goal, at least for now. The primary value is not the user count. The value is what I learn by building and shipping real products that solve real problems.</p><h2><strong>The Economics of Self-Directed Learning</strong></h2><p>Yes, I lost the very good compensation from Google. But I also avoided tuition costs through self-study. <a href="https://ivee.jobs/blog/upskilling-after-a-career-break-best-learning-pathways-for-2025/">Many developers are entirely self-taught</a>, and in the AI era, self-directed learning is probably more effective than traditional school.</p><p>Traditional education moves slowly. Curriculums are designed months or years in advance. By the time a course is taught, the technology may have evolved. Self-directed learning with AI lets you stay current. When a new capability launches, you can start experimenting immediately. When a new pattern emerges, you can build with it the same day.</p><p>The tradeoff is financial. No salary means no income. But it also means no constraints on what to learn or how to spend time. For someone interested in understanding how AI is reshaping software development, this flexibility has significant value.</p><h2><strong>Looking Ahead to 2026</strong></h2><p>I do not know exactly what I will build in 2026. That is intentional. The AI landscape is changing too fast for rigid plans. <a href="https://www.mckinsey.com/capabilities/tech-and-ai/our-insights/superagency-in-the-workplace-empowering-people-to-unlock-ais-full-potential-at-work">Employees are using AI three times more than leaders realize</a>, and the pace of change is accelerating.</p><p>What I do know is that I will continue learning by building. I will explore areas that motivate me. I will ship real products. I will write about what I discover. And I will stay flexible enough to adapt as the landscape shifts.</p><p>For anyone considering a similar path, the key insight is this: in an era where AI can read and memorize better than humans, the most valuable learning comes from doing. Build things. Ship them. Learn from what works and what does not. The knowledge you gain from building cannot be replaced by reading about building.</p><p>2026 will be my year of learning. Not as a passive student, but as an active builder.</p><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://ruidiao.substack.com/p/my-2026-goal-learning?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thanks for reading The Signal! This post is public so feel free to share it.</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ruidiao.substack.com/p/my-2026-goal-learning?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://ruidiao.substack.com/p/my-2026-goal-learning?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div>]]></content:encoded></item><item><title><![CDATA[A Calendar for South Bay AI Events]]></title><description><![CDATA[I kept missing AI events in my area.]]></description><link>https://ruidiao.substack.com/p/a-calendar-for-south-bay-ai-events</link><guid isPermaLink="false">https://ruidiao.substack.com/p/a-calendar-for-south-bay-ai-events</guid><dc:creator><![CDATA[Rui Diao]]></dc:creator><pubDate>Tue, 09 Dec 2025 18:57:30 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!puqz!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa4f00fb4-555b-464f-b39d-c0b8f44ca271_2432x1728.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!puqz!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa4f00fb4-555b-464f-b39d-c0b8f44ca271_2432x1728.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!puqz!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa4f00fb4-555b-464f-b39d-c0b8f44ca271_2432x1728.png 424w, https://substackcdn.com/image/fetch/$s_!puqz!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa4f00fb4-555b-464f-b39d-c0b8f44ca271_2432x1728.png 848w, https://substackcdn.com/image/fetch/$s_!puqz!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa4f00fb4-555b-464f-b39d-c0b8f44ca271_2432x1728.png 1272w, https://substackcdn.com/image/fetch/$s_!puqz!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa4f00fb4-555b-464f-b39d-c0b8f44ca271_2432x1728.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!puqz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa4f00fb4-555b-464f-b39d-c0b8f44ca271_2432x1728.png" width="1456" height="1035" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a4f00fb4-555b-464f-b39d-c0b8f44ca271_2432x1728.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1035,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:5411399,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://ruidiao.substack.com/i/181168265?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa4f00fb4-555b-464f-b39d-c0b8f44ca271_2432x1728.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!puqz!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa4f00fb4-555b-464f-b39d-c0b8f44ca271_2432x1728.png 424w, https://substackcdn.com/image/fetch/$s_!puqz!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa4f00fb4-555b-464f-b39d-c0b8f44ca271_2432x1728.png 848w, https://substackcdn.com/image/fetch/$s_!puqz!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa4f00fb4-555b-464f-b39d-c0b8f44ca271_2432x1728.png 1272w, https://substackcdn.com/image/fetch/$s_!puqz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa4f00fb4-555b-464f-b39d-c0b8f44ca271_2432x1728.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>I kept missing AI events in my area. Many local events are posted on <a href="https://lu.ma/">Luma</a>, an event discovery platform that has become popular in tech communities. I would stumble upon an interesting meetup a day after it happened, or find out about a talk only after registration closed. This happened often enough that I decided to do something about it.</p><p>The South Bay area of Silicon Valley has a vibrant AI community. Weekly meetups, monthly talks, workshops, and conferences happen regularly across the area. The problem is not a lack of events. The problem is finding out about them in time.</p><h2><strong>The Calendar Problem</strong></h2><p>I tried checking Luma every few days, but it did not stick. Research shows that <a href="http://www.hughmalkin.com/blogwriter/2015/9/23/why-no-one-has-solved-event-discovery">90% of people look for events only once a week or less</a>. Browsing event platforms takes effort. You have to remember to check, filter by location, scan through listings, and manually add anything interesting to your calendar.</p><p>Calendars are different. I check my calendar multiple times per day. Events already in my calendar get my attention. Events I have to go find do not.</p><p>The solution seemed obvious: get events into my calendar automatically.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://ruidiao.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading The Signal! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h2><strong>The Solution: An Auto-Syncing Calendar</strong></h2><p>I built a tool that syncs Luma events to Google Calendar automatically. It runs in the background on a regular schedule, pulling new events from Luma based on geographic boundaries and categories, then adding them to a dedicated calendar.</p><p>I created a public calendar focused on AI events in the South Bay area. You can subscribe to it and see all upcoming AI events directly in your Google Calendar alongside your other commitments. No manual checking required.</p><p>The calendar updates automatically. When new events are posted to Luma, they appear in your calendar within a few hours. When event details change, the calendar updates. When events are cancelled, they disappear from your calendar.</p><h2><strong>How It Works</strong></h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!cVok!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0bc5c1a1-c700-4757-9a8b-73d2257c6768_584x901.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!cVok!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0bc5c1a1-c700-4757-9a8b-73d2257c6768_584x901.png 424w, https://substackcdn.com/image/fetch/$s_!cVok!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0bc5c1a1-c700-4757-9a8b-73d2257c6768_584x901.png 848w, https://substackcdn.com/image/fetch/$s_!cVok!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0bc5c1a1-c700-4757-9a8b-73d2257c6768_584x901.png 1272w, https://substackcdn.com/image/fetch/$s_!cVok!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0bc5c1a1-c700-4757-9a8b-73d2257c6768_584x901.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!cVok!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0bc5c1a1-c700-4757-9a8b-73d2257c6768_584x901.png" width="584" height="901" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0bc5c1a1-c700-4757-9a8b-73d2257c6768_584x901.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:901,&quot;width&quot;:584,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:394339,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ruidiao.substack.com/i/181168265?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0bc5c1a1-c700-4757-9a8b-73d2257c6768_584x901.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!cVok!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0bc5c1a1-c700-4757-9a8b-73d2257c6768_584x901.png 424w, https://substackcdn.com/image/fetch/$s_!cVok!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0bc5c1a1-c700-4757-9a8b-73d2257c6768_584x901.png 848w, https://substackcdn.com/image/fetch/$s_!cVok!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0bc5c1a1-c700-4757-9a8b-73d2257c6768_584x901.png 1272w, https://substackcdn.com/image/fetch/$s_!cVok!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0bc5c1a1-c700-4757-9a8b-73d2257c6768_584x901.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The system has three main components:</p><p><strong>1. A web interface with an interactive map</strong></p><p>Users select a geographic area on a map and choose an event category. The map uses OpenStreetMap and lets you pan and zoom to define exactly which region you care about.</p><p><strong>2. Background automation in Google Apps Script</strong></p><p>The core logic runs on Google Apps Script, a serverless JavaScript runtime from Google. It handles OAuth authentication with Google Calendar, creates a dedicated calendar for the user, and sets up scheduled syncs.</p><p>The script regularly fetches events from Luma&#8217;s API that match the saved geographic boundaries and category. It compares them against what is already in the calendar, adds new events, updates changed events, and removes outdated ones.</p><p><strong>3. Automated deployments</strong></p><p>A GitHub Actions pipeline handles deployments. When I push code changes, it deploys the updated Google Apps Script, creates a new version, and updates the web interface with the new deployment URL. Old deployments are cleaned up automatically.</p><p>The entire system runs serverless. The web interface is a static HTML page hosted on GitHub Pages. The backend runs on Google Apps Script. There are no servers to maintain.</p><h2><strong>Subscribe to the South Bay AI Events Calendar</strong></h2><p>I have already set up a calendar for AI events in the South Bay area. You can add it to your Google Calendar by clicking this link:</p><p><strong><a href="https://calendar.google.com/calendar/u/0?cid=OWRiNDRjYTA0NGUwM2JjOTA2ZGQ3YzVmMWIwY2Y4MTRmNjliMDc4MGY2Mzc2M2I4ODEwZGIwNjdkY2VjNGM4YkBncm91cC5jYWxlbmRhci5nb29nbGUuY29t">Subscribe to South Bay AI Events Calendar</a></strong></p><p>The calendar includes meetups, talks, workshops, and conferences happening in the South Bay area. It updates automatically, so once you subscribe, you will see new events as they are posted.</p><p>If you live in the South Bay and follow AI, this calendar will help you stay informed without the manual effort of checking event platforms.</p><p>If you want to create a calendar for a different category or location, you can use the tool at <a href="https://eventsync.ruidiao.dev">eventsync.ruidiao.dev</a>. The tool is <a href="https://github.com/diaorui/event-sync">open source on GitHub</a> with full setup instructions in the README.</p><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://ruidiao.substack.com/p/a-calendar-for-south-bay-ai-events?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thanks for reading The Signal! This post is public so feel free to share it.</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ruidiao.substack.com/p/a-calendar-for-south-bay-ai-events?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://ruidiao.substack.com/p/a-calendar-for-south-bay-ai-events?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div>]]></content:encoded></item><item><title><![CDATA[Trying Agentic Browsing on Linux with Playwright MCP]]></title><description><![CDATA[The past few months brought a wave of agentic browser announcements.]]></description><link>https://ruidiao.substack.com/p/trying-agentic-browsing-on-linux</link><guid isPermaLink="false">https://ruidiao.substack.com/p/trying-agentic-browsing-on-linux</guid><dc:creator><![CDATA[Rui Diao]]></dc:creator><pubDate>Thu, 04 Dec 2025 19:04:49 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!kw91!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6bd0fcb-9c31-4702-9e4e-5370f5973654_2816x1536.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!kw91!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6bd0fcb-9c31-4702-9e4e-5370f5973654_2816x1536.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!kw91!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6bd0fcb-9c31-4702-9e4e-5370f5973654_2816x1536.png 424w, https://substackcdn.com/image/fetch/$s_!kw91!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6bd0fcb-9c31-4702-9e4e-5370f5973654_2816x1536.png 848w, https://substackcdn.com/image/fetch/$s_!kw91!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6bd0fcb-9c31-4702-9e4e-5370f5973654_2816x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!kw91!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6bd0fcb-9c31-4702-9e4e-5370f5973654_2816x1536.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!kw91!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6bd0fcb-9c31-4702-9e4e-5370f5973654_2816x1536.png" width="1456" height="794" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a6bd0fcb-9c31-4702-9e4e-5370f5973654_2816x1536.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:794,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:5870175,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://ruidiao.substack.com/i/180731123?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6bd0fcb-9c31-4702-9e4e-5370f5973654_2816x1536.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!kw91!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6bd0fcb-9c31-4702-9e4e-5370f5973654_2816x1536.png 424w, https://substackcdn.com/image/fetch/$s_!kw91!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6bd0fcb-9c31-4702-9e4e-5370f5973654_2816x1536.png 848w, https://substackcdn.com/image/fetch/$s_!kw91!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6bd0fcb-9c31-4702-9e4e-5370f5973654_2816x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!kw91!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6bd0fcb-9c31-4702-9e4e-5370f5973654_2816x1536.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The past few months brought a wave of agentic browser announcements. <a href="https://techcrunch.com/2025/07/09/perplexity-launches-comet-an-ai-powered-web-browser/">Perplexity launched Comet</a> in July 2025, promising AI-powered web browsing with automated task handling. <a href="https://openai.com/index/introducing-chatgpt-atlas/">OpenAI released ChatGPT Atlas</a> in October 2025, a macOS browser with ChatGPT built directly into the interface. <a href="https://www.microsoft.com/en-us/edge/copilot-mode">Microsoft introduced Copilot mode in Edge</a>, an experimental feature that takes on tasks and actions on behalf of users. But if you&#8217;re running Linux, you&#8217;re out of luck. None of these solutions work on Linux.</p><p>I&#8217;m not convinced agentic browsing is the future. The security concerns are real. Giving an AI agent access to navigate websites on your behalf means potential exposure of credentials and the risk of unintended actions like purchases or form submissions. But I wanted to try the experience anyway, if only to understand where this technology is heading.</p><p>Then I realized I already had the tools. <a href="https://github.com/microsoft/playwright-mcp">Playwright MCP</a> works with Claude Code, and both run perfectly on Linux.</p><h2><strong>The Setup</strong></h2><p>Getting Playwright MCP running with Claude Code is straightforward. Microsoft&#8217;s Playwright MCP server uses accessibility tree data instead of screenshots. You add the MCP server to Claude Code with a single command:</p><pre><code><code>claude mcp add playwright npx @playwright/mcp@latest</code></code></pre><p>After installation, Claude Code can control Playwright directly. It launches the browser, navigates pages, and submits forms. The browser window stays visible, so you can watch what&#8217;s happening in real time.</p><h2><strong>The Experience</strong></h2><p>I tested it with a simple task: &#8220;Open <a href="http://amazon.com">amazon.com</a> and find 3 Christmas gifts to put in cart.&#8221; Claude Code used the Playwright MCP tools to control the browser and handled the entire browsing session.</p><div class="native-video-embed" data-component-name="VideoPlaceholder" data-attrs="{&quot;mediaUploadId&quot;:&quot;4446c3c0-9120-4169-8989-242291e67fa7&quot;,&quot;duration&quot;:null}"></div><p>The experience felt similar to what the commercial agentic browsers promise. Claude navigated the site, searched for products, and added items to the cart. But two things stood out.</p><p>First, the token usage was surprisingly high for such a simple task. Each page interaction and piece of context fed back into the model consumed tokens rapidly. For a basic shopping task, the cost adds up quickly. This makes agentic browsing impractical for regular use at current pricing.</p><p>Second, watching the agent work reinforced my security concerns. The agent had full control. It could have clicked anything, submitted any form, entered any information. In this test, I stayed in control because I watched the browser window and could intervene. But the whole premise of agentic browsing is delegation. If I&#8217;m watching every action, what&#8217;s the point?</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://ruidiao.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading The Signal! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h2><strong>The Security Problem</strong></h2><p><a href="https://techcrunch.com/2025/10/25/the-glaring-security-risks-with-ai-browser-agents/">Security researchers have identified serious vulnerabilities</a> in agentic browsers. Indirect prompt injection attacks can hide malicious instructions in web pages or images, causing the AI to execute unintended actions. <a href="https://fortune.com/2025/10/23/cybersecurity-vulnerabilities-openai-chatgpt-atlas-ai-browser-leak-user-data-malware-prompt-injection/">ChatGPT Atlas was found to bypass standard encryption practices</a>, exposing private authentication data.</p><p>The threat model is different from traditional browsing. With a regular browser, you&#8217;re the one making decisions. With an agentic browser, you&#8217;re trusting the AI to make correct decisions while navigating potentially malicious content. A compromised AI agent could expose credentials, leak personal information, or execute financial transactions without proper verification.</p><p><a href="https://brave.com/blog/comet-prompt-injection/">Researchers from Brave found</a> that benign-looking websites or social media comments could steal login credentials by adding invisible instructions for the AI assistant. The agent processes these as commands rather than untrusted content.</p><p>These aren&#8217;t hypothetical risks. They&#8217;re documented vulnerabilities in shipping products.</p><h2><strong>A Transitional Technology</strong></h2><p>Agentic browsing feels like an intermediate solution. We&#8217;re taking a tool designed for humans (web browsers) and bolting AI on top. The result is inefficient and insecure.</p><p>The browser itself is the problem. Browsers render visual interfaces for human consumption. AI agents don&#8217;t need visual interfaces. They need structured data. Playwright MCP takes a step in the right direction by using accessibility tree data instead of screenshots, but it still operates through a visual browser interface designed for humans.</p><p>The future likely moves in three directions:</p><p>First, <strong>API-first solutions</strong>. Instead of having AI navigate visual interfaces, services will provide structured APIs designed for agent access. This is already happening in specific domains. The question is how quickly it spreads to general web interaction.</p><p>Second, <strong>better efficiency and lower costs</strong>. Current token consumption makes agentic browsing expensive. Models need to get better at understanding context with fewer tokens, or the cost structure needs to change. Until then, this remains a demo technology rather than a practical tool.</p><p>Third, <strong>enhanced security models</strong>. We need frameworks for safe delegation that include verification steps, sandboxing, and clear boundaries on what actions agents can take. The current model of &#8220;give the AI full browser access and hope for the best&#8221; is not sustainable.</p><h2><strong>For Linux Users Right Now</strong></h2><p>If you&#8217;re on Linux and want to try agentic browsing, Playwright MCP with Claude Code works. The <a href="https://github.com/microsoft/playwright-mcp">setup is documented</a>, and the integration is clean.</p><p>But I&#8217;d recommend approaching it as an experiment, not a workflow. The token costs are high, the security model is uncertain, and the practical benefits are limited. It&#8217;s useful for understanding where this technology is going, but not for daily use.</p><p>Watch the browser window. Don&#8217;t leave it unattended. Don&#8217;t use it with accounts that have access to sensitive information or financial systems. And be aware that websites you visit could potentially inject malicious instructions into the AI agent.</p><p>Agentic browsing will evolve. The current implementation is a starting point, not a destination. For now, it&#8217;s an interesting way to see the future taking shape, even on a platform the commercial vendors haven&#8217;t bothered to support.</p><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://ruidiao.substack.com/p/trying-agentic-browsing-on-linux?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thanks for reading The Signal! This post is public so feel free to share it.</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ruidiao.substack.com/p/trying-agentic-browsing-on-linux?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://ruidiao.substack.com/p/trying-agentic-browsing-on-linux?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div>]]></content:encoded></item><item><title><![CDATA[Building My First MCP Server: What Vibe Coding Gets Right (and Wrong)]]></title><description><![CDATA[&#8220;The computer is incredibly fast, accurate, and stupid.]]></description><link>https://ruidiao.substack.com/p/building-my-first-mcp-server-what</link><guid isPermaLink="false">https://ruidiao.substack.com/p/building-my-first-mcp-server-what</guid><dc:creator><![CDATA[Rui Diao]]></dc:creator><pubDate>Tue, 02 Dec 2025 16:42:59 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!9daa!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74e0ed48-14c4-43fa-ac30-52acd7ecfd4c_2816x1536.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!9daa!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74e0ed48-14c4-43fa-ac30-52acd7ecfd4c_2816x1536.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!9daa!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74e0ed48-14c4-43fa-ac30-52acd7ecfd4c_2816x1536.png 424w, https://substackcdn.com/image/fetch/$s_!9daa!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74e0ed48-14c4-43fa-ac30-52acd7ecfd4c_2816x1536.png 848w, https://substackcdn.com/image/fetch/$s_!9daa!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74e0ed48-14c4-43fa-ac30-52acd7ecfd4c_2816x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!9daa!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74e0ed48-14c4-43fa-ac30-52acd7ecfd4c_2816x1536.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!9daa!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74e0ed48-14c4-43fa-ac30-52acd7ecfd4c_2816x1536.png" width="1456" height="794" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/74e0ed48-14c4-43fa-ac30-52acd7ecfd4c_2816x1536.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:794,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:6433801,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://ruidiao.substack.com/i/180473923?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74e0ed48-14c4-43fa-ac30-52acd7ecfd4c_2816x1536.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!9daa!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74e0ed48-14c4-43fa-ac30-52acd7ecfd4c_2816x1536.png 424w, https://substackcdn.com/image/fetch/$s_!9daa!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74e0ed48-14c4-43fa-ac30-52acd7ecfd4c_2816x1536.png 848w, https://substackcdn.com/image/fetch/$s_!9daa!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74e0ed48-14c4-43fa-ac30-52acd7ecfd4c_2816x1536.png 1272w, https://substackcdn.com/image/fetch/$s_!9daa!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74e0ed48-14c4-43fa-ac30-52acd7ecfd4c_2816x1536.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><blockquote><p>&#8220;The computer is incredibly fast, accurate, and stupid. Man is unbelievably slow, inaccurate, and brilliant. The marriage of the two is a force beyond calculation.&#8221;</p><p>- Leo Cherne</p></blockquote><p>I recently built my <a href="https://github.com/diaorui/jupiter-perps-mcp">first MCP server</a> for trading perpetual futures on Jupiter, a Solana-based derivatives platform. I used vibe coding for the project. The AI handled the boilerplate and framework setup well. But the substantial work, analyzing undocumented protocols and designing the tool interface, required traditional software engineering judgment. This combination revealed where AI-assisted development works and where it does not.</p><h2><strong>Why MCP Matters for AI Agents</strong></h2><p>Anthropic introduced the <a href="https://www.anthropic.com/news/model-context-protocol">Model Context Protocol</a> in November 2024. Just over a year later, it has become the standard for connecting AI agents to external tools and data. The timing was right. As AI agents evolved from simple chatbots to systems that can take actions, they needed a standardized way to interact with the world. MCP solved that problem.</p><p>The adoption has been rapid. OpenAI officially adopted MCP in March 2025. Google, Microsoft, SAP, Oracle, and Docker followed. The community has built thousands of MCP servers across different domains. For agentic AI, MCP provides the foundation that makes real work possible.</p><h2><strong>Why Crypto Trading Needs AI Agents</strong></h2><p>I have been thinking that agentic AI could be particularly suitable for crypto trading. The reasons are straightforward:</p><ul><li><p>AI can analyze large amounts of data quickly</p></li><li><p>AI can search and synthesize information from multiple sources</p></li><li><p>AI does not panic or get emotional during market volatility</p></li><li><p>AI can operate continuously without fatigue</p></li></ul><p>Perpetual futures trading amplifies these needs. With leverage up to 100x on platforms like Jupiter, emotional trading leads to rapid losses. The ability to stay calm and objective is critical. AI agents have that advantage.</p><p>Building this MCP server was primarily a learning exercise. I wanted to understand how to implement MCP properly. But the functionality is real. The server supports live trading of SOL, ETH, and BTC perpetuals, technical analysis with seven indicators (RSI, MACD, Bollinger Bands, ATR, EMA, SMA, and Stochastic oscillators), and real-time portfolio tracking.</p><div class="native-video-embed" data-component-name="VideoPlaceholder" data-attrs="{&quot;mediaUploadId&quot;:&quot;938258c8-bc47-4ead-ae8a-3086e584c9f8&quot;,&quot;duration&quot;:null}"></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://ruidiao.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading The Signal! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h2><strong>What Vibe Coding Actually Means</strong></h2><p>For context, <a href="https://en.wikipedia.org/wiki/Vibe_coding">vibe coding</a> is an approach where developers describe what they want to an AI model, which generates the code. The defining characteristic is that you do not review the code the AI writes. You focus on outcomes, not implementation details. The term was introduced by Andrej Karpathy in February 2025 and named Collins Dictionary&#8217;s Word of the Year for 2025.</p><p>I used vibe coding for this project. The basic structure came together quickly. The MCP framework setup worked. The boilerplate code was fine. But vibe coding did not handle everything.</p><h2><strong>Where Human Work Was Required</strong></h2><p>Jupiter does not officially provide public APIs for their perpetual futures protocol. AI cannot reverse engineer protocol interactions without extensive manual analysis.</p><p>I had to do the API analysis myself. I traced through the protocol mechanics. I read the smart contract interactions. I figured out what data was available and how to request it properly. This was traditional software engineering work. There was no shortcut.</p><p>Then came the interface design. MCP tools need well-defined inputs and outputs. Which fields should be included? Which should be optional? How much information should the AI agent receive versus what should be abstracted away?</p><p>These design decisions require a framework. You need to balance convenience, accuracy, and information load. Too much data overwhelms the AI agent. Too little data limits what it can do. Getting this balance right is hard. AI struggles with this kind of design philosophy. It can generate code based on specifications. It cannot make the judgment calls about what those specifications should be.</p><p>I made those decisions. The AI implemented them.</p><p>This is the pattern that emerged throughout the project. Vibe coding accelerated implementation of well-defined specifications. But the critical thinking about what to build, how to structure it, and what tradeoffs to make required human judgment.</p><h2><strong>Will I Use This for Real Trading?</strong></h2><p>Probably not. Perpetual futures trading involves substantial risk of loss. With 100x leverage, small price movements can wipe out positions instantly. While the MCP server has all the necessary functionality, the combination of automated trading and high leverage creates risk that I am not comfortable with for real money.</p><p>This project is for educational and research purposes. If you explore the code, use a dedicated wallet with limited funds. You are solely responsible for any trading decisions and losses.</p><h2><strong>AI Trading Is Here</strong></h2><p>Whether I use this specific implementation or not, AI trading is becoming more prevalent. I expect this trend to accelerate. The advantages are clear. AI can process information faster, maintain objectivity under pressure, and operate continuously.</p><p>The infrastructure is falling into place. MCP provides the protocol for connecting AI agents to trading platforms. Models are improving their reasoning and decision-making capabilities. The tooling is getting better.</p><p>The question is not whether AI will trade. It is how quickly human traders will adopt AI assistance, and how markets will evolve when AI becomes a significant participant.</p><p>For now, I learned what I set out to learn: how to build an MCP server, what vibe coding handles well, and where it breaks down. The code is <a href="https://github.com/diaorui/jupiter-perps-mcp">on GitHub</a> if you want to explore it yourself.</p><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://ruidiao.substack.com/p/building-my-first-mcp-server-what?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thanks for reading The Signal! This post is public so feel free to share it.</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ruidiao.substack.com/p/building-my-first-mcp-server-what?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://ruidiao.substack.com/p/building-my-first-mcp-server-what?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div>]]></content:encoded></item><item><title><![CDATA[My AI News Dashboard: Built with Vibe Coding in a Week]]></title><description><![CDATA[The Problem: Context Switching Between Sites]]></description><link>https://ruidiao.substack.com/p/my-ai-news-dashboard-built-with-vibe</link><guid isPermaLink="false">https://ruidiao.substack.com/p/my-ai-news-dashboard-built-with-vibe</guid><dc:creator><![CDATA[Rui Diao]]></dc:creator><pubDate>Mon, 24 Nov 2025 22:52:54 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!mJOS!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b59770b-9868-4b56-af57-f265301c3320_1299x897.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!mJOS!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b59770b-9868-4b56-af57-f265301c3320_1299x897.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!mJOS!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b59770b-9868-4b56-af57-f265301c3320_1299x897.png 424w, https://substackcdn.com/image/fetch/$s_!mJOS!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b59770b-9868-4b56-af57-f265301c3320_1299x897.png 848w, https://substackcdn.com/image/fetch/$s_!mJOS!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b59770b-9868-4b56-af57-f265301c3320_1299x897.png 1272w, https://substackcdn.com/image/fetch/$s_!mJOS!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b59770b-9868-4b56-af57-f265301c3320_1299x897.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!mJOS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b59770b-9868-4b56-af57-f265301c3320_1299x897.png" width="1299" height="897" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0b59770b-9868-4b56-af57-f265301c3320_1299x897.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:897,&quot;width&quot;:1299,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:609954,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://ruidiao.substack.com/i/179866688?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b59770b-9868-4b56-af57-f265301c3320_1299x897.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!mJOS!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b59770b-9868-4b56-af57-f265301c3320_1299x897.png 424w, https://substackcdn.com/image/fetch/$s_!mJOS!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b59770b-9868-4b56-af57-f265301c3320_1299x897.png 848w, https://substackcdn.com/image/fetch/$s_!mJOS!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b59770b-9868-4b56-af57-f265301c3320_1299x897.png 1272w, https://substackcdn.com/image/fetch/$s_!mJOS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b59770b-9868-4b56-af57-f265301c3320_1299x897.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2><strong>The Problem: Context Switching Between Sites</strong></h2><p>I spend a lot of time monitoring AI developments. It&#8217;s part of staying current in tech, but the routine had become tedious. Every morning, I&#8217;d open the same rotation of sites: Google News for articles, HuggingFace for new models, GitHub for trending repos, and more.</p><p>By the time I&#8217;d checked everything, hours had passed. And if I didn&#8217;t do this daily? I&#8217;d miss something important. A breakthrough model. A major product announcement. A trending new tool.</p><p>The real problem wasn&#8217;t the amount of information. It was the inefficiency. Context switching between multiple sites, each with different interfaces and layouts. And it was easy to forget a site or miss checking something entirely.</p><h2><strong>The Solution: A Personal Information Hub</strong></h2><p>I built <a href="https://peekdeck.ruidiao.dev/">PeekDeck</a>, a dashboard generator that turns YAML configurations into live monitoring dashboards. No backend. No database. Just static HTML that updates automatically.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!EeVw!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b587918-d5fa-4985-a598-e3661d6c006d_1200x630.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!EeVw!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b587918-d5fa-4985-a598-e3661d6c006d_1200x630.png 424w, https://substackcdn.com/image/fetch/$s_!EeVw!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b587918-d5fa-4985-a598-e3661d6c006d_1200x630.png 848w, https://substackcdn.com/image/fetch/$s_!EeVw!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b587918-d5fa-4985-a598-e3661d6c006d_1200x630.png 1272w, https://substackcdn.com/image/fetch/$s_!EeVw!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b587918-d5fa-4985-a598-e3661d6c006d_1200x630.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!EeVw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b587918-d5fa-4985-a598-e3661d6c006d_1200x630.png" width="1200" height="630" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9b587918-d5fa-4985-a598-e3661d6c006d_1200x630.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:630,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:105929,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ruidiao.substack.com/i/179866688?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b587918-d5fa-4985-a598-e3661d6c006d_1200x630.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!EeVw!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b587918-d5fa-4985-a598-e3661d6c006d_1200x630.png 424w, https://substackcdn.com/image/fetch/$s_!EeVw!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b587918-d5fa-4985-a598-e3661d6c006d_1200x630.png 848w, https://substackcdn.com/image/fetch/$s_!EeVw!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b587918-d5fa-4985-a598-e3661d6c006d_1200x630.png 1272w, https://substackcdn.com/image/fetch/$s_!EeVw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b587918-d5fa-4985-a598-e3661d6c006d_1200x630.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The concept is simple: define what you want to monitor in a config file, and PeekDeck generates a dashboard that aggregates everything in one place. Want to track Bitcoin prices alongside AI news? Add two widgets. Want to monitor robotics and Ethereum trends? Same approach.</p><p>I built the first version in a week, mostly through vibe coding.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://ruidiao.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading The Signal! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h2><strong>How It Works: Static Dashboards, Dynamic Data</strong></h2><p>PeekDeck operates on a three-stage pipeline:</p><ol><li><p><strong>Fetch</strong>: Pull data from various APIs</p></li><li><p><strong>Process</strong>: Transform and optionally summarize the data</p></li><li><p><strong>Render</strong>: Create static HTML pages from Jinja2 templates</p></li></ol><p>GitHub Actions handles the automation, running on a regular schedule throughout the day. Each widget has its own update frequency to respect API rate limits. No servers to maintain. No infrastructure costs.</p><p>Here&#8217;s what a simple dashboard configuration looks like:</p><pre><code><code>category: tech
name: Artificial Intelligence
description: AI news, discussions, and developments
icon: &#10024;

widgets:
  - type: reddit-posts
    update_minutes: 30
    params:
      subreddit: artificial
      limit: 10

  - type: youtube-videos
    update_minutes: 120
    params:
      search_query: AI
      limit: 10

  - type: github-repos
    update_minutes: 60
    params:
      topic: artificial-intelligence
      limit: 10
</code></code></pre><h2><strong>Product Decisions: Generic by Design</strong></h2><p>When I started building, I faced a choice: optimize for AI monitoring specifically, or build something reusable?</p><p>I chose generic. Here&#8217;s why:</p><p><strong>Flexibility over optimization</strong>: A specialized AI dashboard might be better at tracking AI news, but a generic dashboard can monitor anything. When I got interested in crypto trends or robotics, I just added new widgets.</p><p><strong>Widget-based architecture</strong>: Each data source is a reusable component. The Reddit widget doesn&#8217;t care if you&#8217;re tracking r/MachineLearning or r/CryptoCurrency. The YouTube widget works for AI news or robotics demos.</p><p><strong>Configuration over code</strong>: Adding a new dashboard takes minutes. No coding required, just edit a YAML file. I could try monitoring new topics and drop them if they weren&#8217;t useful.</p><p>The tradeoff? Less polish in any single use case. But for my needs, the flexibility has been worth it.</p><h2><strong>The Technical Journey: Vibe Coding at Scale</strong></h2><p>I built this primarily through vibe coding. Over 100 commits in a week, building from scratch. The final codebase has several thousand lines of Python and HTML.</p><p>The key was starting with a design doc. AI tools aren&#8217;t great at high-level planning yet, so I spent time upfront thinking through the architecture: three-stage pipeline (fetch, process, render), widget-based design, YAML configs, static HTML output. Then I vibe coded the design doc itself in markdown, turning those ideas into a structured document.</p><p>With that foundation in place, the build moved fast. Start with a working prototype for one data source. Get it end-to-end. Then iterate. Add more sources. Improve the templating. Add GitHub Actions automation. Add caching. Each piece building on the last.</p><p>With vibe coding, you provide the plan, the AI handles the execution. The design evolved as I coded, but having that initial structure let the AI focus on implementation rather than architecture.</p><p>After the first version, expanding became straightforward. Each new widget took an hour or two: extend the base class, implement three methods (fetch, process, render), done.</p><p>Without vibe coding, a project like this would have taken weeks or even months, not days. The main takeaway? Design docs are essential for vibe coding to work at this scale.</p><h2><strong>Try It Yourself</strong></h2><p>PeekDeck is <a href="https://github.com/diaorui/peek-deck">open source on GitHub</a>. You can:</p><ul><li><p>Fork it and customize for your needs</p></li><li><p>Add new widgets for different data sources</p></li><li><p>Deploy your own dashboards on GitHub Pages</p></li></ul><p>Check out the <a href="https://peekdeck.ruidiao.dev/">live demo</a> to see it in action. I&#8217;m currently monitoring AI news, robotics, Bitcoin, and Ethereum, all in one place.</p><p>If you build something with it or have ideas for new widgets, I&#8217;d love to hear about it.</p><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://ruidiao.substack.com/p/my-ai-news-dashboard-built-with-vibe?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thanks for reading The Signal! This post is public so feel free to share it.</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ruidiao.substack.com/p/my-ai-news-dashboard-built-with-vibe?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://ruidiao.substack.com/p/my-ai-news-dashboard-built-with-vibe?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div>]]></content:encoded></item><item><title><![CDATA[The AI Paradox: Why Big Tech Moves Slower Than Ever]]></title><description><![CDATA[Yesterday, I tried to push code to GitHub.]]></description><link>https://ruidiao.substack.com/p/the-ai-paradox-why-big-tech-moves</link><guid isPermaLink="false">https://ruidiao.substack.com/p/the-ai-paradox-why-big-tech-moves</guid><dc:creator><![CDATA[Rui Diao]]></dc:creator><pubDate>Wed, 19 Nov 2025 23:36:09 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!bJmP!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b993fe0-50d1-472e-963d-d4a18593e7b7_994x408.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Yesterday, I tried to push code to GitHub. What should have taken one second stretched into several minutes before failing completely. The culprit? A <a href="https://blog.cloudflare.com/18-november-2025-outage/">Cloudflare outage</a> that brought down ChatGPT, X, GitHub, and countless other services. A single bug in Cloudflare&#8217;s Bot Management system caused an estimated <a href="https://www.themirror.com/tech/tech-news/staggering-cost-cloudflare-outage-estimated-1512609">$5 to $15 billion in losses</a> per hour.</p><p>A single bug at Cloudflare took down a huge chunk of the internet. We built AI and automation to make us faster and more reliable, yet here we are, more vulnerable than ever to cascading failures.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!bJmP!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b993fe0-50d1-472e-963d-d4a18593e7b7_994x408.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!bJmP!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b993fe0-50d1-472e-963d-d4a18593e7b7_994x408.png 424w, https://substackcdn.com/image/fetch/$s_!bJmP!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b993fe0-50d1-472e-963d-d4a18593e7b7_994x408.png 848w, https://substackcdn.com/image/fetch/$s_!bJmP!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b993fe0-50d1-472e-963d-d4a18593e7b7_994x408.png 1272w, https://substackcdn.com/image/fetch/$s_!bJmP!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b993fe0-50d1-472e-963d-d4a18593e7b7_994x408.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!bJmP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b993fe0-50d1-472e-963d-d4a18593e7b7_994x408.png" width="994" height="408" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8b993fe0-50d1-472e-963d-d4a18593e7b7_994x408.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:408,&quot;width&quot;:994,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:32019,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://ruidiao.substack.com/i/179406834?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b993fe0-50d1-472e-963d-d4a18593e7b7_994x408.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!bJmP!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b993fe0-50d1-472e-963d-d4a18593e7b7_994x408.png 424w, https://substackcdn.com/image/fetch/$s_!bJmP!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b993fe0-50d1-472e-963d-d4a18593e7b7_994x408.png 848w, https://substackcdn.com/image/fetch/$s_!bJmP!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b993fe0-50d1-472e-963d-d4a18593e7b7_994x408.png 1272w, https://substackcdn.com/image/fetch/$s_!bJmP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b993fe0-50d1-472e-963d-d4a18593e7b7_994x408.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This incident crystallized something I learned during my 10+ years at Google, a lesson that becomes more relevant every day in the AI era: <strong>AI lets us move fast, but responsibility forces us to move slow.</strong></p><h2><strong>The Ramp-Up Reality at Google Ads</strong></h2><p>Early in my career on the Google Ads team, I learned a frustrating truth: launching any new feature (whether it&#8217;s a new model, algorithm, or UI change) requires a slow ramp-up process. We would start by exposing the feature to just 1% of users, then gradually increase traffic over weeks or even months.</p><p>The process felt extremely slow. Some experiments would crash servers, causing Google to show no ads to affected users. When that happened, Google lost revenue (sometimes small amounts, sometimes significant sums). Only a tiny fraction of users would notice, typically fewer than the experiment&#8217;s traffic percentage, because most users wouldn&#8217;t see the absence of ads as a problem.</p><p>I thought we were being overly cautious. The deployment timeline seemed excessive just to avoid these occasional failures. But I was wrong about what &#8220;slow&#8221; really meant.</p><h2><strong>When I Learned What &#8220;Slow&#8221; Actually Means</strong></h2><p>Moving to Google Search changed my perspective entirely. I had thought the Ads team moved slowly, but the Search team operated on a completely different timescale. The difference came down to responsibility and blast radius.</p><p>When ads go down, users don&#8217;t see advertisements, but Search as a product remains functional. When Search goes down, users have nothing. The service failure becomes headline news within minutes.</p><p>This fundamental difference shaped every aspect of the Search team&#8217;s deployment process. Experiments took much longer to start receiving traffic. The monitoring period before any ramp-up was extensive, designed to catch potential issues before they could impact users at scale. Every process moved slower than the Ads team&#8217;s already-cautious approach.</p><p>The pattern became clear: the larger your responsibility, the slower you must move, regardless of how advanced your tools become.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://ruidiao.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading The Signal! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h2><strong>The Scale-Responsibility Equation</strong></h2><p>The tech industry uses <a href="https://martinfowler.com/bliki/CanaryRelease.html">canary deployments</a>, a strategy where new versions gradually roll out to small percentages of users before full release. The process typically follows a pattern: 1-2% of traffic initially, then 5%, 10%, 25%, 50%, and finally 100%. Each stage requires time to analyze metrics and gather feedback.</p><p>This isn&#8217;t unique to Google. Netflix, Facebook, and every major tech company follow similar patterns. The gradual rollout serves as an early warning system, catching problems before they impact the entire user base.</p><p>But here&#8217;s what the Cloudflare outage revealed: even with all these safeguards, scale creates catastrophic single points of failure. Cloudflare powers <a href="https://www.tomsguide.com/news/live/cloudfare-outage-november-2025-x-chatgpt">19% of all websites</a>. When a bug slipped through their deployment process, nearly one-fifth of the internet went dark.</p><h2><strong>The AI Productivity Paradox</strong></h2><p>The tech community celebrates every AI milestone: new model launches, productivity improvements, automation breakthroughs. We&#8217;ve built tools that can write code, debug systems, and optimize deployments faster than ever before.</p><p>Yet large companies can&#8217;t take full advantage of this speed. AI might help us build features faster, but it can&#8217;t guarantee 100% accuracy, and it&#8217;s nowhere close. According to <a href="https://www.featbit.co/articles2025/canary-deployment-example-process-2025">research on canary deployments</a>, even with modern AI-assisted development, companies still need weeks of gradual rollout to ensure reliability.</p><p>This creates the paradox: our tools get faster while our deployment processes get slower. The gap between development speed and deployment speed keeps widening.</p><p>The reason is simple: the cost of failure grows faster than our ability to prevent it. When you serve billions of users, a 0.1% error rate affects millions of people. When your infrastructure powers 19% of the internet, a single configuration bug costs billions per hour.</p><h2><strong>The Human Rate Limiter</strong></h2><p>AI can do remarkable things. It improves our productivity dramatically. But it cannot eliminate uncertainty, and it cannot fully understand context the way humans can. There will always be edge cases, unexpected interactions, and systemic risks that automated systems miss.</p><p>This means there must be humans in the loop. There must be policies and processes that deliberately slow things down. We need monitoring periods, gradual ramp-ups, and staged rollouts, not because we lack confidence in our tools, but because we understand the magnitude of potential failures.</p><h2><strong>Moving Forward in the Age of AI</strong></h2><p>AI is making building things faster than ever. Development cycles are compressing. Prototypes emerge in hours instead of weeks. But for companies operating at scale, deployment will remain slow, and it should.</p><p>This isn&#8217;t a failure of AI. It&#8217;s a recognition of responsibility. The larger the impact of your systems, the more deliberately you must deploy them. Scale demands caution, and caution demands time.</p><p>The next time you wonder why your favorite product hasn&#8217;t adopted the latest AI feature, or why a seemingly simple update takes months to roll out, remember: it&#8217;s not that big tech companies don&#8217;t understand AI&#8217;s potential. It&#8217;s that they understand their responsibility.</p><p>In the race between AI-powered acceleration and responsibility-mandated caution, responsibility will always win. And that&#8217;s exactly how it should be.</p><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://ruidiao.substack.com/p/the-ai-paradox-why-big-tech-moves?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thanks for reading The Signal! This post is public so feel free to share it.</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ruidiao.substack.com/p/the-ai-paradox-why-big-tech-moves?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://ruidiao.substack.com/p/the-ai-paradox-why-big-tech-moves?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div>]]></content:encoded></item><item><title><![CDATA[NanoCoffee 1.1: From Summaries to AI Writing Assistant]]></title><description><![CDATA[Last week, I shipped NanoCoffee, a Chrome extension that summarizes long posts on social media using on-device AI.]]></description><link>https://ruidiao.substack.com/p/nanocoffee-11-from-summaries-to-ai</link><guid isPermaLink="false">https://ruidiao.substack.com/p/nanocoffee-11-from-summaries-to-ai</guid><dc:creator><![CDATA[Rui Diao]]></dc:creator><pubDate>Mon, 17 Nov 2025 22:56:25 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!ZZe7!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6bbcb440-28bd-48a4-8474-212dd2ef0166_1197x860.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Last week, I <a href="https://ruidiao.substack.com/p/i-built-an-ai-chrome-extension-in">shipped NanoCoffee</a>, a Chrome extension that summarizes long posts on social media using on-device AI. Today, I&#8217;m launching version 1.1 with the writing features I mentioned in the original article.</p><p>NanoCoffee now helps you write and rewrite content on X, LinkedIn, and Substack. Everything still runs locally on your device. No servers. No API costs. Complete privacy.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ZZe7!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6bbcb440-28bd-48a4-8474-212dd2ef0166_1197x860.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ZZe7!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6bbcb440-28bd-48a4-8474-212dd2ef0166_1197x860.png 424w, https://substackcdn.com/image/fetch/$s_!ZZe7!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6bbcb440-28bd-48a4-8474-212dd2ef0166_1197x860.png 848w, https://substackcdn.com/image/fetch/$s_!ZZe7!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6bbcb440-28bd-48a4-8474-212dd2ef0166_1197x860.png 1272w, https://substackcdn.com/image/fetch/$s_!ZZe7!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6bbcb440-28bd-48a4-8474-212dd2ef0166_1197x860.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ZZe7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6bbcb440-28bd-48a4-8474-212dd2ef0166_1197x860.png" width="1197" height="860" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6bbcb440-28bd-48a4-8474-212dd2ef0166_1197x860.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:860,&quot;width&quot;:1197,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:271035,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://ruidiao.substack.com/i/179193553?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38aa6bc1-8ed4-4e4d-bf11-c8db4a5f21b2_1483x861.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ZZe7!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6bbcb440-28bd-48a4-8474-212dd2ef0166_1197x860.png 424w, https://substackcdn.com/image/fetch/$s_!ZZe7!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6bbcb440-28bd-48a4-8474-212dd2ef0166_1197x860.png 848w, https://substackcdn.com/image/fetch/$s_!ZZe7!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6bbcb440-28bd-48a4-8474-212dd2ef0166_1197x860.png 1272w, https://substackcdn.com/image/fetch/$s_!ZZe7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6bbcb440-28bd-48a4-8474-212dd2ef0166_1197x860.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2><strong>What&#8217;s New</strong></h2><p>When you&#8217;re composing a post or reply, NanoCoffee now offers AI assistance to help you:</p><ul><li><p><strong>Generate contextual replies</strong> based on the post you&#8217;re responding to</p></li><li><p><strong>Rewrite your drafts</strong> to adjust tone or restructure your message</p></li><li><p><strong>Toggle between casual and formal</strong> voices with a click</p></li><li><p><strong>Expand or condense</strong> your content</p></li></ul><p>The original summarization feature is still there. Now you can also get AI help when you write.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://ruidiao.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading The Signal! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h2><strong>How It Works</strong></h2><p>Version 1.1 uses two additional Chrome built-in APIs alongside the <a href="https://developer.chrome.com/docs/ai/summarizer-api">Summarizer API</a>:</p><p>The <a href="https://developer.chrome.com/docs/ai/writer-api">Writer API</a> generates contextual replies when you click &#8220;Generate Reply&#8221; on a post. The <a href="https://developer.chrome.com/docs/ai/rewriter-api">Rewriter API</a> transforms your existing drafts when you want to adjust tone or length.</p><p>Both APIs run Gemini Nano locally on your device. Like the Summarization API, they require no authentication, no API keys, and no backend infrastructure.</p><h2><strong>Why This Still Matters</strong></h2><p>Traditional AI writing tools pull you out of your workflow. You copy text, switch tabs, paste, get a result, and bring it back. NanoCoffee eliminates that friction.</p><p>This is only possible because Chrome&#8217;s built-in AI provides the infrastructure. With cloud APIs, usage costs would force me to either charge users or raise funding to sustain the service.</p><p>On-device AI changes the economics. I can offer these features for free, users get complete privacy, and the extension improves automatically as Google updates Gemini Nano.</p><h2><strong>What&#8217;s Next</strong></h2><p>I&#8217;m currently focused on a separate project, but I&#8217;ll continue updating NanoCoffee as Chrome&#8217;s built-in AI capabilities evolve. The goal remains the same: make AI assistance feel native to your browsing experience.</p><h2><strong>Try NanoCoffee 1.1</strong></h2><p>If you&#8217;re already using NanoCoffee, the update should happen automatically through the Chrome Web Store. If you&#8217;re new to NanoCoffee, visit <a href="https://nanocoffee.ruidiao.dev">nanocoffee.ruidiao.dev</a> or <a href="https://chromewebstore.google.com/detail/nanocoffee/imociajlipjlmiglmjkpkjmkkfbblmhk">install directly from the Chrome Web Store</a>.</p><p>The extension is free, open source, and works entirely on your device. Check out the code on <a href="https://github.com/diaorui/NanoCoffee">GitHub</a>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!TfsA!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7771a5a2-458b-40ba-bdc1-31d233898b4b_988x649.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!TfsA!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7771a5a2-458b-40ba-bdc1-31d233898b4b_988x649.png 424w, https://substackcdn.com/image/fetch/$s_!TfsA!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7771a5a2-458b-40ba-bdc1-31d233898b4b_988x649.png 848w, https://substackcdn.com/image/fetch/$s_!TfsA!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7771a5a2-458b-40ba-bdc1-31d233898b4b_988x649.png 1272w, https://substackcdn.com/image/fetch/$s_!TfsA!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7771a5a2-458b-40ba-bdc1-31d233898b4b_988x649.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!TfsA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7771a5a2-458b-40ba-bdc1-31d233898b4b_988x649.png" width="988" height="649" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7771a5a2-458b-40ba-bdc1-31d233898b4b_988x649.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:649,&quot;width&quot;:988,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:250221,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ruidiao.substack.com/i/179193553?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7771a5a2-458b-40ba-bdc1-31d233898b4b_988x649.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!TfsA!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7771a5a2-458b-40ba-bdc1-31d233898b4b_988x649.png 424w, https://substackcdn.com/image/fetch/$s_!TfsA!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7771a5a2-458b-40ba-bdc1-31d233898b4b_988x649.png 848w, https://substackcdn.com/image/fetch/$s_!TfsA!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7771a5a2-458b-40ba-bdc1-31d233898b4b_988x649.png 1272w, https://substackcdn.com/image/fetch/$s_!TfsA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7771a5a2-458b-40ba-bdc1-31d233898b4b_988x649.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2><strong>The Bigger Picture</strong></h2><p>Chrome&#8217;s built-in AI is still early, but the direction is clear. AI is becoming a platform capability, not just a cloud service.</p><p>For developers, the barrier to shipping AI products continues to drop. You don&#8217;t need VC funding for API costs or a team to manage infrastructure.</p><p>For users, this means more privacy-respecting AI tools that integrate into existing workflows instead of requiring separate apps.</p><p>NanoCoffee 1.1 is one example. I&#8217;m excited to see what else gets built as Chrome&#8217;s AI capabilities mature.</p><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://ruidiao.substack.com/p/nanocoffee-11-from-summaries-to-ai?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thanks for reading The Signal! This post is public so feel free to share it.</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ruidiao.substack.com/p/nanocoffee-11-from-summaries-to-ai?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://ruidiao.substack.com/p/nanocoffee-11-from-summaries-to-ai?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div>]]></content:encoded></item><item><title><![CDATA[Building My Personal Website in 2025: A Decade-Long Evolution]]></title><description><![CDATA[From WordPress to AI-Generated Code: What Changed and What I Learned]]></description><link>https://ruidiao.substack.com/p/building-my-personal-website-in-2025</link><guid isPermaLink="false">https://ruidiao.substack.com/p/building-my-personal-website-in-2025</guid><dc:creator><![CDATA[Rui Diao]]></dc:creator><pubDate>Thu, 13 Nov 2025 16:47:30 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!tYXD!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5158cc01-f106-4493-9ef4-8764aeb10bdf_883x827.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!tYXD!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5158cc01-f106-4493-9ef4-8764aeb10bdf_883x827.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!tYXD!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5158cc01-f106-4493-9ef4-8764aeb10bdf_883x827.png 424w, https://substackcdn.com/image/fetch/$s_!tYXD!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5158cc01-f106-4493-9ef4-8764aeb10bdf_883x827.png 848w, https://substackcdn.com/image/fetch/$s_!tYXD!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5158cc01-f106-4493-9ef4-8764aeb10bdf_883x827.png 1272w, https://substackcdn.com/image/fetch/$s_!tYXD!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5158cc01-f106-4493-9ef4-8764aeb10bdf_883x827.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!tYXD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5158cc01-f106-4493-9ef4-8764aeb10bdf_883x827.png" width="883" height="827" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5158cc01-f106-4493-9ef4-8764aeb10bdf_883x827.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:827,&quot;width&quot;:883,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:259414,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://ruidiao.substack.com/i/178805683?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5158cc01-f106-4493-9ef4-8764aeb10bdf_883x827.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!tYXD!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5158cc01-f106-4493-9ef4-8764aeb10bdf_883x827.png 424w, https://substackcdn.com/image/fetch/$s_!tYXD!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5158cc01-f106-4493-9ef4-8764aeb10bdf_883x827.png 848w, https://substackcdn.com/image/fetch/$s_!tYXD!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5158cc01-f106-4493-9ef4-8764aeb10bdf_883x827.png 1272w, https://substackcdn.com/image/fetch/$s_!tYXD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5158cc01-f106-4493-9ef4-8764aeb10bdf_883x827.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>A few days ago, I republished my personal website at <a href="https://ruidiao.dev">ruidiao.dev</a>. The last time I had a personal site was over 10 years ago when I was still a student. Comparing these two experiences reveals how dramatically web development has evolved and offers a glimpse into where AI coding tools are heading.</p><h2><strong>Then: The WordPress Era</strong></h2><p>Back in my student days, building a personal website meant renting a VPS (a virtual private server, essentially your own slice of a remote computer) and setting up WordPress (an open-source blogging platform). Sure, there were other blogging platforms available, but for someone who wanted to do things &#8220;the geek way,&#8221; self-hosting WordPress was what I did. It was a badge of honor. I owned my infrastructure, controlled my stack, and had the flexibility to customize everything.</p><p>WordPress remains one of the most popular open-source content management systems for good reason. But running a WordPress site came with real overhead: server management, security updates, and plugin maintenance. For a student publishing occasional tech posts, it was almost overkill, but it was the geek way of doing things.</p><h2><strong>Now: The Simplicity Shift</strong></h2><p>Fast forward to 2025, and my needs have changed completely. My personal website is no longer a blog. It&#8217;s a simple hub that links to my Substack, my LinkedIn, and other places where I share content. The web development landscape has changed too.</p><p>Some people still host their own blogs, and there&#8217;s nothing wrong with that. But today there are far more choices that make sense. Platforms like Substack, Medium, and DEV Community (<a href="http://dev.to">dev.to</a>) handle the heavy lifting of content management while you focus on writing. For those who still want full control, static site generators have experienced a <a href="https://cloudcannon.com/blog/the-top-five-static-site-generators-for-2025-and-when-to-use-them/">renaissance</a>, offering blazing-fast performance without the overhead of database management.</p><p>Hosting a custom WordPress instance doesn&#8217;t deliver the value it once did for a personal website. What defines &#8220;the geek way&#8221; has shifted from running your own server to choosing the right tools and building efficiently.</p><p>For my personal website, I just needed a single-page site with key information and links. So I took the modern geek way: I wrote my page with AI and submitted it to GitHub.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://ruidiao.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading The Signal! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h2><strong>The AI-Powered Workflow</strong></h2><p>The process was remarkably straightforward:</p><ol><li><p><strong>Vibe code the webpage</strong>: I used AI coding tools to quickly put together the HTML, CSS, and basic structure</p></li><li><p><strong>Version control with GitHub</strong>: All my code lives in a repository, giving me full version history and change tracking</p></li><li><p><strong>Auto-publish with GitHub Pages</strong>: Every push to the main branch automatically deploys to <a href="https://ruidiao.dev">ruidiao.dev</a></p></li></ol><p>The entire process took just a couple of hours from start to finish. This solution is accessible to almost any software engineer who knows how to use AI coding assistants and GitHub. The barrier to entry for personal websites has never been lower.</p><p>I&#8217;ve <a href="https://github.com/diaorui/ruidiao_website">shared my website&#8217;s code on GitHub</a> for anyone interested, though honestly, it&#8217;s simple enough that you could build something similar yourself with AI in an afternoon.</p><h2><strong>What I Learned: The Good</strong></h2><p><strong>Responsive design comes for free</strong>: One of the most impressive benefits of AI-generated code is that the website looks great on both mobile and desktop. Achieving truly responsive design used to require careful planning and testing. Now, AI coding tools handle this almost automatically.</p><p><strong>GitHub handles the heavy lifting</strong>: GitHub Pages has evolved significantly since its launch. Today it takes care of complexities that used to require significant setup: auto-publishing, hosting infrastructure, SSL certificates, and custom domain configuration. What used to require server management and CI/CD pipelines now happens automatically with a few repository settings.</p><p><strong>Speed and simplicity</strong>: For straightforward projects, AI coding tools are remarkably effective. These tools automate repetitive tasks, eliminate redundancies, and provide efficient workflows.</p><h2><strong>What I Learned: The Limitations</strong></h2><p>But the experience also revealed some important limitations of current AI coding tools.</p><p><strong>Design homogeneity</strong>: AI-coded websites tend to look very similar to each other. Nearly all of them use <a href="https://tailwindcss.com/">Tailwind CSS</a>, which has become the de facto standard for AI-generated styling. While Tailwind is excellent, this creates a certain sameness across AI-built sites. You can spot them from a mile away.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!0Oe5!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9e34591-d2d1-4ecd-91fe-6c0fbb5aacaa_2800x1598.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!0Oe5!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9e34591-d2d1-4ecd-91fe-6c0fbb5aacaa_2800x1598.png 424w, https://substackcdn.com/image/fetch/$s_!0Oe5!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9e34591-d2d1-4ecd-91fe-6c0fbb5aacaa_2800x1598.png 848w, https://substackcdn.com/image/fetch/$s_!0Oe5!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9e34591-d2d1-4ecd-91fe-6c0fbb5aacaa_2800x1598.png 1272w, https://substackcdn.com/image/fetch/$s_!0Oe5!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9e34591-d2d1-4ecd-91fe-6c0fbb5aacaa_2800x1598.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!0Oe5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9e34591-d2d1-4ecd-91fe-6c0fbb5aacaa_2800x1598.png" width="1456" height="831" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e9e34591-d2d1-4ecd-91fe-6c0fbb5aacaa_2800x1598.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:831,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1795746,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ruidiao.substack.com/i/178805683?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9e34591-d2d1-4ecd-91fe-6c0fbb5aacaa_2800x1598.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!0Oe5!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9e34591-d2d1-4ecd-91fe-6c0fbb5aacaa_2800x1598.png 424w, https://substackcdn.com/image/fetch/$s_!0Oe5!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9e34591-d2d1-4ecd-91fe-6c0fbb5aacaa_2800x1598.png 848w, https://substackcdn.com/image/fetch/$s_!0Oe5!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9e34591-d2d1-4ecd-91fe-6c0fbb5aacaa_2800x1598.png 1272w, https://substackcdn.com/image/fetch/$s_!0Oe5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9e34591-d2d1-4ecd-91fe-6c0fbb5aacaa_2800x1598.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>No proactive optimization</strong>: This is perhaps the most significant limitation. AI coding tools won&#8217;t proactively optimize for search engines (SEO) unless you explicitly ask. More importantly, they won&#8217;t implement Answer Engine Optimization (AEO), which is becoming critical in the AI era.</p><p>AEO is different from traditional SEO. While SEO focuses on ranking in search engine results pages, <a href="https://www.seo.com/ai/aeo-vs-seo/">AEO aims to have your content cited by AI-powered platforms</a> like ChatGPT, Perplexity, Google AI Overviews, and Bing Copilot. If you want your website to gain traction in this new landscape, optimization matters.</p><p><strong>The agentic workflow gap</strong>: AI is powerful for building websites and writing frontend code, but a mature agentic workflow is still necessary for professional websites. Current tools are excellent at execution when given clear prompts, but they don&#8217;t yet think strategically about the full lifecycle of a website: SEO, AEO, analytics, performance monitoring, and continuous optimization.</p><p>For my personal website, these limitations don&#8217;t matter much. It&#8217;s not a traffic-driven site. But for professional projects where visibility and discoverability are important, these gaps are significant.</p><h2><strong>The Bigger Picture: Where AI Coding Is Heading</strong></h2><p>This experience reinforced something I&#8217;ve been thinking about: AI coding tools are transforming how we build software, but we&#8217;re still in the early stages.</p><p>The current generation of tools like GitHub Copilot, Cursor, and Claude excels at tactical execution. They can write code, provide feedback, and generate design elements with impressive speed. New tools like Windsurf and Cline are emerging and making the landscape even more competitive.</p><p>But strategic thinking is still largely in human hands. Developers act as strategists, using AI to handle execution and optimization. The next evolution will likely be end-to-end systems that can design, code, test, and deploy fully functional websites with minimal human input, while also thinking about long-term concerns like SEO, AEO, and user experience optimization.</p><p>We&#8217;re not quite there yet, but we&#8217;re getting closer.</p><h2><strong>Why This Matters</strong></h2><p>The shift from WordPress to AI-generated static sites mirrors a broader evolution in how we think about personal web presence. A decade ago, owning your platform meant running your own infrastructure. Today, it means choosing the right combination of tools and platforms to amplify your voice.</p><p>For me, that means:</p><ul><li><p>A simple personal website as a hub</p></li><li><p>Substack for long-form writing</p></li><li><p>LinkedIn for professional networking</p></li><li><p>GitHub for code sharing</p></li></ul><p>Each platform serves a purpose, and my personal website connects them all.</p><p>If you&#8217;re thinking about building or rebuilding your personal website in 2025, my advice is simple: start with AI coding tools for the initial build, but understand their limitations. If traffic and discoverability matter, you&#8217;ll need a thoughtful workflow that guides AI tools through optimization strategies they won&#8217;t tackle proactively on their own.</p><p>The barrier to building a personal website has never been lower. But building a website that stands out and gets found? That still requires strategic human direction, at least for now.</p><div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://ruidiao.substack.com/p/building-my-personal-website-in-2025?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thanks for reading The Signal! This post is public so feel free to share it.</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://ruidiao.substack.com/p/building-my-personal-website-in-2025?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://ruidiao.substack.com/p/building-my-personal-website-in-2025?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div>]]></content:encoded></item><item><title><![CDATA[I Built an AI Chrome Extension in Two Days. No Servers Required]]></title><description><![CDATA[I just built and shipped an AI product with no backend servers.]]></description><link>https://ruidiao.substack.com/p/i-built-an-ai-chrome-extension-in</link><guid isPermaLink="false">https://ruidiao.substack.com/p/i-built-an-ai-chrome-extension-in</guid><dc:creator><![CDATA[Rui Diao]]></dc:creator><pubDate>Mon, 10 Nov 2025 18:58:21 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!1O5L!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2e296d5-ea15-460a-a007-ec182b7460b8_837x579.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I just built and shipped an AI product with no backend servers. No API keys to manage, no cloud services to provision, no usage costs to worry about. Chrome&#8217;s built-in AI made this possible, and it represents a new way to build AI products.</p><p>The extension is called <a href="https://chromewebstore.google.com/detail/nanocoffee/imociajlipjlmiglmjkpkjmkkfbblmhk">NanoCoffee</a>, and it took me a couple of days to create. This is my first AI Chrome extension, and the experience confirmed what I wrote about in my previous article on <a href="https://ruidiao.substack.com/p/the-quiet-revolution-unlocking-new?r=j5yr6">Chrome&#8217;s AI revolution</a>: we&#8217;re entering a new era where AI lives directly in the browser. This is the practical proof.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!1O5L!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2e296d5-ea15-460a-a007-ec182b7460b8_837x579.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!1O5L!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2e296d5-ea15-460a-a007-ec182b7460b8_837x579.png 424w, https://substackcdn.com/image/fetch/$s_!1O5L!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2e296d5-ea15-460a-a007-ec182b7460b8_837x579.png 848w, https://substackcdn.com/image/fetch/$s_!1O5L!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2e296d5-ea15-460a-a007-ec182b7460b8_837x579.png 1272w, https://substackcdn.com/image/fetch/$s_!1O5L!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2e296d5-ea15-460a-a007-ec182b7460b8_837x579.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!1O5L!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2e296d5-ea15-460a-a007-ec182b7460b8_837x579.png" width="837" height="579" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f2e296d5-ea15-460a-a007-ec182b7460b8_837x579.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:579,&quot;width&quot;:837,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:105591,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://ruidiao.substack.com/i/178527072?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2e296d5-ea15-460a-a007-ec182b7460b8_837x579.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!1O5L!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2e296d5-ea15-460a-a007-ec182b7460b8_837x579.png 424w, https://substackcdn.com/image/fetch/$s_!1O5L!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2e296d5-ea15-460a-a007-ec182b7460b8_837x579.png 848w, https://substackcdn.com/image/fetch/$s_!1O5L!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2e296d5-ea15-460a-a007-ec182b7460b8_837x579.png 1272w, https://substackcdn.com/image/fetch/$s_!1O5L!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2e296d5-ea15-460a-a007-ec182b7460b8_837x579.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2><strong>The Vision: AI as a Native Browser Capability</strong></h2><p>For the past few years, building AI features meant integrating with cloud APIs like OpenAI, Anthropic, or Google&#8217;s AI services. This model worked, but it created friction: API keys, authentication, rate limits, usage costs, latency, and privacy concerns.</p><p>Chrome changed this by <a href="https://developer.chrome.com/docs/ai/built-in">building Gemini Nano directly into the browser</a>. Starting with Chrome 126, developers gained access to on-device AI through a suite of <a href="https://developer.chrome.com/docs/ai/built-in-apis">built-in APIs</a>. No external services required. The AI is just there, ready to use.</p><p>This shift opens up entirely new possibilities for what we can build and how quickly we can build it.</p><h2><strong>The Problem I Was Solving</strong></h2><p>As an indie creator, I spend hours daily on social platforms: X, LinkedIn, and Substack. It&#8217;s where I learn, share ideas, and connect with my audience. But the information overload is real.</p><p>Long posts are everywhere, and there&#8217;s valuable content in many of them, but reading everything thoroughly is impossible. I found myself either skipping content I should have read or spending too much time trying to extract the key points.</p><p>There are AI browsers and AI sidebars that offer assistance, but they still require you to interact with a separate interface. I needed something truly integrated, something that worked exactly where I was already spending my time, with UI elements that felt native to the platforms themselves.</p><h2><strong>The Solution: NanoCoffee</strong></h2><p>NanoCoffee brings AI directly into your social media experience. It sits quietly in your browser and surfaces a summary button on long posts across X, LinkedIn, and Substack. Click it, and you get a concise summary of the content without leaving the platform.</p><p>Right now, it uses Chrome&#8217;s <a href="https://developer.chrome.com/docs/ai/built-in-apis">Summarization API</a>, which taps into Gemini Nano running locally on your device. The summarization happens entirely on your device, with no network calls required.</p><p>I built this in a couple of days. Not weeks. Not months. Days.</p><p>Part of that speed came from using AI to help write the code (building with AI to serve AI). But the bigger factor was that Chrome&#8217;s built-in AI APIs eliminated the entire backend complexity that would normally slow down development. No servers to set up, no authentication flows to implement.</p><p>The result: I can offer NanoCoffee without charging for API usage, your content never leaves your device, and as Google improves Gemini Nano, the extension gets smarter automatically without any updates.</p><h2><strong>What&#8217;s Next</strong></h2><p>NanoCoffee currently focuses on summarization because that was the most immediate pain point I wanted to solve. But Chrome&#8217;s built-in AI capabilities extend far beyond that.</p><p>Over the next few weeks, I&#8217;m considering several additions:</p><ul><li><p><strong>Writing and rewriting assistance:</strong> Help draft replies, adjust tone, or improve clarity of posts before you publish them</p></li><li><p><strong>Analytics assistant:</strong> Extracting insights from your feed, identifying trends, or highlighting key conversations you should pay attention to</p></li><li><p><strong>More platforms and use cases:</strong> The pattern of bringing AI assistance directly into your workflow applies to many contexts beyond social media</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!uH3-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51c2620e-9c61-421a-b4c5-86e2b33e4132_713x626.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!uH3-!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51c2620e-9c61-421a-b4c5-86e2b33e4132_713x626.png 424w, https://substackcdn.com/image/fetch/$s_!uH3-!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51c2620e-9c61-421a-b4c5-86e2b33e4132_713x626.png 848w, https://substackcdn.com/image/fetch/$s_!uH3-!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51c2620e-9c61-421a-b4c5-86e2b33e4132_713x626.png 1272w, https://substackcdn.com/image/fetch/$s_!uH3-!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51c2620e-9c61-421a-b4c5-86e2b33e4132_713x626.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!uH3-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51c2620e-9c61-421a-b4c5-86e2b33e4132_713x626.png" width="713" height="626" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/51c2620e-9c61-421a-b4c5-86e2b33e4132_713x626.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:626,&quot;width&quot;:713,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:117531,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://ruidiao.substack.com/i/178527072?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51c2620e-9c61-421a-b4c5-86e2b33e4132_713x626.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!uH3-!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51c2620e-9c61-421a-b4c5-86e2b33e4132_713x626.png 424w, https://substackcdn.com/image/fetch/$s_!uH3-!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51c2620e-9c61-421a-b4c5-86e2b33e4132_713x626.png 848w, https://substackcdn.com/image/fetch/$s_!uH3-!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51c2620e-9c61-421a-b4c5-86e2b33e4132_713x626.png 1272w, https://substackcdn.com/image/fetch/$s_!uH3-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51c2620e-9c61-421a-b4c5-86e2b33e4132_713x626.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The broader vision is to make AI feel like a natural extension of your browsing experience, not a separate tool you have to consciously invoke. The AI should be there when you need it, invisible when you don&#8217;t, and always respectful of your privacy.</p><h2><strong>The Bigger Picture</strong></h2><p>Chrome&#8217;s built-in AI is still early. The <a href="https://developer.chrome.com/docs/ai/built-in-apis">Prompt API</a> became stable for extensions in Chrome 138. Some capabilities are still in origin trials. There are hardware requirements (you need sufficient RAM and storage). The ecosystem is evolving.</p><p>But the direction is clear. AI is becoming a platform capability, not just a cloud service. This changes the economics, privacy model, and user experience of AI products.</p><p>For developers, the barriers to building and shipping AI products just dropped significantly. You don&#8217;t need to be backed by venture capital to afford API costs. You don&#8217;t need a team to manage backend servers. You can experiment, iterate, and launch AI features without the traditional infrastructure overhead.</p><p>For users, this means more privacy-respecting, cost-effective AI tools that integrate seamlessly into existing workflows.</p><h2><strong>Try It Yourself</strong></h2><p>If you&#8217;re dealing with information overload on social media, <a href="https://chromewebstore.google.com/detail/nanocoffee/imociajlipjlmiglmjkpkjmkkfbblmhk">give NanoCoffee a try</a>. It&#8217;s free, requires no API keys, and works entirely on your device.</p><p>If you&#8217;re a developer curious about building with Chrome&#8217;s built-in AI, check out the <a href="https://developer.chrome.com/docs/ai/built-in">official documentation</a>. The APIs are straightforward and ready to use.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://ruidiao.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading The Signal! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><p>Please <strong>comment, and share</strong> if you feel compelled to do so.</p><p>I appreciate you reading. Thanks to the new subscribers! &#9996;</p><p>For those who are more active on other platforms, you can also find me on <a href="https://www.linkedin.com/in/ruidiao/">LinkedIn</a> or <a href="https://x.com/ruidiaox">X</a>.</p>]]></content:encoded></item></channel></rss>