<?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: Denys Illichov</title>
    <description>The latest articles on DEV Community by Denys Illichov (@denys_illichov_fb35149166).</description>
    <link>https://dev.to/denys_illichov_fb35149166</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%2F4038592%2Fccebdcba-ab72-4247-a241-757dedd58740.jpg</url>
      <title>DEV Community: Denys Illichov</title>
      <link>https://dev.to/denys_illichov_fb35149166</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/denys_illichov_fb35149166"/>
    <language>en</language>
    <item>
      <title>I built an AI agent that sells your stuff online and manages the listings</title>
      <dc:creator>Denys Illichov</dc:creator>
      <pubDate>Mon, 20 Jul 2026 17:27:30 +0000</pubDate>
      <link>https://dev.to/denys_illichov_fb35149166/i-built-an-ai-agent-that-sells-your-stuff-online-and-manages-the-listings-597g</link>
      <guid>https://dev.to/denys_illichov_fb35149166/i-built-an-ai-agent-that-sells-your-stuff-online-and-manages-the-listings-597g</guid>
      <description>&lt;p&gt;My AirPods Max sat in a drawer for a year. I kept meaning to sell them — but that means writing a listing, guessing a price, and then a week of "is this still available?" messages. So they just sat there.&lt;/p&gt;

&lt;p&gt;For the &lt;a href="https://qwencloud-hackathon.devpost.com/" rel="noopener noreferrer"&gt;Qwen Cloud hackathon&lt;/a&gt; I built an agent that does all of it. I take two photos with my phone. It checks the item is real, looks up what it sells for, lists it on eBay, talks to the buyers, and gives me a shipping label. My only decision is one tap to approve the price range.&lt;/p&gt;

&lt;p&gt;Here's what that looks like with my actual AirPods:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Two photos → &lt;strong&gt;"Apple AirPods Max, Space Gray — verified real"&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;It searches the live market → &lt;strong&gt;"sells for $340–385"&lt;/strong&gt; — I tap once&lt;/li&gt;
&lt;li&gt;It creates a real eBay listing (a real listing id, via the Inventory API)&lt;/li&gt;
&lt;li&gt;Buyers come in → it declines two scams, negotiates with the real one&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sold at $350&lt;/strong&gt; → it shows my payout: &lt;strong&gt;+$303.32&lt;/strong&gt; after the eBay fee&lt;/li&gt;
&lt;li&gt;Shipping label ready — download, print, tape it on the box&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Try it on your phone: &lt;a href="https://agent.onlist.ai" rel="noopener noreferrer"&gt;agent.onlist.ai&lt;/a&gt; · Code: &lt;a href="https://github.com/itsbigdill/onlist-agent" rel="noopener noreferrer"&gt;github.com/itsbigdill/onlist-agent&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The rest of this post is the two problems that turned out to be interesting: how to know a photo is real, and how to let an AI negotiate without letting it give your stuff away.&lt;/p&gt;

&lt;h2&gt;
  
  
  Problem 1: anyone can fake a product photo now
&lt;/h2&gt;

&lt;p&gt;If an agent lists things for you automatically, someone will feed it fake photos. AI-generated "products", screenshots from shops, photos of a monitor. Marketplaces are already full of this — listings for things that don't exist.&lt;/p&gt;

&lt;p&gt;So before selling anything, the agent has to answer: &lt;strong&gt;is this a real object that this person actually has?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;My first try was simple: send the photo to Qwen3.7-VL and ask "is this a real photo of a physical object?" It answered &lt;em&gt;yes&lt;/em&gt; to a photo of my monitor. Which is fair — a screen showing a real photo &lt;em&gt;is&lt;/em&gt; a real photo. From one frame, you can't tell.&lt;/p&gt;

&lt;p&gt;The fix: don't use one frame. The app takes two photos while you move the phone, and the model sees both at once with one instruction — check that it's the same object in the same room, seen from two angles. A real thing shifts against the background, the light moves on it. A photo of a screen stays flat — and brings moiré and a monitor edge with it.&lt;/p&gt;

&lt;p&gt;After that change, here's the model catching my monitor trick, in its own words:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Not a live capture — these are photographs of a digital screen. Moiré interference across the background, a rectangular border separating the image from its surroundings, and no parallax as the camera moves.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A fake doesn't get a warning label. It just doesn't get listed.&lt;/p&gt;

&lt;p&gt;One more nice bit: when the model &lt;em&gt;isn't sure&lt;/em&gt;, it doesn't guess. It asks for one specific extra shot — "tilt it and photograph the underside" — and looks again. That logic is a small pure function (&lt;code&gt;decide()&lt;/code&gt;), covered by unit tests.&lt;/p&gt;

&lt;h3&gt;
  
  
  Did it actually work? Numbers:
&lt;/h3&gt;

&lt;p&gt;I made a test set: 7 fakes (4 AI images generated with qwen-image — so the examiner is tested against its own model family, a photo of a screen, a catalog photo, and a two-different-objects trick) and 7 real things from around my apartment, two photos each. &lt;code&gt;bun run bench&lt;/code&gt; runs the whole thing:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7/7 fakes caught · 7/7 real items passed · median verdict 5.4s · $0.057 for all 14 checks.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Honest footnote: on the hardest real case — a toy shot from the top, then flipped upside down — the model occasionally hesitates and flags it. And my first version let two AI images through at 0.95 confidence before I switched to the two-frame approach. It's not magic; it's a benchmark and iteration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Problem 2: an AI negotiator that can't be talked down
&lt;/h2&gt;

&lt;p&gt;Letting a model chat with buyers is easy. Letting it &lt;em&gt;negotiate&lt;/em&gt; is scary — what if someone prompts it into "sure, take it for $5"?&lt;/p&gt;

&lt;p&gt;The rule I ended up with: &lt;strong&gt;money limits live in code, not in the prompt.&lt;/strong&gt; When I approve "sells for $340–385", the floor ($340) becomes a hard bound. The model drafts replies and counter-offers, but the number it proposes is clamped in TypeScript — it physically can't go below the floor, and the reply never reveals it. Buyers flagged as scams (overpayment, "my shipping agent will pick it up") get no counter-offer at all.&lt;/p&gt;

&lt;p&gt;Same idea everywhere: the model suggests, the code enforces.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it runs on
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;~1,000 lines of zero-dependency TypeScript (plain &lt;code&gt;fetch&lt;/code&gt;, no SDKs) on &lt;strong&gt;Alibaba Function Compute&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;qwen3.7-plus&lt;/strong&gt; — the vision examiner + pricing and buyer triage&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;qwen3.6-flash&lt;/strong&gt; — quick jobs: "one more angle" requests, the live buyer chat&lt;/li&gt;
&lt;li&gt;Pricing uses DashScope's &lt;code&gt;forced_search&lt;/code&gt; so the model searches the live web for comps before naming a price. (Gotcha: &lt;code&gt;enable_search: true&lt;/code&gt; alone is silently ignored — you need &lt;code&gt;forced_search&lt;/code&gt;. That cost me an afternoon.)&lt;/li&gt;
&lt;li&gt;The eBay part is the real Inventory API in sandbox: OAuth, category from their taxonomy, publish, listing id back.&lt;/li&gt;
&lt;li&gt;Every model call is metered — the demo prints exactly what each stage cost.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/itsbigdill/onlist-agent &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;onlist-agent
bun &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cp&lt;/span&gt; .env.example .env   &lt;span class="c"&gt;# add your DASHSCOPE_API_KEY&lt;/span&gt;
bun run bench    &lt;span class="c"&gt;# re-run the real/fake benchmark&lt;/span&gt;
bun run demo     &lt;span class="c"&gt;# the full flow in your terminal&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or open &lt;a href="https://agent.onlist.ai" rel="noopener noreferrer"&gt;agent.onlist.ai&lt;/a&gt; on your phone, photograph something on your desk — and then try to fool it with a screenshot. That's the fun part.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>qwen</category>
      <category>agents</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
