<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Weilu Wang</title>
    <description>The latest articles on DEV Community by Weilu Wang (@wandawwl).</description>
    <link>https://dev.to/wandawwl</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3957614%2F017a7176-6bc7-4002-a882-bc748b0cf787.jpg</url>
      <title>DEV Community: Weilu Wang</title>
      <link>https://dev.to/wandawwl</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/wandawwl"/>
    <language>en</language>
    <item>
      <title>I Couldn't Grow Up with a Cat, So I Made a Django Package to Fix That</title>
      <dc:creator>Weilu Wang</dc:creator>
      <pubDate>Wed, 03 Jun 2026 04:01:27 +0000</pubDate>
      <link>https://dev.to/wandawwl/i-couldnt-grow-up-with-a-cat-so-i-made-a-django-package-to-fix-that-2ba0</link>
      <guid>https://dev.to/wandawwl/i-couldnt-grow-up-with-a-cat-so-i-made-a-django-package-to-fix-that-2ba0</guid>
      <description>&lt;p&gt;I always wanted a cat but never had one as a child. Decades later, I used Doubao API to merge my childhood photos with my cat's images, then built a reusable Django app (&lt;code&gt;django-doubao&lt;/code&gt;) that does AI image fusion and image-to-video generation. Here's how it works and why I built it.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Empty Space
&lt;/h2&gt;

&lt;p&gt;When I was a kid, I longed for a cat. My mother wouldn't allow it. I pressed my face against the neighbour’s window, watching their tabby stretch and roll in the sun – a hollow ache in my chest.&lt;/p&gt;

&lt;p&gt;Only after forty years did I finally get my own cat. But then a new sadness crept in: I couldn’t grow up with her.&lt;/p&gt;

&lt;p&gt;So I devised a trick.&lt;/p&gt;

&lt;p&gt;On Doubao (ByteDance’s AI platform), I took my old, faded childhood photos – gap-toothed, laughing – and merged them with my cat’s plump white face. Suddenly, we were playing together. Then I made videos: the child chasing the cat through a field of flowers, wind lifting our hair, years dissolving.&lt;/p&gt;

&lt;p&gt;Each creation sent ripples through my heart – from a quiet centre to the corners of my lips and eyes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc0f6k9tmmrro1lhyes76.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc0f6k9tmmrro1lhyes76.png" alt=" " width="800" height="459"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  A Programmer’s Solution
&lt;/h2&gt;

&lt;p&gt;I started on Doubao’s official website, but soon I thought: I’m a programmer. Why not build my own app?&lt;/p&gt;

&lt;p&gt;I got a Doubao API key, set up a Django project, and wrote a &lt;code&gt;utils.py&lt;/code&gt; – not three hundred lines – that became the key to my own toy box.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My ritual:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Pick a beautiful landscape – the old locust tree at my childhood hutong, summer thick with cicadas.&lt;/li&gt;
&lt;li&gt;Add my childhood face and my fat white cat (round as a snowball).&lt;/li&gt;
&lt;li&gt;Merge them into one image where we play together.&lt;/li&gt;
&lt;li&gt;Animate that still picture – the cat rolls on the grass, the child chases, flowers tremble in a breeze I only feel in memory.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I created &lt;strong&gt;two Django views&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The first fuses multiple reference images into one AI-generated picture.&lt;/li&gt;
&lt;li&gt;The second turns that picture into a short video (5–12 seconds).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When I saw the boy and the cat move across the screen, something long empty inside me was gently filled.&lt;/p&gt;

&lt;p&gt;I packed the whole thing into a Python package, &lt;code&gt;django-doubao&lt;/code&gt;, and published it on GitHub.&lt;/p&gt;




&lt;h2&gt;
  
  
  What the Package Does
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Multi‑image fusion&lt;/strong&gt; – combine several reference images + text prompt → one new AI image.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Image‑to‑video generation&lt;/strong&gt; – turn a single image (generated or uploaded) into a 5–12 sec video. Supports aspect ratios, resolutions, returns video + last frame.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Asynchronous polling&lt;/strong&gt; – video generation is async; the package polls automatically. No &lt;code&gt;while&lt;/code&gt; loops needed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Task records&lt;/strong&gt; – via Django models, so you can track or re‑create past generations.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Quick Architecture Overview
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;django-doubao/
├── doubao/
│   ├── models.py        # ImageGeneration, VideoGeneration
│   ├── views.py         # generate_image_view, generate_video_view
│   ├── urls.py          # routes with namespace
│   ├── utils.py         # API calls: generate_image, submit_video_task, poll_video_result
│   ├── templates/       # standalone Vue3 templates (no base.html required)
│   └── migrations/
├── tests/               # pytest + mock, 15 tests all green
├── pyproject.toml
└── README.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Key decisions&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No built-in permissions&lt;/strong&gt; – you wrap views with &lt;code&gt;login_required&lt;/code&gt; or &lt;code&gt;user_passes_test&lt;/code&gt; yourself. Each project is different.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Self-contained templates&lt;/strong&gt; – they work even if your project has no &lt;code&gt;base.html&lt;/code&gt;. You can override them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Synchronous polling&lt;/strong&gt; – good for low‑concurrency personal use; you can swap in Celery later.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Using django-doubao
&lt;/h2&gt;

&lt;p&gt;Install:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;django-doubao
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add to &lt;code&gt;INSTALLED_APPS&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;INSTALLED_APPS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="bp"&gt;...&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;doubao&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Set your API key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;DOUBAO_API_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;your-key-here&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Include URLs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# urls.py
&lt;/span&gt;&lt;span class="nf"&gt;path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;doubao/&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;doubao.urls&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then visit &lt;code&gt;/doubao/image/&lt;/code&gt; to generate images, and &lt;code&gt;/doubao/video/&lt;/code&gt; to turn them into videos.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why I’m Sharing This
&lt;/h2&gt;

&lt;p&gt;I could have kept using online tools. But as a programmer, I chose to build a small world with code – one where the child and the cat can finally run, daydream, and watch maple leaves fall together.&lt;/p&gt;

&lt;p&gt;If you have a similar wish – to revive an old photograph or animate a memory – I hope &lt;code&gt;django-doubao&lt;/code&gt; helps you take fewer detours.&lt;/p&gt;

&lt;p&gt;Code is like bricks. The important thing isn’t how complex it is, but what you build with it.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;The cat is purring beside me. The video loops on the screen. I turn off the light, leaving only the screen’s glow – and that old hollow feels truly filled.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;What do you think? Have you ever used AI to fill a childhood gap? Let me know in the comments.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>python</category>
      <category>django</category>
    </item>
    <item>
      <title>RAG in production: three levels from search to conversation</title>
      <dc:creator>Weilu Wang</dc:creator>
      <pubDate>Fri, 29 May 2026 03:23:03 +0000</pubDate>
      <link>https://dev.to/wandawwl/rag-in-production-three-levels-from-search-to-conversation-1g7d</link>
      <guid>https://dev.to/wandawwl/rag-in-production-three-levels-from-search-to-conversation-1g7d</guid>
      <description>&lt;p&gt;DEVELOPER. So, you want to build a website that thinks?&lt;/p&gt;

&lt;p&gt;USER. I want it to answer questions. Not just search.&lt;/p&gt;

&lt;p&gt;DEVELOPER. Then let’s walk the path. First stop: the quiet room.&lt;/p&gt;

&lt;p&gt;(He gestures slowly, almost lazily.)&lt;/p&gt;

&lt;p&gt;DEVELOPER. Level One. RAG as a librarian. You chop up your help pages – articles, product specs, manuals – into chunks. Run each chunk through an embedding model. Vectors. No AI generation. No talking back. Just a silent index.&lt;/p&gt;

&lt;p&gt;USER. Like a smarter search bar?&lt;/p&gt;

&lt;p&gt;DEVELOPER. Exactly. You search for “lightweight running shoes.” It finds “super-light marathon trainers.” Same meaning, different words. But the user still gets a list of snippets. Scroll. Click. Read three paragraphs. Patch the answer together. It’s… polite. But dull.&lt;/p&gt;

&lt;p&gt;USER. So where’s that useful?&lt;/p&gt;

&lt;p&gt;DEVELOPER. “You might also like” recommendations. Back-office content scanning. Batch processing where no human waits for an answer. Not for real conversations.&lt;/p&gt;

&lt;p&gt;(His tone quickens.)&lt;/p&gt;

&lt;p&gt;DEVELOPER. Level Two. Now we add the voice. The AI.&lt;/p&gt;

&lt;p&gt;(He snaps his fingers.)&lt;/p&gt;

&lt;p&gt;DEVELOPER. User asks: “How do I reset my password?” The vector library hunts for relevant chunks. Then we stuff the question plus those chunks into a large language model – DeepSeek V4-Flash, GPT-4o-mini, whatever. And the model writes an answer. Complete. Natural. No fluff.&lt;/p&gt;

&lt;p&gt;USER. So they don’t have to read ten pages.&lt;/p&gt;

&lt;p&gt;DEVELOPER. They get one answer. And they can follow up: “What about the admin reset?” The model remembers the conversation. That’s the jump. From search to answer.&lt;/p&gt;

&lt;p&gt;USER. How much does that cost?&lt;/p&gt;

&lt;p&gt;DEVELOPER. Pennies. DeepSeek V4-Flash costs ~0.87 per million output tokens. A typical Q&amp;amp;A uses maybe 2000 tokens. That’s 0.0017 per query. For a thousand queries a day? &lt;br&gt;
1.70.Runamediume‑commercesiteforamonth–maybe10.&lt;/p&gt;

&lt;p&gt;USER. That’s nothing.&lt;/p&gt;

&lt;p&gt;DEVELOPER. Exactly. That’s why Level Two is the sweet spot today. Perfect for internal knowledge bases, product help centers, e‑commerce Q&amp;amp;A, legal summaries, news article deep dives. Anywhere you want a guide, not a search box.&lt;/p&gt;

&lt;p&gt;(He raises a finger.)&lt;/p&gt;

&lt;p&gt;DEVELOPER. Level Three. CaaS. Conversation as a Service.&lt;/p&gt;

&lt;p&gt;(His pace accelerates, words running together.)&lt;/p&gt;

&lt;p&gt;DEVELOPER. Now you don’t just index documents. You index APIs. Function specs, endpoint descriptions, parameter lists, call examples. The user says: “Pause my subscription for next week.”&lt;/p&gt;

&lt;p&gt;The vector store retrieves the relevant API: PUT /subscriptions/{id}/pause with start_date and duration. The model understands intent and outputs a structured call – JSON, a curl command, whatever your system expects. Then your backend either suggests the action (“Click to confirm”) or executes it directly, depending on safety.&lt;/p&gt;

&lt;p&gt;USER. That’s dangerous.&lt;/p&gt;

&lt;p&gt;DEVELOPER. It’s powerful. You design a confirmation step when needed. But the leap is clear: the user talks, the website acts. No menus. No forms. For SaaS, CRM, IoT dashboards – any place where talking is faster than clicking.&lt;/p&gt;

&lt;p&gt;USER. Where do I start?&lt;/p&gt;

&lt;p&gt;(He slows down, leans back.)&lt;/p&gt;

&lt;p&gt;DEVELOPER. Start simple. Take your existing help docs. Your FAQ. Your user manual. Throw them into a vector database (Milvus Lite, Qdrant, Chroma). Write a tiny endpoint that: (1) embeds the user’s question, (2) retrieves top‑k chunks, (3) calls an LLM, (4) returns the answer. Add a chat bubble on every page. Two weeks. That’s your first step.&lt;/p&gt;

&lt;p&gt;USER. And then?&lt;/p&gt;

&lt;p&gt;DEVELOPER. Then you evolve. Add more documents. Tune chunk size. Switch from “retrieve then generate” to a proper RAG pipeline with reranking. And only after that – when you have real APIs – move to Level Three. From “tell me how” to “do it for me.”&lt;/p&gt;

&lt;p&gt;(He smiles, pauses.)&lt;/p&gt;

&lt;p&gt;DEVELOPER. One sentence: Don’t automate everything at once. Just put your existing help into RAG, add a layer of AI, and you get an assistant that answers “how do I use this feature?” instantly. Happier users. Fewer support tickets. Later, plug in the real APIs. That’s the path.&lt;/p&gt;

&lt;p&gt;(Exit.)&lt;/p&gt;

</description>
      <category>rag</category>
      <category>ai</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
