<?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: Mark Q</title>
    <description>The latest articles on DEV Community by Mark Q (@markgege).</description>
    <link>https://dev.to/markgege</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4029197%2Feef045f9-0a18-4ea4-a131-c74e49afece4.jpg</url>
      <title>DEV Community: Mark Q</title>
      <link>https://dev.to/markgege</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/markgege"/>
    <language>en</language>
    <item>
      <title>I had Qwen build a Qwen-powered app — and sat in the reviewer's chair</title>
      <dc:creator>Mark Q</dc:creator>
      <pubDate>Tue, 14 Jul 2026 19:51:25 +0000</pubDate>
      <link>https://dev.to/markgege/i-had-qwen-build-a-qwen-powered-app-and-sat-in-the-reviewers-chair-4phe</link>
      <guid>https://dev.to/markgege/i-had-qwen-build-a-qwen-powered-app-and-sat-in-the-reviewers-chair-4phe</guid>
      <description>&lt;p&gt;Most hackathon posts are about what the AI &lt;em&gt;does&lt;/em&gt;. This one is also about who&lt;br&gt;
&lt;em&gt;wrote it&lt;/em&gt;. &lt;strong&gt;QuotePilot&lt;/strong&gt; — an autopilot that turns a cross-border B2B inquiry&lt;br&gt;
email into an approved, bilingual (EN/中文) price quote — is powered by Qwen at&lt;br&gt;
runtime. But the app itself was also largely &lt;em&gt;written&lt;/em&gt; by Qwen models, dispatched&lt;br&gt;
through a tiny harness while I sat in the reviewer's chair and accepted or&lt;br&gt;
rejected each piece. Total model spend for the whole build: &lt;strong&gt;under $1 of the&lt;br&gt;
$40 hackathon credit.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here's what that actually felt like, where it was magic, and where I had to keep&lt;br&gt;
both hands on the wheel.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Live demo:&lt;/strong&gt; &lt;a href="https://mark24680617.github.io/quotepilot/" rel="noopener noreferrer"&gt;https://mark24680617.github.io/quotepilot/&lt;/a&gt; (demo login: &lt;code&gt;judge&lt;/code&gt; / &lt;code&gt;qwen2026&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Repo:&lt;/strong&gt; &lt;a href="https://github.com/mark24680617/quotepilot" rel="noopener noreferrer"&gt;https://github.com/mark24680617/quotepilot&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;2-min demo video:&lt;/strong&gt; &lt;a href="https://youtu.be/00BlsBs3ba4" rel="noopener noreferrer"&gt;https://youtu.be/00BlsBs3ba4&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  The problem is boring, expensive, and perfect for an agent
&lt;/h2&gt;

&lt;p&gt;A US software company selling into China answers every inquiry email by hand:&lt;br&gt;
read the ask (often in Chinese), look up pricing, apply volume discounts,&lt;br&gt;
convert USD⇄CNY at today's rate, and draft a bilingual quote with the &lt;em&gt;right&lt;/em&gt;&lt;br&gt;
cross-border legal and tax terms (HKIAC arbitration, Chinese text controlling,&lt;br&gt;
"we can't issue a fapiao" note). It's 1–2 hours per inquiry, and the mistakes —&lt;br&gt;
a wrong rate, a missing tax clause — are the expensive kind.&lt;/p&gt;

&lt;p&gt;That's a real workflow with a real brake pedal built in: someone always reviews&lt;br&gt;
the quote before it goes out. So the design wrote itself — an agent that does&lt;br&gt;
the whole run in under a minute and &lt;strong&gt;pauses for exactly one human decision.&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  The routing: language to the models, ledgers to the code
&lt;/h2&gt;

&lt;p&gt;QuotePilot runs a six-stage pipeline — intake → live FX → pricing → rule risk →&lt;br&gt;
AI risk sweep → bilingual drafting — then stops at a human gate. Three Qwen&lt;br&gt;
models split the work:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Planner / bilingual drafting&lt;/td&gt;
&lt;td&gt;&lt;code&gt;qwen-max&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Extraction + risk-sweep workers&lt;/td&gt;
&lt;td&gt;&lt;code&gt;qwen-flash&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Strict structured output (catalog mapping)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;qwen3-coder-plus&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The single most important line I drew: &lt;strong&gt;the LLM never does arithmetic and never&lt;br&gt;
writes legal terms.&lt;/strong&gt; Every price is Python &lt;code&gt;Decimal&lt;/code&gt;, computed in code. Every&lt;br&gt;
legal clause is fixed, lawyer-shaped bilingual text. The model chooses &lt;em&gt;which&lt;/em&gt;&lt;br&gt;
catalog item a customer meant and writes a warm cover letter — it never decides&lt;br&gt;
that 150 × $290 × 0.92 = $40,020. That's not a stylistic preference; it's the&lt;br&gt;
difference between a demo and something you'd let touch a contract.&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;# The model maps "we want CitizenReady for 150 seats" → SKU CR-ENT.
# The code does the money — always.
&lt;/span&gt;&lt;span class="n"&gt;net&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;unit_price&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;qty&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;discount_pct&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;quantize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CENT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ROUND_HALF_UP&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Letting Qwen write the code
&lt;/h2&gt;

&lt;p&gt;I built a ~150-line dispatcher (&lt;code&gt;scripts/qwen_dev.py&lt;/code&gt;): hand it a task spec, it&lt;br&gt;
sends the spec to a chosen Qwen model, parses the returned files into a staging&lt;br&gt;
area, and appends token usage to a ledger. Nothing lands in the repo until I&lt;br&gt;
review it. Over the build, Qwen wrote the FastAPI backend, the approval&lt;br&gt;
dashboard, the settings UI, the runs index, and more — fourteen dispatches,&lt;br&gt;
&lt;strong&gt;$0.81 total&lt;/strong&gt;, a few cents each. Even the demo video's voiceover is Qwen&lt;br&gt;
(&lt;code&gt;qwen3-tts-flash&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;The pattern that emerged: &lt;strong&gt;describe the interfaces precisely, and a code model&lt;br&gt;
fills them in impressively well.&lt;/strong&gt; When my task spec pinned down exact function&lt;br&gt;
signatures, endpoint shapes, and data models, &lt;code&gt;qwen3-coder-plus&lt;/code&gt; produced code&lt;br&gt;
that dropped in with only small fixes. When I was vague, I got plausible code&lt;br&gt;
that missed the contract.&lt;/p&gt;

&lt;h2&gt;
  
  
  The war stories (nobody's build is clean)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Alibaba Cloud's &lt;code&gt;fcapp.run&lt;/code&gt; domain force-downloads HTML.&lt;/strong&gt; My first deploy&lt;br&gt;
worked in &lt;code&gt;curl&lt;/code&gt; but the browser downloaded the page instead of rendering it —&lt;br&gt;
the system domain sets &lt;code&gt;Content-Disposition: attachment&lt;/code&gt; and forbids 3xx&lt;br&gt;
redirects (anti-phishing). The fix reshaped the architecture for the better: a&lt;br&gt;
static single-page app on GitHub Pages that talks to a CORS-enabled JSON API on&lt;br&gt;
Function Compute. &lt;code&gt;fetch()&lt;/code&gt; doesn't care about the download header, and now the&lt;br&gt;
judges see a clean HTTPS page whose every request visibly hits the Alibaba Cloud&lt;br&gt;
backend.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;custom.debian10&lt;/code&gt; ships Python 3.7, not 3.10.&lt;/strong&gt; The docs promised 3.10. An&lt;br&gt;
in-instance probe said otherwise. Switching the runtime to &lt;code&gt;custom.debian12&lt;/code&gt;&lt;br&gt;
(Python 3.11) — and re-vendoring the wheels for cp311 manylinux — fixed the cold&lt;br&gt;
starts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Don't ask a code model to re-emit a 70 KB file.&lt;/strong&gt; For one big frontend change&lt;br&gt;
I asked Qwen to return the whole updated &lt;code&gt;index.html&lt;/code&gt;. It gave me back a file&lt;br&gt;
&lt;em&gt;23 KB smaller&lt;/em&gt; — it had silently dropped an entire settings module and never&lt;br&gt;
implemented the feature I asked for. Lesson learned: give a code model the&lt;br&gt;
&lt;strong&gt;changed functions&lt;/strong&gt;, not the whole file, and diff the result. I hand-wrote&lt;br&gt;
that feature instead.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;An adversarial review round caught 11 real bugs.&lt;/strong&gt; Before shipping the&lt;br&gt;
multi-company refactor, I ran a small multi-agent review — finders proposing&lt;br&gt;
bugs, independent verifiers trying to &lt;em&gt;refute&lt;/em&gt; each one. It surfaced a&lt;br&gt;
discount-field name mismatch that would have 422'd every settings save, and a&lt;br&gt;
stored-XSS in a free-text config field. Both would have shipped. Verified&lt;br&gt;
findings only; the skeptics killed the noise.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Filming the demo caught the best bug of all.&lt;/strong&gt; The demo video is recorded&lt;br&gt;
programmatically (Playwright drives the real app; ffmpeg cuts each scene to the&lt;br&gt;
voiceover). While reviewing the edit-then-approve scene frame by frame, I&lt;br&gt;
noticed the issued quote document still showed the &lt;em&gt;pre-edit&lt;/em&gt; numbers — the&lt;br&gt;
orchestrator was rendering the quote object it held before the human gate,&lt;br&gt;
while the edit endpoint had replaced the gate's copy. On-screen: totals said&lt;br&gt;
$32,550, the artifact said $21,930. One-line fix, a regression test, redeploy —&lt;br&gt;
and a new rule: &lt;strong&gt;watch your own demo like a judge would.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The human gate is the product
&lt;/h2&gt;

&lt;p&gt;It would have been easy to make QuotePilot fully autonomous and call it a day.&lt;br&gt;
The interesting product decision was the opposite: make the pause &lt;em&gt;good&lt;/em&gt;. The&lt;br&gt;
operator sees the drafted quote, the risk flags, and a plain-language summary,&lt;br&gt;
and can &lt;strong&gt;approve, reject, or edit&lt;/strong&gt; — adjust quantities, prices, discounts,&lt;br&gt;
add or remove line items. When they edit, the server re-prices in &lt;code&gt;Decimal&lt;/code&gt; and&lt;br&gt;
re-renders the document; approve then issues exactly what they saw. A &lt;code&gt;block&lt;/code&gt;&lt;br&gt;
-severity risk flag disables approval outright.&lt;/p&gt;

&lt;p&gt;Autonomy with a brake. For a document that becomes a contract, that's the whole&lt;br&gt;
ballgame — and it's what I'd want a judge to remember.&lt;/p&gt;

&lt;h2&gt;
  
  
  What "AI writes, human reviews" actually feels like
&lt;/h2&gt;

&lt;p&gt;It's genuinely great at &lt;strong&gt;mechanical breadth&lt;/strong&gt; — CRUD endpoints, form UIs,&lt;br&gt;
wiring, tests-to-spec — and it's fast and cheap at it. It is &lt;em&gt;not&lt;/em&gt; the place to&lt;br&gt;
hand over &lt;strong&gt;money math, security-sensitive parsing, or large-file surgery&lt;/strong&gt;;&lt;br&gt;
those are exactly where a confident-but-wrong output costs you. The reviewer's&lt;br&gt;
job isn't ceremony. It's knowing which outputs to trust on sight and which to&lt;br&gt;
read line by line — and never letting the model near the ledger.&lt;/p&gt;

&lt;p&gt;Qwen built most of QuotePilot. I made sure it never did the math.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Try it:&lt;/strong&gt; &lt;a href="https://mark24680617.github.io/quotepilot/" rel="noopener noreferrer"&gt;https://mark24680617.github.io/quotepilot/&lt;/a&gt; (demo login:&lt;br&gt;
&lt;code&gt;judge&lt;/code&gt; / &lt;code&gt;qwen2026&lt;/code&gt;) · &lt;strong&gt;Code:&lt;/strong&gt; &lt;a href="https://github.com/mark24680617/quotepilot" rel="noopener noreferrer"&gt;https://github.com/mark24680617/quotepilot&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>qwen</category>
      <category>hackathon</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
